_g_l_y_f: use floatToFixedToStr and strToFixedToFloat in GlyphComponent toXML/fromXML

This commit is contained in:
Cosimo Lupo 2019-10-07 16:46:42 +01:00
parent 8791caf3b8
commit c60512de0e
No known key found for this signature in database
GPG Key ID: 20D4A261E4A0E642
2 changed files with 146 additions and 14 deletions

View File

@ -11,6 +11,8 @@ from fontTools.misc.bezierTools import calcQuadraticBounds
from fontTools.misc.fixedTools import ( from fontTools.misc.fixedTools import (
fixedToFloat as fi2fl, fixedToFloat as fi2fl,
floatToFixed as fl2fi, floatToFixed as fl2fi,
floatToFixedToStr as fl2str,
strToFixedToFloat as str2fl,
otRound, otRound,
) )
from numbers import Number from numbers import Number
@ -1365,15 +1367,18 @@ class GlyphComponent(object):
transform = self.transform transform = self.transform
if transform[0][1] or transform[1][0]: if transform[0][1] or transform[1][0]:
attrs = attrs + [ attrs = attrs + [
("scalex", transform[0][0]), ("scale01", transform[0][1]), ("scalex", fl2str(transform[0][0], 14)),
("scale10", transform[1][0]), ("scaley", transform[1][1]), ("scale01", fl2str(transform[0][1], 14)),
] ("scale10", fl2str(transform[1][0], 14)),
("scaley", fl2str(transform[1][1], 14)),
]
elif transform[0][0] != transform[1][1]: elif transform[0][0] != transform[1][1]:
attrs = attrs + [ attrs = attrs + [
("scalex", transform[0][0]), ("scaley", transform[1][1]), ("scalex", fl2str(transform[0][0], 14)),
] ("scaley", fl2str(transform[1][1], 14)),
]
else: else:
attrs = attrs + [("scale", transform[0][0])] attrs = attrs + [("scale", fl2str(transform[0][0], 14))]
attrs = attrs + [("flags", hex(self.flags))] attrs = attrs + [("flags", hex(self.flags))]
writer.simpletag("component", attrs) writer.simpletag("component", attrs)
writer.newline() writer.newline()
@ -1387,17 +1392,17 @@ class GlyphComponent(object):
self.x = safeEval(attrs["x"]) self.x = safeEval(attrs["x"])
self.y = safeEval(attrs["y"]) self.y = safeEval(attrs["y"])
if "scale01" in attrs: if "scale01" in attrs:
scalex = safeEval(attrs["scalex"]) scalex = str2fl(attrs["scalex"], 14)
scale01 = safeEval(attrs["scale01"]) scale01 = str2fl(attrs["scale01"], 14)
scale10 = safeEval(attrs["scale10"]) scale10 = str2fl(attrs["scale10"], 14)
scaley = safeEval(attrs["scaley"]) scaley = str2fl(attrs["scaley"], 14)
self.transform = [[scalex, scale01], [scale10, scaley]] self.transform = [[scalex, scale01], [scale10, scaley]]
elif "scalex" in attrs: elif "scalex" in attrs:
scalex = safeEval(attrs["scalex"]) scalex = str2fl(attrs["scalex"], 14)
scaley = safeEval(attrs["scaley"]) scaley = str2fl(attrs["scaley"], 14)
self.transform = [[scalex, 0], [0, scaley]] self.transform = [[scalex, 0], [0, scaley]]
elif "scale" in attrs: elif "scale" in attrs:
scale = safeEval(attrs["scale"]) scale = str2fl(attrs["scale"], 14)
self.transform = [[scale, 0], [0, scale]] self.transform = [[scale, 0], [0, scale]]
self.flags = safeEval(attrs["flags"]) self.flags = safeEval(attrs["flags"])

View File

@ -1,11 +1,20 @@
from fontTools.misc.py23 import * from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound from fontTools.misc.fixedTools import otRound
from fontTools.misc.testTools import getXML, parseXML
from fontTools.pens.ttGlyphPen import TTGlyphPen from fontTools.pens.ttGlyphPen import TTGlyphPen
from fontTools.ttLib import TTFont, newTable, TTLibError from fontTools.ttLib import TTFont, newTable, TTLibError
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates from fontTools.ttLib.tables._g_l_y_f import (
GlyphCoordinates,
GlyphComponent,
ARGS_ARE_XY_VALUES,
WE_HAVE_A_SCALE,
WE_HAVE_A_TWO_BY_TWO,
WE_HAVE_AN_X_AND_Y_SCALE,
)
from fontTools.ttLib.tables import ttProgram from fontTools.ttLib.tables import ttProgram
import sys import sys
import array import array
import itertools
import pytest import pytest
import re import re
import os import os
@ -276,6 +285,124 @@ class glyfTableTest(unittest.TestCase):
composite.compact(glyfTable) composite.compact(glyfTable)
class GlyphComponentTest:
def test_toXML_no_transform(self):
comp = GlyphComponent()
comp.glyphName = "a"
comp.flags = ARGS_ARE_XY_VALUES
comp.x, comp.y = 1, 2
assert getXML(comp.toXML) == [
'<component glyphName="a" x="1" y="2" flags="0x2"/>'
]
def test_toXML_transform_scale(self):
comp = GlyphComponent()
comp.glyphName = "a"
comp.flags = ARGS_ARE_XY_VALUES | WE_HAVE_A_SCALE
comp.x, comp.y = 1, 2
comp.transform = [[0.2999878, 0], [0, 0.2999878]]
assert getXML(comp.toXML) == [
'<component glyphName="a" x="1" y="2" scale="0.3" flags="0xa"/>'
]
def test_toXML_transform_xy_scale(self):
comp = GlyphComponent()
comp.glyphName = "a"
comp.flags = ARGS_ARE_XY_VALUES | WE_HAVE_AN_X_AND_Y_SCALE
comp.x, comp.y = 1, 2
comp.transform = [[0.5999756, 0], [0, 0.2999878]]
assert getXML(comp.toXML) == [
'<component glyphName="a" x="1" y="2" scalex="0.6" '
'scaley="0.3" flags="0x42"/>'
]
def test_toXML_transform_2x2_scale(self):
comp = GlyphComponent()
comp.glyphName = "a"
comp.flags = ARGS_ARE_XY_VALUES | WE_HAVE_A_TWO_BY_TWO
comp.x, comp.y = 1, 2
comp.transform = [[0.5999756, -0.2000122], [0.2000122, 0.2999878]]
assert getXML(comp.toXML) == [
'<component glyphName="a" x="1" y="2" scalex="0.6" scale01="-0.2" '
'scale10="0.2" scaley="0.3" flags="0x82"/>'
]
def test_fromXML_no_transform(self):
comp = GlyphComponent()
for name, attrs, content in parseXML(
['<component glyphName="a" x="1" y="2" flags="0x2"/>']
):
comp.fromXML(name, attrs, content, ttFont=None)
assert comp.glyphName == "a"
assert comp.flags & ARGS_ARE_XY_VALUES != 0
assert (comp.x, comp.y) == (1, 2)
assert not hasattr(comp, "transform")
def test_fromXML_transform_scale(self):
comp = GlyphComponent()
for name, attrs, content in parseXML(
['<component glyphName="a" x="1" y="2" scale="0.3" flags="0xa"/>']
):
comp.fromXML(name, attrs, content, ttFont=None)
assert comp.glyphName == "a"
assert comp.flags & ARGS_ARE_XY_VALUES != 0
assert comp.flags & WE_HAVE_A_SCALE != 0
assert (comp.x, comp.y) == (1, 2)
assert hasattr(comp, "transform")
for value, expected in zip(
itertools.chain(*comp.transform), [0.2999878, 0, 0, 0.2999878]
):
assert value == pytest.approx(expected)
def test_fromXML_transform_xy_scale(self):
comp = GlyphComponent()
for name, attrs, content in parseXML(
[
'<component glyphName="a" x="1" y="2" scalex="0.6" '
'scaley="0.3" flags="0x42"/>'
]
):
comp.fromXML(name, attrs, content, ttFont=None)
assert comp.glyphName == "a"
assert comp.flags & ARGS_ARE_XY_VALUES != 0
assert comp.flags & WE_HAVE_AN_X_AND_Y_SCALE != 0
assert (comp.x, comp.y) == (1, 2)
assert hasattr(comp, "transform")
for value, expected in zip(
itertools.chain(*comp.transform), [0.5999756, 0, 0, 0.2999878]
):
assert value == pytest.approx(expected)
def test_fromXML_transform_2x2_scale(self):
comp = GlyphComponent()
for name, attrs, content in parseXML(
[
'<component glyphName="a" x="1" y="2" scalex="0.6" scale01="-0.2" '
'scale10="0.2" scaley="0.3" flags="0x82"/>'
]
):
comp.fromXML(name, attrs, content, ttFont=None)
assert comp.glyphName == "a"
assert comp.flags & ARGS_ARE_XY_VALUES != 0
assert comp.flags & WE_HAVE_A_TWO_BY_TWO != 0
assert (comp.x, comp.y) == (1, 2)
assert hasattr(comp, "transform")
for value, expected in zip(
itertools.chain(*comp.transform),
[0.5999756, -0.2000122, 0.2000122, 0.2999878]
):
assert value == pytest.approx(expected)
if __name__ == "__main__": if __name__ == "__main__":
import sys import sys
sys.exit(unittest.main()) sys.exit(unittest.main())