_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 (
fixedToFloat as fi2fl,
floatToFixed as fl2fi,
floatToFixedToStr as fl2str,
strToFixedToFloat as str2fl,
otRound,
)
from numbers import Number
@ -1365,15 +1367,18 @@ class GlyphComponent(object):
transform = self.transform
if transform[0][1] or transform[1][0]:
attrs = attrs + [
("scalex", transform[0][0]), ("scale01", transform[0][1]),
("scale10", transform[1][0]), ("scaley", transform[1][1]),
]
("scalex", fl2str(transform[0][0], 14)),
("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]:
attrs = attrs + [
("scalex", transform[0][0]), ("scaley", transform[1][1]),
]
("scalex", fl2str(transform[0][0], 14)),
("scaley", fl2str(transform[1][1], 14)),
]
else:
attrs = attrs + [("scale", transform[0][0])]
attrs = attrs + [("scale", fl2str(transform[0][0], 14))]
attrs = attrs + [("flags", hex(self.flags))]
writer.simpletag("component", attrs)
writer.newline()
@ -1387,17 +1392,17 @@ class GlyphComponent(object):
self.x = safeEval(attrs["x"])
self.y = safeEval(attrs["y"])
if "scale01" in attrs:
scalex = safeEval(attrs["scalex"])
scale01 = safeEval(attrs["scale01"])
scale10 = safeEval(attrs["scale10"])
scaley = safeEval(attrs["scaley"])
scalex = str2fl(attrs["scalex"], 14)
scale01 = str2fl(attrs["scale01"], 14)
scale10 = str2fl(attrs["scale10"], 14)
scaley = str2fl(attrs["scaley"], 14)
self.transform = [[scalex, scale01], [scale10, scaley]]
elif "scalex" in attrs:
scalex = safeEval(attrs["scalex"])
scaley = safeEval(attrs["scaley"])
scalex = str2fl(attrs["scalex"], 14)
scaley = str2fl(attrs["scaley"], 14)
self.transform = [[scalex, 0], [0, scaley]]
elif "scale" in attrs:
scale = safeEval(attrs["scale"])
scale = str2fl(attrs["scale"], 14)
self.transform = [[scale, 0], [0, scale]]
self.flags = safeEval(attrs["flags"])

View File

@ -1,11 +1,20 @@
from fontTools.misc.py23 import *
from fontTools.misc.fixedTools import otRound
from fontTools.misc.testTools import getXML, parseXML
from fontTools.pens.ttGlyphPen import TTGlyphPen
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
import sys
import array
import itertools
import pytest
import re
import os
@ -276,6 +285,124 @@ class glyfTableTest(unittest.TestCase):
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__":
import sys
sys.exit(unittest.main())