Index: pango-layout.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pango-layout.c,v
retrieving revision 1.133
diff -u -p -r1.133 pango-layout.c
--- pango-layout.c	5 Mar 2005 00:50:29 -0000	1.133
+++ pango-layout.c	5 May 2005 19:12:25 -0000
@@ -93,8 +93,8 @@ struct _PangoLayoutIter
   /* Glyph offset to the current cluster start */
   int cluster_start;
 
-  /* The next cluster_start */
-  int next_cluster_start;
+  /* The cluster_start of next LOGICAL cluster */
+  int cluster_end;
 };
 
 typedef struct _PangoLayoutLinePrivate PangoLayoutLinePrivate;
@@ -4315,6 +4315,39 @@ next_cluster_start (PangoGlyphString *gs
   return gs->num_glyphs;
 }
 
+next_logical_cluster_start_rtl (PangoGlyphString *gs,
+				int               cluster_start)
+{
+  int i;
+
+  i = cluster_start - 1;
+  while (i >=0)
+    {
+      if (gs->glyphs[i].attr.is_cluster_start)
+        return i;
+      
+      --i;
+    }
+
+  return gs->num_glyphs;
+}
+
+static int
+cluster_end (PangoGlyphString *gs,
+	     int               cluster_start,
+	     gboolean          ltr)
+{
+  if (ltr)
+    {
+      return next_cluster_start (gs , cluster_start);
+    }
+  else
+    {
+      return next_logical_cluster_start_rtl (gs , cluster_start);
+    }
+}
+
+static int
 static int
 cluster_end_index (PangoLayoutIter *iter)
 {
@@ -4322,17 +4355,13 @@ cluster_end_index (PangoLayoutIter *iter
   
   gs = iter->run->glyphs;
   
-  if (iter->next_cluster_start == gs->num_glyphs)
+  if (iter->cluster_end == gs->num_glyphs)
     {
-      /* Use the left or right end of the run */
-      if (iter->ltr)
-        return iter->run->item->length;
-      else
-        return 0;
+      return iter->run->item->length;
     }
   else
     {
-      return gs->log_clusters[iter->next_cluster_start];
+      return gs->log_clusters[iter->cluster_end];
     }
 }
 
@@ -4388,19 +4417,16 @@ update_run (PangoLayoutIter *iter,
   else
     iter->ltr = TRUE;
   
-  if (iter->ltr)    
-    iter->cluster_x = iter->run_logical_rect.x;
-  else
-    iter->cluster_x = iter->run_logical_rect.x +
-      iter->run_logical_rect.width;
+  iter->cluster_x = iter->run_logical_rect.x;
   
   iter->cluster_start = 0;
 
   if (iter->run)
-    iter->next_cluster_start = next_cluster_start (iter->run->glyphs,
-                                                   iter->cluster_start);
+    iter->cluster_end = cluster_end (iter->run->glyphs,
+                                     iter->cluster_start,
+                                     iter->ltr);
   else
-    iter->next_cluster_start = 0;
+    iter->cluster_end = 0;
   
   /* Index of the first cluster in the glyph string, relative
    * to the start of the run
@@ -4413,7 +4439,7 @@ update_run (PangoLayoutIter *iter,
   /* Get an overall index, leaving it unchanged for
    * a the NULL run
    */
-  iter->index = run_start_index;
+  iter->index = run_start_index + iter->cluster_index;
 }
 
 static PangoLayoutIter *
@@ -4455,7 +4481,7 @@ pango_layout_iter_copy (PangoLayoutIter 
   new->cluster_x = iter->cluster_x;
   new->cluster_index = iter->cluster_index;
   new->cluster_start = iter->cluster_start;
-  new->next_cluster_start = iter->next_cluster_start;
+  new->cluster_end = iter->cluster_end;
 
   return new;
 }
@@ -4484,6 +4510,7 @@ pango_layout_iter_get_type (void)
 PangoLayoutIter*
 pango_layout_get_iter (PangoLayout *layout)
 {
+  int run_start_index;
   PangoLayoutIter *iter;
   
   g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
@@ -4499,10 +4526,14 @@ pango_layout_get_iter (PangoLayout *layo
   iter->line = iter->line_list_link->data;
   pango_layout_line_ref (iter->line);
 
+  run_start_index = iter->line->start_index;
   iter->run_list_link = iter->line->runs;
 
   if (iter->run_list_link)
-    iter->run = iter->run_list_link->data;
+    {
+      iter->run = iter->run_list_link->data;
+      run_start_index = iter->run->item->offset;
+    }
   else
     iter->run = NULL;
 
@@ -4514,7 +4545,7 @@ pango_layout_get_iter (PangoLayout *layo
 
   iter->line_extents_link = iter->line_extents;
 
-  update_run (iter, 0);
+  update_run (iter, run_start_index);
 
   return iter;
 }
@@ -4627,7 +4658,7 @@ pango_layout_iter_next_char (PangoLayout
   const char *oldp;
   const char *item_end;
   int new_index;
-  int next_cluster_index;
+  int abs_cluster_end_index;
   PangoGlyphString *gs;
   
   if (IS_INVALID (iter))
@@ -4638,30 +4669,20 @@ pango_layout_iter_next_char (PangoLayout
   
   gs = iter->run->glyphs;
 
-  next_cluster_index = iter->run->item->offset + cluster_end_index (iter);
+  abs_cluster_end_index = iter->run->item->offset + cluster_end_index (iter);
   
   oldp = iter->layout->text + iter->index;
 
-  if (iter->ltr)
-    {
-      item_end = iter->layout->text +
-        iter->run->item->offset +
-        iter->run->item->length;
-      p = g_utf8_next_char (oldp);
-    }
-  else
-    {
-      item_end = iter->layout->text + iter->run->item->offset;
-      p = g_utf8_prev_char (oldp);
-    }
-
+  item_end = iter->layout->text +
+    iter->run->item->offset +
+    iter->run->item->length;
+  p = g_utf8_next_char (oldp);
+  
   new_index = iter->index + (p - oldp);
-
-  /* Make sure we don't go past the next cluster index */
-  g_assert ((iter->ltr && (new_index <= next_cluster_index)) ||
-            (!iter->ltr && (new_index >= next_cluster_index)));
+  /* Make sure we don't go past the end-of-cluster index */
+  g_assert (new_index <= abs_cluster_end_index);
   
-  if (new_index == next_cluster_index)
+  if (new_index == abs_cluster_end_index)
     return pango_layout_iter_next_cluster (iter);
   else
     {
@@ -4683,6 +4704,7 @@ gboolean
 pango_layout_iter_next_cluster (PangoLayoutIter *iter)
 {
   PangoGlyphString *gs;
+  int next_start;
   
   if (IS_INVALID (iter))
     return FALSE;
@@ -4692,17 +4714,19 @@ pango_layout_iter_next_cluster (PangoLay
   
   gs = iter->run->glyphs;
   
-  if (iter->next_cluster_start == gs->num_glyphs)
+  next_start = next_cluster_start(gs,iter->cluster_start);
+  if (next_start == gs->num_glyphs)
     return pango_layout_iter_next_run (iter);
   else
     {
-      if (iter->ltr)
-        iter->cluster_x += gs->glyphs[iter->cluster_start].geometry.width;
-      else
-        iter->cluster_x -= gs->glyphs[iter->cluster_start].geometry.width;
-        
-      iter->cluster_start = iter->next_cluster_start;
-      iter->next_cluster_start = next_cluster_start (gs, iter->cluster_start);
+      /* AA: in the hebrew engine, the width is stored in the LAST glyph
+       * I don't know what do the other engines do:
+       * If you want to be safe, you should probably add all the glyph widths.
+       */
+      iter->cluster_x += gs->glyphs[next_start-1].geometry.width;
+      
+      iter->cluster_start = next_start;
+      iter->cluster_end = cluster_end (gs, iter->cluster_start, iter->ltr);
       iter->cluster_index = gs->log_clusters[iter->cluster_start];
       iter->index = iter->run->item->offset + iter->cluster_index;
       return TRUE;
@@ -4721,7 +4745,7 @@ pango_layout_iter_next_cluster (PangoLay
 gboolean
 pango_layout_iter_next_run (PangoLayoutIter *iter)
 {
-  gint prev_run_end;
+  gint next_run_start;
   GSList *next_link;
   
   if (IS_INVALID (iter))
@@ -4730,7 +4754,7 @@ pango_layout_iter_next_run (PangoLayoutI
   if (iter->run == NULL)
     return pango_layout_iter_next_line (iter);
   else
-    prev_run_end = iter->run->item->offset + iter->run->item->length;
+    next_run_start = iter->run->item->offset + iter->run->item->length;
   
   next_link = iter->run_list_link->next;
 
@@ -4746,9 +4770,10 @@ pango_layout_iter_next_run (PangoLayoutI
     {
       iter->run_list_link = next_link;
       iter->run = iter->run_list_link->data;
+      next_run_start = iter->run->item->offset;
     }
   
-  update_run (iter, prev_run_end);
+  update_run (iter, next_run_start);
   
   return TRUE;
 }
@@ -4851,13 +4876,7 @@ pango_layout_iter_get_char_extents (Pang
   end_index = iter->run->item->offset + cluster_end_index (iter);
   start_index = iter->run->item->offset + iter->cluster_index;
 
-  if (end_index < start_index)
-    {
-      int tmp = end_index;
-      end_index = start_index;
-      start_index = tmp;
-    }
-
+  /* Should not have null clusters */
   g_assert (start_index < end_index);
   
   p = iter->layout->text + start_index;
@@ -4883,10 +4902,17 @@ pango_layout_iter_get_char_extents (Pang
   logical_rect->height = cluster_rect.height;
   logical_rect->y = cluster_rect.y;
   
+  /* AA: Q: dividing the cluster - does it have any meaning at all?
+   *  (e.g. - when doing fixed font - do they still overlap or not?)
+   *  If yes: then visual order should still be reverse inside cluster
+   *      --> all my changes should be reviewed
+   *  If no: width & x should be either the same or go visually: in visual order x should
+   *      never decrease.
+   */
   if (iter->ltr)
     logical_rect->x = cluster_rect.x + char_width * cluster_offset;
   else
-    logical_rect->x = cluster_rect.x + cluster_rect.width - char_width * cluster_offset;
+    logical_rect->x = cluster_rect.x + cluster_rect.width - char_width * (cluster_offset + 1);
 }
 
 /**
@@ -4918,7 +4944,7 @@ pango_layout_iter_get_cluster_extents (P
   
   pango_glyph_string_extents_range (iter->run->glyphs,
                                     iter->cluster_start,
-                                    iter->next_cluster_start,
+                                    next_cluster_start(iter->run->glyphs,iter->cluster_start),/*AA:FIXME*/
                                     iter->run->item->analysis.font,
                                     ink_rect,
                                     logical_rect);
