[gtk/subpixel-positioning: 2/2] gl: implement subpixel positioning
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/subpixel-positioning: 2/2] gl: implement subpixel positioning
- Date: Sat, 27 Jul 2019 03:34:11 +0000 (UTC)
commit 59faca6123c8daf15a8a2be3142a4a726398e16a
Author: Matthias Clasen <mclasen redhat com>
Date: Thu Jul 25 17:37:14 2019 -0400
gl: implement subpixel positioning
Pass the glyph position into the glyph caching functions,
not just the glyph index. This allows us to cache different
images for different subpixel positions.
gsk/gl/gskglglyphcache.c | 55 +++++++++++++++++++++++++++--------------
gsk/gl/gskglglyphcacheprivate.h | 18 +++++++++-----
gsk/gl/gskglrenderer.c | 8 ++++--
3 files changed, 55 insertions(+), 26 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index 14ff40e453..a4f43c73a3 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -82,6 +82,8 @@ glyph_cache_equal (gconstpointer v1, gconstpointer v2)
return key1->font == key2->font &&
key1->glyph == key2->glyph &&
+ key1->xshift == key2->xshift &&
+ key1->yshift == key2->yshift &&
key1->scale == key2->scale;
}
@@ -90,7 +92,7 @@ glyph_cache_hash (gconstpointer v)
{
const GlyphCacheKey *key = v;
- return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ key->scale;
+ return GPOINTER_TO_UINT (key->font) ^ key->glyph ^ (key->xshift << 24) ^ (key->yshift << 26) ^ key->scale;
}
static void
@@ -116,8 +118,7 @@ render_glyph (GlyphCacheKey *key,
cairo_surface_t *surface;
cairo_t *cr;
cairo_scaled_font_t *scaled_font;
- PangoGlyphString glyph_string;
- PangoGlyphInfo glyph_info;
+ cairo_glyph_t cairo_glyph;
int surface_width, surface_height;
int stride;
unsigned char *data;
@@ -144,18 +145,12 @@ render_glyph (GlyphCacheKey *key,
cairo_set_scaled_font (cr, scaled_font);
cairo_set_source_rgba (cr, 1, 1, 1, 1);
- glyph_info.glyph = key->glyph;
- glyph_info.geometry.width = value->draw_width * 1024;
- if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
- glyph_info.geometry.x_offset = 0;
- else
- glyph_info.geometry.x_offset = - value->draw_x * 1024;
- glyph_info.geometry.y_offset = - value->draw_y * 1024;
+ cairo_glyph.index = key->glyph;
+ cairo_glyph.x = 0.25 * key->xshift - value->draw_x;
+ cairo_glyph.y = 0.25 * key->yshift - value->draw_y;
- glyph_string.num_glyphs = 1;
- glyph_string.glyphs = &glyph_info;
+ cairo_show_glyphs (cr, &cairo_glyph, 1);
- pango_cairo_show_glyph_string (cr, key->font, &glyph_string);
cairo_destroy (cr);
cairo_surface_flush (surface);
@@ -228,10 +223,14 @@ add_to_cache (GskGLGlyphCache *self,
upload_glyph (key, value);
}
+#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
+
void
gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale,
GskGLCachedGlyph *value)
{
@@ -239,12 +238,20 @@ gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
GlyphCacheKey key;
int width, height;
guint texture_id;
+ guint xshift = PHASE (x);
+ guint yshift = PHASE (y);
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
+ if (xshift != 0)
+ ink_rect.width += 1;
+ if (yshift != 0)
+ ink_rect.height += 1;
key.font = font;
key.glyph = glyph;
+ key.xshift = xshift;
+ key.yshift = yshift;
key.scale = (guint)(scale * 1024);
value->atlas = NULL;
@@ -276,15 +283,21 @@ gboolean
gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale,
- GskGLCachedGlyph *cached_glyph_out)
+ GskGLCachedGlyph *glyph_out)
{
GskGLCachedGlyph *value;
+ guint xshift = PHASE (x);
+ guint yshift = PHASE (y);
value = g_hash_table_lookup (cache->hash_table,
&(GlyphCacheKey) {
.font = font,
.glyph = glyph,
+ .xshift = xshift,
+ .yshift = yshift,
.scale = (guint)(scale * 1024)
});
@@ -314,6 +327,10 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
pango_font_get_glyph_extents (font, glyph, &ink_rect, NULL);
pango_extents_to_pixels (&ink_rect, NULL);
+ if (xshift != 0)
+ ink_rect.width += 1;
+ if (yshift != 0)
+ ink_rect.height += 1;
value = g_new0 (GskGLCachedGlyph, 1);
@@ -332,26 +349,28 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache *cache,
key->font = g_object_ref (font);
key->glyph = glyph;
+ key->xshift = xshift;
+ key->yshift = yshift;
key->scale = (guint)(scale * 1024);
if (ink_rect.width > 0 && ink_rect.height > 0 && key->scale > 0)
add_to_cache (cache, key, value);
- *cached_glyph_out = *value;
+ *glyph_out = *value;
g_hash_table_insert (cache->hash_table, key, value);
}
else
{
- *cached_glyph_out = *value;
+ *glyph_out = *value;
glyph_cache_value_free (value);
}
}
else
{
- *cached_glyph_out = *value;
+ *glyph_out = *value;
}
- return cached_glyph_out->atlas != NULL;
+ return glyph_out->atlas != NULL;
}
void
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
index 72fce67539..c1f0641d22 100644
--- a/gsk/gl/gskglglyphcacheprivate.h
+++ b/gsk/gl/gskglglyphcacheprivate.h
@@ -22,6 +22,8 @@ typedef struct
{
PangoFont *font;
PangoGlyph glyph;
+ guint xshift;
+ guint yshift;
guint scale; /* times 1024 */
} GlyphCacheKey;
@@ -55,12 +57,16 @@ void gsk_gl_glyph_cache_begin_frame (GskGLGlyphCache
gboolean gsk_gl_glyph_cache_lookup (GskGLGlyphCache *self,
PangoFont *font,
PangoGlyph glyph,
+ int x,
+ int y,
float scale,
- GskGLCachedGlyph *cached_glyph_out);
-void gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
- PangoFont *font,
- PangoGlyph glyph,
- float scale,
- GskGLCachedGlyph *glyph_out);
+ GskGLCachedGlyph *value);
+void gsk_gl_glyph_cache_get_texture (GskGLDriver *driver,
+ PangoFont *font,
+ PangoGlyph glyph,
+ int x,
+ int y,
+ float scale,
+ GskGLCachedGlyph *value);
#endif
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index e77a9892cd..f64f1c435f 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -595,6 +595,8 @@ render_text_node (GskGLRenderer *self,
gsk_gl_glyph_cache_lookup (self->glyph_cache,
(PangoFont *)font,
gi->glyph,
+ x_position + gi->geometry.x_offset,
+ gi->geometry.y_offset,
text_scale,
&glyph);
@@ -608,13 +610,15 @@ render_text_node (GskGLRenderer *self,
gsk_gl_glyph_cache_get_texture (self->gl_driver,
(PangoFont *)font,
gi->glyph,
+ x_position + gi->geometry.x_offset,
+ gi->geometry.y_offset,
text_scale,
&glyph);
g_assert (glyph.texture_id != 0);
}
- cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
- cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
+ cx = (x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ cy = gi->geometry.y_offset / PANGO_SCALE;
ops_set_texture (builder, glyph.texture_id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]