diff options
-rw-r--r-- | Lib/fontTools/__init__.py | 2 | ||||
-rw-r--r-- | Lib/fontTools/misc/plistlib/__init__.py | 2 | ||||
-rw-r--r-- | Lib/fontTools/ttLib/woff2.py | 4 | ||||
-rw-r--r-- | METADATA | 12 | ||||
-rw-r--r-- | NEWS.rst | 6 | ||||
-rw-r--r-- | Tests/ttLib/data/woff2_overlap_offcurve_in.ttx | 306 | ||||
-rw-r--r-- | Tests/ttLib/woff2_test.py | 15 | ||||
-rw-r--r-- | setup.cfg | 2 | ||||
-rwxr-xr-x | setup.py | 2 |
9 files changed, 336 insertions, 15 deletions
diff --git a/Lib/fontTools/__init__.py b/Lib/fontTools/__init__.py index cc7d69f9..16ee8a4e 100644 --- a/Lib/fontTools/__init__.py +++ b/Lib/fontTools/__init__.py @@ -4,6 +4,6 @@ from fontTools.misc.loggingTools import configLogger log = logging.getLogger(__name__) -version = __version__ = "4.19.0" +version = __version__ = "4.19.1" __all__ = ["version", "log", "configLogger"] diff --git a/Lib/fontTools/misc/plistlib/__init__.py b/Lib/fontTools/misc/plistlib/__init__.py index 1335e8cb..d8391041 100644 --- a/Lib/fontTools/misc/plistlib/__init__.py +++ b/Lib/fontTools/misc/plistlib/__init__.py @@ -543,7 +543,7 @@ def load( if not hasattr(fp, "read"): raise AttributeError("'%s' object has no attribute 'read'" % type(fp).__name__) target = PlistTarget(use_builtin_types=use_builtin_types, dict_type=dict_type) - parser = etree.XMLParser(target=target) # type: ignore + parser = etree.XMLParser(target=target) result = etree.parse(fp, parser=parser) # lxml returns the target object directly, while ElementTree wraps # it as the root of an ElementTree object diff --git a/Lib/fontTools/ttLib/woff2.py b/Lib/fontTools/ttLib/woff2.py index 75b55527..d088b70f 100644 --- a/Lib/fontTools/ttLib/woff2.py +++ b/Lib/fontTools/ttLib/woff2.py @@ -11,7 +11,7 @@ from fontTools.ttLib import (TTFont, TTLibError, getTableModule, getTableClass, from fontTools.ttLib.sfnt import (SFNTReader, SFNTWriter, DirectoryEntry, WOFFFlavorData, sfntDirectoryFormat, sfntDirectorySize, SFNTDirectoryEntry, sfntDirectoryEntrySize, calcChecksum) -from fontTools.ttLib.tables import ttProgram +from fontTools.ttLib.tables import ttProgram, _g_l_y_f import logging @@ -934,7 +934,7 @@ class WOFF2GlyfTable(getTableClass('glyf')): flags = array.array('B') triplets = array.array('B') for i in range(len(coordinates)): - onCurve = glyph.flags[i] + onCurve = glyph.flags[i] & _g_l_y_f.flagOnCurve x, y = coordinates[i] absX = abs(x) absY = abs(y) @@ -1,6 +1,3 @@ -# *** THIS PACKAGE HAS SPECIAL LICENSING CONDITIONS. PLEASE -# CONSULT THE OWNERS AND opensource-licensing@google.com BEFORE -# DEPENDING ON IT IN YOUR PROJECT. *** name: "fonttools" description: "fontTools is a library for manipulating fonts, written in Python." third_party { @@ -10,16 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://github.com/fonttools/fonttools/archive/4.19.0.zip" + value: "https://github.com/fonttools/fonttools/archive/4.19.1.zip" } - version: "4.19.0" - # would be NOTICE except for: - # Doc/README.md - # or RESTRICTED except for the SIL OFL 1.1 license + version: "4.19.1" license_type: BY_EXCEPTION_ONLY last_upgrade_date { year: 2021 month: 1 - day: 25 + day: 28 } } @@ -1,3 +1,9 @@ +4.19.1 (released 2021-01-28) +---------------------------- + +- [woff2] An initial off-curve point with an overlap flag now stays an off-curve + point after compression. + 4.19.0 (released 2021-01-25) ---------------------------- diff --git a/Tests/ttLib/data/woff2_overlap_offcurve_in.ttx b/Tests/ttLib/data/woff2_overlap_offcurve_in.ttx new file mode 100644 index 00000000..a36dbf50 --- /dev/null +++ b/Tests/ttLib/data/woff2_overlap_offcurve_in.ttx @@ -0,0 +1,306 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.18"> + + <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="1.0"/> + <checkSumAdjustment value="0x9aec19bb"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000010"/> + <unitsPerEm value="1000"/> + <created value="Thu Jan 28 15:17:57 2021"/> + <modified value="Thu Jan 28 15:52:10 2021"/> + <xMin value="178"/> + <yMin value="72"/> + <xMax value="586"/> + <yMax value="480"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="750"/> + <descent value="-250"/> + <lineGap value="100"/> + <advanceWidthMax value="639"/> + <minLeftSideBearing value="178"/> + <minRightSideBearing value="53"/> + <xMaxExtent value="586"/> + <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="20"/> + <maxContours value="1"/> + <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="445"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000100"/> + <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="50"/> + <yStrikeoutPosition value="300"/> + <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 11000000"/> + <usFirstCharIndex value="65"/> + <usLastCharIndex value="65"/> + <sTypoAscender value="750"/> + <sTypoDescender value="-250"/> + <sTypoLineGap value="100"/> + <usWinAscent value="750"/> + <usWinDescent value="250"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="700"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="0"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="250" lsb="0"/> + <mtx name="A" width="639" lsb="178"/> + </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"/><!-- contains no outline data --> + + <TTGlyph name="A" xMin="178" yMin="72" xMax="586" yMax="480"> + <contour> + <pt x="382" y="72" on="0" overlap="1"/> + <pt x="336" y="72" on="1"/> + <pt x="261" y="101" on="0"/> + <pt x="207" y="155" on="0"/> + <pt x="178" y="230" on="0"/> + <pt x="178" y="276" on="1"/> + <pt x="178" y="322" on="0"/> + <pt x="207" y="397" on="0"/> + <pt x="261" y="451" on="0"/> + <pt x="336" y="480" on="0"/> + <pt x="382" y="480" on="1"/> + <pt x="428" y="480" on="0"/> + <pt x="503" y="451" on="0"/> + <pt x="557" y="397" on="0"/> + <pt x="586" y="322" on="0"/> + <pt x="586" y="276" on="1"/> + <pt x="586" y="230" on="0"/> + <pt x="557" y="155" on="0"/> + <pt x="503" y="101" on="0"/> + <pt x="428" y="72" on="0"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="256" platformID="1" platEncID="0" langID="0x0" unicode="True"> + Weight + </namerecord> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Unnamed + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="3" platformID="3" platEncID="1" langID="0x409"> + 1.000;NONE;Unnamed-Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Unnamed Regular + </namerecord> + <namerecord nameID="5" platformID="3" platEncID="1" langID="0x409"> + Version 1.000 + </namerecord> + <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409"> + Unnamed-Regular + </namerecord> + <namerecord nameID="256" platformID="3" platEncID="1" langID="0x409"> + Weight + </namerecord> + </name> + + <post> + <formatType value="2.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="-100"/> + <underlineThickness value="50"/> + <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> + + <gasp> + <gaspRange rangeMaxPPEM="65535" rangeGaspBehavior="15"/> + </gasp> + + <HVAR> + <Version value="0x00010000"/> + <VarStore Format="1"> + <Format value="1"/> + <VarRegionList> + <!-- RegionAxisCount=1 --> + <!-- RegionCount=1 --> + <Region index="0"> + <VarRegionAxis index="0"> + <StartCoord value="0.0"/> + <PeakCoord value="1.0"/> + <EndCoord value="1.0"/> + </VarRegionAxis> + </Region> + </VarRegionList> + <!-- VarDataCount=1 --> + <VarData index="0"> + <!-- ItemCount=2 --> + <NumShorts value="0"/> + <!-- VarRegionCount=0 --> + <Item index="0" value="[]"/> + <Item index="1" value="[]"/> + </VarData> + </VarStore> + </HVAR> + + <STAT> + <Version value="0x00010001"/> + <DesignAxisRecordSize value="8"/> + <!-- DesignAxisCount=1 --> + <DesignAxisRecord> + <Axis index="0"> + <AxisTag value="wght"/> + <AxisNameID value="256"/> <!-- Weight --> + <AxisOrdering value="0"/> + </Axis> + </DesignAxisRecord> + <!-- AxisValueCount=0 --> + <ElidedFallbackNameID value="2"/> <!-- Regular --> + </STAT> + + <fvar> + + <!-- Weight --> + <Axis> + <AxisTag>wght</AxisTag> + <Flags>0x0</Flags> + <MinValue>400.0</MinValue> + <DefaultValue>400.0</DefaultValue> + <MaxValue>700.0</MaxValue> + <AxisNameID>256</AxisNameID> + </Axis> + </fvar> + + <gvar> + <version value="1"/> + <reserved value="0"/> + <glyphVariations glyph="A"> + <tuple> + <coord axis="wght" value="1.0"/> + <delta pt="0" x="-64" y="-44"/> + <delta pt="5" x="-138" y="30"/> + <delta pt="7" x="-127" y="73"/> + <delta pt="8" x="-108" y="92"/> + <delta pt="10" x="-64" y="103"/> + <delta pt="12" x="-21" y="92"/> + <delta pt="13" x="-2" y="73"/> + <delta pt="16" x="9" y="13"/> + <delta pt="17" x="-2" y="-14"/> + <delta pt="18" x="-21" y="-33"/> + </tuple> + </glyphVariations> + </gvar> + +</ttFont> diff --git a/Tests/ttLib/woff2_test.py b/Tests/ttLib/woff2_test.py index 5923b7f2..23aab4aa 100644 --- a/Tests/ttLib/woff2_test.py +++ b/Tests/ttLib/woff2_test.py @@ -1,6 +1,7 @@ from fontTools.misc.py23 import * from fontTools import ttLib from fontTools.ttLib import woff2 +from fontTools.ttLib.tables import _g_l_y_f from fontTools.ttLib.woff2 import ( WOFF2Reader, woff2DirectorySize, woff2DirectoryFormat, woff2FlagsSize, woff2UnknownTagSize, woff2Base128MaxSize, WOFF2DirectoryEntry, @@ -1220,6 +1221,20 @@ class WOFF2RoundtripTest(object): assert tmp.getvalue() == tmp2.getvalue() assert ttFont.flavor == "woff2" + def test_roundtrip_off_curve_despite_overlap_bit(self): + ttx = os.path.join(data_dir, "woff2_overlap_offcurve_in.ttx") + ttFont = ttLib.TTFont() + ttFont.importXML(ttx) + + assert ttFont["glyf"]["A"].flags[0] == _g_l_y_f.flagOverlapSimple + + ttFont.flavor = "woff2" + tmp = BytesIO() + ttFont.save(tmp) + + _, ttFont2 = self.roundtrip(tmp) + assert ttFont2.flavor == "woff2" + assert ttFont2["glyf"]["A"].flags[0] == 0 class MainTest(object): @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4.19.0 +current_version = 4.19.1 commit = True tag = False tag_name = {new_version} @@ -441,7 +441,7 @@ if ext_modules: setup_params = dict( name="fonttools", - version="4.19.0", + version="4.19.1", description="Tools to manipulate font files", author="Just van Rossum", author_email="just@letterror.com", |