]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktextlayout.c
filechooserbutton: New test for opening the Other item in the combo box and then...
[~andy/gtk] / gtk / gtktextlayout.c
index 0b1b708f8c23090b0b579b356c965d5e445c2d58..73be6b417c94260929d831b5883ece633c28fae4 100644 (file)
@@ -23,8 +23,7 @@
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.Free
  *
  * Original Tk license:
  *
  */
 
 #define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API
-#include <config.h>
+#include "config.h"
 #include "gtkmarshalers.h"
 #include "gtktextlayout.h"
 #include "gtktextbtree.h"
 #include "gtktextiterprivate.h"
 #include "gtktextutil.h"
 #include "gtkintl.h"
-#include "gtkalias.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -147,6 +145,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,
@@ -161,19 +169,64 @@ enum {
 
 #define PIXEL_BOUND(d) (((d) + PANGO_SCALE - 1) / PANGO_SCALE)
 
-static void gtk_text_layout_finalize (GObject *object);
-
 static guint signals[LAST_SIGNAL] = { 0 };
 
 PangoAttrType gtk_text_attr_appearance_type = 0;
 
 G_DEFINE_TYPE (GtkTextLayout, gtk_text_layout, G_TYPE_OBJECT)
 
+static void
+gtk_text_layout_dispose (GObject *object)
+{
+  GtkTextLayout *layout;
+
+  layout = GTK_TEXT_LAYOUT (object);
+
+  gtk_text_layout_set_buffer (layout, NULL);
+
+  if (layout->default_style != NULL)
+    {
+      gtk_text_attributes_unref (layout->default_style);
+      layout->default_style = NULL;
+    }
+
+  g_clear_object (&layout->ltr_context);
+  g_clear_object (&layout->rtl_context);
+
+  if (layout->one_display_cache)
+    {
+      GtkTextLineDisplay *tmp_display = layout->one_display_cache;
+      layout->one_display_cache = NULL;
+      gtk_text_layout_free_line_display (layout, tmp_display);
+    }
+
+  if (layout->preedit_attrs != NULL)
+    {
+      pango_attr_list_unref (layout->preedit_attrs);
+      layout->preedit_attrs = NULL;
+    }
+
+  G_OBJECT_CLASS (gtk_text_layout_parent_class)->dispose (object);
+}
+
+static void
+gtk_text_layout_finalize (GObject *object)
+{
+  GtkTextLayout *layout;
+
+  layout = GTK_TEXT_LAYOUT (object);
+
+  g_free (layout->preedit_string);
+
+  G_OBJECT_CLASS (gtk_text_layout_parent_class)->finalize (object);
+}
+
 static void
 gtk_text_layout_class_init (GtkTextLayoutClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
+  object_class->dispose = gtk_text_layout_dispose;
   object_class->finalize = gtk_text_layout_finalize;
 
   klass->wrap = gtk_text_layout_real_wrap;
@@ -203,9 +256,11 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT,
                   G_TYPE_INT);
+  g_signal_set_va_marshaller (signals[CHANGED], G_TYPE_FROM_CLASS (klass),
+                              _gtk_marshal_VOID__INT_INT_INTv);
 
   signals[ALLOCATE_CHILD] =
-    g_signal_new (I_("allocate_child"),
+    g_signal_new (I_("allocate-child"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GtkTextLayoutClass, allocate_child),
@@ -213,7 +268,7 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
                   _gtk_marshal_VOID__OBJECT_INT_INT,
                   G_TYPE_NONE,
                   3,
-                  GTK_TYPE_OBJECT,
+                  G_TYPE_OBJECT,
                   G_TYPE_INT,
                   G_TYPE_INT);
   
@@ -242,53 +297,10 @@ free_style_cache (GtkTextLayout *text_layout)
     }
 }
 
-static void
-gtk_text_layout_finalize (GObject *object)
-{
-  GtkTextLayout *layout;
-
-  layout = GTK_TEXT_LAYOUT (object);
-
-  gtk_text_layout_set_buffer (layout, NULL);
-
-  if (layout->default_style)
-    gtk_text_attributes_unref (layout->default_style);
-  layout->default_style = NULL;
-
-  if (layout->ltr_context)
-    {
-      g_object_unref (layout->ltr_context);
-      layout->ltr_context = NULL;
-    }
-  if (layout->rtl_context)
-    {
-      g_object_unref (layout->rtl_context);
-      layout->rtl_context = NULL;
-    }
-  
-  if (layout->one_display_cache) 
-    {
-      GtkTextLineDisplay *tmp_display = layout->one_display_cache;
-      layout->one_display_cache = NULL;
-      gtk_text_layout_free_line_display (layout, tmp_display);
-    }
-
-  if (layout->preedit_string)
-    {
-      g_free (layout->preedit_string);
-      layout->preedit_string = NULL;
-    }
-
-  if (layout->preedit_attrs)
-    {
-      pango_attr_list_unref (layout->preedit_attrs);
-      layout->preedit_attrs = NULL;
-    }
-
-
-  (* G_OBJECT_CLASS (gtk_text_layout_parent_class)->finalize) (object);
-}
-
+/**
+ * gtk_text_layout_set_buffer:
+ * @buffer: (allow-none):
+ */
 void
 gtk_text_layout_set_buffer (GtkTextLayout *layout,
                             GtkTextBuffer *buffer)
@@ -329,11 +341,11 @@ gtk_text_layout_set_buffer (GtkTextLayout *layout,
       _gtk_text_btree_add_view (_gtk_text_buffer_get_btree (buffer), layout);
 
       /* Bind to all signals that move the insert mark. */
-      g_signal_connect_after (layout->buffer, "mark_set",
+      g_signal_connect_after (layout->buffer, "mark-set",
                               G_CALLBACK (gtk_text_layout_mark_set_handler), layout);
-      g_signal_connect_after (layout->buffer, "insert_text",
+      g_signal_connect_after (layout->buffer, "insert-text",
                               G_CALLBACK (gtk_text_layout_buffer_insert_text), layout);
-      g_signal_connect_after (layout->buffer, "delete_range",
+      g_signal_connect_after (layout->buffer, "delete-range",
                               G_CALLBACK (gtk_text_layout_buffer_delete_range), layout);
 
       gtk_text_layout_update_cursor_line (layout);
@@ -404,7 +416,7 @@ gtk_text_layout_set_contexts (GtkTextLayout *layout,
  * @overwrite: overwrite mode
  *
  * Sets overwrite mode
- **/
+ */
 void
 gtk_text_layout_set_overwrite_mode (GtkTextLayout *layout,
                                    gboolean       overwrite)
@@ -429,7 +441,7 @@ gtk_text_layout_set_overwrite_mode (GtkTextLayout *layout,
  * point at which new text is inserted depends on whether the new
  * text is right-to-left or left-to-right, so it may be desired to
  * make the drawn position of the cursor depend on the keyboard state.
- **/
+ */
 void
 gtk_text_layout_set_cursor_direction (GtkTextLayout   *layout,
                                      GtkTextDirection direction)
@@ -448,7 +460,7 @@ gtk_text_layout_set_cursor_direction (GtkTextLayout   *layout,
  * Sets the keyboard direction; this is used as for the bidirectional
  * base direction for the line with the cursor if the line contains
  * only neutral characters.
- **/
+ */
 void
 gtk_text_layout_set_keyboard_direction (GtkTextLayout   *layout,
                                        GtkTextDirection keyboard_dir)
@@ -468,7 +480,7 @@ gtk_text_layout_set_keyboard_direction (GtkTextLayout   *layout,
  * gtk_text_layout_set_buffer().
  *
  * Return value: the text buffer used by the layout.
- **/
+ */
 GtkTextBuffer *
 gtk_text_layout_get_buffer (GtkTextLayout *layout)
 {
@@ -502,7 +514,7 @@ gtk_text_layout_set_screen_width (GtkTextLayout *layout, gint width)
  * Sets whether the insertion cursor should be shown. Generally,
  * widgets using #GtkTextLayout will hide the cursor when the
  * widget does not have the input focus.
- **/
+ */
 void
 gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
                                     gboolean       cursor_visible)
@@ -519,7 +531,7 @@ gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
       /* Now queue a redraw on the paragraph containing the cursor
        */
       gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter,
-                                        gtk_text_buffer_get_mark (layout->buffer, "insert"));
+                                        gtk_text_buffer_get_insert (layout->buffer));
 
       gtk_text_layout_get_line_yrange (layout, &iter, &y, &height);
       gtk_text_layout_emit_changed (layout, y, height, height);
@@ -535,8 +547,8 @@ gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
  * Returns whether the insertion cursor will be shown.
  *
  * Return value: if %FALSE, the insertion cursor will not be
-    shown, even if the text is editable.
- **/
*     shown, even if the text is editable.
+ */
 gboolean
 gtk_text_layout_get_cursor_visible (GtkTextLayout *layout)
 {
@@ -553,7 +565,7 @@ gtk_text_layout_get_cursor_visible (GtkTextLayout *layout)
  * Set the preedit string and attributes. The preedit string is a
  * string showing text that is currently being edited and not
  * yet committed into the buffer.
- **/
+ */
 void
 gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
                                    const gchar   *preedit_string,
@@ -665,8 +677,7 @@ gtk_text_layout_free_line_data (GtkTextLayout     *layout,
                                 GtkTextLine       *line,
                                 GtkTextLineData   *line_data)
 {
-  (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->free_line_data)
-    (layout, line, line_data);
+  GTK_TEXT_LAYOUT_GET_CLASS (layout)->free_line_data (layout, line, line_data);
 }
 
 void
@@ -674,8 +685,7 @@ gtk_text_layout_invalidate (GtkTextLayout *layout,
                             const GtkTextIter *start_index,
                             const GtkTextIter *end_index)
 {
-  (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate)
-    (layout, start_index, end_index);
+  GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate (layout, start_index, end_index);
 }
 
 void
@@ -683,8 +693,7 @@ gtk_text_layout_invalidate_cursors (GtkTextLayout *layout,
                                    const GtkTextIter *start_index,
                                    const GtkTextIter *end_index)
 {
-  (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate_cursors)
-    (layout, start_index, end_index);
+  GTK_TEXT_LAYOUT_GET_CLASS (layout)->invalidate_cursors (layout, start_index, end_index);
 }
 
 GtkTextLineData*
@@ -693,9 +702,15 @@ gtk_text_layout_wrap (GtkTextLayout *layout,
                       /* may be NULL */
                       GtkTextLineData *line_data)
 {
-  return (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap) (layout, line, line_data);
+  return GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap (layout, line, line_data);
 }
 
+
+/**
+ * gtk_text_layout_get_lines:
+ *
+ * Return value: (element-type GtkTextLine) (transfer container):
+ */
 GSList*
 gtk_text_layout_get_lines (GtkTextLayout *layout,
                            /* [top_y, bottom_y) */
@@ -811,8 +826,8 @@ gtk_text_layout_invalidate_cache (GtkTextLayout *layout,
 
       if (cursors_only)
        {
-         g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
-         g_slist_free (display->cursors);
+          if (display->cursors)
+            g_array_free (display->cursors, TRUE);
          display->cursors = NULL;
          display->cursors_invalid = TRUE;
          display->has_block_cursor = FALSE;
@@ -859,8 +874,8 @@ gtk_text_layout_update_cursor_line(GtkTextLayout *layout)
   GtkTextIter iter;
 
   gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter,
-                                    gtk_text_buffer_get_mark (layout->buffer, "insert"));
-  
+                                    gtk_text_buffer_get_insert (layout->buffer));
+
   priv->cursor_line = _gtk_text_iter_get_text_line (&iter);
 }
 
@@ -921,8 +936,8 @@ gtk_text_layout_real_invalidate_cursors (GtkTextLayout     *layout,
       GtkTextIter line_start, line_end;
       GtkTextLine *line = layout->one_display_cache->line;
 
-      _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                        &line_start, line, 0);
+      gtk_text_layout_get_iter_at_line (layout, &line_start, line, 0);
+
       line_end = line_start;
       if (!gtk_text_iter_ends_line (&line_end))
        gtk_text_iter_forward_to_line_end (&line_end);
@@ -954,8 +969,6 @@ gtk_text_layout_real_free_line_data (GtkTextLayout     *layout,
   g_free (line_data);
 }
 
-
-
 /**
  * gtk_text_layout_is_valid:
  * @layout: a #GtkTextLayout
@@ -963,7 +976,7 @@ gtk_text_layout_real_free_line_data (GtkTextLayout     *layout,
  * Check if there are any invalid regions in a #GtkTextLayout's buffer
  *
  * Return value: %TRUE if any invalid regions were found
- **/
+ */
 gboolean
 gtk_text_layout_is_valid (GtkTextLayout *layout)
 {
@@ -995,7 +1008,7 @@ update_layout_size (GtkTextLayout *layout)
  *
  * Ensure that a region of a #GtkTextLayout is valid. The ::changed
  * signal will be emitted if any lines are validated.
- **/
+ */
 void
 gtk_text_layout_validate_yrange (GtkTextLayout *layout,
                                  GtkTextIter   *anchor,
@@ -1243,9 +1256,7 @@ totally_invisible_line (GtkTextLayout *layout,
    * invisible/noninvisible toggle state; this function can use the whole btree 
    * to get it right.
    */
-  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                   iter, line, 0);
-  
+  gtk_text_layout_get_iter_at_line (layout, iter, line, 0);
   if (!_gtk_text_btree_char_is_invisible (iter))
     return FALSE;
 
@@ -1269,8 +1280,8 @@ totally_invisible_line (GtkTextLayout *layout,
           invalidate_cached_style (layout);
 
           /* Bail out if an elision-unsetting tag begins */
-          if (seg->body.toggle.info->tag->invisible_set &&
-              !seg->body.toggle.info->tag->values->invisible)
+          if (seg->body.toggle.info->tag->priv->invisible_set &&
+              !seg->body.toggle.info->tag->priv->values->invisible)
             break;
         }
       else if (seg->type == &gtk_text_toggle_off_type)
@@ -1278,8 +1289,8 @@ totally_invisible_line (GtkTextLayout *layout,
           invalidate_cached_style (layout);
 
           /* Bail out if an elision-setting tag ends */
-          if (seg->body.toggle.info->tag->invisible_set &&
-              seg->body.toggle.info->tag->values->invisible)
+          if (seg->body.toggle.info->tag->priv->invisible_set &&
+              seg->body.toggle.info->tag->priv->values->invisible)
             break;
         }
 
@@ -1394,7 +1405,12 @@ set_para_values (GtkTextLayout      *layout,
   if (style->pg_bg_color)
     display->pg_bg_color = gdk_color_copy (style->pg_bg_color);
   else
-    display->pg_bg_color = NULL;  
+    display->pg_bg_color = NULL;
+
+  if (style->pg_bg_rgba)
+    display->pg_bg_rgba = gdk_rgba_copy (style->pg_bg_rgba);
+  else
+    display->pg_bg_rgba = NULL;
 }
 
 static PangoAttribute *
@@ -1410,14 +1426,27 @@ gtk_text_attr_appearance_destroy (PangoAttribute *attr)
 {
   GtkTextAttrAppearance *appearance_attr = (GtkTextAttrAppearance *)attr;
 
-  if (appearance_attr->appearance.bg_stipple)
-    g_object_unref (appearance_attr->appearance.bg_stipple);
-  if (appearance_attr->appearance.fg_stipple)
-    g_object_unref (appearance_attr->appearance.fg_stipple);
+  if (appearance_attr->appearance.rgba[0])
+    gdk_rgba_free (appearance_attr->appearance.rgba[0]);
+
+  if (appearance_attr->appearance.rgba[1])
+    gdk_rgba_free (appearance_attr->appearance.rgba[1]);
 
   g_slice_free (GtkTextAttrAppearance, appearance_attr);
 }
 
+static gboolean 
+rgba_equal (const GdkRGBA *rgba1, const GdkRGBA *rgba2)
+{
+  if (rgba1 && rgba2)
+    return gdk_rgba_equal (rgba1, rgba2);
+  
+  if (rgba1 || rgba2)
+    return FALSE;
+
+  return TRUE;
+}
+
 static gboolean
 gtk_text_attr_appearance_compare (const PangoAttribute *attr1,
                                   const PangoAttribute *attr2)
@@ -1425,17 +1454,14 @@ gtk_text_attr_appearance_compare (const PangoAttribute *attr1,
   const GtkTextAppearance *appearance1 = &((const GtkTextAttrAppearance *)attr1)->appearance;
   const GtkTextAppearance *appearance2 = &((const GtkTextAttrAppearance *)attr2)->appearance;
 
-  return (gdk_color_equal (&appearance1->fg_color, &appearance2->fg_color) &&
-          gdk_color_equal (&appearance1->bg_color, &appearance2->bg_color) &&
-          appearance1->fg_stipple ==  appearance2->fg_stipple &&
-          appearance1->bg_stipple ==  appearance2->bg_stipple &&
+  return (rgba_equal (appearance1->rgba[0], appearance2->rgba[0]) &&
+          rgba_equal (appearance1->rgba[1], appearance2->rgba[1]) &&
           appearance1->underline == appearance2->underline &&
           appearance1->strikethrough == appearance2->strikethrough &&
           appearance1->draw_bg == appearance2->draw_bg);
-
 }
 
-/**
+/*
  * gtk_text_attr_appearance_new:
  * @desc:
  *
@@ -1444,7 +1470,7 @@ gtk_text_attr_appearance_compare (const PangoAttribute *attr1,
  * and size simultaneously.)
  *
  * Return value:
- **/
+ */
 static PangoAttribute *
 gtk_text_attr_appearance_new (const GtkTextAppearance *appearance)
 {
@@ -1466,15 +1492,15 @@ gtk_text_attr_appearance_new (const GtkTextAppearance *appearance)
 
   result->appearance = *appearance;
 
-  if (appearance->bg_stipple)
-    g_object_ref (appearance->bg_stipple);
-  if (appearance->fg_stipple)
-    g_object_ref (appearance->fg_stipple);
+  if (appearance->rgba[0])
+    result->appearance.rgba[0] = gdk_rgba_copy (appearance->rgba[0]);
+
+  if (appearance->rgba[1])
+    result->appearance.rgba[1] = gdk_rgba_copy (appearance->rgba[1]);
 
   return (PangoAttribute *)result;
 }
 
-
 static void
 add_generic_attrs (GtkTextLayout      *layout,
                    GtkTextAppearance  *appearance,
@@ -1582,9 +1608,6 @@ add_pixbuf_attrs (GtkTextLayout      *layout,
   attr->start_index = start;
   attr->end_index = start + seg->byte_count;
   pango_attr_list_insert (attrs, attr);
-
-  display->shaped_objects =
-    g_slist_append (display->shaped_objects, pixbuf->pixbuf);
 }
 
 static void
@@ -1614,8 +1637,8 @@ add_child_attrs (GtkTextLayout      *layout,
           /* Found it */
           GtkRequisition req;
 
-          gtk_widget_get_child_requisition (child, &req);
-          
+          gtk_widget_get_preferred_size (child, &req, NULL);
+
           width = req.width;
           height = req.height;
 
@@ -1643,8 +1666,6 @@ add_child_attrs (GtkTextLayout      *layout,
       widget = NULL;
     }
 
-  display->shaped_objects = g_slist_append (display->shaped_objects, widget);
-  
   logical_rect.x = 0;
   logical_rect.y = -height * PANGO_SCALE;
   logical_rect.width = width * PANGO_SCALE;
@@ -1657,7 +1678,7 @@ add_child_attrs (GtkTextLayout      *layout,
   pango_attr_list_insert (attrs, attr);
 }
 
-/**
+/*
  * get_block_cursor:
  * @layout: a #GtkTextLayout
  * @display: a #GtkTextLineDisplay
@@ -1671,7 +1692,7 @@ add_child_attrs (GtkTextLayout      *layout,
  * Checks whether layout should display block cursor at given position.
  * For this layout must be in overwrite mode and text at @insert_iter 
  * must be editable.
- **/
+ */
 static gboolean
 get_block_cursor (GtkTextLayout      *layout,
                  GtkTextLineDisplay *display,
@@ -1709,11 +1730,6 @@ add_cursor (GtkTextLayout      *layout,
             GtkTextLineSegment *seg,
             gint                start)
 {
-  PangoRectangle strong_pos, weak_pos;
-  GtkTextCursorDisplay *cursor = NULL; /* Quiet GCC */
-  gboolean add_weak = FALSE;
-  gboolean add_strong = FALSE;
-  
   /* Hide insertion cursor when we have a selection or the layout
    * user has hidden the cursor.
    */
@@ -1743,46 +1759,10 @@ add_cursor (GtkTextLayout      *layout,
        }
     }
 
-  pango_layout_get_cursor_pos (display->layout, start, &strong_pos, &weak_pos);
+  if (!display->cursors)
+    display->cursors = g_array_new (FALSE, FALSE, sizeof(int));
 
-  if (layout->cursor_direction == GTK_TEXT_DIR_NONE)
-    {
-      add_strong = TRUE;
-      add_weak = TRUE;
-    }
-  else if (display->direction == layout->cursor_direction)
-    add_strong = TRUE;
-  else
-    add_weak = TRUE;
-
-  if (add_strong)
-    {
-      cursor = g_new (GtkTextCursorDisplay, 1);
-
-      cursor->x = PANGO_PIXELS (strong_pos.x);
-      cursor->y = PANGO_PIXELS (strong_pos.y);
-      cursor->height = PANGO_PIXELS (strong_pos.height);
-      cursor->is_strong = TRUE;
-      cursor->is_weak = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
-      display->cursors = g_slist_prepend (display->cursors, cursor);
-    }
-  
-  if (add_weak)
-    {
-      if (weak_pos.x == strong_pos.x && add_strong)
-       cursor->is_weak = TRUE;
-      else
-       {
-         cursor = g_new (GtkTextCursorDisplay, 1);
-         
-         cursor->x = PANGO_PIXELS (weak_pos.x);
-         cursor->y = PANGO_PIXELS (weak_pos.y);
-         cursor->height = PANGO_PIXELS (weak_pos.height);
-         cursor->is_strong = (layout->cursor_direction == GTK_TEXT_DIR_NONE) ? FALSE : TRUE;
-         cursor->is_weak = TRUE;
-         display->cursors = g_slist_prepend (display->cursors, cursor);
-       }
-    }
+  display->cursors = g_array_append_val (display->cursors, start);
 }
 
 static gboolean
@@ -1807,58 +1787,72 @@ static void
 allocate_child_widgets (GtkTextLayout      *text_layout,
                         GtkTextLineDisplay *display)
 {
-  GSList *shaped = display->shaped_objects;
   PangoLayout *layout = display->layout;
-  PangoLayoutIter *iter;
-  
-  iter = pango_layout_get_iter (layout);
-  
+  PangoLayoutIter *run_iter;
+
+  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 = NULL;
+          GList *widgets = NULL;
+          GList *l;
+
+          /* The pango iterator iterates in visual order.
+           * We use the byte index to find the child widget.
            */
-          if (shaped_object && 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);
+         if (anchor)
+            widgets = gtk_text_child_anchor_get_widgets (anchor);
+
+          for (l = widgets; l; l = l->next)
             {
               PangoRectangle extents;
+              GtkWidget *child = l->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,
-                                                 NULL,
-                                                 &extents);
-              
-              g_signal_emit (text_layout,
-                             signals[ALLOCATE_CHILD],
-                             0,
-                             shaped_object,
-                             PANGO_PIXELS (extents.x) + display->x_offset,
-                             PANGO_PIXELS (extents.y) + display->top_margin);
+              if (_gtk_anchored_child_get_layout (child) == text_layout)
+                {
+
+                  /* 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 (run_iter,
+                                                     NULL,
+                                                     &extents);
+
+                  g_signal_emit (text_layout,
+                                 signals[ALLOCATE_CHILD],
+                                 0,
+                                 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));
-  
-  pango_layout_iter_free (iter);
+  while (pango_layout_iter_next_run (run_iter));
+
+  pango_layout_iter_free (run_iter);
 }
 
 static void
-convert_color (GdkColor       *result,
+convert_color (GdkRGBA        *result,
               PangoAttrColor *attr)
 {
-  result->red = attr->color.red;
-  result->blue = attr->color.blue;
-  result->green = attr->color.green;
+  result->red = attr->color.red / 65535.;
+  result->blue = attr->color.blue / 65535.;
+  result->green = attr->color.green / 65535.;
+  result->alpha = 1;
 }
 
 /* This function is used to convert the preedit string attributes, which are
@@ -1898,14 +1892,21 @@ add_preedit_attrs (GtkTextLayout     *layout,
       while (tmp_list)
        {
          PangoAttribute *attr = tmp_list->data;
+         GdkRGBA rgba;
          
          switch (attr->klass->type)
            {
            case PANGO_ATTR_FOREGROUND:
-             convert_color (&appearance.fg_color, (PangoAttrColor *)attr);
+             convert_color (&rgba, (PangoAttrColor *)attr);
+             if (appearance.rgba[1])
+               gdk_rgba_free (appearance.rgba[1]);
+             appearance.rgba[1] = gdk_rgba_copy (&rgba);
              break;
            case PANGO_ATTR_BACKGROUND:
-             convert_color (&appearance.bg_color, (PangoAttrColor *)attr);
+             convert_color (&rgba, (PangoAttrColor *)attr);
+             if (appearance.rgba[0])
+               gdk_rgba_free (appearance.rgba[0]);
+             appearance.rgba[0] = gdk_rgba_copy (&rgba);
              appearance.draw_bg = TRUE;
              break;
            case PANGO_ATTR_UNDERLINE:
@@ -1972,9 +1973,6 @@ update_text_display_cursors (GtkTextLayout      *layout,
 
   display->cursors_invalid = FALSE;
 
-  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                    &iter, line, 0);
-
   /* Special-case optimization for completely
    * invisible lines; makes it faster to deal
    * with sequences of invisible lines.
@@ -1993,11 +1991,10 @@ update_text_display_cursors (GtkTextLayout      *layout,
           seg->type == &gtk_text_pixbuf_type ||
           seg->type == &gtk_text_child_type)
         {
-          _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                            &iter, line,
+          gtk_text_layout_get_iter_at_line (layout, &iter, line,
                                             buffer_byte_offset);
 
-         if (!_gtk_text_btree_char_is_invisible (&iter))
+          if (!_gtk_text_btree_char_is_invisible (&iter))
             layout_byte_offset += seg->byte_count;
 
          buffer_byte_offset += seg->byte_count;
@@ -2072,8 +2069,6 @@ get_tags_array_at_iter (GtkTextIter *iter)
 
   if (n_tags > 0)
     {
-      /* Sort tags in ascending order of priority */
-      _gtk_text_tag_array_sort (tags, n_tags);
       array = g_ptr_array_sized_new (n_tags);
       g_ptr_array_set_size (array, n_tags);
       memcpy (array->pdata, tags, n_tags * sizeof (GtkTextTag*));
@@ -2097,7 +2092,7 @@ tags_array_toggle_tag (GPtrArray  *array,
 
   tags = (GtkTextTag**) array->pdata;
 
-  for (pos = 0; pos < array->len && tags[pos]->priority < tag->priority; pos++) ;
+  for (pos = 0; pos < array->len && tags[pos]->priv->priority < tag->priv->priority; pos++) ;
 
   if (pos < array->len && tags[pos] == tag)
     g_ptr_array_remove_index (array, pos);
@@ -2157,15 +2152,12 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
 
   DV (g_print ("creating one line display cache (%s)\n", G_STRLOC));
 
-  display = g_new0 (GtkTextLineDisplay, 1);
+  display = g_slice_new0 (GtkTextLineDisplay);
 
   display->size_only = size_only;
   display->line = line;
   display->insert_index = -1;
 
-  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                    &iter, line, 0);
-
   /* Special-case optimization for completely
    * invisible lines; makes it faster to deal
    * with sequences of invisible lines.
@@ -2299,7 +2291,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                                      size_only, FALSE);
                   add_pixbuf_attrs (layout, display, style,
                                     seg, attrs, layout_byte_offset);
-                  memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
+                  memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
                           seg->byte_count);
                   layout_byte_offset += seg->byte_count;
                   buffer_byte_offset += seg->byte_count;
@@ -2314,7 +2306,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
                                      size_only, FALSE);
                   add_child_attrs (layout, display, style,
                                    seg, attrs, layout_byte_offset);
-                  memcpy (text + layout_byte_offset, gtk_text_unknown_char_utf8,
+                  memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
                           seg->byte_count);
                   layout_byte_offset += seg->byte_count;
                   buffer_byte_offset += seg->byte_count;
@@ -2495,16 +2487,15 @@ gtk_text_layout_free_line_display (GtkTextLayout      *layout,
         g_object_unref (display->layout);
 
       if (display->cursors)
-        {
-          g_slist_foreach (display->cursors, (GFunc)g_free, NULL);
-          g_slist_free (display->cursors);
-        }
-      g_slist_free (display->shaped_objects);
-      
+        g_array_free (display->cursors, TRUE);
+
       if (display->pg_bg_color)
         gdk_color_free (display->pg_bg_color);
 
-      g_free (display);
+      if (display->pg_bg_rgba)
+        gdk_rgba_free (display->pg_bg_rgba);
+
+      g_slice_free (GtkTextLineDisplay, display);
     }
 }
 
@@ -2552,8 +2543,7 @@ line_display_index_to_iter (GtkTextLayout      *layout,
        }
     }
 
-  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                    iter, display->line, 0);
+  gtk_text_layout_get_iter_at_line (layout, iter, display->line, 0);
 
   gtk_text_iter_set_visible_line_index (iter, index);
   
@@ -2562,9 +2552,7 @@ line_display_index_to_iter (GtkTextLayout      *layout,
       /* Clamp to end of line - really this clamping should have been done
        * before here, maybe in Pango, this is a broken band-aid I think
        */
-      _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                        iter, display->line, 0);
-
+      gtk_text_layout_get_iter_at_line (layout, iter, display->line, 0);
       if (!gtk_text_iter_ends_line (iter))
         gtk_text_iter_forward_to_line_end (iter);
     }
@@ -2602,11 +2590,11 @@ get_line_at_y (GtkTextLayout *layout,
  * @target_iter: the iterator in which the result is stored
  * @y: the y positition
  * @line_top: location to store the y coordinate of the
- *            top of the line. (Can by %NULL.)
+ *            top of the line. (Can by %NULL)
  *
  * Get the iter at the beginning of the line which is displayed
  * at the given y.
- **/
+ */
 void
 gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
                                GtkTextIter   *target_iter,
@@ -2619,8 +2607,7 @@ gtk_text_layout_get_line_at_y (GtkTextLayout *layout,
   g_return_if_fail (target_iter != NULL);
 
   get_line_at_y (layout, y, &line, line_top);
-  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                   target_iter, line, 0);
+  gtk_text_layout_get_iter_at_line (layout, target_iter, line, 0);
 }
 
 void
@@ -2663,7 +2650,8 @@ void gtk_text_layout_get_iter_at_position (GtkTextLayout     *layout,
   if (y > display->height - display->top_margin - display->bottom_margin)
     {
       byte_index = _gtk_text_line_byte_count (line);
-      *trailing = 0;
+      if (trailing)
+        *trailing = 0;
     }
   else
     {
@@ -2685,8 +2673,8 @@ void gtk_text_layout_get_iter_at_position (GtkTextLayout     *layout,
  * gtk_text_layout_get_cursor_locations:
  * @layout: a #GtkTextLayout
  * @iter: a #GtkTextIter
- * @strong_pos: location to store the strong cursor position (may be %NULL)
- * @weak_pos: location to store the weak cursor position (may be %NULL)
+ * @strong_pos: (allow-none): location to store the strong cursor position (may be %NULL)
+ * @weak_pos: (allow-none): location to store the weak cursor position (may be %NULL)
  *
  * Given an iterator within a text layout, determine the positions of the
  * strong and weak cursors if the insertion point is at that
@@ -2723,8 +2711,7 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout  *layout,
                                            line, layout);
   
   gtk_text_buffer_get_iter_at_mark (layout->buffer, &insert_iter,
-                                    gtk_text_buffer_get_mark (layout->buffer,
-                                                              "insert"));
+                                    gtk_text_buffer_get_insert (layout->buffer));
 
   if (gtk_text_iter_equal (iter, &insert_iter))
     index += layout->preedit_cursor - layout->preedit_len;
@@ -2993,8 +2980,7 @@ find_display_line_below (GtkTextLayout *layout,
       line = next;
     }
 
-  _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                   iter, found_line, found_byte);
+  gtk_text_layout_get_iter_at_line (layout, iter, found_line, found_byte);
 }
 
 /* Find the iter for the logical beginning of the last display line whose
@@ -3062,10 +3048,9 @@ find_display_line_above (GtkTextLayout *layout,
     }
 
  done:
-  
+
   if (found_line)
-    _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                     iter, found_line, found_byte);
+    gtk_text_layout_get_iter_at_line (layout, iter, found_line, found_byte);
   else
     gtk_text_buffer_get_iter_at_offset (layout->buffer, iter, 0);
 }
@@ -3432,7 +3417,6 @@ gtk_text_layout_get_iter_at_line (GtkTextLayout  *layout,
                                     iter, line, byte_offset);
 }
 
-
 /**
  * gtk_text_layout_move_iter_to_x:
  * @layout: a #GtkTextLayout
@@ -3579,12 +3563,8 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
           do
             {
               line = _gtk_text_line_previous (line);
-
               if (!line)
                 goto done;
-              
-              _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                                &lineiter, line, 0);
             }
           while (totally_invisible_line (layout, line, &lineiter));
           
@@ -3600,12 +3580,9 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
               line = _gtk_text_line_next_excluding_last (line);
               if (!line)
                 goto done;
-
-              _gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
-                                                &lineiter, line, 0);
             }
           while (totally_invisible_line (layout, line, &lineiter));
-  
+
          gtk_text_layout_free_line_display (layout, display);
          display = gtk_text_layout_get_line_display (layout, line, FALSE);
           new_index = 0;
@@ -3697,6 +3674,3 @@ gtk_text_layout_buffer_delete_range (GtkTextBuffer *textbuffer,
 
   gtk_text_layout_update_cursor_line (layout);
 }
-
-#define __GTK_TEXT_LAYOUT_C__
-#include "gtkaliasdef.c"