Merge pull request #1652 from anthrotype/varlib-set-default-OS2-classes
varLib: add set_default_weight_width_slant
This commit is contained in:
commit
06fe38dd6b
@ -857,6 +857,45 @@ def load_designspace(designspace):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# https://docs.microsoft.com/en-us/typography/opentype/spec/os2#uswidthclass
|
||||||
|
WDTH_VALUE_TO_OS2_WIDTH_CLASS = {
|
||||||
|
50: 1,
|
||||||
|
62.5: 2,
|
||||||
|
75: 3,
|
||||||
|
87.5: 4,
|
||||||
|
100: 5,
|
||||||
|
112.5: 6,
|
||||||
|
125: 7,
|
||||||
|
150: 8,
|
||||||
|
200: 9,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def set_default_weight_width_slant(font, location):
|
||||||
|
if "OS/2" in font:
|
||||||
|
if "wght" in location:
|
||||||
|
weight_class = otRound(max(1, min(location["wght"], 1000)))
|
||||||
|
if font["OS/2"].usWeightClass != weight_class:
|
||||||
|
log.info("Setting OS/2.usWidthClass = %s", weight_class)
|
||||||
|
font["OS/2"].usWeightClass = weight_class
|
||||||
|
|
||||||
|
if "wdth" in location:
|
||||||
|
# map 'wdth' axis (50..200) to OS/2.usWidthClass (1..9), rounding to closest
|
||||||
|
widthValue = min(max(location["wdth"], 50), 200)
|
||||||
|
widthClass = otRound(
|
||||||
|
models.piecewiseLinearMap(widthValue, WDTH_VALUE_TO_OS2_WIDTH_CLASS)
|
||||||
|
)
|
||||||
|
if font["OS/2"].usWidthClass != widthClass:
|
||||||
|
log.info("Setting OS/2.usWidthClass = %s", widthClass)
|
||||||
|
font["OS/2"].usWidthClass = widthClass
|
||||||
|
|
||||||
|
if "slnt" in location and "post" in font:
|
||||||
|
italicAngle = max(-90, min(location["slnt"], 90))
|
||||||
|
if font["post"].italicAngle != italicAngle:
|
||||||
|
log.info("Setting post.italicAngle = %s", italicAngle)
|
||||||
|
font["post"].italicAngle = italicAngle
|
||||||
|
|
||||||
|
|
||||||
def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
|
def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
|
||||||
"""
|
"""
|
||||||
Build variation font from a designspace file.
|
Build variation font from a designspace file.
|
||||||
@ -930,6 +969,10 @@ def build(designspace, master_finder=lambda s:s, exclude=[], optimize=True):
|
|||||||
post.extraNames = []
|
post.extraNames = []
|
||||||
post.mapping = {}
|
post.mapping = {}
|
||||||
|
|
||||||
|
set_default_weight_width_slant(
|
||||||
|
vf, location={axis.axisTag: axis.defaultValue for axis in vf["fvar"].axes}
|
||||||
|
)
|
||||||
|
|
||||||
for tag in exclude:
|
for tag in exclude:
|
||||||
if tag in vf:
|
if tag in vf:
|
||||||
del vf[tag]
|
del vf[tag]
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
will be recalculated by the compiler -->
|
will be recalculated by the compiler -->
|
||||||
<version value="4"/>
|
<version value="4"/>
|
||||||
<xAvgCharWidth value="506"/>
|
<xAvgCharWidth value="506"/>
|
||||||
<usWeightClass value="400"/>
|
<usWeightClass value="368"/>
|
||||||
<usWidthClass value="5"/>
|
<usWidthClass value="5"/>
|
||||||
<fsType value="00000000 00000100"/>
|
<fsType value="00000000 00000100"/>
|
||||||
<ySubscriptXSize value="650"/>
|
<ySubscriptXSize value="650"/>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
will be recalculated by the compiler -->
|
will be recalculated by the compiler -->
|
||||||
<version value="4"/>
|
<version value="4"/>
|
||||||
<xAvgCharWidth value="580"/>
|
<xAvgCharWidth value="580"/>
|
||||||
<usWeightClass value="400"/>
|
<usWeightClass value="350"/>
|
||||||
<usWidthClass value="5"/>
|
<usWidthClass value="5"/>
|
||||||
<fsType value="00000000 00000100"/>
|
<fsType value="00000000 00000100"/>
|
||||||
<ySubscriptXSize value="650"/>
|
<ySubscriptXSize value="650"/>
|
||||||
|
@ -4,6 +4,7 @@ from fontTools.ttLib import TTFont, newTable
|
|||||||
from fontTools.varLib import build
|
from fontTools.varLib import build
|
||||||
from fontTools.varLib.mutator import instantiateVariableFont
|
from fontTools.varLib.mutator import instantiateVariableFont
|
||||||
from fontTools.varLib import main as varLib_main, load_masters
|
from fontTools.varLib import main as varLib_main, load_masters
|
||||||
|
from fontTools.varLib import set_default_weight_width_slant
|
||||||
from fontTools.designspaceLib import (
|
from fontTools.designspaceLib import (
|
||||||
DesignSpaceDocumentError, DesignSpaceDocument, SourceDescriptor,
|
DesignSpaceDocumentError, DesignSpaceDocument, SourceDescriptor,
|
||||||
)
|
)
|
||||||
@ -661,5 +662,81 @@ def _extract_flat_kerning(font, pairpos_table):
|
|||||||
return extracted_kerning
|
return extracted_kerning
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def ttFont():
|
||||||
|
f = TTFont()
|
||||||
|
f["OS/2"] = newTable("OS/2")
|
||||||
|
f["OS/2"].usWeightClass = 400
|
||||||
|
f["OS/2"].usWidthClass = 100
|
||||||
|
f["post"] = newTable("post")
|
||||||
|
f["post"].italicAngle = 0
|
||||||
|
return f
|
||||||
|
|
||||||
|
|
||||||
|
class SetDefaultWeightWidthSlantTest(object):
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"wght": 0}, 1),
|
||||||
|
({"wght": 1}, 1),
|
||||||
|
({"wght": 100}, 100),
|
||||||
|
({"wght": 1000}, 1000),
|
||||||
|
({"wght": 1001}, 1000),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_wght(self, ttFont, location, expected):
|
||||||
|
set_default_weight_width_slant(ttFont, location)
|
||||||
|
|
||||||
|
assert ttFont["OS/2"].usWeightClass == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"wdth": 0}, 1),
|
||||||
|
({"wdth": 56}, 1),
|
||||||
|
({"wdth": 57}, 2),
|
||||||
|
({"wdth": 62.5}, 2),
|
||||||
|
({"wdth": 75}, 3),
|
||||||
|
({"wdth": 87.5}, 4),
|
||||||
|
({"wdth": 100}, 5),
|
||||||
|
({"wdth": 112.5}, 6),
|
||||||
|
({"wdth": 125}, 7),
|
||||||
|
({"wdth": 150}, 8),
|
||||||
|
({"wdth": 200}, 9),
|
||||||
|
({"wdth": 201}, 9),
|
||||||
|
({"wdth": 1000}, 9),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_wdth(self, ttFont, location, expected):
|
||||||
|
set_default_weight_width_slant(ttFont, location)
|
||||||
|
|
||||||
|
assert ttFont["OS/2"].usWidthClass == expected
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"location, expected",
|
||||||
|
[
|
||||||
|
({"slnt": -91}, -90),
|
||||||
|
({"slnt": -90}, -90),
|
||||||
|
({"slnt": 0}, 0),
|
||||||
|
({"slnt": 11.5}, 11.5),
|
||||||
|
({"slnt": 90}, 90),
|
||||||
|
({"slnt": 91}, 90),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_slnt(self, ttFont, location, expected):
|
||||||
|
set_default_weight_width_slant(ttFont, location)
|
||||||
|
|
||||||
|
assert ttFont["post"].italicAngle == expected
|
||||||
|
|
||||||
|
def test_all(self, ttFont):
|
||||||
|
set_default_weight_width_slant(
|
||||||
|
ttFont, {"wght": 500, "wdth": 150, "slnt": -12.0}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert ttFont["OS/2"].usWeightClass == 500
|
||||||
|
assert ttFont["OS/2"].usWidthClass == 8
|
||||||
|
assert ttFont["post"].italicAngle == -12.0
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(unittest.main())
|
sys.exit(unittest.main())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user