Merge pull request #2673 from daltonmaag/instancer-set-bits

Set RIBBI bits when cutting instances
This commit is contained in:
Nikolaus Waxweiler 2022-07-06 11:01:08 +01:00 committed by GitHub
commit ce38db6562
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 1908 additions and 6 deletions

View File

@ -90,12 +90,10 @@ from fontTools.varLib import builder
from fontTools.varLib.mvar import MVAR_ENTRIES
from fontTools.varLib.merger import MutatorMerger
from fontTools.varLib.instancer import names
from contextlib import contextmanager
import collections
from copy import deepcopy
from enum import IntEnum
import logging
from itertools import islice
import os
import re
@ -1200,10 +1198,10 @@ def instantiateVariableFont(
requires the skia-pathops package (available to pip install).
The overlap parameter only has effect when generating full static instances.
updateFontNames (bool): if True, update the instantiated font's name table using
the Axis Value Tables from the STAT table. The name table will be updated so
it conforms to the R/I/B/BI model. If the STAT table is missing or
an Axis Value table is missing for a given axis coordinate, a ValueError will
be raised.
the Axis Value Tables from the STAT table. The name table and the style bits
in the head and OS/2 table will be updated so they conform to the R/I/B/BI
model. If the STAT table is missing or an Axis Value table is missing for
a given axis coordinate, a ValueError will be raised.
"""
# 'overlap' used to be bool and is now enum; for backward compat keep accepting bool
overlap = OverlapMode(int(overlap))
@ -1273,9 +1271,51 @@ def instantiateVariableFont(
},
)
if updateFontNames:
# Set Regular/Italic/Bold/Bold Italic bits as appropriate, after the
# name table has been updated.
setRibbiBits(varfont)
return varfont
def setRibbiBits(font):
"""Set the `head.macStyle` and `OS/2.fsSelection` style bits
appropriately."""
english_ribbi_style = font["name"].getName(names.NameID.SUBFAMILY_NAME, 3, 1, 0x409)
if english_ribbi_style is None:
return
styleMapStyleName = english_ribbi_style.toStr().lower()
if styleMapStyleName not in {"regular", "bold", "italic", "bold italic"}:
return
if styleMapStyleName == "bold":
font["head"].macStyle = 0b01
elif styleMapStyleName == "bold italic":
font["head"].macStyle = 0b11
elif styleMapStyleName == "italic":
font["head"].macStyle = 0b10
selection = font["OS/2"].fsSelection
# First clear...
selection &= ~(1 << 0)
selection &= ~(1 << 5)
selection &= ~(1 << 6)
# ...then re-set the bits.
if styleMapStyleName == "regular":
selection |= 1 << 6
elif styleMapStyleName == "bold":
selection |= 1 << 5
elif styleMapStyleName == "italic":
selection |= 1 << 0
elif styleMapStyleName == "bold italic":
selection |= 1 << 0
selection |= 1 << 5
font["OS/2"].fsSelection = selection
def splitAxisLocationAndRanges(axisLimits, rangeType=AxisRange):
location, axisRanges = {}, {}
for axisTag, value in axisLimits.items():

File diff suppressed because it is too large Load Diff

View File

@ -1975,3 +1975,35 @@ def test_main_exit_multiple_limits(varfont, tmpdir, capsys):
captured = capsys.readouterr()
assert "Specified multiple limits for the same axis" in captured.err
def test_set_ribbi_bits():
varfont = ttLib.TTFont()
varfont.importXML(os.path.join(TESTDATA, "STATInstancerTest.ttx"))
for location in [instance.coordinates for instance in varfont["fvar"].instances]:
instance = instancer.instantiateVariableFont(
varfont, location, updateFontNames=True
)
name_id_2 = instance["name"].getDebugName(2)
mac_style = instance["head"].macStyle
fs_selection = instance["OS/2"].fsSelection & 0b1100001 # Just bits 0, 5, 6
if location["ital"] == 0:
if location["wght"] == 700:
assert name_id_2 == "Bold", location
assert mac_style == 0b01, location
assert fs_selection == 0b0100000, location
else:
assert name_id_2 == "Regular", location
assert mac_style == 0b00, location
assert fs_selection == 0b1000000, location
else:
if location["wght"] == 700:
assert name_id_2 == "Bold Italic", location
assert mac_style == 0b11, location
assert fs_selection == 0b0100001, location
else:
assert name_id_2 == "Italic", location
assert mac_style == 0b10, location
assert fs_selection == 0b0000001, location