[gtk: 14/31] textview: Use paintables instead of textures, and fix the support



commit 828269820183c6f6a8fc553bfd1387d110f3ae02
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Feb 6 16:33:34 2020 +0100

    textview: Use paintables instead of textures, and fix the support
    
    This changes gtk_text_buffer_insert_texture() to
    gtk_text_buffer_insert_paintable() which is strictly more useful
    (as textures are paintables). It also fixes the code to actually
    support drawing the paintables (as well as tracking changes
    to the paintables.

 demos/gtk-demo/textview.c  |  20 ++++----
 gtk/gtktextbtree.c         |  21 ++++----
 gtk/gtktextbtree.h         |  17 ++++---
 gtk/gtktextbuffer.c        |  68 +++++++++++++-------------
 gtk/gtktextbuffer.h        |  12 ++---
 gtk/gtktextchild.c         | 117 +++++++++++++++++++++++++++++++++------------
 gtk/gtktextchildprivate.h  |  10 ++--
 gtk/gtktextiter.c          |  36 +++++++++-----
 gtk/gtktextiter.h          |   8 ++--
 gtk/gtktextlayout.c        |  60 ++++++++++++++++-------
 gtk/gtktextsegment.h       |   8 ++--
 gtk/gtktexttypes.h         |   2 +-
 testsuite/gtk/textbuffer.c |  14 +++---
 13 files changed, 250 insertions(+), 143 deletions(-)
---
diff --git a/demos/gtk-demo/textview.c b/demos/gtk-demo/textview.c
index 01eb503b85..2a2298a14c 100644
--- a/demos/gtk-demo/textview.c
+++ b/demos/gtk-demo/textview.c
@@ -9,6 +9,7 @@
 
 #include <gtk/gtk.h>
 #include <stdlib.h> /* for exit() */
+#include "paintable.h"
 
 static void easter_egg_callback (GtkWidget *button, gpointer data);
 
@@ -130,20 +131,18 @@ insert_text (GtkTextView *view)
   GtkTextBuffer *buffer = gtk_text_view_get_buffer (view);
   GtkTextIter iter;
   GtkTextIter start, end;
-  GdkTexture *texture;
   GtkIconTheme *icon_theme;
   GtkIconPaintable *icon;
+  GdkPaintable *nuclear;
 
   icon_theme = gtk_icon_theme_get_for_display (gtk_widget_get_display (widget));
   icon = gtk_icon_theme_lookup_icon (icon_theme,
-                                     "gtk3-demo",
+                                     "face-cool",
                                      NULL,
                                      32, 1,
                                      gtk_widget_get_direction (widget),
                                      0);
-  texture = gtk_icon_paintable_download_texture (icon);
-  g_object_unref (icon);
-  g_assert (texture);
+  nuclear = gtk_nuclear_animation_new ();
 
   /* get start of buffer; each insertion will revalidate the
    * iterator to point to just after the inserted text.
@@ -239,9 +238,11 @@ insert_text (GtkTextView *view)
                                             "heading", NULL);
 
   gtk_text_buffer_insert (buffer, &iter, "The buffer can have images in it: ", -1);
-  gtk_text_buffer_insert_texture (buffer, &iter, texture);
-  gtk_text_buffer_insert_texture (buffer, &iter, texture);
-  gtk_text_buffer_insert_texture (buffer, &iter, texture);
+  gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
+  gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (icon));
+
+  gtk_text_buffer_insert_paintable (buffer, &iter, nuclear);
+
   gtk_text_buffer_insert (buffer, &iter, " for example.\n\n", -1);
 
   gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, "Spacing. ", -1,
@@ -386,7 +387,8 @@ insert_text (GtkTextView *view)
 
   gtk_text_buffer_end_irreversible_action (buffer);
 
-  g_object_unref (texture);
+  g_object_unref (icon);
+  g_object_unref (nuclear);
 }
 
 static gboolean
diff --git a/gtk/gtktextbtree.c b/gtk/gtktextbtree.c
index db7d3485e3..4a0de2a141 100644
--- a/gtk/gtktextbtree.c
+++ b/gtk/gtktextbtree.c
@@ -1259,9 +1259,8 @@ _gtk_text_btree_insert (GtkTextIter *iter,
 }
 
 static void
-insert_texture_or_widget_segment (GtkTextIter        *iter,
-                                  GtkTextLineSegment *seg)
-
+insert_paintable_or_widget_segment (GtkTextIter        *iter,
+                                    GtkTextLineSegment *seg)
 {
   GtkTextIter start;
   GtkTextLineSegment *prevPtr;
@@ -1297,19 +1296,21 @@ insert_texture_or_widget_segment (GtkTextIter        *iter,
   *iter = start;
   gtk_text_iter_forward_char (iter); /* skip forward past the segment */
 
-  DV (g_print ("invalidating due to inserting texture/widget (%s)\n", G_STRLOC));
+  DV (g_print ("invalidating due to inserting paintable/widget (%s)\n", G_STRLOC));
   _gtk_text_btree_invalidate_region (tree, &start, iter, FALSE);
 }
      
 void
-_gtk_text_btree_insert_texture (GtkTextIter *iter,
-                                GdkTexture  *texture)
+_gtk_text_btree_insert_paintable (GtkTextIter  *iter,
+                                  GdkPaintable *paintable)
 {
   GtkTextLineSegment *seg;
   
-  seg = _gtk_texture_segment_new (texture);
+  seg = _gtk_paintable_segment_new (paintable);
+  seg->body.paintable.tree = _gtk_text_iter_get_btree (iter);
+  seg->body.paintable.line = _gtk_text_iter_get_text_line (iter);
 
-  insert_texture_or_widget_segment (iter, seg);
+  insert_paintable_or_widget_segment (iter, seg);
 }
 
 void
@@ -1330,7 +1331,7 @@ _gtk_text_btree_insert_child_anchor (GtkTextIter        *iter,
   tree = seg->body.child.tree = _gtk_text_iter_get_btree (iter);
   seg->body.child.line = _gtk_text_iter_get_text_line (iter);
   
-  insert_texture_or_widget_segment (iter, seg);
+  insert_paintable_or_widget_segment (iter, seg);
 
   if (tree->child_anchor_table == NULL)
     tree->child_anchor_table = g_hash_table_new (NULL, NULL);
@@ -2380,7 +2381,7 @@ copy_segment (GString *string,
 
       /* printf ("  :%s\n", string->str); */
     }
-  else if (seg->type == &gtk_text_texture_type ||
+  else if (seg->type == &gtk_text_paintable_type ||
            seg->type == &gtk_text_child_type)
     {
       gboolean copy = TRUE;
diff --git a/gtk/gtktextbtree.h b/gtk/gtktextbtree.h
index 5b5e331bdd..d333216b69 100644
--- a/gtk/gtktextbtree.h
+++ b/gtk/gtktextbtree.h
@@ -63,13 +63,13 @@ gboolean _gtk_text_btree_is_end (GtkTextBTree       *tree,
 
 /* Indexable segment mutation */
 
-void _gtk_text_btree_delete        (GtkTextIter *start,
-                                    GtkTextIter *end);
-void _gtk_text_btree_insert        (GtkTextIter *iter,
-                                    const gchar *text,
-                                    gint         len);
-void _gtk_text_btree_insert_texture (GtkTextIter *iter,
-                                     GdkTexture  *texture);
+void _gtk_text_btree_delete           (GtkTextIter  *start,
+                                       GtkTextIter  *end);
+void _gtk_text_btree_insert           (GtkTextIter  *iter,
+                                       const gchar  *text,
+                                       gint          len);
+void _gtk_text_btree_insert_paintable (GtkTextIter  *iter,
+                                       GdkPaintable *texture);
 
 void _gtk_text_btree_insert_child_anchor (GtkTextIter        *iter,
                                           GtkTextChildAnchor *anchor);
@@ -161,6 +161,9 @@ gboolean _gtk_text_btree_get_iter_at_mark_name    (GtkTextBTree       *tree,
 void     _gtk_text_btree_get_iter_at_mark         (GtkTextBTree       *tree,
                                                    GtkTextIter        *iter,
                                                    GtkTextMark        *mark);
+void     _gtk_text_btree_get_iter_at_paintable    (GtkTextBTree       *tree,
+                                                   GtkTextIter        *iter,
+                                                   GtkTextLineSegment *seg);
 void     _gtk_text_btree_get_end_iter             (GtkTextBTree       *tree,
                                                    GtkTextIter        *iter);
 void     _gtk_text_btree_get_iter_at_line         (GtkTextBTree       *tree,
diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c
index 8bf2d50356..abf6b6174d 100644
--- a/gtk/gtktextbuffer.c
+++ b/gtk/gtktextbuffer.c
@@ -87,7 +87,7 @@ struct _ClipboardRequest
 
 enum {
   INSERT_TEXT,
-  INSERT_TEXTURE,
+  INSERT_PAINTABLE,
   INSERT_CHILD_ANCHOR,
   DELETE_RANGE,
   CHANGED,
@@ -128,9 +128,9 @@ static void gtk_text_buffer_real_insert_text           (GtkTextBuffer     *buffe
                                                         GtkTextIter       *iter,
                                                         const gchar       *text,
                                                         gint               len);
-static void gtk_text_buffer_real_insert_texture        (GtkTextBuffer     *buffer,
+static void gtk_text_buffer_real_insert_paintable      (GtkTextBuffer     *buffer,
                                                         GtkTextIter       *iter,
-                                                        GdkTexture        *texture);
+                                                        GdkPaintable      *paintable);
 static void gtk_text_buffer_real_insert_anchor         (GtkTextBuffer     *buffer,
                                                         GtkTextIter       *iter,
                                                         GtkTextChildAnchor *anchor);
@@ -434,7 +434,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
   object_class->get_property = gtk_text_buffer_get_property;
  
   klass->insert_text = gtk_text_buffer_real_insert_text;
-  klass->insert_texture = gtk_text_buffer_real_insert_texture;
+  klass->insert_paintable = gtk_text_buffer_real_insert_paintable;
   klass->insert_child_anchor = gtk_text_buffer_real_insert_anchor;
   klass->delete_range = gtk_text_buffer_real_delete_range;
   klass->apply_tag = gtk_text_buffer_real_apply_tag;
@@ -596,33 +596,33 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
                               _gtk_marshal_VOID__BOXED_STRING_INTv);
 
   /**
-   * GtkTextBuffer::insert-texture:
+   * GtkTextBuffer::insert-paintable:
    * @textbuffer: the object which received the signal
-   * @location: position to insert @texture in @textbuffer
-   * @texture: the #GdkTexture to be inserted
+   * @location: position to insert @paintable in @textbuffer
+   * @paintable: the #GdkPaintable to be inserted
    *
-   * The ::insert-texture signal is emitted to insert a #GdkTexture
+   * The ::insert-paintable signal is emitted to insert a #GdkPaintable
    * in a #GtkTextBuffer. Insertion actually occurs in the default handler.
    *
    * Note that if your handler runs before the default handler it must not
    * invalidate the @location iter (or has to revalidate it).
    * The default signal handler revalidates it to be placed after the
-   * inserted @texture.
+   * inserted @paintable.
    *
-   * See also: gtk_text_buffer_insert_texture().
+   * See also: gtk_text_buffer_insert_paintable().
    */
-  signals[INSERT_TEXTURE] =
-    g_signal_new (I_("insert-texture"),
+  signals[INSERT_PAINTABLE] =
+    g_signal_new (I_("insert-paintable"),
                   G_OBJECT_CLASS_TYPE (object_class),
                   G_SIGNAL_RUN_LAST,
-                  G_STRUCT_OFFSET (GtkTextBufferClass, insert_texture),
+                  G_STRUCT_OFFSET (GtkTextBufferClass, insert_paintable),
                   NULL, NULL,
                   _gtk_marshal_VOID__BOXED_OBJECT,
                   G_TYPE_NONE,
                   2,
                   GTK_TYPE_TEXT_ITER | G_SIGNAL_TYPE_STATIC_SCOPE,
-                  GDK_TYPE_TEXTURE);
-  g_signal_set_va_marshaller (signals[INSERT_TEXTURE],
+                  GDK_TYPE_PAINTABLE);
+  g_signal_set_va_marshaller (signals[INSERT_PAINTABLE],
                               G_TYPE_FROM_CLASS (klass),
                               _gtk_marshal_VOID__BOXED_OBJECTv);
 
@@ -1519,19 +1519,19 @@ insert_range_untagged (GtkTextBuffer     *buffer,
             }
           else if (gtk_text_iter_get_char (&range_end) == GTK_TEXT_UNKNOWN_CHAR)
             {
-              GdkTexture *texture;
+              GdkPaintable *paintable;
               GtkTextChildAnchor *anchor;
 
-              texture = gtk_text_iter_get_texture (&range_end);
+              paintable = gtk_text_iter_get_paintable (&range_end);
               anchor = gtk_text_iter_get_child_anchor (&range_end);
 
-              if (texture)
+              if (paintable)
                 {
                   r = save_range (&range_start,
                                   &range_end,
                                   &end);
 
-                  gtk_text_buffer_insert_texture (buffer, iter, texture);
+                  gtk_text_buffer_insert_paintable (buffer, iter, paintable);
 
                   restore_range (r);
                   r = NULL;
@@ -1733,7 +1733,7 @@ gtk_text_buffer_real_insert_range (GtkTextBuffer     *buffer,
  * @start: a position in a #GtkTextBuffer
  * @end: another position in the same buffer as @start
  *
- * Copies text, tags, and texture between @start and @end (the order
+ * Copies text, tags, and paintables between @start and @end (the order
  * of @start and @end doesn’t matter) and inserts the copy at @iter.
  * Used instead of simply getting/inserting text because it preserves
  * images and tags. If @start and @end are in a different buffer from
@@ -2215,7 +2215,7 @@ gtk_text_buffer_get_text (GtkTextBuffer     *buffer,
  * the returned string do correspond to byte
  * and character indexes into the buffer. Contrast with
  * gtk_text_buffer_get_text(). Note that 0xFFFC can occur in normal
- * text as well, so it is not a reliable indicator that a texture or
+ * text as well, so it is not a reliable indicator that a paintable or
  * widget is in the buffer.
  *
  * Returns: (transfer full): an allocated UTF-8 string
@@ -2243,41 +2243,41 @@ gtk_text_buffer_get_slice (GtkTextBuffer     *buffer,
  */
 
 static void
-gtk_text_buffer_real_insert_texture (GtkTextBuffer *buffer,
-                                     GtkTextIter   *iter,
-                                     GdkTexture    *texture)
+gtk_text_buffer_real_insert_paintable (GtkTextBuffer *buffer,
+                                       GtkTextIter   *iter,
+                                       GdkPaintable  *paintable)
 { 
-  _gtk_text_btree_insert_texture (iter, texture);
+  _gtk_text_btree_insert_paintable (iter, paintable);
 
   g_signal_emit (buffer, signals[CHANGED], 0);
 }
 
 /**
- * gtk_text_buffer_insert_texture:
+ * gtk_text_buffer_insert_paintable:
  * @buffer: a #GtkTextBuffer
- * @iter: location to insert the texture
- * @texture: a #GdkTexture
+ * @iter: location to insert the paintable
+ * @paintable: a #GdkPaintable
  *
  * Inserts an image into the text buffer at @iter. The image will be
  * counted as one character in character counts, and when obtaining
  * the buffer contents as a string, will be represented by the Unicode
  * “object replacement character” 0xFFFC. Note that the “slice”
  * variants for obtaining portions of the buffer as a string include
- * this character for texture, but the “text” variants do
+ * this character for paintable, but the “text” variants do
  * not. e.g. see gtk_text_buffer_get_slice() and
  * gtk_text_buffer_get_text().
  **/
 void
-gtk_text_buffer_insert_texture (GtkTextBuffer *buffer,
-                                GtkTextIter   *iter,
-                                GdkTexture    *texture)
+gtk_text_buffer_insert_paintable (GtkTextBuffer *buffer,
+                                  GtkTextIter   *iter,
+                                  GdkPaintable    *paintable)
 {
   g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
   g_return_if_fail (iter != NULL);
-  g_return_if_fail (GDK_IS_TEXTURE (texture));
+  g_return_if_fail (GDK_IS_PAINTABLE (paintable));
   g_return_if_fail (gtk_text_iter_get_buffer (iter) == buffer);
 
-  g_signal_emit (buffer, signals[INSERT_TEXTURE], 0, iter, texture);
+  g_signal_emit (buffer, signals[INSERT_PAINTABLE], 0, iter, paintable);
 }
 
 /*
diff --git a/gtk/gtktextbuffer.h b/gtk/gtktextbuffer.h
index 969db7f3d8..a844d94f5b 100644
--- a/gtk/gtktextbuffer.h
+++ b/gtk/gtktextbuffer.h
@@ -85,7 +85,7 @@ struct _GtkTextBuffer
  * GtkTextBufferClass:
  * @parent_class: The object class structure needs to be the first.
  * @insert_text: The class handler for the #GtkTextBuffer::insert-text signal.
- * @insert_texture: The class handler for the #GtkTextBuffer::insert-texture signal.
+ * @insert_paintable: The class handler for the #GtkTextBuffer::insert-paintable signal.
  * @insert_child_anchor: The class handler for the #GtkTextBuffer::insert-child-anchor signal.
  * @delete_range: The class handler for the #GtkTextBuffer::delete-range signal.
  * @changed: The class handler for the #GtkTextBuffer::changed signal.
@@ -107,9 +107,9 @@ struct _GtkTextBufferClass
                                    const gchar        *new_text,
                                    gint                new_text_length);
 
-  void (* insert_texture)         (GtkTextBuffer      *buffer,
+  void (* insert_paintable)       (GtkTextBuffer      *buffer,
                                    GtkTextIter        *iter,
-                                   GdkTexture         *texture);
+                                   GdkPaintable       *paintable);
 
   void (* insert_child_anchor)    (GtkTextBuffer      *buffer,
                                    GtkTextIter        *iter,
@@ -267,11 +267,11 @@ gchar          *gtk_text_buffer_get_slice           (GtkTextBuffer     *buffer,
                                                      const GtkTextIter *end,
                                                      gboolean           include_hidden_chars);
 
-/* Insert a texture */
+/* Insert a paintable */
 GDK_AVAILABLE_IN_ALL
-void gtk_text_buffer_insert_texture        (GtkTextBuffer *buffer,
+void gtk_text_buffer_insert_paintable      (GtkTextBuffer *buffer,
                                             GtkTextIter   *iter,
-                                            GdkTexture    *texture);
+                                            GdkPaintable  *texture);
 
 /* Insert a child anchor */
 GDK_AVAILABLE_IN_ALL
diff --git a/gtk/gtktextchild.c b/gtk/gtktextchild.c
index 2ce394c94e..0a2e6163dd 100644
--- a/gtk/gtktextchild.c
+++ b/gtk/gtktextchild.c
@@ -72,67 +72,109 @@
       }                                                                 \
   } G_STMT_END
 
-#define TEXTURE_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
-        + sizeof (GtkTextTexture)))
+#define PAINTABLE_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
+        + sizeof (GtkTextPaintable)))
 
 #define WIDGET_SEG_SIZE ((unsigned) (G_STRUCT_OFFSET (GtkTextLineSegment, body) \
         + sizeof (GtkTextChildBody)))
 
+
+static void
+paintable_invalidate_size (GdkPaintable       *paintable,
+                           GtkTextLineSegment *seg)
+{
+  if (seg->body.paintable.tree)
+    {
+      GtkTextIter start, end;
+
+      _gtk_text_btree_get_iter_at_paintable (seg->body.paintable.tree, &start, seg);
+      end = start;
+      gtk_text_iter_forward_char (&end);
+
+      _gtk_text_btree_invalidate_region (seg->body.paintable.tree, &start, &end, FALSE);
+    }
+}
+
+static void
+paintable_invalidate_contents (GdkPaintable       *paintable,
+                               GtkTextLineSegment *seg)
+{
+  /* These do the same anyway */
+  paintable_invalidate_size (paintable, seg);
+}
+
 static GtkTextLineSegment *
-texture_segment_cleanup_func (GtkTextLineSegment *seg,
-                              GtkTextLine        *line)
+paintable_segment_cleanup_func (GtkTextLineSegment *seg,
+                                GtkTextLine        *line)
 {
-  /* nothing */
+  seg->body.paintable.line = line;
+
   return seg;
 }
 
 static int
-texture_segment_delete_func (GtkTextLineSegment *seg,
-                             GtkTextLine        *line,
-                             gboolean            tree_gone)
+paintable_segment_delete_func (GtkTextLineSegment *seg,
+                               GtkTextLine        *line,
+                               gboolean            tree_gone)
 {
-  if (seg->body.texture.texture)
-    g_object_unref (seg->body.texture.texture);
+  GdkPaintable *paintable;
+  guint flags;
 
-  g_slice_free1 (TEXTURE_SEG_SIZE, seg);
+  seg->body.paintable.tree = NULL;
+  seg->body.paintable.line = NULL;
+
+  paintable = seg->body.paintable.paintable;
+  if (paintable)
+    {
+      flags = gdk_paintable_get_flags (paintable);
+      if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
+        g_signal_handlers_disconnect_by_func (paintable, G_CALLBACK (paintable_invalidate_contents), seg);
+
+      if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
+        g_signal_handlers_disconnect_by_func (paintable, G_CALLBACK (paintable_invalidate_size), seg);
+
+      g_object_unref (paintable);
+    }
+
+  g_slice_free1 (PAINTABLE_SEG_SIZE, seg);
 
   return 0;
 }
 
 static void
-texture_segment_check_func (GtkTextLineSegment *seg,
-                            GtkTextLine        *line)
+paintable_segment_check_func (GtkTextLineSegment *seg,
+                              GtkTextLine        *line)
 {
   if (seg->next == NULL)
-    g_error ("texture segment is the last segment in a line");
+    g_error ("paintable segment is the last segment in a line");
 
   if (seg->byte_count != GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN)
-    g_error ("texture segment has byte count of %d", seg->byte_count);
+    g_error ("paintable segment has byte count of %d", seg->byte_count);
 
   if (seg->char_count != 1)
-    g_error ("texture segment has char count of %d", seg->char_count);
+    g_error ("paintable segment has char count of %d", seg->char_count);
 }
 
-
-const GtkTextLineSegmentClass gtk_text_texture_type = {
-  "texture",                          /* name */
-  FALSE,                                            /* leftGravity */
-  NULL,                                          /* splitFunc */
-  texture_segment_delete_func,                             /* deleteFunc */
-  texture_segment_cleanup_func,                            /* cleanupFunc */
-  NULL,                                                    /* lineChangeFunc */
-  texture_segment_check_func                               /* checkFunc */
+const GtkTextLineSegmentClass gtk_text_paintable_type = {
+  "paintable",                          /* name */
+  FALSE,                                /* leftGravity */
+  NULL,                                 /* splitFunc */
+  paintable_segment_delete_func,        /* deleteFunc */
+  paintable_segment_cleanup_func,       /* cleanupFunc */
+  NULL,                                 /* lineChangeFunc */
+  paintable_segment_check_func          /* checkFunc */
 
 };
 
 GtkTextLineSegment *
-_gtk_texture_segment_new (GdkTexture *texture)
+_gtk_paintable_segment_new (GdkPaintable *paintable)
 {
   GtkTextLineSegment *seg;
+  guint flags;
 
-  seg = g_slice_alloc (TEXTURE_SEG_SIZE);
+  seg = g_slice_alloc (PAINTABLE_SEG_SIZE);
 
-  seg->type = &gtk_text_texture_type;
+  seg->type = &gtk_text_paintable_type;
 
   seg->next = NULL;
 
@@ -142,9 +184,24 @@ _gtk_texture_segment_new (GdkTexture *texture)
   seg->byte_count = GTK_TEXT_UNKNOWN_CHAR_UTF8_LEN;
   seg->char_count = 1;
 
-  seg->body.texture.texture = texture;
+  seg->body.paintable.paintable = paintable;
+  seg->body.paintable.tree = NULL;
+  seg->body.paintable.line = NULL;
+
+  flags = gdk_paintable_get_flags (paintable);
+  if ((flags & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
+    g_signal_connect (paintable,
+                      "invalidate-contents",
+                      G_CALLBACK (paintable_invalidate_contents),
+                      seg);
+
+  if ((flags & GDK_PAINTABLE_STATIC_SIZE) == 0)
+    g_signal_connect (paintable,
+                      "invalidate-size",
+                      G_CALLBACK (paintable_invalidate_size),
+                      seg);
 
-  g_object_ref (texture);
+  g_object_ref (paintable);
 
   return seg;
 }
diff --git a/gtk/gtktextchildprivate.h b/gtk/gtktextchildprivate.h
index 6473d455af..33a395efc4 100644
--- a/gtk/gtktextchildprivate.h
+++ b/gtk/gtktextchildprivate.h
@@ -54,14 +54,16 @@
 
 G_BEGIN_DECLS
 
-typedef struct _GtkTextTexture GtkTextTexture;
+typedef struct _GtkTextPaintable GtkTextPaintable;
 
-struct _GtkTextTexture
+struct _GtkTextPaintable
 {
-  GdkTexture *texture;
+  GdkPaintable *paintable;
+  GtkTextBTree *tree;
+  GtkTextLine *line;
 };
 
-GtkTextLineSegment *_gtk_texture_segment_new (GdkTexture *texture);
+GtkTextLineSegment *_gtk_paintable_segment_new (GdkPaintable *paintable);
 
 typedef struct _GtkTextChildBody GtkTextChildBody;
 
diff --git a/gtk/gtktextiter.c b/gtk/gtktextiter.c
index c031c98fa1..c4c1bfc024 100644
--- a/gtk/gtktextiter.c
+++ b/gtk/gtktextiter.c
@@ -173,7 +173,7 @@ gtk_text_iter_make_surreal (const GtkTextIter *_iter)
       _gtk_text_btree_get_chars_changed_stamp (iter->tree))
     {
       g_warning ("Invalid text buffer iterator: either the iterator "
-                 "is uninitialized, or the characters/textures/widgets "
+                 "is uninitialized, or the characters/paintables/widgets "
                  "in the buffer have been modified since the iterator "
                  "was created.\nYou must use marks, character numbers, "
                  "or line numbers to preserve a position across buffer "
@@ -896,7 +896,7 @@ gtk_text_iter_get_char (const GtkTextIter *iter)
  * such as images.  Because images are encoded in the slice, byte and
  * character offsets in the returned array will correspond to byte
  * offsets in the text buffer. Note that 0xFFFC can occur in normal
- * text as well, so it is not a reliable indicator that a texture or
+ * text as well, so it is not a reliable indicator that a paintable or
  * widget is in the buffer.
  *
  * Returns: (transfer full): slice of text from the buffer
@@ -990,16 +990,16 @@ gtk_text_iter_get_visible_text (const GtkTextIter  *start,
 }
 
 /**
- * gtk_text_iter_get_texture:
+ * gtk_text_iter_get_paintable:
  * @iter: an iterator
  *
- * If the element at @iter is a texture, the texture is returned
+ * If the element at @iter is a paintable, the paintable is returned
  * (with no new reference count added). Otherwise, %NULL is returned.
  *
- * Returns: (transfer none): the texture at @iter
+ * Returns: (transfer none): the paintable at @iter
  **/
-GdkTexture *
-gtk_text_iter_get_texture (const GtkTextIter *iter)
+GdkPaintable *
+gtk_text_iter_get_paintable (const GtkTextIter *iter)
 {
   GtkTextRealIter *real;
 
@@ -1012,10 +1012,10 @@ gtk_text_iter_get_texture (const GtkTextIter *iter)
 
   check_invariants (iter);
 
-  if (real->segment->type != &gtk_text_texture_type)
+  if (real->segment->type != &gtk_text_paintable_type)
     return NULL;
   else
-    return real->segment->body.texture.texture;
+    return real->segment->body.paintable.paintable;
 }
 
 /**
@@ -2444,7 +2444,7 @@ gtk_text_iter_backward_chars (GtkTextIter *iter, gint count)
  * @iter: a #GtkTextIter
  * @count: number of chars to move
  *
- * Moves forward by @count text characters (textures, widgets,
+ * Moves forward by @count text characters (paintables, widgets,
  * etc. do not count as characters for this). Equivalent to moving
  * through the results of gtk_text_iter_get_text(), rather than
  * gtk_text_iter_get_slice().
@@ -2465,7 +2465,7 @@ gtk_text_iter_forward_text_chars  (GtkTextIter *iter,
  * @iter: a #GtkTextIter
  * @count: number of chars to move
  *
- * Moves backward by @count text characters (textures, widgets,
+ * Moves backward by @count text characters (paintables, widgets,
  * etc. do not count as characters for this). Equivalent to moving
  * through the results of gtk_text_iter_get_text(), rather than
  * gtk_text_iter_get_slice().
@@ -5666,6 +5666,20 @@ _gtk_text_btree_get_iter_at_mark_name (GtkTextBTree *tree,
     }
 }
 
+void
+_gtk_text_btree_get_iter_at_paintable (GtkTextBTree *tree,
+                                       GtkTextIter *iter,
+                                       GtkTextLineSegment *seg)
+{
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (tree != NULL);
+
+  iter_init_from_segment (iter, tree,
+                          seg->body.paintable.line, seg);
+  g_assert (seg->body.paintable.line == _gtk_text_iter_get_text_line (iter));
+  check_invariants (iter);
+}
+
 void
 _gtk_text_btree_get_iter_at_mark (GtkTextBTree *tree,
                                   GtkTextIter *iter,
diff --git a/gtk/gtktextiter.h b/gtk/gtktextiter.h
index 890244e459..9655bcfe66 100644
--- a/gtk/gtktextiter.h
+++ b/gtk/gtktextiter.h
@@ -38,7 +38,7 @@ G_BEGIN_DECLS
  * GtkTextSearchFlags:
  * @GTK_TEXT_SEARCH_VISIBLE_ONLY: Search only visible data. A search match may
  * have invisible text interspersed.
- * @GTK_TEXT_SEARCH_TEXT_ONLY: Search only text. A match may have textures or
+ * @GTK_TEXT_SEARCH_TEXT_ONLY: Search only text. A match may have paintables or
  * child widgets mixed inside the matched range.
  * @GTK_TEXT_SEARCH_CASE_INSENSITIVE: The text will be matched regardless of
  * what case it is in.
@@ -47,7 +47,7 @@ G_BEGIN_DECLS
  *
  * If neither #GTK_TEXT_SEARCH_VISIBLE_ONLY nor #GTK_TEXT_SEARCH_TEXT_ONLY are
  * enabled, the match must be exact; the special 0xFFFC character will match
- * embedded textures or child widgets.
+ * embedded paintables or child widgets.
  */
 typedef enum {
   GTK_TEXT_SEARCH_VISIBLE_ONLY     = 1 << 0,
@@ -155,9 +155,9 @@ gchar   *gtk_text_iter_get_visible_text  (const GtkTextIter  *start,
                                           const GtkTextIter  *end);
 
 GDK_AVAILABLE_IN_ALL
-GdkTexture * gtk_text_iter_get_texture (const GtkTextIter *iter);
+GdkPaintable *gtk_text_iter_get_paintable (const GtkTextIter *iter);
 GDK_AVAILABLE_IN_ALL
-GSList  *  gtk_text_iter_get_marks  (const GtkTextIter *iter);
+GSList      *gtk_text_iter_get_marks      (const GtkTextIter *iter);
 
 GDK_AVAILABLE_IN_ALL
 GtkTextChildAnchor* gtk_text_iter_get_child_anchor (const GtkTextIter *iter);
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 5a2b419730..406437c5fd 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -1710,20 +1710,31 @@ add_text_attrs (GtkTextLayout      *layout,
 }
 
 static void
-add_texture_attrs (GtkTextLayout      *layout,
-                   GtkTextLineDisplay *display,
-                   GtkTextAttributes  *style,
-                   GtkTextLineSegment *seg,
-                   PangoAttrList      *attrs,
-                   gint                start)
+add_paintable_attrs (GtkTextLayout      *layout,
+                     GtkTextLineDisplay *display,
+                     GtkTextAttributes  *style,
+                     GtkTextLineSegment *seg,
+                     PangoAttrList      *attrs,
+                     gint                start)
 {
   PangoAttribute *attr;
   PangoRectangle logical_rect;
-  GtkTextTexture *texture = &seg->body.texture;
+  GtkTextPaintable *paintable = &seg->body.paintable;
   gint width, height;
 
-  width = gdk_texture_get_width (texture->texture);
-  height = gdk_texture_get_height (texture->texture);
+  width = gdk_paintable_get_intrinsic_width (paintable->paintable);
+  height = gdk_paintable_get_intrinsic_height (paintable->paintable);
+
+  /* Pick *some* default size */
+  if (width == 0)
+    width = 32;
+  if (height == 0)
+    {
+      double aspect = gdk_paintable_get_intrinsic_aspect_ratio (paintable->paintable);
+      if (aspect == 0)
+        aspect = 1.0;
+      height = width / aspect;
+    }
 
   logical_rect.x = 0;
   logical_rect.y = -height * PANGO_SCALE;
@@ -1731,7 +1742,7 @@ add_texture_attrs (GtkTextLayout      *layout,
   logical_rect.height = height * PANGO_SCALE;
 
   attr = pango_attr_shape_new_with_data (&logical_rect, &logical_rect,
-                                        texture->texture, NULL, NULL);
+                                        paintable->paintable, NULL, NULL);
   attr->start_index = start;
   attr->end_index = start + seg->byte_count;
   pango_attr_list_insert (attrs, attr);
@@ -2149,7 +2160,7 @@ gtk_text_layout_update_display_cursors (GtkTextLayout      *layout,
     {
       /* Displayable segments */
       if (seg->type == &gtk_text_char_type ||
-          seg->type == &gtk_text_texture_type ||
+          seg->type == &gtk_text_paintable_type ||
           seg->type == &gtk_text_child_type)
         {
           gtk_text_layout_get_iter_at_line (layout, &iter, line,
@@ -2346,14 +2357,14 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
     {
       /* Displayable segments */
       if (seg->type == &gtk_text_char_type ||
-          seg->type == &gtk_text_texture_type ||
+          seg->type == &gtk_text_paintable_type ||
           seg->type == &gtk_text_child_type)
         {
           style = get_style (layout, tags);
           initial_toggle_segments = FALSE;
 
           /* We have to delay setting the paragraph values until we
-           * hit the first texture or text segment because toggles at
+           * hit the first paintable or text segment because toggles at
            * the beginning of the paragraph should affect the
            * paragraph-global values
            */
@@ -2430,15 +2441,15 @@ gtk_text_layout_create_display (GtkTextLayout *layout,
                                   &last_scale_attr,
                                   &last_fallback_attr);
                 }
-              else if (seg->type == &gtk_text_texture_type)
+              else if (seg->type == &gtk_text_paintable_type)
                 {
                   add_generic_attrs (layout,
                                      &style->appearance,
                                      seg->byte_count,
                                      attrs, layout_byte_offset,
                                      size_only, FALSE);
-                  add_texture_attrs (layout, display, style,
-                                     seg, attrs, layout_byte_offset);
+                  add_paintable_attrs (layout, display, style,
+                                       seg, attrs, layout_byte_offset);
                   memcpy (text + layout_byte_offset, _gtk_text_unknown_char_utf8,
                           seg->byte_count);
                   layout_byte_offset += seg->byte_count;
@@ -4072,6 +4083,21 @@ render_para (GskPangoRenderer   *crenderer,
   pango_layout_iter_free (iter);
 }
 
+static gboolean
+snapshot_shape (PangoAttrShape         *attr,
+                GdkSnapshot            *snapshot,
+                double                  width,
+                double                  height)
+{
+  if (GDK_IS_PAINTABLE (attr->data))
+    {
+      gdk_paintable_snapshot (GDK_PAINTABLE (attr->data), snapshot, width, height);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 void
 gtk_text_layout_snapshot (GtkTextLayout      *layout,
                           GtkWidget          *widget,
@@ -4106,6 +4132,8 @@ gtk_text_layout_snapshot (GtkTextLayout      *layout,
 
   crenderer = gsk_pango_renderer_acquire ();
 
+  gsk_pango_renderer_set_shape_handler (crenderer, snapshot_shape);
+
   crenderer->widget = widget;
   crenderer->snapshot = snapshot;
   crenderer->fg_color = color;
diff --git a/gtk/gtktextsegment.h b/gtk/gtktextsegment.h
index 690edba4fe..ed987742ff 100644
--- a/gtk/gtktextsegment.h
+++ b/gtk/gtktextsegment.h
@@ -142,10 +142,10 @@ struct _GtkTextLineSegment {
     char chars[4];                      /* Characters that make up character
                                          * info.  Actual length varies to
                                          * hold as many characters as needed.*/
-    GtkTextToggleBody toggle;              /* Information about tag toggle. */
-    GtkTextMarkBody mark;              /* Information about mark. */
-    GtkTextTexture texture;            /* Child texture */
-    GtkTextChildBody child;            /* Child widget */
+    GtkTextToggleBody toggle;           /* Information about tag toggle. */
+    GtkTextMarkBody mark;               /* Information about mark. */
+    GtkTextPaintable paintable;         /* Child texture */
+    GtkTextChildBody child;             /* Child widget */
   } body;
 };
 
diff --git a/gtk/gtktexttypes.h b/gtk/gtktexttypes.h
index a66114778b..02520eab3a 100644
--- a/gtk/gtktexttypes.h
+++ b/gtk/gtktexttypes.h
@@ -50,7 +50,7 @@ extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_left_mark_type;
 extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_right_mark_type;
 
 /* In gtktextchild.c */
-extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_texture_type;
+extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_paintable_type;
 extern G_GNUC_INTERNAL const GtkTextLineSegmentClass gtk_text_child_type;
 
 /*
diff --git a/testsuite/gtk/textbuffer.c b/testsuite/gtk/textbuffer.c
index d4bb416a2b..33b3048d3d 100644
--- a/testsuite/gtk/textbuffer.c
+++ b/testsuite/gtk/textbuffer.c
@@ -686,11 +686,11 @@ fill_buffer (GtkTextBuffer *buffer)
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 1);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE (texture));
 
       str = g_strdup_printf ("%d Hello World!\nwoo woo woo woo woo woo woo woo\n",
                             i);
@@ -706,20 +706,20 @@ fill_buffer (GtkTextBuffer *buffer)
                               "Spanish (Espa\303\261ol) \302\241Hola! / French (Fran\303\247ais) Bonjour, 
Salut / German (Deutsch S\303\274d) Gr\303\274\303\237 Gott (testing Latin-1 chars encoded in UTF8)\nThai (we 
can't display this, just making sure we don't crash)  
(\340\270\240\340\270\262\340\270\251\340\270\262\340\271\204\340\270\227\340\270\242)  
\340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\270\243\340\270\261\340\270\232,
 
\340\270\252\340\270\247\340\270\261\340\270\252\340\270\224\340\270\265\340\270\204\340\271\210\340\270\260\n",
                               -1);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 4);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 7);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_offset (buffer, &iter, 8);
 
-      gtk_text_buffer_insert_texture (buffer, &iter, texture);
+      gtk_text_buffer_insert_paintable (buffer, &iter, GDK_PAINTABLE(texture));
 
       gtk_text_buffer_get_iter_at_line_offset (buffer, &iter, 0, 8);
       iter2 = iter;



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