[pango/variation-coords: 2/2] fc: Set variation coords on the harfbuzz font



commit 11a4de7eae8eb51a45c35f6789a8cdda84a36b45
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Jul 25 08:26:21 2019 -0400

    fc: Set variation coords on the harfbuzz font
    
    We need to call hb_font_set_var_coords,
    otherwise the hb_font_t has no coords.

 pango/pangofc-font.c | 109 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 86 insertions(+), 23 deletions(-)
---
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 0bb25ba5..247ea1a0 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -45,6 +45,9 @@
 #include "pango-layout.h"
 #include "pango-impl-utils.h"
 
+#include <ft2build.h>
+#include FT_MULTIPLE_MASTERS_H
+
 #include <harfbuzz/hb-ot.h>
 
 enum {
@@ -901,36 +904,89 @@ get_font_size (PangoFcFontKey *key)
 }
 
 static void
-parse_variations (const char      *variations,
-                  hb_variation_t **hb_variations,
-                  guint           *n_variations)
+set_variation (hb_variation_t *vars,
+               unsigned int    n,
+               hb_variation_t *var)
 {
-  guint n;
-  hb_variation_t *var;
   int i;
-  const char *p;
 
-  n = 1;
-  for (i = 0; variations[i]; i++)
+  for (i = 0; i < n; i++)
     {
-      if (variations[i] == ',')
-        n++;
+      if (vars[i].tag == var->tag)
+        {
+          vars[i].value = var->value;
+          break;
+        }
     }
+}
 
-  var = g_new (hb_variation_t, n);
+static void
+parse_variations (hb_variation_t *vars,
+                  unsigned int    n,
+                  const char     *variations)
+{
+  hb_variation_t var;
+  const char *p;
 
   p = variations;
-  n = 0;
   while (p && *p)
     {
       char *end = strchr (p, ',');
-      if (hb_variation_from_string (p, end ? end - p: -1, &var[n]))
-        n++;
+      if (hb_variation_from_string (p, end ? end - p: -1, &var))
+        set_variation (vars, n, &var);
       p = end ? end + 1 : NULL;
     }
+}
+
+#define FixedToFloat(f) (((float)(f))/65536.0)
+
+static gboolean
+get_font_variations (PangoFcFont     *fc_font,
+                     hb_variation_t **vars,
+                     unsigned int    *n)
+{
+  FT_Face ft_face;
+  FT_MM_Var *ft_mm_var;
+  int ret;
+  gboolean retval;
+
+  retval = FALSE;
+
+  ft_face = pango_fc_font_lock_face (fc_font);
+
+  ret = FT_Get_MM_Var (ft_face, &ft_mm_var);
+  if (ret == 0)
+    {
+      FT_Fixed *coords;
+      unsigned int ret;
+
+      coords = g_new (FT_Fixed, ft_mm_var->num_axis);
+      ret = FT_Get_Var_Design_Coordinates (ft_face, ft_mm_var->num_axis, coords);
+      if (ret == 0)
+        {
+          hb_variation_t *v;
+          int i;
+
+          v = g_new (hb_variation_t, ft_mm_var->num_axis);
+
+          for (i = 0; i < ft_mm_var->num_axis; i++)
+            {
+              v[i].tag = ft_mm_var->axis[i].tag;
+              v[i].value = FixedToFloat (coords[i]);
+            }
+
+          *vars = v;
+          *n = ft_mm_var->num_axis;
+          retval = TRUE;
+        }
+      g_free (coords);
+
+      free (ft_mm_var);
+    }
 
-  *hb_variations = var;
-  *n_variations = n;
+  pango_fc_font_unlock_face (fc_font);
+
+  return retval;
 }
 
 static hb_font_t *
@@ -969,18 +1025,25 @@ pango_fc_font_create_hb_font (PangoFont *font)
   hb_font_set_scale (hb_font,
                      size * PANGO_SCALE * x_scale,
                      size * PANGO_SCALE * y_scale);
+
   if (key)
     {
-      const char *variations = pango_fc_font_key_get_variations (key);
-      if (variations)
+      FcPattern *pattern = pango_fc_font_key_get_pattern (key);
+      const char *variations;
+      hb_variation_t *vars;
+      unsigned int n;
+
+      if (get_font_variations (fc_font, &vars, &n))
         {
-          guint n_variations;
-          hb_variation_t *hb_variations;
+          if (FcPatternGetString (pattern, PANGO_FC_FONT_VARIATIONS, 0, (FcChar8 **)&variations) == 
FcResultMatch)
+            parse_variations (vars, n, variations);
 
-          parse_variations (variations, &hb_variations, &n_variations);
-          hb_font_set_variations (hb_font, hb_variations, n_variations);
+          variations = pango_fc_font_key_get_variations (key);
+          if (variations)
+            parse_variations (vars, n, variations);
 
-          g_free (hb_variations);
+          hb_font_set_variations (hb_font, vars, n);
+          g_free (vars);
         }
     }
 


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