[gtk/subpixel-positioning: 14/14] gl: implement subpixel positioning



commit f84bbb0c6a21d6d1c428583b91324a24592bcfab
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 28 10:06:47 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        | 28 ++++++++++++++++++++++++----
 gsk/gl/gskglglyphcacheprivate.h |  4 ++++
 gsk/gl/gskglrenderer.c          |  6 ++++--
 3 files changed, 32 insertions(+), 6 deletions(-)
---
diff --git a/gsk/gl/gskglglyphcache.c b/gsk/gl/gskglglyphcache.c
index 9dfe045edf..a33a1357aa 100644
--- a/gsk/gl/gskglglyphcache.c
+++ b/gsk/gl/gskglglyphcache.c
@@ -83,6 +83,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;
 }
 
@@ -91,7 +93,11 @@ 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
@@ -146,10 +152,10 @@ render_glyph (GlyphCacheKey    *key,
 
   cairo_glyph.index = key->glyph;
   if (key->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
-    cairo_glyph.x = 0;
+    cairo_glyph.x = 0.25 * key->xshift;
   else
-    cairo_glyph.x = - value->draw_x;
-  cairo_glyph.y = - value->draw_y;
+    cairo_glyph.x = 0.25 * key->xshift - value->draw_x;
+  cairo_glyph.y = 0.25 * key->yshift - value->draw_y;
 
   cairo_show_glyphs (cr, &cairo_glyph, 1);
   cairo_destroy (cr);
@@ -243,20 +249,28 @@ add_to_cache (GskGLGlyphCache  *self,
   upload_glyph (key, value);
 }
 
+#define PHASE(x) ((x % PANGO_SCALE) * 4 / PANGO_SCALE)
+
 gboolean
 gsk_gl_glyph_cache_lookup (GskGLGlyphCache  *cache,
                            PangoFont        *font,
                            PangoGlyph        glyph,
+                           int               x,
+                           int               y,
                            float             scale,
                            GskGLDriver      *driver,
                            GskGLCachedGlyph *cached_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)
                                });
 
@@ -288,6 +302,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);
 
@@ -302,6 +320,8 @@ gsk_gl_glyph_cache_lookup (GskGLGlyphCache  *cache,
 
       key->font = g_object_ref (font);
       key->glyph = glyph;
+      key->xshift = xshift;
+      key->yshift = yshift;
       key->scale =  key_scale;
 
       if (key->scale > 0 &&
diff --git a/gsk/gl/gskglglyphcacheprivate.h b/gsk/gl/gskglglyphcacheprivate.h
index a7f5d3e032..0859798907 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,6 +57,8 @@ 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,
                                                              GskGLDriver            *driver,
                                                              GskGLCachedGlyph       *cached_glyph_out);
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 9438ce2513..b2fee7872f 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 * PANGO_SCALE + x_position + gi->geometry.x_offset,
++                                y * PANGO_SCALE + gi->geometry.y_offset,
                                  text_scale,
                                  self->gl_driver,
                                  &glyph);
@@ -606,8 +608,8 @@ render_text_node (GskGLRenderer   *self,
       if (glyph.texture_id == 0)
         goto next;
 
-      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]