Merge pull request #2837 from daltonmaag/fix-subset-palette-labels
[subset] Keep nameIDs used by CPAL palette entry labels
This commit is contained in:
commit
25bcde5f31
@ -2258,8 +2258,24 @@ def prune_post_subset(self, font, options):
|
||||
self.numPaletteEntries = len(self.palettes[0])
|
||||
|
||||
if self.version == 1:
|
||||
self.paletteEntryLabels = [
|
||||
label for i, label in self.paletteEntryLabels if i in retained_palette_indices
|
||||
kept_labels = []
|
||||
dropped_labels = []
|
||||
for i, label in enumerate(self.paletteEntryLabels):
|
||||
if i in retained_palette_indices:
|
||||
kept_labels.append(label)
|
||||
else:
|
||||
dropped_labels.append(label)
|
||||
self.paletteEntryLabels = kept_labels
|
||||
# Remove dropped labels from the name table.
|
||||
name_table = font["name"]
|
||||
name_table.names = [
|
||||
n for n in name_table.names
|
||||
if (
|
||||
n.nameID not in dropped_labels
|
||||
# Only remove nameIDs in the user range and if they're not explicitly kept
|
||||
or n.nameID < 256
|
||||
or n.nameID in options.name_IDs
|
||||
)
|
||||
]
|
||||
return bool(self.numPaletteEntries)
|
||||
|
||||
@ -2553,6 +2569,10 @@ def prune_pre_subset(self, font, options):
|
||||
if stat.table.AxisValueArray:
|
||||
nameIDs.update([val_rec.ValueNameID for val_rec in stat.table.AxisValueArray.AxisValue])
|
||||
nameIDs.update([axis_rec.AxisNameID for axis_rec in stat.table.DesignAxisRecord.Axis])
|
||||
cpal = font.get('CPAL')
|
||||
if cpal and cpal.version == 1:
|
||||
nameIDs.update(cpal.paletteLabels)
|
||||
nameIDs.update(cpal.paletteEntryLabels)
|
||||
if '*' not in options.name_IDs:
|
||||
self.names = [n for n in self.names if n.nameID in nameIDs]
|
||||
if not options.name_legacy:
|
||||
|
46
NEWS.rst
46
NEWS.rst
@ -1,3 +1,11 @@
|
||||
4.37.4 (released 2022-09-30)
|
||||
----------------------------
|
||||
|
||||
- [subset] Keep nameIDs used by CPAL palette entry labels (#2837).
|
||||
- [varLib] Avoid negative hmtx values when creating font from variable CFF2 font (#2827).
|
||||
- [instancer] Don't prune stat.ElidedFallbackNameID (#2828).
|
||||
- [unicodedata] Update Scripts/Blocks to Unicode 15.0 (#2833).
|
||||
|
||||
4.37.3 (released 2022-09-20)
|
||||
----------------------------
|
||||
|
||||
@ -218,30 +226,30 @@
|
||||
- [OS/2 / merge] Automatically recalculate ``OS/2.xAvgCharWidth`` after merging
|
||||
fonts with ``fontTools.merge`` (#2591, #2538).
|
||||
- [misc/config] Added ``fontTools.misc.configTools`` module, a generic configuration
|
||||
system (#2416, #2439).
|
||||
system (#2416, #2439).
|
||||
Added ``fontTools.config`` module, a fontTools-specific configuration
|
||||
system using ``configTools`` above.
|
||||
system using ``configTools`` above.
|
||||
Attached a ``Config`` object to ``TTFont``.
|
||||
- [otlLib] Replaced environment variable for GPOS compression level with an
|
||||
equivalent option using the new config system.
|
||||
- [designspaceLib] Incremented format version to 5.0 (#2436).
|
||||
- [designspaceLib] Incremented format version to 5.0 (#2436).
|
||||
Added discrete axes, variable fonts, STAT information, either design- or
|
||||
user-space location on instances.
|
||||
user-space location on instances.
|
||||
Added ``fontTools.designspaceLib.split`` module to split a designspace
|
||||
into sub-spaces that interpolate and that represent the variable fonts
|
||||
listed in the document.
|
||||
listed in the document.
|
||||
Made instance names optional and allow computing them from STAT data instead.
|
||||
Added ``fontTools.designspaceLib.statNames`` module.
|
||||
Allow instances to have the same location as a previously defined STAT label.
|
||||
Deprecated some attributes:
|
||||
``SourceDescriptor``: ``copyLib``, ``copyInfo``, ``copyGroups``, ``copyFeatures``.
|
||||
Added ``fontTools.designspaceLib.statNames`` module.
|
||||
Allow instances to have the same location as a previously defined STAT label.
|
||||
Deprecated some attributes:
|
||||
``SourceDescriptor``: ``copyLib``, ``copyInfo``, ``copyGroups``, ``copyFeatures``.
|
||||
``InstanceDescriptor``: ``kerning``, ``info``; ``glyphs``: use rules or sparse
|
||||
sources.
|
||||
For both, ``location``: use the more explicit designLocation.
|
||||
Note: all are soft deprecations and existing code should keep working.
|
||||
sources.
|
||||
For both, ``location``: use the more explicit designLocation.
|
||||
Note: all are soft deprecations and existing code should keep working.
|
||||
Updated documentation for Python methods and the XML format.
|
||||
- [varLib] Added ``build_many`` to build several variable fonts from a single
|
||||
designspace document (#2436).
|
||||
designspace document (#2436).
|
||||
Added ``fontTools.varLib.stat`` module to build STAT tables from a designspace
|
||||
document.
|
||||
- [otBase] Try to use the Harfbuzz Repacker for packing GSUB/GPOS tables when
|
||||
@ -432,12 +440,12 @@
|
||||
4.25.2 (released 2021-07-26)
|
||||
----------------------------
|
||||
|
||||
- [COLRv1] Various changes to sync with the latest CORLv1 draft spec. In particular:
|
||||
define COLR.VarIndexMap, remove/inline ColorIndex struct, add VarIndexBase to ``PaintVar*`` tables (#2372);
|
||||
add reduced-precicion specialized transform Paints;
|
||||
define Angle as fraction of half circle encoded as F2Dot14;
|
||||
use FWORD (int16) for all Paint center coordinates;
|
||||
change PaintTransform to have an offset to Affine2x3;
|
||||
- [COLRv1] Various changes to sync with the latest CORLv1 draft spec. In particular:
|
||||
define COLR.VarIndexMap, remove/inline ColorIndex struct, add VarIndexBase to ``PaintVar*`` tables (#2372);
|
||||
add reduced-precicion specialized transform Paints;
|
||||
define Angle as fraction of half circle encoded as F2Dot14;
|
||||
use FWORD (int16) for all Paint center coordinates;
|
||||
change PaintTransform to have an offset to Affine2x3;
|
||||
- [ttLib] when importing XML, only set sfntVersion if the font has no reader and is empty (#2376)
|
||||
|
||||
4.25.1 (released 2021-07-16)
|
||||
|
@ -1244,6 +1244,52 @@ def colrv1_path(tmp_path):
|
||||
|
||||
return output_path
|
||||
|
||||
@pytest.fixture
|
||||
def colrv1_cpalv1_path(colrv1_path):
|
||||
# upgrade CPAL from v0 to v1 by adding labels
|
||||
font = TTFont(colrv1_path)
|
||||
fb = FontBuilder(font=font)
|
||||
fb.setupCPAL(
|
||||
[
|
||||
[
|
||||
(1.0, 0.0, 0.0, 1.0), # red
|
||||
(0.0, 1.0, 0.0, 1.0), # green
|
||||
(0.0, 0.0, 1.0, 1.0), # blue
|
||||
],
|
||||
],
|
||||
paletteLabels=["test palette"],
|
||||
paletteEntryLabels=["first color", "second color", "third color"]
|
||||
)
|
||||
|
||||
output_path = colrv1_path.parent / "TestCOLRv1CPALv1.ttf"
|
||||
fb.save(output_path)
|
||||
|
||||
return output_path
|
||||
|
||||
@pytest.fixture
|
||||
def colrv1_cpalv1_share_nameID_path(colrv1_path):
|
||||
font = TTFont(colrv1_path)
|
||||
fb = FontBuilder(font=font)
|
||||
fb.setupCPAL(
|
||||
[
|
||||
[
|
||||
(1.0, 0.0, 0.0, 1.0), # red
|
||||
(0.0, 1.0, 0.0, 1.0), # green
|
||||
(0.0, 0.0, 1.0, 1.0), # blue
|
||||
],
|
||||
],
|
||||
paletteLabels=["test palette"],
|
||||
paletteEntryLabels=["first color", "second color", "third color"]
|
||||
)
|
||||
|
||||
# Set the name ID of the first color to use nameID 1 = familyName = "TestCOLRv1"
|
||||
fb.font["CPAL"].paletteEntryLabels[0] = 1
|
||||
|
||||
output_path = colrv1_path.parent / "TestCOLRv1CPALv1.ttf"
|
||||
fb.save(output_path)
|
||||
|
||||
return output_path
|
||||
|
||||
|
||||
def test_subset_COLRv1_and_CPAL(colrv1_path):
|
||||
subset_path = colrv1_path.parent / (colrv1_path.name + ".subset")
|
||||
@ -1322,6 +1368,103 @@ def test_subset_COLRv1_and_CPAL(colrv1_path):
|
||||
]
|
||||
|
||||
|
||||
def test_subset_COLRv1_and_CPALv1(colrv1_cpalv1_path):
|
||||
subset_path = colrv1_cpalv1_path.parent / (colrv1_cpalv1_path.name + ".subset")
|
||||
|
||||
subset.main(
|
||||
[
|
||||
str(colrv1_cpalv1_path),
|
||||
"--glyph-names",
|
||||
f"--output-file={subset_path}",
|
||||
"--unicodes=E002,E003,E004",
|
||||
]
|
||||
)
|
||||
subset_font = TTFont(subset_path)
|
||||
|
||||
assert "CPAL" in subset_font
|
||||
cpal = subset_font["CPAL"]
|
||||
name_table = subset_font["name"]
|
||||
assert [name_table.getDebugName(name_id) for name_id in cpal.paletteEntryLabels] == [
|
||||
# "first color", # The first color was pruned
|
||||
"second color",
|
||||
"third color",
|
||||
]
|
||||
# check that the "first color" name is dropped from name table
|
||||
font = TTFont(colrv1_cpalv1_path)
|
||||
|
||||
first_color_nameID = None
|
||||
for n in font["name"].names:
|
||||
if n.toUnicode() == "first color":
|
||||
first_color_nameID = n.nameID
|
||||
break
|
||||
assert first_color_nameID is not None
|
||||
assert all(n.nameID != first_color_nameID for n in name_table.names)
|
||||
|
||||
|
||||
def test_subset_COLRv1_and_CPALv1_keep_nameID(colrv1_cpalv1_path):
|
||||
subset_path = colrv1_cpalv1_path.parent / (colrv1_cpalv1_path.name + ".subset")
|
||||
|
||||
# figure out the name ID of first color so we can keep it
|
||||
font = TTFont(colrv1_cpalv1_path)
|
||||
|
||||
first_color_nameID = None
|
||||
for n in font["name"].names:
|
||||
if n.toUnicode() == "first color":
|
||||
first_color_nameID = n.nameID
|
||||
break
|
||||
assert first_color_nameID is not None
|
||||
|
||||
subset.main(
|
||||
[
|
||||
str(colrv1_cpalv1_path),
|
||||
"--glyph-names",
|
||||
f"--output-file={subset_path}",
|
||||
"--unicodes=E002,E003,E004",
|
||||
f"--name-IDs={first_color_nameID}",
|
||||
|
||||
]
|
||||
)
|
||||
subset_font = TTFont(subset_path)
|
||||
|
||||
assert "CPAL" in subset_font
|
||||
cpal = subset_font["CPAL"]
|
||||
name_table = subset_font["name"]
|
||||
assert [name_table.getDebugName(name_id) for name_id in cpal.paletteEntryLabels] == [
|
||||
# "first color", # The first color was pruned
|
||||
"second color",
|
||||
"third color",
|
||||
]
|
||||
|
||||
# Check that the name ID is kept
|
||||
assert any(n.nameID == first_color_nameID for n in name_table.names)
|
||||
|
||||
|
||||
def test_subset_COLRv1_and_CPALv1_share_nameID(colrv1_cpalv1_share_nameID_path):
|
||||
subset_path = colrv1_cpalv1_share_nameID_path.parent / (colrv1_cpalv1_share_nameID_path.name + ".subset")
|
||||
|
||||
subset.main(
|
||||
[
|
||||
str(colrv1_cpalv1_share_nameID_path),
|
||||
"--glyph-names",
|
||||
f"--output-file={subset_path}",
|
||||
"--unicodes=E002,E003,E004",
|
||||
]
|
||||
)
|
||||
subset_font = TTFont(subset_path)
|
||||
|
||||
assert "CPAL" in subset_font
|
||||
cpal = subset_font["CPAL"]
|
||||
name_table = subset_font["name"]
|
||||
assert [name_table.getDebugName(name_id) for name_id in cpal.paletteEntryLabels] == [
|
||||
# "first color", # The first color was pruned
|
||||
"second color",
|
||||
"third color",
|
||||
]
|
||||
|
||||
# Check that the name ID 1 is kept
|
||||
assert any(n.nameID == 1 for n in name_table.names)
|
||||
|
||||
|
||||
def test_subset_COLRv1_and_CPAL_drop_empty(colrv1_path):
|
||||
subset_path = colrv1_path.parent / (colrv1_path.name + ".subset")
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user