Merge pull request #1677 from fonttools/fdselct-format-4
[cffLib] Support FDSselect format 4
This commit is contained in:
commit
71ea0cbe07
@ -831,6 +831,23 @@ class FDSelect(object):
|
|||||||
for glyphID in range(prev, first):
|
for glyphID in range(prev, first):
|
||||||
gidArray[glyphID] = fd
|
gidArray[glyphID] = fd
|
||||||
self.gidArray = gidArray
|
self.gidArray = gidArray
|
||||||
|
elif self.format == 4:
|
||||||
|
gidArray = [None] * numGlyphs
|
||||||
|
nRanges = readCard32(file)
|
||||||
|
fd = None
|
||||||
|
prev = None
|
||||||
|
for i in range(nRanges):
|
||||||
|
first = readCard32(file)
|
||||||
|
if prev is not None:
|
||||||
|
for glyphID in range(prev, first):
|
||||||
|
gidArray[glyphID] = fd
|
||||||
|
prev = first
|
||||||
|
fd = readCard16(file)
|
||||||
|
if prev is not None:
|
||||||
|
first = readCard32(file)
|
||||||
|
for glyphID in range(prev, first):
|
||||||
|
gidArray[glyphID] = fd
|
||||||
|
self.gidArray = gidArray
|
||||||
else:
|
else:
|
||||||
assert False, "unsupported FDSelect format: %s" % format
|
assert False, "unsupported FDSelect format: %s" % format
|
||||||
else:
|
else:
|
||||||
@ -1001,6 +1018,10 @@ def packCard16(value):
|
|||||||
return struct.pack(">H", value)
|
return struct.pack(">H", value)
|
||||||
|
|
||||||
|
|
||||||
|
def packCard32(value):
|
||||||
|
return struct.pack(">L", value)
|
||||||
|
|
||||||
|
|
||||||
def buildOperatorDict(table):
|
def buildOperatorDict(table):
|
||||||
d = {}
|
d = {}
|
||||||
for op, name, arg, default, conv in table:
|
for op, name, arg, default, conv in table:
|
||||||
@ -1732,6 +1753,27 @@ def packFDSelect3(fdSelectArray):
|
|||||||
return bytesjoin(data)
|
return bytesjoin(data)
|
||||||
|
|
||||||
|
|
||||||
|
def packFDSelect4(fdSelectArray):
|
||||||
|
fmt = 4
|
||||||
|
fdRanges = []
|
||||||
|
lenArray = len(fdSelectArray)
|
||||||
|
lastFDIndex = -1
|
||||||
|
for i in range(lenArray):
|
||||||
|
fdIndex = fdSelectArray[i]
|
||||||
|
if lastFDIndex != fdIndex:
|
||||||
|
fdRanges.append([i, fdIndex])
|
||||||
|
lastFDIndex = fdIndex
|
||||||
|
sentinelGID = i + 1
|
||||||
|
|
||||||
|
data = [packCard8(fmt)]
|
||||||
|
data.append(packCard32(len(fdRanges)))
|
||||||
|
for fdRange in fdRanges:
|
||||||
|
data.append(packCard32(fdRange[0]))
|
||||||
|
data.append(packCard16(fdRange[1]))
|
||||||
|
data.append(packCard32(sentinelGID))
|
||||||
|
return bytesjoin(data)
|
||||||
|
|
||||||
|
|
||||||
class FDSelectCompiler(object):
|
class FDSelectCompiler(object):
|
||||||
|
|
||||||
def __init__(self, fdSelect, parent):
|
def __init__(self, fdSelect, parent):
|
||||||
@ -1741,6 +1783,8 @@ class FDSelectCompiler(object):
|
|||||||
self.data = packFDSelect0(fdSelectArray)
|
self.data = packFDSelect0(fdSelectArray)
|
||||||
elif fmt == 3:
|
elif fmt == 3:
|
||||||
self.data = packFDSelect3(fdSelectArray)
|
self.data = packFDSelect3(fdSelectArray)
|
||||||
|
elif fmt == 4:
|
||||||
|
self.data = packFDSelect4(fdSelectArray)
|
||||||
else:
|
else:
|
||||||
# choose smaller of the two formats
|
# choose smaller of the two formats
|
||||||
data0 = packFDSelect0(fdSelectArray)
|
data0 = packFDSelect0(fdSelectArray)
|
||||||
|
@ -79,6 +79,20 @@ class CffLibTest(DataFilesHandler):
|
|||||||
font.importXML(ttx_path)
|
font.importXML(ttx_path)
|
||||||
copy.deepcopy(font)
|
copy.deepcopy(font)
|
||||||
|
|
||||||
|
def test_FDSelect_format_4(self):
|
||||||
|
ttx_path = self.getpath('TestFDSelect4.ttx')
|
||||||
|
font = TTFont(recalcBBoxes=False, recalcTimestamp=False)
|
||||||
|
font.importXML(ttx_path)
|
||||||
|
|
||||||
|
self.temp_dir()
|
||||||
|
save_path = os.path.join(self.tempdir, 'TestOTF.otf')
|
||||||
|
font.save(save_path)
|
||||||
|
|
||||||
|
font2 = TTFont(save_path)
|
||||||
|
topDict2 = font2["CFF2"].cff.topDictIndex[0]
|
||||||
|
self.assertEqual(topDict2.FDSelect.format, 4)
|
||||||
|
self.assertEqual(topDict2.FDSelect.gidArray, [0, 0, 1])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
sys.exit(unittest.main())
|
sys.exit(unittest.main())
|
||||||
|
211
Tests/cffLib/data/TestFDSelect4.ttx
Normal file
211
Tests/cffLib/data/TestFDSelect4.ttx
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ttFont sfntVersion="OTTO" ttLibVersion="3.43">
|
||||||
|
|
||||||
|
<GlyphOrder>
|
||||||
|
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||||
|
<GlyphID id="0" name=".notdef"/>
|
||||||
|
<GlyphID id="1" name="A"/>
|
||||||
|
<GlyphID id="2" name="a"/>
|
||||||
|
</GlyphOrder>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<!-- Most of this table will be recalculated by the compiler -->
|
||||||
|
<tableVersion value="1.0"/>
|
||||||
|
<fontRevision value="1.004"/>
|
||||||
|
<checkSumAdjustment value="0x61e1f145"/>
|
||||||
|
<magicNumber value="0x5f0f3cf5"/>
|
||||||
|
<flags value="00000000 00000011"/>
|
||||||
|
<unitsPerEm value="1000"/>
|
||||||
|
<created value="Sat Oct 10 16:55:59 2015"/>
|
||||||
|
<modified value="Mon Jul 29 22:04:10 2019"/>
|
||||||
|
<xMin value="-454"/>
|
||||||
|
<yMin value="-322"/>
|
||||||
|
<xMax value="2159"/>
|
||||||
|
<yMax value="968"/>
|
||||||
|
<macStyle value="00000000 00000000"/>
|
||||||
|
<lowestRecPPEM value="6"/>
|
||||||
|
<fontDirectionHint value="2"/>
|
||||||
|
<indexToLocFormat value="0"/>
|
||||||
|
<glyphDataFormat value="0"/>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<hhea>
|
||||||
|
<tableVersion value="0x00010000"/>
|
||||||
|
<ascent value="900"/>
|
||||||
|
<descent value="-300"/>
|
||||||
|
<lineGap value="96"/>
|
||||||
|
<advanceWidthMax value="2200"/>
|
||||||
|
<minLeftSideBearing value="-454"/>
|
||||||
|
<minRightSideBearing value="-454"/>
|
||||||
|
<xMaxExtent value="2159"/>
|
||||||
|
<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="3"/>
|
||||||
|
</hhea>
|
||||||
|
|
||||||
|
<maxp>
|
||||||
|
<tableVersion value="0x5000"/>
|
||||||
|
<numGlyphs value="3"/>
|
||||||
|
</maxp>
|
||||||
|
|
||||||
|
<OS_2>
|
||||||
|
<!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
|
||||||
|
will be recalculated by the compiler -->
|
||||||
|
<version value="4"/>
|
||||||
|
<xAvgCharWidth value="564"/>
|
||||||
|
<usWeightClass value="500"/>
|
||||||
|
<usWidthClass value="5"/>
|
||||||
|
<fsType value="00000000 00000000"/>
|
||||||
|
<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="294"/>
|
||||||
|
<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="ALIF"/>
|
||||||
|
<fsSelection value="00000000 11000000"/>
|
||||||
|
<usFirstCharIndex value="65"/>
|
||||||
|
<usLastCharIndex value="97"/>
|
||||||
|
<sTypoAscender value="900"/>
|
||||||
|
<sTypoDescender value="-300"/>
|
||||||
|
<sTypoLineGap value="100"/>
|
||||||
|
<usWinAscent value="790"/>
|
||||||
|
<usWinDescent value="330"/>
|
||||||
|
<ulCodePageRange1 value="00100000 00000000 00000001 11011111"/>
|
||||||
|
<ulCodePageRange2 value="00000000 00001000 00000000 00000000"/>
|
||||||
|
<sxHeight value="489"/>
|
||||||
|
<sCapHeight value="655"/>
|
||||||
|
<usDefaultChar value="0"/>
|
||||||
|
<usBreakChar value="32"/>
|
||||||
|
<usMaxContext value="3"/>
|
||||||
|
</OS_2>
|
||||||
|
|
||||||
|
<hmtx>
|
||||||
|
<mtx name=".notdef" width="663" lsb="86"/>
|
||||||
|
<mtx name="A" width="552" lsb="0"/>
|
||||||
|
<mtx name="a" width="510" lsb="49"/>
|
||||||
|
</hmtx>
|
||||||
|
|
||||||
|
<cmap>
|
||||||
|
<tableVersion version="0"/>
|
||||||
|
<cmap_format_4 platformID="0" platEncID="3" language="0">
|
||||||
|
<map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A -->
|
||||||
|
<map code="0x61" name="a"/><!-- LATIN SMALL LETTER A -->
|
||||||
|
</cmap_format_4>
|
||||||
|
</cmap>
|
||||||
|
|
||||||
|
<name>
|
||||||
|
<namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
|
||||||
|
Copyright © 2015-2019 The Mada Project Authors, with Reserved Font Name “Source”.
|
||||||
|
</namerecord>
|
||||||
|
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
|
||||||
|
Mada Medium
|
||||||
|
</namerecord>
|
||||||
|
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
|
||||||
|
Mada-Medium
|
||||||
|
</namerecord>
|
||||||
|
</name>
|
||||||
|
|
||||||
|
<post>
|
||||||
|
<formatType value="3.0"/>
|
||||||
|
<italicAngle value="0.0"/>
|
||||||
|
<underlinePosition value="-200"/>
|
||||||
|
<underlineThickness value="50"/>
|
||||||
|
<isFixedPitch value="0"/>
|
||||||
|
<minMemType42 value="0"/>
|
||||||
|
<maxMemType42 value="0"/>
|
||||||
|
<minMemType1 value="0"/>
|
||||||
|
<maxMemType1 value="0"/>
|
||||||
|
</post>
|
||||||
|
|
||||||
|
<CFF2>
|
||||||
|
<major value="2"/>
|
||||||
|
<minor value="0"/>
|
||||||
|
<CFFFont name="CFF2Font">
|
||||||
|
<FontMatrix value="0.001 0 0 0.001 0 0"/>
|
||||||
|
<FDSelect format="4"/>
|
||||||
|
<FDArray>
|
||||||
|
<FontDict index="0">
|
||||||
|
<Private>
|
||||||
|
<BlueScale value="0.039625"/>
|
||||||
|
<BlueShift value="7"/>
|
||||||
|
<BlueFuzz value="1"/>
|
||||||
|
</Private>
|
||||||
|
</FontDict>
|
||||||
|
<FontDict index="1">
|
||||||
|
<Private>
|
||||||
|
<BlueScale value="0.039625"/>
|
||||||
|
<BlueShift value="7"/>
|
||||||
|
<BlueFuzz value="1"/>
|
||||||
|
</Private>
|
||||||
|
</FontDict>
|
||||||
|
</FDArray>
|
||||||
|
<CharStrings>
|
||||||
|
<CharString name=".notdef" fdSelectIndex="0">
|
||||||
|
</CharString>
|
||||||
|
<CharString name="A" fdSelectIndex="0">
|
||||||
|
0 hmoveto
|
||||||
|
103 hlineto
|
||||||
|
107 357 22 71 20 73 19 74 rlinecurve
|
||||||
|
4 hlineto
|
||||||
|
20 -74 20 -73 22 -71 rrcurveto
|
||||||
|
106 -357 108 0 -217 655 rlineto
|
||||||
|
-117 hlineto
|
||||||
|
-96 -467 rmoveto
|
||||||
|
306 hlineto
|
||||||
|
0 80 rlineto
|
||||||
|
-306 hlineto
|
||||||
|
</CharString>
|
||||||
|
<CharString name="a" fdSelectIndex="1">
|
||||||
|
193 -12 rmoveto
|
||||||
|
60 52 30 38 45 hvcurveto
|
||||||
|
3 hlineto
|
||||||
|
8 -56 82 0 0 294 rlineto
|
||||||
|
130 0 -56 77 -121 hhcurveto
|
||||||
|
-78 -69 -32 -32 -50 hvcurveto
|
||||||
|
38 -68 rlineto
|
||||||
|
26 41 48 24 52 hhcurveto
|
||||||
|
73 20 -51 -57 1 hvcurveto
|
||||||
|
-204 -22 -89 -54 0 -106 rrcurveto
|
||||||
|
-86 0 60 -55 84 hhcurveto
|
||||||
|
31 79 rmoveto
|
||||||
|
-44 -34 21 49 0 hvcurveto
|
||||||
|
0 55 50 37 146 18 0 -122 rcurveline
|
||||||
|
-38 -41 -34 -21 -43 hhcurveto
|
||||||
|
</CharString>
|
||||||
|
</CharStrings>
|
||||||
|
</CFFFont>
|
||||||
|
|
||||||
|
<GlobalSubrs>
|
||||||
|
<!-- The 'index' attribute is only for humans; it is ignored when parsed. -->
|
||||||
|
</GlobalSubrs>
|
||||||
|
</CFF2>
|
||||||
|
|
||||||
|
</ttFont>
|
Loading…
x
Reference in New Issue
Block a user