summaryrefslogtreecommitdiff
path: root/trunk/pango/mini-fribidi/fribidi.patch
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/pango/mini-fribidi/fribidi.patch')
-rw-r--r--trunk/pango/mini-fribidi/fribidi.patch1369
1 files changed, 1369 insertions, 0 deletions
diff --git a/trunk/pango/mini-fribidi/fribidi.patch b/trunk/pango/mini-fribidi/fribidi.patch
new file mode 100644
index 00000000..0975dbcb
--- /dev/null
+++ b/trunk/pango/mini-fribidi/fribidi.patch
@@ -0,0 +1,1369 @@
+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 <stdlib.h>
++#include <string.h>
+
+ #ifdef HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+ #include "fribidi.h"
+-#include "fribidi_mem.h"
+-#ifdef DEBUG
+-#include <stdio.h>
+-#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 <fribidi@behdad.org>.\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;
+