Skip to content

Commit

Permalink
Improve getAssociatedMasterId + unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
ollimeier committed Jan 23, 2025
1 parent f1fc7e0 commit 7d56bac
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 18 deletions.
2 changes: 1 addition & 1 deletion src/fontra_glyphs/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ def variableGlyphToGSGlyph(variableGlyph, gsGlyph):
]
gsLayer.attributes["coordinates"] = gsLocation

associatedMasterId = getAssociatedMasterId(gsGlyph, gsLocation)
associatedMasterId = getAssociatedMasterId(gsGlyph.parent, gsLocation)
if associatedMasterId:
gsLayer.associatedMasterId = associatedMasterId

Expand Down
12 changes: 6 additions & 6 deletions src/fontra_glyphs/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,21 @@ def getLocationFromSources(sources, layerName):
return {k.lower(): v for k, v in s.location.items()}


def getAssociatedMasterId(gsGlyph, gsLocation):
def getAssociatedMasterId(gsFont, gsLocation):
# Best guess for associatedMasterId
closestMaster = None
closestMasterID = gsFont.masters[0].id # default first master.
closestDistance = float("inf")
for gsLayer in gsGlyph.layers:
gsMaster = gsLayer.master
for gsMaster in gsFont.masters:
distance = sum(
abs(gsMaster.axes[i] - gsLocation[i])
for i in range(len(gsMaster.axes))
if i < len(gsLocation)
)
if distance < closestDistance:
closestDistance = distance
closestMaster = gsMaster
return closestMaster.id if closestMaster else None
closestMasterID = gsMaster.id

return closestMasterID


def gsFormatting(content):
Expand Down
77 changes: 66 additions & 11 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pathlib

import glyphsLib
import pytest
from fontra.backends import getFileSystemBackend
from glyphsLib.classes import GSAxis, GSFont, GSFontMaster, GSGlyph, GSLayer

from fontra_glyphs.utils import (
getAssociatedMasterId,
Expand All @@ -22,9 +22,54 @@ def testFont(request):
return getFileSystemBackend(request.param)


@pytest.fixture(scope="module", params=[glyphs2Path, glyphs3Path, glyphsPackagePath])
def testGSFont(request):
return glyphsLib.GSFont(request.param)
def createGSFontMaster(axes=[100, 100], id="DUMMY-MASTER-ID"):
master = GSFontMaster()
master.axes = axes
master.id = id
return master


def createGSGlyph(name="GlyphName", unicodes=[], layers=[]):
glyph = GSGlyph()
glyph.name = name
glyph.unicodes = unicodes
glyph.layers = layers
return glyph


@pytest.fixture(scope="module")
def testGSFontWW():
gsFont = GSFont()
gsFont.format_version = 3
gsFont.axes = [
GSAxis(name="Optical Size", tag="opsz"),
GSAxis(name="Weight", tag="wght"),
GSAxis(name="Width", tag="wdth"),
]
gsFont.masters = [
createGSFontMaster(axes=[12, 50, 100], id="MasterID-TextCondLight"),
createGSFontMaster(axes=[12, 50, 400], id="MasterID-TextCondRegular"),
createGSFontMaster(axes=[12, 50, 900], id="MasterID-TextCondBold"),
createGSFontMaster(axes=[12, 200, 100], id="MasterID-TextWideLight"),
createGSFontMaster(axes=[12, 200, 400], id="MasterID-TextWideRegular"),
createGSFontMaster(axes=[12, 200, 900], id="MasterID-TextWideBold"),
createGSFontMaster(axes=[60, 50, 100], id="MasterID-PosterCondLight"),
createGSFontMaster(axes=[60, 50, 400], id="MasterID-PosterCondRegular"),
createGSFontMaster(axes=[60, 50, 900], id="MasterID-PosterCondBold"),
createGSFontMaster(axes=[60, 200, 100], id="MasterID-PosterWideLight"),
createGSFontMaster(axes=[60, 200, 400], id="MasterID-PosterWideRegular"),
createGSFontMaster(axes=[60, 200, 900], id="MasterID-PosterWideBold"),
]
gsFont.glyphs.append(
createGSGlyph(
name="A",
unicodes=[
0x0041,
],
layers=[GSLayer()],
)
)
return gsFont


async def test_getLocationFromSources(testFont):
Expand All @@ -35,13 +80,23 @@ async def test_getLocationFromSources(testFont):
assert location == {"weight": 155}


def test_getAssociatedMasterId(testGSFont):
# TODO: need more complex test with at least two axes,
# then improvement getAssociatedMasterId
gsGlyph = testGSFont.glyphs["a"]
associatedMasterId = getAssociatedMasterId(gsGlyph, [155])
associatedMaster = gsGlyph.layers[associatedMasterId]
assert associatedMaster.name == "Regular"
expectedAssociatedMasterId = [
# gsLocation, associatedMasterId
[[14, 155, 900], "MasterID-TextWideBold"],
[[14, 155, 100], "MasterID-TextWideLight"],
[[14, 55, 900], "MasterID-TextCondBold"],
[[14, 55, 110], "MasterID-TextCondLight"],
[[55, 155, 900], "MasterID-PosterWideBold"],
[[55, 155, 100], "MasterID-PosterWideLight"],
[[55, 55, 900], "MasterID-PosterCondBold"],
[[55, 55, 110], "MasterID-PosterCondLight"],
[[30, 100, 399], "MasterID-TextCondRegular"],
]


@pytest.mark.parametrize("gsLocation,expected", expectedAssociatedMasterId)
def test_getAssociatedMasterId(testGSFontWW, gsLocation, expected):
assert getAssociatedMasterId(testGSFontWW, gsLocation) == expected


contentSnippets = [
Expand Down

0 comments on commit 7d56bac

Please sign in to comment.