[gtk/glyphy2: 31/32] wip: Add a quad to the glyphy atlas




commit 2fafab17d8759c066f737c9976973d212a6e3b2f
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Apr 5 22:55:58 2022 -0400

    wip: Add a quad to the glyphy atlas

 gsk/gl/gskglglyphylibrary.c | 207 ++++++++++++++++++++++++++++++--------------
 1 file changed, 143 insertions(+), 64 deletions(-)
---
diff --git a/gsk/gl/gskglglyphylibrary.c b/gsk/gl/gskglglyphylibrary.c
index 3a0ec8b3a1..5d9277f44f 100644
--- a/gsk/gl/gskglglyphylibrary.c
+++ b/gsk/gl/gskglglyphylibrary.c
@@ -118,17 +118,6 @@ gsk_gl_glyphy_library_clear_cache (GskGLTextureLibrary *library)
   memset (self->front, 0, sizeof self->front);
 }
 
-static void
-gsk_gl_glyphy_library_init_atlas (GskGLTextureLibrary *library,
-                                  GskGLTextureAtlas   *atlas)
-{
-  g_assert (GSK_IS_GL_GLYPHY_LIBRARY (library));
-  g_assert (atlas != NULL);
-
-  atlas->cursor_x = 0;
-  atlas->cursor_y = 0;
-}
-
 static gboolean
 gsk_gl_glyphy_library_allocate (GskGLTextureLibrary *library,
                                 GskGLTextureAtlas   *atlas,
@@ -189,6 +178,9 @@ gsk_gl_glyphy_library_finalize (GObject *object)
 
 GQuark quark_glyphy_font_key;
 
+static void gsk_gl_glyphy_library_init_atlas (GskGLTextureLibrary *library,
+                                              GskGLTextureAtlas   *atlas);
+
 static void
 gsk_gl_glyphy_library_class_init (GskGLGlyphyLibraryClass *klass)
 {
@@ -337,27 +329,23 @@ acc_callback (GskPathOperation        op,
 }
 
 static inline gboolean
-encode_glyph (GskGLGlyphyLibrary *self,
-              hb_font_t          *font,
-              unsigned int        glyph_index,
-              double              tolerance_per_em,
-              glyphy_rgba_t      *buffer,
-              guint               buffer_len,
-              guint              *output_len,
-              guint              *nominal_width,
-              guint              *nominal_height,
-              glyphy_extents_t   *extents)
+encode_path (GskGLGlyphyLibrary *self,
+             GskPath            *path,
+             guint               upem,
+             double              tolerance_per_em,
+             glyphy_rgba_t      *buffer,
+             guint               buffer_len,
+             guint              *output_len,
+             guint              *nominal_width,
+             guint              *nominal_height,
+             glyphy_extents_t   *extents)
 {
-  hb_face_t *face = hb_font_get_face (font);
-  guint upem = hb_face_get_upem (face);
   double tolerance = upem * tolerance_per_em;
   double faraway = (double)upem / (MIN_FONT_SIZE * M_SQRT2);
   double unit_size = (double) upem / GRID_SIZE;
   double enlighten_max = (double) upem * ENLIGHTEN_MAX;
   double embolden_max = (double) upem * EMBOLDEN_MAX;
   double avg_fetch_achieved;
-  GskPathBuilder *builder;
-  GskPath *path, *simplified;
 
   self->acc_endpoints->len = 0;
 
@@ -367,14 +355,7 @@ encode_glyph (GskGLGlyphyLibrary *self,
                                        (glyphy_arc_endpoint_accumulator_callback_t)accumulate_endpoint,
                                        self->acc_endpoints);
 
-  builder = gsk_path_builder_new ();
-  hb_font_get_glyph_shape (font, glyph_index, gsk_path_get_draw_funcs (), builder);
-  path = gsk_path_builder_free_to_path (builder);
-  simplified = gsk_path_simplify (path);
-
-  gsk_path_foreach (simplified, GSK_PATH_FOREACH_ALLOW_CURVE, acc_callback, self->acc);
-  gsk_path_unref (simplified);
-  gsk_path_unref (path);
+  gsk_path_foreach (path, GSK_PATH_FOREACH_ALLOW_CURVE, acc_callback, self->acc);
 
   if (!glyphy_arc_accumulator_successful (self->acc))
     return FALSE;
@@ -406,6 +387,22 @@ encode_glyph (GskGLGlyphyLibrary *self,
   return TRUE;
 }
 
+static GskPath *
+glyph_to_path (hb_font_t    *font,
+               unsigned int  glyph)
+{
+  GskPathBuilder *builder;
+  GskPath *path, *simplified;
+
+  builder = gsk_path_builder_new ();
+  hb_font_get_glyph_shape (font, glyph, gsk_path_get_draw_funcs (), builder);
+  path = gsk_path_builder_free_to_path (builder);
+  simplified = gsk_path_simplify (path);
+  gsk_path_unref (path);
+
+  return simplified;
+}
+
 static inline hb_font_t *
 get_nominal_size_hb_font (PangoFont *font)
 {
@@ -428,6 +425,42 @@ get_nominal_size_hb_font (PangoFont *font)
   return hbfont;
 }
 
+static void
+upload_buffer (guint          packed_x,
+               guint          packed_y,
+               guint          width,
+               guint          height,
+               glyphy_rgba_t *buffer,
+               guint          output_len)
+{
+  g_assert (width > 0);
+  g_assert (height > 0);
+
+  /* Upload the arc list */
+  if (width * height == output_len)
+    {
+      glTexSubImage2D (GL_TEXTURE_2D, 0,
+                       packed_x, packed_y,
+                       width, height,
+                       GL_RGBA, GL_UNSIGNED_BYTE,
+                       buffer);
+    }
+  else
+    {
+      glTexSubImage2D (GL_TEXTURE_2D, 0,
+                       packed_x, packed_y,
+                       width, height - 1,
+                       GL_RGBA, GL_UNSIGNED_BYTE,
+                       buffer);
+      /* Upload the last row separately */
+      glTexSubImage2D (GL_TEXTURE_2D, 0,
+                       packed_x, packed_y + height - 1,
+                       output_len - (width * (height - 1)), 1,
+                       GL_RGBA, GL_UNSIGNED_BYTE,
+                       buffer + (width * (height - 1)));
+    }
+}
+
 gboolean
 gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
                            GskGLGlyphyKey          *key,
@@ -445,6 +478,8 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
   guint output_len = 0;
   guint texture_id;
   guint width, height;
+  GskPath *path;
+  guint upem;
 
   g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
   g_assert (key != NULL);
@@ -452,12 +487,19 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
   g_assert (out_value != NULL);
 
   hbfont = get_nominal_size_hb_font (font);
+  path = glyph_to_path (hbfont, key->glyph);
+  upem = hb_face_get_upem (hb_font_get_face (hbfont));
 
   /* Convert the glyph to a list of arcs */
-  if (!encode_glyph (self, hbfont, key->glyph, TOLERANCE,
-                     buffer, sizeof buffer, &output_len,
-                     &nominal_w, &nominal_h, &extents))
-    return FALSE;
+  if (!encode_path (self, path, upem, TOLERANCE,
+                    buffer, sizeof buffer, &output_len,
+                    &nominal_w, &nominal_h, &extents))
+    {
+      gsk_path_unref (path);
+      return FALSE;
+    }
+
+  gsk_path_unref (path);
 
   /* Allocate space for list within atlas */
   width = self->item_w;
@@ -479,33 +521,7 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
       /* Connect the texture for data upload */
       glActiveTexture (GL_TEXTURE0);
       glBindTexture (GL_TEXTURE_2D, texture_id);
-
-      g_assert (width > 0);
-      g_assert (height > 0);
-
-      /* Upload the arc list */
-      if (width * height == output_len)
-        {
-          glTexSubImage2D (GL_TEXTURE_2D, 0,
-                           packed_x, packed_y,
-                           width, height,
-                           GL_RGBA, GL_UNSIGNED_BYTE,
-                           buffer);
-        }
-      else
-        {
-          glTexSubImage2D (GL_TEXTURE_2D, 0,
-                           packed_x, packed_y,
-                           width, height - 1,
-                           GL_RGBA, GL_UNSIGNED_BYTE,
-                           buffer);
-          /* Upload the last row separately */
-          glTexSubImage2D (GL_TEXTURE_2D, 0,
-                           packed_x, packed_y + height - 1,
-                           output_len - (width * (height - 1)), 1,
-                           GL_RGBA, GL_UNSIGNED_BYTE,
-                           buffer + (width * (height - 1)));
-        }
+      upload_buffer (packed_x, packed_y, width, height, buffer, output_len);
     }
 
   value->extents.min_x = extents.min_x;
@@ -521,3 +537,66 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
 
   return TRUE;
 }
+
+static glyphy_rgba_t buffer[128];
+static guint output_len = 0;
+static guint nominal_w;
+static guint nominal_h;
+static glyphy_extents_t extents;
+
+static void
+gsk_gl_glyphy_library_init_atlas (GskGLTextureLibrary *library,
+                                  GskGLTextureAtlas   *atlas)
+{
+  GskGLGlyphyLibrary *self = (GskGLGlyphyLibrary *)library;
+  guint width;
+  guint height;
+  gboolean packed;
+  int x, y;
+
+  g_assert (GSK_IS_GL_GLYPHY_LIBRARY (library));
+  g_assert (atlas != NULL);
+
+  atlas->cursor_x = 0;
+  atlas->cursor_y = 0;
+
+  if (output_len == 0)
+    {
+      GskPathBuilder *builder;
+      GskPath *path;
+
+      builder = gsk_path_builder_new ();
+      gsk_path_builder_add_rect (builder, &GRAPHENE_RECT_INIT (0, 0, 1, 1));
+      path = gsk_path_builder_free_to_path (builder);
+
+      if (!encode_path (self, path, 1000, TOLERANCE,
+                        buffer, sizeof buffer, &output_len,
+                        &nominal_w, &nominal_h, &extents))
+        g_error ("Failed to initialize glyphy atlas");
+
+      gsk_path_unref (path);
+    }
+
+  width = self->item_w;
+  height = (output_len + width - 1) / width;
+
+  packed = gsk_gl_texture_library_allocate (library, atlas, width, height, &x, &y);
+
+  g_assert (packed);
+  g_assert (x == 0 && y == 0);
+
+  glBindTexture (GL_TEXTURE_2D, atlas->texture_id);
+  upload_buffer (0, 0, width, height, buffer, output_len);
+
+#if 0
+  value->extents.min_x = extents.min_x;
+  value->extents.min_y = extents.min_y;
+  value->extents.max_x = extents.max_x;
+  value->extents.max_y = extents.max_y;
+  value->nominal_w = nominal_w;
+  value->nominal_h = nominal_h;
+  value->atlas_x = 0;
+  value->atlas_y = 0;
+#endif
+}
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]