diff -rua /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi.c ./fribidi.c --- /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi.c 2005-09-25 18:50:30.000000000 -0400 +++ fribidi.c 2005-12-05 11:35:07.000000000 -0500 @@ -22,15 +22,12 @@ */ #include +#include #ifdef HAVE_CONFIG_H #include #endif #include "fribidi.h" -#include "fribidi_mem.h" -#ifdef DEBUG -#include -#endif /* Redefine FRIBIDI_CHUNK_SIZE in config.h to override this. */ #ifndef FRIBIDI_CHUNK_SIZE @@ -41,19 +38,8 @@ #endif #endif -#ifdef DEBUG -#define DBG(s) do { if (fribidi_debug) { fprintf(stderr, s); } } while (0) -#define DBG2(s, t) do { if (fribidi_debug) { fprintf(stderr, s, t); } } while (0) -#else #define DBG(s) #define DBG2(s, t) -#endif - -#ifdef DEBUG -char fribidi_char_from_type (FriBidiCharType c); -#endif - -#define MAX(a,b) ((a) > (b) ? (a) : (b)) /*====================================================================== * Typedef for the run-length list. @@ -81,95 +67,20 @@ } LevelInfo; -#ifdef DEBUG -static fribidi_boolean fribidi_debug = FRIBIDI_FALSE; -#endif - -fribidi_boolean -fribidi_set_debug (fribidi_boolean debug) -{ -#ifdef DEBUG - fribidi_debug = debug; -#else - debug = 0; -#endif - return debug; -} - -static void -bidi_string_reverse (FriBidiChar *str, - FriBidiStrIndex len) -{ - FriBidiStrIndex 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, - FriBidiStrIndex len) -{ - FriBidiStrIndex i; - for (i = 0; i < len / 2; i++) - { - FriBidiStrIndex tmp = arr[i]; - arr[i] = arr[len - 1 - i]; - arr[len - 1 - i] = tmp; - } -} - -#ifndef USE_SIMPLE_MALLOC -static TypeLink *free_type_links = NULL; -#endif - static TypeLink * new_type_link (void) { TypeLink *link; -#ifdef USE_SIMPLE_MALLOC - link = malloc (sizeof (TypeLink)); -#else /* !USE_SIMPLE_MALLOC */ - if (free_type_links) - { - link = free_type_links; - free_type_links = free_type_links->next; - } - else - { - static FriBidiMemChunk *mem_chunk = NULL; - - if (!mem_chunk) - mem_chunk = fribidi_mem_chunk_create (TypeLink, - FRIBIDI_CHUNK_SIZE, - FRIBIDI_ALLOC_ONLY); - - link = fribidi_chunk_new (TypeLink, - mem_chunk); - } -#endif /* !USE_SIMPLE_MALLOC */ + link = g_slice_new0 (TypeLink); - link->len = 0; - link->pos = 0; - link->level = 0; - link->next = NULL; - link->prev = NULL; return link; } static void free_type_link (TypeLink *link) { -#ifdef USE_SIMPLE_MALLOC - free (link); -#else - link->next = free_type_links; - free_type_links = link; -#endif + g_slice_free (TypeLink, link); } #define FRIBIDI_ADD_TYPE_LINK(p,q) \ @@ -181,12 +92,18 @@ } while (0) static TypeLink * -run_length_encode_types (FriBidiCharType *char_type, - FriBidiStrIndex type_len) +run_length_encode_types_utf8 (const char *s, + int bytelen, + FriBidiStrIndex *len, + FriBidiCharType *pored_types, + FriBidiCharType *panded_strongs) { TypeLink *list, *last, *link; - + FriBidiCharType char_type; + FriBidiCharType ored_types = 0; + FriBidiCharType anded_strongs = FRIBIDI_TYPE_RLE; FriBidiStrIndex i; + const char *p; /* Add the starting link */ list = new_type_link (); @@ -194,23 +111,38 @@ list->level = FRIBIDI_LEVEL_START; last = list; - /* Sweep over the string_type s */ - for (i = 0; i < type_len; i++) - if (char_type[i] != last->type) + /* Sweep over the string s */ + i = 0; + for (p = s; p < s + bytelen; p = g_utf8_next_char(p)) { + char_type = fribidi_get_type (g_utf8_get_char (p)); + ored_types |= char_type; + if (FRIBIDI_IS_STRONG (char_type)) + anded_strongs &= char_type; + if (char_type != last->type) { link = new_type_link (); - link->type = char_type[i]; + link->type = char_type; link->pos = i; FRIBIDI_ADD_TYPE_LINK (last, link); } + i++; + } /* Add the ending link */ link = new_type_link (); link->type = FRIBIDI_TYPE_EOT; link->level = FRIBIDI_LEVEL_END; - link->pos = type_len; + link->pos = i; FRIBIDI_ADD_TYPE_LINK (last, link); + if (len) + *len = i; + + if (pored_types) + *pored_types = ored_types; + if (panded_strongs) + *panded_strongs = anded_strongs; + return list; } @@ -418,6 +350,27 @@ } } +/*====================================================================== + * Frees up the rl_list, must be called after each call to + * fribidi_analyse_string(), after the list is not needed anymore. + *----------------------------------------------------------------------*/ +static void +free_rl_list (TypeLink *type_rl_list) +{ + DBG ("Entering free_rl_list()\n"); + + if (!type_rl_list) + { + DBG ("Leaving free_rl_list()\n"); + return; + } + + g_slice_free_chain (TypeLink, type_rl_list, next); + + DBG ("Leaving free_rl_list()\n"); + return; +} + /*========================================================================= * define macros for push and pop the status in to / out of the stack *-------------------------------------------------------------------------*/ @@ -512,95 +465,22 @@ #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 char 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"); -} - -static void -print_resolved_levels (TypeLink *pp) -{ - fprintf (stderr, " Res. levels: "); - while (pp) - { - FriBidiStrIndex 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) - { - FriBidiStrIndex i; - for (i = 0; i < RL_LEN (pp); i++) - fprintf (stderr, "%c", fribidi_char_from_type (pp->type)); - pp = pp->next; - } - fprintf (stderr, "\n"); -} - -/* Here, only for test porpuses, we have assumed that a fribidi_string - ends with a 0 character */ -static void -print_bidi_string (FriBidiChar *str) -{ - FriBidiStrIndex i; - fprintf (stderr, " Org. types : "); - for (i = 0; str[i]; i++) - fprintf (stderr, "%c", - fribidi_char_from_type (fribidi_get_type (str[i]))); - fprintf (stderr, "\n"); -} -#endif /*====================================================================== * This function should follow the Unicode specification closely! *----------------------------------------------------------------------*/ -static void -fribidi_analyse_string ( /* input */ - FriBidiChar *str, - FriBidiStrIndex len, +static fribidi_boolean +fribidi_analyse_string_utf8 ( /* input */ + const char *str, + int bytelen, FriBidiCharType *pbase_dir, /* output */ + FriBidiStrIndex *len, TypeLink **ptype_rl_list, FriBidiLevel *pmax_level) { FriBidiLevel base_level, max_level; FriBidiCharType base_dir; - FriBidiStrIndex i; TypeLink *type_rl_list, *explicits_list, *explicits_list_end, *pp; DBG ("Entering fribidi_analyse_string()\n"); @@ -608,14 +488,53 @@ /* Determinate character types */ DBG (" Determine character types\n"); { - FriBidiCharType *char_type = - (FriBidiCharType *) malloc (len * sizeof (FriBidiCharType)); - for (i = 0; i < len; i++) - char_type[i] = fribidi_get_type (str[i]); + FriBidiCharType ored_types; + FriBidiCharType anded_strongs; /* Run length encode the character types */ - type_rl_list = run_length_encode_types (char_type, len); - free (char_type); + type_rl_list = run_length_encode_types_utf8 (str, bytelen, len, + &ored_types, &anded_strongs); + + /* The case that all resolved levels will be ltr. + * First, all strongs should be ltr, and one of the following: + * + * o *pbase_dir doesn't have an rtl taste. + * o there are letters, and *pbase_dir is weak. + */ + if (!FRIBIDI_IS_RTL (ored_types) && + (!FRIBIDI_IS_RTL (*pbase_dir) || + (FRIBIDI_IS_WEAK (*pbase_dir) && FRIBIDI_IS_LETTER (ored_types)) + )) + { + /* all ltr */ + free_rl_list (type_rl_list); + + *ptype_rl_list = NULL; + *pmax_level = 0; + *pbase_dir = FRIBIDI_TYPE_LTR; + + return 0; + } + /* The case that all resolved levels will be rtl is much more complex. + * First, there should be no numbers, all strongs be rtl, and one of + * the following: + * + * o *pbase_dir has an rtl taste (may be weak). + * o there are letters, and *pbase_dir is weak. + */ + else if (!FRIBIDI_IS_NUMBER (ored_types) && FRIBIDI_IS_RTL (anded_strongs) && + (FRIBIDI_IS_RTL (*pbase_dir) || + (FRIBIDI_IS_WEAK (*pbase_dir) && FRIBIDI_IS_LETTER (ored_types)) + )) + { + free_rl_list (type_rl_list); + + *ptype_rl_list = NULL; + *pmax_level = 1; + *pbase_dir = FRIBIDI_TYPE_RTL; + + return 0; + } } DBG (" Determine character types, Done\n"); @@ -646,13 +565,6 @@ DBG2 (" Base dir : %c\n", fribidi_char_from_type (base_dir)); DBG (" Finding the base level, Done\n"); -#ifdef DEBUG - if (fribidi_debug) - { - print_types_re (type_rl_list); - } -#endif - /* Explicit Levels and Directions */ DBG ("Explicit Levels and Directions\n"); { @@ -752,16 +664,6 @@ compact_list (type_rl_list); -#ifdef DEBUG - if (fribidi_debug) - { - print_types_re (type_rl_list); - print_bidi_string (str); - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); - } -#endif - /* 4. Resolving weak types */ DBG ("Resolving weak types\n"); { @@ -884,14 +786,6 @@ compact_neutrals (type_rl_list); -#ifdef DEBUG - if (fribidi_debug) - { - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); - } -#endif - /* 5. Resolving Neutral Types */ DBG ("Resolving neutral types\n"); { @@ -916,14 +810,6 @@ compact_list (type_rl_list); -#ifdef DEBUG - if (fribidi_debug) - { - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); - } -#endif - /* 6. Resolving implicit levels */ DBG ("Resolving implicit levels\n"); { @@ -952,15 +838,6 @@ 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"); @@ -976,30 +853,23 @@ p->level = p->prev->level; } -#ifdef DEBUG - if (fribidi_debug) - { - print_types_re (type_rl_list); - print_resolved_levels (type_rl_list); - print_resolved_types (type_rl_list); - } -#endif - DBG ("Reset the embedding levels\n"); { int j, k, state, pos; TypeLink *p, *q, *list, *list_end; + const char *strp = str + bytelen; + /* 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 >= -1; j--) + pos = *len - 1; + for (j = *len - 1; j >= -1; j--) { /* if state is on at the very first of string, do this too. */ if (j >= 0) - k = fribidi_get_type (str[j]); + k = fribidi_get_type (g_utf8_get_char (strp = g_utf8_prev_char (strp))); else k = FRIBIDI_TYPE_ON; if (!state && FRIBIDI_IS_SEPARATOR (k)) @@ -1023,395 +893,59 @@ override_list (type_rl_list, 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; *pbase_dir = base_dir; DBG ("Leaving fribidi_analyse_string()\n"); - return; -} - -/*====================================================================== - * Frees up the rl_list, must be called after each call to - * fribidi_analyse_string(), after the list is not needed anymore. - *----------------------------------------------------------------------*/ -static void -free_rl_list (TypeLink *type_rl_list) -{ - - TypeLink *pp; - - DBG ("Entering free_rl_list()\n"); - - if (!type_rl_list) - { - DBG ("Leaving free_rl_list()\n"); - return; - } - -#ifdef USE_SIMPLE_MALLOC - pp = type_rl_list; - while (pp) - { - TypeLink *p; - - p = pp; - pp = pp->next; - free_type_link (p); - }; -#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 - - DBG ("Leaving free_rl_list()\n"); - return; -} - -static fribidi_boolean mirroring = FRIBIDI_TRUE; - -FRIBIDI_API fribidi_boolean -fribidi_mirroring_status (void) -{ - return mirroring; -} - -FRIBIDI_API void -fribidi_set_mirroring (fribidi_boolean mirror) -{ - mirroring = mirror; -} - -static fribidi_boolean reorder_nsm = FRIBIDI_FALSE; - -fribidi_boolean -fribidi_reorder_nsm_status (void) -{ - return reorder_nsm; -} - -FRIBIDI_API void -fribidi_set_reorder_nsm (fribidi_boolean reorder) -{ - reorder_nsm = reorder; -} - -/*====================================================================== - * Here starts the exposed front end functions. - *----------------------------------------------------------------------*/ - -/*====================================================================== - * fribidi_remove_bidi_marks() removes bidirectional marks, and returns - * the new length, updates each of other inputs if not NULL. - *----------------------------------------------------------------------*/ -FRIBIDI_API FriBidiStrIndex -fribidi_remove_bidi_marks (FriBidiChar *str, - FriBidiStrIndex length, - FriBidiStrIndex *position_to_this_list, - FriBidiStrIndex *position_from_this_list, - FriBidiLevel *embedding_level_list) -{ - FriBidiStrIndex i, j; - fribidi_boolean private_from_this = FRIBIDI_FALSE; - - DBG ("Entering fribidi_remove_bidi_marks()\n"); - - /* If to_this is to not null, we must have from_this as well. If it is - not given by the caller, we have to make a private instance of it. */ - if (position_to_this_list && !position_from_this_list) - { - private_from_this = FRIBIDI_TRUE; - position_from_this_list = - (FriBidiStrIndex *) malloc (sizeof (FriBidiStrIndex) * length); - } - - j = 0; - for (i = 0; i < length; i++) - if (!FRIBIDI_IS_EXPLICIT (fribidi_get_type (str[i])) - && str[i] != UNI_LRM && str[i] != UNI_RLM) - { - str[j] = str[i]; - if (embedding_level_list) - embedding_level_list[j] = embedding_level_list[i]; - if (position_from_this_list) - position_from_this_list[j] = position_from_this_list[i]; - j++; - } - - /* Convert the from_this list to to_this */ - if (position_to_this_list) - { - DBG (" Converting from_this list to to_this\n"); - for (i = 0; i < length; i++) - position_to_this_list[i] = -1; - for (i = 0; i < length; i++) - position_to_this_list[position_from_this_list[i]] = i; - DBG (" Converting from_this list to to_this, Done\n"); - } - - if (private_from_this) - free (position_from_this_list); - - DBG ("Leaving fribidi_remove_bidi_marks()\n"); - return j; -} - - -/*====================================================================== - * fribidi_log2vis() calls the function_analyse_string() and then - * does reordering and fills in the output strings. - *----------------------------------------------------------------------*/ -FRIBIDI_API fribidi_boolean -fribidi_log2vis ( /* input */ - FriBidiChar *str, - FriBidiStrIndex len, - FriBidiCharType *pbase_dir, - /* output */ - FriBidiChar *visual_str, - FriBidiStrIndex *position_L_to_V_list, - FriBidiStrIndex *position_V_to_L_list, - FriBidiLevel *embedding_level_list) -{ - TypeLink *type_rl_list, *pp = NULL; - FriBidiLevel max_level; - fribidi_boolean private_V_to_L = FRIBIDI_FALSE; - - DBG ("Entering fribidi_log2vis()\n"); - - if (len == 0) - { - DBG ("Leaving fribidi_log2vis()\n"); - return FRIBIDI_TRUE; - } - - /* If l2v is to be calculated we must have v2l 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 = FRIBIDI_TRUE; - position_V_to_L_list = - (FriBidiStrIndex *) malloc (sizeof (FriBidiStrIndex) * len); - } - - if (len > FRIBIDI_MAX_STRING_LENGTH && position_V_to_L_list) - { -#ifdef DEBUG - fprintf (stderr, "%s: cannot handle strings > %ld characters\n", - FRIBIDI_PACKAGE, (long) FRIBIDI_MAX_STRING_LENGTH); -#endif - return FRIBIDI_FALSE; - } - fribidi_analyse_string (str, len, pbase_dir, - /* output */ - &type_rl_list, &max_level); - - /* 7. Reordering resolved levels */ - DBG ("Reordering resolved levels\n"); - { - FriBidiLevel level_idx; - FriBidiStrIndex i; - - /* Set up the ordering array to sorted order */ - if (position_V_to_L_list) - { - DBG (" Initialize position_V_to_L_list\n"); - for (i = 0; i < len; i++) - position_V_to_L_list[i] = i; - DBG (" Initialize position_V_to_L_list, Done\n"); - } - /* Copy the logical string to the visual */ - if (visual_str) - { - DBG (" Initialize visual_str\n"); - for (i = 0; i < len; i++) - visual_str[i] = str[i]; - visual_str[len] = 0; - DBG (" Initialize visual_str, Done\n"); - } - - /* Assign the embedding level array */ - if (embedding_level_list) - { - DBG (" Fill the embedding levels array\n"); - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - FriBidiStrIndex i, pos, len; - FriBidiLevel level; - - pos = pp->pos; - len = pp->len; - level = pp->level; - for (i = 0; i < len; i++) - embedding_level_list[pos + i] = level; - } - DBG (" Fill the embedding levels array, Done\n"); - } - - /* 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. */ - DBG (" Mirroring\n"); - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - if (pp->level & 1) - { - FriBidiStrIndex 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; - } - } - } - DBG (" Mirroring, Done\n"); - } - - if (reorder_nsm) - { - /* L3. Reorder NSMs. */ - DBG (" Reordering NSM sequences\n"); - /* We apply this rule before L2, so go backward in odd levels. */ - for (pp = type_rl_list->next; pp->next; pp = pp->next) - { - if (pp->level & 1) - { - FriBidiStrIndex i, seq_end = 0; - fribidi_boolean is_nsm_seq; - - is_nsm_seq = FRIBIDI_FALSE; - for (i = RL_POS (pp) + RL_LEN (pp) - 1; i >= RL_POS (pp); - i--) - { - FriBidiCharType this_type; - - this_type = fribidi_get_type (str[i]); - if (is_nsm_seq && this_type != FRIBIDI_TYPE_NSM) - { - if (visual_str) - { - bidi_string_reverse (visual_str + i, - seq_end - i + 1); - } - if (position_V_to_L_list) - { - index_array_reverse (position_V_to_L_list + i, - seq_end - i + 1); - } - is_nsm_seq = 0; - } - else if (!is_nsm_seq && this_type == FRIBIDI_TYPE_NSM) - { - seq_end = i; - is_nsm_seq = 1; - } - } - if (is_nsm_seq) - { - DBG - ("Warning: NSMs at the beggining of run level.\n"); - } - } - } - DBG (" Reordering NSM sequences, Done\n"); - } - - /* L2. Reorder. */ - DBG (" Reordering\n"); - 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 */ - FriBidiStrIndex len = RL_LEN (pp), - 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); - } - } - } - DBG (" Reordering, Done\n"); - } - - /* Convert the v2l list to l2v */ - if (position_L_to_V_list) - { - DBG (" Converting v2l list to l2v\n"); - for (i = 0; i < len; i++) - position_L_to_V_list[position_V_to_L_list[i]] = i; - DBG (" Converting v2l list to l2v, Done\n"); - } - } - DBG ("Reordering resolved levels, Done\n"); - - if (private_V_to_L) - free (position_V_to_L_list); - - free_rl_list (type_rl_list); - - DBG ("Leaving fribidi_log2vis()\n"); - return FRIBIDI_TRUE; - + return 1; } /*====================================================================== * fribidi_log2vis_get_embedding_levels() is used in order to just get * the embedding levels. *----------------------------------------------------------------------*/ -FRIBIDI_API fribidi_boolean -fribidi_log2vis_get_embedding_levels ( /* input */ - FriBidiChar *str, - FriBidiStrIndex len, - FriBidiCharType *pbase_dir, - /* output */ - FriBidiLevel *embedding_level_list) +FRIBIDI_API FriBidiLevel * +fribidi_log2vis_get_embedding_levels_new_utf8 ( /* input */ + const char *str, + int bytelen, + FriBidiCharType *pbase_dir) { TypeLink *type_rl_list, *pp; - FriBidiLevel max_level; + FriBidiLevel max_level, *embedding_level_list; + FriBidiStrIndex len; DBG ("Entering fribidi_log2vis_get_embedding_levels()\n"); - if (len == 0) + if (bytelen == 0) { DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n"); - return FRIBIDI_TRUE; + return NULL; } - fribidi_analyse_string (str, len, pbase_dir, + if (!fribidi_analyse_string_utf8 (str, bytelen, pbase_dir, /* output */ - &type_rl_list, &max_level); + &len, &type_rl_list, &max_level)) + { + /* unidirectional. return all-zero or all-one embedding levels */ + + if (max_level) + { + embedding_level_list = g_new (FriBidiLevel, len); + /* assumes sizeof(FriBidiLevel) == 1, which is true! */ + memset (embedding_level_list, max_level, len); + return embedding_level_list; + } + else + { + return g_new0 (FriBidiLevel, len); + } + } + embedding_level_list = g_new (FriBidiLevel, len); for (pp = type_rl_list->next; pp->next; pp = pp->next) { - FriBidiStrIndex i, pos = RL_POS (pp), - len = RL_LEN (pp); + FriBidiStrIndex i, pos = RL_POS (pp), len = RL_LEN (pp); FriBidiLevel level = RL_LEVEL (pp); for (i = 0; i < len; i++) embedding_level_list[pos + i] = level; @@ -1420,34 +954,6 @@ free_rl_list (type_rl_list); DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n"); - return FRIBIDI_TRUE; + return embedding_level_list; } - - -const char *fribidi_version_info = - FRIBIDI_PACKAGE " " FRIBIDI_VERSION "\n" "interface version " - TOSTR (FRIBIDI_INTERFACE_VERSION) - "\n" - "Unicode version " FRIBIDI_UNICODE_VERSION "\n" - "\n" - "Copyright (C) 2001,2002,2005 Behdad Esfahbod .\n" - "Copyright (C) 1999,2000 Dov Grobgeld\n" - FRIBIDI_PACKAGE " comes with NO WARRANTY, to the extent permitted by law.\n" - "You may redistribute copies of " FRIBIDI_PACKAGE " under the terms of\n" - "the GNU Lesser General Public License.\n" - "For more information about these matters, see the files named COPYING.\n" - "\n" "Configured with following options:\n" -#ifdef DEBUG - "--enable-debug\n" -#endif -#ifdef MEM_OPTIMIZED - "--enable-memopt\n" -#endif -#ifdef USE_SIMPLE_MALLOC - "--enable-malloc\n" -#endif -#ifdef FRIBIDI_NO_CHARSETS - "--without-charsts\n" -#endif -; diff -rua /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi_char_type.c ./fribidi_char_type.c --- /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi_char_type.c 2005-09-25 18:31:19.000000000 -0400 +++ ./fribidi_char_type.c 2005-11-03 11:30:26.000000000 -0500 @@ -24,29 +24,6 @@ #endif #include "fribidi.h" -/*====================================================================== - * fribidi_get_type() returns the bidi type of a character. - *----------------------------------------------------------------------*/ -FRIBIDI_API FriBidiCharType fribidi_get_type_internal (FriBidiChar uch); - -FRIBIDI_API FriBidiCharType -fribidi_get_type (FriBidiChar uch) -{ - return fribidi_get_type_internal (uch); -} - -FRIBIDI_API void -fribidi_get_types ( /* input */ - FriBidiChar *str, FriBidiStrIndex len, - /* output */ - FriBidiCharType *type) -{ - FriBidiStrIndex i; - - for (i = 0; i < len; i++) - type[i] = fribidi_get_type (str[i]); -} - #ifdef MEM_OPTIMIZED #if HAS_FRIBIDI_TAB_CHAR_TYPE_9_I diff -rua /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi.h ./fribidi.h --- /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi.h 2005-09-25 14:43:38.000000000 -0400 +++ ./fribidi.h 2005-11-03 11:30:26.000000000 -0500 @@ -29,252 +29,26 @@ #endif #include "fribidi_config.h" -#include "fribidi_unicode.h" #include "fribidi_types.h" -#ifndef FRIBIDI_NO_CHARSETS -#include "fribidi_char_sets.h" -#endif #ifdef __cplusplus extern "C" { #endif - FRIBIDI_API fribidi_boolean fribidi_log2vis ( /* input */ - FriBidiChar *str, - FriBidiStrIndex len, - FriBidiCharType *pbase_dirs, - /* output */ - FriBidiChar *visual_str, - FriBidiStrIndex - *position_L_to_V_list, - FriBidiStrIndex - *position_V_to_L_list, - FriBidiLevel - *embedding_level_list); - - FRIBIDI_API fribidi_boolean fribidi_log2vis_get_embedding_levels ( /* input */ - FriBidiChar - *str, - FriBidiStrIndex - len, - FriBidiCharType - *pbase_dir, - /* output */ - FriBidiLevel - *embedding_level_list); +#define FRIBIDI_HAVE_UTF8 -/*====================================================================== - * fribidi_remove_bidi_marks() removes bidirectional marks, and returns - * the new length, also updates each of other inputs if not NULL. - *----------------------------------------------------------------------*/ - FRIBIDI_API FriBidiStrIndex fribidi_remove_bidi_marks (FriBidiChar *str, - FriBidiStrIndex - length, - FriBidiStrIndex - *position_to_this_list, - FriBidiStrIndex - *position_from_this_list, - FriBidiLevel - *embedding_level_list); + FRIBIDI_API FriBidiLevel *fribidi_log2vis_get_embedding_levels_new_utf8 ( /* input */ + const char *str, + int bytelen, + FriBidiCharType + *pbase_dir); /*====================================================================== * fribidi_get_type() returns bidi type of a character. *----------------------------------------------------------------------*/ FRIBIDI_API FriBidiCharType fribidi_get_type (FriBidiChar uch); -/*====================================================================== - * fribidi_get_types() returns bidi type of a string. - *----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_get_types ( /* input */ - FriBidiChar *str, - FriBidiStrIndex len, - /* output */ - FriBidiCharType *type); - -/*====================================================================== - * fribidi_get_mirror_char() returns the mirrored character, if input - * character has a mirror, or the input itself. - * if mirrored_ch is NULL, just returns if character has a mirror or not. - *----------------------------------------------------------------------*/ - FRIBIDI_API fribidi_boolean fribidi_get_mirror_char ( /* Input */ - FriBidiChar ch, - /* Output */ - FriBidiChar - *mirrored_ch); - -/*====================================================================== - * fribidi_mirroring_status() returns whether mirroring is on or off, - * default is on. - *----------------------------------------------------------------------*/ - FRIBIDI_API fribidi_boolean fribidi_mirroring_status (void); - -/*====================================================================== - * fribidi_set_mirroring() sets mirroring on or off. - *----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_set_mirroring (fribidi_boolean mirror); - -/*====================================================================== - * fribidi_reorder_nsm_status() returns whether reordering of NSM - * sequences is on or off, default is off. - *----------------------------------------------------------------------*/ - FRIBIDI_API fribidi_boolean fribidi_reorder_nsm_status (void); - -/*====================================================================== - * fribidi_set_reorder_nsm() sets reordering of NSM characters on or off. - *----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_set_reorder_nsm (fribidi_boolean); - -/*====================================================================== - * fribidi_set_debug() turn on or off debugging, default is off, return - * false is fribidi is not compiled with debug enabled. - *----------------------------------------------------------------------*/ - FRIBIDI_API fribidi_boolean fribidi_set_debug (fribidi_boolean debug); - -/* fribidi_utils.c */ - -/*====================================================================== - * fribidi_find_string_changes() finds the bounding box of the section - * of characters that need redrawing. It returns the start and the - * length of the section in the new string that needs redrawing. - *----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_find_string_changes ( /* input */ - FriBidiChar *old_str, - FriBidiStrIndex old_len, - FriBidiChar *new_str, - FriBidiStrIndex new_len, - /* output */ - FriBidiStrIndex - *change_start, - FriBidiStrIndex *change_len); - - -/*====================================================================== - * The find_visual_ranges() function is used to convert between a - * continous span in either logical or visual space to a one, two or - * three discontinous spans in the other space. The function outputs - * the number of ranges needed to display the mapped range as - * well as the resolved ranges. - * - * The variable is_v2l_map indicates whether the position map is - * is in the direction of visual-to-logical. This information is - * needed in order to look up the correct character from the - * embedding_level_list which is assumed to be in logical order. - * - * This function is typically used to resolve a logical range to visual - * ranges e.g. to display the selection. - * - * Example: - * The selection is between logical characters 10 to 45. Calculate - * the corresponding visual selection(s): - * - * FriBidiStrIndex sel_span[2] = {10,45}; - * - * fribidi_map_range(sel_span, - * TRUE, - * length, - * vis2log_map, - * embedding_levels, - * // output - * &num_vis_ranges, *vis_ranges); - **----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_map_range (FriBidiStrIndex span[2], - FriBidiStrIndex len, - fribidi_boolean is_v2l_map, - FriBidiStrIndex *position_map, - FriBidiLevel *embedding_level_list, - /* output */ - int *num_mapped_spans, - FriBidiStrIndex spans[3][2]); - -/*====================================================================== - * fribidi_is_char_rtl() answers the question whether a character - * was resolved in the rtl direction. This simply involves asking - * if the embedding level for the character is odd. - *----------------------------------------------------------------------*/ - FRIBIDI_API fribidi_boolean fribidi_is_char_rtl (FriBidiLevel - *embedding_level_list, - FriBidiCharType base_dir, - FriBidiStrIndex idx); - -/*====================================================================== - * fribidi_xpos_resolve() does the complicated translation of - * an x-coordinate, e.g. as received through a mouse press event, - * to the logical and the visual position the xcoordinate is closest - * to. It will also resolve the direction of the cursor according - * to the embedding level of the closest character. - * - * It does this through the following logics: - * Here are the different possibilities: - * - * Pointer => Log Pos Vis pos - * - * Before first vis char log_pos(vis=0)L 0 - * After last vis char log_pos(vis=n-1)R n - * Within 1/2 width of vis char i log_pos(vis=i)L i - * Within last 1/2 width of vchar i log_pos(vis=i)R i+1 - * Border between vis chars i,i+1 resolve! i+1 - * - * Input: - * x_pos The pixel position to be resolved measured in pixels. - * x_offset The x_offset is the pixel position of the left side - * of the leftmost visual character. - * len The length of the embedding level, the vis2log and - * the char width arrays. - * base_dir The resolved base direction of the line. - * vis2log The vis2log mapping. - * x_position and the character widths. The position - * (x_pos-x_offset) is number of pixels from the left - * of logical character 0. - * char_widths Width in pixels of each character. Note that the - * widths should be provided in logical order. - * - * Output: - * res_log_pos Resolved logical position. - * res_vis_pos Resolved visual position - * res_cursor_x_pos The resolved pixel position to the left or - * the right of the character position x_pos. - * res_cursor_dir_is_rtl Whether the resolved dir of the character - * at position x_pos is rtl. - * res_attach_before Whether the x_pos is cutting the bounding - * box in such a way that the visual cursor should be - * be positioned before the following logical character. - * Note that in the bidi context, the positions "after - * a logical character" and "before the following logical - * character" is not necessarily the same. If x_pos is - * beyond the end of the line, res_attach_before is true. - * - *----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_xpos_resolve (int x_pos, - int x_offset, - FriBidiStrIndex len, - FriBidiLevel *embedding_level_list, - FriBidiCharType base_dir, - FriBidiStrIndex *vis2log, - int *char_widths, - /* output */ - FriBidiStrIndex *res_log_pos, - FriBidiStrIndex *res_vis_pos, - int *res_cursor_x_pos, - fribidi_boolean - *res_cursor_dir_is_rtl, - fribidi_boolean *res_attach_before); - -/*====================================================================== - * fribidi_runs_log2vis takes a list of logical runs and returns a - * a list of visual runs. A run is defined as a sequence that has - * the same attributes. - *----------------------------------------------------------------------*/ - FRIBIDI_API void fribidi_runs_log2vis ( /* input */ - FriBidiList *logical_runs, /* List of FriBidiRunType */ - - FriBidiStrIndex len, - FriBidiStrIndex *log2vis, - FriBidiCharType base_dir, - /* output */ - FriBidiList **visual_runs); - - #ifdef __cplusplus } #endif diff -rua /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi_types.c ./fribidi_types.c --- /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi_types.c 2005-09-25 16:41:35.000000000 -0400 +++ ./fribidi_types.c 2005-11-03 11:30:26.000000000 -0500 @@ -80,44 +80,6 @@ #endif -char * -fribidi_type_name (FriBidiCharType c) -{ -#define _FRIBIDI_CASE(type) case FRIBIDI_TYPE_##type: return #type - switch (c) - { - _FRIBIDI_CASE (LTR); - _FRIBIDI_CASE (RTL); - _FRIBIDI_CASE (AL); - - _FRIBIDI_CASE (EN); - _FRIBIDI_CASE (AN); - _FRIBIDI_CASE (ES); - _FRIBIDI_CASE (ET); - _FRIBIDI_CASE (CS); - _FRIBIDI_CASE (NSM); - _FRIBIDI_CASE (BN); - - _FRIBIDI_CASE (BS); - _FRIBIDI_CASE (SS); - _FRIBIDI_CASE (WS); - _FRIBIDI_CASE (ON); - - _FRIBIDI_CASE (LRE); - _FRIBIDI_CASE (RLE); - _FRIBIDI_CASE (LRO); - _FRIBIDI_CASE (RLO); - _FRIBIDI_CASE (PDF); - - _FRIBIDI_CASE (SOT); - _FRIBIDI_CASE (EOT); - - default: - return "?"; - } -#undef _FRIBIDI_CASE -} - /* Map fribidi_prop_types to fribidi_types. */ const FriBidiCharType fribidi_prop_to_type[] = { #define _FRIBIDI_ADD_TYPE(TYPE) FRIBIDI_TYPE_##TYPE, diff -rua /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi_types.h ./fribidi_types.h --- /home/behdad/src/fdo/fribidi/fribidi.stable/fribidi_types.h 2005-09-25 18:49:59.000000000 -0400 +++ ./fribidi_types.h 2005-11-03 11:30:26.000000000 -0500 @@ -25,44 +25,26 @@ #include "fribidi_config.h" -#define FRIBIDI_INT8 char -#if FRIBIDI_SIZEOF_INT+0 == 2 -# define FRIBIDI_INT16 int -#elif FRIBIDI_SIZEOF_SHORT+0 == 2 -# define FRIBIDI_INT16 short -#else -# error cannot determine a 16-bit integer type. check fribidi_config.h -#endif -#if FRIBIDI_SIZEOF_INT+0 == 4 -# define FRIBIDI_INT32 int -#elif FRIBIDI_SIZEOF_LONG+0 == 4 -# define FRIBIDI_INT32 long -#else -# error cannot determine a 32-bit integer type. check fribidi_config.h -#endif - - #ifdef __cplusplus extern "C" { #endif - typedef int fribidi_boolean; - - typedef signed FRIBIDI_INT8 fribidi_int8; - typedef unsigned FRIBIDI_INT8 fribidi_uint8; - typedef signed FRIBIDI_INT16 fribidi_int16; - typedef unsigned FRIBIDI_INT16 fribidi_uint16; - typedef signed FRIBIDI_INT32 fribidi_int32; - typedef unsigned FRIBIDI_INT32 fribidi_uint32; + typedef gboolean fribidi_boolean; - typedef signed int fribidi_int; - typedef unsigned int fribidi_uint; + typedef gint8 fribidi_int8; + typedef guint8 fribidi_uint8; + typedef gint16 fribidi_int16; + typedef guint16 fribidi_uint16; + typedef gint32 fribidi_int32; + typedef guint32 fribidi_uint32; + typedef gint fribidi_int; + typedef guint fribidi_uint; typedef fribidi_int8 FriBidiLevel; - typedef fribidi_uint32 FriBidiChar; - typedef fribidi_int FriBidiStrIndex; + typedef gunichar FriBidiChar; + typedef gsize FriBidiStrIndex; typedef fribidi_int32 FriBidiMaskType; typedef FriBidiMaskType FriBidiCharType;