diff options
author | Owen Taylor <otaylor@redhat.com> | 2001-04-13 19:03:26 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2001-04-13 19:03:26 +0000 |
commit | f8dd42e8d90e924975b50a4f45d3ef5a15a10d3d (patch) | |
tree | c892aa8937a40e17f7a3eb4513e0c7ea427c62ca | |
parent | 6f2bd3ee69d5a79e5d7806ad91782c0743aa328c (diff) | |
download | pango-f8dd42e8d90e924975b50a4f45d3ef5a15a10d3d.tar.gz |
Update to correspond to FriBidi-0.9.0 (with some small fixes)
Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com>
* pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}:
Update to correspond to FriBidi-0.9.0 (with some small fixes)
* pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for
Fribidi-0.9.0.
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | ChangeLog.pre-1-0 | 8 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 8 | ||||
-rw-r--r-- | ChangeLog.pre-1-2 | 8 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 8 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 8 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 8 | ||||
-rw-r--r-- | pango/mini-fribidi/Makefile.am | 2 | ||||
-rw-r--r-- | pango/mini-fribidi/fribidi-0.1.12.patch | 441 | ||||
-rw-r--r-- | pango/mini-fribidi/fribidi-0.9.0.patch | 375 | ||||
-rw-r--r-- | pango/mini-fribidi/fribidi.c | 1286 | ||||
-rw-r--r-- | pango/mini-fribidi/fribidi_get_type.c | 114 | ||||
-rw-r--r-- | pango/mini-fribidi/fribidi_tables.i | 208 | ||||
-rw-r--r-- | pango/mini-fribidi/fribidi_types.h | 337 |
14 files changed, 1852 insertions, 967 deletions
@@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index dc4af043..0e4e4fb4 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index dc4af043..0e4e4fb4 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index dc4af043..0e4e4fb4 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index dc4af043..0e4e4fb4 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index dc4af043..0e4e4fb4 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index dc4af043..0e4e4fb4 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,11 @@ +Fri Apr 13 14:55:20 2001 Owen Taylor <otaylor@redhat.com> + + * pango/mini-fribidi/{fribidi.c,fribidi_get_type.c,fribidi_tables.i}: + Update to correspond to FriBidi-0.9.0 (with some small fixes) + + * pango/mini-fribidi/fribidi-0.9.0.patch: Update patch for + Fribidi-0.9.0. + 2001-04-13 Havoc Pennington <hp@redhat.com> * pango/pango-font.h: Add macros for CSS font scale factors diff --git a/pango/mini-fribidi/Makefile.am b/pango/mini-fribidi/Makefile.am index 98b22e36..1afd6635 100644 --- a/pango/mini-fribidi/Makefile.am +++ b/pango/mini-fribidi/Makefile.am @@ -23,4 +23,4 @@ EXTRA_DIST = \ README \ makefile.mingw \ fribidi_tables.i \ - fribidi-0.1.12.patch + fribidi-0.9.0.patch diff --git a/pango/mini-fribidi/fribidi-0.1.12.patch b/pango/mini-fribidi/fribidi-0.1.12.patch deleted file mode 100644 index b6f30428..00000000 --- a/pango/mini-fribidi/fribidi-0.1.12.patch +++ /dev/null @@ -1,441 +0,0 @@ ---- /home/otaylor/ftp/fribidi-0.1.12/fribidi.c Sat Jul 22 10:33:30 2000 -+++ fribidi.c Sun Nov 12 15:12:09 2000 -@@ -17,8 +17,8 @@ - * Boston, MA 02111-1307, USA. - */ - #include <glib.h> --#include <stdio.h> --#include "fribidi.h" -+#include "pango/pango-utils.h" -+#include "fribidi_types.h" - - /*====================================================================== - // Typedef for the run-length list. -@@ -39,47 +39,6 @@ - FriBidiChar value; - } key_value_t; - --/* Global variables */ --gboolean fribidi_debug = FALSE; -- --void fribidi_set_debug(gboolean debug) --{ -- fribidi_debug = debug; --} -- --static int bidi_string_strlen(FriBidiChar *str) --{ -- int len = 0; -- -- while(*str++) -- len++; -- -- return len; --} -- --static void bidi_string_reverse(FriBidiChar *str, gint len) --{ -- int i; -- for (i=0; i<len/2; i++) -- { -- FriBidiChar tmp = str[i]; -- str[i] = str[len-1-i]; -- str[len-1-i] = tmp; -- } --} -- --static void --int16_array_reverse(gint16 *arr, gint len) --{ -- int i; -- for (i=0; i<len/2; i++) -- { -- gint tmp = arr[i]; -- arr[i] = arr[len-1-i]; -- arr[len-1-i] = tmp; -- } --} -- - static TypeLink *free_type_links = NULL; - - static TypeLink *new_type_link() -@@ -240,103 +199,6 @@ - } - - /*====================================================================== --// For debugging, define some macros for printing the types and the --// levels. --//----------------------------------------------------------------------*/ --static void print_types_re(TypeLink *pp) --{ -- while(pp) -- { -- printf("%d:%c(%d)[%d] ", RL_POS(pp), RL_TYPE(pp), RL_LEN(pp), RL_LEVEL(pp)); -- pp = pp->next; -- } -- printf("\n"); --} -- --static void print_resolved_levels(TypeLink *pp) --{ -- while(pp) -- { -- int i; -- for (i=0; i<RL_LEN(pp); i++) -- printf("%d", RL_LEVEL(pp)); -- pp = pp->next; -- } -- printf("\n"); --} -- --static void print_resolved_types(TypeLink *pp) --{ -- while(pp) -- { -- int i; -- for (i=0; i<RL_LEN(pp); i++) -- { -- gchar ch; -- FriBidiCharType type = RL_TYPE(pp); -- -- /* Convert the type to something readable */ -- if (type == FRIBIDI_TYPE_R) -- ch = 'R'; -- else if (type == FRIBIDI_TYPE_L) -- ch = 'L'; -- else if (type == FRIBIDI_TYPE_E) -- ch = 'E'; -- else if (type == FRIBIDI_TYPE_EN) -- ch = 'n'; -- else if (type == FRIBIDI_TYPE_N) -- ch = 'N'; -- else -- ch = '?'; -- -- printf("%c", ch); -- } -- pp = pp->next; -- } -- printf("\n"); --} -- --static void print_bidi_string(FriBidiChar *str) --{ -- int i; -- for (i=0; i<bidi_string_strlen(str); i++) -- printf("%c", str[i]); -- printf("\n"); --} -- --/*====================================================================== --// search_rl_for strong searches the run length list in the direction --// indicated by dir for a strong directional. It returns a pointer to --// the found character or NULL if none is found. */ --//----------------------------------------------------------------------*/ --static TypeLink * --search_rl_for_strong(TypeLink *pos, -- gint dir) --{ -- TypeLink *pp = pos; -- -- if (dir == -1) -- { -- for (pp = pos; pp; pp=pp->prev) -- { -- FriBidiCharType char_type = RL_TYPE(pp); -- if (char_type == FRIBIDI_TYPE_R || char_type == FRIBIDI_TYPE_L) -- return pp; -- } -- } -- else -- { -- for (pp = pos; pp; pp=pp->next) -- { -- FriBidiCharType char_type = RL_TYPE(pp); -- if (char_type == FRIBIDI_TYPE_R || char_type == FRIBIDI_TYPE_L) -- return pp; -- } -- } -- return NULL; --} -- --/*====================================================================== - // This function should follow the Unicode specification closely! - // - // It is still lacking the support for <RLO> and <LRO>. -@@ -360,7 +222,7 @@ - /* Determinate character types */ - char_type = g_new(gint, len); - for (i=0; i<len; i++) -- char_type[i] = fribidi_get_type(str[i]); -+ char_type[i] = _pango_fribidi_get_type (str[i]); - - /* Run length encode the character types */ - type_rl_list = run_length_encode_types(char_type, len); -@@ -511,8 +373,6 @@ - compact_list(type_rl_list); - - /* 5. Resolving Neutral Types */ -- if (fribidi_debug) -- fprintf(stderr,"Resolving neutral types.\n"); - - /* We can now collapse all separators and other neutral types to - plain neutrals */ -@@ -559,12 +419,8 @@ - } - - compact_list(type_rl_list); -- if (fribidi_debug) -- print_types_re(type_rl_list); - - /* 6. Resolving Implicit levels */ -- if (fribidi_debug) -- fprintf(stderr,"Resolving implicit levels.\n"); - { - int level = base_level; - max_level = base_level; -@@ -605,13 +461,6 @@ - - compact_list(type_rl_list); - -- if (fribidi_debug) -- { -- print_bidi_string(str); -- print_resolved_levels(type_rl_list); -- print_resolved_types(type_rl_list); -- } -- - *ptype_rl_list = type_rl_list; - *pmax_level = max_level; - *pbase_dir = base_dir; -@@ -622,160 +471,26 @@ - //----------------------------------------------------------------------*/ - - /*====================================================================== --// fribidi_log2vis() calls the function_analyse_string() and then --// does reordering and fills in the output strings. --//----------------------------------------------------------------------*/ --void fribidi_log2vis(/* input */ -- FriBidiChar *str, -- gint len, -- FriBidiCharType *pbase_dir, -- /* output */ -- FriBidiChar *visual_str, -- guint16 *position_L_to_V_list, -- guint16 *position_V_to_L_list, -- guint8 *embedding_level_list -- ) --{ -- TypeLink *type_rl_list, *pp = NULL; -- int max_level; -- gboolean private_L_to_V = FALSE; -- -- /* If v2l is to be calculated we must have l2v as well. If it is not -- given by the caller, we have to make a private instance of it. */ -- if (position_V_to_L_list && !position_L_to_V_list) -- { -- private_L_to_V++; -- position_L_to_V_list = g_new(guint16, len+1); -- } -- -- if (len > (2L<<16)-1) -- { -- fprintf(stderr, "Fribidi can't handle strings > 65000 chars!\n"); -- return; -- } -- fribidi_analyse_string(str, len, pbase_dir, -- /* output */ -- &type_rl_list, -- &max_level); -- -- /* 7. Reordering resolved levels */ -- if (fribidi_debug) -- fprintf(stderr, "Reordering.\n"); -- -- { -- int level_idx; -- int i; -- -- /* Set up the ordering array to sorted order and copy the logical -- string to the visual */ -- if (position_L_to_V_list) -- for (i=0; i<len+1; i++) -- position_L_to_V_list[i]=i; -- -- if (visual_str) -- for (i=0; i<len+1; i++) -- visual_str[i] = str[i]; -- -- /* Assign the embedding level array */ -- if (embedding_level_list) -- for (pp = type_rl_list->next; pp->next; pp = pp->next) -- { -- int i; -- int pos = RL_POS(pp); -- int len = RL_LEN(pp); -- int level = RL_LEVEL(pp); -- for (i=0; i<len; i++) -- embedding_level_list[pos + i] = level; -- } -- -- /* Reorder both the outstring and the order array*/ -- if (visual_str || position_L_to_V_list) -- { -- -- if (visual_str) -- /* Mirror all characters that are in odd levels and have mirrors */ -- for (pp = type_rl_list->next; pp->next; pp = pp->next) -- { -- if (RL_LEVEL(pp) % 2 == 1) -- { -- int i; -- for (i=RL_POS(pp); i<RL_POS(pp)+RL_LEN(pp); i++) -- { -- FriBidiChar mirrored_ch; -- if (fribidi_get_mirror_char(visual_str[i], &mirrored_ch)) -- visual_str[i] = mirrored_ch; -- } -- } -- } -- -- /* Reorder */ -- for (level_idx = max_level; level_idx>0; level_idx--) -- { -- for (pp = type_rl_list->next; pp->next; pp = pp->next) -- { -- if (RL_LEVEL(pp) >= level_idx) -- { -- /* Find all stretches that are >= level_idx */ -- int len = RL_LEN(pp); -- int pos = RL_POS(pp); -- TypeLink *pp1 = pp->next; -- while(pp1->next && RL_LEVEL(pp1) >= level_idx) -- { -- len+= RL_LEN(pp1); -- pp1 = pp1->next; -- } -- -- pp = pp1->prev; -- if (visual_str) -- bidi_string_reverse(visual_str+pos, len); -- if (position_L_to_V_list) -- int16_array_reverse(position_L_to_V_list+pos, len); -- -- } -- } -- } -- } -- -- /* Convert the l2v list to v2l */ -- if (position_V_to_L_list && position_L_to_V_list) -- for (i=0; i<len; i++) -- position_V_to_L_list[position_L_to_V_list[i]] = i; -- } -- -- /* Free up the rl_list */ -- -- /* At this point, pp points to the last link or (rarely) might be NULL -- */ -- if (!pp) -- for (pp = type_rl_list->next; pp->next; pp = pp->next) -- /* Nothing */; -- -- pp->next = free_type_links; -- free_type_links = type_rl_list; -- -- /* Free up L_to_V if we allocated it */ -- if (private_L_to_V) -- g_free(position_L_to_V_list); -- --} -- --/*====================================================================== - // fribidi_embedding_levels() is used in order to just get the - // embedding levels. - //----------------------------------------------------------------------*/ --void fribidi_log2vis_get_embedding_levels( -+void -+pango_log2vis_get_embedding_levels( - /* input */ -- FriBidiChar *str, -+ gunichar *str, - int len, -- FriBidiCharType *pbase_dir, -+ PangoDirection *pbase_dir, - /* output */ - guint8 *embedding_level_list - ) - { - TypeLink *type_rl_list, *pp; - int max_level; -+ FriBidiCharType fribidi_base_dir; -+ -+ fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ? FRIBIDI_TYPE_L : FRIBIDI_TYPE_R; - -- fribidi_analyse_string(str, len, pbase_dir, -+ fribidi_analyse_string(str, len, &fribidi_base_dir, - /* output */ - &type_rl_list, - &max_level); -@@ -793,5 +508,7 @@ - /* Free up the rl_list */ - pp->next = free_type_links; - free_type_links = type_rl_list; -+ -+ *pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; - } - ---- /home/otaylor/ftp/fribidi-0.1.12/fribidi_get_type.c Fri May 19 05:36:54 2000 -+++ fribidi_get_type.c Sun Nov 12 14:42:56 2000 -@@ -18,13 +18,14 @@ - */ - #include <stdio.h> - #include <stdlib.h> --#include "fribidi.h" -+#include "pango/pango-utils.h" -+#include "fribidi_types.h" - #include "fribidi_tables.i" - - /*====================================================================== - // fribidi_get_type() returns the bidi type of a character. - //----------------------------------------------------------------------*/ --FriBidiCharType fribidi_get_type(FriBidiChar uch) -+FriBidiCharType _pango_fribidi_get_type(FriBidiChar uch) - { - guchar *block = FriBidiPropertyBlocks[uch / 256]; - if (block) -@@ -34,10 +35,10 @@ - } - - gboolean --fribidi_get_mirror_char(/* Input */ -- FriBidiChar ch, -- /* Output */ -- FriBidiChar *mirrored_ch) -+pango_get_mirror_char(/* Input */ -+ gunichar ch, -+ /* Output */ -+ gunichar *mirrored_ch) - { - int pos, step; - gboolean found = FALSE; ---- /home/otaylor/ftp/fribidi-0.1.12/fribidi_tables.i Fri May 19 05:12:01 2000 -+++ fribidi_tables.i Sun Nov 12 15:07:10 2000 -@@ -3,8 +3,6 @@ - // by the perl script CreateGetType.pl. - //----------------------------------------------------------------------*/ - --#include "fribidi.h" -- - #define LTR FRIBIDI_TYPE_LTR - #define RTL FRIBIDI_TYPE_RTL - #define EN FRIBIDI_TYPE_EN ---- /home/otaylor/ftp/fribidi-0.1.12/fribidi_types.h Fri May 19 05:07:48 2000 -+++ fribidi_types.h Sun Nov 12 14:40:58 2000 -@@ -96,4 +96,6 @@ - void *attribute; - } FriBidiRunType; - -+FriBidiCharType _pango_fribidi_get_type(FriBidiChar uch); -+ - #endif diff --git a/pango/mini-fribidi/fribidi-0.9.0.patch b/pango/mini-fribidi/fribidi-0.9.0.patch new file mode 100644 index 00000000..6611cf5a --- /dev/null +++ b/pango/mini-fribidi/fribidi-0.9.0.patch @@ -0,0 +1,375 @@ +--- /home/otaylor/fribidi-0.9.0/fribidi.c Wed Mar 28 01:55:42 2001 ++++ ./fribidi.c Fri Apr 13 14:26:35 2001 +@@ -20,9 +20,13 @@ + * For licensing issues, contact <dov@imagic.weizmann.ac.il> and + * <fwpg@sharif.edu>. + */ +- +-#include "fribidi.h" +-#include "config.h" ++ ++#include <glib.h> ++#include "pango/pango-utils.h" ++#include "fribidi_types.h" ++ ++#undef DEBUG ++ + #ifdef DEBUG + #include <stdio.h> + #endif +@@ -87,6 +91,7 @@ + #endif + } + ++#ifdef DEBUG + static gint + bidi_string_strlen (FriBidiChar * str) + { +@@ -97,30 +102,7 @@ + + return len; + } +- +-static void +-bidi_string_reverse (FriBidiChar * str, gint len) +-{ +- gint i; +- for (i = 0; i < len / 2; i++) +- { +- FriBidiChar tmp = str[i]; +- str[i] = str[len - 1 - i]; +- str[len - 1 - i] = tmp; +- } +-} +- +-static void +-index_array_reverse (FriBidiStrIndex * arr, gint len) +-{ +- gint i; +- for (i = 0; i < len / 2; i++) +- { +- FriBidiStrIndex tmp = arr[i]; +- arr[i] = arr[len - 1 - i]; +- arr[len - 1 - i] = tmp; +- } +-} ++#endif + + #ifndef USE_SIMPLE_MALLOC + static TypeLink *free_type_links = NULL; +@@ -231,7 +213,7 @@ + codes that are removed from rl_list, to reinsert them later by calling + the override_list. + */ +-static void * ++static void + init_list (TypeLink ** start, TypeLink ** end) + { + TypeLink *list = NULL; +@@ -601,7 +583,7 @@ + fprintf (stderr, "Org. types : "); + for (i = 0; i < bidi_string_strlen (str); i++) + fprintf (stderr, "%c", +- fribidi_char_from_type (fribidi_get_type (str[i]))); ++ fribidi_char_from_type (_pango_fribidi_get_type (str[i]))); + fprintf (stderr, "\n"); + } + #endif +@@ -626,7 +608,7 @@ + /* Determinate character types */ + char_type = g_new (FriBidiCharType, len); + for (i = 0; i < len; i++) +- char_type[i] = fribidi_get_type (str[i]); ++ char_type[i] = _pango_fribidi_get_type (str[i]); + + /* Run length encode the character types */ + type_rl_list = run_length_encode_types (char_type, len); +@@ -812,7 +794,7 @@ + /* Resolving dependency of loops for rules W1 and W2, so we + can merge them in one loop. */ + if (next_type == FRIBIDI_TYPE_NSM) +- RL_TYPE (pp->next) == FRIBIDI_TYPE_AN; ++ RL_TYPE (pp->next) = FRIBIDI_TYPE_AN; + } + } + +@@ -1004,7 +986,7 @@ + pos = len - 1; + for (j = len - 1; j >= 0; j--) + { +- k = fribidi_get_type (str[j]); ++ k = _pango_fribidi_get_type (str[j]); + if (!state && FRIBIDI_IS_SEPARATOR (k)) + { + state = 1; +@@ -1054,7 +1036,7 @@ + { + + TypeLink *p, *pp; +- if (!pp) ++ if (!type_rl_list) + return; + #ifdef USE_SIMPLE_MALLOC + for (pp = type_rl_list; pp; pp = pp->next) +@@ -1089,169 +1071,28 @@ + //----------------------------------------------------------------------*/ + + /*====================================================================== +-// fribidi_remove_explicits() removes explicit marks, and returns the +-// new length. +-//----------------------------------------------------------------------*/ +-gint fribidi_remove_explicits (FriBidiChar * str, gint length) +-{ +- gint i, j; +- +- j = 0; +- for (i = 0; i < length; i++) +- if (!FRIBIDI_IS_EXPLICIT (fribidi_get_type (str[i]))) +- str[j++] = str[i]; +- +- return j; +-} +- +-/*====================================================================== +-// fribidi_log2vis() calls the function_analyse_string() and then +-// does reordering and fills in the output strings. +-//----------------------------------------------------------------------*/ +-void +-fribidi_log2vis ( /* input */ +- FriBidiChar * str, gint len, FriBidiCharType * pbase_dir, +- /* output */ +- FriBidiChar * visual_str, +- FriBidiStrIndex * position_L_to_V_list, +- FriBidiStrIndex * position_V_to_L_list, +- guint8 * embedding_level_list) +-{ +- TypeLink *type_rl_list, *pp = NULL; +- gint max_level; +- gboolean private_V_to_L = FALSE; +- +- if (len == 0) +- return; +- +- /* If l2v is to be calculated we must have l2v as well. If it is not +- given by the caller, we have to make a private instance of it. */ +- if (position_L_to_V_list && !position_V_to_L_list) +- { +- private_V_to_L = TRUE; +- position_V_to_L_list = g_new (FriBidiStrIndex, len + 1); +- } +- +- if (len > FRIBIDI_MAX_STRING_LENGTH && position_V_to_L_list) +- { +-#ifdef DEBUG +- fprintf (stderr, "%s: cannot handle strings > %d characters\n", +- PACKAGE, FRIBIDI_MAX_STRING_LENGTH); +-#endif +- return; +- } +- fribidi_analyse_string (str, len, pbase_dir, +- /* output */ +- &type_rl_list, &max_level); +- +- /* 7. Reordering resolved levels */ +- DBG ("Reordering resolved levels.\n"); +- { +- gint level_idx; +- gint i, j; +- +- /* TBD: L3 */ +- +- /* Set up the ordering array to sorted order */ +- if (position_V_to_L_list) +- for (i = 0; i < len + 1; i++) +- position_V_to_L_list[i] = i; +- /* Copy the logical string to the visual */ +- if (visual_str) +- for (i = 0; i < len + 1; i++) +- visual_str[i] = str[i]; +- +- /* Assign the embedding level array */ +- if (embedding_level_list) +- for (pp = type_rl_list->next; pp->next; pp = pp->next) +- { +- gint i; +- gint pos = RL_POS (pp); +- gint len = RL_LEN (pp); +- gint level = RL_LEVEL (pp); +- for (i = 0; i < len; i++) +- embedding_level_list[pos + i] = level; +- } +- +- /* Reorder both the outstring and the order array */ +- if (visual_str || position_V_to_L_list) +- { +- +- if (mirroring && visual_str) +- /* L4. Mirror all characters that are in odd levels and have mirrors. */ +- for (pp = type_rl_list->next; pp->next; pp = pp->next) +- { +- if (RL_LEVEL (pp) & 1) +- { +- gint i; +- for (i = RL_POS (pp); i < RL_POS (pp) + RL_LEN (pp); i++) +- { +- FriBidiChar mirrored_ch; +- if (fribidi_get_mirror_char +- (visual_str[i], &mirrored_ch)) +- visual_str[i] = mirrored_ch; +- } +- } +- } +- +- /* L2. Reorder. */ +- for (level_idx = max_level; level_idx > 0; level_idx--) +- { +- for (pp = type_rl_list->next; pp->next; pp = pp->next) +- { +- if (RL_LEVEL (pp) >= level_idx) +- { +- /* Find all stretches that are >= level_idx */ +- gint len = RL_LEN (pp); +- gint pos = RL_POS (pp); +- TypeLink *pp1 = pp->next; +- while (pp1->next && RL_LEVEL (pp1) >= level_idx) +- { +- len += RL_LEN (pp1); +- pp1 = pp1->next; +- } +- pp = pp1->prev; +- if (visual_str) +- bidi_string_reverse (visual_str + pos, len); +- if (position_V_to_L_list) +- index_array_reverse (position_V_to_L_list + pos, len); +- } +- } +- } +- } +- +- /* Convert the v2l list to l2v */ +- if (position_L_to_V_list) +- for (i = 0; i < len; i++) +- position_L_to_V_list[position_V_to_L_list[i]] = i; +- } +- +- if (private_V_to_L) +- g_free (position_V_to_L_list); +- +- free_rl_list (type_rl_list); +- +-} +- +-/*====================================================================== + // fribidi_embedding_levels() is used in order to just get the + // embedding levels. + //----------------------------------------------------------------------*/ + void +-fribidi_log2vis_get_embedding_levels ( ++pango_log2vis_get_embedding_levels ( + /* input */ +- FriBidiChar * str, +- gint len, FriBidiCharType * pbase_dir, ++ gunichar * str, ++ int len, ++ PangoDirection *pbase_dir, + /* output */ + guint8 * embedding_level_list) + { + TypeLink *type_rl_list, *pp; + gint max_level; +- +- if (len = 0) ++ FriBidiCharType fribidi_base_dir; ++ ++ fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ? FRIBIDI_TYPE_L : FRIBIDI_TYPE_R; ++ ++ if (len == 0) + return; + +- fribidi_analyse_string (str, len, pbase_dir, ++ fribidi_analyse_string (str, len, &fribidi_base_dir, + /* output */ + &type_rl_list, &max_level); + +@@ -1266,28 +1107,6 @@ + } + + free_rl_list (type_rl_list); ++ ++ *pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; + } +- +-guchar *fribidi_version_info = +- "Copyright (C) 2001 FriBidi Project.\n" +- PACKAGE " comes with NO WARRANTY, to the extent permitted by law.\n" +- "You may redistribute copies of " PACKAGE " under the terms of\n" +- "the GNU General Public License.\n" +- "For more information about these matters, see the files named COPYING.\n" +-#if (defined(MEM_OPTIMIZED) || defined(DEBUG) || defined(USE_SIMPLE_MALLOC) \ +- || defined(FRIBIDI_USE_MINI_GLIB)) +- "This " PACKAGE " is compiled with following options:\n" +-#if (defined(MEM_OPTIMIZED)) +- "MEM_OPTIMIZED\n" +-#endif +-#if (defined(DEBUG)) +- "DEBUG\n" +-#endif +-#if (defined(USE_SIMPLE_MALLOC)) +- "USE_SIMPLE_MALLOC\n" +-#endif +-#if (defined(FRIBIDI_USE_MINI_GLIB)) +- "FRIBIDI_USE_MINI_GLIB\n" +-#endif +-#endif +- ; +--- /home/otaylor/fribidi-0.9.0/fribidi_get_type.c Wed Mar 28 01:55:42 2001 ++++ ./fribidi_get_type.c Fri Apr 13 14:15:44 2001 +@@ -23,7 +23,9 @@ + + #include <stdio.h> + #include <stdlib.h> +-#include "fribidi.h" ++#include <glib.h> ++#include "pango/pango-utils.h" ++#include "fribidi_types.h" + #include "fribidi_tables.i" + + #ifdef MEM_OPTIMIZED +@@ -34,7 +36,7 @@ + // fribidi_get_type() returns the bidi type of a character. + //----------------------------------------------------------------------*/ + FriBidiCharType +-fribidi_get_type (FriBidiChar uch) ++_pango_fribidi_get_type(FriBidiChar uch) + { + int i = uch % 256, j = uch / 256; + FriBidiPropCharType *block = FriBidiPropertyBlocks[j]; +@@ -80,7 +82,7 @@ + } + } + +-gboolean fribidi_get_mirror_char ( /* Input */ ++gboolean pango_get_mirror_char ( /* Input */ + FriBidiChar ch, + /* Output */ + FriBidiChar * mirrored_ch) +--- /home/otaylor/fribidi-0.9.0/fribidi_tables.i Wed Mar 28 03:02:09 2001 ++++ ./fribidi_tables.i Fri Apr 13 14:22:07 2001 +@@ -3,8 +3,6 @@ + // and BidiMirroring.txt, version 1, by the perl script CreateGetType.pl. + //----------------------------------------------------------------------*/ + +-#include "fribidi.h" +- + #define WS FRIBIDI_PROP_TYPE_WS + #define BS FRIBIDI_PROP_TYPE_BS + #define EO FRIBIDI_PROP_TYPE_EO +--- /home/otaylor/fribidi-0.9.0/fribidi_types.h Wed Mar 28 01:55:42 2001 ++++ ./fribidi_types.h Fri Apr 13 14:04:11 2001 +@@ -281,4 +281,6 @@ + #define FRIBIDI_MAX_STRING_LENGTH 65535 + #endif + ++FriBidiCharType _pango_fribidi_get_type(FriBidiChar uch); ++ + #endif diff --git a/pango/mini-fribidi/fribidi.c b/pango/mini-fribidi/fribidi.c index 62db6124..902cde31 100644 --- a/pango/mini-fribidi/fribidi.c +++ b/pango/mini-fribidi/fribidi.c @@ -1,50 +1,121 @@ /* FriBidi - Library of BiDi algorithm - * Copyright (C) 1999 Dov Grobgeld - * + * Copyright (C) 1999,2000 Dov Grobgeld, and + * Copyright (C) 2001 Behdad Esfahbod. + * * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public + * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library, in a file named COPYING.LIB; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA + * + * For licensing issues, contact <dov@imagic.weizmann.ac.il> and + * <fwpg@sharif.edu>. */ + #include <glib.h> #include "pango/pango-utils.h" #include "fribidi_types.h" +#undef DEBUG + +#ifdef DEBUG +#include <stdio.h> +#endif + +#ifdef DEBUG +#define DBG(s) if (fribidi_debug) { fprintf(stderr, s); } +#else +#define DBG(s) +#endif + +#ifdef DEBUG +// for easier test with the reference code only. +#define MAX_LEVEL 15 +#else +// default value. +#define MAX_LEVEL 61 +#endif /*====================================================================== // Typedef for the run-length list. //----------------------------------------------------------------------*/ typedef struct _TypeLink TypeLink; -struct _TypeLink { +struct _TypeLink +{ TypeLink *prev; TypeLink *next; + FriBidiCharType type; - int pos; - int len; - int level; + gint pos; + gint len; + gint level; }; -typedef struct { +#define FRIBIDI_LEVEL_START -1 +#define FRIBIDI_LEVEL_END -1 +#define FRIBIDI_LEVEL_REMOVED -2 + +typedef struct +{ FriBidiChar key; FriBidiChar value; -} key_value_t; +} +key_value_t; + +typedef struct +{ + FriBidiCharType override; /* only L, R and N are valid */ + gint level; +} +level_info; + +#ifdef DEBUG +static gboolean fribidi_debug = FALSE; +#endif + +gboolean fribidi_set_debug (gboolean debug) +{ +#ifdef DEBUG + return fribidi_debug = debug; +#else + return 0; +#endif +} + +#ifdef DEBUG +static gint +bidi_string_strlen (FriBidiChar * str) +{ + gint len = 0; + while (*str++) + len++; + + return len; +} +#endif + +#ifndef USE_SIMPLE_MALLOC static TypeLink *free_type_links = NULL; +#endif -static TypeLink *new_type_link(void) +static TypeLink * +new_type_link (void) { TypeLink *link; - + +#ifdef USE_SIMPLE_MALLOC + link = g_malloc (sizeof (TypeLink)); +#else if (free_type_links) { link = free_type_links; @@ -55,13 +126,13 @@ static TypeLink *new_type_link(void) static GMemChunk *mem_chunk = NULL; if (!mem_chunk) - mem_chunk = g_mem_chunk_new ("TypeLinkList", - sizeof (TypeLink), - sizeof (TypeLink) * 128, - G_ALLOC_ONLY); + mem_chunk = g_mem_chunk_new ("TypeLinkList", + sizeof (TypeLink), + sizeof (TypeLink) * 128, G_ALLOC_ONLY); link = g_chunk_new (TypeLink, mem_chunk); } +#endif link->len = 0; link->pos = 0; @@ -71,57 +142,65 @@ static TypeLink *new_type_link(void) return link; } -static void free_type_link(TypeLink *link) +static void +free_type_link (TypeLink * link) { +#ifdef USE_SIMPLE_MALLOC + g_free (link); +#else link->next = free_type_links; free_type_links = link; +#endif } -static TypeLink *run_length_encode_types(int *char_type, int type_len) +static TypeLink * +run_length_encode_types (FriBidiCharType * char_type, gint type_len) { - TypeLink *list = NULL; - TypeLink *last; - TypeLink *link; + TypeLink *list = NULL, *last, *link; + TypeLink current; + FriBidiCharType type; - int len, pos, i; + gint len, pos, i; /* Add the starting link */ - list = new_type_link(); + list = new_type_link (); list->type = FRIBIDI_TYPE_SOT; + list->level = FRIBIDI_LEVEL_START; list->len = 0; list->pos = 0; last = list; /* Sweep over the string_types */ - type = -1; - len = 0; - pos = -1; - for (i=0; i<=type_len; i++) + current.type = FRIBIDI_LEVEL_START; + current.len = 0; + current.pos = -1; + for (i = 0; i <= type_len; i++) { - if (i==type_len || char_type[i] != type) + if (char_type[i] != current.type || i == type_len) { - if (pos>=0) + if (current.pos >= 0) { - link = new_type_link(); - link->type = type; - link->pos = pos; - link->len = len; - last->next = link; - link->prev = last; + link = new_type_link (); + link->type = current.type; + link->pos = current.pos; + link->len = current.len; + last->next = link; + link->prev = last; last = last->next; } - if (i==type_len) + if (i == type_len) break; - len = 0; - pos = i; + current.len = 0; + current.pos = i; } - type =char_type[i]; - len++; + current.type = char_type[i]; + current.len++; } /* Add the ending link */ - link = new_type_link(); + link = new_type_link (); link->type = FRIBIDI_TYPE_EOT; + link->level = FRIBIDI_LEVEL_END; link->len = 0; link->pos = type_len; last->next = link; @@ -130,336 +209,818 @@ static TypeLink *run_length_encode_types(int *char_type, int type_len) return list; } +/* explicits_list is a list like type_rl_list, that holds the explicit + codes that are removed from rl_list, to reinsert them later by calling + the override_list. +*/ +static void +init_list (TypeLink ** start, TypeLink ** end) +{ + TypeLink *list = NULL; + TypeLink *link; + + /* Add the starting link */ + list = new_type_link (); + list->type = FRIBIDI_TYPE_SOT; + list->level = FRIBIDI_LEVEL_START; + list->len = 0; + list->pos = 0; + + /* Add the ending link */ + link = new_type_link (); + link->type = FRIBIDI_TYPE_EOT; + link->level = FRIBIDI_LEVEL_END; + link->len = 0; + link->pos = 0; + list->next = link; + link->prev = list; + + *start = list; + *end = link; +} + +/* move an element before another element in a list, the list must have a + previous element, used to update explicits_list. + assuming that p have both prev and next or none of them, also update + the list that p is currently in, if any. +*/ +void +move_element_before (TypeLink * p, TypeLink * list) +{ + if (p->prev) + { + p->prev->next = p->next; + p->next->prev = p->prev; + } + p->prev = list->prev; + list->prev->next = p; + p->next = list; + list->prev = p; +} + +/* override the rl_list 'base', with the elements in the list 'over', to + reinsert the previously-removed explicit codes (at X9) from + 'explicits_list' back into 'type_rl_list'. This is used at the end of I2 + to restore the explicit marks, and also to reset the character types of + characters at L1. + + it is assumed that the 'pos' of the first element in 'base' list is not + more than the 'pos' of the first element of the 'over' list, and the + 'pos' of the last element of the 'base' list is not less than the 'pos' + of the last element of the 'over' list. these two conditions are always + satisfied for the two usages mentioned above. + + TBD: use some explanatory names instead of p, q, ... +*/ +void +override_list (TypeLink * base, TypeLink * over) +{ + TypeLink *p = base, *q, *r, *s, *t; + gint pos = 0, pos2; + + if (!base) + base = over; + else if (over) + { + q = over; + while (q) + { + if (!q->len || q->pos < pos) + { + t = q; + q = q->next; + free_type_link (t); + continue; + } + pos = q->pos; + while (p->next && p->next->pos <= pos) + p = p->next; + /* now p is the element that q must be inserted 'in'. */ + pos2 = pos + q->len; + r = p; + while (r->next && r->next->pos < pos2) + r = r->next; + /* now r is the last element that q affects. */ + if (p == r) + { + /* split p into at most 3 interval, and insert q in the place of + the second interval, set r to be the third part. */ + /* third part needed? */ + if (p->next && p->next->pos == pos2) + r = r->next; + else + { + r = new_type_link (); + *r = *p; + if (r->next) + { + r->next->prev = r; + r->len = r->next->pos - pos2; + } + else + r->len -= pos - p->pos; + r->pos = pos2; + } + /* first part needed? */ + if (p->prev && p->pos == pos) + { + t = p; + p = p->prev; + free_type_link (t); + } + else + p->len = pos - p->pos; + } + else + { + /* cut the end of p. */ + p->len = pos - p->pos; + /* if all of p is cut, remove it. */ + if (!p->len && p->prev) + p = p->prev; + + /* cut the begining of r. */ + r->pos = pos2; + if (r->next) + r->len = r->next->pos - pos2; + /* if all of r is cut, remove it. */ + if (!r->len && r->next) + r = r->next; + + /* remove the elements between p and r. */ + for (s = p->next; s != r;) + { + t = s; + s = s->next; + free_type_link (t); + } + } + /* before updating the next and prev links to point to the inserted q, + we must remember the next element of q in the 'over' list. + */ + t = q; + q = q->next; + p->next = t; + t->prev = p; + t->next = r; + r->prev = t; + } + } +} + /* Some convenience macros */ #define RL_TYPE(list) (list)->type #define RL_LEN(list) (list)->len #define RL_POS(list) (list)->pos #define RL_LEVEL(list) (list)->level -static void compact_list(TypeLink *list) +static void +compact_list (TypeLink * list) { - while(list) + if (list->next) { - if (list->prev - && RL_TYPE(list->prev) == RL_TYPE(list)) + list = list->next; + while (list) { - TypeLink *next = list->next; - list->prev->next = list->next; - list->next->prev = list->prev; - RL_LEN(list->prev) = RL_LEN(list->prev) + RL_LEN(list); - free_type_link(list); - list = next; - } - else - list = list->next; + if (RL_TYPE (list->prev) == RL_TYPE (list) + && RL_LEVEL (list->prev) == RL_LEVEL (list)) + { + TypeLink *next = list->next; + list->prev->next = list->next; + list->next->prev = list->prev; + RL_LEN (list->prev) += RL_LEN (list); + free_type_link (list); + list = next; + } + else + list = list->next; + } + } +} + +static void +compact_neutrals (TypeLink * list) +{ + if (list->next) + { + list = list->next; + while (list) + { + if (RL_LEVEL (list->prev) == RL_LEVEL (list) + && + ((RL_TYPE + (list->prev) == RL_TYPE (list) + || FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev)) + && FRIBIDI_IS_NEUTRAL (RL_TYPE (list))))) + { + TypeLink *next = list->next; + list->prev->next = list->next; + list->next->prev = list->prev; + RL_LEN (list->prev) += RL_LEN (list); + free_type_link (list); + list = next; + } + else + list = list->next; + } + } +} + +/*======================================================= +// define macros for push and pop the status in to / out of the stack +//-------------------------------------------------------*/ + +/* There's some little points in pushing and poping into the status stack: + 1. when the embedding level is not valid (more than MAX_LEVEL=61), + you must reject it, and not to push into the stack, but when you see a + PDF, you must find the matching code, and if it was pushed in the stack, + pop it, it means you must pop if and only if you have pushed the + matching code, the over_pushed var counts the number of rejected codes yet. + 2. there's a more confusing point too, when the embedding level is exactly + MAX_LEVEL-1=60, an LRO or LRE must be rejected because the new level would + be MAX_LEVEL+1=62, that is invalid, but an RLO or RLE must be accepted + because the new level is MAX_LEVEL=61, that is valid, so the rejected + codes may be not continuous in the logical order, in fact there is at + most two continuous intervals of codes, with a RLO or RLE between them. + to support the case, the first_interval var counts the number of rejected + codes in the first interval, when it is 0, means that there is only one + interval yet. +*/ + +/* a. If this new level would be valid, then this embedding code is valid. + Remember (push) the current embedding level and override status. + Reset current level to this new level, and reset the override status to + new_override. + b. If the new level would not be valid, then this code is invalid. Don't + change the current level or override status. +*/ +#define PUSH_STATUS \ + { \ + if (new_level <= MAX_LEVEL) \ + { \ + if (level == MAX_LEVEL - 1) \ + first_interval = over_pushed; \ + status_stack->level = level; \ + status_stack->override = override; \ + status_stack++; \ + stack_size++; \ + level = new_level; \ + override = new_override; \ + } else \ + over_pushed++; \ + } + +/* If there was a valid matching code, restore (pop) the last remembered + (pushed) embedding level and directional override. +*/ +#define POP_STATUS \ + { \ + if (over_pushed || stack_size) \ + { \ + if (over_pushed > first_interval) \ + over_pushed--; \ + else \ + { \ + if (over_pushed == first_interval) \ + first_interval = 0; \ + status_stack--; \ + stack_size--; \ + level = status_stack->level; \ + override = status_stack->override; \ + } \ + } \ + } + +/*========================================================================== +// There was no support for sor and eor in the absence of Explicit Embedding +// Levels, so define macros, to support them, with as less change as needed. +//--------------------------------------------------------------------------*/ + +/* Return the type of previous char or the sor, if already at the start of + a run level. */ +#define PREV_TYPE_OR_SOR(pp) \ + (RL_LEVEL(pp->prev)==RL_LEVEL(pp) ? RL_TYPE(pp->prev) : FRIBIDI_LEVEL_TO_DIR( \ + (RL_LEVEL(pp->prev)>RL_LEVEL(pp) ? RL_LEVEL(pp->prev) : RL_LEVEL(pp)) \ + )) + +/* Return the type of next char or the eor, if already at the end of + a run level. */ +#define NEXT_TYPE_OR_EOR(pp) \ + (!pp->next ? FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(pp)) : \ + (RL_LEVEL(pp->next)==RL_LEVEL(pp) ? RL_TYPE(pp->next) : FRIBIDI_LEVEL_TO_DIR( \ + (RL_LEVEL(pp->next)>RL_LEVEL(pp) ? RL_LEVEL(pp->next) : RL_LEVEL(pp)) \ + ))) + + +/* Return the embedding direction of a link. */ +#define FRIBIDI_EMBEDDING_DIRECTION(list) \ + FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(list)) + +#ifdef DEBUG +/*====================================================================== +// For debugging, define some functions for printing the types and the +// levels. +//----------------------------------------------------------------------*/ + +static guchar char_from_level_array[] = { + 'e', /* FRIBIDI_LEVEL_REMOVED, internal error, this level shouldn't be viewed. */ + '_', /* FRIBIDI_LEVEL_START or _END, indicating start of string and end of string. */ + /* 0-9,A-F are the only valid levels in debug mode and before resolving + implicits. after that the levels X, Y, Z may be appear too. */ + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', + 'X', 'Y', 'Z', /* only must appear after resolving implicits. */ + 'o', 'o', 'o' /* overflows, this levels and higher levels show a bug!. */ +}; + +#define fribidi_char_from_level(level) char_from_level_array[(level) + 2] + +static void +print_types_re (TypeLink * pp) +{ + fprintf (stderr, "Run types : "); + while (pp) + { + fprintf (stderr, "%d:l%d(%s)[%d] ", + pp->pos, pp->len, fribidi_type_name (pp->type), pp->level); + pp = pp->next; } + fprintf (stderr, "\n"); } -/* Define a rule macro */ - -/* Rules for overriding current type */ -#define TYPE_RULE1(old_this, \ - new_this) \ - if (this_type == TYPE_ ## old_this) \ - RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \ - -/* Rules for current and previous type */ -#define TYPE_RULE2(old_prev, old_this, \ - new_prev, new_this) \ - if ( prev_type == FRIBIDI_TYPE_ ## old_prev \ - && this_type == FRIBIDI_TYPE_ ## old_this) \ - { \ - RL_TYPE(pp->prev) = FRIBIDI_TYPE_ ## new_prev; \ - RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \ - continue; \ - } - -/* A full rule that assigns all three types */ -#define TYPE_RULE(old_prev, old_this, old_next, \ - new_prev, new_this, new_next) \ - if ( prev_type == FRIBIDI_TYPE_ ## old_prev \ - && this_type == FRIBIDI_TYPE_ ## old_this \ - && next_type == FRIBIDI_TYPE_ ## old_next) \ - { \ - RL_TYPE(pp->prev) = FRIBIDI_TYPE_ ## new_prev; \ - RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \ - RL_TYPE(pp->next) = FRIBIDI_TYPE_ ## new_next; \ - continue; \ - } - -/* For optimization the following macro only assigns the center type */ -#define TYPE_RULE_C(old_prev, old_this, old_next, \ - new_this) \ - if ( prev_type == FRIBIDI_TYPE_ ## old_prev \ - && this_type == FRIBIDI_TYPE_ ## old_this \ - && next_type == FRIBIDI_TYPE_ ## old_next) \ - { \ - RL_TYPE(pp) = FRIBIDI_TYPE_ ## new_this; \ - continue; \ - } +static void +print_resolved_levels (TypeLink * pp) +{ + fprintf (stderr, "Res. levels: "); + while (pp) + { + gint i; + for (i = 0; i < RL_LEN (pp); i++) + fprintf (stderr, "%c", fribidi_char_from_level (RL_LEVEL (pp))); + pp = pp->next; + } + fprintf (stderr, "\n"); +} + +static void +print_resolved_types (TypeLink * pp) +{ + fprintf (stderr, "Res. types : "); + while (pp) + { + gint i; + for (i = 0; i < RL_LEN (pp); i++) + fprintf (stderr, "%c", fribidi_char_from_type (pp->type)); + pp = pp->next; + } + fprintf (stderr, "\n"); +} + +static void +print_bidi_string (FriBidiChar * str) +{ + gint i; + fprintf (stderr, "Org. types : "); + for (i = 0; i < bidi_string_strlen (str); i++) + fprintf (stderr, "%c", + fribidi_char_from_type (_pango_fribidi_get_type (str[i]))); + fprintf (stderr, "\n"); +} +#endif /*====================================================================== // This function should follow the Unicode specification closely! -// -// It is still lacking the support for <RLO> and <LRO>. //----------------------------------------------------------------------*/ static void -fribidi_analyse_string(/* input */ - FriBidiChar *str, - int len, - FriBidiCharType *pbase_dir, - /* output */ - TypeLink **ptype_rl_list, - gint *pmax_level) +fribidi_analyse_string ( /* input */ + FriBidiChar * str, + gint len, FriBidiCharType * pbase_dir, + /* output */ + TypeLink ** ptype_rl_list, gint * pmax_level) { - int base_level, base_dir; - int max_level; - int i; - int *char_type; - int prev_last_strong, last_strong; - TypeLink *type_rl_list, *pp; + gint base_level, base_dir; + gint max_level; + gint i; + gint prev_last_strong, last_strong; + FriBidiCharType *char_type; + TypeLink *type_rl_list, *explicits_list, *explicits_list_end, *pp; /* Determinate character types */ - char_type = g_new(gint, len); - for (i=0; i<len; i++) + char_type = g_new (FriBidiCharType, len); + for (i = 0; i < len; i++) char_type[i] = _pango_fribidi_get_type (str[i]); /* Run length encode the character types */ - type_rl_list = run_length_encode_types(char_type, len); - g_free(char_type); + type_rl_list = run_length_encode_types (char_type, len); + g_free (char_type); + + init_list (&explicits_list, &explicits_list_end); /* Find the base level */ - if (*pbase_dir == FRIBIDI_TYPE_L) + if (FRIBIDI_IS_STRONG (*pbase_dir)) + base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir); + /* P2. P3. Search for first strong character and use its direction as + base direction */ + else { - base_dir = FRIBIDI_TYPE_L; - base_level = 0; + base_level = 0; /* Default */ + base_dir = FRIBIDI_TYPE_ON; + for (pp = type_rl_list; pp; pp = pp->next) + if (FRIBIDI_IS_LETTER (RL_TYPE (pp))) + { + base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp)); + base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); + break; + } + + /* If no strong base_dir was found, resort to the weak direction + that was passed on input. */ + if (FRIBIDI_IS_NEUTRAL (base_dir)) + base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir); } - else if (*pbase_dir == FRIBIDI_TYPE_R) + base_dir = FRIBIDI_LEVEL_TO_DIR (base_level); + +#ifdef DEBUG + if (fribidi_debug) { - base_dir = FRIBIDI_TYPE_R; - base_level = 1; + fprintf (stderr, "Base level : %c\n", + fribidi_char_from_level (base_level)); + fprintf (stderr, "Base dir : %c\n", + fribidi_char_from_type (base_dir)); + print_types_re (type_rl_list); } +#endif - /* Search for first strong character and use its direction as base - direciton */ - else + /* Explicit Levels and Directions */ + DBG ("Explicit Levels and Directions.\n"); + { + /* X1. Begin by setting the current embedding level to the paragraph + embedding level. Set the directional override status to neutral. + Process each character iteratively, applying rules X2 through X9. + Only embedding levels from 0 to 61 are valid in this phase. */ + gint level = base_level; + gint override = FRIBIDI_TYPE_ON; + gint new_level, new_override; + /* stack */ + gint stack_size = 0; + gint over_pushed = 0; + gint first_interval = 0; + level_info *status_stack = g_new (level_info, MAX_LEVEL + 2); + TypeLink *temp_link = new_type_link (); + + gint i; + + for (pp = type_rl_list->next; pp->next; pp = pp->next) + { + gint this_type = RL_TYPE (pp); + if (FRIBIDI_IS_EXPLICIT_OR_BN (this_type)) + { + if (FRIBIDI_IS_STRONG (this_type)) + { /* LRE, RLE, LRO, RLO */ + /* 1. Explicit Embeddings */ + /* X2. With each RLE, compute the least greater odd embedding level. */ + /* X3. With each LRE, compute the least greater even embedding level. */ + /* 2. Explicit Overrides */ + /* X4. With each RLO, compute the least greater odd embedding level. */ + /* X5. With each LRO, compute the least greater even embedding level. */ + new_override = FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR (this_type); + for (i = 0; i < RL_LEN (pp); i++) + { + new_level = + ((level + FRIBIDI_DIR_TO_LEVEL (this_type) + 2) & ~1) - + FRIBIDI_DIR_TO_LEVEL (this_type); + PUSH_STATUS; + } + } + else if (this_type == FRIBIDI_TYPE_PDF) + { + /* 3. Terminating Embeddings and overrides */ + /* X7. With each PDF, determine the matching embedding or + override code. */ + for (i = 0; i < RL_LEN (pp); i++) + POP_STATUS; + } + /* X9. Remove all RLE, LRE, RLO, LRO, PDF, and BN codes. */ + /* Remove element and add it to explicits_list */ + temp_link->next = pp->next; + pp->level = FRIBIDI_LEVEL_REMOVED; + move_element_before (pp, explicits_list_end); + pp = temp_link; + } + else + { + /* X6. For all typed besides RLE, LRE, RLO, LRO, and PDF: + a. Set the level of the current character to the current + embedding level. + b. Whenever the directional override status is not neutral, + reset the current character type to the directional override + status. */ + RL_LEVEL (pp) = level; + if (!FRIBIDI_IS_NEUTRAL (override)) + RL_TYPE (pp) = override; + } + /* X8. All explicit directional embeddings and overrides are + completely terminated at the end of each paragraph. Paragraph + separators are not included in the embedding. */ + /* This function is running on a single paragraph, so we can do + X8 after all the input is processed. */ + } + + /* Implementing X8. It has no effect on a single paragraph! */ + level = base_level; + override = FRIBIDI_TYPE_ON; + status_stack -= stack_size; + stack_size = 0; + over_pushed = 0; + + free_type_link (temp_link); + g_free (status_stack); + } + /* X10. The remaining rules are applied to each run of characters at the + same level. For each run, determine the start-of-level-run (sor) and + end-of-level-run (eor) type, either L or R. This depends on the + higher of the two levels on either side of the boundary (at the start + or end of the paragraph, the level of the 'other' run is the base + embedding level). If the higher level is odd, the type is R, otherwise + it is L. */ + /* Resolving Implicit Levels can be done out of X10 loop, so only change + of Resolving Weak Types and Resolving Neutral Types is needed. */ + + compact_list (type_rl_list); + +#ifdef DEBUG + if (fribidi_debug) { - base_level = 0; /* Default */ - base_dir = FRIBIDI_TYPE_N; - for (pp = type_rl_list; pp; pp = pp->next) - { - if (RL_TYPE(pp) == FRIBIDI_TYPE_R) - { - base_level = 1; - base_dir = FRIBIDI_TYPE_R; - break; - } - else if (RL_TYPE(pp) == FRIBIDI_TYPE_L) - { - base_level = 0; - base_dir = FRIBIDI_TYPE_L; - break; - } - } - - /* If no strong base_dir was found, resort to the weak direction - * that was passed on input. - */ - if (base_dir == FRIBIDI_TYPE_N) - { - if (*pbase_dir == FRIBIDI_TYPE_WR) - { - base_dir = FRIBIDI_TYPE_RTL; - base_level = 1; - } - else if (*pbase_dir == FRIBIDI_TYPE_WL) - { - base_dir = FRIBIDI_TYPE_LTR; - base_level = 0; - } - } + print_types_re (type_rl_list); + print_bidi_string (str); + print_resolved_levels (type_rl_list); + print_resolved_types (type_rl_list); } - - /* 1. Explicit Levels and Directions. TBD! */ - compact_list(type_rl_list); - - /* 2. Explicit Overrides. TBD! */ - compact_list(type_rl_list); - - /* 3. Terminating Embeddings and overrides. TBD! */ - compact_list(type_rl_list); - +#endif + /* 4. Resolving weak types */ - last_strong = base_dir; - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - int prev_type = RL_TYPE(pp->prev); - int this_type = RL_TYPE(pp); - int next_type = RL_TYPE(pp->next); - - /* Remember the last strong character */ - if (prev_type == FRIBIDI_TYPE_AL - || prev_type == FRIBIDI_TYPE_R - || prev_type == FRIBIDI_TYPE_L) + DBG ("Resolving weak types.\n"); + { + gint last_strong, prev_type_org, w4; + + last_strong = base_dir; + + for (pp = type_rl_list->next; pp->next; pp = pp->next) + { + gint prev_type, this_type, next_type; + + prev_type = PREV_TYPE_OR_SOR (pp); + this_type = RL_TYPE (pp); + next_type = NEXT_TYPE_OR_EOR (pp); + + if (FRIBIDI_IS_STRONG (prev_type)) last_strong = prev_type; - - /* W1. NSM */ - if (this_type == FRIBIDI_TYPE_NSM) - { - if (prev_type == FRIBIDI_TYPE_SOT) - RL_TYPE(pp) = FRIBIDI_TYPE_N; /* Will be resolved to base dir */ - else - RL_TYPE(pp) = prev_type; - } - /* W2: European numbers */ - if (this_type == FRIBIDI_TYPE_N - && last_strong == FRIBIDI_TYPE_AL) - RL_TYPE(pp) = FRIBIDI_TYPE_AN; - - /* W3: Change ALs to R - We have to do this for prev character as we would otherwise - interfer with the next last_strong which is FRIBIDI_TYPE_AL. - */ - if (prev_type == FRIBIDI_TYPE_AL) - RL_TYPE(pp->prev) = FRIBIDI_TYPE_R; - - /* W4. A single european separator changes to a european number. - A single common separator between two numbers of the same type - changes to that type. - */ - if (RL_LEN(pp) == 1) - { - TYPE_RULE_C(EN,ES,EN, EN); - TYPE_RULE_C(EN,CS,EN, EN); - TYPE_RULE_C(AN,CS,AN, AN); - } + /* W1. NSM + Examine each non-spacing mark (NSM) in the level run, and change the + type of the NSM to the type of the previous character. If the NSM + is at the start of the level run, it will get the type of sor. */ + if (this_type == FRIBIDI_TYPE_NSM) + { + RL_TYPE (pp) = prev_type; + continue; + } - /* W5. A sequence of European terminators adjacent to European - numbers changes to All European numbers. - */ - if (this_type == FRIBIDI_TYPE_ET) - { - if (next_type == FRIBIDI_TYPE_EN - || prev_type == FRIBIDI_TYPE_EN) { - RL_TYPE(pp) = FRIBIDI_TYPE_EN; + /* W2: European numbers. */ + if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_AL) + { + RL_TYPE (pp) = FRIBIDI_TYPE_AN; + + /* Resolving dependency of loops for rules W1 and W2, so we + can merge them in one loop. */ + if (next_type == FRIBIDI_TYPE_NSM) + RL_TYPE (pp->next) = FRIBIDI_TYPE_AN; } - } + } - /* This type may have been overriden */ - this_type = RL_TYPE(pp); - - /* W6. Otherwise change separators and terminators to other neutral */ - if (this_type == FRIBIDI_TYPE_ET - || this_type == FRIBIDI_TYPE_CS - || this_type == FRIBIDI_TYPE_ES) - RL_TYPE(pp) = FRIBIDI_TYPE_ON; - - /* W7. Change european numbers to L. */ - if (prev_type == FRIBIDI_TYPE_EN - && last_strong == FRIBIDI_TYPE_L) - RL_TYPE(pp->prev) = FRIBIDI_TYPE_L; - } - /* Handle the two rules that effect pp->prev for the last element */ + last_strong = base_dir; + /* Resolving dependency of loops for rules W4 and W5, W5 may + want to prevent W4 to take effect in the next turn, do this + through "w4". */ + w4 = 1; + /* Resolving dependency of loops for rules W4 and W5 with W7, + W7 may change an EN to L but it sets the prev_type_org if needed, + so W4 and W5 in next turn can still do their works. */ + prev_type_org = FRIBIDI_TYPE_ON; + + for (pp = type_rl_list->next; pp->next; pp = pp->next) + { + gint prev_type, this_type, next_type; - if (RL_TYPE (pp->prev) == FRIBIDI_TYPE_AL) /* W3 */ - RL_TYPE(pp->prev) = FRIBIDI_TYPE_R; - if (RL_TYPE (pp->prev) == FRIBIDI_TYPE_EN /* W7 */ - && last_strong == FRIBIDI_TYPE_L) - RL_TYPE(pp->prev) = FRIBIDI_TYPE_L; - + prev_type = PREV_TYPE_OR_SOR (pp); + this_type = RL_TYPE (pp); + next_type = NEXT_TYPE_OR_EOR (pp); - compact_list(type_rl_list); - - /* 5. Resolving Neutral Types */ + if (FRIBIDI_IS_STRONG (prev_type)) + last_strong = prev_type; - /* We can now collapse all separators and other neutral types to - plain neutrals */ - for (pp = type_rl_list->next; pp->next; pp = pp->next) + /* W3: Change ALs to R. */ + if (this_type == FRIBIDI_TYPE_AL) + { + RL_TYPE (pp) = FRIBIDI_TYPE_RTL; + w4 = 1; + prev_type_org = FRIBIDI_TYPE_ON; + continue; + } + + /* W4. A single european separator changes to a european number. + A single common separator between two numbers of the same type + changes to that type. */ + if (w4 + && RL_LEN (pp) == 1 && FRIBIDI_IS_ES_OR_CS (this_type) + && FRIBIDI_IS_NUMBER (prev_type_org) && prev_type_org == next_type + && (prev_type_org == FRIBIDI_TYPE_EN + || this_type == FRIBIDI_TYPE_CS)) + { + RL_TYPE (pp) = prev_type; + this_type = RL_TYPE (pp); + } + w4 = 1; + + /* W5. A sequence of European terminators adjacent to European + numbers changes to All European numbers. */ + if (this_type == FRIBIDI_TYPE_ET + && (prev_type_org == FRIBIDI_TYPE_EN + || next_type == FRIBIDI_TYPE_EN)) + { + RL_TYPE (pp) = FRIBIDI_TYPE_EN; + w4 = 0; + this_type = RL_TYPE (pp); + } + + /* W6. Otherwise change separators and terminators to other neutral. */ + if (FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR (this_type)) + RL_TYPE (pp) = FRIBIDI_TYPE_ON; + + /* W7. Change european numbers to L. */ + if (this_type == FRIBIDI_TYPE_EN && last_strong == FRIBIDI_TYPE_LTR) + { + RL_TYPE (pp) = FRIBIDI_TYPE_LTR; + prev_type_org = (RL_LEVEL (pp) == RL_LEVEL (pp->next) ? + FRIBIDI_TYPE_EN : FRIBIDI_TYPE_ON); + } + else + prev_type_org = PREV_TYPE_OR_SOR (pp->next); + } + } + + compact_neutrals (type_rl_list); + +#ifdef DEBUG + if (fribidi_debug) { - int this_type = RL_TYPE(pp); - - if ( this_type == FRIBIDI_TYPE_WS - || this_type == FRIBIDI_TYPE_ON - || this_type == FRIBIDI_TYPE_ES - || this_type == FRIBIDI_TYPE_ET - || this_type == FRIBIDI_TYPE_CS - || this_type == FRIBIDI_TYPE_BN) - RL_TYPE(pp) = FRIBIDI_TYPE_N; + print_resolved_levels (type_rl_list); + print_resolved_types (type_rl_list); } - - compact_list(type_rl_list); - - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - int prev_type = RL_TYPE(pp->prev); - int this_type = RL_TYPE(pp); - int next_type = RL_TYPE(pp->next); +#endif - if (this_type == FRIBIDI_TYPE_N) /* optimization! */ - { - /* "European and arabic numbers are treated - as though they were R" */ + /* 5. Resolving Neutral Types */ + DBG ("Resolving neutral types.\n"); + { + gint prev_type, next_type; + + /* N1. and N2. + For each neutral, resolve it. */ + for (pp = type_rl_list->next; pp->next; pp = pp->next) + { + gint prev_type, this_type, next_type; - if (prev_type == FRIBIDI_TYPE_EN || prev_type == FRIBIDI_TYPE_AN) - prev_type = FRIBIDI_TYPE_R; + /* "European and arabic numbers are treated as though they were R" + FRIBIDI_CHANGE_NUMBER_TO_RTL does this. */ + this_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (RL_TYPE (pp)); + prev_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (PREV_TYPE_OR_SOR (pp)); + next_type = FRIBIDI_CHANGE_NUMBER_TO_RTL (NEXT_TYPE_OR_EOR (pp)); - if (next_type == FRIBIDI_TYPE_EN || next_type == FRIBIDI_TYPE_AN) - next_type = FRIBIDI_TYPE_R; + if (FRIBIDI_IS_NEUTRAL (this_type)) + RL_TYPE (pp) = (prev_type == next_type) ? + /* N1. */ prev_type : + /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp); + } + } - /* N1. */ - TYPE_RULE_C(R,N,R, R); - TYPE_RULE_C(L,N,L, L); + compact_list (type_rl_list); - /* N2. Any remaining neutrals takes the embedding direction */ - if (RL_TYPE(pp) == FRIBIDI_TYPE_N) - RL_TYPE(pp) = FRIBIDI_TYPE_E; - } +#ifdef DEBUG + if (fribidi_debug) + { + print_resolved_levels (type_rl_list); + print_resolved_types (type_rl_list); } +#endif - compact_list(type_rl_list); - - /* 6. Resolving Implicit levels */ + /* 6. Resolving implicit levels */ + DBG ("Resolving implicit levels.\n"); { - int level = base_level; max_level = base_level; - + for (pp = type_rl_list->next; pp->next; pp = pp->next) { - int this_type = RL_TYPE(pp); + gint this_type, level; + + this_type = RL_TYPE (pp); + level = RL_LEVEL (pp); + + /* I1. Even */ + /* I2. Odd */ + if (FRIBIDI_IS_NUMBER (this_type)) + RL_LEVEL (pp) = (RL_LEVEL (pp) + 2) & ~1; + else + RL_LEVEL (pp) = (RL_LEVEL (pp) ^ FRIBIDI_DIR_TO_LEVEL (this_type)) + + (RL_LEVEL (pp) & 1); + + if (RL_LEVEL (pp) > max_level) + max_level = RL_LEVEL (pp); + } + } + + compact_list (type_rl_list); + +#ifdef DEBUG + if (fribidi_debug) + { + print_bidi_string (str); + print_resolved_levels (type_rl_list); + print_resolved_types (type_rl_list); + } +#endif + +/* Reinsert the explicit codes & bn's that already removed, from the + explicits_list to type_rl_list. */ + DBG ("Reinserting explicit codes.\n"); + { + TypeLink *p; + + override_list (type_rl_list, explicits_list); + p = type_rl_list->next; + if (p->level < 0) + p->level = base_level; + for (; p->next; p = p->next) + if (p->level < 0) + p->level = p->prev->level; + } - /* This code should be expanded to handle explicit directions! */ +#ifdef DEBUG + if (fribidi_debug) + { + print_types_re (type_rl_list); + print_resolved_levels (type_rl_list); + print_resolved_types (type_rl_list); + } +#endif - /* Even */ - if (level % 2 == 0) + DBG ("Reset the embedding levels.\n"); + { + gint j, k, state, pos; + TypeLink *p, *q, *list, *list_end; + + /* L1. Reset the embedding levels of some chars. */ + init_list (&list, &list_end); + q = list_end; + state = 1; + pos = len - 1; + for (j = len - 1; j >= 0; j--) + { + k = _pango_fribidi_get_type (str[j]); + if (!state && FRIBIDI_IS_SEPARATOR (k)) { - if (this_type == FRIBIDI_TYPE_R) - RL_LEVEL(pp) = level + 1; - else if (this_type == FRIBIDI_TYPE_AN) - RL_LEVEL(pp) = level + 2; - else if (RL_TYPE(pp->prev) != FRIBIDI_TYPE_L && this_type == FRIBIDI_TYPE_EN) - RL_LEVEL(pp) = level + 2; - else - RL_LEVEL(pp) = level; + state = 1; + pos = j; } - /* Odd */ else + if (state + && !(j && FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS (k))) { - if ( this_type == FRIBIDI_TYPE_L - || this_type == FRIBIDI_TYPE_AN - || this_type == FRIBIDI_TYPE_EN) - RL_LEVEL(pp) = level+1; - else - RL_LEVEL(pp) = level; + /* if state is on at the very first of string, do this too. */ + if (!j) + j--; + state = 0; + p = new_type_link (); + p->prev = p->next = 0; + p->pos = j + 1; + p->len = pos - j; + p->type = base_dir; + p->level = base_level; + move_element_before (p, q); + q = p; } - - if (RL_LEVEL(pp) > max_level) - max_level = RL_LEVEL(pp); } + override_list (type_rl_list, list); } - - compact_list(type_rl_list); + +#ifdef DEBUG + if (fribidi_debug) + { + print_types_re (type_rl_list); + print_resolved_levels (type_rl_list); + print_resolved_types (type_rl_list); + } +#endif *ptype_rl_list = type_rl_list; *pmax_level = max_level; @@ -467,6 +1028,45 @@ fribidi_analyse_string(/* input */ } /*====================================================================== +// Frees up the rl_list, must be called after each call to +// fribidi_analyse_string(), after the list is not needed anymore. +//----------------------------------------------------------------------*/ +void +free_rl_list (TypeLink * type_rl_list) +{ + + TypeLink *p, *pp; + if (!type_rl_list) + return; +#ifdef USE_SIMPLE_MALLOC + for (pp = type_rl_list; pp; pp = pp->next) + { + p = pp->next; + g_free (pp); + }; +#else + for (pp = type_rl_list->next; pp->next; pp = pp->next) + /*Nothing */ ; + pp->next = free_type_links; + free_type_links = type_rl_list; + type_rl_list = NULL; +#endif +} + +static gboolean mirroring = TRUE; + +gboolean fribidi_mirroring_status (void) +{ + return mirroring; +} + +void +fribidi_set_mirroring (gboolean mirror) +{ + mirroring = mirror; +} + +/*====================================================================== // Here starts the exposed front end functions. //----------------------------------------------------------------------*/ @@ -474,41 +1074,39 @@ fribidi_analyse_string(/* input */ // fribidi_embedding_levels() is used in order to just get the // embedding levels. //----------------------------------------------------------------------*/ -void -pango_log2vis_get_embedding_levels( - /* input */ - gunichar *str, - int len, - PangoDirection *pbase_dir, - /* output */ - guint8 *embedding_level_list - ) +void +pango_log2vis_get_embedding_levels ( + /* input */ + gunichar * str, + int len, + PangoDirection *pbase_dir, + /* output */ + guint8 * embedding_level_list) { TypeLink *type_rl_list, *pp; - int max_level; + gint max_level; FriBidiCharType fribidi_base_dir; - + fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ? FRIBIDI_TYPE_L : FRIBIDI_TYPE_R; - - fribidi_analyse_string(str, len, &fribidi_base_dir, - /* output */ - &type_rl_list, - &max_level); + + if (len == 0) + return; + + fribidi_analyse_string (str, len, &fribidi_base_dir, + /* output */ + &type_rl_list, &max_level); for (pp = type_rl_list->next; pp->next; pp = pp->next) { - int i; - int pos = RL_POS(pp); - int len = RL_LEN(pp); - int level = RL_LEVEL(pp); - for (i=0; i<len; i++) + gint i; + gint pos = RL_POS (pp); + gint len = RL_LEN (pp); + gint level = RL_LEVEL (pp); + for (i = 0; i < len; i++) embedding_level_list[pos + i] = level; } - - /* Free up the rl_list */ - pp->next = free_type_links; - free_type_links = type_rl_list; - + + free_rl_list (type_rl_list); + *pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; } - diff --git a/pango/mini-fribidi/fribidi_get_type.c b/pango/mini-fribidi/fribidi_get_type.c index 3daad57b..e93643fd 100644 --- a/pango/mini-fribidi/fribidi_get_type.c +++ b/pango/mini-fribidi/fribidi_get_type.c @@ -1,66 +1,113 @@ /* FriBidi - Library of BiDi algorithm - * Copyright (C) 1999 Dov Grobgeld - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Copyright (C) 1999,2000 Dov Grobgeld, and + * Copyright (C) 2001 Behdad Esfahbod. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library, in a file named COPYING.LIB; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA + * + * For licensing issues, contact <dov@imagic.weizmann.ac.il> and + * <fwpg@sharif.edu>. */ + #include <stdio.h> #include <stdlib.h> +#include <glib.h> #include "pango/pango-utils.h" #include "fribidi_types.h" #include "fribidi_tables.i" +#ifdef MEM_OPTIMIZED +extern FriBidiCharType prop_to_type[]; +#endif + /*====================================================================== // fribidi_get_type() returns the bidi type of a character. //----------------------------------------------------------------------*/ -FriBidiCharType _pango_fribidi_get_type(FriBidiChar uch) +FriBidiCharType +_pango_fribidi_get_type(FriBidiChar uch) { - guchar *block = FriBidiPropertyBlocks[uch / 256]; + int i = uch % 256, j = uch / 256; + FriBidiPropCharType *block = FriBidiPropertyBlocks[j]; if (block) - return block[uch % 256]; +#ifdef MEM_OPTIMIZED + return prop_to_type[block[i]]; +#else + return block[i]; +#endif else - return 0; + { + switch (j) + { + case 0x05: + if (i >= 0x90) + return FRIBIDI_TYPE_RTL; + else + break; + + case 0xFB: + if (i >= 0x50) + return FRIBIDI_TYPE_AL; + else if (i >= 0x1D) + return FRIBIDI_TYPE_RTL; + else + break; + case 0x06: + case 0xFC: + case 0xFD: + return FRIBIDI_TYPE_AL; + case 0x07: + if (i <= 0xBF) + return FRIBIDI_TYPE_AL; + else + break; + case 0xFE: + if (i >= 0x70) + return FRIBIDI_TYPE_AL; + else + break; + } + return FRIBIDI_TYPE_LTR; + } } -gboolean -pango_get_mirror_char(/* Input */ - gunichar ch, - /* Output */ - gunichar *mirrored_ch) +gboolean pango_get_mirror_char ( /* Input */ + FriBidiChar ch, + /* Output */ + FriBidiChar * mirrored_ch) { int pos, step; gboolean found = FALSE; - pos = step = (nFriBidiMirroredChars/2)+1; + pos = step = (nFriBidiMirroredChars / 2) + 1; - while(step > 1) + while (step > 1) { FriBidiChar cmp_ch = FriBidiMirroredChars[pos].ch; - step = (step+1)/2; - + step = (step + 1) / 2; + if (cmp_ch < ch) { pos += step; - if (pos>nFriBidiMirroredChars-1) - pos = nFriBidiMirroredChars-1; + if (pos > nFriBidiMirroredChars - 1) + pos = nFriBidiMirroredChars - 1; } else if (cmp_ch > ch) { pos -= step; - if (pos<0) - pos=0; + if (pos < 0) + pos = 0; } else break; @@ -72,4 +119,3 @@ pango_get_mirror_char(/* Input */ } return found; } - diff --git a/pango/mini-fribidi/fribidi_tables.i b/pango/mini-fribidi/fribidi_tables.i index b5505880..850487ac 100644 --- a/pango/mini-fribidi/fribidi_tables.i +++ b/pango/mini-fribidi/fribidi_tables.i @@ -1,32 +1,32 @@ -/*====================================================================== -// This file was automatically created from PropList-3.0.1.txt -// by the perl script CreateGetType.pl. +/*======================================================================== +// This file was automatically created from PropList.txt, version 3.0.1, +// and BidiMirroring.txt, version 1, by the perl script CreateGetType.pl. //----------------------------------------------------------------------*/ -#define LTR FRIBIDI_TYPE_LTR -#define RTL FRIBIDI_TYPE_RTL -#define EN FRIBIDI_TYPE_EN -#define ES FRIBIDI_TYPE_ES -#define ET FRIBIDI_TYPE_ET -#define AN FRIBIDI_TYPE_AN -#define CS FRIBIDI_TYPE_CS -#define BS FRIBIDI_TYPE_BS -#define SS FRIBIDI_TYPE_SS -#define CTL FRIBIDI_TYPE_CTL -#define LRE FRIBIDI_TYPE_LRE -#define RLE FRIBIDI_TYPE_RLE -#define LRO FRIBIDI_TYPE_LRO -#define RLO FRIBIDI_TYPE_RLO -#define WS FRIBIDI_TYPE_WS -#define ON FRIBIDI_TYPE_ON -#define AL FRIBIDI_TYPE_AL -#define NSM FRIBIDI_TYPE_NSM -#define BN FRIBIDI_TYPE_BN -#define PDF FRIBIDI_TYPE_PDF -#define EO FRIBIDI_TYPE_EO +#define WS FRIBIDI_PROP_TYPE_WS +#define BS FRIBIDI_PROP_TYPE_BS +#define EO FRIBIDI_PROP_TYPE_EO +#define CTL FRIBIDI_PROP_TYPE_CTL +#define LRE FRIBIDI_PROP_TYPE_LRE +#define RLE FRIBIDI_PROP_TYPE_RLE +#define ES FRIBIDI_PROP_TYPE_ES +#define LRO FRIBIDI_PROP_TYPE_LRO +#define RLO FRIBIDI_PROP_TYPE_RLO +#define AL FRIBIDI_PROP_TYPE_AL +#define SS FRIBIDI_PROP_TYPE_SS +#define ET FRIBIDI_PROP_TYPE_ET +#define NSM FRIBIDI_PROP_TYPE_NSM +#define LTR FRIBIDI_PROP_TYPE_LTR +#define ON FRIBIDI_PROP_TYPE_ON +#define AN FRIBIDI_PROP_TYPE_AN +#define BN FRIBIDI_PROP_TYPE_BN +#define RTL FRIBIDI_PROP_TYPE_RTL +#define CS FRIBIDI_PROP_TYPE_CS +#define PDF FRIBIDI_PROP_TYPE_PDF +#define EN FRIBIDI_PROP_TYPE_EN -guchar FriBidiPropertyBlock0000[256] = { +FriBidiPropCharType FriBidiPropertyBlock0000[256] = { BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,SS ,BS ,SS ,WS ,BS ,BN ,BN , BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,BN ,BS ,BS ,BS ,SS , WS ,ON ,ON ,ET ,ET ,ET ,ON ,ON ,ON ,ON ,ON ,ET ,CS ,ET ,CS ,ES , @@ -45,7 +45,7 @@ guchar FriBidiPropertyBlock0000[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,ON ,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0100[256] = { +FriBidiPropCharType FriBidiPropertyBlock0100[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -64,7 +64,7 @@ guchar FriBidiPropertyBlock0100[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0200[256] = { +FriBidiPropCharType FriBidiPropertyBlock0200[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -83,7 +83,7 @@ guchar FriBidiPropertyBlock0200[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0300[256] = { +FriBidiPropCharType FriBidiPropertyBlock0300[256] = { NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, @@ -102,7 +102,7 @@ guchar FriBidiPropertyBlock0300[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0400[256] = { +FriBidiPropCharType FriBidiPropertyBlock0400[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -121,7 +121,7 @@ guchar FriBidiPropertyBlock0400[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0500[256] = { +FriBidiPropCharType FriBidiPropertyBlock0500[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -140,7 +140,7 @@ guchar FriBidiPropertyBlock0500[256] = { RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL, }; -guchar FriBidiPropertyBlock0600[256] = { +FriBidiPropCharType FriBidiPropertyBlock0600[256] = { CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS , CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,CS ,AL ,AL ,AL ,AL ,AL , AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , @@ -159,7 +159,7 @@ guchar FriBidiPropertyBlock0600[256] = { EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,AL ,AL ,AL ,AL ,AL ,AL , }; -guchar FriBidiPropertyBlock0700[256] = { +FriBidiPropCharType FriBidiPropertyBlock0700[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,BN , AL ,NSM,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , @@ -178,7 +178,7 @@ guchar FriBidiPropertyBlock0700[256] = { NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, }; -guchar FriBidiPropertyBlock0900[256] = { +FriBidiPropCharType FriBidiPropertyBlock0900[256] = { NSM,NSM,NSM,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -197,7 +197,7 @@ guchar FriBidiPropertyBlock0900[256] = { LTR,LTR,ET ,ET ,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0a00[256] = { +FriBidiPropCharType FriBidiPropertyBlock0a00[256] = { NSM,NSM,NSM,NSM,NSM,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -216,7 +216,7 @@ guchar FriBidiPropertyBlock0a00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0b00[256] = { +FriBidiPropCharType FriBidiPropertyBlock0b00[256] = { NSM,NSM,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -235,7 +235,7 @@ guchar FriBidiPropertyBlock0b00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0c00[256] = { +FriBidiPropCharType FriBidiPropertyBlock0c00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -254,7 +254,7 @@ guchar FriBidiPropertyBlock0c00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0d00[256] = { +FriBidiPropCharType FriBidiPropertyBlock0d00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -273,7 +273,7 @@ guchar FriBidiPropertyBlock0d00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0e00[256] = { +FriBidiPropCharType FriBidiPropertyBlock0e00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -292,7 +292,7 @@ guchar FriBidiPropertyBlock0e00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock0f00[256] = { +FriBidiPropCharType FriBidiPropertyBlock0f00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,NSM,NSM,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -311,7 +311,7 @@ guchar FriBidiPropertyBlock0f00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock1000[256] = { +FriBidiPropCharType FriBidiPropertyBlock1000[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,NSM,NSM,NSM, @@ -330,7 +330,7 @@ guchar FriBidiPropertyBlock1000[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock1600[256] = { +FriBidiPropCharType FriBidiPropertyBlock1600[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -349,7 +349,7 @@ guchar FriBidiPropertyBlock1600[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock1700[256] = { +FriBidiPropCharType FriBidiPropertyBlock1700[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -368,7 +368,7 @@ guchar FriBidiPropertyBlock1700[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlock1800[256] = { +FriBidiPropCharType FriBidiPropertyBlock1800[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,BN ,BN ,BN ,BN ,BN , LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -387,7 +387,7 @@ guchar FriBidiPropertyBlock1800[256] = { NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, }; -guchar FriBidiPropertyBlock1f00[256] = { +FriBidiPropCharType FriBidiPropertyBlock1f00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -406,7 +406,7 @@ guchar FriBidiPropertyBlock1f00[256] = { ON ,ON ,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,ON ,ON ,ON , }; -guchar FriBidiPropertyBlock2000[256] = { +FriBidiPropCharType FriBidiPropertyBlock2000[256] = { WS ,WS ,WS ,WS ,WS ,WS ,WS ,WS ,WS ,WS ,WS ,BN ,BN ,BN ,LTR,RTL, ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,WS ,BS ,LRE,RLE,PDF,LRO,RLO,WS , @@ -425,7 +425,7 @@ guchar FriBidiPropertyBlock2000[256] = { NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, }; -guchar FriBidiPropertyBlock2100[256] = { +FriBidiPropCharType FriBidiPropertyBlock2100[256] = { ON ,ON ,LTR,ON ,ON ,ON ,ON ,LTR,ON ,ON ,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,ON ,LTR,ON ,ON ,ON ,LTR,LTR,LTR,LTR,LTR,ON ,ON , ON ,ON ,ON ,ON ,LTR,ON ,LTR,ON ,LTR,ON ,LTR,LTR,LTR,LTR,ET ,LTR, @@ -444,7 +444,7 @@ guchar FriBidiPropertyBlock2100[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , }; -guchar FriBidiPropertyBlock2200[256] = { +FriBidiPropCharType FriBidiPropertyBlock2200[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ET ,ET ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , @@ -463,7 +463,7 @@ guchar FriBidiPropertyBlock2200[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , }; -guchar FriBidiPropertyBlock2300[256] = { +FriBidiPropCharType FriBidiPropertyBlock2300[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , @@ -482,7 +482,7 @@ guchar FriBidiPropertyBlock2300[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , }; -guchar FriBidiPropertyBlock2400[256] = { +FriBidiPropCharType FriBidiPropertyBlock2400[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , @@ -501,7 +501,7 @@ guchar FriBidiPropertyBlock2400[256] = { EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN , }; -guchar FriBidiPropertyBlock2500[256] = { +FriBidiPropCharType FriBidiPropertyBlock2500[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , @@ -520,7 +520,7 @@ guchar FriBidiPropertyBlock2500[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , }; -guchar FriBidiPropertyBlock3000[256] = { +FriBidiPropCharType FriBidiPropertyBlock3000[256] = { WS ,ON ,ON ,ON ,ON ,LTR,LTR,LTR,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , ON ,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,NSM,NSM,NSM,NSM,NSM,NSM, @@ -539,7 +539,7 @@ guchar FriBidiPropertyBlock3000[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,ON ,LTR,LTR,LTR,LTR, }; -guchar FriBidiPropertyBlocka400[256] = { +FriBidiPropCharType FriBidiPropertyBlocka400[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -558,7 +558,7 @@ guchar FriBidiPropertyBlocka400[256] = { ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON ,ON , }; -guchar FriBidiPropertyBlockfb00[256] = { +FriBidiPropCharType FriBidiPropertyBlockfb00[256] = { LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,RTL,NSM,RTL, RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,RTL,ET ,RTL,RTL,RTL,RTL,RTL,RTL, @@ -577,7 +577,7 @@ guchar FriBidiPropertyBlockfb00[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , }; -guchar FriBidiPropertyBlockfc00[256] = { +FriBidiPropCharType FriBidiPropertyBlockfc00[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , @@ -596,7 +596,7 @@ guchar FriBidiPropertyBlockfc00[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , }; -guchar FriBidiPropertyBlockfd00[256] = { +FriBidiPropCharType FriBidiPropertyBlockfd00[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , @@ -615,7 +615,7 @@ guchar FriBidiPropertyBlockfd00[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL , }; -guchar FriBidiPropertyBlockfe00[256] = { +FriBidiPropCharType FriBidiPropertyBlockfe00[256] = { NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM,NSM, @@ -634,7 +634,7 @@ guchar FriBidiPropertyBlockfe00[256] = { AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,AL ,BN , }; -guchar FriBidiPropertyBlockff00[256] = { +FriBidiPropCharType FriBidiPropertyBlockff00[256] = { ON ,ON ,ON ,ET ,ET ,ET ,ON ,ON ,ON ,ON ,ON ,ET ,CS ,ET ,CS ,ES , EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,EN ,CS ,ON ,ON ,ON ,ON ,ON , ON ,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR, @@ -655,7 +655,7 @@ guchar FriBidiPropertyBlockff00[256] = { /* 33 blocks defined */ -guchar *FriBidiPropertyBlocks[256] = { +FriBidiPropCharType *FriBidiPropertyBlocks[256] = { FriBidiPropertyBlock0000, FriBidiPropertyBlock0100, FriBidiPropertyBlock0200, @@ -914,27 +914,27 @@ guchar *FriBidiPropertyBlocks[256] = { FriBidiPropertyBlockff00, }; -#undef LTR -#undef RTL -#undef EN -#undef ES -#undef ET -#undef AN -#undef CS +#undef WS #undef BS -#undef SS +#undef EO #undef CTL #undef LRE #undef RLE +#undef ES #undef LRO #undef RLO -#undef WS -#undef ON #undef AL +#undef SS +#undef ET #undef NSM +#undef LTR +#undef ON +#undef AN #undef BN +#undef RTL +#undef CS #undef PDF -#undef EO +#undef EN /*====================================================================== @@ -946,7 +946,7 @@ guchar *FriBidiPropertyBlocks[256] = { // but do not have any mirrored glyph, e.g. the sign for there exist. // Are these used in Arabic? That is are all the mathematical signs // that are assigned to be mirrorable actually mirrored in Arabic? -// If that is the case, I'll change the below code to include also +// If that is the case, we'll change the below code to include also // characters that mirror to themself. It will then be the responsibility // of the display engine to actually mirror these. //----------------------------------------------------------------------*/ @@ -972,6 +972,19 @@ struct { {0x207E, 0x207D}, {0x208D, 0x208E}, {0x208E, 0x208D}, + {0x2208, 0x220B}, + {0x2209, 0x220C}, + {0x220A, 0x220D}, + {0x220B, 0x2208}, + {0x220C, 0x2209}, + {0x220D, 0x220A}, + {0x223C, 0x223D}, + {0x223D, 0x223C}, + {0x2243, 0x22CD}, + {0x2252, 0x2253}, + {0x2253, 0x2252}, + {0x2254, 0x2255}, + {0x2255, 0x2254}, {0x2264, 0x2265}, {0x2265, 0x2264}, {0x2266, 0x2267}, @@ -988,20 +1001,73 @@ struct { {0x2273, 0x2272}, {0x2274, 0x2275}, {0x2275, 0x2274}, + {0x2276, 0x2277}, + {0x2277, 0x2276}, + {0x2278, 0x2279}, + {0x2279, 0x2278}, + {0x227A, 0x227B}, + {0x227B, 0x227A}, + {0x227C, 0x227D}, + {0x227D, 0x227C}, + {0x227E, 0x227F}, + {0x227F, 0x227E}, + {0x2280, 0x2281}, + {0x2281, 0x2280}, + {0x2282, 0x2283}, + {0x2283, 0x2282}, + {0x2284, 0x2285}, + {0x2285, 0x2284}, + {0x2286, 0x2287}, + {0x2287, 0x2286}, + {0x2288, 0x2289}, + {0x2289, 0x2288}, + {0x228A, 0x228B}, + {0x228B, 0x228A}, + {0x228F, 0x2290}, + {0x2290, 0x228F}, + {0x2291, 0x2292}, + {0x2292, 0x2291}, {0x22A2, 0x22A3}, {0x22A3, 0x22A2}, + {0x22B0, 0x22B1}, + {0x22B1, 0x22B0}, + {0x22B2, 0x22B3}, + {0x22B3, 0x22B2}, + {0x22B4, 0x22B5}, + {0x22B5, 0x22B4}, + {0x22B6, 0x22B7}, + {0x22B7, 0x22B6}, {0x22C9, 0x22CA}, {0x22CA, 0x22C9}, {0x22CB, 0x22CC}, {0x22CC, 0x22CB}, + {0x22CD, 0x2243}, + {0x22D0, 0x22D1}, + {0x22D1, 0x22D0}, {0x22D6, 0x22D7}, {0x22D7, 0x22D6}, {0x22D8, 0x22D9}, {0x22D9, 0x22D8}, + {0x22DA, 0x22DB}, + {0x22DB, 0x22DA}, {0x22DC, 0x22DD}, {0x22DD, 0x22DC}, + {0x22DE, 0x22DF}, + {0x22DF, 0x22DE}, + {0x22E0, 0x22E1}, + {0x22E1, 0x22E0}, + {0x22E2, 0x22E3}, + {0x22E3, 0x22E2}, + {0x22E4, 0x22E5}, + {0x22E5, 0x22E4}, {0x22E6, 0x22E7}, {0x22E7, 0x22E6}, + {0x22E8, 0x22E9}, + {0x22E9, 0x22E8}, + {0x22EA, 0x22EB}, + {0x22EB, 0x22EA}, + {0x22EC, 0x22ED}, + {0x22ED, 0x22EC}, {0x22F0, 0x22F1}, {0x22F1, 0x22F0}, {0x2308, 0x2309}, @@ -1030,4 +1096,4 @@ struct { {0x301B, 0x301A} }; -gint nFriBidiMirroredChars = 74; +gint nFriBidiMirroredChars = 140; diff --git a/pango/mini-fribidi/fribidi_types.h b/pango/mini-fribidi/fribidi_types.h index edb9637e..427737c7 100644 --- a/pango/mini-fribidi/fribidi_types.h +++ b/pango/mini-fribidi/fribidi_types.h @@ -1,100 +1,285 @@ /* FriBidi - Library of BiDi algorithm - * Copyright (C) 1999 Dov Grobgeld - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Copyright (C) 1999,2000 Dov Grobgeld, and + * Copyright (C) 2001 Behdad Esfahbod. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library, in a file named COPYING.LIB; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA + * + * For licensing issues, contact <dov@imagic.weizmann.ac.il> and + * <fwpg@sharif.edu>. */ #ifndef FRIBIDI_TYPES_H #define FRIBIDI_TYPES_H +#ifndef FRIBIDI_USE_MINI_GLIB #include <glib.h> +#else +#include "fribidi_mini_glib.h" +#endif typedef guint32 FriBidiChar; -#if 0 -/* Classifications of the various Bidi properties */ +typedef guint16 FriBidiStrIndex; + +/* Define some bit masks, that character types are based on, each one has + only one bit on. */ typedef enum { - FRIBIDI_TYPE_LTR = 0x01000000, /* Strong left to right */ - FRIBIDI_TYPE_RTL = 0x02000000, /* Strong right to left */ - FRIBIDI_TYPE_WL = 0x01000001, /* Weak left to right */ - FRIBIDI_TYPE_WR = 0x02000002, /* Weak right to left */ - FRIBIDI_TYPE_EN = 0x03000000, /* European digit */ - FRIBIDI_TYPE_ES = 0x04000000, /* European number separator */ - FRIBIDI_TYPE_ET = 0x05000000, /* European number terminator */ - FRIBIDI_TYPE_AN = 0x06000000, /* Arabic digit */ - FRIBIDI_TYPE_CS = 0x07000000, /* Common Separator */ - FRIBIDI_TYPE_BS = 0x08000000, /* Block separator */ - FRIBIDI_TYPE_SS = 0x09000000, /* Segment separator */ - FRIBIDI_TYPE_WS = 0x0A000000, /* Whitespace */ - FRIBIDI_TYPE_CTL = 0x10000090, /* Control units */ - FRIBIDI_TYPE_ON = 0x80000009, /* Other Neutral */ + FRIBIDI_MASK_RTL = 0x00000001, /* Is right to left */ + FRIBIDI_MASK_ARABIC = 0x00000002, /* Is arabic */ - /* The following are only used internally */ - FRIBIDI_TYPE_L = 0x01000000, - FRIBIDI_TYPE_R = 0x02000000, - FRIBIDI_TYPE_BN = 0xF1000000, - FRIBIDI_TYPE_CM = 0xF2000000, - FRIBIDI_TYPE_SOT = 0xF3000000, - FRIBIDI_TYPE_EOT = 0xF4000000, - FRIBIDI_TYPE_N = 0xF5000000, - FRIBIDI_TYPE_E = 0xF6000000, -} FriBidiCharType; -#endif + /* Each char can be only one of the three following. */ + FRIBIDI_MASK_STRONG = 0x00000010, /* Is strong */ + FRIBIDI_MASK_WEAK = 0x00000020, /* Is weak */ + FRIBIDI_MASK_NEUTRAL = 0x00000040, /* Is neutral */ + FRIBIDI_MASK_SENTINEL = 0x00000080, /* Is sentinel: SOT, EOT */ + /* Sentinels are not valid chars, just identify the start and end of strings. */ + + /* Each char can be only one of the five following. */ + FRIBIDI_MASK_LETTER = 0x00000100, /* Is letter: L, R, AL */ + FRIBIDI_MASK_NUMBER = 0x00000200, /* Is number: EN, AN */ + FRIBIDI_MASK_NUMSEPTER = 0x00000400, /* Is number separator or terminator: ES, ET, CS */ + FRIBIDI_MASK_SPACE = 0x00000800, /* Is space: BN, BS, SS, WS */ + FRIBIDI_MASK_EXPLICIT = 0x00001000, /* Is expilict mark: LRE, RLE, LRO, RLO, PDF */ + + /* Can be on only if FRIBIDI_MASK_SPACE is also on. */ + FRIBIDI_MASK_SEPARATOR = 0x00002000, /* Is test separator: BS, SS */ + + /* Can be on only if FRIBIDI_MASK_EXPLICIT is also on. */ + FRIBIDI_MASK_OVERRIDE = 0x00004000, /* Is explicit override: LRO, RLO */ + + /* Can be on for SOT and EOT sentinels only, not a valid char if is on. */ + + /* The following must be to make types pairwise different, some of them can + be removed but are here because of efficiency (make queries faster). */ + + FRIBIDI_MASK_ES = 0x00010000, + FRIBIDI_MASK_ET = 0x00020000, + FRIBIDI_MASK_CS = 0x00040000, + + FRIBIDI_MASK_NSM = 0x00080000, + FRIBIDI_MASK_BN = 0x00100000, + + FRIBIDI_MASK_BS = 0x00200000, + FRIBIDI_MASK_SS = 0x00400000, + FRIBIDI_MASK_WS = 0x00800000, +} +FriBidiMaskType; typedef enum { - FRIBIDI_TYPE_LTR , /* Strong left to right */ - FRIBIDI_TYPE_RTL , /* Right to left characters */ - FRIBIDI_TYPE_WL , /* Weak left to right */ - FRIBIDI_TYPE_WR , /* Weak right to left */ - FRIBIDI_TYPE_EN , /* European digit */ - FRIBIDI_TYPE_ES , /* European number separator */ - FRIBIDI_TYPE_ET , /* European number terminator */ - FRIBIDI_TYPE_AN , /* Arabic digit */ - FRIBIDI_TYPE_CS , /* Common Separator */ - FRIBIDI_TYPE_BS , /* Block separator */ - FRIBIDI_TYPE_SS , /* Segment separator */ - FRIBIDI_TYPE_WS , /* Whitespace */ - FRIBIDI_TYPE_AL , /* Arabic characters */ - FRIBIDI_TYPE_NSM , /* Non spacing mark */ - FRIBIDI_TYPE_LRE , /* Left-To-Right embedding */ - FRIBIDI_TYPE_RLE , /* Right-To-Left embedding */ - FRIBIDI_TYPE_LRO , /* Left-To-Right override */ - FRIBIDI_TYPE_RLO , /* Right-To-Left override */ - FRIBIDI_TYPE_PDF , /* Pop directional override */ - FRIBIDI_TYPE_ON , /* Other Neutral */ + FRIBIDI_TYPE_LTR = /* Strong left to right */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_LETTER, + FRIBIDI_TYPE_RTL = /* Right to left characters */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_LETTER + FRIBIDI_MASK_RTL, + FRIBIDI_TYPE_AL = /* Arabic characters */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_LETTER + + FRIBIDI_MASK_RTL + FRIBIDI_MASK_ARABIC, + FRIBIDI_TYPE_LRE = /* Left-To-Right embedding */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_EXPLICIT, + FRIBIDI_TYPE_RLE = /* Right-To-Left embedding */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_EXPLICIT + FRIBIDI_MASK_RTL, + FRIBIDI_TYPE_LRO = /* Left-To-Right override */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_EXPLICIT + FRIBIDI_MASK_OVERRIDE, + FRIBIDI_TYPE_RLO = /* Right-To-Left override */ + FRIBIDI_MASK_STRONG + FRIBIDI_MASK_EXPLICIT + + FRIBIDI_MASK_RTL + FRIBIDI_MASK_OVERRIDE, + + FRIBIDI_TYPE_PDF = /* Pop directional override */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_EXPLICIT, + FRIBIDI_TYPE_EN = /* European digit */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_NUMBER, + FRIBIDI_TYPE_AN = /* Arabic digit */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_NUMBER + FRIBIDI_MASK_ARABIC, + FRIBIDI_TYPE_ES = /* European number separator */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_NUMSEPTER + FRIBIDI_MASK_ES, + FRIBIDI_TYPE_ET = /* European number terminator */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_NUMSEPTER + FRIBIDI_MASK_ET, + FRIBIDI_TYPE_CS = /* Common Separator */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_NUMSEPTER + FRIBIDI_MASK_CS, + FRIBIDI_TYPE_NSM = /* Non spacing mark */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_NSM, + FRIBIDI_TYPE_BN = /* Boundary neutral */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_SPACE + FRIBIDI_MASK_BN, + + FRIBIDI_TYPE_BS = /* Block separator */ + FRIBIDI_MASK_NEUTRAL + FRIBIDI_MASK_SPACE + + FRIBIDI_MASK_SEPARATOR + FRIBIDI_MASK_BS, + FRIBIDI_TYPE_SS = /* Segment separator */ + FRIBIDI_MASK_NEUTRAL + FRIBIDI_MASK_SPACE + + FRIBIDI_MASK_SEPARATOR + FRIBIDI_MASK_SS, + FRIBIDI_TYPE_WS = /* Whitespace */ + FRIBIDI_MASK_NEUTRAL + FRIBIDI_MASK_SPACE + FRIBIDI_MASK_WS, + FRIBIDI_TYPE_ON = /* Other Neutral */ + FRIBIDI_MASK_NEUTRAL, + + /* The following are used to identify the paragraph direction, + types L, R, N are not used internally anymore, and recommended to use + LTR, RTL and ON instead, didn't removed because of compatability. */ + FRIBIDI_TYPE_L = FRIBIDI_TYPE_LTR, + FRIBIDI_TYPE_R = FRIBIDI_TYPE_RTL, + FRIBIDI_TYPE_N = FRIBIDI_TYPE_ON, + FRIBIDI_TYPE_WL = /* Weak left to right */ + FRIBIDI_MASK_WEAK, + FRIBIDI_TYPE_WR = /* Weak right to left */ + FRIBIDI_MASK_WEAK + FRIBIDI_MASK_RTL, /* The following are only used internally */ - FRIBIDI_TYPE_L = FRIBIDI_TYPE_LTR, - FRIBIDI_TYPE_R = FRIBIDI_TYPE_RTL, - FRIBIDI_TYPE_BN = FRIBIDI_TYPE_ON + 2, - FRIBIDI_TYPE_CM , - FRIBIDI_TYPE_SOT , - FRIBIDI_TYPE_EOT , - FRIBIDI_TYPE_N , - FRIBIDI_TYPE_E , - FRIBIDI_TYPE_CTL , /* Control units */ - FRIBIDI_TYPE_EO , /* Control units */ -} FriBidiCharType; + FRIBIDI_TYPE_SOT = /* Start of text */ + FRIBIDI_MASK_SENTINEL, + FRIBIDI_TYPE_EOT = /* End of text */ + FRIBIDI_MASK_SENTINEL + FRIBIDI_MASK_RTL, +} +FriBidiCharType; + +/* Defining macros for needed queries, It is fully dependent on the + implementation of FriBidiCharType. */ + +/* Return the direction of the level number, FRIBIDI_TYPE_LTR for even and + FRIBIDI_TYPE_RTL for odds. */ +#define FRIBIDI_LEVEL_TO_DIR(lev) (FRIBIDI_TYPE_LTR | (lev & 1)) + +/* Return the minimum level of the direction, 0 for FRIBIDI_TYPE_LTR and + 1 for FRIBIDI_TYPE_RTL and FRIBIDI_TYPE_AL. */ +#define FRIBIDI_DIR_TO_LEVEL(dir) (dir & 1) + +/* Is right to left? */ +#define FRIBIDI_IS_RTL(p) ((P) & FRIBIDI_MASK_RTL) +/* Is arabic? */ +#define FRIBIDI_IS_ARABIC(p) ((p) & FRIBIDI_MASK_ARABIC) + +/* Is strong? */ +#define FRIBIDI_IS_STRONG(p) ((p) & FRIBIDI_MASK_STRONG) +/* Is weak? */ +#define FRIBIDI_IS_WEAK(p) ((p) & FRIBIDI_MASK_WEAK) +/* Is neutral? */ +#define FRIBIDI_IS_NEUTRAL(p) ((p) & FRIBIDI_MASK_NEUTRAL) +/* Is sentinel? */ +#define FRIBIDI_IS_SENTINEL(p) ((p) & FRIBIDI_MASK_SENTINEL) + +/* Is letter: L, R, AL? */ +#define FRIBIDI_IS_LETTER(p) ((p) & FRIBIDI_MASK_LETTER) +/* Is number: EN, AN? */ +#define FRIBIDI_IS_NUMBER(p) ((p) & FRIBIDI_MASK_NUMBER) +/* Is number separator or terminator: ES, ET, CS? */ +#define FRIBIDI_IS_NUMBER_SEPARATOR_OR_TERMINATOR(p) \ + ((p) & FRIBIDI_MASK_NUMSEPTER) +/* Is space: BN, BS, SS, WS? */ +#define FRIBIDI_IS_SPACE(p) ((p) & FRIBIDI_MASK_SPACE) +/* Is explicit mark: LRE, RLE, LRO, RLO, PDF? */ +#define FRIBIDI_IS_EXPLICIT(p) ((p) & FRIBIDI_MASK_EXPLICIT) + +/* Is test separator: BS, SS? */ +#define FRIBIDI_IS_SEPARATOR(p) ((p) & FRIBIDI_MASK_SEPARATOR) + +/* Is explicit override: LRO, RLO? */ +#define FRIBIDI_IS_OVERRIDE(p) ((p) & FRIBIDI_MASK_OVERRIDE) + +/* Some more: */ + +/* Is left to right letter: LTR? */ +#define FRIBIDI_IS_LTR_LETTER(p) \ + ((p) & (FRIBIDI_MASK_LETTER | FRIBIDI_MASK_RTL) == FRIBIDI_MASK_LETTER) + +/* Is right to left letter: RTL, AL? */ +#define FRIBIDI_IS_RTL_LETTER(p) \ + ((p) & (FRIBIDI_MASK_LETTER | FRIBIDI_MASK_RTL) == \ + (FRIBIDI_MASK_LETTER | FRIBIDI_MASK_RTL)) + +/* Is ES or CS: ES, CS? */ +#define FRIBIDI_IS_ES_OR_CS(p) \ + ((p) & (FRIBIDI_MASK_ES | FRIBIDI_MASK_CS)) + +/* Is explicit or BN: LRE, RLE, LRO, RLO, PDF, BN? */ +#define FRIBIDI_IS_EXPLICIT_OR_BN(p) \ + ((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_BN)) + +/* Is explicit or separator or BN or WS: LRE, RLE, LRO, RLO, PDF, BS, SS, BN, WS? */ +#define FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS(p) \ + ((p) & (FRIBIDI_MASK_EXPLICIT | FRIBIDI_MASK_SEPARATOR | \ + FRIBIDI_MASK_BN | FRIBIDI_MASK_WS)) + +/* Define some conversions. */ + +/* Change numbers:EN, AN to RTL. */ +#define FRIBIDI_CHANGE_NUMBER_TO_RTL(p) \ + (FRIBIDI_IS_NUMBER(p) ? FRIBIDI_TYPE_RTL : (p)) + +/* Override status of an explicit mark: LRO->LTR, RLO->RTL, otherwise->ON. */ +#define FRIBIDI_EXPLICIT_TO_OVERRIDE_DIR(p) \ + (FRIBIDI_IS_OVERRIDE(p) ? FRIBIDI_LEVEL_TO_DIR(FRIBIDI_DIR_TO_LEVEL(p)) : \ + FRIBIDI_TYPE_ON) + + +guchar fribidi_char_from_type (FriBidiCharType c); + +guchar *fribidi_type_name (FriBidiCharType c); + + +/* Define character types that fribidi_tables.i uses. if MEM_OPTIMIZED + defined, then define them to be 0, 1, 2, ... and then in + fribidi_get_type.c map them on FriBidiCharType-s, else define them to + be equal to FribidiCharType-s */ +#ifdef MEM_OPTIMIZED +#define _FRIBIDI_PROP(type) FRIBIDI_PROP_TYPE_##type +typedef guint8 FriBidiPropCharType; +#else +#define _FRIBIDI_PROP(type) FRIBIDI_PROP_TYPE_##type = FRIBIDI_TYPE_##type +typedef FriBidiCharType FriBidiPropCharType; +#endif +enum +{ + _FRIBIDI_PROP (LTR), /* Strong left to right */ + _FRIBIDI_PROP (RTL), /* Right to left characters */ + _FRIBIDI_PROP (AL), /* Arabic characters */ + _FRIBIDI_PROP (LRE), /* Left-To-Right embedding */ + _FRIBIDI_PROP (RLE), /* Right-To-Left embedding */ + _FRIBIDI_PROP (LRO), /* Left-To-Right override */ + _FRIBIDI_PROP (RLO), /* Right-To-Left override */ + _FRIBIDI_PROP (PDF), /* Pop directional override */ + _FRIBIDI_PROP (EN), /* European digit */ + _FRIBIDI_PROP (AN), /* Arabic digit */ + _FRIBIDI_PROP (ES), /* European number separator */ + _FRIBIDI_PROP (ET), /* European number terminator */ + _FRIBIDI_PROP (CS), /* Common Separator */ + _FRIBIDI_PROP (NSM), /* Non spacing mark */ + _FRIBIDI_PROP (BN), /* Boundary neutral */ + _FRIBIDI_PROP (BS), /* Block separator */ + _FRIBIDI_PROP (SS), /* Segment separator */ + _FRIBIDI_PROP (WS), /* Whitespace */ + _FRIBIDI_PROP (ON), /* Other Neutral */ + _FRIBIDI_PROP (WL), /* Weak left to right */ + _FRIBIDI_PROP (WR), /* Weak right to left */ + _FRIBIDI_PROP (SOT), /* Start of text */ + _FRIBIDI_PROP (EOT), /* End of text */ +}; +#undef _FRIBIDI_PROP /* The following type is used by fribidi_utils */ -typedef struct { +typedef struct +{ int length; void *attribute; -} FriBidiRunType; +} +FriBidiRunType; + +/* TBD: The following should be configuration parameters, once we can + figure out how to make configure set them... */ +#ifndef FRIBIDI_MAX_STRING_LENGTH +#define FRIBIDI_MAX_STRING_LENGTH 65535 +#endif FriBidiCharType _pango_fribidi_get_type(FriBidiChar uch); |