Merge pull request #3024 from fonttools/no-overwrite-stat

[varLib] Don't overwrite pre-existing STAT
This commit is contained in:
Cosimo Lupo 2023-03-08 13:00:34 +00:00 committed by GitHub
commit 1a202ab1be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1276 additions and 13 deletions

View File

@ -45,6 +45,7 @@ import os.path
import logging
from copy import deepcopy
from pprint import pformat
from re import fullmatch
from .errors import VarLibError, VarLibValidationError
log = logging.getLogger("fontTools.varLib")
@ -995,11 +996,11 @@ def build_many(
vf = build(
vfDoc,
master_finder,
exclude=list(exclude) + ["STAT"],
exclude=exclude,
optimize=optimize,
colr_layer_reuse=colr_layer_reuse,
)[0]
if "STAT" not in exclude:
if "STAT" not in vf and "STAT" not in exclude:
buildVFStatTable(vf, designspace, name)
res[name] = vf
return res
@ -1174,15 +1175,23 @@ class MasterFinder(object):
def main(args=None):
"""Build a variable font from a designspace file and masters"""
"""Build variable fonts from a designspace file and masters"""
from argparse import ArgumentParser
from fontTools import configLogger
parser = ArgumentParser(prog="varLib", description=main.__doc__)
parser.add_argument("designspace")
parser.add_argument(
output_group = parser.add_mutually_exclusive_group()
output_group.add_argument(
"-o", metavar="OUTPUTFILE", dest="outfile", default=None, help="output file"
)
output_group.add_argument(
"-d",
"--output-dir",
metavar="OUTPUTDIR",
default=None,
help="output dir (default: same as input designspace file)",
)
parser.add_argument(
"-x",
metavar="TAG",
@ -1218,6 +1227,19 @@ def main(args=None):
'name. The default value is "%(default)s".'
),
)
parser.add_argument(
"--variable-fonts",
default=".*",
metavar="VF_NAME",
help=(
"Filter the list of variable fonts produced from the input "
"Designspace v5 file. By default all listed variable fonts are "
"generated. To generate a specific variable font (or variable fonts) "
'that match a given "name" attribute, you can pass as argument '
"the full name or a regular expression. E.g.: --variable-fonts "
'"MyFontVF_WeightOnly"; or --variable-fonts "MyFontVFItalic_.*".'
),
)
logging_group = parser.add_mutually_exclusive_group(required=False)
logging_group.add_argument(
"-v", "--verbose", action="store_true", help="Run more verbosely."
@ -1232,23 +1254,58 @@ def main(args=None):
)
designspace_filename = options.designspace
designspace = DesignSpaceDocument.fromfile(designspace_filename)
vf_descriptors = designspace.getVariableFonts()
if not vf_descriptors:
parser.error(f"No variable fonts in given designspace {designspace.path!r}")
vfs_to_build = []
for vf in vf_descriptors:
# Skip variable fonts that do not match the user's inclusion regex if given.
if not fullmatch(options.variable_fonts, vf.name):
continue
vfs_to_build.append(vf)
if not vfs_to_build:
parser.error(f"No variable fonts matching {options.variable_fonts!r}")
if options.outfile is not None and len(vfs_to_build) > 1:
parser.error(
"can't specify -o because there are multiple VFs to build; "
"use --output-dir, or select a single VF with --variable-fonts"
)
output_dir = options.output_dir
if output_dir is None:
output_dir = os.path.dirname(designspace_filename)
vf_name_to_output_path = {}
if len(vfs_to_build) == 1 and options.outfile is not None:
vf_name_to_output_path[vfs_to_build[0].name] = options.outfile
else:
for vf in vfs_to_build:
filename = vf.filename if vf.filename is not None else vf.name + ".{ext}"
vf_name_to_output_path[vf.name] = os.path.join(output_dir, filename)
finder = MasterFinder(options.master_finder)
vf, _, _ = build(
designspace_filename,
vfs = build_many(
designspace,
finder,
exclude=options.exclude,
optimize=options.optimize,
colr_layer_reuse=options.colr_layer_reuse,
)
outfile = options.outfile
if outfile is None:
for vf_name, vf in vfs.items():
ext = "otf" if vf.sfntVersion == "OTTO" else "ttf"
outfile = os.path.splitext(designspace_filename)[0] + "-VF." + ext
log.info("Saving variation font %s", outfile)
vf.save(outfile)
output_path = vf_name_to_output_path[vf_name].format(ext=ext)
output_dir = os.path.dirname(output_path)
if output_dir:
os.makedirs(output_dir, exist_ok=True)
log.info("Saving variation font %s", output_path)
vf.save(output_path)
if __name__ == "__main__":

View File

@ -0,0 +1,36 @@
<?xml version='1.0' encoding='UTF-8'?>
<designspace format="5.0">
<axes>
<axis tag="wght" name="Weight" minimum="100" maximum="900" default="100">
<map input="100" output="30"/>
<map input="900" output="240"/>
</axis>
<axis tag="wdth" name="Width" minimum="80" maximum="115" default="80"/>
</axes>
<sources>
<source filename="master_no_overwrite_stat/Test-CondensedThin.ttx" name="Test Condensed Thin">
<location>
<dimension name="Weight" xvalue="30"/>
<dimension name="Width" xvalue="80"/>
</location>
</source>
<source filename="master_no_overwrite_stat/Test-CondensedBlack.ttx" name="Test Condensed Black">
<location>
<dimension name="Weight" xvalue="240"/>
<dimension name="Width" xvalue="80"/>
</location>
</source>
<source filename="master_no_overwrite_stat/Test-ExtendedThin.ttx" name="Test Extended Thin">
<location>
<dimension name="Weight" xvalue="30"/>
<dimension name="Width" xvalue="115"/>
</location>
</source>
<source filename="master_no_overwrite_stat/Test-ExtendedBlack.ttx" name="Test Extended Black">
<location>
<dimension name="Weight" xvalue="240"/>
<dimension name="Width" xvalue="115"/>
</location>
</source>
</sources>
</designspace>

View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.39">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="A"/>
</GlyphOrder>
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="3.013"/>
<checkSumAdjustment value="0x37268237"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Fri Feb 17 14:29:44 2023"/>
<modified value="Tue Mar 7 12:56:58 2023"/>
<xMin value="-2"/>
<yMin value="-250"/>
<xMax value="583"/>
<yMax value="750"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>
<hhea>
<tableVersion value="0x00010000"/>
<ascent value="1000"/>
<descent value="-300"/>
<lineGap value="0"/>
<advanceWidthMax value="582"/>
<minLeftSideBearing value="-2"/>
<minRightSideBearing value="-1"/>
<xMaxExtent value="583"/>
<caretSlopeRise value="1"/>
<caretSlopeRun value="0"/>
<caretOffset value="0"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="2"/>
</hhea>
<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="2"/>
<maxPoints value="19"/>
<maxContours value="2"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="0"/>
</maxp>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<version value="4"/>
<xAvgCharWidth value="541"/>
<usWeightClass value="900"/>
<usWidthClass value="3"/>
<fsType value="00000000 00001000"/>
<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>
<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>
<yStrikeoutSize value="80"/>
<yStrikeoutPosition value="303"/>
<sFamilyClass value="0"/>
<panose>
<bFamilyType value="0"/>
<bSerifStyle value="0"/>
<bWeight value="0"/>
<bProportion value="0"/>
<bContrast value="0"/>
<bStrokeVariation value="0"/>
<bArmStyle value="0"/>
<bLetterForm value="0"/>
<bMidline value="0"/>
<bXHeight value="0"/>
</panose>
<ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
<ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
<achVendID value="NONE"/>
<fsSelection value="00000000 01000000"/>
<usFirstCharIndex value="65"/>
<usLastCharIndex value="65"/>
<sTypoAscender value="750"/>
<sTypoDescender value="-250"/>
<sTypoLineGap value="250"/>
<usWinAscent value="1000"/>
<usWinDescent value="300"/>
<ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
<ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
<sxHeight value="505"/>
<sCapHeight value="670"/>
<usDefaultChar value="0"/>
<usBreakChar value="32"/>
<usMaxContext value="0"/>
</OS_2>
<hmtx>
<mtx name=".notdef" width="500" lsb="50"/>
<mtx name="A" width="582" lsb="-2"/>
</hmtx>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="0" platEncID="3" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
</cmap>
<loca>
<!-- The 'loca' table will be calculated by the compiler -->
</loca>
<glyf>
<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->
<TTGlyph name=".notdef" xMin="50" yMin="-250" xMax="450" yMax="750">
<contour>
<pt x="50" y="-250" on="1"/>
<pt x="50" y="750" on="1"/>
<pt x="450" y="750" on="1"/>
<pt x="450" y="-250" on="1"/>
</contour>
<contour>
<pt x="100" y="-200" on="1"/>
<pt x="400" y="-200" on="1"/>
<pt x="400" y="700" on="1"/>
<pt x="100" y="700" on="1"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="A" xMin="-2" yMin="0" xMax="583" yMax="672">
<contour>
<pt x="410" y="672" on="1"/>
<pt x="570" y="81" on="1"/>
<pt x="576" y="58" on="0"/>
<pt x="583" y="19" on="0"/>
<pt x="583" y="0" on="1"/>
<pt x="384" y="0" on="1"/>
<pt x="315" y="355" on="1"/>
<pt x="297" y="480" on="1"/>
<pt x="292" y="480" on="1"/>
<pt x="195" y="0" on="1"/>
<pt x="-2" y="0" on="1"/>
<pt x="-2" y="15" on="0"/>
<pt x="2" y="55" on="0"/>
<pt x="9" y="79" on="1"/>
<pt x="176" y="668" on="1"/>
</contour>
<contour>
<pt x="422" y="257" on="1"/>
<pt x="422" y="107" on="1"/>
<pt x="137" y="107" on="1"/>
<pt x="137" y="257" on="1"/>
</contour>
<instructions/>
</TTGlyph>
</glyf>
<name>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
Test Condensed Black
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
3.013;NONE;Test-CondensedBlack
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
Test Condensed Black
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 3.013
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
Test-CondensedBlack
</namerecord>
<namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
Test
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
Condensed Black
</namerecord>
</name>
<post>
<formatType value="2.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="-130"/>
<underlineThickness value="80"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
<psNames>
<!-- This file uses unique glyph names based on the information
found in the 'post' table. Since these names might not be unique,
we have to invent artificial names in case of clashes. In order to
be able to retain the original information, we need a name to
ps name mapping for those cases where they differ. That's what
you see below.
-->
</psNames>
<extraNames>
<!-- following are the name that are not taken from the standard Mac glyph order -->
</extraNames>
</post>
</ttFont>

View File

@ -0,0 +1,373 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.39">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="A"/>
</GlyphOrder>
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="3.013"/>
<checkSumAdjustment value="0x176a479f"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Fri Feb 17 14:29:44 2023"/>
<modified value="Tue Mar 7 12:56:58 2023"/>
<xMin value="28"/>
<yMin value="-250"/>
<xMax value="450"/>
<yMax value="750"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>
<hhea>
<tableVersion value="0x00010000"/>
<ascent value="1000"/>
<descent value="-300"/>
<lineGap value="0"/>
<advanceWidthMax value="500"/>
<minLeftSideBearing value="28"/>
<minRightSideBearing value="31"/>
<xMaxExtent value="450"/>
<caretSlopeRise value="1"/>
<caretSlopeRun value="0"/>
<caretOffset value="0"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="2"/>
</hhea>
<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="2"/>
<maxPoints value="19"/>
<maxContours value="2"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="0"/>
</maxp>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<version value="4"/>
<xAvgCharWidth value="482"/>
<usWeightClass value="100"/>
<usWidthClass value="3"/>
<fsType value="00000000 00001000"/>
<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>
<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>
<yStrikeoutSize value="25"/>
<yStrikeoutPosition value="274"/>
<sFamilyClass value="0"/>
<panose>
<bFamilyType value="0"/>
<bSerifStyle value="0"/>
<bWeight value="0"/>
<bProportion value="0"/>
<bContrast value="0"/>
<bStrokeVariation value="0"/>
<bArmStyle value="0"/>
<bLetterForm value="0"/>
<bMidline value="0"/>
<bXHeight value="0"/>
</panose>
<ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
<ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
<achVendID value="NONE"/>
<fsSelection value="00000000 01000000"/>
<usFirstCharIndex value="65"/>
<usLastCharIndex value="65"/>
<sTypoAscender value="750"/>
<sTypoDescender value="-250"/>
<sTypoLineGap value="250"/>
<usWinAscent value="1000"/>
<usWinDescent value="300"/>
<ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
<ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
<sxHeight value="456"/>
<sCapHeight value="670"/>
<usDefaultChar value="0"/>
<usBreakChar value="32"/>
<usMaxContext value="0"/>
</OS_2>
<hmtx>
<mtx name=".notdef" width="500" lsb="50"/>
<mtx name="A" width="464" lsb="28"/>
</hmtx>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="0" platEncID="3" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
</cmap>
<loca>
<!-- The 'loca' table will be calculated by the compiler -->
</loca>
<glyf>
<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->
<TTGlyph name=".notdef" xMin="50" yMin="-250" xMax="450" yMax="750">
<contour>
<pt x="50" y="-250" on="1"/>
<pt x="50" y="750" on="1"/>
<pt x="450" y="750" on="1"/>
<pt x="450" y="-250" on="1"/>
</contour>
<contour>
<pt x="100" y="-200" on="1"/>
<pt x="400" y="-200" on="1"/>
<pt x="400" y="700" on="1"/>
<pt x="100" y="700" on="1"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="A" xMin="28" yMin="0" xMax="433" yMax="672">
<contour>
<pt x="247" y="672" on="1"/>
<pt x="408" y="90" on="1"/>
<pt x="414" y="68" on="0"/>
<pt x="427" y="23" on="0"/>
<pt x="433" y="0" on="1"/>
<pt x="399" y="0" on="1"/>
<pt x="266" y="482" on="1"/>
<pt x="235" y="613" on="1"/>
<pt x="233" y="613" on="1"/>
<pt x="62" y="0" on="1"/>
<pt x="28" y="0" on="1"/>
<pt x="35" y="23" on="0"/>
<pt x="47" y="68" on="0"/>
<pt x="54" y="90" on="1"/>
<pt x="218" y="668" on="1"/>
</contour>
<contour>
<pt x="354" y="244" on="1"/>
<pt x="354" y="217" on="1"/>
<pt x="109" y="217" on="1"/>
<pt x="109" y="244" on="1"/>
</contour>
<instructions/>
</TTGlyph>
</glyf>
<name>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
Test Condensed Thin
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
3.013;NONE;Test-CondensedThin
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
Test Condensed Thin
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 3.013
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
Test-CondensedThin
</namerecord>
<namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
Test
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
Condensed Thin
</namerecord>
<namerecord nameID="256" platformID="3" platEncID="1" langID="0x409">
Standard
</namerecord>
<namerecord nameID="257" platformID="3" platEncID="1" langID="0x409">
Heaviness
</namerecord>
<namerecord nameID="258" platformID="3" platEncID="1" langID="0x409">
Extralight
</namerecord>
<namerecord nameID="259" platformID="3" platEncID="1" langID="0x409">
Thin
</namerecord>
<namerecord nameID="260" platformID="3" platEncID="1" langID="0x409">
Light
</namerecord>
<namerecord nameID="261" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="262" platformID="3" platEncID="1" langID="0x409">
Medium
</namerecord>
<namerecord nameID="263" platformID="3" platEncID="1" langID="0x409">
Semibold
</namerecord>
<namerecord nameID="264" platformID="3" platEncID="1" langID="0x409">
Bold
</namerecord>
<namerecord nameID="265" platformID="3" platEncID="1" langID="0x409">
Wideness
</namerecord>
<namerecord nameID="266" platformID="3" platEncID="1" langID="0x409">
Compressed
</namerecord>
<namerecord nameID="267" platformID="3" platEncID="1" langID="0x409">
Condensed
</namerecord>
<namerecord nameID="268" platformID="3" platEncID="1" langID="0x409">
Normal
</namerecord>
<namerecord nameID="269" platformID="3" platEncID="1" langID="0x409">
Extended
</namerecord>
</name>
<post>
<formatType value="2.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="-130"/>
<underlineThickness value="25"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
<psNames>
<!-- This file uses unique glyph names based on the information
found in the 'post' table. Since these names might not be unique,
we have to invent artificial names in case of clashes. In order to
be able to retain the original information, we need a name to
ps name mapping for those cases where they differ. That's what
you see below.
-->
</psNames>
<extraNames>
<!-- following are the name that are not taken from the standard Mac glyph order -->
</extraNames>
</post>
<STAT>
<Version value="0x00010001"/>
<DesignAxisRecordSize value="8"/>
<!-- DesignAxisCount=2 -->
<DesignAxisRecord>
<Axis index="0">
<AxisTag value="wght"/>
<AxisNameID value="257"/> <!-- Heaviness -->
<AxisOrdering value="0"/>
</Axis>
<Axis index="1">
<AxisTag value="wdth"/>
<AxisNameID value="265"/> <!-- Wideness -->
<AxisOrdering value="1"/>
</Axis>
</DesignAxisRecord>
<!-- AxisValueCount=11 -->
<AxisValueArray>
<AxisValue index="0" Format="1">
<AxisIndex value="0"/>
<Flags value="0"/>
<ValueNameID value="258"/> <!-- Extralight -->
<Value value="100.0"/>
</AxisValue>
<AxisValue index="1" Format="1">
<AxisIndex value="0"/>
<Flags value="0"/>
<ValueNameID value="259"/> <!-- Thin -->
<Value value="200.0"/>
</AxisValue>
<AxisValue index="2" Format="1">
<AxisIndex value="0"/>
<Flags value="0"/>
<ValueNameID value="260"/> <!-- Light -->
<Value value="300.0"/>
</AxisValue>
<AxisValue index="3" Format="1">
<AxisIndex value="0"/>
<Flags value="2"/> <!-- ElidableAxisValueName -->
<ValueNameID value="261"/> <!-- Regular -->
<Value value="400.0"/>
</AxisValue>
<AxisValue index="4" Format="1">
<AxisIndex value="0"/>
<Flags value="0"/>
<ValueNameID value="262"/> <!-- Medium -->
<Value value="500.0"/>
</AxisValue>
<AxisValue index="5" Format="1">
<AxisIndex value="0"/>
<Flags value="0"/>
<ValueNameID value="263"/> <!-- Semibold -->
<Value value="600.0"/>
</AxisValue>
<AxisValue index="6" Format="1">
<AxisIndex value="0"/>
<Flags value="0"/>
<ValueNameID value="264"/> <!-- Bold -->
<Value value="700.0"/>
</AxisValue>
<AxisValue index="7" Format="1">
<AxisIndex value="1"/>
<Flags value="0"/>
<ValueNameID value="266"/> <!-- Compressed -->
<Value value="80.0"/>
</AxisValue>
<AxisValue index="8" Format="1">
<AxisIndex value="1"/>
<Flags value="0"/>
<ValueNameID value="267"/> <!-- Condensed -->
<Value value="90.0"/>
</AxisValue>
<AxisValue index="9" Format="1">
<AxisIndex value="1"/>
<Flags value="0"/>
<ValueNameID value="268"/> <!-- Normal -->
<Value value="100.0"/>
</AxisValue>
<AxisValue index="10" Format="1">
<AxisIndex value="1"/>
<Flags value="0"/>
<ValueNameID value="269"/> <!-- Extended -->
<Value value="115.0"/>
</AxisValue>
</AxisValueArray>
<ElidedFallbackNameID value="256"/> <!-- Standard -->
</STAT>
</ttFont>

View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.39">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="A"/>
</GlyphOrder>
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="3.013"/>
<checkSumAdjustment value="0xc2b89a77"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Fri Feb 17 14:29:44 2023"/>
<modified value="Tue Mar 7 12:56:58 2023"/>
<xMin value="-6"/>
<yMin value="-250"/>
<xMax value="759"/>
<yMax value="750"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>
<hhea>
<tableVersion value="0x00010000"/>
<ascent value="1000"/>
<descent value="-300"/>
<lineGap value="0"/>
<advanceWidthMax value="762"/>
<minLeftSideBearing value="-6"/>
<minRightSideBearing value="3"/>
<xMaxExtent value="759"/>
<caretSlopeRise value="1"/>
<caretSlopeRun value="0"/>
<caretOffset value="0"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="2"/>
</hhea>
<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="2"/>
<maxPoints value="19"/>
<maxContours value="2"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="0"/>
</maxp>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<version value="4"/>
<xAvgCharWidth value="631"/>
<usWeightClass value="900"/>
<usWidthClass value="6"/>
<fsType value="00000000 00001000"/>
<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>
<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>
<yStrikeoutSize value="100"/>
<yStrikeoutPosition value="303"/>
<sFamilyClass value="0"/>
<panose>
<bFamilyType value="0"/>
<bSerifStyle value="0"/>
<bWeight value="0"/>
<bProportion value="0"/>
<bContrast value="0"/>
<bStrokeVariation value="0"/>
<bArmStyle value="0"/>
<bLetterForm value="0"/>
<bMidline value="0"/>
<bXHeight value="0"/>
</panose>
<ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
<ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
<achVendID value="NONE"/>
<fsSelection value="00000000 01000000"/>
<usFirstCharIndex value="65"/>
<usLastCharIndex value="65"/>
<sTypoAscender value="750"/>
<sTypoDescender value="-250"/>
<sTypoLineGap value="250"/>
<usWinAscent value="1000"/>
<usWinDescent value="300"/>
<ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
<ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
<sxHeight value="505"/>
<sCapHeight value="670"/>
<usDefaultChar value="0"/>
<usBreakChar value="32"/>
<usMaxContext value="0"/>
</OS_2>
<hmtx>
<mtx name=".notdef" width="500" lsb="50"/>
<mtx name="A" width="762" lsb="-6"/>
</hmtx>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="0" platEncID="3" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
</cmap>
<loca>
<!-- The 'loca' table will be calculated by the compiler -->
</loca>
<glyf>
<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->
<TTGlyph name=".notdef" xMin="50" yMin="-250" xMax="450" yMax="750">
<contour>
<pt x="50" y="-250" on="1"/>
<pt x="50" y="750" on="1"/>
<pt x="450" y="750" on="1"/>
<pt x="450" y="-250" on="1"/>
</contour>
<contour>
<pt x="100" y="-200" on="1"/>
<pt x="400" y="-200" on="1"/>
<pt x="400" y="700" on="1"/>
<pt x="100" y="700" on="1"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="A" xMin="-6" yMin="0" xMax="759" yMax="672">
<contour>
<pt x="542" y="672" on="1"/>
<pt x="735" y="121" on="1"/>
<pt x="747" y="86" on="0"/>
<pt x="759" y="24" on="0"/>
<pt x="759" y="0" on="1"/>
<pt x="501" y="0" on="1"/>
<pt x="421" y="258" on="1"/>
<pt x="384" y="458" on="1"/>
<pt x="377" y="458" on="1"/>
<pt x="244" y="0" on="1"/>
<pt x="-6" y="0" on="1"/>
<pt x="-6" y="21" on="0"/>
<pt x="4" y="87" on="0"/>
<pt x="17" y="121" on="1"/>
<pt x="233" y="668" on="1"/>
</contour>
<contour>
<pt x="545" y="259" on="1"/>
<pt x="545" y="92" on="1"/>
<pt x="176" y="92" on="1"/>
<pt x="176" y="259" on="1"/>
</contour>
<instructions/>
</TTGlyph>
</glyf>
<name>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
Test Extended Black
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
3.013;NONE;Test-ExtendedBlack
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
Test Extended Black
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 3.013
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
Test-ExtendedBlack
</namerecord>
<namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
Test
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
Extended Black
</namerecord>
</name>
<post>
<formatType value="2.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="-130"/>
<underlineThickness value="100"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
<psNames>
<!-- This file uses unique glyph names based on the information
found in the 'post' table. Since these names might not be unique,
we have to invent artificial names in case of clashes. In order to
be able to retain the original information, we need a name to
ps name mapping for those cases where they differ. That's what
you see below.
-->
</psNames>
<extraNames>
<!-- following are the name that are not taken from the standard Mac glyph order -->
</extraNames>
</post>
</ttFont>

View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.39">
<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="A"/>
</GlyphOrder>
<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="3.013"/>
<checkSumAdjustment value="0x4af8381f"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Fri Feb 17 14:29:44 2023"/>
<modified value="Tue Mar 7 12:56:58 2023"/>
<xMin value="23"/>
<yMin value="-250"/>
<xMax value="605"/>
<yMax value="750"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>
<hhea>
<tableVersion value="0x00010000"/>
<ascent value="1000"/>
<descent value="-300"/>
<lineGap value="0"/>
<advanceWidthMax value="633"/>
<minLeftSideBearing value="23"/>
<minRightSideBearing value="28"/>
<xMaxExtent value="605"/>
<caretSlopeRise value="1"/>
<caretSlopeRun value="0"/>
<caretOffset value="0"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="2"/>
</hhea>
<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="2"/>
<maxPoints value="19"/>
<maxContours value="2"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="0"/>
</maxp>
<OS_2>
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
will be recalculated by the compiler -->
<version value="4"/>
<xAvgCharWidth value="567"/>
<usWeightClass value="100"/>
<usWidthClass value="6"/>
<fsType value="00000000 00001000"/>
<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>
<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>
<yStrikeoutSize value="28"/>
<yStrikeoutPosition value="274"/>
<sFamilyClass value="0"/>
<panose>
<bFamilyType value="0"/>
<bSerifStyle value="0"/>
<bWeight value="0"/>
<bProportion value="0"/>
<bContrast value="0"/>
<bStrokeVariation value="0"/>
<bArmStyle value="0"/>
<bLetterForm value="0"/>
<bMidline value="0"/>
<bXHeight value="0"/>
</panose>
<ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
<ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
<achVendID value="NONE"/>
<fsSelection value="00000000 01000000"/>
<usFirstCharIndex value="65"/>
<usLastCharIndex value="65"/>
<sTypoAscender value="750"/>
<sTypoDescender value="-250"/>
<sTypoLineGap value="250"/>
<usWinAscent value="1000"/>
<usWinDescent value="300"/>
<ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
<ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
<sxHeight value="456"/>
<sCapHeight value="670"/>
<usDefaultChar value="0"/>
<usBreakChar value="32"/>
<usMaxContext value="0"/>
</OS_2>
<hmtx>
<mtx name=".notdef" width="500" lsb="50"/>
<mtx name="A" width="633" lsb="23"/>
</hmtx>
<cmap>
<tableVersion version="0"/>
<cmap_format_4 platformID="0" platEncID="3" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
<cmap_format_4 platformID="3" platEncID="1" language="0">
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
</cmap_format_4>
</cmap>
<loca>
<!-- The 'loca' table will be calculated by the compiler -->
</loca>
<glyf>
<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->
<TTGlyph name=".notdef" xMin="50" yMin="-250" xMax="450" yMax="750">
<contour>
<pt x="50" y="-250" on="1"/>
<pt x="50" y="750" on="1"/>
<pt x="450" y="750" on="1"/>
<pt x="450" y="-250" on="1"/>
</contour>
<contour>
<pt x="100" y="-200" on="1"/>
<pt x="400" y="-200" on="1"/>
<pt x="400" y="700" on="1"/>
<pt x="100" y="700" on="1"/>
</contour>
<instructions/>
</TTGlyph>
<TTGlyph name="A" xMin="23" yMin="0" xMax="605" yMax="672">
<contour>
<pt x="339" y="672" on="1"/>
<pt x="566" y="100" on="1"/>
<pt x="576" y="75" on="0"/>
<pt x="595" y="25" on="0"/>
<pt x="605" y="0" on="1"/>
<pt x="563" y="0" on="1"/>
<pt x="384" y="453" on="1"/>
<pt x="320" y="626" on="1"/>
<pt x="317" y="626" on="1"/>
<pt x="62" y="0" on="1"/>
<pt x="23" y="0" on="1"/>
<pt x="34" y="25" on="0"/>
<pt x="54" y="75" on="0"/>
<pt x="64" y="100" on="1"/>
<pt x="297" y="668" on="1"/>
</contour>
<contour>
<pt x="491" y="250" on="1"/>
<pt x="491" y="217" on="1"/>
<pt x="139" y="217" on="1"/>
<pt x="139" y="250" on="1"/>
</contour>
<instructions/>
</TTGlyph>
</glyf>
<name>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
Test Extended Thin
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
3.013;NONE;Test-ExtendedThin
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
Test Extended Thin
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 3.013
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
Test-ExtendedThin
</namerecord>
<namerecord nameID="16" platformID="3" platEncID="1" langID="0x409">
Test
</namerecord>
<namerecord nameID="17" platformID="3" platEncID="1" langID="0x409">
Extended Thin
</namerecord>
</name>
<post>
<formatType value="2.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="-130"/>
<underlineThickness value="28"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
<psNames>
<!-- This file uses unique glyph names based on the information
found in the 'post' table. Since these names might not be unique,
we have to invent artificial names in case of clashes. In order to
be able to retain the original information, we need a name to
ps name mapping for those cases where they differ. That's what
you see below.
-->
</psNames>
<extraNames>
<!-- following are the name that are not taken from the standard Mac glyph order -->
</extraNames>
</post>
</ttFont>

View File

@ -1,7 +1,7 @@
from fontTools.colorLib.builder import buildCOLR
from fontTools.ttLib import TTFont, newTable
from fontTools.ttLib.tables import otTables as ot
from fontTools.varLib import build, load_designspace, _add_COLR
from fontTools.varLib import build, build_many, load_designspace, _add_COLR
from fontTools.varLib.errors import VarLibValidationError
import fontTools.varLib.errors as varLibErrors
from fontTools.varLib.models import VariationModel
@ -493,6 +493,74 @@ class BuildTest(unittest.TestCase):
expected_ttx_path = self.get_test_output("BuildMain.ttx")
self.expect_ttx(varfont, expected_ttx_path, tables)
def test_varLib_main_output_dir(self):
self.temp_dir()
outdir = os.path.join(self.tempdir, "output_dir_test")
self.assertFalse(os.path.exists(outdir))
ds_path = os.path.join(self.tempdir, "BuildMain.designspace")
shutil.copy2(self.get_test_input("Build.designspace"), ds_path)
shutil.copytree(
self.get_test_input("master_ttx_interpolatable_ttf"),
os.path.join(outdir, "master_ttx"),
)
finder = "%s/output_dir_test/master_ttx/{stem}.ttx" % self.tempdir
varLib_main([ds_path, "--output-dir", outdir, "--master-finder", finder])
self.assertTrue(os.path.isdir(outdir))
self.assertTrue(os.path.exists(os.path.join(outdir, "BuildMain-VF.ttf")))
def test_varLib_main_filter_variable_fonts(self):
self.temp_dir()
outdir = os.path.join(self.tempdir, "filter_variable_fonts_test")
self.assertFalse(os.path.exists(outdir))
ds_path = os.path.join(self.tempdir, "BuildMain.designspace")
shutil.copy2(self.get_test_input("Build.designspace"), ds_path)
shutil.copytree(
self.get_test_input("master_ttx_interpolatable_ttf"),
os.path.join(outdir, "master_ttx"),
)
finder = "%s/filter_variable_fonts_test/master_ttx/{stem}.ttx" % self.tempdir
cmd = [ds_path, "--output-dir", outdir, "--master-finder", finder]
with pytest.raises(SystemExit):
varLib_main(cmd + ["--variable-fonts", "FooBar"]) # no font matches
varLib_main(cmd + ["--variable-fonts", "Build.*"]) # this does match
self.assertTrue(os.path.isdir(outdir))
self.assertTrue(os.path.exists(os.path.join(outdir, "BuildMain-VF.ttf")))
def test_varLib_build_many_no_overwrite_STAT(self):
# Ensure that varLib.build_many doesn't overwrite a pre-existing STAT table,
# e.g. one built by feaLib from features.fea; the VF simply should inherit the
# STAT from the base master: https://github.com/googlefonts/fontmake/issues/985
base_master = TTFont()
base_master.importXML(
self.get_test_input("master_no_overwrite_stat/Test-CondensedThin.ttx")
)
assert "STAT" in base_master
vf = next(
iter(
build_many(
DesignSpaceDocument.fromfile(
self.get_test_input("TestNoOverwriteSTAT.designspace")
)
).values()
)
)
assert "STAT" in vf
assert vf["STAT"].table == base_master["STAT"].table
def test_varlib_build_from_ds_object_in_memory_ttfonts(self):
ds_path = self.get_test_input("Build.designspace")
ttx_dir = self.get_test_input("master_ttx_interpolatable_ttf")