Index: examples/pangoft2topgm.c
===================================================================
RCS file: /cvs/gnome/pango/examples/pangoft2topgm.c,v
retrieving revision 1.9
diff -u -p -r1.9 pangoft2topgm.c
--- examples/pangoft2topgm.c	15 Sep 2003 19:54:39 -0000	1.9
+++ examples/pangoft2topgm.c	14 Oct 2003 20:53:09 -0000
@@ -54,6 +54,7 @@ static char *opt_output = NULL;
 static int opt_margin = 10;
 static int opt_markup = FALSE;
 static gboolean opt_rtl = FALSE;
+static gboolean opt_auto_dir = FALSE;
 static char *opt_text = NULL;
 static  gboolean opt_waterfall = FALSE;
 static  int opt_width = -1;
@@ -105,6 +106,8 @@ make_layout(PangoContext *context,
   else
     pango_layout_set_text (layout, text, -1);
 
+  pango_layout_set_auto_dir(layout, opt_auto_dir);
+  
   font_description = get_font_description ();
   if (size > 0)
     pango_font_description_set_size (font_description, size * PANGO_SCALE);
@@ -254,6 +257,8 @@ int main(int argc, char *argv[])
       ARG_STRING,   &opt_output },
     { "rtl",        "Set base dir to RTL",
       ARG_BOOL,     &opt_rtl },
+    { "auto_dir",   "Set layout direction according to contents",
+      ARG_BOOL,     &opt_auto_dir },
     { "text",       "Text to display (instead of a file)",
       ARG_STRING,   &opt_text },
     { "waterfall",  "Create a waterfall display",
Index: pango/pango-context.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-context.c,v
retrieving revision 1.56
diff -u -p -r1.56 pango-context.c
--- pango/pango-context.c	23 Sep 2003 23:47:54 -0000	1.56
+++ pango/pango-context.c	14 Oct 2003 20:53:18 -0000
@@ -325,6 +325,13 @@ pango_context_get_language (PangoContext
  * @direction: the new base direction
  * 
  * Sets the base direction for the context.
+ *
+ * The base direction is used in applying the Unicode bidirectional
+ * algorithm; if the @direction is %PANGO_DIRECTION_LTR or
+ * %PANGO_DIRECTION_RTL, then the value will be used as the paragraph
+ * direction in the Unicode bidirectional algorithm.  A value of
+ * %PANGO_DIRECTION_WEAK_LTR or %PANGO_DIRECTION_WEAK_RTL is used only
+ * for paragraphs that do not contain any strong characters themselves. 
  **/
 void
 pango_context_set_base_dir (PangoContext  *context,
@@ -337,9 +344,10 @@ pango_context_set_base_dir (PangoContext
 
 /**
  * pango_context_get_base_dir:
- * @context: 
+ * @context: a #PangoContext
  * 
- * Retrieves the base direction for the context.
+ * Retrieves the base direction for the context. See
+ * pango_context_set_base_dir().
  * 
  * Return value: the base direction for the context.
  **/
@@ -563,12 +571,12 @@ static void
 itemize_state_init (ItemizeState      *state,
 		    PangoContext      *context, 
 		    const char        *text,
+		    PangoDirection     base_dir,
 		    int                start_index,
 		    int                length,
 		    PangoAttrList     *attrs,
 		    PangoAttrIterator *cached_iter)
 {
-  PangoDirection base_dir;
   gunichar *text_ucs4;
   long n_chars;
 
@@ -584,8 +592,6 @@ itemize_state_init (ItemizeState      *s
   /* First, apply the bidirectional algorithm to break
    * the text into directional runs.
    */
-  base_dir = context->base_dir;
-
   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,
@@ -997,6 +1003,7 @@ itemize_state_finish (ItemizeState *stat
  * @context:   a structure holding information that affects
                the itemization process.
  * @text:      the text to itemize.
+ * @base_dir:  base direction to use for BiDi algorithm.
  * @start_index: first byte in @text to process
  * @length:    the number of bytes (not characters) to process
  *             after @start_index.
@@ -1020,6 +1027,7 @@ itemize_state_finish (ItemizeState *stat
 GList *
 pango_itemize (PangoContext      *context, 
 	       const char        *text,
+	       PangoDirection     base_dir,
                int                start_index,
 	       int                length,
 	       PangoAttrList     *attrs,
@@ -1035,7 +1043,7 @@ pango_itemize (PangoContext      *contex
   if (length == 0)
     return NULL;
 
-  itemize_state_init (&state, context, text, start_index, length,
+  itemize_state_init (&state, context, text, base_dir, start_index, length,
 		      attrs, cached_iter);
 
   do 
Index: pango/pango-context.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-context.h,v
retrieving revision 1.16
diff -u -p -r1.16 pango-context.h
--- pango/pango-context.h	18 Nov 2001 23:23:14 -0000	1.16
+++ pango/pango-context.h	14 Oct 2003 20:53:19 -0000
@@ -84,6 +84,7 @@ PangoDirection            pango_context_
  */
 GList *pango_itemize (PangoContext      *context,
                       const char        *text,
+		      PangoDirection     base_dir,
                       int                start_index,
                       int                length,
                       PangoAttrList     *attrs,
Index: pango/pango-layout.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-layout.c,v
retrieving revision 1.104
diff -u -p -r1.104 pango-layout.c
--- pango/pango-layout.c	3 Aug 2003 21:57:33 -0000	1.104
+++ pango/pango-layout.c	14 Oct 2003 20:53:43 -0000
@@ -24,6 +24,7 @@
 #include <pango/pango-break.h>
 #include <pango/pango-item.h>
 #include <pango/pango-engine.h>
+#include <pango/pango-utils.h>
 #include <string.h>
 
 #define LINE_IS_VALID(line) ((line)->layout != NULL)
@@ -117,6 +118,7 @@ struct _PangoLayout
   guint alignment : 2;
 
   guint single_paragraph : 1;
+  guint auto_dir : 1;
   
   gint n_chars;		        /* Total number of characters in layout */
   PangoLogAttr *log_attrs;	/* Logical attributes for layout's text */
@@ -203,6 +205,7 @@ pango_layout_init (PangoLayout *layout)
 
   layout->alignment = PANGO_ALIGN_LEFT;
   layout->justify = FALSE;
+  layout->auto_dir = TRUE;
 
   layout->log_attrs = NULL;
   layout->lines = NULL;
@@ -591,6 +594,39 @@ pango_layout_get_justify (PangoLayout *l
 }
 
 /**
+ * pango_layout_set_auto_dir:
+ * @layout: a #PangoLayout
+ * @auto_dir: whether to do auto bidi dir according to the contents.
+ * 
+ * Sets whether or not to calculate the bidi direction according to
+ * the contents of the layout.
+ **/
+void
+pango_layout_set_auto_dir (PangoLayout *layout,
+			   gboolean     auto_dir)
+{
+  g_return_if_fail (layout != NULL);
+
+  layout->auto_dir = auto_dir;
+}
+
+/**
+ * pango_layout_get_auto_dir:
+ * @layout: a #PangoLayout
+ * 
+ * Gets whether or not the bidi direction of the layout are calculated
+ * according to the layout contents.
+ * 
+ * Return value: the auto_dir
+ **/
+gboolean
+pango_layout_get_auto_dir (PangoLayout *layout)
+{
+  g_return_val_if_fail (layout != NULL, FALSE);
+  return layout->auto_dir;
+}
+
+/**
  * pango_layout_set_alignment:
  * @layout: a #PangoLayout
  * @alignment: the new alignment
@@ -1243,11 +1279,11 @@ pango_layout_move_cursor_visually (Pango
 
   pango_layout_check_lines (layout);
 
-  base_dir = pango_context_get_base_dir (layout->context);
-
   /* Find the line the old cursor is on */
   line = pango_layout_index_to_line (layout, old_index,
 				     NULL, &prev_line, &next_line);
+
+  base_dir = line->resolved_dir;
   
   start_offset = g_utf8_pointer_to_offset (layout->text, layout->text + line->start_index);
 
@@ -1550,7 +1586,7 @@ pango_layout_line_get_vis2log_map (Pango
 				   gboolean         strong)
 {
   PangoLayout *layout = line->layout;
-  PangoDirection base_dir = pango_context_get_base_dir (layout->context);
+  PangoDirection base_dir = line->resolved_dir;
   PangoDirection prev_dir;
   PangoDirection cursor_dir;
   GSList *tmp_list;
@@ -1714,11 +1750,11 @@ pango_layout_get_cursor_pos (PangoLayout
   g_return_if_fail (layout != NULL);
   g_return_if_fail (index >= 0 && index <= layout->length);
   
-  base_dir = pango_context_get_base_dir (layout->context);
-
   layout_line = pango_layout_index_to_line_and_extents (layout, index,
 							&line_rect);
 
+  base_dir = layout_line->resolved_dir;
+  
   g_assert (index >= layout_line->start_index);
   
   /* Examine the trailing edge of the character before the cursor */
@@ -1788,10 +1824,20 @@ get_x_offset (PangoLayout     *layout,
               int              line_width,
               int             *x_offset)
 {
+  PangoAlignment alignment = layout->alignment;
+
+  if (line->layout->auto_dir && line->resolved_dir == PANGO_DIRECTION_RTL)
+    {
+      if (alignment == PANGO_ALIGN_LEFT)
+	alignment = PANGO_ALIGN_RIGHT;
+      else if (alignment == PANGO_ALIGN_RIGHT)
+	alignment = PANGO_ALIGN_LEFT;
+    }
+	
   /* Alignment */
-  if (layout->alignment == PANGO_ALIGN_RIGHT)
+  if (alignment == PANGO_ALIGN_RIGHT)
     *x_offset = layout_width - line_width;
-  else if (layout->alignment == PANGO_ALIGN_CENTER)
+  else if (alignment == PANGO_ALIGN_CENTER)
     *x_offset = (layout_width - line_width) / 2;
   else
     *x_offset = 0;
@@ -1805,7 +1851,7 @@ get_x_offset (PangoLayout     *layout,
    * knowing whether left/right is the "normal" thing for this text
    */
    
-  if (layout->alignment == PANGO_ALIGN_CENTER)
+  if (alignment == PANGO_ALIGN_CENTER)
     return;
   
   if (line == layout->lines->data)
@@ -1813,7 +1859,7 @@ get_x_offset (PangoLayout     *layout,
       /* First line */
       if (layout->indent > 0)
         {
-          if (layout->alignment == PANGO_ALIGN_LEFT)
+          if (alignment == PANGO_ALIGN_LEFT)
             *x_offset += layout->indent;
           else
             *x_offset -= layout->indent;
@@ -1823,7 +1869,7 @@ get_x_offset (PangoLayout     *layout,
     {
       if (layout->indent < 0)
         {
-          if (layout->alignment == PANGO_ALIGN_LEFT)
+          if (alignment == PANGO_ALIGN_LEFT)
             *x_offset -= layout->indent;
           else
             *x_offset += layout->indent;
@@ -1881,7 +1927,8 @@ pango_layout_get_extents_internal (Pango
   GSList *line_list;
   int y_offset = 0;
   int width;
-  
+  gboolean one_line_is_not_ltr = FALSE;
+
   g_return_if_fail (layout != NULL);
 
   pango_layout_check_lines (layout);
@@ -1891,7 +1938,30 @@ pango_layout_get_extents_internal (Pango
    * x_offsets if we are computing the ink_rect or individual line extents.
    */
   width = layout->width;
-  if (width == -1 && layout->alignment != PANGO_ALIGN_LEFT && (ink_rect || line_extents))
+
+  /* Calculate if one of the lines is not LTR. Either because the alignment
+   * is not LTR or one of the lines has been resolved dir RTL.
+  */
+  one_line_is_not_ltr = FALSE;
+  if (layout->alignment != PANGO_ALIGN_LEFT)
+    one_line_is_not_ltr = TRUE;
+  else
+    {
+      line_list = layout->lines;
+      while (line_list)
+	{
+	  PangoLayoutLine *line = line_list->data;
+	  
+	  if (line->resolved_dir == PANGO_DIRECTION_RTL)
+	    {
+	      one_line_is_not_ltr = TRUE;
+	      break;
+	    }
+	  line_list = line_list->next;
+	}
+    }
+  
+  if (width == -1 && one_line_is_not_ltr && (ink_rect || line_extents))
     {
       PangoRectangle overall_logical;
       
@@ -2281,7 +2351,7 @@ ensure_tab_width (PangoLayout *layout)
 	  pango_attr_list_insert_before (tmp_attrs, attr);
 	}
 	  
-      items = pango_itemize (layout->context, " ", 0, 1, tmp_attrs, NULL);
+      items = pango_itemize (layout->context, " ", pango_context_get_base_dir(layout->context), 0, 1, tmp_attrs, NULL);
 
       pango_attr_iterator_destroy (iter);
       if (layout_attrs != layout->attrs)
@@ -2708,6 +2778,7 @@ process_item (PangoLayout     *layout,
 
 static void
 process_line (PangoLayout    *layout,
+	      PangoDirection base_dir,
 	      ParaBreakState *state)
 {
   PangoLayoutLine *line;
@@ -2719,6 +2790,7 @@ process_line (PangoLayout    *layout,
   
   line = pango_layout_line_new (layout);
   line->start_index = state->line_start_index;
+  line->resolved_dir = base_dir;
 
   if (state->first_line)
     state->remaining_width = (layout->indent >= 0) ? layout->width - layout->indent : layout->width;
@@ -2928,6 +3000,7 @@ pango_layout_check_lines (PangoLayout *l
   PangoAttrList *attrs;
   PangoAttrList *no_shape_attrs;
   PangoAttrIterator *iter;
+  PangoDirection prev_base_dir = PANGO_DIRECTION_NEUTRAL, base_dir = PANGO_DIRECTION_NEUTRAL;
   
   if (layout->lines)
     return;
@@ -2948,6 +3021,16 @@ pango_layout_check_lines (PangoLayout *l
   
   start_offset = 0;
   start = layout->text;
+  
+  /* Find the first strong direction of the text */
+  if (layout->auto_dir)
+    {
+      prev_base_dir = pango_find_base_dir(layout->text, layout->length);
+      if (prev_base_dir == PANGO_DIRECTION_NEUTRAL)
+	prev_base_dir = pango_context_get_base_dir(layout->context);
+    }
+  else
+    base_dir = pango_context_get_base_dir(layout->context);
 
   do
     {
@@ -2970,7 +3053,18 @@ pango_layout_check_lines (PangoLayout *l
         }
 
       g_assert (next_para_index >= delimiter_index);
-      
+
+      if (layout->auto_dir)
+	{
+	  base_dir = pango_find_base_dir(start, delimiter_index);
+	  
+	  /* Propagate the base direction for neutral paragraphs */
+	  if (base_dir == PANGO_DIRECTION_NEUTRAL)
+	    base_dir = prev_base_dir;
+	  else
+	    prev_base_dir = base_dir;
+	}
+
       end = start + delimiter_index;
       
       delim_len = next_para_index - delimiter_index;
@@ -2985,6 +3079,7 @@ pango_layout_check_lines (PangoLayout *l
 
       state.items = pango_itemize (layout->context,
 				   layout->text,
+				   base_dir,
 				   start - layout->text,
 				   end - start,
 				   attrs,
@@ -3004,14 +3099,15 @@ pango_layout_check_lines (PangoLayout *l
 	  state.log_widths = NULL;
 	  
 	  while (state.items)
-            process_line (layout, &state);
+            process_line (layout, base_dir, &state);
 	}
       else
         {
           PangoLayoutLine *empty_line;
 
           empty_line = pango_layout_line_new (layout);
-          empty_line->start_index = start - layout->text; 
+          empty_line->start_index = start - layout->text;
+	  empty_line->resolved_dir = base_dir;
 
           layout->lines = g_slist_prepend (layout->lines,
                                            empty_line);
@@ -3128,11 +3224,10 @@ pango_layout_line_x_to_index (PangoLayou
 
   layout = line->layout;
 
-  base_dir = pango_context_get_base_dir (layout->context);
-
   /* Find the last index in the line
    */
   first_index = line->start_index;
+  base_dir = line->resolved_dir;
 
   if (line->length == 0)
     {
@@ -3341,15 +3436,24 @@ pango_layout_line_get_x_ranges (PangoLay
   int accumulated_width = 0;
   int x_offset;
   int width;
+  PangoAlignment alignment = line->layout->alignment;
+
+  if (line->layout->auto_dir && line->resolved_dir == PANGO_DIRECTION_RTL)
+    {
+      if (alignment == PANGO_ALIGN_LEFT)
+	alignment = PANGO_ALIGN_RIGHT;
+      else if (alignment == PANGO_ALIGN_RIGHT)
+	alignment = PANGO_ALIGN_LEFT;
+    }
   
   g_return_if_fail (line != NULL);
   g_return_if_fail (line->layout != NULL);
   g_return_if_fail (start_index <= end_index);
 
-  base_dir = pango_context_get_base_dir (line->layout->context);
+  base_dir = line->resolved_dir;
 
   width = line->layout->width;
-  if (width == -1 && line->layout->alignment != PANGO_ALIGN_LEFT)
+  if (width == -1 && alignment != PANGO_ALIGN_LEFT)
     {
       pango_layout_get_extents (line->layout, NULL, &logical_rect);
       width = logical_rect.width;
@@ -3710,6 +3814,7 @@ pango_layout_line_new (PangoLayout *layo
   private->line.layout = layout;
   private->line.runs = 0;
   private->line.length = 0;
+  private->line.resolved_dir = pango_context_get_base_dir(layout->context);
 
   /* Note that we leave start_index uninitialized */
   
Index: pango/pango-layout.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-layout.h,v
retrieving revision 1.30
diff -u -p -r1.30 pango-layout.h
--- pango/pango-layout.h	3 Dec 2002 06:21:49 -0000	1.30
+++ pango/pango-layout.h	14 Oct 2003 20:53:45 -0000
@@ -53,6 +53,7 @@ struct _PangoLayoutLine
   PangoLayout *layout;
   gint         start_index;     /* start of line as byte index into layout->text */
   gint         length;		/* length of line in bytes */
+  PangoDirection resolved_dir;  /* Resolved direction of line */
   GSList      *runs;
 };
 
@@ -110,6 +111,9 @@ int            pango_layout_get_spacing 
 void           pango_layout_set_justify          (PangoLayout                *layout,
 						  gboolean                    justify);
 gboolean       pango_layout_get_justify          (PangoLayout                *layout);
+void           pango_layout_set_auto_dir          (PangoLayout                *layout,
+						  gboolean                    auto_dir);
+gboolean       pango_layout_get_auto_dir          (PangoLayout                *layout);
 void           pango_layout_set_alignment        (PangoLayout                *layout,
 						  PangoAlignment              alignment);
 PangoAlignment pango_layout_get_alignment        (PangoLayout                *layout);
Index: pango/pango-types.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-types.h,v
retrieving revision 1.12
diff -u -p -r1.12 pango-types.h
--- pango/pango-types.h	18 Sep 2001 20:05:17 -0000	1.12
+++ pango/pango-types.h	14 Oct 2003 20:53:46 -0000
@@ -65,15 +65,46 @@ struct _PangoRectangle
 #define PANGO_LBEARING(rect) ((rect).x)
 #define PANGO_RBEARING(rect) ((rect).x + (rect).width)
 
-/* Information about a segment of text with a consistent
- * shaping/language engine and bidirectional level
- */
-
+/**
+ * PangoDirection:
+ * 
+ * The #PangoDirection type represents a direction in the
+ * Unicode bidirectional algorithm; not every value in this
+ * enumeration makes sense for every usage of #PangoDirection;
+ * for example, the return value of pango_unichar_direction()
+ * and pango_find_base_direction() cannot be %PANGO_DIRECTION_WEAK_LTR
+ * or %PANGO_DIRECTION_WEAK_RTL, since every character is either
+ * neutral or has a strong direction; on the other hand
+ * %PANGO_DIRECTION_NEUTRAL doesn't make sense to pass
+ * to pango_log2vis_get_embedding_levels().
+ *
+ * The %PANGO_DIRECTION_TTB_LTR, %PANGO_DIRECTION_TTB_RTL
+ * values come from an earlier interpretation of this
+ * enumeration as the writing direction of a block of
+ * text and are no longer used; See the Text module of the
+ * CSS3 spec for how vertical text is planned to be handled
+ * in a future version of Pango. The explanation of why
+ * %PANGO_DIRECTION_TTB_LTR is treated as %PANGO_DIRECTION_RTL
+ * can be found there as well.
+ *
+ * @PANGO_DIRECTION_LTR: A strong left-to-right direction
+ * @PANGO_DIRECTION_RTL: A strong right-to-left direction
+ * @PANGO_DIRECTION_TTB_LTR: Deprecated value; treated the
+ *   same as %PANGO_DIRECTION_RTL.
+ * @PANGO_DIRECTION_TTB_RTL: Deprecated value; treated the
+ *   same as PANGO_DIRECTION_LTR
+ * @PANGO_DIRECTION_WEAK_LTR: A weak left-to-right direction
+ * @PANGO_DIRECTION_WEAK_RTL: A weak right-to-left direction
+ * @PANGO_DIRECTION_NEUTRAL: No direction specified
+ */			  
 typedef enum {
   PANGO_DIRECTION_LTR,
   PANGO_DIRECTION_RTL,
   PANGO_DIRECTION_TTB_LTR,
-  PANGO_DIRECTION_TTB_RTL
+  PANGO_DIRECTION_TTB_RTL,
+  PANGO_DIRECTION_WEAK_LTR,
+  PANGO_DIRECTION_WEAK_RTL,
+  PANGO_DIRECTION_NEUTRAL
 } PangoDirection;
 
 #define PANGO_TYPE_LANGUAGE (pango_language_get_type ())
@@ -84,6 +115,12 @@ PangoLanguage *pango_language_from_strin
 
 gboolean      pango_language_matches  (PangoLanguage *language,
 				       const char *range_list);
+
+gboolean       pango_get_mirror_char        (gunichar     ch,
+					     gunichar    *mirrored_ch);
+PangoDirection pango_unichar_direction      (gunichar     ch);
+PangoDirection pango_find_base_dir          (const gchar *text,
+					     gint         length);
 
 G_END_DECLS
 
Index: pango/pango-utils.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-utils.c,v
retrieving revision 1.41
diff -u -p -r1.41 pango-utils.c
--- pango/pango-utils.c	22 Aug 2003 22:52:07 -0000	1.41
+++ pango/pango-utils.c	14 Oct 2003 20:53:53 -0000
@@ -1232,38 +1232,6 @@ 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)
-{
-  FriBidiCharType fribidi_base_dir;
-  gboolean result;
-
-  fribidi_base_dir = (*pbase_dir == PANGO_DIRECTION_LTR) ? FRIBIDI_TYPE_L : FRIBIDI_TYPE_R;
-
-  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;
-}
-
-
-gboolean 
-pango_get_mirror_char (gunichar        ch,
-		       gunichar       *mirrored_ch)
-{
-  return fribidi_get_mirror_char (ch, mirrored_ch); 
-}
-
-#endif /* HAVE_FRIBIDI */
-
-
 static guint
 alias_hash (struct PangoAlias *alias)
 {
@@ -1494,3 +1462,40 @@ pango_lookup_aliases (const char   *font
       *n_families = 0;
     }
 }
+
+/**
+ * pango_find_base_dir:
+ * @text:   the text to process
+ * @length: length of @text in bytes (may be -1 if @text is nul-terminated)
+ *
+ * Searches a string the first character that has a strong 
+ * direction, according to the Unicode bidirectional algorithm.
+ *
+ * Return value: The direction corresponding to the first strong character.
+ * If no such character is found, then %PANGO_DIRECTION_NEUTRAL is returned.
+ */
+PangoDirection
+pango_find_base_dir (const gchar *text,
+		     gint         length)
+{
+  PangoDirection dir = PANGO_DIRECTION_NEUTRAL;
+  const gchar *p;
+
+  g_return_val_if_fail (text != NULL, PANGO_DIRECTION_NEUTRAL);
+
+  p = text;
+  while ((length < 0 || p < text + length) && *p)
+    {
+      gunichar wc = g_utf8_get_char (p);
+
+      dir = pango_unichar_direction (wc);
+
+      if (dir != PANGO_DIRECTION_NEUTRAL)
+	break;
+
+      p = g_utf8_next_char (p);
+    }
+
+  return dir;
+}
+
Index: pango/pango-utils.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-utils.h,v
retrieving revision 1.15
diff -u -p -r1.15 pango-utils.h
--- pango/pango-utils.h	18 Nov 2001 16:06:01 -0000	1.15
+++ pango/pango-utils.h	14 Oct 2003 20:53:54 -0000
@@ -19,10 +19,15 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#ifndef __PANGO_UTILS_H__
+#define __PANGO_UTILS_H__
+
 #include <stdio.h>
 #include <glib.h>
 #include <pango/pango-font.h>
 
+G_BEGIN_DECLS
+
 char **  pango_split_file_list (const char *str);
 
 char    *pango_trim_string     (const char *str);
@@ -88,8 +93,9 @@ gboolean pango_log2vis_get_embedding_lev
 					     int             len,
 					     PangoDirection *pbase_dir,
 					     guint8         *embedding_level_list);
-gboolean pango_get_mirror_char              (gunichar        ch,
-					     gunichar       *mirrored_ch);
 
 G_CONST_RETURN char *pango_language_get_sample_string (PangoLanguage *language);
 
+G_BEGIN_DECLS
+
+#endif /* __PANGO_UTILS_H__ */
Index: pango/mini-fribidi/fribidi.c
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi.c,v
retrieving revision 1.9
diff -u -p -r1.9 fribidi.c
--- pango/mini-fribidi/fribidi.c	27 May 2003 23:24:28 -0000	1.9
+++ pango/mini-fribidi/fribidi.c	14 Oct 2003 20:54:00 -0000
@@ -1077,7 +1077,23 @@ pango_log2vis_get_embedding_levels (	/* 
 
   DBG ("Entering fribidi_log2vis_get_embedding_levels()\n");
 
-  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_LTR:
+      fribidi_base_dir = FRIBIDI_TYPE_WL;
+      break;
+    case PANGO_DIRECTION_WEAK_RTL:
+      fribidi_base_dir = FRIBIDI_TYPE_WR;
+      break;
+    }
 
   if (len == 0)
     {
@@ -1106,3 +1122,24 @@ pango_log2vis_get_embedding_levels (	/* 
   DBG ("Leaving fribidi_log2vis_get_embedding_levels()\n");
   return TRUE;
 }
+
+/**
+ * pango_unichar_direction:
+ * @ch: character to examine
+ *
+ * Returns the direction of a character, as used in the
+ *  Unicode bidirectional algorithm.
+ */
+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_types.h
===================================================================
RCS file: /cvs/gnome/pango/pango/mini-fribidi/fribidi_types.h,v
retrieving revision 1.4
diff -u -p -r1.4 fribidi_types.h
--- pango/mini-fribidi/fribidi_types.h	25 Feb 2002 21:40:47 -0000	1.4
+++ pango/mini-fribidi/fribidi_types.h	14 Oct 2003 20:54:02 -0000
@@ -154,7 +154,7 @@ FriBidiCharType;
 #define FRIBIDI_DIR_TO_LEVEL(dir) (dir & 1)
 
 /* Is right to left? */
-#define FRIBIDI_IS_RTL(p)      ((P) & FRIBIDI_MASK_RTL)
+#define FRIBIDI_IS_RTL(p)      ((p) & FRIBIDI_MASK_RTL)
 /* Is arabic? */
 #define FRIBIDI_IS_ARABIC(p)   ((p) & FRIBIDI_MASK_ARABIC)
 
