[gtk/subpixel-positioning: 4/5] gl: implement subpixel positioning



commit f2a04cb4be2d7f0564327d1ac06f4fb8857541f4
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]