Index: configure.in
===================================================================
RCS file: /cvs/gnome/pango/configure.in,v
retrieving revision 1.208
diff -u -p -r1.208 configure.in
--- configure.in	15 Aug 2005 22:45:13 -0000	1.208
+++ configure.in	3 Nov 2005 16:41:28 -0000
@@ -205,13 +205,27 @@ else
 fi
 AM_CONDITIONAL(HAVE_X, $have_x) 
 
-#
-# Check for fontconfig
-#
 have_fontconfig=false
 have_freetype=false
 have_xft=false
+have_fribidi=false
+
+#
+# Check for fribidi
+#
+AC_ARG_WITH(fribidi,
+	    AC_HELP_STRING([--with-fribidi],
+	    		   [use GNU FriBidi installed on the system]),
+	    test $withval = "yes" && have_fribidi=true, :)
 
+if $have_fribidi ; then
+  PKG_CHECK_MODULES(FRIBIDI, fribidi >= 0.10.4)
+  AC_DEFINE(HAVE_FRIBIDI, 1, [Using GNU FriBidi installed on the system])
+fi
+
+#
+# Check for fontconfig
+#
 PKG_CHECK_MODULES(FONTCONFIG, fontconfig >= 1.0.1, have_fontconfig=true, :)
 
 if $have_fontconfig ; then
@@ -296,6 +310,7 @@ if $have_cairo ; then
   LDFLAGS=$pango_save_ldflags
 fi
 
+AM_CONDITIONAL(HAVE_FRIBIDI, $have_fribidi)
 AM_CONDITIONAL(HAVE_CAIRO, $have_cairo)
 AM_CONDITIONAL(HAVE_CAIRO_WIN32, $have_cairo_win32 && $have_win32)
 AM_CONDITIONAL(HAVE_CAIRO_FREETYPE, $have_cairo_freetype && $have_freetype)
Index: docs/tmpl/main.sgml
===================================================================
RCS file: /cvs/gnome/pango/docs/tmpl/main.sgml,v
retrieving revision 1.36
diff -u -p -r1.36 main.sgml
--- docs/tmpl/main.sgml	21 Jul 2005 13:55:18 -0000	1.36
+++ docs/tmpl/main.sgml	3 Nov 2005 16:41:28 -0000
@@ -296,18 +296,6 @@ The GObject type for #PangoDirection.
 @Returns: 
 
 
-<!-- ##### FUNCTION pango_unichar_direction ##### -->
-<para>
-Determines the direction of a character; either
-%PANGO_DIRECTION_LTR, %PANGO_DIRECTION_RTL, or
-%PANGO_DIRECTION_NEUTRAL.
-</para>
-
-@ch: character to examine
-@Returns:  the direction of a character, as used in the
-  Unicode bidirectional algorithm.
-
-
 <!-- ##### FUNCTION pango_find_base_dir ##### -->
 <para>
 
Index: pango/Makefile.am
===================================================================
RCS file: /cvs/gnome/pango/pango/Makefile.am,v
retrieving revision 1.123
diff -u -p -r1.123 Makefile.am
--- pango/Makefile.am	22 Sep 2005 15:00:39 -0000	1.123
+++ pango/Makefile.am	3 Nov 2005 16:41:28 -0000
@@ -8,7 +8,12 @@ if HAVE_FREETYPE
 OPENTYPE_SUBDIR=opentype
 endif
 
-SUBDIRS = $(OPENTYPE_SUBDIR) mini-fribidi
+if HAVE_FRIBIDI
+else
+FRIBIDI_SUBDIR=mini-fribidi
+endif
+
+SUBDIRS = $(OPENTYPE_SUBDIR) $(FRIBIDI_SUBDIR)
 
 DIST_SUBDIRS = mini-fribidi opentype
 
@@ -42,8 +47,16 @@ endif
 lib_LTLIBRARIES = libpango-1.0.la
 
 libpango_1_0_la_LDFLAGS = $(LIBRARY_LIBTOOL_OPTIONS)
-libpango_1_0_la_LIBADD = $(GLIB_LIBS) mini-fribidi/libmini-fribidi.la $(libm)
-libpango_1_0_la_DEPENDENCIES = mini-fribidi/libmini-fribidi.la
+libpango_1_0_la_LIBADD = $(GLIB_LIBS) $(libm)
+libpango_1_0_la_DEPENDENCIES = 
+
+if HAVE_FRIBIDI
+libpango_1_0_la_LIBADD += $(FRIBIDI_LIBS)
+INCLUDES += $(FRIBIDI_CFLAGS)
+else
+libpango_1_0_la_LIBADD += mini-fribidi/libmini-fribidi.la
+libpango_1_0_la_DEPENDENCIES += mini-fribidi/libmini-fribidi.la
+endif
 
 if OS_WIN32
 libpango_1_0_la_LDFLAGS += -export-symbols $(srcdir)/pango.def -Wl,pango-win32-res.o
Index: pango/pango-context.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-context.c,v
retrieving revision 1.77
diff -u -p -r1.77 pango-context.c
--- pango/pango-context.c	14 Jun 2005 19:54:18 -0000	1.77
+++ pango/pango-context.c	3 Nov 2005 16:41:28 -0000
@@ -659,11 +659,7 @@ itemize_state_init (ItemizeState      *s
   /* First, apply the bidirectional algorithm to break
    * the text into directional runs.
    */
-  text_ucs4 = g_utf8_to_ucs4_fast (text + start_index, length, &n_chars);
-  state->embedding_levels = g_new (guint8, n_chars);
-  pango_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
-                                      state->embedding_levels);
-  g_free (text_ucs4);
+  state->embedding_levels = pango_log2vis_get_embedding_levels (text + start_index, length, &base_dir);
   
   state->embedding_end_offset = 0;
   state->embedding_end = text + start_index;
Index: pango/pango-utils.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-utils.c,v
retrieving revision 1.59
diff -u -p -r1.59 pango-utils.c
--- pango/pango-utils.c	27 Jul 2005 22:14:46 -0000	1.59
+++ pango/pango-utils.c	3 Nov 2005 16:41:29 -0000
@@ -32,7 +32,9 @@
 #include <glib/gstdio.h>
 
 #ifdef HAVE_FRIBIDI
-#include <fribidi/fribidi.h>
+#  include <fribidi/fribidi.h>
+#else
+#  include <mini-fribidi/fribidi.h>
 #endif
 
 #ifndef HAVE_FLOCKFILE
@@ -1402,28 +1404,88 @@ pango_language_get_sample_string (PangoL
   return result;
 }
 
-#ifdef HAVE_FRIBIDI
-
-gboolean
-pango_log2vis_get_embedding_levels (gunichar       *str,
-				    int             len,
-				    PangoDirection *pbase_dir,
-				    guint8         *embedding_level_list)
+guint8 *
+pango_log2vis_get_embedding_levels (const gchar    *str,
+				    int             bytelen,
+				    PangoDirection *pbase_dir)
 {
   FriBidiCharType fribidi_base_dir;
   gboolean result;
+  guint8 *embedding_levels_list;
 
-  fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ? FRIBIDI_TYPE_L : FRIBIDI_TYPE_R;
+  switch (*pbase_dir)
+    {
+    case PANGO_DIRECTION_LTR:
+    case PANGO_DIRECTION_TTB_RTL:
+      fribidi_base_dir = FRIBIDI_TYPE_L;
+      break;
+    case PANGO_DIRECTION_RTL:
+    case PANGO_DIRECTION_TTB_LTR:
+      fribidi_base_dir = FRIBIDI_TYPE_R;
+      break;
+    case PANGO_DIRECTION_WEAK_RTL:
+      fribidi_base_dir = FRIBIDI_TYPE_WR;
+      break;
+    /*
+    case PANGO_DIRECTION_WEAK_LTR:
+    case PANGO_DIRECTION_NEUTRAL:
+    */
+    default:
+      fribidi_base_dir = FRIBIDI_TYPE_WL;
+      break;
+    }
+
+  /* make sure fribidi does not go insane */
+  if (sizeof (gunichar) != sizeof (FriBidiChar))
+    g_assert_not_reached ();
+
+#ifdef FRIBIDI_HAVE_UTF8
+  {
+    if (bytelen < 0)
+      bytelen = strlen (str);
+    embedding_levels_list = fribidi_log2vis_get_embedding_levels_new_utf8 (str, bytelen, &fribidi_base_dir);
+  }
+#else
+  {
+    gunichar *text_ucs4;
+    int n_chars;
+    text_ucs4 = g_utf8_to_ucs4_fast (str, bytelen, &n_chars);
+    embedding_levels_list = g_new (guint8, n_chars);
+    fribidi_log2vis_get_embedding_levels ((FriBidiChar*)text_ucs4, n_chars,
+					  &fribidi_base_dir,
+					  (FriBidiLevel*)embedding_levels_list);
+    g_free (text_ucs4);
+  }
+#endif
 
-  result = fribidi_log2vis_get_embedding_levels (str, len, &fribidi_base_dir,
-						 embedding_level_list);
-  
   *pbase_dir = (fribidi_base_dir == FRIBIDI_TYPE_L) ?  PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL;
 
-  return result;
+  return embedding_levels_list;
 }
 
-#endif /* HAVE_FRIBIDI */
+/**
+ * pango_unichar_direction:
+ * @ch: a unicode character
+ *
+ * Determines the direction of a character; either
+ * %PANGO_DIRECTION_LTR, %PANGO_DIRECTION_RTL, or
+ * %PANGO_DIRECTION_NEUTRAL.
+ *
+ * Return value: the direction of the character, as used in the
+ * Unicode bidirectional algorithm.
+ */
+PangoDirection
+pango_unichar_direction (gunichar ch)
+{
+  FriBidiCharType fribidi_ch_type = fribidi_get_type (ch);
+
+  if (!FRIBIDI_IS_LETTER (fribidi_ch_type))
+    return PANGO_DIRECTION_NEUTRAL;
+  else if (FRIBIDI_IS_RTL (fribidi_ch_type))
+    return PANGO_DIRECTION_RTL;
+  else
+    return PANGO_DIRECTION_LTR;
+}
 
 /**
  * pango_get_mirror_char:
Index: pango/pango-utils.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-utils.h,v
retrieving revision 1.17
diff -u -p -r1.17 pango-utils.h
--- pango/pango-utils.h	23 Jul 2005 19:24:48 -0000	1.17
+++ pango/pango-utils.h	3 Nov 2005 16:41:29 -0000
@@ -88,10 +88,9 @@ G_CONST_RETURN char *   pango_get_lib_su
 
 /* A routine from fribidi that we either wrap or provide ourselves.
  */
-gboolean pango_log2vis_get_embedding_levels (gunichar       *str,
-					     int             len,
-					     PangoDirection *pbase_dir,
-					     guint8         *embedding_level_list);
+guint8 * pango_log2vis_get_embedding_levels (const gchar    *str,
+					     int             bytelen,
+					     PangoDirection *pbase_dir);
 
 G_CONST_RETURN char *pango_language_get_sample_string (PangoLanguage *language);
 
Index: pango/pangox.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangox.c,v
retrieving revision 1.86
diff -u -p -r1.86 pangox.c
--- pango/pangox.c	25 Feb 2005 20:16:29 -0000	1.86
+++ pango/pangox.c	3 Nov 2005 16:41:29 -0000
@@ -703,20 +703,12 @@ itemize_string_foreach (PangoFont     *f
   PangoGlyphString *glyph_str = pango_glyph_string_new ();
   PangoEngineShape *shaper, *last_shaper;
   int last_level;
-  gunichar *text_ucs4;
   long n_chars, i;
   guint8 *embedding_levels;
   PangoDirection base_dir = PANGO_DIRECTION_LTR;
   gboolean finished = FALSE;
   
-  text_ucs4 = g_utf8_to_ucs4_fast (str, -1, &n_chars);
-  if (!text_ucs4)
-    return;
-
-  embedding_levels = g_new (guint8, n_chars);
-  pango_log2vis_get_embedding_levels (text_ucs4, n_chars, &base_dir,
-				      embedding_levels);
-  g_free (text_ucs4);
+  embedding_levels = pango_log2vis_get_embedding_levels (str, -1, &base_dir);
 
   last_shaper = NULL;
   last_level = 0;
Index: pango/mini-fribidi/Makefile.am
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/Makefile.am,v
retrieving revision 1.9
diff -u -p -r1.9 Makefile.am
--- pango/mini-fribidi/Makefile.am	20 Nov 2003 05:34:45 -0000	1.9
+++ pango/mini-fribidi/Makefile.am	3 Nov 2005 16:41:29 -0000
@@ -13,13 +13,15 @@ LDADDS = @STRIP_BEGIN@ 	\
 	@x_libs@	\
 	@GLIB_LIBS@	\
 	-lm		\
-@STRIP_END@
+	@STRIP_END@
 
 noinst_LTLIBRARIES = libmini-fribidi.la
 
 libmini_fribidi_la_SOURCES =    \
 	fribidi.c		\
 	fribidi_char_type.c 	\
+	fribidi_config.h 	\
+	fribidi.h		\
 	fribidi_types.c 	\
 	fribidi_types.h
 
Index: pango/mini-fribidi/README
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/README,v
retrieving revision 1.6
diff -u -p -r1.6 README
--- pango/mini-fribidi/README	15 Aug 2005 22:10:03 -0000	1.6
+++ pango/mini-fribidi/README	3 Nov 2005 16:41:29 -0000
@@ -1,57 +1,20 @@
-This directory holds a stripped down version of GNU FriBidi
-library. The fribidi version that fribidi.patch is against was
-obtained with "cvs up -D '2003-07-14'" from the fribidi cvs repository.
+This directory holds a stripped down version of GNU FriBidi library. The
+fribidi version that fribidi.patch is against is 0.10.7 release.  The files
+fribidi_config.h and Makefile.am are specifically written for Pango integration.
 
-00:18:24 < behdad> please write somewhere in bold huge red font that
-                   you have grabbed fribidi from CVS dated X, with
-                   fribidi_env patch, and you dropped env stuff
-                   yourself.
+Like Pango, FriBidi is licensed under the terms of the GNU Lesser General
+Public License - see the file COPYING in the toplevel directory of the Pango
+distribution.
 
-Like Pango, FriBidi is licensed under the terms of the GNU Lesser
-General Public License - see the file COPYING in the toplevel
-directory of the Pango distribution.
+The fribidi_tab_char_type_2.i table corresponds to Unicode 4.1.
 
-12 November 2000, 18 October 2001
-Owen Taylor
-14 July 2003
-Noah Levitt
+Please try not to make any changes to files duplicated in this directory.
+The aim has been to only remove lines from those files, not add new ones.
+Most of desired features can be implemented by preprocessor tricks in
+fribidi_config.h.
 
+This version of FriBidi is modified to support UTF-8 directly.  Search for
+utf8 in the code to see where changes have gone.
 
-The fribidi_tab_char_type_2.i table was updated to that of FriBidi 0.10.5
-which corresponds to Unicode 4.1.
-
-15 August 2005
+November 03, 2005
 Behdad Esfahbod
-
-
-
-From the README of Fribidi:
-
-
-This is is FriBidi, a Free Implementation of the Unicode BiDi algorithm.
-
-Background
-==========
-One of the missing links stopping the penetration of free software in
-Israel is the lack of support for Hebrew. In order to have proper
-Hebrew support, the BiDi algorithm must be implemented. It is my hope
-that this library will stimulate more Hebrew free software.
-
-Of course the BiDi algorithm is not limited to Hebrew, so I expect 
-that our Arab neighbors will also find this software useful.
-
-Audience
-========
-
-It is my hope that this library will stimulate the implementation of
-Hebrew and Arabic in lots of free software. Here is a small list of
-projects that would benifit from the use of the FriBidi library, but
-of course there are many more: Wine, Mozilla, Gtk, Gnome, Qt, KDE,
-AbiWord, lynx.
-
-Downloading
-===========
-The latest version of FriBidi may be found at:
-
-   http://fribidi.sourceforge.net
-
Index: pango/mini-fribidi/fribidi.c
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi.c,v
retrieving revision 1.13
diff -u -p -r1.13 fribidi.c
--- pango/mini-fribidi/fribidi.c	2 Mar 2004 00:59:01 -0000	1.13
+++ pango/mini-fribidi/fribidi.c	3 Nov 2005 16:41:30 -0000
@@ -21,27 +21,24 @@
  * <fwpg@sharif.edu>.
  */
 
-#include <glib.h>
-#include "pango/pango-utils.h"
-#include "fribidi_types.h"
+#include <stdlib.h>
 
-#ifdef DEBUG
-static gboolean fribidi_debug = FALSE;
+#ifdef HAVE_CONFIG_H
+#include <config.h>
 #endif
+#include "fribidi.h"
 
-#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)
+/* Redefine FRIBIDI_CHUNK_SIZE in config.h to override this. */
+#ifndef FRIBIDI_CHUNK_SIZE
+#ifdef MEM_OPTIMIZED
+#define FRIBIDI_CHUNK_SIZE 16
 #else
-#define DBG(s)
-#define DBG2(s, t)
+#define FRIBIDI_CHUNK_SIZE 128
 #endif
-
-#ifdef DEBUG
-char fribidi_char_from_type (FriBidiCharType c);
 #endif
 
-#define UNI_MAX_BIDI_LEVEL 61
+#define DBG(s)
+#define DBG2(s, t)
 
 /*======================================================================
  * Typedef for the run-length list.
@@ -64,17 +61,41 @@ struct _TypeLink
 
 typedef struct
 {
-  FriBidiCharType override;     /* only L, R and N are valid */
+  FriBidiCharType override;	/* only L, R and N are valid */
   FriBidiLevel level;
 }
 LevelInfo;
 
+#ifndef USE_SIMPLE_MALLOC
+static TypeLink *free_type_links = NULL;
+#endif
+
 static TypeLink *
-new_type_link ()
+new_type_link (void)
 {
   TypeLink *link;
 
-  link = (TypeLink *) g_malloc (sizeof (TypeLink));
+#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->len = 0;
   link->pos = 0;
@@ -87,24 +108,30 @@ new_type_link ()
 static void
 free_type_link (TypeLink *link)
 {
-  g_free (link);
+#ifdef USE_SIMPLE_MALLOC
+  free (link);
+#else
+  link->next = free_type_links;
+  free_type_links = link;
+#endif
 }
 
 #define FRIBIDI_ADD_TYPE_LINK(p,q) \
-        do {    \
-                (p)->len = (q)->pos - (p)->pos; \
-                (p)->next = (q);        \
-                (q)->prev = (p);        \
-                (p) = (q);      \
-        } while (0)
+	do {	\
+		(p)->len = (q)->pos - (p)->pos;	\
+		(p)->next = (q);	\
+		(q)->prev = (p);	\
+		(p) = (q);	\
+	} 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)
 {
   TypeLink *list, *last, *link;
-
+  FriBidiCharType char_type;
   FriBidiStrIndex i;
+  const char *p;
 
   /* Add the starting link */
   list = new_type_link ();
@@ -112,23 +139,30 @@ run_length_encode_types (FriBidiCharType
   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));
+    if (char_type != last->type)
       {
-        link = new_type_link ();
-        link->type = char_type[i];
-        link->pos = i;
-        FRIBIDI_ADD_TYPE_LINK (last, link);
+	link = new_type_link ();
+	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;
+
   return list;
 }
 
@@ -138,7 +172,7 @@ run_length_encode_types (FriBidiCharType
 */
 static void
 init_list (TypeLink **start,
-           TypeLink **end)
+	   TypeLink **end)
 {
   TypeLink *list;
   TypeLink *link;
@@ -170,7 +204,7 @@ init_list (TypeLink **start,
 */
 static void
 move_element_before (TypeLink *p,
-                     TypeLink *list)
+		     TypeLink *list)
 {
   if (p->prev)
     {
@@ -199,7 +233,7 @@ move_element_before (TypeLink *p,
 */
 static void
 override_list (TypeLink *base,
-               TypeLink *over)
+	       TypeLink *over)
 {
   TypeLink *p = base, *q, *r, *s, *t;
   FriBidiStrIndex pos = 0, pos2;
@@ -210,75 +244,75 @@ override_list (TypeLink *base,
   while (q)
     {
       if (!q->len || q->pos < pos)
-        {
-          t = q;
-          q = q->next;
-          free_type_link (t);
-          continue;
-        }
+	{
+	  t = q;
+	  q = q->next;
+	  free_type_link (t);
+	  continue;
+	}
       pos = q->pos;
       while (p->next && p->next->pos <= pos)
-        p = p->next;
+	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;
+	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;
-        }
+	{
+	  /* 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);
-            }
-        }
+	{
+	  /* 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.
        */
@@ -314,8 +348,8 @@ compact_list (TypeLink *list)
   if (list->next)
     for (list = list->next; list; list = list->next)
       if (RL_TYPE (list->prev) == RL_TYPE (list)
-          && RL_LEVEL (list->prev) == RL_LEVEL (list))
-        list = merge_with_prev (list);
+	  && RL_LEVEL (list->prev) == RL_LEVEL (list))
+	list = merge_with_prev (list);
 }
 
 static void
@@ -324,15 +358,15 @@ compact_neutrals (TypeLink *list)
   if (list->next)
     {
       for (list = list->next; list; list = list->next)
-        {
-          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))))))
-            list = merge_with_prev (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))))))
+	    list = merge_with_prev (list);
+	}
     }
 }
 
@@ -376,7 +410,7 @@ compact_neutrals (TypeLink *list)
           level = new_level; \
           override = new_override; \
         } else \
-          over_pushed++; \
+	  over_pushed++; \
     } while (0)
 
 /* If there was a valid matching code, restore (pop) the last remembered
@@ -425,98 +459,27 @@ compact_neutrals (TypeLink *list)
       ) \
     )
 
+
 /* 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 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 (_pango_fribidi_get_type (str[i])));
-  fprintf (stderr, "\n");
-}
-#endif
 /*======================================================================
  *  This function should follow the Unicode specification closely!
  *----------------------------------------------------------------------*/
 static void
-fribidi_analyse_string (/* input */
-                        const FriBidiChar *str,
-                        FriBidiStrIndex len,
-                        FriBidiCharType *pbase_dir,
-                        /* output */
-                        TypeLink **ptype_rl_list,
-                        FriBidiLevel *pmax_level)
+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");
@@ -524,14 +487,8 @@ fribidi_analyse_string (/* input */
   /* Determinate character types */
   DBG ("  Determine character types\n");
   {
-    FriBidiCharType *char_type =
-      (FriBidiCharType *) g_malloc (len * sizeof (FriBidiCharType));
-    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_utf8 (str, bytelen, len);
   }
   DBG ("  Determine character types, Done\n");
 
@@ -550,25 +507,18 @@ fribidi_analyse_string (/* input */
       base_level = FRIBIDI_DIR_TO_LEVEL (*pbase_dir);
       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 (FRIBIDI_IS_LETTER (RL_TYPE (pp)))
+	  {
+	    base_level = FRIBIDI_DIR_TO_LEVEL (RL_TYPE (pp));
+	    base_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
+	    break;
+	  }
     }
   base_dir = FRIBIDI_LEVEL_TO_DIR (base_level);
   DBG2 ("  Base level : %c\n", fribidi_char_from_level (base_level));
   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");
   {
@@ -590,62 +540,62 @@ fribidi_analyse_string (/* input */
     over_pushed = 0;
     first_interval = 0;
     status_stack =
-      (LevelInfo *) g_malloc (sizeof (LevelInfo) * (UNI_MAX_BIDI_LEVEL + 2));
+      (LevelInfo *) malloc (sizeof (LevelInfo) * (UNI_MAX_BIDI_LEVEL + 2));
 
     for (pp = type_rl_list->next; pp->next; pp = pp->next)
       {
-        FriBidiCharType 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. */
+	FriBidiCharType 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! */
@@ -654,7 +604,7 @@ fribidi_analyse_string (/* input */
     stack_size = 0;
     over_pushed = 0;
 
-    g_free (status_stack);
+    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
@@ -668,62 +618,52 @@ fribidi_analyse_string (/* input */
 
   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");
   {
     FriBidiCharType last_strong, prev_type_org;
-    gboolean w4;
+    fribidi_boolean w4;
 
     last_strong = base_dir;
 
     for (pp = type_rl_list->next; pp->next; pp = pp->next)
       {
-        FriBidiCharType prev_type, this_type, next_type;
+	FriBidiCharType 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
-           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. */
-        /* Implementation note: it is important that if the previous character
-           is not sor, then we should merge this run with the previous,
-           because of rules like W5, that we assume all of a sequence of
-           adjacent ETs are in one TypeLink. */
-        if (this_type == FRIBIDI_TYPE_NSM)
-          {
-            if (RL_LEVEL (pp->prev) == RL_LEVEL (pp))
-              pp = merge_with_prev (pp);
-            else
-              RL_TYPE (pp) = prev_type;
-            continue;           /* As we know the next condition cannot be true. */
-          }
-
-        /* 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;
-          }
+	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
+	   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. */
+	/* Implementation note: it is important that if the previous character
+	   is not sor, then we should merge this run with the previous,
+	   because of rules like W5, that we assume all of a sequence of
+	   adjacent ETs are in one TypeLink. */
+	if (this_type == FRIBIDI_TYPE_NSM)
+	  {
+	    if (RL_LEVEL (pp->prev) == RL_LEVEL (pp))
+	      pp = merge_with_prev (pp);
+	    else
+	      RL_TYPE (pp) = prev_type;
+	    continue;		/* As we know the next condition cannot be true. */
+	  }
+
+	/* 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;
+	  }
       }
 
 
@@ -731,7 +671,7 @@ fribidi_analyse_string (/* input */
     /* 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 = TRUE;
+    w4 = FRIBIDI_TRUE;
     /* 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. */
@@ -739,75 +679,67 @@ fribidi_analyse_string (/* input */
 
     for (pp = type_rl_list->next; pp->next; pp = pp->next)
       {
-        FriBidiCharType prev_type, this_type, next_type;
+	FriBidiCharType 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;
-
-        /* W3: Change ALs to R. */
-        if (this_type == FRIBIDI_TYPE_AL)
-          {
-            RL_TYPE (pp) = FRIBIDI_TYPE_RTL;
-            w4 = TRUE;
-            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 = TRUE;
-
-        /* 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 = FALSE;
-            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);
+	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;
+
+	/* W3: Change ALs to R. */
+	if (this_type == FRIBIDI_TYPE_AL)
+	  {
+	    RL_TYPE (pp) = FRIBIDI_TYPE_RTL;
+	    w4 = FRIBIDI_TRUE;
+	    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 = FRIBIDI_TRUE;
+
+	/* 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 = FRIBIDI_FALSE;
+	    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)
-    {
-      print_resolved_levels (type_rl_list);
-      print_resolved_types (type_rl_list);
-    }
-#endif
-
   /* 5. Resolving Neutral Types */
   DBG ("Resolving neutral types\n");
   {
@@ -815,31 +747,23 @@ fribidi_analyse_string (/* input */
        For each neutral, resolve it. */
     for (pp = type_rl_list->next; pp->next; pp = pp->next)
       {
-        FriBidiCharType prev_type, this_type, next_type;
+	FriBidiCharType prev_type, this_type, next_type;
 
-        /* "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 (FRIBIDI_IS_NEUTRAL (this_type))
-          RL_TYPE (pp) = (prev_type == next_type) ?
-            /* N1. */ prev_type :
-            /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp);
+	/* "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 (FRIBIDI_IS_NEUTRAL (this_type))
+	  RL_TYPE (pp) = (prev_type == next_type) ?
+	    /* N1. */ prev_type :
+	    /* N2. */ FRIBIDI_EMBEDDING_DIRECTION (pp);
       }
   }
 
   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");
   {
@@ -847,36 +771,27 @@ fribidi_analyse_string (/* input */
 
     for (pp = type_rl_list->next; pp->next; pp = pp->next)
       {
-        FriBidiCharType this_type;
-        FriBidiLevel level;
+	FriBidiCharType this_type;
+	int level;
 
-        this_type = RL_TYPE (pp);
-        level = RL_LEVEL (pp);
+	this_type = RL_TYPE (pp);
+	level = RL_LEVEL (pp);
 
-        /* I1. Even */
-        /* I2. Odd */
-        if (FRIBIDI_IS_NUMBER (this_type))
-          RL_LEVEL (pp) = (level + 2) & ~1;
-        else
-          RL_LEVEL (pp) = (level ^ FRIBIDI_DIR_TO_LEVEL (this_type)) +
-            (level & 1);
+	/* I1. Even */
+	/* I2. Odd */
+	if (FRIBIDI_IS_NUMBER (this_type))
+	  RL_LEVEL (pp) = (level + 2) & ~1;
+	else
+	  RL_LEVEL (pp) = (level ^ FRIBIDI_DIR_TO_LEVEL (this_type)) +
+	    (level & 1);
 
-        if (RL_LEVEL (pp) > max_level)
-          max_level = RL_LEVEL (pp);
+	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");
@@ -889,65 +804,49 @@ fribidi_analyse_string (/* input */
       p->level = base_level;
     for (; p->next; p = p->next)
       if (p->level < 0)
-        p->level = p->prev->level;
+	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 = _pango_fribidi_get_type (str[j]);
-        else
-          k = FRIBIDI_TYPE_ON;
-        if (!state && FRIBIDI_IS_SEPARATOR (k))
-          {
-            state = 1;
-            pos = j;
-          }
-        else if (state && !FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS (k))
-          {
-            state = 0;
-            p = new_type_link ();
-            p->prev = p->next = (TypeLink *) NULL;
-            p->pos = j + 1;
-            p->len = pos - j;
-            p->type = base_dir;
-            p->level = base_level;
-            move_element_before (p, q);
-            q = p;
-          }
+	/* if state is on at the very first of string, do this too. */
+	if (j >= 0)
+	  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))
+	  {
+	    state = 1;
+	    pos = j;
+	  }
+	else if (state && !FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS (k))
+	  {
+	    state = 0;
+	    p = new_type_link ();
+	    p->prev = p->next = NULL;
+	    p->pos = j + 1;
+	    p->len = pos - j;
+	    p->type = base_dir;
+	    p->level = base_level;
+	    move_element_before (p, q);
+	    q = p;
+	  }
       }
     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;
@@ -974,6 +873,7 @@ free_rl_list (TypeLink *type_rl_list)
       return;
     }
 
+#ifdef USE_SIMPLE_MALLOC
   pp = type_rl_list;
   while (pp)
     {
@@ -983,6 +883,13 @@ free_rl_list (TypeLink *type_rl_list)
       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;
@@ -992,73 +899,40 @@ free_rl_list (TypeLink *type_rl_list)
  *  fribidi_log2vis_get_embedding_levels() is used in order to just get
  *  the embedding levels.
  *----------------------------------------------------------------------*/
-gboolean
-pango_log2vis_get_embedding_levels (/* input */
-                                    gunichar *str,
-                                    gint len,
-                                    PangoDirection *pbase_dir,
-                                    /* output */
-                                    guint8 *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;
-  FriBidiCharType fribidi_base_dir;
+  FriBidiLevel max_level, *embedding_level_list;
+  FriBidiStrIndex len;
 
   DBG ("Entering fribidi_log2vis_get_embedding_levels()\n");
 
-  switch (*pbase_dir)
-    {
-    case PANGO_DIRECTION_LTR:
-    case PANGO_DIRECTION_TTB_RTL:
-      fribidi_base_dir = FRIBIDI_TYPE_L;
-      break;
-    case PANGO_DIRECTION_RTL:
-    case PANGO_DIRECTION_TTB_LTR:
-      fribidi_base_dir = FRIBIDI_TYPE_R;
-      break;
-    case PANGO_DIRECTION_WEAK_LTR:
-    case PANGO_DIRECTION_NEUTRAL:
-      fribidi_base_dir = FRIBIDI_TYPE_WL;
-      break;
-    case PANGO_DIRECTION_WEAK_RTL:
-      fribidi_base_dir = FRIBIDI_TYPE_WR;
-      break;
-    }
-  
-  if (len == 0)
+  if (bytelen == 0)
     {
       DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n");
-      return TRUE;
+      return NULL;
     }
 
-  fribidi_analyse_string (str, len, &fribidi_base_dir,
-                                 /* output */
-                                 &type_rl_list, &max_level);
+  fribidi_analyse_string_utf8 (str, bytelen, pbase_dir,
+			  /* output */
+			  &len, &type_rl_list, &max_level);
 
+  embedding_level_list = g_new (FriBidiLevel, len);
   for (pp = type_rl_list->next; pp->next; pp = pp->next)
     {
-      gint i, pos = RL_POS (pp),
-        len = RL_LEN (pp);
-      gint level = RL_LEVEL (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;
+	embedding_level_list[pos + i] = level;
     }
 
   free_rl_list (type_rl_list);
 
   DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n");
-  return TRUE;
+  return embedding_level_list;
 }
 
-PangoDirection
-pango_unichar_direction (gunichar ch)
-{
-  FriBidiCharType fribidi_ch_type = _pango_fribidi_get_type (ch);
-
-  if (!FRIBIDI_IS_LETTER (fribidi_ch_type))
-    return PANGO_DIRECTION_NEUTRAL;
-  else if (FRIBIDI_IS_RTL (fribidi_ch_type))
-    return PANGO_DIRECTION_RTL;
-  else
-    return PANGO_DIRECTION_LTR;
-}
Index: pango/mini-fribidi/fribidi.h
===================================================================
RCS file: pango/mini-fribidi/fribidi.h
diff -N pango/mini-fribidi/fribidi.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pango/mini-fribidi/fribidi.h	3 Nov 2005 16:41:30 -0000
@@ -0,0 +1,56 @@
+/* FriBidi - Library of BiDi algorithm
+ * Copyright (C) 1999,2000 Dov Grobgeld, and
+ * Copyright (C) 2001,2002 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; 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_H
+#define FRIBIDI_H
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#include "fribidi_config.h"
+#include "fribidi_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define FRIBIDI_HAVE_UTF8
+
+  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);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif				/* FRIBIDI_H */
Index: pango/mini-fribidi/fribidi.patch
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi.patch,v
retrieving revision 1.4
diff -u -p -r1.4 fribidi.patch
--- pango/mini-fribidi/fribidi.patch	20 Nov 2003 05:34:45 -0000	1.4
+++ pango/mini-fribidi/fribidi.patch	3 Nov 2005 16:41:30 -0000
@@ -1,77 +1,55 @@
-Only in /usr/src/fribidi/: acconfig.h
-Only in /usr/src/fribidi/: acinclude.m4
-Only in /usr/src/fribidi/: aclocal.m4
-Only in /usr/src/fribidi/: ANNOUNCE
-Only in /usr/src/fribidi/: AUTHORS
-Only in /usr/src/fribidi/: autom4te.cache
-Only in /usr/src/fribidi/: bootstrap
-Only in /usr/src/fribidi/: ChangeLog
-Only in /usr/src/fribidi/: config.guess
-Only in /usr/src/fribidi/: config.h
-Only in /usr/src/fribidi/: config.h.in
-Only in /usr/src/fribidi/: config.log
-Only in /usr/src/fribidi/: config.status
-Only in /usr/src/fribidi/: config.sub
-Only in /usr/src/fribidi/: configure
-Only in /usr/src/fribidi/: configure.in
-Only in /usr/src/fribidi/: conformance
-Only in /usr/src/fribidi/: COPYING
-Common subdirectories: /usr/src/fribidi/CVS and mini-fribidi/CVS
-Only in mini-fribidi/: .cvsignore
-Only in /usr/src/fribidi/: depcomp
-Only in /usr/src/fribidi/: .deps
-Only in /usr/src/fribidi/: fribidi_benchmark.c
-diff -bu /usr/src/fribidi/fribidi.c mini-fribidi/fribidi.c
---- /usr/src/fribidi/fribidi.c	2002-09-13 16:26:42.000000000 -0400
-+++ mini-fribidi/fribidi.c	2003-07-14 18:21:27.000000000 -0400
-@@ -21,27 +21,17 @@
-  * <fwpg@sharif.edu>.
-  */
- 
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif
--#include "fribidi.h"
+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-11-03 11:30:26.000000000 -0500
+@@ -27,10 +27,6 @@
+ #include <config.h>
+ #endif
+ #include "fribidi.h"
 -#include "fribidi_mem.h"
 -#ifdef DEBUG
 -#include <stdio.h>
 -#endif
-+#include <glib.h>
-+#include "pango/pango-utils.h"
-+#include "fribidi_types.h"
  
--/* Redefine FRIBIDI_CHUNK_SIZE in config.h to override this. */
--#ifndef FRIBIDI_CHUNK_SIZE
--#ifdef MEM_OPTIMIZED
--#define FRIBIDI_CHUNK_SIZE 16
--#else
--#define FRIBIDI_CHUNK_SIZE 128
--#endif
-+#ifdef DEBUG
-+static gboolean fribidi_debug = FALSE;
+ /* Redefine FRIBIDI_CHUNK_SIZE in config.h to override this. */
+ #ifndef FRIBIDI_CHUNK_SIZE
+@@ -41,19 +37,8 @@
+ #endif
  #endif
  
- #ifdef DEBUG
--#define DBG(s) do { if (fribidi_debug_status(fribidienv)) { fprintf(stderr, s); } } while (0)
--#define DBG2(s, t) do { if (fribidi_debug_status(fribidienv)) { fprintf(stderr, s, t); } } while (0)
-+#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
+-#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)
-@@ -51,7 +41,7 @@
- char fribidi_char_from_type (FriBidiCharType c);
- #endif
- 
+-#endif
+-
+-#ifdef DEBUG
+-char fribidi_char_from_type (FriBidiCharType c);
+-#endif
+-
 -#define MAX(a,b) ((a) > (b) ? (a) : (b))
-+#define UNI_MAX_BIDI_LEVEL 61
  
  /*======================================================================
   * Typedef for the run-length list.
-@@ -79,63 +69,12 @@
+@@ -81,47 +66,6 @@
  }
  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,
@@ -99,496 +77,338 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -    }
 -}
 -
--#ifndef USE_SIMPLE_MALLOC
--static TypeLink *free_type_links = NULL;
--#endif
--
- static TypeLink *
--new_type_link (FriBidiEnv *fribidienv)
-+new_type_link ()
- {
-   TypeLink *link;
- 
--#ifdef USE_SIMPLE_MALLOC
--  link = (TypeLink *) fribidi_malloc (fribidienv, 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 (fribidienv, TypeLink,
--					      FRIBIDI_CHUNK_SIZE,
--					      FRIBIDI_ALLOC_ONLY);
--
--      link = fribidi_chunk_new (fribidienv, TypeLink,
--				mem_chunk);
--    }
--#endif /* !USE_SIMPLE_MALLOC */
-+  link = (TypeLink *) g_malloc (sizeof (TypeLink));
- 
-   link->len = 0;
-   link->pos = 0;
-@@ -146,15 +85,9 @@
- }
- 
- static void
--free_type_link (FriBidiEnv *fribidienv,
--		TypeLink *link)
-+free_type_link (TypeLink *link)
- {
--#ifdef USE_SIMPLE_MALLOC
--  fribidi_free (fribidienv, link);
--#else
--  link->next = free_type_links;
--  free_type_links = link;
--#endif
-+  g_free (link);
- }
- 
- #define FRIBIDI_ADD_TYPE_LINK(p,q) \
-@@ -166,8 +99,7 @@
+ #ifndef USE_SIMPLE_MALLOC
+ static TypeLink *free_type_links = NULL;
+ #endif
+@@ -181,12 +125,13 @@
  	} while (0)
  
  static TypeLink *
--run_length_encode_types (FriBidiEnv *fribidienv,
--			 FriBidiCharType *char_type,
-+run_length_encode_types (FriBidiCharType *char_type,
- 			 FriBidiStrIndex type_len)
+-run_length_encode_types (FriBidiCharType *char_type,
+-			 FriBidiStrIndex type_len)
++run_length_encode_types_utf8 (const char *s,
++			      int bytelen, FriBidiStrIndex *len)
  {
    TypeLink *list, *last, *link;
-@@ -175,7 +107,7 @@
+-
++  FriBidiCharType char_type;
    FriBidiStrIndex i;
++  const char *p;
  
    /* Add the starting link */
--  list = new_type_link (fribidienv);
-+  list = new_type_link ();
-   list->type = FRIBIDI_TYPE_SOT;
+   list = new_type_link ();
+@@ -194,23 +139,30 @@
    list->level = FRIBIDI_LEVEL_START;
    last = list;
-@@ -184,14 +116,14 @@
-   for (i = 0; i < type_len; i++)
-     if (char_type[i] != last->type)
+ 
+-  /* 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));
++    if (char_type != last->type)
        {
--	link = new_type_link (fribidienv);
-+        link = new_type_link ();
- 	link->type = char_type[i];
+ 	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 (fribidienv);
-+  link = new_type_link ();
-   link->type = FRIBIDI_TYPE_EOT;
-   link->level = FRIBIDI_LEVEL_END;
-   link->pos = type_len;
-@@ -205,22 +137,21 @@
-    the override_list.
- */
- static void
--init_list (FriBidiEnv *fribidienv,
--	   TypeLink **start,
-+init_list (TypeLink **start,
- 	   TypeLink **end)
- {
-   TypeLink *list;
-   TypeLink *link;
- 
-   /* Add the starting link */
--  list = new_type_link (fribidienv);
-+  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 (fribidienv);
-+  link = new_type_link ();
+   link = new_type_link ();
    link->type = FRIBIDI_TYPE_EOT;
    link->level = FRIBIDI_LEVEL_END;
-   link->len = 0;
-@@ -267,8 +198,7 @@
-    TBD: use some explanatory names instead of p, q, ...
- */
- static void
--override_list (FriBidiEnv *fribidienv,
--	       TypeLink *base,
-+override_list (TypeLink *base,
- 	       TypeLink *over)
- {
-   TypeLink *p = base, *q, *r, *s, *t;
-@@ -283,7 +213,7 @@
- 	{
- 	  t = q;
- 	  q = q->next;
--	  free_type_link (fribidienv, t);
-+          free_type_link (t);
- 	  continue;
- 	}
-       pos = q->pos;
-@@ -304,7 +234,7 @@
- 	    r = r->next;
- 	  else
- 	    {
--	      r = new_type_link (fribidienv);
-+              r = new_type_link ();
- 	      *r = *p;
- 	      if (r->next)
- 		{
-@@ -320,7 +250,7 @@
- 	    {
- 	      t = p;
- 	      p = p->prev;
--	      free_type_link (fribidienv, t);
-+              free_type_link (t);
- 	    }
- 	  else
- 	    p->len = pos - p->pos;
-@@ -346,7 +276,7 @@
- 	    {
- 	      t = s;
- 	      s = s->next;
--	      free_type_link (fribidienv, t);
-+              free_type_link (t);
- 	    }
- 	}
-       /* before updating the next and prev links to point to the inserted q,
-@@ -368,31 +298,28 @@
- #define RL_LEVEL(list) ((list)->level)
- 
- static TypeLink *
--merge_with_prev (FriBidiEnv *fribidienv,
--		 TypeLink *second)
-+merge_with_prev (TypeLink *second)
- {
-   TypeLink *first = second->prev;
-   first->next = second->next;
-   first->next->prev = first;
-   RL_LEN (first) += RL_LEN (second);
--  free_type_link (fribidienv, second);
-+  free_type_link (second);
-   return first;
- }
- 
- static void
--compact_list (FriBidiEnv *fribidienv,
--	      TypeLink *list)
-+compact_list (TypeLink *list)
- {
-   if (list->next)
-     for (list = list->next; list; list = list->next)
-       if (RL_TYPE (list->prev) == RL_TYPE (list)
- 	  && RL_LEVEL (list->prev) == RL_LEVEL (list))
--	list = merge_with_prev (fribidienv, list);
-+        list = merge_with_prev (list);
- }
+-  link->pos = type_len;
++  link->pos = i;
+   FRIBIDI_ADD_TYPE_LINK (last, link);
  
- static void
--compact_neutrals (FriBidiEnv *fribidienv,
--		  TypeLink *list)
-+compact_neutrals (TypeLink *list)
- {
-   if (list->next)
-     {
-@@ -404,7 +331,7 @@
- 		(list->prev) == RL_TYPE (list)
- 		|| (FRIBIDI_IS_NEUTRAL (RL_TYPE (list->prev))
- 		    && FRIBIDI_IS_NEUTRAL (RL_TYPE (list))))))
--	    list = merge_with_prev (fribidienv, list);
-+            list = merge_with_prev (list);
- 	}
-     }
++  if (len)
++    *len = i;
++
+   return list;
  }
-@@ -498,7 +425,6 @@
-       ) \
-     )
  
--
- /* Return the embedding direction of a link. */
+@@ -512,95 +464,22 @@
  #define FRIBIDI_EMBEDDING_DIRECTION(list) \
      FRIBIDI_LEVEL_TO_DIR(RL_LEVEL(list))
-@@ -572,17 +498,15 @@
-   fprintf (stderr, "  Org. types : ");
-   for (i = 0; str[i]; i++)
-     fprintf (stderr, "%c",
--	     fribidi_char_from_type (fribidi_get_type (fribidienv, str[i])));
-+	     fribidi_char_from_type (_pango_fribidi_get_type (str[i])));
-   fprintf (stderr, "\n");
- }
- #endif
+ 
+-#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 (FriBidiEnv *fribidienv,
--			/* input */
-+fribidi_analyse_string (/* input */
- 			const FriBidiChar *str,
- 			FriBidiStrIndex len,
- 			FriBidiCharType *pbase_dir,
-@@ -601,18 +525,17 @@
+-fribidi_analyse_string (	/* input */
+-			 FriBidiChar *str,
+-			 FriBidiStrIndex len,
++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 +487,8 @@
+   /* Determinate character types */
    DBG ("  Determine character types\n");
    {
-     FriBidiCharType *char_type =
--      (FriBidiCharType *) fribidi_malloc (fribidienv,
--					  len * sizeof (FriBidiCharType));
-+      (FriBidiCharType *) g_malloc (len * sizeof (FriBidiCharType));
-     for (i = 0; i < len; i++)
--      char_type[i] = fribidi_get_type (fribidienv, str[i]);
-+      char_type[i] = _pango_fribidi_get_type (str[i]);
- 
+-    FriBidiCharType *char_type =
+-      (FriBidiCharType *) malloc (len * sizeof (FriBidiCharType));
+-    for (i = 0; i < len; i++)
+-      char_type[i] = fribidi_get_type (str[i]);
+-
      /* Run length encode the character types */
--    type_rl_list = run_length_encode_types (fribidienv, char_type, len);
--    fribidi_free (fribidienv, char_type);
-+    type_rl_list = run_length_encode_types (char_type, len);
-+    g_free (char_type);
+-    type_rl_list = run_length_encode_types (char_type, len);
+-    free (char_type);
++    type_rl_list = run_length_encode_types_utf8 (str, bytelen, len);
    }
    DBG ("  Determine character types, Done\n");
  
--  init_list (fribidienv, &explicits_list, &explicits_list_end);
-+  init_list (&explicits_list, &explicits_list_end);
- 
-   /* Find base level */
-   DBG ("  Finding the base level\n");
-@@ -640,7 +563,7 @@
+@@ -646,13 +519,6 @@
+   DBG2 ("  Base dir   : %c\n", fribidi_char_from_type (base_dir));
    DBG ("  Finding the base level, Done\n");
  
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_types_re (type_rl_list);
-     }
-@@ -667,9 +590,7 @@
-     over_pushed = 0;
-     first_interval = 0;
-     status_stack =
--      (LevelInfo *) fribidi_malloc (fribidienv,
--				    sizeof (LevelInfo) * (UNI_MAX_BIDI_LEVEL +
--							  2));
-+      (LevelInfo *) g_malloc (sizeof (LevelInfo) * (UNI_MAX_BIDI_LEVEL + 2));
+-#ifdef DEBUG
+-  if (fribidi_debug)
+-    {
+-      print_types_re (type_rl_list);
+-    }
+-#endif
+-
+   /* Explicit Levels and Directions */
+   DBG ("Explicit Levels and Directions\n");
+   {
+@@ -752,16 +618,6 @@
  
-     for (pp = type_rl_list->next; pp->next; pp = pp->next)
-       {
-@@ -733,7 +654,7 @@
-     stack_size = 0;
-     over_pushed = 0;
+   compact_list (type_rl_list);
  
--    fribidi_free (fribidienv, status_stack);
-+    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
-@@ -745,10 +666,10 @@
-   /* 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 (fribidienv, type_rl_list);
-+  compact_list (type_rl_list);
- 
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_types_re (type_rl_list);
-       print_bidi_string (str);
-@@ -761,7 +682,7 @@
+-#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");
    {
-     FriBidiCharType last_strong, prev_type_org;
--    fribidi_boolean w4;
-+    gboolean w4;
- 
-     last_strong = base_dir;
- 
-@@ -787,7 +708,7 @@
- 	if (this_type == FRIBIDI_TYPE_NSM)
- 	  {
- 	    if (RL_LEVEL (pp->prev) == RL_LEVEL (pp))
--	      pp = merge_with_prev (fribidienv, pp);
-+              pp = merge_with_prev (pp);
- 	    else
- 	      RL_TYPE (pp) = prev_type;
- 	    continue;		/* As we know the next condition cannot be true. */
-@@ -810,7 +731,7 @@
-     /* 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 = FRIBIDI_TRUE;
-+    w4 = TRUE;
-     /* 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. */
-@@ -831,7 +752,7 @@
- 	if (this_type == FRIBIDI_TYPE_AL)
- 	  {
- 	    RL_TYPE (pp) = FRIBIDI_TYPE_RTL;
--	    w4 = FRIBIDI_TRUE;
-+            w4 = TRUE;
- 	    prev_type_org = FRIBIDI_TYPE_ON;
- 	    continue;
- 	  }
-@@ -848,7 +769,7 @@
- 	    RL_TYPE (pp) = prev_type;
- 	    this_type = RL_TYPE (pp);
- 	  }
--	w4 = FRIBIDI_TRUE;
-+        w4 = TRUE;
- 
- 	/* W5. A sequence of European terminators adjacent to European
- 	   numbers changes to All European numbers. */
-@@ -857,7 +778,7 @@
- 		|| next_type == FRIBIDI_TYPE_EN))
- 	  {
- 	    RL_TYPE (pp) = FRIBIDI_TYPE_EN;
--	    w4 = FRIBIDI_FALSE;
-+            w4 = FALSE;
- 	    this_type = RL_TYPE (pp);
- 	  }
- 
-@@ -877,10 +798,10 @@
-       }
-   }
+@@ -884,14 +740,6 @@
  
--  compact_neutrals (fribidienv, type_rl_list);
-+  compact_neutrals (type_rl_list);
+   compact_neutrals (type_rl_list);
  
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_resolved_levels (type_rl_list);
-       print_resolved_types (type_rl_list);
-@@ -909,10 +830,10 @@
-       }
-   }
- 
--  compact_list (fribidienv, type_rl_list);
-+  compact_list (type_rl_list);
- 
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_resolved_levels (type_rl_list);
-       print_resolved_types (type_rl_list);
-@@ -945,10 +866,10 @@
-       }
-   }
+-#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 +764,6 @@
  
--  compact_list (fribidienv, type_rl_list);
-+  compact_list (type_rl_list);
+   compact_list (type_rl_list);
  
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_bidi_string (str);
-       print_resolved_levels (type_rl_list);
-@@ -962,7 +883,7 @@
+-#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");
    {
-     TypeLink *p;
+@@ -952,15 +792,6 @@
  
--    override_list (fribidienv, type_rl_list, explicits_list);
-+    override_list (type_rl_list, explicits_list);
-     p = type_rl_list->next;
-     if (p->level < 0)
-       p->level = base_level;
-@@ -972,7 +893,7 @@
+   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 +807,23 @@
+ 	p->level = p->prev->level;
    }
  
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_types_re (type_rl_list);
-       print_resolved_levels (type_rl_list);
-@@ -986,7 +907,7 @@
+-#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 (fribidienv, &list, &list_end);
-+    init_list (&list, &list_end);
+     init_list (&list, &list_end);
      q = list_end;
      state = 1;
-     pos = len - 1;
-@@ -994,7 +915,7 @@
+-    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 (fribidienv, str[j]);
-+          k = _pango_fribidi_get_type (str[j]);
+-	  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))
-@@ -1005,7 +926,7 @@
- 	else if (state && !FRIBIDI_IS_EXPLICIT_OR_SEPARATOR_OR_BN_OR_WS (k))
- 	  {
- 	    state = 0;
--	    p = new_type_link (fribidienv);
-+            p = new_type_link ();
- 	    p->prev = p->next = (TypeLink *) NULL;
- 	    p->pos = j + 1;
- 	    p->len = pos - j;
-@@ -1015,11 +936,11 @@
- 	    q = p;
- 	  }
-       }
--    override_list (fribidienv, type_rl_list, list);
-+    override_list (type_rl_list, list);
+@@ -1023,15 +847,6 @@
+     override_list (type_rl_list, list);
    }
  
- #ifdef DEBUG
--  if (fribidi_debug_status (fribidienv))
-+  if (fribidi_debug)
-     {
-       print_types_re (type_rl_list);
-       print_resolved_levels (type_rl_list);
-@@ -1040,8 +961,7 @@
-  *  fribidi_analyse_string(), after the list is not needed anymore.
-  *----------------------------------------------------------------------*/
- static void
--free_rl_list (FriBidiEnv *fribidienv,
--	      TypeLink *type_rl_list)
-+free_rl_list (TypeLink *type_rl_list)
- {
- 
-   TypeLink *pp;
-@@ -1054,7 +974,6 @@
-       return;
-     }
- 
--#ifdef USE_SIMPLE_MALLOC
-   pp = type_rl_list;
-   while (pp)
-     {
-@@ -1062,366 +981,55 @@
- 
-       p = pp;
-       pp = pp->next;
--      free_type_link (fribidienv, p);
-+      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;
+-#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 ("Leaving free_rl_list()\n");
+-
+   *ptype_rl_list = type_rl_list;
+   *pmax_level = max_level;
+   *pbase_dir = base_dir;
+@@ -1080,338 +895,36 @@
    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.
@@ -599,8 +419,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 - *  the new length, updates each of other inputs if not NULL.
 - *----------------------------------------------------------------------*/
 -FRIBIDI_API FriBidiStrIndex
--fribidi_remove_bidi_marks (FriBidiEnv *fribidienv,
--			   FriBidiChar *str,
+-fribidi_remove_bidi_marks (FriBidiChar *str,
 -			   FriBidiStrIndex length,
 -			   FriBidiStrIndex *position_to_this_list,
 -			   FriBidiStrIndex *position_from_this_list,
@@ -617,14 +436,12 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -    {
 -      private_from_this = FRIBIDI_TRUE;
 -      position_from_this_list =
--	(FriBidiStrIndex *) fribidi_malloc (fribidienv,
--					    sizeof (FriBidiStrIndex) *
--					    length);
+-	(FriBidiStrIndex *) malloc (sizeof (FriBidiStrIndex) * length);
 -    }
 -
 -  j = 0;
 -  for (i = 0; i < length; i++)
--    if (!FRIBIDI_IS_EXPLICIT (fribidi_get_type (fribidienv, str[i]))
+-    if (!FRIBIDI_IS_EXPLICIT (fribidi_get_type (str[i]))
 -	&& str[i] != UNI_LRM && str[i] != UNI_RLM)
 -      {
 -	str[j] = str[i];
@@ -647,7 +464,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -    }
 -
 -  if (private_from_this)
--    fribidi_free (fribidienv, position_from_this_list);
+-    free (position_from_this_list);
 -
 -  DBG ("Leaving fribidi_remove_bidi_marks()\n");
 -  return j;
@@ -659,18 +476,17 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 - *  does reordering and fills in the output strings.
 - *----------------------------------------------------------------------*/
 -FRIBIDI_API fribidi_boolean
--fribidi_log2vis (FriBidiEnv *fribidienv,
--		 /* input */
--		 const 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)
+-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 = (TypeLink *) NULL;
+-  TypeLink *type_rl_list, *pp = NULL;
 -  FriBidiLevel max_level;
 -  fribidi_boolean private_V_to_L = FRIBIDI_FALSE;
 -
@@ -688,8 +504,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -    {
 -      private_V_to_L = FRIBIDI_TRUE;
 -      position_V_to_L_list =
--	(FriBidiStrIndex *) fribidi_malloc (fribidienv,
--					    sizeof (FriBidiStrIndex) * len);
+-	(FriBidiStrIndex *) malloc (sizeof (FriBidiStrIndex) * len);
 -    }
 -
 -  if (len > FRIBIDI_MAX_STRING_LENGTH && position_V_to_L_list)
@@ -700,7 +515,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -#endif
 -      return FRIBIDI_FALSE;
 -    }
--  fribidi_analyse_string (fribidienv, str, len, pbase_dir,
+-  fribidi_analyse_string (str, len, pbase_dir,
 -			  /* output */
 -			  &type_rl_list, &max_level);
 -
@@ -749,7 +564,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -    /* Reorder both the outstring and the order array */
 -    if (visual_str || position_V_to_L_list)
 -      {
--	if (fribidi_mirroring_status (fribidienv) && visual_str)
+-	if (mirroring && visual_str)
 -	  {
 -	    /* L4. Mirror all characters that are in odd levels and have mirrors. */
 -	    DBG ("  Mirroring\n");
@@ -762,7 +577,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -		      {
 -			FriBidiChar mirrored_ch;
 -			if (fribidi_get_mirror_char
--			    (fribidienv, visual_str[i], &mirrored_ch))
+-			    (visual_str[i], &mirrored_ch))
 -			  visual_str[i] = mirrored_ch;
 -		      }
 -		  }
@@ -770,7 +585,7 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -	    DBG ("  Mirroring, Done\n");
 -	  }
 -
--	if (fribidi_reorder_nsm_status (fribidienv))
+-	if (reorder_nsm)
 -	  {
 -	    /* L3. Reorder NSMs. */
 -	    DBG ("  Reordering NSM sequences\n");
@@ -782,13 +597,13 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -		    FriBidiStrIndex i, seq_end = 0;
 -		    fribidi_boolean is_nsm_seq;
 -
--		    is_nsm_seq = 0;
+-		    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 (NULL, str[i]);
+-			this_type = fribidi_get_type (str[i]);
 -			if (is_nsm_seq && this_type != FRIBIDI_TYPE_NSM)
 -			  {
 -			    if (visual_str)
@@ -859,9 +674,9 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -  DBG ("Reordering resolved levels, Done\n");
 -
 -  if (private_V_to_L)
--    fribidi_free (fribidienv, position_V_to_L_list);
+-    free (position_V_to_L_list);
 -
--  free_rl_list (fribidienv, type_rl_list);
+-  free_rl_list (type_rl_list);
 -
 -  DBG ("Leaving fribidi_log2vis()\n");
 -  return FRIBIDI_TRUE;
@@ -873,57 +688,54 @@ diff -bu /usr/src/fribidi/fribidi.c mini
   *  the embedding levels.
   *----------------------------------------------------------------------*/
 -FRIBIDI_API fribidi_boolean
--fribidi_log2vis_get_embedding_levels (FriBidiEnv *fribidienv,
--				      /* input */
--				      const FriBidiChar *str,
--				      FriBidiStrIndex len,
--				      FriBidiCharType *pbase_dir,
-+gboolean
-+pango_log2vis_get_embedding_levels (/* input */
-+                                    gunichar *str,
-+                                    gint len,
-+                                    PangoDirection *pbase_dir,
- 				      /* output */
--				      FriBidiLevel *embedding_level_list)
-+                                    guint8 *embedding_level_list)
+-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;
-+  FriBidiCharType fribidi_base_dir;
+-  FriBidiLevel max_level;
++  FriBidiLevel max_level, *embedding_level_list;
++  FriBidiStrIndex len;
  
    DBG ("Entering fribidi_log2vis_get_embedding_levels()\n");
  
-+  fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ? FRIBIDI_TYPE_LTR : FRIBIDI_TYPE_RTL;
-+
-   if (len == 0)
+-  if (len == 0)
++  if (bytelen == 0)
      {
        DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n");
 -      return FRIBIDI_TRUE;
-+      return TRUE;
++      return NULL;
      }
  
--  fribidi_analyse_string (fribidienv, str, len, pbase_dir,
-+  fribidi_analyse_string (str, len, &fribidi_base_dir,
+-  fribidi_analyse_string (str, len, pbase_dir,
++  fribidi_analyse_string_utf8 (str, bytelen, pbase_dir,
  			  /* output */
- 			  &type_rl_list, &max_level);
+-			  &type_rl_list, &max_level);
++			  &len, &type_rl_list, &max_level);
  
++  embedding_level_list = g_new (FriBidiLevel, len);
    for (pp = type_rl_list->next; pp->next; pp = pp->next)
      {
 -      FriBidiStrIndex i, pos = RL_POS (pp),
-+      gint i, pos = RL_POS (pp),
-         len = RL_LEN (pp);
--      FriBidiLevel level = RL_LEVEL (pp);
-+      gint level = RL_LEVEL (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;
-     }
- 
--  free_rl_list (fribidienv, type_rl_list);
-+  free_rl_list (type_rl_list);
+@@ -1420,34 +933,6 @@
+   free_rl_list (type_rl_list);
  
    DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n");
 -  return FRIBIDI_TRUE;
-+  return TRUE;
++  return embedding_level_list;
  }
  
 -
@@ -934,7 +746,8 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -  "\n"
 -  "Unicode version " FRIBIDI_UNICODE_VERSION "\n"
 -  "\n"
--  "Copyright (C) 2002 FriBidi Project (http://fribidi.sf.net/).\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"
@@ -953,242 +766,378 @@ diff -bu /usr/src/fribidi/fribidi.c mini
 -  "--without-charsts\n"
 -#endif
 -;
-Only in /usr/src/fribidi/: fribidi_char_sets.c
-Only in /usr/src/fribidi/: fribidi_char_sets_cap_rtl.c
-Only in /usr/src/fribidi/: fribidi_char_sets_cap_rtl.h
-Only in /usr/src/fribidi/: fribidi_char_sets_cp1255.c
-Only in /usr/src/fribidi/: fribidi_char_sets_cp1255.h
-Only in /usr/src/fribidi/: fribidi_char_sets_cp1256.c
-Only in /usr/src/fribidi/: fribidi_char_sets_cp1256.h
-Only in /usr/src/fribidi/: fribidi_char_sets.h
-Only in /usr/src/fribidi/: fribidi_char_sets.i
-Only in /usr/src/fribidi/: fribidi_char_sets_isiri_3342.c
-Only in /usr/src/fribidi/: fribidi_char_sets_isiri_3342.h
-Only in /usr/src/fribidi/: fribidi_char_sets_iso8859_6.c
-Only in /usr/src/fribidi/: fribidi_char_sets_iso8859_6.h
-Only in /usr/src/fribidi/: fribidi_char_sets_iso8859_8.c
-Only in /usr/src/fribidi/: fribidi_char_sets_iso8859_8.h
-Only in /usr/src/fribidi/: fribidi_char_sets_utf8.c
-Only in /usr/src/fribidi/: fribidi_char_sets_utf8.h
-diff -bu /usr/src/fribidi/fribidi_char_type.c mini-fribidi/fribidi_char_type.c
---- /usr/src/fribidi/fribidi_char_type.c	2003-07-17 17:18:01.000000000 -0400
-+++ mini-fribidi/fribidi_char_type.c	2003-07-14 18:06:19.000000000 -0400
-@@ -19,85 +19,18 @@
-  * For licensing issues, contact <fwpg@sharif.edu>. 
-  */
- 
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif
--#include "fribidi.h"
-+#include <glib.h>
-+#include "fribidi_types.h"
+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.
-+ *  _pango_fribidi_get_type() returns the bidi type of a character.
-  *----------------------------------------------------------------------*/
+- *----------------------------------------------------------------------*/
 -FRIBIDI_API FriBidiCharType fribidi_get_type_internal (FriBidiChar uch);
-+FriBidiCharType _pango_fribidi_get_type_internal (FriBidiChar uch);
- 
+-
 -FRIBIDI_API FriBidiCharType
--fribidi_get_type (FriBidiEnv *env,
--		  FriBidiChar uch)
-+FriBidiCharType
-+_pango_fribidi_get_type (FriBidiChar uch)
- {
+-fribidi_get_type (FriBidiChar uch)
+-{
 -  return fribidi_get_type_internal (uch);
-+  return _pango_fribidi_get_type_internal (uch);
- }
- 
+-}
+-
 -FRIBIDI_API void
--fribidi_get_types (FriBidiEnv *env,
--		   /* input */
--		   const FriBidiChar *str,
--		   FriBidiStrIndex len,
--		   /* output */
--		   FriBidiCharType *type)
+-fribidi_get_types (		/* input */
+-		    FriBidiChar *str, FriBidiStrIndex len,
+-		    /* output */
+-		    FriBidiCharType *type)
 -{
 -  FriBidiStrIndex i;
 -
 -  for (i = 0; i < len; i++)
--    type[i] = fribidi_get_type (env, str[i]);
+-    type[i] = fribidi_get_type (str[i]);
 -}
 -
--#ifdef MEM_OPTIMIZED
--
--#if   HAS_FRIBIDI_TAB_CHAR_TYPE_9_I
--#include "fribidi_tab_char_type_9.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_8_I
--#include "fribidi_tab_char_type_8.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_7_I
--#include "fribidi_tab_char_type_7.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_6_I
--#include "fribidi_tab_char_type_6.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_5_I
--#include "fribidi_tab_char_type_5.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_4_I
--#include "fribidi_tab_char_type_4.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_3_I
--#include "fribidi_tab_char_type_3.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_2_I
- #include "fribidi_tab_char_type_2.i"
--#else
--#error You have no fribidi_tab_char_type_*.i file, please first make one by \
--       make fribidi_tab_char_type_n.i which n is the compress level, a digit \
--       between 2 and 9, or simply run make fribidi_tab_char_type_small, \
--       retry to make.
+ #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
--
--#else
--
--#if   HAS_FRIBIDI_TAB_CHAR_TYPE_2_I
--#include "fribidi_tab_char_type_2.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_3_I
--#include "fribidi_tab_char_type_3.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_4_I
--#include "fribidi_tab_char_type_4.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_5_I
--#include "fribidi_tab_char_type_5.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_6_I
--#include "fribidi_tab_char_type_6.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_7_I
--#include "fribidi_tab_char_type_7.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_8_I
--#include "fribidi_tab_char_type_8.i"
--#elif HAS_FRIBIDI_TAB_CHAR_TYPE_9_I
--#include "fribidi_tab_char_type_9.i"
--#else
--#error You have no fribidi_tab_char_type_*.i file, please first make one by \
--       make fribidi_tab_char_type_n.i which n is the compress level, a digit \
--       between 2 and 9, or simply run make fribidi_tab_char_type_large, \
--       retry to make.
--#endif
--
--#endif
-Only in /usr/src/fribidi/: fribidi-config
-Only in /usr/src/fribidi/: fribidi_config.h
-Only in /usr/src/fribidi/: fribidi_config.h.in
-Only in /usr/src/fribidi/: fribidi-config.in
-Only in /usr/src/fribidi/: fribidi_create_char_types
-Only in /usr/src/fribidi/: fribidi_create_char_types.c
-Only in /usr/src/fribidi/: fribidi_create_char_types.o
-Only in /usr/src/fribidi/: fribidi_create_mirroring.c
-Only in /usr/src/fribidi/: fribidi_env.c
-Only in /usr/src/fribidi/: fribidi_env.h
-Only in mini-fribidi/: fribidi_get_type.c
-Only in /usr/src/fribidi/: fribidi.h
-Only in /usr/src/fribidi/: fribidi_main.c
-Only in /usr/src/fribidi/: fribidi_mem.c
-Only in /usr/src/fribidi/: fribidi_mem.h
-Only in /usr/src/fribidi/: fribidi_mirroring.c
-Only in mini-fribidi/: fribidi.patch
-Only in /usr/src/fribidi/: fribidi.pc
-Only in /usr/src/fribidi/: fribidi.pc.in
-Only in /usr/src/fribidi/: fribidi.spec
-Only in /usr/src/fribidi/: fribidi.spec.in
-diff -bu /usr/src/fribidi/fribidi_tab_char_type_2.i mini-fribidi/fribidi_tab_char_type_2.i
---- /usr/src/fribidi/fribidi_tab_char_type_2.i	2003-07-17 17:18:01.000000000 -0400
-+++ mini-fribidi/fribidi_tab_char_type_2.i	2003-07-17 17:49:01.000000000 -0400
-@@ -1,12 +1,13 @@
- /*
--  This file was automatically created from UnicodeData.txt version 3.2.0
-+  This file was automatically created from UnicodeData.txt version 4.0.0
-   by fribidi_create_char_types
- */
- 
- #ifndef FRIBIDI_TAB_CHAR_TYPE_2_I
- #define FRIBIDI_TAB_CHAR_TYPE_2_I
- 
--#include "fribidi.h"
-+#include <glib.h>
-+#include "fribidi_types.h"
- 
- #define LTR FRIBIDI_PROP_TYPE_LTR
- #define RTL FRIBIDI_PROP_TYPE_RTL
-@@ -28,9 +29,6 @@
- #define SS FRIBIDI_PROP_TYPE_SS
- #define WS FRIBIDI_PROP_TYPE_WS
- 
--#define PACKTAB_UINT8 fribidi_uint8
--#define PACKTAB_UINT16 fribidi_uint16
--#define PACKTAB_UINT32 fribidi_uint32
- /*
-   Automatically generated by packtab.c version 2
- 
-@@ -979,7 +977,7 @@
-   LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,LTR,
- };
- 
--static const PACKTAB_UINT16 FriBidiPropertyBlockLevel0[4352*1] = {
-+static const guint16 FriBidiPropertyBlockLevel0[4352*1] = {
- 
- #define FriBidiPropertyBlockLevel0_0000 0x0
- 
-@@ -5363,13 +5361,13 @@
- #undef RTL
- #undef LTR
+ 
+ #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_internal() returns the bidi type of a character.
-+ *  _pango_fribidi_get_type_internal() returns the bidi type of a character.
+  *  fribidi_get_type() returns bidi type of a character.
   *----------------------------------------------------------------------*/
--FRIBIDI_API FriBidiCharType
--fribidi_get_type_internal (FriBidiChar uch)
-+FriBidiCharType
-+_pango_fribidi_get_type_internal (FriBidiChar uch)
- {
-   if (uch < 0x110000)
--    return fribidi_prop_to_type[(unsigned char)FRIBIDI_GET_TYPE (uch)];
-+    return _pango_fribidi_prop_to_type[(unsigned char)FRIBIDI_GET_TYPE (uch)];
-   else
-     return FRIBIDI_TYPE_LTR;
-   /* Non-Unicode chars */
-Only in /usr/src/fribidi/: fribidi_tab_char_type_9.i
-Only in /usr/src/fribidi/: fribidi_tab_char_type_stamp
-Only in mini-fribidi/: fribidi_tables.i
-Only in /usr/src/fribidi/: fribidi_tab_mirroring.i
-diff -bu /usr/src/fribidi/fribidi_types.c mini-fribidi/fribidi_types.c
---- /usr/src/fribidi/fribidi_types.c	2002-08-01 09:39:28.000000000 -0400
-+++ mini-fribidi/fribidi_types.c	2003-07-14 18:06:21.000000000 -0400
-@@ -19,10 +19,8 @@
-  * For licensing issues, contact <fwpg@sharif.edu>. 
-  */
- 
--#ifdef HAVE_CONFIG_H
--#include <config.h>
--#endif
--#include "fribidi.h"
-+#include <glib.h>
-+#include "fribidi_types.h"
- 
- #ifdef DEBUG
- 
-@@ -125,4 +123,4 @@
- #undef _FRIBIDI_ADD_TYPE
- };
- 
--FriBidiCharType *fribidi_prop_to_type = fribidi_prop_to_type_array;
-+FriBidiCharType *_pango_fribidi_prop_to_type = fribidi_prop_to_type_array;
-diff -bu /usr/src/fribidi/fribidi_types.h mini-fribidi/fribidi_types.h
---- /usr/src/fribidi/fribidi_types.h	2002-08-07 08:02:52.000000000 -0400
-+++ mini-fribidi/fribidi_types.h	2003-07-14 18:06:22.000000000 -0400
-@@ -23,37 +23,15 @@
- #ifndef FRIBIDI_TYPES_H
- #define FRIBIDI_TYPES_H
+   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 @@
  
--#include "fribidi_config.h"
-+#include <glib.h>
+ #endif
  
--#ifdef __cplusplus
--extern "C"
+-char *
+-fribidi_type_name (FriBidiCharType c)
 -{
--#endif
+-#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
--#define FRIBIDI_INT16	short
--#define FRIBIDI_INT32	long
--#define FRIBIDI_INT	int
+-#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;
@@ -1197,499 +1146,25 @@ diff -bu /usr/src/fribidi/fribidi_types.
 -  typedef unsigned FRIBIDI_INT16 fribidi_uint16;
 -  typedef signed FRIBIDI_INT32 fribidi_int32;
 -  typedef unsigned FRIBIDI_INT32 fribidi_uint32;
--  typedef signed FRIBIDI_INT fribidi_int;
--  typedef unsigned FRIBIDI_INT fribidi_uint;
--
--
--  typedef fribidi_int8 FriBidiLevel;
++  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 fribidi_int32 FriBidiMaskType;
-+  typedef gint8 FriBidiLevel;
 +  typedef gunichar FriBidiChar;
-+  typedef gint FriBidiStrIndex;
-+  typedef gint32 FriBidiMaskType;
++  typedef gsize FriBidiStrIndex;
+   typedef fribidi_int32 FriBidiMaskType;
    typedef FriBidiMaskType FriBidiCharType;
  
--  char *fribidi_type_name (FriBidiCharType c);
-+  gchar *fribidi_type_name (FriBidiCharType c);
- 
- /* The following type is used by fribidi_utils */
-   typedef struct
-@@ -291,10 +269,9 @@
- 	(FRIBIDI_IS_OVERRIDE(p) ? FRIBIDI_LEVEL_TO_DIR(FRIBIDI_DIR_TO_LEVEL(p)) \
- 				: FRIBIDI_TYPE_ON)
- 
--
- /*
-  * Define character types that char_type_tables use.
-- * define them to be 0, 1, 2, ... and then in fribidi_get_type.c map them
-+ * define them to be 0, 1, 2, ... and then in _pango_fribidi_get_type.c map them
-  * to FriBidiCharTypes.
-  */
-   typedef char FriBidiPropCharType;
-@@ -308,10 +285,12 @@
-   };
- 
- /* Map fribidi_prop_types to fribidi_types */
--  extern FriBidiCharType *fribidi_prop_to_type;
-+  extern FriBidiCharType *_pango_fribidi_prop_to_type;
- 
--#ifdef	__cplusplus
--}
--#endif
- 
--#endif
-+/*======================================================================
-+ *  _pango_fribidi_get_type() returns bidi type of a character.
-+ *----------------------------------------------------------------------*/
-+  FriBidiCharType _pango_fribidi_get_type (FriBidiChar uch);
-+
-+#endif  /* #ifndef FRIBIDI_TYPES_H */
-Only in /usr/src/fribidi/: fribidi_unicode.h
-Only in /usr/src/fribidi/: fribidi_utils.c
-Only in /usr/src/fribidi/: fribidi_wcwidth.c
-Only in /usr/src/fribidi/: fribidi_wcwidth.i
-Only in /usr/src/fribidi/: getopt1.c
-Only in /usr/src/fribidi/: getopt.c
-Only in /usr/src/fribidi/: getopt.h
-Only in /usr/src/fribidi/: .indent.pro
-Only in /usr/src/fribidi/: INSTALL
-Only in /usr/src/fribidi/: install-sh
-Only in /usr/src/fribidi/: .libs
-Only in /usr/src/fribidi/: libtool
-Only in /usr/src/fribidi/: ltconfig
-Only in /usr/src/fribidi/: ltmain.sh
-Only in /usr/src/fribidi/: Makefile
-diff -bu /usr/src/fribidi/Makefile.am mini-fribidi/Makefile.am
---- /usr/src/fribidi/Makefile.am	2002-08-10 00:17:54.000000000 -0400
-+++ mini-fribidi/Makefile.am	2003-07-14 18:21:14.000000000 -0400
-@@ -1,208 +1,30 @@
-+## Process this file with automake to produce Makefile.in
- 
--AUTOMAKE_OPTIONS = gnu 
-+INCLUDES = 					\
-+	-DSYSCONFDIR=\"$(sysconfdir)\" 		\
-+	-DLIBDIR=\"$(libdir)\" 			\
-+	-DG_DISABLE_DEPRECATED			\
-+	$(PANGO_DEBUG_FLAGS)			\
-+	-I$(top_srcdir)				\
-+	$(GLIB_CFLAGS)
-+
-+LDADDS = @STRIP_BEGIN@ 	\
-+	@x_ldflags@	\
-+	@x_libs@	\
-+	@GLIB_LIBS@	\
-+	-lm		\
-+@STRIP_END@
- 
--noinst_PROGRAMS = fribidi_benchmark	\
--		fribidi_create_char_types	\
--		fribidi_create_mirroring
--
--libfribidi_charsets =	\
--	fribidi_char_sets.c	\
--	fribidi_char_sets_utf8.c
--
--libfribidi_charsets_extra =	\
--	fribidi_char_sets_cap_rtl.c	\
--	fribidi_char_sets_iso8859_6.c	\
--	fribidi_char_sets_iso8859_8.c	\
--	fribidi_char_sets_cp1255.c	\
--	fribidi_char_sets_cp1256.c	\
--	fribidi_char_sets_isiri_3342.c
--
--libfribidi_charsets_h =	\
--	fribidi_char_sets.h	\
--	fribidi_char_sets_utf8.h
--
--libfribidi_charsets_extra_h =	\
--	fribidi_char_sets_cap_rtl.h	\
--	fribidi_char_sets_cp1255.h	\
--	fribidi_char_sets_cp1256.h	\
--	fribidi_char_sets_isiri_3342.h	\
--	fribidi_char_sets_iso8859_6.h	\
--	fribidi_char_sets_iso8859_8.h
-+noinst_LTLIBRARIES = libmini-fribidi.la
- 
--libfribidi_extra_h =	\
--	fribidi_mem.h
--
--lib_LTLIBRARIES = libfribidi.la
--
--libfribidi_la_SOURCES =	\
-+libmini_fribidi_la_SOURCES =    \
- 	fribidi.c	\
--	fribidi_types.c		\
--	fribidi_env.c	\
--	fribidi_mem.c	\
--	fribidi_mirroring.c	\
- 	fribidi_char_type.c	\
--	fribidi_wcwidth.c	\
--	fribidi_utils.c	\
--	$(libfribidi_charsets)	\
--	$(libfribidi_charsets_extra)
--
--libfribidi_la_LIBADD = 
--
--libfribidiincdir = $(includedir)/fribidi
--
--libfribidiinc_HEADERS =	\
--	fribidi.h	\
--	fribidi_types.h	\
--	fribidi_env.h	\
--	fribidi_unicode.h	\
--	$(libfribidi_charsets_h)	\
--	$(libfribidi_charsets_extra_h)	\
--	fribidi_config.h
--
--GETOPT_SRC =	\
--	getopt.c	\
--	getopt1.c
--
--GETOPT_HDR =	\
--	getopt.h
--
--TEST_FILES =	\
--	tests/test_CapRTL_explicit.input	\
--	tests/test_CapRTL_explicit.reference	\
--	tests/test_CapRTL_implicit.input	\
--	tests/test_CapRTL_implicit.reference	\
--	tests/test_ISO8859-8_hebrew.input	\
--	tests/test_ISO8859-8_hebrew.reference	\
--	tests/test_UTF-8_persian.input	\
--	tests/test_UTF-8_persian.reference
--
--TABLE_FILES =	\
--	fribidi_types.i	\
--	fribidi_char_sets.i	\
--	fribidi_tab_mirroring.i	\
--	fribidi_tab_char_type_2.i	\
--	fribidi_tab_char_type_9.i
--
--UNIDATA_FILES =	\
--	unidata/README	\
--	unidata/UnicodeData.txt	\
--	unidata/BidiMirroring.txt
--
--OTHER_FILES =	\
--	fribidi_wcwidth.i
--
--EXTRA_HEADERS =	\
--	packtab.h	\
--	$(libfribidi_extra_h)	\
--	$(GETOPT_HDR)
-+	fribidi_types.c 	\
-+	fribidi_types.h
- 
- EXTRA_DIST =	\
--	bootstrap \
--	run.tests	\
--	ANNOUNCE	\
--	acinclude.m4	\
--	fribidi_config.h.in	\
--	fribidi.pc.in	\
--	fribidi.spec.in	\
--	fribidi.spec	\
--	$(TEST_FILES)	\
--	$(TABLE_FILES)	\
--	$(UNIDATA_FILES)	\
--	$(OTHER_FILES)	\
--	$(EXTRA_HEADERS)
--
--fribidi_benchmark_SOURCES = fribidi_benchmark.c $(GETOPT_SRC)
--fribidi_benchmark_LDADD = libfribidi.la
--
--fribidi_create_char_types_SOURCES = fribidi_create_char_types.c packtab.c
--
--fribidi_create_mirroring_SOURCES = fribidi_create_mirroring.c
--
--bin_PROGRAMS = fribidi
--fribidi_SOURCES = fribidi_main.c $(GETOPT_SRC)
--fribidi_LDADD = libfribidi.la
--
--
--fribidi_tab_mirroring.i: $(fribidi_create_mirroring_SOURCES) fribidi_types.h	\
--		unidata/BidiMirroring.txt
--	$(MAKE) fribidi_create_mirroring
--	if test -d unidata; then UNIDATA=unidata;	\
--	else UNIDATA="$(srcdir)/unidata"; fi &&	\
--	./fribidi_create_mirroring "$$UNIDATA" ||	\
--	($(RM) "$@"; false)
--
--
--$(srcdir)/fribidi_mirroring.c: fribidi_tab_mirroring.i
--	touch "$@" || $(MAKE) clean
--
--fribidi_tab_mirroring:	fribidi_tab_mirroring.i
--
--
--fribidi_tab_char_type_%.i: $(fribidi_create_char_types_SOURCES)	\
--		unidata/UnicodeData.txt
--	$(MAKE) fribidi_create_char_types
--	if test -d unidata; then UNIDATA=unidata;	\
--	else UNIDATA="$(srcdir)/unidata"; fi &&	\
--	./fribidi_create_char_types "`echo "$@"	\
--	  | $(SED) 's/[^0-9]*//g'`" "$$UNIDATA" ||	\
--	($(RM) "$@"; false)
--	$(RM) fribidi_tab_char_type_stamp
--	$(MAKE) fribidi_tab_char_type_stamp
--
--fribidi_tab_char_type_stamp:
--	touch "$(srcdir)/fribidi_char_type.c" || $(MAKE) clean
--	touch "$@"
--
--fribidi_tab_char_type_small:
--	$(MAKE) fribidi_tab_char_type_9.i
--
--fribidi_tab_char_type_large:
--	$(MAKE) fribidi_tab_char_type_2.i
--
--fribidi_tab tab:	fribidi_tab_char_type_small	\
--			fribidi_tab_char_type_large	\
--			fribidi_tab_mirroring
--
--
--config.h: fribidi_tab_char_type_stamp
--	./config.status --recheck
--	./config.status
--	touch "$@"
--
--$(srcdir)/fribidi_char_type.c: config.h
--
--tests/test_%.reference: tests/test_%.input $(libfribidi_la_SOURCES)
--	$(MAKE) fribidi
--	(test -d tests || mkdir tests) &&	\
--	testcase="$@" && 	\
--	charset="`echo "$@" | $(SED) 's/_[^_]*$$//;s/.*_//'`" &&	\
--	./fribidi --test --charset "$$charset" "$<" > "$@" || \
--	($(RM) "$@"; false)
--
--test.reference:
--	for testcase in "$(srcdir)"/tests/test_*.input; do	\
--		test="`echo "$$testcase"	\
--		  | $(SED) 's/\.input$$/.reference/i; s|.*/||;'`" &&	\
--		$(MAKE) "tests/$$test" ||	\
--		exit 1;	\
--	done
--
--test: fribidi
--	"$(srcdir)/run.tests"
--
--.PHONY:		test test.reference	\
--		fribidi_tab_char_type_small fribidi_tab_char_type_large	\
--		fribidi_tab_mirroring fribidi_tab tab
--
--TESTS = run.tests
--
--bin_SCRIPTS = fribidi-config
--
--pkgconfigdir = $(libdir)/pkgconfig
--pkgconfig_DATA = fribidi.pc
--
--CLEANFILES = 
--
--DISTCLEANFILES = fribidi_tab_char_type_stamp
-+	README	                \
-+	fribidi_tab_char_type_2.i \
-+        fribidi_types.i
- 
--MAINTAINERCLEANFILES = Makefile.in configure aclocal.m4 config.h.in
-Only in /usr/src/fribidi/: Makefile.in
-Only in /usr/src/fribidi/: missing
-Only in /usr/src/fribidi/: mkinstalldirs
-Only in /usr/src/fribidi/: NEWS
-Only in /usr/src/fribidi/: packtab.c
-Only in /usr/src/fribidi/: packtab.h
-Only in /usr/src/fribidi/: packtab.o
-diff -bu /usr/src/fribidi/README mini-fribidi/README
---- /usr/src/fribidi/README	2002-08-07 06:23:34.000000000 -0400
-+++ mini-fribidi/README	2003-07-14 18:31:21.000000000 -0400
-@@ -1,149 +1,44 @@
-+This directory holds a stripped down version of Dov Grobgeld's FriBidi
-+library. The fribidi version that fribidi.patch is against was
-+obtained with "cvs up -D '2003-07-14'" from the fribidi cvs repository.
-+
-+Like Pango, FriBidi is licensed under the terms of the GNU Lesser
-+General Public License - see the file COPYING in the toplevel
-+directory of the Pango distribution.
-+
-+12 November 2000, 18 October 2001
-+Owen Taylor
-+14 July 2003
-+Noah Levitt
-+
-+
-+From the README of Fribidi:
-+
-+
- This is is FriBidi, a Free Implementation of the Unicode BiDi algorithm.
- 
- Background
- ==========
--One of the missing links stopping the penetration of free software in Middle
--East is the lack of support for the Arabic and Hebrew alphabets. In order to
--have proper Arabic and Hebrew support, the BiDi algorithm should have been
--implemented. It is our hope that this library will stimulate more free
--software in the Middle Eastern countries.
-+One of the missing links stopping the penetration of free software in
-+Israel is the lack of support for Hebrew. In order to have proper
-+Hebrew support, the BiDi algorithm must be implemented. It is my hope
-+that this library will stimulate more Hebrew free software.
-+
-+Of course the BiDi algorithm is not limited to Hebrew, so I expect 
-+that our Arab neighbors will also find this software useful.
- 
- Audience
- ========
--It is our hope that this library will stimulate the implementation of Hebrew
--and Arabic in lots of free software. Here is a small list of projects that
--would benifit from the use of the FriBidi library, but of course there are
--many more: Wine, Mozilla, Qt, KDE, lynx, OpenOffice.
- 
--It may be interesting for you to know that Fribidi is already being used in
--projects like Gnome, GTK+, Pango, AbiWord, and Xterm.
-+It is my hope that this library will stimulate the implementation of
-+Hebrew and Arabic in lots of free software. Here is a small list of
-+projects that would benifit from the use of the FriBidi library, but
-+of course there are many more: Wine, Mozilla, Gtk, Gnome, Qt, KDE,
-+AbiWord, lynx.
- 
- Downloading
- ===========
- The latest version of FriBidi may be found at:
- 
--   http://fribidi.sourceforge.net/
--
--Building
--========
--See INSTALL for a description of how to build and install this library.
--
--Copyright
--=========
--Fribidi is:
--Copyright (C) 1999,2000 Dov Grobgeld, and
--Copyright (C) 2001,2002 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; 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>.
--
--Implementation
--==============
--The library implements the algorithm described in the "Unicode Standard
--Annex #9, The Bidirectional Algorithm", available at
--http://www.unicode.org/unicode/reports/tr9/. Fribidi has been tested
--exhaustively against the Unicode Reference Code, and due to our knowledge,
--it completely conforms to the specification, always producing the same
--result as the Reference Code.
--
--In the API we were inspired by the document "Bi-Di languages support
--- BiDi API propasal", http://www.langbox.com/AraMosaic/mozilla/BiDi_API.html,
--by Franck Portaneri <franck@langbox.com> which he wrote as a proposal for
--adding BiDi support to Mozilla.
--
--Internally, the library uses Unicode entirely. The character property
--function was automatically created from the Unicode property list document
--PropList.txt available from the Unicode FTP site. This means that every
--Unicode character is treated in strict accordance with the Unicode
--specification. The same is true for the mirroring of characters, which also
--works for all the characters listed as mirrorable in the the Unicode
--specification.
--
--Other character sets must be converted into Unicode before the library
--may be used. In order to use, e.g. iso8859-8, the function
--
--     void
--     fribidi_iso8859_8_to_unicode(guchar *s,
--             	                  /* output */
--	    	                  FriBidiChar *us)
--
--must be called which translates the guchar string *s to a unicode 
--string. There is also a corresponding fribidi_unicode_to_iso8859_8
--that may be called to convert the string back to iso8859_8 for output.
--
--The reordering of characters is done through the function:
--      
--     void
--     fribidi_log2vis(/* input */
--		     FriBidiChar *str,
--		     int len,
--		     FriBidiCharType *pbase_dir,
--		     /* output */
--		     FriBidiChar *visual_str,
--		     gint        *position_L_to_V_list,
--		     gint        *position_V_to_L_list,
--		     gint8       *embedding_level_list
--		     )
--    
--
--where
--     str                    is the Unicode input string
--     len                    is the length of the unicode string
--     pbase_dir              is the input and output base direction. If 
--                            base == FRIBIDI_TYPE_ON then fribidi_log2vis 
--                            calculates the base direction on its own
--                            according to the BiDi algorithm.
--     visual_str             The reordered output unicode string.
--     position_L_to_V_list   Maps the positions in the logical string to 
--                            positions in the visual string.
--     position_V_to_L_list   Maps the positions in the visual string to 
--                            the positions in the logical string.
--     embedding_level_list   Returns the classification of each character. Even
--                            levels indicate LTR characters, and odd levels
--                            indicate RTL characters. The main use of this
--                            list is in interactive applications when the
--                            embedding e.g. level determines cursor display.
--
--In any of the output pointers == NULL, then that information is not 
--calculated.
--
--How it looks like
--=================
--
--Have a look at tests directory, to see some input and outputs, which
--CapRTL charset means that CAPITAL letters are right to left, and digits
--6, 7, 8, 9 are Arabic digits, try 'fribidi --charsetdesc CapRTL' for the
--full description.
--
--Executable
--==========
--There is also a command line utilitity called fribidi that loops over
--the text of a file and performs the BiDi algorithm on each line, also
--used for testing the algorithm. Run fribidi with the --help option to
--learn about usage.
--
--Bugs and comments
--=================
--
--Report FriBidi bugs at:
--
--	http://fribidi.sourceforge.net/bugs.php
--
--And send your comments to:
-+   http://fribidi.sourceforge.net
- 
--	fribidi-discuss@lists.sourceforge.net
-Only in /usr/src/fribidi/: run.tests
-Only in /usr/src/fribidi/: stamp-h1
-Only in /usr/src/fribidi/: stamp-h.in
-Only in /usr/src/fribidi/: tests
-Only in /usr/src/fribidi/: THANKS
-Only in /usr/src/fribidi/: TODO
-Only in /usr/src/fribidi/: unidata
-Only in /usr/src/fribidi/: win
Index: pango/mini-fribidi/fribidi_char_type.c
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi_char_type.c,v
retrieving revision 1.1
diff -u -p -r1.1 fribidi_char_type.c
--- pango/mini-fribidi/fribidi_char_type.c	20 Nov 2003 05:34:45 -0000	1.1
+++ pango/mini-fribidi/fribidi_char_type.c	3 Nov 2005 16:41:30 -0000
@@ -19,18 +19,59 @@
  * For licensing issues, contact <fwpg@sharif.edu>. 
  */
 
-#include <glib.h>
-#include "fribidi_types.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "fribidi.h"
 
-/*======================================================================
- *  _pango_fribidi_get_type() returns the bidi type of a character.
- *----------------------------------------------------------------------*/
-FriBidiCharType _pango_fribidi_get_type_internal (FriBidiChar uch);
+#ifdef MEM_OPTIMIZED
 
-FriBidiCharType
-_pango_fribidi_get_type (FriBidiChar uch)
-{
-  return _pango_fribidi_get_type_internal (uch);
-}
+#if   HAS_FRIBIDI_TAB_CHAR_TYPE_9_I
+#include "fribidi_tab_char_type_9.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_8_I
+#include "fribidi_tab_char_type_8.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_7_I
+#include "fribidi_tab_char_type_7.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_6_I
+#include "fribidi_tab_char_type_6.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_5_I
+#include "fribidi_tab_char_type_5.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_4_I
+#include "fribidi_tab_char_type_4.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_3_I
+#include "fribidi_tab_char_type_3.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_2_I
+#include "fribidi_tab_char_type_2.i"
+#else
+#error You have no fribidi_tab_char_type_*.i file, please first make one by \
+       make fribidi_tab_char_type_n.i which n is the compress level, a digit \
+       between 2 and 9, or simply run make fribidi_tab_char_type_small, \
+       retry to make.
+#endif
+
+#else
 
+#if   HAS_FRIBIDI_TAB_CHAR_TYPE_2_I
 #include "fribidi_tab_char_type_2.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_3_I
+#include "fribidi_tab_char_type_3.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_4_I
+#include "fribidi_tab_char_type_4.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_5_I
+#include "fribidi_tab_char_type_5.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_6_I
+#include "fribidi_tab_char_type_6.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_7_I
+#include "fribidi_tab_char_type_7.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_8_I
+#include "fribidi_tab_char_type_8.i"
+#elif HAS_FRIBIDI_TAB_CHAR_TYPE_9_I
+#include "fribidi_tab_char_type_9.i"
+#else
+#error You have no fribidi_tab_char_type_*.i file, please first make one by \
+       make fribidi_tab_char_type_n.i which n is the compress level, a digit \
+       between 2 and 9, or simply run make fribidi_tab_char_type_large, \
+       retry to make.
+#endif
+
+#endif
Index: pango/mini-fribidi/fribidi_config.h
===================================================================
RCS file: pango/mini-fribidi/fribidi_config.h
diff -N pango/mini-fribidi/fribidi_config.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pango/mini-fribidi/fribidi_config.h	3 Nov 2005 16:41:30 -0000
@@ -0,0 +1,35 @@
+#include <glib.h>
+
+#define FRIBIDI_TRUE    TRUE
+#define FRIBIDI_FALSE   FALSE
+#define HAS_FRIBIDI_TAB_CHAR_TYPE_2_I 1
+#define FRIBIDI_API
+
+/* this was in fribidi_unicode.h.  we only need these bits from that
+ * file, so moved here. */
+#define UNI_MAX_BIDI_LEVEL 61
+
+/* ripped off debugging functions, make sure it's not triggerred. */
+#undef DEBUG
+
+/* fribidi's memchunk code was a reimplementation of glib's api.
+ * use glib proper. */
+# include <glib/gmem.h>
+#define FriBidiMemChunk GMemChunk
+#define FRIBIDI_ALLOC_ONLY G_ALLOC_ONLY
+#define fribidi_mem_chunk_new g_mem_chunk_new
+#define fribidi_mem_chunk_create g_mem_chunk_create
+#define fribidi_mem_chunk_alloc g_mem_chunk_alloc
+#define fribidi_mem_chunk_destroy g_mem_chunk_destroy
+#define fribidi_chunk_new g_chunk_new
+
+/* g_malloc and g_free verbatim */
+#define malloc g_malloc
+#define free g_free
+
+/* rename symbols to pango internal namespace */
+#define fribidi_log2vis_get_embedding_levels_new_utf8 _pango_fribidi_log2vis_get_embedding_levels_new_utf8
+#define fribidi_prop_to_type _pango_fribidi_prop_to_type
+#define fribidi_get_type _pango_fribidi_get_type
+#define fribidi_get_type_internal fribidi_get_type
+
Index: pango/mini-fribidi/fribidi_tab_char_type_2.i
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi_tab_char_type_2.i,v
retrieving revision 1.2
diff -u -p -r1.2 fribidi_tab_char_type_2.i
--- pango/mini-fribidi/fribidi_tab_char_type_2.i	15 Aug 2005 22:10:03 -0000	1.2
+++ pango/mini-fribidi/fribidi_tab_char_type_2.i	3 Nov 2005 16:41:30 -0000
@@ -6,8 +6,7 @@
 #ifndef FRIBIDI_TAB_CHAR_TYPE_2_I
 #define FRIBIDI_TAB_CHAR_TYPE_2_I
 
-#include <glib.h>
-#include "fribidi_types.h"
+#include "fribidi.h"
 
 #define LTR FRIBIDI_PROP_TYPE_LTR
 #define RTL FRIBIDI_PROP_TYPE_RTL
@@ -29,6 +28,9 @@
 #define SS FRIBIDI_PROP_TYPE_SS
 #define WS FRIBIDI_PROP_TYPE_WS
 
+#define PACKTAB_UINT8 fribidi_uint8
+#define PACKTAB_UINT16 fribidi_uint16
+#define PACKTAB_UINT32 fribidi_uint32
 /*
   Automatically generated by packtab.c version 2
 
@@ -1186,7 +1188,7 @@ static const FriBidiPropCharType FriBidi
    BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN, BN,
 };
 
-static const guint16 FriBidiPropertyBlockLevel0[4352*1] = {
+static const PACKTAB_UINT16 FriBidiPropertyBlockLevel0[4352*1] = {
 
 #define FriBidiPropertyBlockLevel0_0000 0x0
 
@@ -5570,13 +5572,13 @@ static const guint16 FriBidiPropertyBloc
 #undef RTL
 #undef LTR
 /*======================================================================
- *  _pango_fribidi_get_type_internal() returns the bidi type of a character.
+ *  fribidi_get_type_internal() returns the bidi type of a character.
  *----------------------------------------------------------------------*/
-FriBidiCharType
-_pango_fribidi_get_type_internal (FriBidiChar uch)
+FRIBIDI_API FriBidiCharType
+fribidi_get_type_internal (FriBidiChar uch)
 {
   if (uch < 0x110000)
-    return _pango_fribidi_prop_to_type[(unsigned char)FRIBIDI_GET_TYPE (uch)];
+    return fribidi_prop_to_type[(unsigned char)FRIBIDI_GET_TYPE (uch)];
   else
     return FRIBIDI_TYPE_LTR;
   /* Non-Unicode chars */
Index: pango/mini-fribidi/fribidi_types.c
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi_types.c,v
retrieving revision 1.4
diff -u -p -r1.4 fribidi_types.c
--- pango/mini-fribidi/fribidi_types.c	5 Mar 2005 21:52:42 -0000	1.4
+++ pango/mini-fribidi/fribidi_types.c	3 Nov 2005 16:41:30 -0000
@@ -19,8 +19,10 @@
  * For licensing issues, contact <fwpg@sharif.edu>. 
  */
 
-#include <glib.h>
-#include "fribidi_types.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "fribidi.h"
 
 #ifdef DEBUG
 
@@ -76,51 +78,11 @@ fribidi_char_from_type (FriBidiCharType 
     }
 };
 
-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
-}
-
 #endif
 
 /* Map fribidi_prop_types to fribidi_types. */
-static const FriBidiCharType fribidi_prop_to_type_array[] = {
+const FriBidiCharType fribidi_prop_to_type[] = {
 #define _FRIBIDI_ADD_TYPE(TYPE) FRIBIDI_TYPE_##TYPE,
 #include "fribidi_types.i"
 #undef _FRIBIDI_ADD_TYPE
 };
-
-const FriBidiCharType *_pango_fribidi_prop_to_type = fribidi_prop_to_type_array;
Index: pango/mini-fribidi/fribidi_types.h
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi_types.h,v
retrieving revision 1.6
diff -u -p -r1.6 fribidi_types.h
--- pango/mini-fribidi/fribidi_types.h	5 Mar 2005 21:52:42 -0000	1.6
+++ pango/mini-fribidi/fribidi_types.h	3 Nov 2005 16:41:30 -0000
@@ -23,15 +23,32 @@
 #ifndef FRIBIDI_TYPES_H
 #define FRIBIDI_TYPES_H
 
-#include <glib.h>
+#include "fribidi_config.h"
 
-  typedef gint8 FriBidiLevel;
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+  typedef gboolean fribidi_boolean;
+
+  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 gunichar FriBidiChar;
-  typedef gint FriBidiStrIndex;
-  typedef gint32 FriBidiMaskType;
+  typedef gsize FriBidiStrIndex;
+  typedef fribidi_int32 FriBidiMaskType;
   typedef FriBidiMaskType FriBidiCharType;
 
-  gchar *fribidi_type_name (FriBidiCharType c);
+  char *fribidi_type_name (FriBidiCharType c);
 
 /* The following type is used by fribidi_utils */
   typedef struct
@@ -41,7 +58,7 @@
   }
   FriBidiRunType;
 
-/* The following type is used by fribidi_utils */
+/* The following type is used by fribdi_utils */
   typedef struct _FriBidiList FriBidiList;
   struct _FriBidiList
   {
@@ -51,9 +68,10 @@
   };
 
 #ifndef FRIBIDI_MAX_STRING_LENGTH
-#define FRIBIDI_MAX_STRING_LENGTH (sizeof (FriBidiStrIndex) == 2 ?	\
+#define FRIBIDI_MAX_STRING_LENGTH (FriBidiStrIndex) \
+				  (sizeof (FriBidiStrIndex) == 2 ?	\
     				   0x7FFE : (sizeof (FriBidiStrIndex) == 1 ? \
-					     0x7E : 0x8FFFFFFEL))
+					     0x7E : 0x7FFFFFFEL))
 #endif
 
 
@@ -269,9 +287,10 @@
 	(FRIBIDI_IS_OVERRIDE(p) ? FRIBIDI_LEVEL_TO_DIR(FRIBIDI_DIR_TO_LEVEL(p)) \
 				: FRIBIDI_TYPE_ON)
 
+
 /*
  * Define character types that char_type_tables use.
- * define them to be 0, 1, 2, ... and then in _pango_fribidi_get_type.c map them
+ * define them to be 0, 1, 2, ... and then in fribidi_char_type.c map them
  * to FriBidiCharTypes.
  */
   typedef char FriBidiPropCharType;
@@ -285,12 +304,10 @@
   };
 
 /* Map fribidi_prop_types to fribidi_types */
-  extern const FriBidiCharType *_pango_fribidi_prop_to_type;
-
+  extern const FriBidiCharType fribidi_prop_to_type[];
 
-/*======================================================================
- *  _pango_fribidi_get_type() returns bidi type of a character.
- *----------------------------------------------------------------------*/
-  FriBidiCharType _pango_fribidi_get_type (FriBidiChar uch);
+#ifdef	__cplusplus
+}
+#endif
 
-#endif  /* #ifndef FRIBIDI_TYPES_H */
+#endif
