diff options
author | Alexander Larsson <alexl@redhat.com> | 2020-02-06 16:33:34 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2020-02-06 17:47:56 +0100 |
commit | 828269820183c6f6a8fc553bfd1387d110f3ae02 (patch) | |
tree | 77591b43b95930aa5fb99a7f7611389c90b2c672 /gtk | |
parent | fcc3c1291970f115315e24a9281ad3ac94388a12 (diff) | |
download | gtk+-828269820183c6f6a8fc553bfd1387d110f3ae02.tar.gz |
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.
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtktextbtree.c | 21 | ||||
-rw-r--r-- | gtk/gtktextbtree.h | 17 | ||||
-rw-r--r-- | gtk/gtktextbuffer.c | 68 | ||||
-rw-r--r-- | gtk/gtktextbuffer.h | 12 | ||||
-rw-r--r-- | gtk/gtktextchild.c | 117 | ||||
-rw-r--r-- | gtk/gtktextchildprivate.h | 10 | ||||
-rw-r--r-- | gtk/gtktextiter.c | 36 | ||||
-rw-r--r-- | gtk/gtktextiter.h | 8 | ||||
-rw-r--r-- | gtk/gtktextlayout.c | 60 | ||||
-rw-r--r-- | gtk/gtktextsegment.h | 8 | ||||
-rw-r--r-- | gtk/gtktexttypes.h | 2 |
11 files changed, 232 insertions, 127 deletions
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 == >k_text_texture_type || + else if (seg->type == >k_text_paintable_type || seg->type == >k_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 = >k_text_texture_type; + seg->type = >k_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 != >k_text_texture_type) + if (real->segment->type != >k_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(). @@ -5667,6 +5667,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, GtkTextMark *mark) 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 == >k_text_char_type || - seg->type == >k_text_texture_type || + seg->type == >k_text_paintable_type || seg->type == >k_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 == >k_text_char_type || - seg->type == >k_text_texture_type || + seg->type == >k_text_paintable_type || seg->type == >k_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 == >k_text_texture_type) + else if (seg->type == >k_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; /* |