summaryrefslogtreecommitdiff
path: root/gtk/gtktextlayout.c
diff options
context:
space:
mode:
authorItay Perl <itay.perl@gmail.com>2009-05-03 23:26:11 -0400
committerMatthias Clasen <mclasen@redhat.com>2009-05-03 23:26:11 -0400
commit850965101f54667f9448193e333626fab8b4005b (patch)
tree5fbce1d7a786e25f2eea763099c7a58b9f5f72c1 /gtk/gtktextlayout.c
parent7f6a534d0fe10854c862fcecf81ddbb4b64afe55 (diff)
downloadgtk+-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.c50
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