]> granicus.if.org Git - fribidi/commitdiff
Reimplemented Arabic joining. Hopefullly it's conforming to the standard now,
authorbehdad <behdad>
Mon, 21 Jun 2004 21:15:31 +0000 (21:15 +0000)
committerbehdad <behdad>
Mon, 21 Jun 2004 21:15:31 +0000 (21:15 +0000)
with the exception that we assume "level run" instead of "directional run",
which is a proposed changed to be applied for Unicode 4.1.

.indent.pro
lib/fribidi-bidi.h
lib/fribidi-joining-types.h
lib/fribidi-joining.c
lib/fribidi-joining.h
lib/fribidi-unicode.h
lib/fribidi.c
lib/fribidi.h

index 08eb245b39942bb13824db0237019dfe9a3f6b43..4359aac896622729625684cee343b092597d8bcf 100644 (file)
@@ -8,7 +8,7 @@
 -T FriBidiCharType
 -T FriBidiParType
 -T FriBidiJoiningType
--T FriBidiArabicProps
+-T FriBidiArabicProp
 -T FriBidiCharSet
 -T FriBidiCharSetHandler
 -T FriBidiMemChunk
index 99596bd840a0b6b292fa66bd4f9090d4b5d0cce9..53469f27898fd2725de36b3cf5c48545950c7f72 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi-bidi.h - bidirectional algorithm
  *
- * $Id: fribidi-bidi.h,v 1.13 2004-06-21 18:49:23 behdad Exp $
+ * $Id: fribidi-bidi.h,v 1.14 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-21 18:49:23 $
- * $Revision: 1.13 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.14 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-bidi.h,v $
  *
  * Authors:
@@ -63,7 +63,8 @@
  * only LTR, RTL, or ON.
  */
 FRIBIDI_ENTRY FriBidiParType fribidi_get_par_direction (
-  const FriBidiCharType *bidi_types,   /* input bidi types */
+  const FriBidiCharType *bidi_types,   /* input list of bidi types as returned by
+                                          fribidi_get_bidi_types() */
   const FriBidiStrIndex len    /* input string length */
 );
 
@@ -85,7 +86,8 @@ FRIBIDI_ENTRY FriBidiParType fribidi_get_par_direction (
  */
 FRIBIDI_ENTRY FriBidiLevel
 fribidi_get_par_embedding_levels (
-  const FriBidiCharType *bidi_types,   /* input bidi types */
+  const FriBidiCharType *bidi_types,   /* input list of bidi types as returned by
+                                          fribidi_get_bidi_types() */
   const FriBidiStrIndex len,   /* input string length of the paragraph */
   FriBidiParType *pbase_dir,   /* requested and resolved paragraph
                                 * base direction */
@@ -118,12 +120,13 @@ fribidi_get_par_embedding_levels (
  * occured (memory allocation failure most probably).
  */
      FRIBIDI_ENTRY FriBidiLevel fribidi_reorder_line (
-  const FriBidiCharType *bidi_types,   /* input bidi types */
+  const FriBidiCharType *bidi_types,   /* input list of bidi types as returned by
+                                          fribidi_get_bidi_types() */
   const FriBidiStrIndex len,   /* input length of the line */
   const FriBidiStrIndex off,   /* input offset of the beginning of the line
                                   in the paragraph */
   const FriBidiParType base_dir,       /* resolved paragraph base direction */
-  FriBidiLevel *embedding_levels,      /* list of embedding levels,
+  FriBidiLevel *embedding_levels,      /* input list of embedding levels,
                                           as returned by
                                           fribidi_get_par_embedding_levels */
   FriBidiChar *visual_str,     /* visual string to reorder */
index 9935d9f355e0aa4f89ad08a67c634348c0896fbf..e1edb6b5b3ed8dca6c184dd3c2959fa9e3e3c970 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi-joining-types.h - character joining types
  *
- * $Id: fribidi-joining-types.h,v 1.3 2004-06-15 11:52:02 behdad Exp $
+ * $Id: fribidi-joining-types.h,v 1.4 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-15 11:52:02 $
- * $Revision: 1.3 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.4 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-joining-types.h,v $
  *
  * Author:
@@ -98,12 +98,12 @@ typedef enum _FriBidiJoiningTypeEnum FriBidiJoiningType;
 typedef fribidi_uint8 FriBidiJoiningType;
 #endif /* !__FRIBIDI_DOC */
 
-/* FriBidiArabicProps is essentially the same type as FriBidiJoiningType, but
+/* FriBidiArabicProp is essentially the same type as FriBidiJoiningType, but
  * not limited to the few values returned by fribidi_get_joining_type. */
-typedef fribidi_uint8 FriBidiArabicProps;
+typedef fribidi_uint8 FriBidiArabicProp;
 
 /*
- * The equivalent of JoiningType values for ArabicProps
+ * The equivalent of JoiningType values for ArabicProp
  */
 
 /* Primary Arabic Joining Classes (Table 8-2) */
@@ -184,6 +184,12 @@ typedef fribidi_uint8 FriBidiArabicProps;
 #define FRIBIDI_IS_JOIN_SKIPPED(p)     \
        ((p) & (FRIBIDI_MASK_TRANSPARENT | FRIBIDI_MASK_IGNORED))
 
+/* Is base that will be shaped: R, D, L? */
+#define FRIBIDI_IS_JOIN_BASE_SHAPES(p) \
+       ( FRIBIDI_MASK_ARAB_SHAPES == ( (p) &   \
+               ( FRIBIDI_MASK_TRANSPARENT | FRIBIDI_MASK_IGNORED       \
+               | FRIBIDI_MASK_ARAB_SHAPES ) ) )
+
 #define FRIBIDI_JOINS_PRECEDING_MASK(level)    \
        (FRIBIDI_LEVEL_IS_RTL (level) ? FRIBIDI_MASK_JOINS_RIGHT        \
                                      : FRIBIDI_MASK_JOINS_LEFT)
index fea9ba820e59102c9c6bf9deff3c97d36302b8c0..a9ac5d235d21213cf0f5b34944a19ca1c837e410 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi-joining.h - Arabic joining algorithm
  *
- * $Id: fribidi-joining.c,v 1.3 2004-06-21 18:49:23 behdad Exp $
+ * $Id: fribidi-joining.c,v 1.4 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-21 18:49:23 $
- * $Revision: 1.3 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.4 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-joining.c,v $
  *
  * Authors:
@@ -40,6 +40,7 @@
 
 #include "mem.h"
 #include "env.h"
+#include "bidi-types.h"
 #include "joining-types.h"
 
 #if DEBUG
@@ -69,23 +70,22 @@ print_joining_types (
 }
 #endif /* DEBUG */
 
+#define FRIBIDI_CONSISTENT_LEVEL(i)    \
+       (FRIBIDI_IS_EXPLICIT_OR_BN (bidi_types[(i)])    \
+        ? FRIBIDI_SENTINEL     \
+        : embedding_levels[(i)])
 
-#if FRIBIDI_JOIN_WITHIN_RUN_LEVEL
-/* Join within same level run (to be proposed for inclusion in Unicode 4.1) */
-# define FRIBIDI_JOINING_RUN(l) (l)
-#else /* !FRIBIDI_JOIN_WITHIN_RUN_LEVEL */
-/* Join within same directional run (current rule in Unicode 4.0.1) */
-# define FRIBIDI_JOINING_RUN(l) FRIBIDI_LEVEL_IS_RTL(l)
-#endif /* !FRIBIDI_JOIN_WITHIN_RUN_LEVEL */
-
+#define FRIBIDI_LEVELS_MATCH(i, j)     \
+       ((i) == (j) || (i) == FRIBIDI_SENTINEL || (j) == FRIBIDI_SENTINEL)
 
 FRIBIDI_ENTRY void
 fribidi_join_arabic (
   /* input */
-  const FriBidiLevel *embedding_levels,
+  const FriBidiCharType *bidi_types,
   const FriBidiStrIndex len,
+  const FriBidiLevel *embedding_levels,
   /* input and output */
-  FriBidiArabicProps *ar_props
+  FriBidiArabicProp *ar_props
 )
 {
   if UNLIKELY
@@ -93,6 +93,7 @@ fribidi_join_arabic (
 
   DBG ("in fribidi_join_arabic");
 
+  fribidi_assert (bidi_types);
   fribidi_assert (embedding_levels);
   fribidi_assert (ar_props);
 
@@ -104,52 +105,76 @@ fribidi_join_arabic (
     }
 # endif        /* DEBUG */
 
+  /* The joining algorithm turned out very very dirty :(.  That's what happens
+   * when you follow the standard which has never been implemented closely
+   * before.  We assume "level run" instead of "directional run", which is a
+   * proposed update to be considered for Unicode 4.1. */
+
   /* 8.2 Arabic - Cursive Joining */
   DBG ("Arabic cursive joining");
   {
-    register FriBidiStrIndex i = 0;
+    /* The following do not need to be initialized as long as joins is
+     * initialized to false.  We just do to turn off compiler warnings. */
+    register FriBidiStrIndex saved = 0;
+    register FriBidiLevel saved_level = FRIBIDI_SENTINEL;
+    register fribidi_boolean saved_shapes = false;
+    register FriBidiArabicProp saved_joins_following_mask = 0;
+
+    register fribidi_boolean joins = false;
+    register FriBidiStrIndex i;
 
     for (i = 0; i < len; i++)
-      {
-       register FriBidiStrIndex saved = i;
-       register const FriBidiLevel direction =
-         FRIBIDI_LEVEL_IS_RTL (embedding_levels[i]);
-       register const FriBidiArabicProps joins_preceding_mask =
-         FRIBIDI_JOINS_PRECEDING_MASK (direction);
-       register const FriBidiArabicProps joins_following_mask =
-         FRIBIDI_JOINS_FOLLOWING_MASK (direction);
-       register fribidi_boolean joins = false;
-
-       /* Sweep over directional runs */
-       for (;
-            i < len
-            && FRIBIDI_LEVEL_IS_RTL (embedding_levels[i]) == direction; i++)
-         {
-           /* R1. Transparent chars are skipped (and so do iGnored chars) */
-           if (FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
-             continue;
-
-           /* R2..R7. */
-           if (!joins)
-             FRIBIDI_UNSET_BITS (ar_props[i], joins_preceding_mask);
-           else if (!FRIBIDI_TEST_BITS (ar_props[i], joins_preceding_mask))
-             FRIBIDI_UNSET_BITS (ar_props[saved], joins_following_mask);
-           else
-             {
-               /* This is a FriBidi extension:  we set joining properties
-                * for skipped characters in between. */
-               for (saved++; saved < i; saved++)
-                 FRIBIDI_SET_BITS (ar_props[saved],
-                                   joins_preceding_mask |
-                                   joins_following_mask);
-             }
-
-           joins = FRIBIDI_TEST_BITS (ar_props[i], joins_following_mask);
-           saved = i;
-         }
-       FRIBIDI_UNSET_BITS (ar_props[saved], joins_following_mask);
-       i--;
-      }
+      if (!FRIBIDI_IS_JOINING_TYPE_G (ar_props[i]))
+       {
+         register fribidi_boolean disjoin = false;
+         register fribidi_boolean shapes = FRIBIDI_ARAB_SHAPES (ar_props[i]);
+         register FriBidiLevel level = FRIBIDI_CONSISTENT_LEVEL (i);
+
+         if (joins && !FRIBIDI_LEVELS_MATCH (saved_level, level))
+           {
+             disjoin = true;
+             joins = false;
+           }
+
+         if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
+           {
+             register const FriBidiArabicProp joins_preceding_mask =
+               FRIBIDI_JOINS_PRECEDING_MASK (level);
+
+             if (!joins)
+               {
+                 if (shapes)
+                   FRIBIDI_UNSET_BITS (ar_props[i], joins_preceding_mask);
+               }
+             else if (!FRIBIDI_TEST_BITS (ar_props[i], joins_preceding_mask))
+               disjoin = true;
+           }
+
+         if (disjoin && saved_shapes)
+           FRIBIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);
+
+         if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
+           {
+             saved = i;
+             saved_level = level;
+             saved_shapes = shapes;
+             saved_joins_following_mask =
+               FRIBIDI_JOINS_FOLLOWING_MASK (level);
+             joins =
+               FRIBIDI_TEST_BITS (ar_props[i], saved_joins_following_mask);
+           }
+       }
+    if (joins && saved_shapes)
+      FRIBIDI_UNSET_BITS (ar_props[saved], saved_joins_following_mask);
+
+    /* if joining on transparents then... */
+    /* This is a FriBidi extension:  we set joining properties
+     * for skipped characters in between. 
+     for (saved++; saved < i; saved++)
+     FRIBIDI_SET_BITS (ar_props[saved],
+     joins_preceding_mask |
+     joins_following_mask);
+     */
   }
 
 # if DEBUG
index a341d329300639834ec818519ac06784b00cb54f..09b123c7caf3861881bac4f49c59740c9c1940ef 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi-joining.h - Arabic joining algorithm
  *
- * $Id: fribidi-joining.h,v 1.2 2004-06-15 11:52:02 behdad Exp $
+ * $Id: fribidi-joining.h,v 1.3 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-15 11:52:02 $
- * $Revision: 1.2 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.3 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-joining.h,v $
  *
  * Authors:
@@ -46,7 +46,7 @@
  *
  * This function does the Arabic joining algorithm.  Means, given Arabic
  * joining types of the characters in ar_props (don't worry,
- * FriBidiJoiningType can be casted to FriBidiArabicProps automagically), this
+ * FriBidiJoiningType can be casted to FriBidiArabicProp automagically), this
  * function modifies this properties to grasp the effect of neighboring
  * characters.  You probably need this information later to do Arabic shaping.
  *
  * Arabic properties computed by this function.
  */
 FRIBIDI_ENTRY void fribidi_join_arabic (
+  const FriBidiCharType *bidi_types,   /* input list of bidi types as
+                                          returned by
+                                          fribidi_get_bidi_types() */
+  const FriBidiStrIndex len,   /* input string length */
   const FriBidiLevel *embedding_levels,        /* input list of embedding
                                           levels, as returned by
                                           fribidi_get_par_embedding_levels */
-  const FriBidiStrIndex len,   /* input string length */
-  FriBidiArabicProps *ar_props /* Arabic properties to analyze, initilized by
+  FriBidiArabicProp *ar_props  /* Arabic properties to analyze, initilized by
                                   joining types, as returned by
                                   fribidi_get_joining_types */
 );
index e77da2e90fcf1a665434619792a1e6abbefee01c..0cb2a4f1af608aec24314faa549e25cfa2542311 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi-unicode.h - general Unicode definitions
  *
- * $Id: fribidi-unicode.h,v 1.4 2004-06-21 18:49:23 behdad Exp $
+ * $Id: fribidi-unicode.h,v 1.5 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-21 18:49:23 $
- * $Revision: 1.4 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.5 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi-unicode.h,v $
  *
  * Author:
@@ -66,13 +66,7 @@ extern const char *fribidi_unicode_version;
 #define FRIBIDI_BIDI_MAX_RESOLVED_LEVELS       63
 
 
-/* Unicode Arabic joining/shaping definitions: */
-
-/* Unicode 4.0.1: join within "directional run", not "level run". */
-#undef FRIBIDI_JOIN_WITHIN_RUN_LEVEL
-
-
-/* A few Unicode characters */
+/* A few Unicode characters: */
 
 /* Bidirectional marks */
 #define FRIBIDI_CHAR_LRM               0x200E
index 4b92dcad6f2f4f8300bf27b3758f7ae6ec3ff6b8..c50511954fddaead6ad2ebffc29b1cfab4a1dcda 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi.c - Unicode bidirectional and Arabic joining/shaping algorithms
  *
- * $Id: fribidi.c,v 1.14 2004-06-21 18:49:23 behdad Exp $
+ * $Id: fribidi.c,v 1.15 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-21 18:49:23 $
- * $Revision: 1.14 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.15 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi.c,v $
  *
  * Authors:
@@ -145,7 +145,7 @@ fribidi_log2vis (
   fribidi_boolean private_V_to_L = false;
   fribidi_boolean private_embedding_levels = false;
   fribidi_boolean status = false;
-  FriBidiArabicProps *ar_props = NULL;
+  FriBidiArabicProp *ar_props = NULL;
   FriBidiCharType *bidi_types = NULL;
 
   if UNLIKELY
@@ -190,7 +190,7 @@ fribidi_log2vis (
       /* Arabic joining */
       ar_props = fribidi_malloc (len * sizeof ar_props[0]);
       fribidi_get_joining_types (str, len, ar_props);
-      fribidi_join_arabic (embedding_levels, len, ar_props);
+      fribidi_join_arabic (bidi_types, len, embedding_levels, ar_props);
 #endif /* !FRIBIDI_NO_ARABIC */
 
       fribidi_shape (embedding_levels, len, visual_str);
index cbdfbec696ffaf85297bef28bf6c628fb647c66f..13fdbf2b45f483cc448e7634fce2a703b05a98ca 100644 (file)
@@ -1,10 +1,10 @@
 /* FriBidi
  * fribidi.h - Unicode bidirectional and Arabic joining/shaping algorithms
  *
- * $Id: fribidi.h,v 1.7 2004-06-15 11:52:02 behdad Exp $
+ * $Id: fribidi.h,v 1.8 2004-06-21 21:15:31 behdad Exp $
  * $Author: behdad $
- * $Date: 2004-06-15 11:52:02 $
- * $Revision: 1.7 $
+ * $Date: 2004-06-21 21:15:31 $
+ * $Revision: 1.8 $
  * $Source: /home/behdad/src/fdo/fribidi/togit/git/../fribidi/fribidi2/lib/fribidi.h,v $
  *
  * Author:
@@ -42,7 +42,7 @@
 #include "fribidi-joining-types.h"
 #include "fribidi-joining.h"
 #else
-typedef void FriBidiJoiningType typedef void FriBidiArabicProps
+typedef void FriBidiJoiningType typedef void FriBidiArabicProp
 #endif                         /* !FRIBIDI_NO_ARABIC */
 #if FRIBIDI_CHARSETS
 # include "fribidi-char-sets.h"