diff -u -r gtk+-2.2.1/gtk/gtktextbtree.c gtk+-2.2.1.dov/gtk/gtktextbtree.c
--- gtk+-2.2.1/gtk/gtktextbtree.c	2002-10-10 17:45:40.000000000 -0400
+++ gtk+-2.2.1.dov/gtk/gtktextbtree.c	2003-03-12 00:09:45.000000000 -0500
@@ -554,6 +554,178 @@
  * Indexable segment mutation
  */
 
+/*
+ *  The following function is responsible for resolving the bidi direction
+ *  for the lines between start and end. But it also calculates any
+ *  dependent bidi direction for surrounding lines that change as a result
+ *  of the bidi direction decisions within the range. The function is
+ *  trying to do as little propagation as is needed.
+ */
+static void
+_gtk_text_btree_resolve_bidi(GtkTextIter *start,
+			     GtkTextIter *end)
+{
+  GtkTextBTree *tree = _gtk_text_iter_get_btree (start);
+  GtkTextLine *start_line, *end_line, *line;
+  PangoDirection last_strong, above_strong, above_propagated;
+
+  /* Resolve the strong bidi direction for all lines between
+     start and end.
+  */
+  start_line = _gtk_text_iter_get_text_line(start);
+  end_line = _gtk_text_iter_get_text_line (end);
+  if (end_line)
+    end_line = end_line->next;
+  
+  line = start_line;
+  last_strong = PANGO_DIRECTION_NEUTRAL;
+  while(line && line != end_line)
+    {
+      PangoDirection p_dir;
+      
+      /* Loop through the segments and search for a strong character
+       */
+      GtkTextLineSegment *seg = line->segments;
+      line->dir_strong = PANGO_DIRECTION_NEUTRAL;
+      
+      while(seg)
+	{
+	  if (seg->byte_count > 0)
+	    {
+	      p_dir = pango_find_base_dir_utf8(seg->body.chars,
+					       seg->byte_count);
+	      if (p_dir != PANGO_DIRECTION_NEUTRAL)
+		{
+		  line->dir_strong = p_dir;
+
+		  /* Remember the first resolved non-neutral paragraph */
+		  if (last_strong == PANGO_DIRECTION_NEUTRAL)
+		    last_strong = PANGO_DIRECTION_NEUTRAL;
+		  break;
+		}
+	    }
+	  seg = seg->next;
+	}
+
+      line = _gtk_text_line_next(line);
+    }
+
+  /* Search backwards for a strong paragraph above start. The direction
+     of it has two uses:
+
+     - This will be the direction for start if it is neutral.
+
+     - If no strong direction is found before start, then we need
+       to propagate the strong direction backwards.
+  */
+  {
+    GtkTextLine *prev = _gtk_text_line_previous(start_line);
+
+    above_strong = PANGO_DIRECTION_NEUTRAL;
+    if (prev)
+      above_propagated = prev->dir_propagated;
+    else
+      above_propagated = PANGO_DIRECTION_NEUTRAL;
+    while(prev)
+      {
+	if (prev->dir_strong != PANGO_DIRECTION_NEUTRAL)
+	  {
+	    above_strong = prev->dir_strong;
+	    break;
+	  }
+	prev = _gtk_text_line_previous(prev);
+      }
+  }
+
+  /* If we haven't found a strong paragraph yet, then use the direction 
+     for the previous strong paragraph */
+  if (last_strong == PANGO_DIRECTION_NEUTRAL)
+    last_strong = above_strong;
+
+  /* If we still haven't found a paragraph continue searching through
+     the whole text for one! */
+  if (last_strong == PANGO_DIRECTION_NEUTRAL)
+    {
+      GtkTextLine *next = end_line;
+      
+      while(next)
+	{
+	  if (next->dir_strong != PANGO_DIRECTION_NEUTRAL)
+	    {
+	      last_strong = next->dir_strong;
+	      break;
+	    }
+	  next = _gtk_text_line_next(next);
+	}
+    }
+  
+  /* Loop again and propagate the direction of each paragraph forward
+     to all neutral lines. */
+  line = start_line;
+
+  while(line != end_line)
+    {
+      if (line->dir_strong != PANGO_DIRECTION_NEUTRAL)
+	last_strong = line->dir_strong;
+
+      line->dir_propagated = last_strong;
+
+      line = _gtk_text_line_next(line);
+    }
+
+  /* Continue propagating as long as the following paragraph is neutral.
+     Then invalidate that region as it is beyond end. */
+  line = end_line;
+  if (line &&
+      line->dir_strong == PANGO_DIRECTION_NEUTRAL
+      && line->dir_propagated != last_strong
+      )
+    {
+      GtkTextIter end_propagate;
+      
+      while(line && line->dir_strong == PANGO_DIRECTION_NEUTRAL)
+	{
+	  GtkTextLine *prev = line;
+	  line->dir_propagated = last_strong;
+
+	  line = _gtk_text_line_next(line);
+	  if (!line)
+	    {
+	      line = prev;
+	      break;
+	    }
+	}
+
+      /* The last character to invalidate is the last character of the
+	 line above a line with a strong direction, or the end of the
+	 text. Therefore we need the iter_backward_char. */
+      _gtk_text_btree_get_iter_at_line (tree, &end_propagate, line, 0);
+      gtk_text_iter_backward_char(&end_propagate);
+      _gtk_text_btree_invalidate_region(tree, end, &end_propagate);
+    }
+
+  /* Check if we need to propagate backwards. If so, set all resolved
+     directions from the beggining of the text, and then invalidate
+     that region. */
+  if (start_line
+      && above_strong == PANGO_DIRECTION_NEUTRAL
+      && above_propagated != start_line->dir_propagated
+      )
+    {
+      GtkTextLine *line;
+      GtkTextIter start_text;
+
+      _gtk_text_btree_get_iter_at_line_char(tree, &start_text, 0, 0);
+      line = _gtk_text_iter_get_text_line(&start_text);
+      while(line && line != start_line)
+	{
+	  line->dir_propagated = start_line->dir_propagated;
+	  line = _gtk_text_line_next(line);
+	}
+      _gtk_text_btree_invalidate_region(tree, &start_text, start);
+    }
+}
+
 void
 _gtk_text_btree_delete (GtkTextIter *start,
                         GtkTextIter *end)
@@ -884,6 +1056,8 @@
   /* Re-initialize our iterators */
   _gtk_text_btree_get_iter_at_line (tree, start, start_line, start_byte_offset);
   *end = *start;
+  
+  _gtk_text_btree_resolve_bidi(start, end);
 }
 
 void
@@ -1031,7 +1205,6 @@
     GtkTextIter start;
     GtkTextIter end;
 
-
     _gtk_text_btree_get_iter_at_line (tree,
                                       &start,
                                       start_line,
@@ -1050,6 +1223,8 @@
 
     /* Convenience for the user */
     *iter = end;
+    
+    _gtk_text_btree_resolve_bidi(&start, &end);
   }
 }
 
@@ -3352,6 +3527,7 @@
   line_data->width = 0;
   line_data->height = 0;
   line_data->valid = FALSE;
+  line_data->dir_resolved = PANGO_DIRECTION_NEUTRAL;
 
   return line_data;
 }
@@ -4486,6 +4662,8 @@
   GtkTextLine *line;
 
   line = g_new0(GtkTextLine, 1);
+  line->dir_strong = PANGO_DIRECTION_NEUTRAL;
+  line->dir_propagated = PANGO_DIRECTION_NEUTRAL;
 
   return line;
 }
diff -u -r gtk+-2.2.1/gtk/gtktextbtree.h gtk+-2.2.1.dov/gtk/gtktextbtree.h
--- gtk+-2.2.1/gtk/gtktextbtree.h	2002-09-23 15:20:48.000000000 -0400
+++ gtk+-2.2.1.dov/gtk/gtktextbtree.h	2003-03-11 20:25:26.000000000 -0500
@@ -194,6 +194,8 @@
   gint height;
   signed int width : 24;
   guint valid : 8;		/* Actually a boolean */
+  PangoAlignment dir_resolved;  /* If the paragraph is weak, this is the
+				   resolved direction. */
 };
 
 /*
@@ -211,7 +213,9 @@
                                  * means end of list. */
   GtkTextLineSegment *segments; /* First in ordered list of segments
                                  * that make up the line. */
-  GtkTextLineData *views;      /* data stored here by views */
+  GtkTextLineData *views;       /* data stored here by views */
+  PangoDirection dir_strong;    /* BiDi algo dir of line */
+  PangoDirection dir_propagated;    /* BiDi algo dir of line */
 };
 
 
diff -u -r gtk+-2.2.1/gtk/gtktextlayout.c gtk+-2.2.1.dov/gtk/gtktextlayout.c
--- gtk+-2.2.1/gtk/gtktextlayout.c	2003-01-15 17:01:21.000000000 -0500
+++ gtk+-2.2.1.dov/gtk/gtktextlayout.c	2003-03-12 00:21:40.000000000 -0500
@@ -81,7 +81,7 @@
 #include "gtktextlayout.h"
 #include "gtktextbtree.h"
 #include "gtktextiterprivate.h"
-
+#include <fribidi/fribidi.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -1101,6 +1101,7 @@
 
 static void
 set_para_values (GtkTextLayout      *layout,
+		 PangoDirection base_dir,
                  GtkTextAttributes *style,
                  GtkTextLineDisplay *display)
 {
@@ -1109,7 +1110,7 @@
 
   display->direction = style->direction;
 
-  if (display->direction == GTK_TEXT_DIR_LTR)
+  if (base_dir == PANGO_DIRECTION_LTR)
     display->layout = pango_layout_new (layout->ltr_context);
   else
     display->layout = pango_layout_new (layout->rtl_context);
@@ -1117,10 +1118,10 @@
   switch (style->justification)
     {
     case GTK_JUSTIFY_LEFT:
-      pango_align = (style->direction == GTK_TEXT_DIR_LTR) ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT;
+      pango_align = (base_dir == PANGO_DIRECTION_LTR) ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT;
       break;
     case GTK_JUSTIFY_RIGHT:
-      pango_align = (style->direction == GTK_TEXT_DIR_LTR) ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
+      pango_align = (base_dir == PANGO_DIRECTION_LTR) ? PANGO_ALIGN_RIGHT : PANGO_ALIGN_LEFT;
       break;
     case GTK_JUSTIFY_CENTER:
       pango_align = PANGO_ALIGN_CENTER;
@@ -1426,7 +1427,8 @@
 add_cursor (GtkTextLayout      *layout,
             GtkTextLineDisplay *display,
             GtkTextLineSegment *seg,
-            gint                start)
+            gint                start
+	    )
 {
   PangoRectangle strong_pos, weak_pos;
   GtkTextCursorDisplay *cursor = NULL; /* Quiet GCC */
@@ -1657,6 +1659,7 @@
                                   GtkTextLine   *line,
                                   gboolean       size_only)
 {
+  GtkTextLine *cursor_line = NULL;
   GtkTextLineDisplay *display;
   GtkTextLineSegment *seg;
   GtkTextIter iter;
@@ -1670,6 +1673,7 @@
   GSList *cursor_segs = NULL;
   GSList *tmp_list1, *tmp_list2;
   gboolean saw_widget = FALSE;
+  PangoDirection base_dir;
   
   g_return_val_if_fail (line != NULL, NULL);
 
@@ -1702,6 +1706,26 @@
   if (totally_invisible_line (layout, line, &iter))
     return display;
 
+  /* Find the bidi base direction */
+  base_dir = line->dir_propagated;
+
+  if (layout->buffer)
+    {
+      GtkTextIter cursor_iter;
+      gtk_text_buffer_get_iter_at_mark (layout->buffer, &cursor_iter,
+					gtk_text_buffer_get_mark (layout->buffer, "insert"));
+      
+      cursor_line = _gtk_text_iter_get_text_line (&cursor_iter);
+    }
+  
+  if (line == cursor_line &&
+      line->dir_strong == PANGO_DIRECTION_NEUTRAL)
+    {
+      GtkTextDirection dir = layout->keyboard_direction;
+
+      base_dir = (dir == GTK_TEXT_DIR_LTR) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL;
+    }
+  
   /* Allocate space for flat text for buffer
    */
   text_allocated = _gtk_text_line_byte_count (line);
@@ -1732,7 +1756,7 @@
            */
           if (!para_values_set)
             {
-              set_para_values (layout, style, display);
+              set_para_values (layout, base_dir, style, display);
               para_values_set = TRUE;
             }
 
@@ -1901,7 +1925,7 @@
   if (!para_values_set)
     {
       style = get_style (layout, &iter);
-      set_para_values (layout, style, display);
+      set_para_values (layout, base_dir, style, display);
       release_style (layout, style);
     }
   
@@ -1931,6 +1955,29 @@
       }
   }
   
+  /* Search text for the first strong character and let that be
+     the director of the paragraph */
+  {
+    PangoDirection p_dir = pango_find_base_dir_utf8(text,
+						    layout_byte_offset);
+    GtkTextDirection dir = layout->keyboard_direction;
+
+    switch (p_dir)
+      {
+      case PANGO_DIRECTION_NEUTRAL:
+	/* If the paragraph is neutral then we should either use the
+	   direction of the previous paragraph or the the direction
+	   of the keyboard */
+	dir = layout->keyboard_direction;
+	break;
+      case PANGO_DIRECTION_RTL:
+	dir = GTK_TEXT_DIR_RTL;
+	break;
+      default:
+	dir = GTK_TEXT_DIR_LTR;
+      }
+  }
+
   pango_layout_set_text (display->layout, text, layout_byte_offset);
   pango_layout_set_attributes (display->layout, attrs);
 
diff -u -r gtk+-2.2.1/gtk/gtktextlayout.h gtk+-2.2.1.dov/gtk/gtktextlayout.h
--- gtk+-2.2.1/gtk/gtktextlayout.h	2002-11-08 14:41:50.000000000 -0500
+++ gtk+-2.2.1.dov/gtk/gtktextlayout.h	2003-02-26 00:05:10.000000000 -0500
@@ -165,6 +165,11 @@
    */
   guint cursor_direction : 2;
 
+  /* The keyboard direction is used to default the alignment when
+     there are no strong characters.
+  */
+  guint keyboard_direction : 2;
+  
   /* The preedit string and attributes, if any */
 
   gchar *preedit_string;
diff -u -r gtk+-2.2.1/gtk/gtktextview.c gtk+-2.2.1.dov/gtk/gtktextview.c
--- gtk+-2.2.1/gtk/gtktextview.c	2003-01-27 16:13:18.000000000 -0500
+++ gtk+-2.2.1.dov/gtk/gtktextview.c	2003-02-26 00:07:48.000000000 -0500
@@ -5322,19 +5322,25 @@
       gboolean split_cursor;
       GtkTextDirection new_dir;
       GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (text_view));
+      GdkKeymap *keymap;
   
       g_object_get (G_OBJECT (settings),
 		    "gtk-split-cursor", &split_cursor,
 		    NULL);
+      
+      keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (text_view)));
+      
+      text_view->layout->keyboard_direction
+	  = (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ?
+	    GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
+
       if (split_cursor)
 	{
 	  new_dir = GTK_TEXT_DIR_NONE;
 	}
       else
 	{
-	  GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (text_view)));
-	  new_dir = (gdk_keymap_get_direction (keymap) == PANGO_DIRECTION_LTR) ?
-	    GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL;
+	  new_dir = text_view->layout->keyboard_direction;
 	}
       
       if (text_view->layout->cursor_direction != new_dir)
