summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2018-07-14 20:21:15 +0200
committerBenjamin Otte <otte@redhat.com>2018-07-24 20:55:45 +0200
commit51d40ca02372bcf242ed62f84a59d3b9152c4d8d (patch)
tree373192507b213e1bc26b039dafdfd71916f9cadd
parent5d9d73b0907cbffe53fdbb343d7f1702f28e4739 (diff)
downloadgtk+-51d40ca02372bcf242ed62f84a59d3b9152c4d8d.tar.gz
render: Make gtk_render_layout() use the snapshot API
This removes a lot of duplicated code.
-rw-r--r--gtk/gtkcssshadowsvalue.c15
-rw-r--r--gtk/gtkcssshadowsvalueprivate.h4
-rw-r--r--gtk/gtkcssshadowvalue.c137
-rw-r--r--gtk/gtkcssshadowvalueprivate.h4
-rw-r--r--gtk/gtkpango.c206
-rw-r--r--gtk/gtkpango.h4
-rw-r--r--gtk/gtkrender.c63
7 files changed, 14 insertions, 419 deletions
diff --git a/gtk/gtkcssshadowsvalue.c b/gtk/gtkcssshadowsvalue.c
index 729b879991..6aa4c50a93 100644
--- a/gtk/gtkcssshadowsvalue.c
+++ b/gtk/gtkcssshadowsvalue.c
@@ -288,21 +288,6 @@ gtk_css_shadows_value_get_shadows (const GtkCssValue *shadows,
}
void
-_gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
- cairo_t *cr,
- PangoLayout *layout)
-{
- guint i;
-
- g_return_if_fail (shadows->class == &GTK_CSS_VALUE_SHADOWS);
-
- for (i = 0; i < shadows->len; i++)
- {
- _gtk_css_shadow_value_paint_layout (shadows->values[i], cr, layout);
- }
-}
-
-void
_gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
cairo_t *cr)
{
diff --git a/gtk/gtkcssshadowsvalueprivate.h b/gtk/gtkcssshadowsvalueprivate.h
index 5bd78615f4..30eb4eebd9 100644
--- a/gtk/gtkcssshadowsvalueprivate.h
+++ b/gtk/gtkcssshadowsvalueprivate.h
@@ -41,10 +41,6 @@ gsize gtk_css_shadows_value_get_n_shadows (const GtkCssValue
void gtk_css_shadows_value_get_shadows (const GtkCssValue *shadows,
GskShadow *out_shadows);
-void _gtk_css_shadows_value_paint_layout (const GtkCssValue *shadows,
- cairo_t *cr,
- PangoLayout *layout);
-
void _gtk_css_shadows_value_paint_icon (const GtkCssValue *shadows,
cairo_t *cr);
diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c
index 62e0db7340..b57d6aa9f0 100644
--- a/gtk/gtkcssshadowvalue.c
+++ b/gtk/gtkcssshadowvalue.c
@@ -430,143 +430,6 @@ gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow,
return original_cr;
}
-static const cairo_user_data_key_t radius_key;
-static const cairo_user_data_key_t layout_serial_key;
-
-GQuark pango_cached_blurred_surface_quark (void);
-
-G_DEFINE_QUARK (GtkCssShadowValue pango_cached_blurred_surface, pango_cached_blurred_surface)
-
-static cairo_surface_t *
-get_cached_pango_surface (PangoLayout *layout,
- const GtkCssValue *shadow)
-{
- cairo_surface_t *cached_surface = g_object_get_qdata (G_OBJECT (layout), pango_cached_blurred_surface_quark ());
- guint cached_radius, cached_serial;
- guint radius, serial;
-
- if (!cached_surface)
- return NULL;
-
- radius = _gtk_css_number_value_get (shadow->radius, 0);
- cached_radius = GPOINTER_TO_UINT (cairo_surface_get_user_data (cached_surface, &radius_key));
- if (radius != cached_radius)
- return NULL;
-
- serial = pango_layout_get_serial (layout);
- cached_serial = GPOINTER_TO_UINT (cairo_surface_get_user_data (cached_surface, &layout_serial_key));
- if (serial != cached_serial)
- return NULL;
-
- return cached_surface;
-}
-
-static cairo_surface_t *
-make_blurred_pango_surface (cairo_t *existing_cr,
- PangoLayout *layout,
- const GtkCssValue *shadow)
-{
- cairo_surface_t *surface;
- cairo_t *cr;
- gdouble radius, clip_radius;
- gdouble x_scale, y_scale;
- PangoRectangle ink_rect;
-
- radius = _gtk_css_number_value_get (shadow->radius, 0);
-
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
- clip_radius = gsk_cairo_blur_compute_pixels (radius);
- x_scale = y_scale = 1;
- cairo_surface_get_device_scale (cairo_get_target (existing_cr), &x_scale, &y_scale);
-
- surface = cairo_surface_create_similar_image (cairo_get_target (existing_cr),
- CAIRO_FORMAT_A8,
- x_scale * (ink_rect.width + 2 * clip_radius),
- y_scale * (ink_rect.height + 2 * clip_radius));
- cairo_surface_set_device_scale (surface, x_scale, y_scale);
- cairo_surface_set_device_offset (surface, -ink_rect.x + clip_radius, -ink_rect.y + clip_radius);
- cr = cairo_create (surface);
- cairo_move_to (cr, 0, 0);
- _gtk_pango_fill_layout (cr, layout);
- gsk_cairo_blur_surface (surface, radius * x_scale, GSK_BLUR_X | GSK_BLUR_Y);
-
- cairo_destroy (cr);
-
- return surface;
-}
-
-static cairo_surface_t *
-get_blurred_pango_surface (cairo_t *cr,
- PangoLayout *layout,
- const GtkCssValue *shadow)
-{
- cairo_surface_t *surface;
- guint radius, serial;
-
- surface = get_cached_pango_surface (layout, shadow);
- if (!surface)
- {
- surface = make_blurred_pango_surface (cr, layout, shadow);
-
- /* Cache the surface on the PangoLayout */
- radius = _gtk_css_number_value_get (shadow->radius, 0);
- cairo_surface_set_user_data (surface, &radius_key, GUINT_TO_POINTER (radius), NULL);
-
- serial = pango_layout_get_serial (layout);
- cairo_surface_set_user_data (surface, &layout_serial_key, GUINT_TO_POINTER (serial), NULL);
-
- g_object_set_qdata_full (G_OBJECT (layout), pango_cached_blurred_surface_quark (),
- surface, (GDestroyNotify) cairo_surface_destroy);
- }
-
- return surface;
-}
-
-void
-_gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
- cairo_t *cr,
- PangoLayout *layout)
-{
- g_return_if_fail (shadow->class == &GTK_CSS_VALUE_SHADOW);
-
- /* We don't need to draw invisible shadows */
- if (gdk_rgba_is_clear (_gtk_css_rgba_value_get_rgba (shadow->color)))
- return;
-
- if (!cairo_has_current_point (cr))
- cairo_move_to (cr, 0, 0);
-
- cairo_save (cr);
-
- if (needs_blur (shadow))
- {
- cairo_surface_t *blurred_surface = get_blurred_pango_surface (cr, layout, shadow);
- double x, y;
- cairo_get_current_point (cr, &x, &y);
- cairo_translate (cr, x, y);
- cairo_translate (cr,
- _gtk_css_number_value_get (shadow->hoffset, 0),
- _gtk_css_number_value_get (shadow->voffset, 0));
-
- gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
- cairo_mask_surface (cr, blurred_surface, 0, 0);
- }
- else
- {
- /* The no blur case -- just paint directly. */
- cairo_rel_move_to (cr,
- _gtk_css_number_value_get (shadow->hoffset, 0),
- _gtk_css_number_value_get (shadow->voffset, 0));
- gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
- _gtk_pango_fill_layout (cr, layout);
- cairo_rel_move_to (cr,
- - _gtk_css_number_value_get (shadow->hoffset, 0),
- - _gtk_css_number_value_get (shadow->voffset, 0));
- }
-
- cairo_restore (cr);
-}
-
void
_gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
cairo_t *cr)
diff --git a/gtk/gtkcssshadowvalueprivate.h b/gtk/gtkcssshadowvalueprivate.h
index e3113d106a..b04beea986 100644
--- a/gtk/gtkcssshadowvalueprivate.h
+++ b/gtk/gtkcssshadowvalueprivate.h
@@ -42,10 +42,6 @@ void gtk_css_shadow_value_get_extents (const GtkCssValue
void gtk_css_shadow_value_get_shadow (const GtkCssValue *value,
GskShadow *shadow);
-void _gtk_css_shadow_value_paint_layout (const GtkCssValue *shadow,
- cairo_t *cr,
- PangoLayout *layout);
-
void _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
cairo_t *cr);
void _gtk_css_shadow_value_paint_box (const GtkCssValue *shadow,
diff --git a/gtk/gtkpango.c b/gtk/gtkpango.c
index 2c87e8cb65..1f6e70954a 100644
--- a/gtk/gtkpango.c
+++ b/gtk/gtkpango.c
@@ -27,212 +27,6 @@
#include <pango/pangocairo.h>
#include "gtkintl.h"
-#define GTK_TYPE_FILL_LAYOUT_RENDERER (_gtk_fill_layout_renderer_get_type())
-#define GTK_FILL_LAYOUT_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GTK_TYPE_FILL_LAYOUT_RENDERER, GtkFillLayoutRenderer))
-#define GTK_IS_FILL_LAYOUT_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_FILL_LAYOUT_RENDERER))
-#define GTK_FILL_LAYOUT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_FILL_LAYOUT_RENDERER, GtkFillLayoutRendererClass))
-#define GTK_IS_FILL_LAYOUT_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_FILL_LAYOUT_RENDERER))
-#define GTK_FILL_LAYOUT_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_FILL_LAYOUT_RENDERER, GtkFillLayoutRendererClass))
-
-typedef struct _GtkFillLayoutRenderer GtkFillLayoutRenderer;
-typedef struct _GtkFillLayoutRendererClass GtkFillLayoutRendererClass;
-
-struct _GtkFillLayoutRenderer
-{
- PangoRenderer parent_instance;
-
- cairo_t *cr;
-};
-
-struct _GtkFillLayoutRendererClass
-{
- PangoRendererClass parent_class;
-};
-
-GType _gtk_fill_layout_renderer_get_type (void);
-
-G_DEFINE_TYPE (GtkFillLayoutRenderer, _gtk_fill_layout_renderer, PANGO_TYPE_RENDERER)
-
-static void
-gtk_fill_layout_renderer_draw_glyphs (PangoRenderer *renderer,
- PangoFont *font,
- PangoGlyphString *glyphs,
- int x,
- int y)
-{
- GtkFillLayoutRenderer *text_renderer = GTK_FILL_LAYOUT_RENDERER (renderer);
-
- cairo_move_to (text_renderer->cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
- pango_cairo_show_glyph_string (text_renderer->cr, font, glyphs);
-}
-
-static void
-gtk_fill_layout_renderer_draw_glyph_item (PangoRenderer *renderer,
- const char *text,
- PangoGlyphItem *glyph_item,
- int x,
- int y)
-{
- GtkFillLayoutRenderer *text_renderer = GTK_FILL_LAYOUT_RENDERER (renderer);
-
- cairo_move_to (text_renderer->cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
- pango_cairo_show_glyph_item (text_renderer->cr, text, glyph_item);
-}
-
-static void
-gtk_fill_layout_renderer_draw_rectangle (PangoRenderer *renderer,
- PangoRenderPart part,
- int x,
- int y,
- int width,
- int height)
-{
- GtkFillLayoutRenderer *text_renderer = GTK_FILL_LAYOUT_RENDERER (renderer);
-
- if (part == PANGO_RENDER_PART_BACKGROUND)
- return;
-
- cairo_rectangle (text_renderer->cr,
- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
- cairo_fill (text_renderer->cr);
-}
-
-static void
-gtk_fill_layout_renderer_draw_trapezoid (PangoRenderer *renderer,
- PangoRenderPart part,
- double y1_,
- double x11,
- double x21,
- double y2,
- double x12,
- double x22)
-{
- GtkFillLayoutRenderer *text_renderer = GTK_FILL_LAYOUT_RENDERER (renderer);
- cairo_matrix_t matrix;
- cairo_t *cr;
-
- cr = text_renderer->cr;
-
- cairo_save (cr);
-
- /* use identity scale, but keep translation */
- cairo_get_matrix (cr, &matrix);
- matrix.xx = matrix.yy = 1;
- matrix.xy = matrix.yx = 0;
- cairo_set_matrix (cr, &matrix);
-
- cairo_move_to (cr, x11, y1_);
- cairo_line_to (cr, x21, y1_);
- cairo_line_to (cr, x22, y2);
- cairo_line_to (cr, x12, y2);
- cairo_close_path (cr);
-
- cairo_fill (cr);
-
- cairo_restore (cr);
-}
-
-static void
-gtk_fill_layout_renderer_draw_error_underline (PangoRenderer *renderer,
- int x,
- int y,
- int width,
- int height)
-{
- GtkFillLayoutRenderer *text_renderer = GTK_FILL_LAYOUT_RENDERER (renderer);
-
- pango_cairo_show_error_underline (text_renderer->cr,
- (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
-}
-
-static void
-gtk_fill_layout_renderer_draw_shape (PangoRenderer *renderer,
- PangoAttrShape *attr,
- int x,
- int y)
-{
- GtkFillLayoutRenderer *text_renderer = GTK_FILL_LAYOUT_RENDERER (renderer);
- cairo_t *cr = text_renderer->cr;
- PangoLayout *layout;
- PangoCairoShapeRendererFunc shape_renderer;
- gpointer shape_renderer_data;
-
- layout = pango_renderer_get_layout (renderer);
-
- if (!layout)
- return;
-
- shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout),
- &shape_renderer_data);
-
- if (!shape_renderer)
- return;
-
- cairo_save (cr);
-
- cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE);
-
- shape_renderer (cr, attr, FALSE, shape_renderer_data);
-
- cairo_restore (cr);
-}
-
-static void
-gtk_fill_layout_renderer_finalize (GObject *object)
-{
- G_OBJECT_CLASS (_gtk_fill_layout_renderer_parent_class)->finalize (object);
-}
-
-static void
-_gtk_fill_layout_renderer_init (GtkFillLayoutRenderer *renderer)
-{
-}
-
-static void
-_gtk_fill_layout_renderer_class_init (GtkFillLayoutRendererClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
-
- renderer_class->draw_glyphs = gtk_fill_layout_renderer_draw_glyphs;
- renderer_class->draw_glyph_item = gtk_fill_layout_renderer_draw_glyph_item;
- renderer_class->draw_rectangle = gtk_fill_layout_renderer_draw_rectangle;
- renderer_class->draw_trapezoid = gtk_fill_layout_renderer_draw_trapezoid;
- renderer_class->draw_error_underline = gtk_fill_layout_renderer_draw_error_underline;
- renderer_class->draw_shape = gtk_fill_layout_renderer_draw_shape;
-
- object_class->finalize = gtk_fill_layout_renderer_finalize;
-}
-
-void
-_gtk_pango_fill_layout (cairo_t *cr,
- PangoLayout *layout)
-{
- static GtkFillLayoutRenderer *renderer = NULL;
- gboolean has_current_point;
- double current_x, current_y;
-
- has_current_point = cairo_has_current_point (cr);
- cairo_get_current_point (cr, &current_x, &current_y);
-
- if (renderer == NULL)
- renderer = g_object_new (GTK_TYPE_FILL_LAYOUT_RENDERER, NULL);
-
- cairo_save (cr);
- cairo_translate (cr, current_x, current_y);
-
- renderer->cr = cr;
- pango_renderer_draw_layout (PANGO_RENDERER (renderer), layout, 0, 0);
-
- cairo_restore (cr);
-
- if (has_current_point)
- cairo_move_to (cr, current_x, current_y);
-}
-
static AtkAttributeSet *
add_attribute (AtkAttributeSet *attributes,
AtkTextAttribute attr,
diff --git a/gtk/gtkpango.h b/gtk/gtkpango.h
index 216f928e8b..09c50b8731 100644
--- a/gtk/gtkpango.h
+++ b/gtk/gtkpango.h
@@ -31,10 +31,6 @@
G_BEGIN_DECLS
-void _gtk_pango_fill_layout (cairo_t *cr,
- PangoLayout *layout);
-
-
AtkAttributeSet *_gtk_pango_get_default_attributes (AtkAttributeSet *attributes,
PangoLayout *layout);
diff --git a/gtk/gtkrender.c b/gtk/gtkrender.c
index 3c90bb03d2..ae772a7f91 100644
--- a/gtk/gtkrender.c
+++ b/gtk/gtkrender.c
@@ -427,54 +427,6 @@ gtk_render_focus (GtkStyleContext *context,
x, y, width, height);
}
-static void
-prepare_context_for_layout (cairo_t *cr,
- gdouble x,
- gdouble y,
- PangoLayout *layout)
-{
- const PangoMatrix *matrix;
-
- matrix = pango_context_get_matrix (pango_layout_get_context (layout));
-
- cairo_move_to (cr, x, y);
-
- if (matrix)
- {
- cairo_matrix_t cairo_matrix;
-
- cairo_matrix_init (&cairo_matrix,
- matrix->xx, matrix->yx,
- matrix->xy, matrix->yy,
- matrix->x0, matrix->y0);
-
- cairo_transform (cr, &cairo_matrix);
- }
-}
-
-static void
-gtk_do_render_layout (GtkStyleContext *context,
- cairo_t *cr,
- gdouble x,
- gdouble y,
- PangoLayout *layout)
-{
- const GdkRGBA *fg_color;
-
- cairo_save (cr);
- fg_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_COLOR));
-
- prepare_context_for_layout (cr, x, y, layout);
-
- _gtk_css_shadows_value_paint_layout (_gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_SHADOW),
- cr, layout);
-
- gdk_cairo_set_source_rgba (cr, fg_color);
- pango_cairo_show_layout (cr, layout);
-
- cairo_restore (cr);
-}
-
/**
* gtk_render_layout:
* @context: a #GtkStyleContext
@@ -492,11 +444,24 @@ gtk_render_layout (GtkStyleContext *context,
gdouble y,
PangoLayout *layout)
{
+ GtkSnapshot *snapshot;
+ GskRenderNode *node;
+
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (PANGO_IS_LAYOUT (layout));
g_return_if_fail (cr != NULL);
- gtk_do_render_layout (context, cr, x, y, layout);
+ snapshot = gtk_snapshot_new ();
+ gtk_snapshot_render_layout (snapshot, context, x, y, layout);
+ node = gtk_snapshot_free_to_node (snapshot);
+ if (node == NULL)
+ return;
+
+ cairo_save (cr);
+ gsk_render_node_draw (node, cr);
+ cairo_restore (cr);
+
+ gsk_render_node_unref (node);
}
static void