[gtk/wip/chergert/group-gsk-pango] gskpango: group similar drawings together
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/group-gsk-pango] gskpango: group similar drawings together
- Date: Sat, 27 Jul 2019 23:44:47 +0000 (UTC)
commit 908b708d33f542eb53f6209d346d8e76a7bb70e7
Author: Christian Hergert <chergert redhat com>
Date: Sat Jul 27 16:38:28 2019 -0700
gskpango: group similar drawings together
This groups various operations together into a common parent render node.
The longer term goal is to simplify drawing items of similar types
together.
gtk/gskpango.c | 108 ++++++++++++++++++++++++++++++++++++++++++++--------
gtk/gskpango.h | 8 +++-
gtk/gtktextlayout.c | 71 +++++++++++++++++++++++-----------
3 files changed, 149 insertions(+), 38 deletions(-)
---
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index ae7bbb3672..e07ad4b82b 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -43,6 +43,32 @@ gsk_pango_renderer_set_state (GskPangoRenderer *crenderer,
crenderer->state = state;
}
+static GtkSnapshot *
+get_snapshot (GskPangoRenderer *crenderer,
+ gboolean foreground)
+{
+ switch (crenderer->state)
+ {
+ case GSK_PANGO_RENDERER_CURSOR:
+ return crenderer->cursors_snapshot;
+
+ case GSK_PANGO_RENDERER_NORMAL:
+ if (foreground)
+ return crenderer->fg_snapshot;
+ else
+ return crenderer->bg_snapshot;
+
+ case GSK_PANGO_RENDERER_SELECTED:
+ if (foreground)
+ return crenderer->selection_fg_snapshot;
+ else
+ return crenderer->selection_bg_snapshot;
+
+ default:
+ g_return_val_if_reached (NULL);
+ }
+}
+
static void
get_color (GskPangoRenderer *crenderer,
PangoRenderPart part,
@@ -97,7 +123,7 @@ gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
get_color (crenderer, PANGO_RENDER_PART_FOREGROUND, &color);
- gtk_snapshot_append_text (crenderer->snapshot,
+ gtk_snapshot_append_text (get_snapshot (crenderer, TRUE),
glyph_item->item->analysis.font,
glyph_item->glyphs,
&color,
@@ -117,7 +143,7 @@ gsk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
GdkRGBA rgba;
get_color (crenderer, part, &rgba);
- gtk_snapshot_append_color (crenderer->snapshot,
+ gtk_snapshot_append_color (get_snapshot (crenderer, FALSE),
&rgba,
&GRAPHENE_RECT_INIT ((double)x / PANGO_SCALE,
(double)y / PANGO_SCALE,
@@ -139,7 +165,8 @@ gsk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
cairo_t *cr;
gdouble x, y;
- cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
+ cr = gtk_snapshot_append_cairo (get_snapshot (crenderer, TRUE),
+ &crenderer->bounds);
set_color (crenderer, part, cr);
@@ -168,12 +195,14 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
int width,
int height)
{
+ GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+ GtkSnapshot *snapshot;
GdkRGBA rgba;
double xx, yy, ww, hh;
double hs;
double e, o;
- GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+ snapshot = get_snapshot (crenderer, TRUE);
xx = (double)x / PANGO_SCALE;
yy = (double)y / PANGO_SCALE;
@@ -185,18 +214,18 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
#if 0
gdk_rgba_parse (&rgba, "yellow");
- gtk_snapshot_append_color (crenderer->snapshot, &rgba,
+ gtk_snapshot_append_color (snapshot, &rgba,
&GRAPHENE_RECT_INIT (xx, yy, ww, hh));
#endif
get_color (crenderer, PANGO_RENDER_PART_UNDERLINE, &rgba);
- gtk_snapshot_save (crenderer->snapshot);
- gtk_snapshot_translate (crenderer->snapshot,
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate (snapshot,
&GRAPHENE_POINT_INIT (xx, yy));
- gtk_snapshot_rotate (crenderer->snapshot, 45);
- gtk_snapshot_translate (crenderer->snapshot,
+ gtk_snapshot_rotate (snapshot, 45);
+ gtk_snapshot_translate (snapshot,
&GRAPHENE_POINT_INIT (e / 2 + hs * HEIGHT_RATIO,
- hs * HEIGHT_RATIO));
@@ -206,7 +235,7 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
if (o + hs * (1 + HEIGHT_RATIO) >= ww)
break;
- gtk_snapshot_append_color (crenderer->snapshot, &rgba,
+ gtk_snapshot_append_color (snapshot, &rgba,
&GRAPHENE_RECT_INIT (xx, yy, hh, hh * HEIGHT_RATIO));
xx += hh * (1 - HEIGHT_RATIO);
@@ -216,13 +245,13 @@ gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
if (o + hs * (1 + HEIGHT_RATIO) >= ww)
break;
- gtk_snapshot_append_color (crenderer->snapshot, &rgba,
+ gtk_snapshot_append_color (snapshot, &rgba,
&GRAPHENE_RECT_INIT (xx, yy, hh * HEIGHT_RATIO, hh));
o += hs * (1 - HEIGHT_RATIO);
}
- gtk_snapshot_restore (crenderer->snapshot);
+ gtk_snapshot_restore (snapshot);
}
static void
@@ -232,6 +261,7 @@ gsk_pango_renderer_draw_shape (PangoRenderer *renderer,
int y)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+ GtkSnapshot *snapshot;
cairo_t *cr;
PangoLayout *layout;
PangoCairoShapeRendererFunc shape_renderer;
@@ -239,7 +269,8 @@ gsk_pango_renderer_draw_shape (PangoRenderer *renderer,
double base_x = (double)x / PANGO_SCALE;
double base_y = (double)y / PANGO_SCALE;
- cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds);
+ snapshot = get_snapshot (crenderer, TRUE);
+ cr = gtk_snapshot_append_cairo (snapshot, &crenderer->bounds);
layout = pango_renderer_get_layout (renderer);
if (!layout)
@@ -419,6 +450,12 @@ gsk_pango_renderer_acquire (void)
renderer = g_object_new (GSK_TYPE_PANGO_RENDERER, NULL);
}
+ renderer->fg_snapshot = gtk_snapshot_new ();
+ renderer->bg_snapshot = gtk_snapshot_new ();
+ renderer->selection_fg_snapshot = gtk_snapshot_new ();
+ renderer->selection_bg_snapshot = gtk_snapshot_new ();
+ renderer->cursors_snapshot = gtk_snapshot_new ();
+
return renderer;
}
@@ -428,7 +465,6 @@ gsk_pango_renderer_release (GskPangoRenderer *renderer)
if (G_LIKELY (renderer->is_cached_renderer))
{
renderer->widget = NULL;
- renderer->snapshot = NULL;
if (renderer->error_color)
{
@@ -436,12 +472,54 @@ gsk_pango_renderer_release (GskPangoRenderer *renderer)
renderer->error_color = NULL;
}
+ g_clear_object (&renderer->fg_snapshot);
+ g_clear_object (&renderer->bg_snapshot);
+ g_clear_object (&renderer->selection_fg_snapshot);
+ g_clear_object (&renderer->selection_bg_snapshot);
+ g_clear_object (&renderer->cursors_snapshot);
+
G_UNLOCK (cached_renderer);
}
else
g_object_unref (renderer);
}
+static void
+append_to_snapshot (GtkSnapshot *snapshot,
+ GtkSnapshot **source)
+{
+ g_assert (GTK_IS_SNAPSHOT (snapshot));
+ g_assert (source != NULL);
+
+ if (*source != NULL)
+ {
+ GskRenderNode *node;
+
+ node = gtk_snapshot_free_to_node (*source);
+ *source = NULL;
+
+ if (node != NULL)
+ {
+ gtk_snapshot_append_node (snapshot, node);
+ gsk_render_node_unref (node);
+ }
+ }
+}
+
+void
+gsk_pango_renderer_apply (GskPangoRenderer *crenderer,
+ GtkSnapshot *snapshot)
+{
+ g_return_if_fail (GSK_IS_PANGO_RENDERER (crenderer));
+ g_return_if_fail (GTK_IS_SNAPSHOT (snapshot));
+
+ append_to_snapshot (snapshot, &crenderer->bg_snapshot);
+ append_to_snapshot (snapshot, &crenderer->fg_snapshot);
+ append_to_snapshot (snapshot, &crenderer->selection_bg_snapshot);
+ append_to_snapshot (snapshot, &crenderer->selection_fg_snapshot);
+ append_to_snapshot (snapshot, &crenderer->cursors_snapshot);
+}
+
/**
* gtk_snapshot_append_layout:
* @snapshot: a #GtkSnapshot
@@ -465,7 +543,6 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
crenderer = gsk_pango_renderer_acquire ();
- crenderer->snapshot = snapshot;
crenderer->fg_color = *color;
pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
@@ -473,5 +550,6 @@ gtk_snapshot_append_layout (GtkSnapshot *snapshot,
pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
+ gsk_pango_renderer_apply (crenderer, snapshot);
gsk_pango_renderer_release (crenderer);
}
diff --git a/gtk/gskpango.h b/gtk/gskpango.h
index 33ebff422a..1e01645486 100644
--- a/gtk/gskpango.h
+++ b/gtk/gskpango.h
@@ -52,7 +52,11 @@ struct _GskPangoRenderer
PangoRenderer parent_instance;
GtkWidget *widget;
- GtkSnapshot *snapshot;
+ GtkSnapshot *fg_snapshot;
+ GtkSnapshot *bg_snapshot;
+ GtkSnapshot *selection_fg_snapshot;
+ GtkSnapshot *selection_bg_snapshot;
+ GtkSnapshot *cursors_snapshot;
GdkRGBA fg_color;
graphene_rect_t bounds;
@@ -75,6 +79,8 @@ void gsk_pango_renderer_set_state (GskPangoRenderer *crenderer
GskPangoRendererState state);
GskPangoRenderer *gsk_pango_renderer_acquire (void);
void gsk_pango_renderer_release (GskPangoRenderer *crenderer);
+void gsk_pango_renderer_apply (GskPangoRenderer *crenderer,
+ GtkSnapshot *snapshot);
G_END_DECLS
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index 2ee27ed762..0a578ea3de 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -3847,6 +3847,33 @@ gtk_text_layout_after_buffer_delete_range (GtkTextBuffer *textbuffer,
gtk_text_layout_update_cursor_line (layout);
}
+static void
+push_translate (GskPangoRenderer *crenderer,
+ const graphene_point_t *point)
+{
+ gtk_snapshot_save (crenderer->fg_snapshot);
+ gtk_snapshot_save (crenderer->bg_snapshot);
+ gtk_snapshot_save (crenderer->selection_fg_snapshot);
+ gtk_snapshot_save (crenderer->selection_bg_snapshot);
+ gtk_snapshot_save (crenderer->cursors_snapshot);
+
+ gtk_snapshot_translate (crenderer->fg_snapshot, point);
+ gtk_snapshot_translate (crenderer->bg_snapshot, point);
+ gtk_snapshot_translate (crenderer->selection_fg_snapshot, point);
+ gtk_snapshot_translate (crenderer->selection_bg_snapshot, point);
+ gtk_snapshot_translate (crenderer->cursors_snapshot, point);
+}
+
+static void
+pop_translate (GskPangoRenderer *crenderer)
+{
+ gtk_snapshot_restore (crenderer->fg_snapshot);
+ gtk_snapshot_restore (crenderer->bg_snapshot);
+ gtk_snapshot_restore (crenderer->selection_fg_snapshot);
+ gtk_snapshot_restore (crenderer->selection_bg_snapshot);
+ gtk_snapshot_restore (crenderer->cursors_snapshot);
+}
+
static void
render_para (GskPangoRenderer *crenderer,
int offset_y,
@@ -3880,8 +3907,7 @@ render_para (GskPangoRenderer *crenderer,
gtk_style_context_restore (context);
}
- gtk_snapshot_save (crenderer->snapshot);
- gtk_snapshot_translate (crenderer->snapshot, &point);
+ push_translate (crenderer, &point);
do
{
@@ -3923,7 +3949,7 @@ render_para (GskPangoRenderer *crenderer,
if (selection_start_index < byte_offset &&
selection_end_index > line->length + byte_offset) /* All selected */
{
- gtk_snapshot_append_color (crenderer->snapshot,
+ gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
selection,
&GRAPHENE_RECT_INIT (line_display->left_margin,
selection_y,
@@ -3938,7 +3964,7 @@ render_para (GskPangoRenderer *crenderer,
else
{
if (line_display->pg_bg_rgba_set)
- gtk_snapshot_append_color (crenderer->snapshot,
+ gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
&line_display->pg_bg_rgba,
&GRAPHENE_RECT_INIT (line_display->left_margin,
selection_y,
@@ -3975,13 +4001,13 @@ render_para (GskPangoRenderer *crenderer,
bounds.size.width = PANGO_PIXELS (ranges[2*i + 1]) - PANGO_PIXELS (ranges[2*i]);
bounds.size.height = selection_height;
- gtk_snapshot_append_color (crenderer->snapshot, selection, &bounds);
- gtk_snapshot_push_clip (crenderer->snapshot, &bounds);
+ gtk_snapshot_append_color (crenderer->selection_bg_snapshot, selection, &bounds);
+ gtk_snapshot_push_clip (crenderer->selection_fg_snapshot, &bounds);
pango_renderer_draw_layout_line (PANGO_RENDERER (crenderer),
line,
line_rect.x,
baseline);
- gtk_snapshot_pop (crenderer->snapshot);
+ gtk_snapshot_pop (crenderer->selection_fg_snapshot);
}
g_free (ranges);
@@ -3990,7 +4016,7 @@ render_para (GskPangoRenderer *crenderer,
if (line_rect.x > line_display->left_margin * PANGO_SCALE &&
((line_display->direction == GTK_TEXT_DIR_LTR && selection_start_index < byte_offset) ||
(line_display->direction == GTK_TEXT_DIR_RTL && selection_end_index > byte_offset +
line->length)))
- gtk_snapshot_append_color (crenderer->snapshot,
+ gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
selection,
&GRAPHENE_RECT_INIT (line_display->left_margin,
selection_y,
@@ -4006,7 +4032,7 @@ render_para (GskPangoRenderer *crenderer,
+ screen_width
- PANGO_PIXELS (line_rect.x)
- PANGO_PIXELS (line_rect.width);
- gtk_snapshot_append_color (crenderer->snapshot,
+ gtk_snapshot_append_color (crenderer->selection_bg_snapshot,
selection,
&GRAPHENE_RECT_INIT (PANGO_PIXELS (line_rect.x) + PANGO_PIXELS
(line_rect.width),
selection_y,
@@ -4032,21 +4058,21 @@ render_para (GskPangoRenderer *crenderer,
* (normally white on black) */
_gtk_style_context_get_cursor_color (context, &cursor_color, NULL);
- gtk_snapshot_push_opacity (crenderer->snapshot, cursor_alpha);
- gtk_snapshot_append_color (crenderer->snapshot, &cursor_color, &bounds);
+ gtk_snapshot_push_opacity (crenderer->cursors_snapshot, cursor_alpha);
+ gtk_snapshot_append_color (crenderer->cursors_snapshot, &cursor_color, &bounds);
/* draw text under the cursor if any */
if (!line_display->cursor_at_line_end)
{
gsk_pango_renderer_set_state (crenderer, GSK_PANGO_RENDERER_CURSOR);
- gtk_snapshot_push_clip (crenderer->snapshot, &bounds);
+ gtk_snapshot_push_clip (crenderer->cursors_snapshot, &bounds);
pango_renderer_draw_layout_line (PANGO_RENDERER (crenderer),
line,
line_rect.x,
baseline);
- gtk_snapshot_pop (crenderer->snapshot);
+ gtk_snapshot_pop (crenderer->cursors_snapshot);
}
- gtk_snapshot_pop (crenderer->snapshot);
+ gtk_snapshot_pop (crenderer->cursors_snapshot);
}
}
@@ -4054,7 +4080,7 @@ render_para (GskPangoRenderer *crenderer,
}
while (pango_layout_iter_next_line (iter));
- gtk_snapshot_restore (crenderer->snapshot);
+ pop_translate (crenderer);
gdk_rgba_free (selection);
pango_layout_iter_free (iter);
@@ -4070,12 +4096,12 @@ gtk_text_layout_snapshot (GtkTextLayout *layout,
GtkTextLayoutPrivate *priv;
GskPangoRenderer *crenderer;
GtkStyleContext *context;
- gint offset_y;
GtkTextIter selection_start, selection_end;
gboolean have_selection;
GSList *line_list;
GSList *tmp_list;
GdkRGBA color;
+ gint offset_y;
g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
g_return_if_fail (layout->default_style != NULL);
@@ -4095,7 +4121,6 @@ gtk_text_layout_snapshot (GtkTextLayout *layout,
crenderer = gsk_pango_renderer_acquire ();
crenderer->widget = widget;
- crenderer->snapshot = snapshot;
crenderer->fg_color = color;
graphene_rect_init (&crenderer->bounds, 0, 0, clip->width, clip->height);
@@ -4157,7 +4182,7 @@ gtk_text_layout_snapshot (GtkTextLayout *layout,
{
int i;
- gtk_snapshot_push_opacity (crenderer->snapshot, cursor_alpha);
+ gtk_snapshot_push_opacity (crenderer->cursors_snapshot, cursor_alpha);
for (i = 0; i < line_display->cursors->len; i++)
{
int index;
@@ -4166,12 +4191,12 @@ gtk_text_layout_snapshot (GtkTextLayout *layout,
index = g_array_index(line_display->cursors, int, i);
dir = (line_display->direction == GTK_TEXT_DIR_RTL) ? PANGO_DIRECTION_RTL :
PANGO_DIRECTION_LTR;
- gtk_snapshot_render_insertion_cursor (crenderer->snapshot, context,
+ gtk_snapshot_render_insertion_cursor (crenderer->cursors_snapshot, context,
line_display->x_offset, offset_y +
line_display->top_margin,
line_display->layout, index, dir);
}
- gtk_snapshot_pop (crenderer->snapshot);
+ gtk_snapshot_pop (crenderer->cursors_snapshot);
}
} /* line_display->height > 0 */
@@ -4184,11 +4209,13 @@ gtk_text_layout_snapshot (GtkTextLayout *layout,
gtk_text_layout_wrap_loop_end (layout);
+ g_slist_free (line_list);
+
+ gsk_pango_renderer_apply (crenderer, snapshot);
+
/* Only update eviction source once per snapshot */
gtk_text_line_display_cache_delay_eviction (priv->cache);
- g_slist_free (line_list);
-
gsk_pango_renderer_release (crenderer);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]