From 7efae33209c900580a1e8c8e88bcc407ebccba26 Mon Sep 17 00:00:00 2001
From: Matthias Clasen <mclasen@redhat.com>
Date: Sat, 16 Sep 2017 01:01:39 -0400
Subject: [PATCH] Add font variation information

Display the available axes and named instances.

https://bugzilla.gnome.org/show_bug.cgi?id=787759
---
 src/font-view.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/src/font-view.c b/src/font-view.c
index c86e82c..5694e6e 100644
--- a/src/font-view.c
+++ b/src/font-view.c
@@ -28,6 +28,7 @@
 #include FT_TYPE1_TABLES_H
 #include FT_SFNT_NAMES_H
 #include FT_TRUETYPE_IDS_H
+#include FT_MULTIPLE_MASTERS_H
 #include <cairo/cairo-ft.h>
 #include <fontconfig/fontconfig.h>
 #include <gio/gio.h>
@@ -185,6 +186,69 @@ add_row (GtkWidget *grid,
                              1, 1);
 }
 
+#define FixedToFloat(f) (((float)(f))/65536.0)
+
+static char *
+describe_axis (FT_Var_Axis *ax)
+{
+  return g_strdup_printf (_("%s %g — %g, default %g"), ax->name,
+                          FixedToFloat(ax->minimum),
+                          FixedToFloat(ax->maximum),
+                          FixedToFloat(ax->def));
+}
+
+static char *
+get_sfnt_name (FT_Face face, guint id)
+{
+    guint count, i;
+
+    count = FT_Get_Sfnt_Name_Count (face);
+    for (i = 0; i < count; i++) {
+        FT_SfntName sname;
+
+        if (FT_Get_Sfnt_Name (face, i, &sname) != 0)
+            continue;
+
+        if (sname.name_id != id)
+            continue;
+
+        /* only handle the unicode names for US langid */
+        if (!(sname.platform_id == TT_PLATFORM_MICROSOFT &&
+            sname.encoding_id == TT_MS_ID_UNICODE_CS &&
+            sname.language_id == TT_MS_LANGID_ENGLISH_UNITED_STATES))
+            continue;
+
+        return g_convert ((gchar *)sname.string, sname.string_len,
+                          "UTF-8", "UTF-16BE", NULL, NULL, NULL);
+    }
+    return NULL;
+}
+
+static gboolean
+is_valid_subfamily_id (guint id)
+{
+  return id == 2 || id == 17 || (255 < id && id < 32768);
+}
+
+static void
+describe_instance (FT_Face face, FT_Var_Named_Style *ns, int pos, GString *s)
+{
+    if (is_valid_subfamily_id (ns->strid)) {
+        char *str = get_sfnt_name (face, ns->strid);
+        if (str) {
+            if (s->len > 0)
+                g_string_append (s, ", ");
+            g_string_append (s, str);
+            g_free (str);
+            return;
+        }
+    }
+
+    if (s->len > 0)
+        g_string_append (s, ", ");
+    g_string_append_printf (s, _("Instance %d"), pos);
+}
+
 static void
 populate_grid (FontViewApplication *self,
                GtkWidget *grid,
@@ -193,6 +257,7 @@ populate_grid (FontViewApplication *self,
     gchar *s;
     GFileInfo *info;
     PS_FontInfoRec ps_info;
+    FT_MM_Var *ft_mm_var;
 
     add_row (grid, _("Name"), face->family_name, FALSE);
 
@@ -318,6 +383,23 @@ populate_grid (FontViewApplication *self,
         g_free (s);
     }
     add_row (grid, _("Color glyphs"), FT_HAS_COLOR (face) ? _("yes") : _("no"), FALSE);
+
+    if (FT_Get_MM_Var (face, &ft_mm_var) == 0) {
+        int i;
+        for (i = 0; i < ft_mm_var->num_axis; i++) {
+             char *s = describe_axis (&ft_mm_var->axis[i]);
+             add_row (grid, i == 0 ? _("Variation Axes") : "", s, FALSE);
+             g_free (s);
+        }
+        {
+            GString *s = g_string_new ("");
+            for (i = 0; i < ft_mm_var->num_namedstyles; i++) {
+                 describe_instance (face, &ft_mm_var->namedstyle[i], i, s);
+             }
+             add_row (grid, _("Named Styles"), s->str, TRUE);
+             g_string_free (s, TRUE);
+        }
+    }
 }
 
 static void
-- 
2.14.1