Repository: googlefonts/glyphsLib

Issue:
support for `meta` table needed
ufo2ft [now supports](https://github.com/googlefonts/ufo2ft/pull/509) the `meta` table [defined in UFO3](https://unifiedfontobject.org/versions/ufo3/lib.plist/#publicopentypemeta).  

However, it doesn't look as though glyphsLib supports it yet: I tried round-tripping a UFO to glyphs and back, and the meta table info was removed -- but maybe I did something wrong?


Discussion:

Patch:
diff --git a/Lib/glyphsLib/builder/constants.py b/Lib/glyphsLib/builder/constants.py
index 2cc80013..91d83134 100644
--- a/Lib/glyphsLib/builder/constants.py
+++ b/Lib/glyphsLib/builder/constants.py
@@ -89,6 +89,7 @@ UFO2FT_COLOR_PALETTES_KEY = "com.github.googlei18n.ufo2ft.colorPalettes"
 UFO2FT_COLOR_LAYER_MAPPING_KEY = "com.github.googlei18n.ufo2ft.colorLayerMapping"
 UFO2FT_COLOR_LAYERS_KEY = "com.github.googlei18n.ufo2ft.colorLayers"
 
+UFO2FT_META_TABLE_KEY = PUBLIC_PREFIX + "openTypeMeta"
 # ufo2ft KernFeatureWriter default to "skip" mode (i.e. do not write features
 # if they are already present), while Glyphs.app always adds its automatic
 # kerning to any user written kern lookups. So we need to pass custom "append"
diff --git a/Lib/glyphsLib/builder/custom_params.py b/Lib/glyphsLib/builder/custom_params.py
index 666f7d38..f3da9c30 100644
--- a/Lib/glyphsLib/builder/custom_params.py
+++ b/Lib/glyphsLib/builder/custom_params.py
@@ -15,6 +15,7 @@
 
 from collections import defaultdict
 import re
+import logging
 
 from glyphsLib.util import bin_to_int_list, int_list_to_bin
 from .filters import parse_glyphs_filter
@@ -28,6 +29,7 @@ from .constants import (
     REVERSE_CODEPAGE_RANGES,
     PUBLIC_PREFIX,
     UFO_FILENAME_CUSTOM_PARAM,
+    UFO2FT_META_TABLE_KEY,
 )
 from .features import replace_feature, replace_prefixes
 
@@ -72,6 +74,9 @@ going from Glyphs to UFOs.
 CUSTOM_PARAM_PREFIX = GLYPHS_PREFIX + "customParameter."
 
 
+logger = logging.getLogger(__name__)
+
+
 def identity(value):
     return value
 
@@ -529,6 +534,48 @@ register(
 )
 
 
+# convert Glyphs' meta Table to UFO openTypeMeta
+def to_ufo_meta_table(value):
+    meta = {}
+    # In:  {data = "de-Latn"; tag = dlng; }, {data = "sr-Cyrl"; tag = slng; }
+    # Out: { "dlng": [ "de-Latn" ], "slng": [ "sr-Cyrl" ] }
+    for entry in value:
+        tag, data = entry["tag"], entry["data"]
+        if tag in meta:
+            logger.warning(
+                f"Multiple '{tag}' tags in meta table; only the last one will be used"
+            )
+
+        if tag in ("appl", "bild"):
+            meta[tag] = data
+        else:
+            meta.setdefault(tag, []).append(data)
+    return meta
+
+
+def to_glyphs_meta_table(value):
+    meta = []
+    for tag, data in value.items():
+        if isinstance(data, list):
+            for entry in data:
+                meta.append({"tag": tag, "data": entry})
+        else:
+            meta.append({"tag": tag, "data": data})
+    return meta
+
+
+register(
+    ParamHandler(
+        glyphs_name="meta Table",
+        ufo_name=UFO2FT_META_TABLE_KEY,
+        ufo_info=False,
+        ufo_prefix="",
+        value_to_ufo=to_ufo_meta_table,
+        value_to_glyphs=to_glyphs_meta_table,
+    )
+)
+
+
 def to_ufo_color_palettes(value):
     return [[to_ufo_color(color) for color in palette] for palette in value]
 


Test patch:
diff --git a/tests/builder/custom_params_test.py b/tests/builder/custom_params_test.py
index 79ab8d12..88969358 100644
--- a/tests/builder/custom_params_test.py
+++ b/tests/builder/custom_params_test.py
@@ -460,6 +460,25 @@ class SetCustomParamsTestBase(object):
         font = glyphsLib.to_glyphs([self.ufo])
         self.assertEqual(font.customParameters["Color Palettes"], glyphs_palettes)
 
+    def test_meta_table(self):
+        glyphs_meta = [
+            {"data": "de-Latn", "tag": "dlng"},
+            {"data": "en-Latn", "tag": "dlng"},
+            {"data": "sr-Cyrl", "tag": "slng"},
+            {"data": "\x00\x00...", "tag": "appl"},
+        ]
+        self.font.customParameters["meta Table"] = glyphs_meta
+        ufo_meta = {
+            "dlng": ["de-Latn", "en-Latn"],
+            "slng": ["sr-Cyrl"],
+            "appl": "\x00\x00...",
+        }
+        self.set_custom_params()
+        self.assertEqual(self.ufo.lib["public.openTypeMeta"], ufo_meta)
+
+        font = glyphsLib.to_glyphs([self.ufo])
+        self.assertEqual(font.customParameters["meta Table"], glyphs_meta)
+
 
 class SetCustomParamsTestUfoLib2(SetCustomParamsTestBase, unittest.TestCase):
     ufo_module = ufoLib2