[gtk+/wip/matthiasc/gskpango: 1/4] Move node creation into the renderer
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/gskpango: 1/4] Move node creation into the renderer
- Date: Fri, 1 Sep 2017 02:32:08 +0000 (UTC)
commit 2f0518674eea342abc277a033d01e149e2f88a98
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Aug 30 13:52:40 2017 -0400
Move node creation into the renderer
Create a cairo node for each show_text_glyphs call.
gtk/gskpango.c | 575 ++++++++++++-----------------------------------------
gtk/gskpango.h | 8 +-
gtk/gtksnapshot.c | 39 ++--
3 files changed, 157 insertions(+), 465 deletions(-)
---
diff --git a/gtk/gskpango.c b/gtk/gskpango.c
index 643af01..f63179f 100644
--- a/gtk/gskpango.c
+++ b/gtk/gskpango.c
@@ -19,6 +19,7 @@
#include "config.h"
+#include "gsk/gsk.h"
#include "gskpango.h"
#include <math.h>
@@ -26,21 +27,6 @@
#include <pango/pango.h>
#include <cairo/cairo.h>
-typedef struct _PangoCairoFontHexBoxInfo PangoCairoFontHexBoxInfo;
-
-struct _PangoCairoFontHexBoxInfo
-{
- PangoCairoFont *font;
- int rows;
- double digit_width;
- double digit_height;
- double pad_x;
- double pad_y;
- double line_width;
- double box_descent;
- double box_height;
-};
-
#define GSK_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_PANGO_RENDERER,
GskPangoRendererClass))
#define GSK_IS_PANGO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_PANGO_RENDERER))
#define GSK_PANGO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_PANGO_RENDERER,
GskPangoRendererClass))
@@ -49,14 +35,13 @@ struct _GskPangoRenderer
{
PangoRenderer parent_instance;
- cairo_t *cr;
- gboolean do_path;
- gboolean has_show_text_glyphs;
+ GtkSnapshot *snapshot;
+ const GdkRGBA *fg_color;
double x_offset, y_offset;
+ graphene_rect_t bounds;
/* house-keeping options */
gboolean is_cached_renderer;
- gboolean cr_had_current_point;
};
struct _GskPangoRendererClass
@@ -66,16 +51,17 @@ struct _GskPangoRendererClass
G_DEFINE_TYPE (GskPangoRenderer, gsk_pango_renderer, PANGO_TYPE_RENDERER)
-static void
-set_color (GskPangoRenderer *crenderer,
- PangoRenderPart part)
+static gboolean
+get_color (GskPangoRenderer *crenderer,
+ PangoRenderPart part,
+ GdkRGBA *rgba)
{
PangoColor *color = pango_renderer_get_color ((PangoRenderer *) (crenderer), part);
guint16 a = pango_renderer_get_alpha ((PangoRenderer *) (crenderer), part);
gdouble red, green, blue, alpha;
if (!a && !color)
- return;
+ return FALSE;
if (color)
{
@@ -85,158 +71,31 @@ set_color (GskPangoRenderer *crenderer,
alpha = 1.;
}
else
- {
- cairo_pattern_t *pattern = cairo_get_source (crenderer->cr);
-
- if (pattern && cairo_pattern_get_type (pattern) == CAIRO_PATTERN_TYPE_SOLID)
- cairo_pattern_get_rgba (pattern, &red, &green, &blue, &alpha);
- else
- {
- red = 0.;
- green = 0.;
- blue = 0.;
- alpha = 1.;
- }
- }
+ return FALSE;
if (a)
alpha = a / 65535.;
- cairo_set_source_rgba (crenderer->cr, red, green, blue, alpha);
-}
-
-#if 0
-/* note: modifies crenderer->cr without doing cairo_save/restore() */
-static void
-gsk_pango_renderer_draw_frame (GskPangoRenderer *crenderer,
- double x,
- double y,
- double width,
- double height,
- double line_width,
- gboolean invalid)
-{
- cairo_t *cr = crenderer->cr;
-
- if (crenderer->do_path)
- {
- double d2 = line_width * .5, d = line_width;
-
- /* we draw an outer box in one winding direction and an inner one in the
- * opposite direction. This works for both cairo windings rules.
- *
- * what we really want is cairo_stroke_to_path(), but that's not
- * implemented in cairo yet.
- */
-
- /* outer */
- cairo_rectangle (cr, x-d2, y-d2, width+d, height+d);
+ rgba->red = red;
+ rgba->green = green;
+ rgba->blue = blue;
+ rgba->alpha = alpha;
- /* inner */
- if (invalid)
- {
- /* delicacies of computing the joint... this is REALLY slow */
-
- double alpha, tan_alpha2, cos_alpha;
- double sx, sy;
-
- alpha = atan2 (height, width);
-
- tan_alpha2 = tan (alpha * .5);
- if (tan_alpha2 < 1e-5 || (sx = d2 / tan_alpha2, 2. * sx > width - d))
- sx = (width - d) * .5;
-
- cos_alpha = cos (alpha);
- if (cos_alpha < 1e-5 || (sy = d2 / cos_alpha, 2. * sy > height - d))
- sy = (height - d) * .5;
-
- /* top triangle */
- cairo_new_sub_path (cr);
- cairo_line_to (cr, x+width-sx, y+d2);
- cairo_line_to (cr, x+sx, y+d2);
- cairo_line_to (cr, x+.5*width, y+.5*height-sy);
- cairo_close_path (cr);
-
- /* bottom triangle */
- cairo_new_sub_path (cr);
- cairo_line_to (cr, x+width-sx, y+height-d2);
- cairo_line_to (cr, x+.5*width, y+.5*height+sy);
- cairo_line_to (cr, x+sx, y+height-d2);
- cairo_close_path (cr);
-
-
- alpha = G_PI_2 - alpha;
- tan_alpha2 = tan (alpha * .5);
- if (tan_alpha2 < 1e-5 || (sy = d2 / tan_alpha2, 2. * sy > height - d))
- sy = (height - d) * .5;
-
- cos_alpha = cos (alpha);
- if (cos_alpha < 1e-5 || (sx = d2 / cos_alpha, 2. * sx > width - d))
- sx = (width - d) * .5;
-
- /* left triangle */
- cairo_new_sub_path (cr);
- cairo_line_to (cr, x+d2, y+sy);
- cairo_line_to (cr, x+d2, y+height-sy);
- cairo_line_to (cr, x+.5*width-sx, y+.5*height);
- cairo_close_path (cr);
-
- /* right triangle */
- cairo_new_sub_path (cr);
- cairo_line_to (cr, x+width-d2, y+sy);
- cairo_line_to (cr, x+.5*width+sx, y+.5*height);
- cairo_line_to (cr, x+width-d2, y+height-sy);
- cairo_close_path (cr);
- }
- else
- cairo_rectangle (cr, x+width-d2, y+d2, - (width-d), height-d);
- }
- else
- {
- cairo_rectangle (cr, x, y, width, height);
-
- if (invalid)
- {
- /* draw an X */
-
- cairo_new_sub_path (cr);
- cairo_move_to (cr, x, y);
- cairo_rel_line_to (cr, width, height);
-
- cairo_new_sub_path (cr);
- cairo_move_to (cr, x + width, y);
- cairo_rel_line_to (cr, -width, height);
-
- cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
- }
-
- cairo_set_line_width (cr, line_width);
- cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
- cairo_set_miter_limit (cr, 2.);
- cairo_stroke (cr);
- }
+ return TRUE;
}
static void
-gsk_pango_renderer_draw_box_glyph (GskPangoRenderer *crenderer,
- PangoGlyphInfo *gi,
- double cx,
- double cy,
- gboolean invalid)
+set_color (GskPangoRenderer *crenderer,
+ PangoRenderPart part,
+ cairo_t *cr)
{
- cairo_save (crenderer->cr);
-
- gsk_pango_renderer_draw_frame (crenderer,
- cx + 1.5,
- cy + 1.5 - PANGO_UNKNOWN_GLYPH_HEIGHT,
- (double)gi->geometry.width / PANGO_SCALE - 3.0,
- PANGO_UNKNOWN_GLYPH_HEIGHT - 3.0,
- 1.0,
- invalid);
+ GdkRGBA rgba = { 0, 0, 0, 1 };
- cairo_restore (crenderer->cr);
+ if (get_color (crenderer, part, &rgba))
+ gdk_cairo_set_source_rgba (cr, &rgba);
+ else
+ gdk_cairo_set_source_rgba (cr, crenderer->fg_color);
}
-#endif
static gboolean
_pango_cairo_font_install (PangoFont *font,
@@ -254,84 +113,27 @@ _pango_cairo_font_install (PangoFont *font,
static void
gsk_pango_renderer_draw_unknown_glyph (GskPangoRenderer *crenderer,
- PangoFont *font,
- PangoGlyphInfo *gi,
- double cx,
- double cy)
+ PangoFont *font,
+ PangoGlyphInfo *gi,
+ double cx,
+ double cy)
{
-#if 0
- char buf[7];
- double x0, y0;
- int row, col;
- int rows, cols;
- double width, lsb;
- char hexbox_string[2] = {0, 0};
- PangoCairoFontHexBoxInfo *hbi;
- gunichar ch;
- gboolean invalid_input;
-
- cairo_save (crenderer->cr);
-
- ch = gi->glyph & ~PANGO_GLYPH_UNKNOWN_FLAG;
- invalid_input = G_UNLIKELY (gi->glyph == PANGO_GLYPH_INVALID_INPUT || ch > 0x10FFFF);
-
- hbi = pango_cairo_font_get_hex_box_info ((PangoCairoFont *)font);
- if (!hbi || !_pango_cairo_font_install ((PangoFont *)(hbi->font), crenderer->cr))
- {
- gsk_pango_renderer_draw_box_glyph (crenderer, gi, cx, cy, invalid_input);
- goto done;
- }
-
- rows = hbi->rows;
- if (G_UNLIKELY (invalid_input))
- {
- cols = 1;
- }
- else
- {
- cols = (ch > 0xffff ? 6 : 4) / rows;
- g_snprintf (buf, sizeof(buf), (ch > 0xffff) ? "%06X" : "%04X", ch);
- }
+ cairo_t *cr;
+ PangoGlyphString *glyphs;
- width = (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));
- lsb = ((double)gi->geometry.width / PANGO_SCALE - width) * .5;
- lsb = floor (lsb / hbi->pad_x) * hbi->pad_x;
+ cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawUnknownGlyph<%u>",
gi->glyph);
- gsk_pango_renderer_draw_frame (crenderer,
- cx + lsb + .5 * hbi->pad_x,
- cy + hbi->box_descent - hbi->box_height + hbi->pad_y * 0.5,
- width - hbi->pad_x,
- (hbi->box_height - hbi->pad_y),
- hbi->line_width,
- invalid_input);
+ gdk_cairo_set_source_rgba (cr, crenderer->fg_color);
- if (invalid_input)
- goto done;
+ cairo_move_to (cr, cx, cy);
- x0 = cx + lsb + hbi->pad_x * 2;
- y0 = cy + hbi->box_descent - hbi->pad_y * 2;
+ glyphs = pango_glyph_string_new ();
+ pango_glyph_string_set_size (glyphs, 1);
+ glyphs->glyphs[0] = *gi;
- for (row = 0; row < rows; row++)
- {
- double y = y0 - (rows - 1 - row) * (hbi->digit_height + hbi->pad_y);
- for (col = 0; col < cols; col++)
- {
- double x = x0 + col * (hbi->digit_width + hbi->pad_x);
+ pango_cairo_show_glyph_string (cr, font, glyphs);
- cairo_move_to (crenderer->cr, x, y);
-
- hexbox_string[0] = buf[row * cols + col];
-
- if (crenderer->do_path)
- cairo_text_path (crenderer->cr, hexbox_string);
- else
- cairo_show_text (crenderer->cr, hexbox_string);
- }
- }
-
-done:
- cairo_restore (crenderer->cr);
-#endif
+ cairo_destroy (cr);
}
#ifndef STACK_BUFFER_SIZE
@@ -354,6 +156,7 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+ cairo_t *cr;
int i, count;
int x_position = 0;
cairo_glyph_t *cairo_glyphs;
@@ -361,11 +164,11 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
- cairo_save (crenderer->cr);
- if (!crenderer->do_path)
- set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
+ cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "Text<%dglyphs>",
glyphs->num_glyphs);
+
+ set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
- if (!_pango_cairo_font_install (font, crenderer->cr))
+ if (!_pango_cairo_font_install (font, cr))
{
for (i = 0; i < glyphs->num_glyphs; i++)
{
@@ -416,39 +219,30 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
x_position += gi->geometry.width;
}
- if (G_UNLIKELY (crenderer->do_path))
- cairo_glyph_path (crenderer->cr, cairo_glyphs, count);
+ if (G_UNLIKELY (clusters))
+ cairo_show_text_glyphs (cr,
+ text, text_len,
+ cairo_glyphs, count,
+ clusters, num_clusters,
+ backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : 0);
else
- if (G_UNLIKELY (clusters))
- cairo_show_text_glyphs (crenderer->cr,
- text, text_len,
- cairo_glyphs, count,
- clusters, num_clusters,
- backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : 0);
- else
- cairo_show_glyphs (crenderer->cr, cairo_glyphs, count);
+ cairo_show_glyphs (cr, cairo_glyphs, count);
if (cairo_glyphs != stack_glyphs)
g_free (cairo_glyphs);
done:
- cairo_restore (crenderer->cr);
+ cairo_destroy (cr);
}
static void
-gsk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
- PangoFont *font,
- PangoGlyphString *glyphs,
- int x,
- int y)
+gsk_pango_renderer_draw_glyphs (PangoRenderer *renderer,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ int x,
+ int y)
{
- gsk_pango_renderer_show_text_glyphs (renderer,
- NULL, 0,
- glyphs,
- NULL, 0,
- FALSE,
- font,
- x, y);
+ gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
}
static void
@@ -458,128 +252,52 @@ gsk_pango_renderer_draw_glyph_item (PangoRenderer *renderer,
int x,
int y)
{
- GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
- PangoFont *font = glyph_item->item->analysis.font;
- PangoGlyphString *glyphs = glyph_item->glyphs;
- PangoItem *item = glyph_item->item;
- gboolean backward = (item->analysis.level & 1) != 0;
-
- PangoGlyphItemIter iter;
- cairo_text_cluster_t *cairo_clusters;
- cairo_text_cluster_t stack_clusters[STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
- int num_clusters;
-
- if (!crenderer->has_show_text_glyphs || crenderer->do_path)
- {
- gsk_pango_renderer_show_text_glyphs (renderer,
- NULL, 0,
- glyphs,
- NULL, 0,
- FALSE,
- font,
- x, y);
- return;
- }
-
- if (glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_clusters))
- cairo_clusters = g_new (cairo_text_cluster_t, glyphs->num_glyphs);
- else
- cairo_clusters = stack_clusters;
+ PangoFont *font = glyph_item->item->analysis.font;
+ PangoGlyphString *glyphs = glyph_item->glyphs;
- num_clusters = 0;
- if (pango_glyph_item_iter_init_start (&iter, glyph_item, text))
- {
- do {
- int num_bytes, num_glyphs, i;
-
- num_bytes = iter.end_index - iter.start_index;
- num_glyphs = backward ? iter.start_glyph - iter.end_glyph : iter.end_glyph - iter.start_glyph;
-
- if (num_bytes < 1)
- g_warning ("gsk_pango_renderer_draw_glyph_item: bad cluster has num_bytes %d", num_bytes);
- if (num_glyphs < 1)
- g_warning ("gsk_pango_renderer_draw_glyph_item: bad cluster has num_glyphs %d", num_glyphs);
-
- /* Discount empty and unknown glyphs */
- for (i = MIN (iter.start_glyph, iter.end_glyph+1);
- i < MAX (iter.start_glyph+1, iter.end_glyph);
- i++)
- {
- PangoGlyphInfo *gi = &glyphs->glyphs[i];
-
- if (gi->glyph == PANGO_GLYPH_EMPTY ||
- gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
- num_glyphs--;
- }
-
- cairo_clusters[num_clusters].num_bytes = num_bytes;
- cairo_clusters[num_clusters].num_glyphs = num_glyphs;
- num_clusters++;
- } while (pango_glyph_item_iter_next_cluster (&iter));
- }
-
- gsk_pango_renderer_show_text_glyphs (renderer,
- text + item->offset, item->length,
- glyphs,
- cairo_clusters, num_clusters,
- backward,
- font,
- x, y);
-
- if (cairo_clusters != stack_clusters)
- g_free (cairo_clusters);
+ gsk_pango_renderer_show_text_glyphs (renderer, NULL, 0, glyphs, NULL, 0, FALSE, font, x, y);
}
static void
gsk_pango_renderer_draw_rectangle (PangoRenderer *renderer,
- PangoRenderPart part,
- int x,
- int y,
- int width,
- int height)
+ PangoRenderPart part,
+ int x,
+ int y,
+ int width,
+ int height)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
+ GdkRGBA rgba;
+ graphene_rect_t bounds;
- if (!crenderer->do_path)
- {
- cairo_save (crenderer->cr);
-
- set_color (crenderer, part);
- }
-
- cairo_rectangle (crenderer->cr,
- crenderer->x_offset + (double)x / PANGO_SCALE,
- crenderer->y_offset + (double)y / PANGO_SCALE,
- (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+ if (!get_color (crenderer, part, &rgba))
+ rgba = *crenderer->fg_color;
- if (!crenderer->do_path)
- {
- cairo_fill (crenderer->cr);
+ graphene_rect_init (&bounds,
+ crenderer->x_offset + (double)x / PANGO_SCALE,
+ crenderer->y_offset + (double)y / PANGO_SCALE,
+ (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
- cairo_restore (crenderer->cr);
- }
+ gtk_snapshot_append_color (crenderer->snapshot, &rgba, &bounds, "DrawRectangle");
}
static void
-gsk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
- PangoRenderPart part,
- double y1_,
- double x11,
- double x21,
- double y2,
- double x12,
- double x22)
+gsk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
+ PangoRenderPart part,
+ double y1_,
+ double x11,
+ double x21,
+ double y2,
+ double x12,
+ double x22)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
cairo_t *cr;
- double x, y;
-
- cr = crenderer->cr;
+ gdouble x, y;
- cairo_save (cr);
+ cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawTrapezoid");
- if (!crenderer->do_path)
- set_color (crenderer, part);
+ set_color (crenderer, part, cr);
x = crenderer->x_offset,
y = crenderer->y_offset;
@@ -593,10 +311,9 @@ gsk_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
cairo_line_to (cr, x12, y2);
cairo_close_path (cr);
- if (!crenderer->do_path)
- cairo_fill (cr);
+ cairo_fill (cr);
- cairo_restore (cr);
+ cairo_destroy (cr);
}
/* Draws an error underline that looks like one of:
@@ -674,56 +391,54 @@ draw_error_underline (cairo_t *cr,
static void
gsk_pango_renderer_draw_error_underline (PangoRenderer *renderer,
- int x,
- int y,
- int width,
- int height)
+ int x,
+ int y,
+ int width,
+ int height)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
- cairo_t *cr = crenderer->cr;
+ cairo_t *cr;
+ GdkRGBA rgba = { 0, 0, 0, 1 };
- if (!crenderer->do_path)
- {
- cairo_save (cr);
+ cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawTrapezoid");
- set_color (crenderer, PANGO_RENDER_PART_UNDERLINE);
+ if (get_color (crenderer, PANGO_RENDER_PART_UNDERLINE, &rgba))
+ gdk_cairo_set_source_rgba (cr, &rgba);
+ else
+ gdk_cairo_set_source_rgba (cr, crenderer->fg_color);
- cairo_new_path (cr);
- }
+ cairo_new_path (cr);
draw_error_underline (cr,
crenderer->x_offset + (double)x / PANGO_SCALE,
crenderer->y_offset + (double)y / PANGO_SCALE,
(double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
- if (!crenderer->do_path)
- {
- cairo_fill (cr);
+ cairo_fill (cr);
- cairo_restore (cr);
- }
+ cairo_destroy (cr);
}
static void
gsk_pango_renderer_draw_shape (PangoRenderer *renderer,
- PangoAttrShape *attr,
- int x,
- int y)
+ PangoAttrShape *attr,
+ int x,
+ int y)
{
-#if 0
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
- cairo_t *cr = crenderer->cr;
+ cairo_t *cr;
PangoLayout *layout;
- GskPangoShapeRendererFunc shape_renderer;
- gpointer shape_renderer_data;
+ PangoCairoShapeRendererFunc shape_renderer;
+ gpointer shape_renderer_data;
double base_x, base_y;
- layout = pango_renderer_get_layout (renderer);
+ cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawShape");
+ layout = pango_renderer_get_layout (renderer);
if (!layout)
- return;
+ return;
- shape_renderer = gsk_pango_context_get_shape_renderer (pango_layout_get_context (layout),
+ shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout),
&shape_renderer_data);
if (!shape_renderer)
@@ -732,16 +447,13 @@ gsk_pango_renderer_draw_shape (PangoRenderer *renderer,
base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
- cairo_save (cr);
- if (!crenderer->do_path)
- set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
+ set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
cairo_move_to (cr, base_x, base_y);
- shape_renderer (cr, attr, crenderer->do_path, shape_renderer_data);
+ shape_renderer (cr, attr, FALSE, shape_renderer_data);
- cairo_restore (cr);
-#endif
+ cairo_destroy (cr);
}
static void
@@ -793,9 +505,7 @@ release_renderer (GskPangoRenderer *renderer)
{
if (G_LIKELY (renderer->is_cached_renderer))
{
- renderer->cr = NULL;
- renderer->do_path = FALSE;
- renderer->has_show_text_glyphs = FALSE;
+ renderer->snapshot = NULL;
renderer->x_offset = 0.;
renderer->y_offset = 0.;
@@ -805,54 +515,29 @@ release_renderer (GskPangoRenderer *renderer)
g_object_unref (renderer);
}
-static void
-save_current_point (GskPangoRenderer *renderer)
-{
- renderer->cr_had_current_point = cairo_has_current_point (renderer->cr);
- cairo_get_current_point (renderer->cr, &renderer->x_offset, &renderer->y_offset);
-
- /* abuse save_current_point() to cache cairo_has_show_text_glyphs() result */
- renderer->has_show_text_glyphs = cairo_surface_has_show_text_glyphs (cairo_get_target (renderer->cr));
-}
-
-static void
-restore_current_point (GskPangoRenderer *renderer)
-{
- if (renderer->cr_had_current_point)
- /* XXX should do cairo_set_current_point() when we have that function */
- cairo_move_to (renderer->cr, renderer->x_offset, renderer->y_offset);
- else
- cairo_new_sub_path (renderer->cr);
-}
-
-
/* convenience wrappers using the default renderer */
-static void
-gsk_pango_do_layout (cairo_t *cr,
- PangoLayout *layout,
- gboolean do_path)
+void
+gsk_pango_show_layout (GtkSnapshot *snapshot,
+ const GdkRGBA *fg_color,
+ PangoLayout *layout)
{
- GskPangoRenderer *crenderer = acquire_renderer ();
- PangoRenderer *renderer = (PangoRenderer *) crenderer;
+ GskPangoRenderer *crenderer;
+ PangoRectangle ink_rect;
- crenderer->cr = cr;
- crenderer->do_path = do_path;
- save_current_point (crenderer);
+ g_return_if_fail (snapshot != NULL);
+ g_return_if_fail (PANGO_IS_LAYOUT (layout));
- pango_renderer_draw_layout (renderer, layout, 0, 0);
+ crenderer = acquire_renderer ();
- restore_current_point (crenderer);
+ crenderer->snapshot = snapshot;
+ crenderer->fg_color = fg_color;
+ crenderer->x_offset = crenderer->y_offset = 0;
- release_renderer (crenderer);
-}
+ pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+ graphene_rect_init (&crenderer->bounds, ink_rect.x, ink_rect.y, ink_rect.width, ink_rect.height);
-void
-gsk_pango_show_layout (cairo_t *cr,
- PangoLayout *layout)
-{
- g_return_if_fail (cr != NULL);
- g_return_if_fail (PANGO_IS_LAYOUT (layout));
+ pango_renderer_draw_layout (PANGO_RENDERER (crenderer), layout, 0, 0);
- gsk_pango_do_layout (cr, layout, FALSE);
+ release_renderer (crenderer);
}
diff --git a/gtk/gskpango.h b/gtk/gskpango.h
index 75a54d8..f8703d2 100644
--- a/gtk/gskpango.h
+++ b/gtk/gskpango.h
@@ -19,7 +19,8 @@
#ifndef __GSK_PANGO_H__
#define __GSK_PANGO_H__
-#include <gsk/gsk.h>
+#include <pango/pango.h>
+#include "gtk/gtksnapshot.h"
G_BEGIN_DECLS
@@ -35,8 +36,9 @@ GDK_AVAILABLE_IN_3_92
GType gsk_pango_renderer_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_92
-void gsk_pango_show_layout (cairo_t *cr,
- PangoLayout *layout);
+void gsk_pango_show_layout (GtkSnapshot *snapshot,
+ const GdkRGBA *fg_color,
+ PangoLayout *layout);
G_END_DECLS
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index d46c0a0..11e594e 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -1332,37 +1332,42 @@ gtk_snapshot_render_layout (GtkSnapshot *snapshot,
PangoLayout *layout)
{
const GdkRGBA *fg_color;
- graphene_rect_t bounds;
- GtkBorder shadow_extents;
- PangoRectangle ink_rect;
GtkCssValue *shadow;
- cairo_t *cr;
g_return_if_fail (snapshot != NULL);
g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
g_return_if_fail (PANGO_IS_LAYOUT (layout));
+ gtk_snapshot_offset (snapshot, x, y);
+
fg_color = _gtk_css_rgba_value_get_rgba (_gtk_style_context_peek_property (context,
GTK_CSS_PROPERTY_COLOR));
+
shadow = _gtk_style_context_peek_property (context, GTK_CSS_PROPERTY_TEXT_SHADOW);
- pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
- _gtk_css_shadows_value_get_extents (shadow, &shadow_extents);
- graphene_rect_init (&bounds,
- ink_rect.x - shadow_extents.left,
- ink_rect.y - shadow_extents.top,
- ink_rect.width + shadow_extents.left + shadow_extents.right,
- ink_rect.height + shadow_extents.top + shadow_extents.bottom);
+ if (!_gtk_css_shadows_value_is_none (shadow))
+ {
+ PangoRectangle ink_rect;
+ graphene_rect_t bounds;
+ GtkBorder shadow_extents = { 0, };
+ cairo_t *cr;
- gtk_snapshot_offset (snapshot, x, y);
+ pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
+ _gtk_css_shadows_value_get_extents (shadow, &shadow_extents);
+ graphene_rect_init (&bounds,
+ ink_rect.x - shadow_extents.left,
+ ink_rect.y - shadow_extents.top,
+ ink_rect.width + shadow_extents.left + shadow_extents.right,
+ ink_rect.height + shadow_extents.top + shadow_extents.bottom);
- cr = gtk_snapshot_append_cairo (snapshot, &bounds, "Text<%dchars>", pango_layout_get_character_count
(layout));
+ cr = gtk_snapshot_append_cairo (snapshot, &bounds, "Text<%dchars>", pango_layout_get_character_count
(layout));
- _gtk_css_shadows_value_paint_layout (shadow, cr, layout);
+ gdk_cairo_set_source_rgba (cr, fg_color);
- gdk_cairo_set_source_rgba (cr, fg_color);
+ _gtk_css_shadows_value_paint_layout (shadow, cr, layout);
+ cairo_destroy (cr);
+ }
- gsk_pango_show_layout (cr, layout);
+ gsk_pango_show_layout (snapshot, fg_color, layout);
- cairo_destroy (cr);
gtk_snapshot_offset (snapshot, -x, -y);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]