Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle MATH input more carefully #820

Merged
merged 4 commits into from Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
20 changes: 8 additions & 12 deletions Lib/ufo2ft/outlineCompiler.py
Expand Up @@ -1186,24 +1186,20 @@ def setupTable_MATH(self):
for name, glyph in self.allGlyphs.items():
if GLYPHS_MATH_VARIANTS_KEY in glyph.lib:
variants = glyph.lib[GLYPHS_MATH_VARIANTS_KEY]
if "hVariants" in variants:
h_variants[name] = [
(n, self._bboxWidth(n)) for n in variants["hVariants"]
]
if "vVariants" in variants:
v_variants[name] = [
(n, self._bboxHeight(n)) for n in variants["vVariants"]
]
if "hAssembly" in variants:
parts = variants["hAssembly"]
if names := variants.get("hVariants"):
h_variants[name] = [(n, self._bboxWidth(n)) for n in names]
if names := variants.get("vVariants"):
v_variants[name] = [(n, self._bboxHeight(n)) for n in names]
if parts := variants.get("hAssembly"):
assert all(len(part) == 4 for part in parts), "Invalid assembly"
khaledhosny marked this conversation as resolved.
Show resolved Hide resolved
h_assemblies[name] = (
[(*part, self._bboxWidth(part[0])) for part in parts],
# If the last part has italic correction, we use it as
# the assembly's.
italics_correction.pop(parts[-1][0], 0),
)
if "vAssembly" in variants:
parts = variants["vAssembly"]
if parts := variants.get("vAssembly"):
assert all(len(part) == 4 for part in parts), "Invalid assembly"
v_assemblies[name] = (
[(*part, self._bboxHeight(part[0])) for part in parts],
# If the last part has italic correction, we use it as
Expand Down
52 changes: 50 additions & 2 deletions tests/outlineCompiler_test.py
Expand Up @@ -1406,9 +1406,10 @@ def test_achVendId_space_padded_if_less_than_4_chars(
assert font["OS/2"].achVendID == expected


def test_MATH_table(FontClass):
@pytest.mark.parametrize("compile", [compileTTF, compileOTF])
def test_MATH_table(FontClass, compile):
ufo = FontClass(getpath("TestMathFont-Regular.ufo"))
result = compileTTF(ufo)
result = compile(ufo)
assert "MATH" in result

math = result["MATH"].table
Expand All @@ -1427,6 +1428,53 @@ def test_MATH_table(FontClass):

assert set(math.MathGlyphInfo.ExtendedShapeCoverage.glyphs) == extendedShapes

assert set(math.MathVariants.VertGlyphCoverage.glyphs) == {
"parenright",
"parenleft",
}
assert math.MathVariants.VertGlyphConstruction
assert len(math.MathVariants.VertGlyphConstruction) == 2
assert (
math.MathVariants.VertGlyphConstruction[0].GlyphAssembly.ItalicsCorrection.Value
== 0
)
assert (
len(math.MathVariants.VertGlyphConstruction[0].GlyphAssembly.PartRecords) == 3
)

assert not math.MathVariants.HorizGlyphCoverage
assert not math.MathVariants.HorizGlyphConstruction


@pytest.mark.parametrize("compile", [compileTTF, compileOTF])
@pytest.mark.parametrize(
"attribute",
[
"vAssembly",
"hAssembly",
"vVariants",
"hVariants",
],
)
def test_MATH_table_ignore_empty(FontClass, compile, attribute):
# Should not raise becaise of empty assembly/variants
ufo = FontClass(getpath("TestMathFont-Regular.ufo"))
ufo["parenright"].lib[GLYPHS_MATH_VARIANTS_KEY][attribute] = []
compile(ufo)


@pytest.mark.parametrize("compile", [compileTTF, compileOTF])
@pytest.mark.parametrize("attribute", ["vAssembly", "hAssembly"])
def test_MATH_table_invalid(FontClass, compile, attribute):
ufo = FontClass(getpath("TestMathFont-Regular.ufo"))
ufo["parenright"].lib[GLYPHS_MATH_VARIANTS_KEY][attribute] = [
["parenright.top", 0, 0],
["parenright.ext", 1, 100, 100],
["parenright.bot", 0, 100, 0],
]
with pytest.raises(AssertionError, match="Invalid assembly"):
compile(ufo)


if __name__ == "__main__":
import sys
Expand Down