Add glyf flags bit6 to ttx output (#1316)
* Implement glyf outline flags bit 6 when decompiling/compiling * Add test data for outline flag bit 6 * Rename flags, use bitwise OR for setting flag bit * Remove unneeded code
This commit is contained in:
parent
5c2ea41fa6
commit
7c8077a63d
@ -260,8 +260,11 @@ flagYShort = 0x04
|
||||
flagRepeat = 0x08
|
||||
flagXsame = 0x10
|
||||
flagYsame = 0x20
|
||||
flagReserved1 = 0x40
|
||||
flagReserved2 = 0x80
|
||||
flagOverlapSimple = 0x40
|
||||
flagReserved = 0x80
|
||||
|
||||
# These flags are kept for XML output after decompiling the coordinates
|
||||
keepFlags = flagOnCurve + flagOverlapSimple
|
||||
|
||||
_flagSignBytes = {
|
||||
0: 2,
|
||||
@ -408,10 +411,15 @@ class Glyph(object):
|
||||
writer.begintag("contour")
|
||||
writer.newline()
|
||||
for j in range(last, self.endPtsOfContours[i] + 1):
|
||||
writer.simpletag("pt", [
|
||||
attrs = [
|
||||
("x", self.coordinates[j][0]),
|
||||
("y", self.coordinates[j][1]),
|
||||
("on", self.flags[j] & flagOnCurve)])
|
||||
("on", self.flags[j] & flagOnCurve),
|
||||
]
|
||||
if self.flags[j] & flagOverlapSimple:
|
||||
# Apple's rasterizer uses flagOverlapSimple in the first contour/first pt to flag glyphs that contain overlapping contours
|
||||
attrs.append(("overlap", 1))
|
||||
writer.simpletag("pt", attrs)
|
||||
writer.newline()
|
||||
last = self.endPtsOfContours[i] + 1
|
||||
writer.endtag("contour")
|
||||
@ -441,7 +449,10 @@ class Glyph(object):
|
||||
if name != "pt":
|
||||
continue # ignore anything but "pt"
|
||||
coordinates.append((safeEval(attrs["x"]), safeEval(attrs["y"])))
|
||||
flags.append(not not safeEval(attrs["on"]))
|
||||
flag = not not safeEval(attrs["on"])
|
||||
if "overlap" in attrs and bool(safeEval(attrs["overlap"])):
|
||||
flag |= flagOverlapSimple
|
||||
flags.append(flag)
|
||||
flags = array.array("B", flags)
|
||||
if not hasattr(self, "coordinates"):
|
||||
self.coordinates = coordinates
|
||||
@ -560,8 +571,8 @@ class Glyph(object):
|
||||
assert xIndex == len(xCoordinates)
|
||||
assert yIndex == len(yCoordinates)
|
||||
coordinates.relativeToAbsolute()
|
||||
# discard all flags but for "flagOnCurve"
|
||||
self.flags = array.array("B", (f & flagOnCurve for f in flags))
|
||||
# discard all flags except "keepFlags"
|
||||
self.flags = array.array("B", (f & keepFlags for f in flags))
|
||||
|
||||
def decompileCoordinatesRaw(self, nCoordinates, data):
|
||||
# unpack flags and prepare unpacking of coordinates
|
||||
|
@ -1,10 +1,14 @@
|
||||
from __future__ import print_function, division, absolute_import
|
||||
from fontTools.misc.py23 import *
|
||||
from fontTools.misc.fixedTools import otRound
|
||||
from fontTools.ttLib import TTFont, newTable
|
||||
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
|
||||
import sys
|
||||
import array
|
||||
import pytest
|
||||
import re
|
||||
import os
|
||||
import unittest
|
||||
|
||||
|
||||
class GlyphCoordinatesTest(object):
|
||||
@ -158,3 +162,60 @@ class GlyphCoordinatesTest(object):
|
||||
g.append((0x8000, 0))
|
||||
assert g.array.typecode == "d"
|
||||
assert g.array == array.array("d", [1.0, 1.0, 32768.0, 0.0])
|
||||
|
||||
|
||||
CURR_DIR = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
|
||||
DATA_DIR = os.path.join(CURR_DIR, 'data')
|
||||
|
||||
GLYF_TTX = os.path.join(DATA_DIR, "_g_l_y_f_outline_flag_bit6.ttx")
|
||||
GLYF_BIN = os.path.join(DATA_DIR, "_g_l_y_f_outline_flag_bit6.glyf.bin")
|
||||
HEAD_BIN = os.path.join(DATA_DIR, "_g_l_y_f_outline_flag_bit6.head.bin")
|
||||
LOCA_BIN = os.path.join(DATA_DIR, "_g_l_y_f_outline_flag_bit6.loca.bin")
|
||||
MAXP_BIN = os.path.join(DATA_DIR, "_g_l_y_f_outline_flag_bit6.maxp.bin")
|
||||
|
||||
|
||||
def strip_ttLibVersion(string):
|
||||
return re.sub(' ttLibVersion=".*"', '', string)
|
||||
|
||||
|
||||
class glyfTableTest(unittest.TestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
with open(GLYF_BIN, 'rb') as f:
|
||||
cls.glyfData = f.read()
|
||||
with open(HEAD_BIN, 'rb') as f:
|
||||
cls.headData = f.read()
|
||||
with open(LOCA_BIN, 'rb') as f:
|
||||
cls.locaData = f.read()
|
||||
with open(MAXP_BIN, 'rb') as f:
|
||||
cls.maxpData = f.read()
|
||||
with open(GLYF_TTX, 'r') as f:
|
||||
cls.glyfXML = strip_ttLibVersion(f.read()).splitlines()
|
||||
|
||||
def test_toXML(self):
|
||||
font = TTFont(sfntVersion="\x00\x01\x00\x00")
|
||||
glyfTable = font['glyf'] = newTable('glyf')
|
||||
font['head'] = newTable('head')
|
||||
font['loca'] = newTable('loca')
|
||||
font['maxp'] = newTable('maxp')
|
||||
font['maxp'].decompile(self.maxpData, font)
|
||||
font['head'].decompile(self.headData, font)
|
||||
font['loca'].decompile(self.locaData, font)
|
||||
glyfTable.decompile(self.glyfData, font)
|
||||
out = UnicodeIO()
|
||||
font.saveXML(out)
|
||||
glyfXML = strip_ttLibVersion(out.getvalue()).splitlines()
|
||||
self.assertEqual(glyfXML, self.glyfXML)
|
||||
|
||||
def test_fromXML(self):
|
||||
font = TTFont(sfntVersion="\x00\x01\x00\x00")
|
||||
font.importXML(GLYF_TTX)
|
||||
glyfTable = font['glyf']
|
||||
glyfData = glyfTable.compile(font)
|
||||
self.assertEqual(glyfData, self.glyfData)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
sys.exit(unittest.main())
|
||||
|
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.glyf.bin
Normal file
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.glyf.bin
Normal file
Binary file not shown.
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.head.bin
Normal file
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.head.bin
Normal file
Binary file not shown.
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.loca.bin
Normal file
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.loca.bin
Normal file
Binary file not shown.
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.maxp.bin
Normal file
BIN
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.maxp.bin
Normal file
Binary file not shown.
88
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.ttx
Normal file
88
Tests/ttLib/tables/data/_g_l_y_f_outline_flag_bit6.ttx
Normal file
@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.29">
|
||||
|
||||
<GlyphOrder>
|
||||
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||
<GlyphID id="0" name=".notdef"/>
|
||||
<GlyphID id="1" name="glyph00001"/>
|
||||
<GlyphID id="2" name="glyph00002"/>
|
||||
<GlyphID id="3" name="glyph00003"/>
|
||||
</GlyphOrder>
|
||||
|
||||
<head>
|
||||
<!-- Most of this table will be recalculated by the compiler -->
|
||||
<tableVersion value="1.0"/>
|
||||
<fontRevision value="1.0"/>
|
||||
<checkSumAdjustment value="0x6e4f1ccf"/>
|
||||
<magicNumber value="0x5f0f3cf5"/>
|
||||
<flags value="00100000 00011011"/>
|
||||
<unitsPerEm value="2048"/>
|
||||
<created value="Thu Sep 13 14:22:20 2018"/>
|
||||
<modified value="Fri Sep 14 09:25:13 2018"/>
|
||||
<xMin value="12"/>
|
||||
<yMin value="0"/>
|
||||
<xMax value="1172"/>
|
||||
<yMax value="1430"/>
|
||||
<macStyle value="00000000 00000000"/>
|
||||
<lowestRecPPEM value="9"/>
|
||||
<fontDirectionHint value="2"/>
|
||||
<indexToLocFormat value="0"/>
|
||||
<glyphDataFormat value="0"/>
|
||||
</head>
|
||||
|
||||
<maxp>
|
||||
<!-- Most of this table will be recalculated by the compiler -->
|
||||
<tableVersion value="0x10000"/>
|
||||
<numGlyphs value="4"/>
|
||||
<maxPoints value="11"/>
|
||||
<maxContours value="2"/>
|
||||
<maxCompositePoints value="0"/>
|
||||
<maxCompositeContours value="0"/>
|
||||
<maxZones value="1"/>
|
||||
<maxTwilightPoints value="0"/>
|
||||
<maxStorage value="0"/>
|
||||
<maxFunctionDefs value="10"/>
|
||||
<maxInstructionDefs value="0"/>
|
||||
<maxStackElements value="512"/>
|
||||
<maxSizeOfInstructions value="353"/>
|
||||
<maxComponentElements value="0"/>
|
||||
<maxComponentDepth value="0"/>
|
||||
</maxp>
|
||||
|
||||
<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="glyph00001"/><!-- contains no outline data -->
|
||||
|
||||
<TTGlyph name="glyph00002"/><!-- contains no outline data -->
|
||||
|
||||
<TTGlyph name="glyph00003" xMin="12" yMin="0" xMax="1172" yMax="1430">
|
||||
<contour>
|
||||
<pt x="501" y="1430" on="1" overlap="1"/>
|
||||
<pt x="683" y="1430" on="1"/>
|
||||
<pt x="1172" y="0" on="1"/>
|
||||
<pt x="983" y="0" on="1"/>
|
||||
<pt x="591" y="1193" on="1"/>
|
||||
<pt x="199" y="0" on="1"/>
|
||||
<pt x="12" y="0" on="1"/>
|
||||
</contour>
|
||||
<contour>
|
||||
<pt x="249" y="514" on="1"/>
|
||||
<pt x="935" y="514" on="1"/>
|
||||
<pt x="935" y="352" on="1"/>
|
||||
<pt x="249" y="352" on="1"/>
|
||||
</contour>
|
||||
<instructions/>
|
||||
</TTGlyph>
|
||||
|
||||
</glyf>
|
||||
|
||||
</ttFont>
|
Loading…
x
Reference in New Issue
Block a user