[gtk+] Fix handling of child widgets in the presence of bidi text



commit 850965101f54667f9448193e333626fab8b4005b
Author: Itay Perl <itay perl gmail com>
Date:   Sun May 3 23:26:11 2009 -0400

    Fix handling of child widgets in the presence of bidi text
    
    GtkTextLayout incorrectly assumed that pango iterates in logical
    order. Fixes bug 580814.
---
 gtk/gtktextlayout.c |   50 +++++++++++++++++++++++++++++++++++---------------
 1 files changed, 35 insertions(+), 15 deletions(-)

diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 156503a..319b8ce 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -147,6 +147,16 @@ static void gtk_text_layout_buffer_delete_range (GtkTextBuffer     *textbuffer,
 
 static void gtk_text_layout_update_cursor_line (GtkTextLayout *layout);
 
+static void line_display_index_to_iter (GtkTextLayout      *layout,
+	                                GtkTextLineDisplay *display,
+			                GtkTextIter        *iter,
+                                        gint                index,
+                                        gint                trailing);
+
+static gint line_display_iter_to_index (GtkTextLayout      *layout,
+                                        GtkTextLineDisplay *display,
+                                        const GtkTextIter  *iter);
+
 enum {
   INVALIDATED,
   CHANGED,
@@ -1800,49 +1810,59 @@ static void
 allocate_child_widgets (GtkTextLayout      *text_layout,
                         GtkTextLineDisplay *display)
 {
-  GSList *shaped = display->shaped_objects;
   PangoLayout *layout = display->layout;
-  PangoLayoutIter *iter;
+  PangoLayoutIter *run_iter;
   
-  iter = pango_layout_get_iter (layout);
+  run_iter = pango_layout_get_iter (layout);
   
   do
     {
-      PangoLayoutRun *run = pango_layout_iter_get_run_readonly (iter);
-
+      PangoLayoutRun *run = pango_layout_iter_get_run_readonly (run_iter);
+      
       if (run && is_shape (run))
         {
-          GObject *shaped_object = shaped->data;
-          shaped = shaped->next;
-
-          /* shaped_object is NULL for child anchors with no
-           * widgets stored at them
+          gint byte_index;
+          GtkTextIter text_iter;
+          GtkTextChildAnchor *anchor = 0;
+          GList *widgets = 0;
+          
+          /* The pango iterator iterates in visual order. 
+           * We use the byte index to find the child widget.
            */
-          if (GTK_IS_WIDGET (shaped_object))
+          
+          byte_index = pango_layout_iter_get_index (run_iter);
+          line_display_index_to_iter (text_layout, display, &text_iter, byte_index, 0);
+          anchor = gtk_text_iter_get_child_anchor (&text_iter);
+          widgets = gtk_text_child_anchor_get_widgets (anchor);
+          
+          if (widgets)
             {
               PangoRectangle extents;
+              GtkWidget *child = widgets->data;
 
               /* We emit "allocate_child" with the x,y of
                * the widget with respect to the top of the line
                * and the left side of the buffer
                */
               
-              pango_layout_iter_get_run_extents (iter,
+              pango_layout_iter_get_run_extents (run_iter,
                                                  NULL,
                                                  &extents);
               
               g_signal_emit (text_layout,
                              signals[ALLOCATE_CHILD],
                              0,
-                             shaped_object,
+                             child,
                              PANGO_PIXELS (extents.x) + display->x_offset,
                              PANGO_PIXELS (extents.y) + display->top_margin);
+              
+              g_list_free (widgets);
             }
         }
     }
-  while (pango_layout_iter_next_run (iter));
+  while (pango_layout_iter_next_run (run_iter));
   
-  pango_layout_iter_free (iter);
+  pango_layout_iter_free (run_iter);
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]