Use a text render node in GskPangoRenderer

This pushes the rendering closer to the place where we can
insert a texture atlas for glyph caching.
This commit is contained in:
Matthias Clasen
2017-09-01 12:42:21 -04:00
parent 4975aa7920
commit a367d34949

View File

@@ -98,51 +98,6 @@ set_color (GskPangoRenderer *crenderer,
gdk_cairo_set_source_rgba (cr, &rgba);
}
static gboolean
_pango_cairo_font_install (PangoFont *font,
cairo_t *cr)
{
cairo_scaled_font_t *scaled_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *)font);
if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))
return FALSE;
cairo_set_scaled_font (cr, scaled_font);
return TRUE;
}
static void
gsk_pango_renderer_draw_unknown_glyph (GskPangoRenderer *crenderer,
PangoFont *font,
PangoGlyphInfo *gi,
double cx,
double cy)
{
cairo_t *cr;
PangoGlyphString *glyphs;
cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "DrawUnknownGlyph<%u>", gi->glyph);
gdk_cairo_set_source_rgba (cr, &crenderer->fg_color);
cairo_move_to (cr, cx, cy);
glyphs = pango_glyph_string_new ();
pango_glyph_string_set_size (glyphs, 1);
glyphs->glyphs[0] = *gi;
pango_cairo_show_glyph_string (cr, font, glyphs);
cairo_destroy (cr);
}
#ifndef STACK_BUFFER_SIZE
#define STACK_BUFFER_SIZE (512 * sizeof (int))
#endif
#define STACK_ARRAY_LENGTH(T) (STACK_BUFFER_SIZE / sizeof(T))
static void
gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
const char *text,
@@ -156,84 +111,23 @@ gsk_pango_renderer_show_text_glyphs (PangoRenderer *renderer,
int y)
{
GskPangoRenderer *crenderer = (GskPangoRenderer *) (renderer);
double base_x = (double)x / PANGO_SCALE;
double base_y = (double)y / PANGO_SCALE;
int x_offset, y_offset;
GskRenderNode *node;
char name[64];
cairo_t *cr;
int i, count;
int x_position = 0;
cairo_glyph_t *cairo_glyphs;
cairo_glyph_t stack_glyphs[STACK_ARRAY_LENGTH (cairo_glyph_t)];
double base_x = crenderer->x_offset + (double)x / PANGO_SCALE;
double base_y = crenderer->y_offset + (double)y / PANGO_SCALE;
gtk_snapshot_get_offset (crenderer->snapshot, &x_offset, &y_offset);
cr = gtk_snapshot_append_cairo (crenderer->snapshot, &crenderer->bounds, "Text<%dglyphs>", glyphs->num_glyphs);
gtk_snapshot_offset (crenderer->snapshot, base_x, base_y);
set_color (crenderer, PANGO_RENDER_PART_FOREGROUND, cr);
node = gsk_text_node_new (font, glyphs, crenderer->fg_color, x_offset, y_offset, base_x, base_y);
snprintf (name, sizeof (name), "Glyphs<%d>", glyphs->num_glyphs);
gsk_render_node_set_name (node, name);
gtk_snapshot_append_node (crenderer->snapshot, node);
gsk_render_node_unref (node);
if (!_pango_cairo_font_install (font, cr))
{
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoGlyphInfo *gi = &glyphs->glyphs[i];
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
double cx = base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset == 0 ?
base_y :
base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
gsk_pango_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
}
x_position += gi->geometry.width;
}
goto done;
}
if (glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs))
cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs);
else
cairo_glyphs = stack_glyphs;
count = 0;
for (i = 0; i < glyphs->num_glyphs; i++)
{
PangoGlyphInfo *gi = &glyphs->glyphs[i];
if (gi->glyph != PANGO_GLYPH_EMPTY)
{
double cx = base_x + (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
double cy = gi->geometry.y_offset == 0 ?
base_y :
base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;
if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
gsk_pango_renderer_draw_unknown_glyph (crenderer, font, gi, cx, cy);
else
{
cairo_glyphs[count].index = gi->glyph;
cairo_glyphs[count].x = cx;
cairo_glyphs[count].y = cy;
count++;
}
}
x_position += gi->geometry.width;
}
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
cairo_show_glyphs (cr, cairo_glyphs, count);
if (cairo_glyphs != stack_glyphs)
g_free (cairo_glyphs);
done:
cairo_destroy (cr);
gtk_snapshot_offset (crenderer->snapshot, -base_x, -base_y);
}
static void