diff options
author | Itay Perl <itay.perl@gmail.com> | 2009-05-03 23:26:11 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2009-05-03 23:26:11 -0400 |
commit | 850965101f54667f9448193e333626fab8b4005b (patch) | |
tree | 5fbce1d7a786e25f2eea763099c7a58b9f5f72c1 /gtk/gtktextlayout.c | |
parent | 7f6a534d0fe10854c862fcecf81ddbb4b64afe55 (diff) | |
download | gtk+-850965101f54667f9448193e333626fab8b4005b.tar.gz |
Fix handling of child widgets in the presence of bidi text
GtkTextLayout incorrectly assumed that pango iterates in logical
order. Fixes bug 580814.
Diffstat (limited to 'gtk/gtktextlayout.c')
-rw-r--r-- | gtk/gtktextlayout.c | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c index 156503a506..319b8ce645 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 |