Skip to content

Commit

Permalink
[ttfcomponentizer] Fix setting the flag on first component of composi…
Browse files Browse the repository at this point in the history
…te glyphs

Fixes #709
  • Loading branch information
miguelsousa committed Jan 9, 2019
1 parent fa5eff2 commit d1f90fe
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 13 deletions.
22 changes: 19 additions & 3 deletions python/afdko/ttfcomponentizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from defcon import Font


__version__ = '0.1.1'
__version__ = '0.2.0'


PUBLIC_PSNAMES = "public.postscriptNames"
Expand Down Expand Up @@ -176,12 +176,24 @@ class ComponentsData(object):
def __init__(self):
self.names = ()
self.positions = ()
self.same_advwidth = False

def add_component(self, name, pos):
self.names += (name,)
self.positions += (pos,)


def check_1st_comp_advwidth(glyph):
"""
Returns True if the advance width of the composite glyph is the same as
the advance width of its first component, and False otherwise.
This information is essential for setting the flag of the composite's
first component later on.
"""
font = glyph.getParent()
return glyph.width == font[glyph.components[0].baseGlyph].width


def get_composites_data(ufo, ps_names):
"""
Iterate thru each glyph of a UFO and collect the names and positions of
Expand All @@ -201,12 +213,14 @@ def get_composites_data(ufo, ps_names):
if glyph.components and not len(glyph):
components = ComponentsData()
all_comps_are_basic = True
for comp in glyph.components:
for i, comp in enumerate(glyph.components):
if comp.transformation[:4] != (1, 0, 0, 1):
all_comps_are_basic = False
break
comp_name = ps_names.get(comp.baseGlyph, comp.baseGlyph)
components.add_component(comp_name, comp.transformation[4:])
if i == 0:
components.same_advwidth = check_1st_comp_advwidth(glyph)
if all_comps_are_basic:
glyf_name = ps_names.get(glyph.name, glyph.name)
composites_data[glyf_name] = components
Expand All @@ -222,7 +236,9 @@ def assemble_components(comps_data):
component = getTableModule('glyf').GlyphComponent()
component.glyphName = cname
component.x, component.y = comps_data.positions[i]
component.flags = 0x204 if i == 0 else 0x4
component.flags = 0x4
if i == 0 and comps_data.same_advwidth:
component.flags = 0x204
components.append(component)
return components

Expand Down
13 changes: 9 additions & 4 deletions tests/ttfcomponentizer_data/expected_output/ttfcomponentizer.ttx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.28">
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.33">

<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="11"/>
<numGlyphs value="12"/>
<maxPoints value="61"/>
<maxContours value="5"/>
<maxCompositePoints value="45"/>
<maxCompositeContours value="3"/>
<maxCompositePoints value="74"/>
<maxCompositeContours value="4"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
Expand Down Expand Up @@ -106,6 +106,11 @@
<instructions/>
</TTGlyph>

<TTGlyph name="aa" xMin="52" yMin="-12" xMax="873" yMax="498">
<component glyphName="a" x="0" y="0" flags="0x4"/>
<component glyphName="a" x="440" y="0" flags="0x4"/>
</TTGlyph>

<TTGlyph name="aacute" xMin="52" yMin="-12" xMax="433" yMax="781">
<component glyphName="a" x="0" y="0" flags="0x204"/>
<component glyphName="uni0301" x="263" y="0" flags="0x4"/>
Expand Down
Binary file modified tests/ttfcomponentizer_data/input/ttfcomponentizer.ttf
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<glyph name="aa" format="1">
<advance width="944"/>
<outline>
<component base="a"/>
<component base="a" xOffset="440"/>
</outline>
</glyph>
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<string>_notdef.glif</string>
<key>a</key>
<string>a.glif</string>
<key>aa</key>
<string>aa.glif</string>
<key>aacute</key>
<string>aacute.glif</string>
<key>acaron</key>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<string>tildecmb</string>
<string>caroncmb</string>
<string>dieresiscmb</string>
<string>aa</string>
</array>
<key>public.postscriptNames</key>
<dict>
Expand Down
14 changes: 8 additions & 6 deletions tests/ttfcomponentizer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_run_with_output_path():
gtable = TTFont(save_path)['glyf']
composites = [gname for gname in gtable.glyphs if (
gtable[gname].isComposite())]
assert sorted(composites) == ['aacute', 'uni01CE']
assert sorted(composites) == ['aa', 'aacute', 'uni01CE']


def test_run_cli_with_output_path():
Expand Down Expand Up @@ -221,17 +221,19 @@ def test_get_composites_data():
comps_data = ttfcomp.get_composites_data(ufo, ps_names)
comps_name_list = sorted(comps_data.keys())
comps_comp_list = [comps_data[gname] for gname in comps_name_list]
assert comps_name_list == ['aacute', 'adieresis', 'atilde', 'uni01CE']
assert comps_comp_list[0].names == ('a', 'uni0301')
assert comps_comp_list[3].names == ('a', 'uni030C')
assert comps_comp_list[0].positions == ((0, 0), (263.35, 0))
assert comps_comp_list[3].positions == ((0, 0), (263, 0))
assert comps_name_list == ['aa', 'aacute', 'adieresis', 'atilde',
'uni01CE']
assert comps_comp_list[1].names == ('a', 'uni0301')
assert comps_comp_list[4].names == ('a', 'uni030C')
assert comps_comp_list[1].positions == ((0, 0), (263.35, 0))
assert comps_comp_list[4].positions == ((0, 0), (263, 0))


def test_assemble_components():
comps_data = Object()
setattr(comps_data, 'names', ('a', 'uni01CE'))
setattr(comps_data, 'positions', ((0, 0), (263, 0)))
setattr(comps_data, 'same_advwidth', True)
comp_one, comp_two = ttfcomp.assemble_components(comps_data)
assert comp_one.glyphName == 'a'
assert comp_two.glyphName == 'uni01CE'
Expand Down

0 comments on commit d1f90fe

Please sign in to comment.