[FriBidi-commit] fribidi/lib fribidi-bidi.h, 1.13, 1.14 fribidi-joining-types.h, 1.3, 1.4 fribidi-joining.c, 1.3, 1.4 fribidi-joining.h, 1.2, 1.3 fribidi-unicode.h, 1.4, 1.5 fribidi.c, 1.14, 1.15 fribidi.h, 1.7, 1.8

Behdad Esfahbod behdad at pdx.freedesktop.org
Mon Jun 21 14:15:33 PDT 2004


Update of /cvs/fribidi/fribidi/lib
In directory pdx:/tmp/cvs-serv8054/lib

Modified Files:
	fribidi-bidi.h fribidi-joining-types.h fribidi-joining.c 
	fribidi-joining.h fribidi-unicode.h fribidi.c fribidi.h 
Log Message:
Reimplemented Arabic joining.  Hopefullly it's conforming to the standard now,
with the exception that we assume "level run" instead of "directional run",
which is a proposed changed to be applied for Unicode 4.1.


Index: fribidi-bidi.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-bidi.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- fribidi-bidi.h	21 Jun 2004 18:49:23 -0000	1.13
+++ fribidi-bidi.h	21 Jun 2004 21:15:31 -0000	1.14
@@ -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 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 @@
  * 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: fribidi-joining-types.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-joining-types.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- fribidi-joining-types.h	15 Jun 2004 11:52:02 -0000	1.3
+++ fribidi-joining-types.h	21 Jun 2004 21:15:31 -0000	1.4
@@ -98,12 +98,12 @@
 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 @@
 #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: fribidi-joining.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-joining.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- fribidi-joining.c	21 Jun 2004 18:49:23 -0000	1.3
+++ fribidi-joining.c	21 Jun 2004 21:15:31 -0000	1.4
@@ -40,6 +40,7 @@
 
 #include "mem.h"
 #include "env.h"
+#include "bidi-types.h"
 #include "joining-types.h"
 
 #if DEBUG
@@ -69,23 +70,22 @@
 }
 #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 @@
 
   DBG ("in fribidi_join_arabic");
 
+  fribidi_assert (bidi_types);
   fribidi_assert (embedding_levels);
   fribidi_assert (ar_props);
 
@@ -104,52 +105,76 @@
     }
 # 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;
+      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);
 
-	/* 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;
+	  if (joins && !FRIBIDI_LEVELS_MATCH (saved_level, level))
+	    {
+	      disjoin = true;
+	      joins = false;
+	    }
 
-	    /* 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);
-	      }
+	  if (!FRIBIDI_IS_JOIN_SKIPPED (ar_props[i]))
+	    {
+	      register const FriBidiArabicProp joins_preceding_mask =
+		FRIBIDI_JOINS_PRECEDING_MASK (level);
 
-	    joins = FRIBIDI_TEST_BITS (ar_props[i], joins_following_mask);
-	    saved = i;
-	  }
-	FRIBIDI_UNSET_BITS (ar_props[saved], joins_following_mask);
-	i--;
-      }
+	      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: fribidi-joining.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-joining.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- fribidi-joining.h	15 Jun 2004 11:52:02 -0000	1.2
+++ fribidi-joining.h	21 Jun 2004 21:15:31 -0000	1.3
@@ -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.
  *
@@ -61,11 +61,14 @@
  * 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: fribidi-unicode.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi-unicode.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- fribidi-unicode.h	21 Jun 2004 18:49:23 -0000	1.4
+++ fribidi-unicode.h	21 Jun 2004 21:15:31 -0000	1.5
@@ -66,13 +66,7 @@
 #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: fribidi.c
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- fribidi.c	21 Jun 2004 18:49:23 -0000	1.14
+++ fribidi.c	21 Jun 2004 21:15:31 -0000	1.15
@@ -145,7 +145,7 @@
   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 @@
       /* 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: fribidi.h
===================================================================
RCS file: /cvs/fribidi/fribidi/lib/fribidi.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- fribidi.h	15 Jun 2004 11:52:02 -0000	1.7
+++ fribidi.h	21 Jun 2004 21:15:31 -0000	1.8
@@ -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"




More information about the FriBidi-Commit mailing list