[fontBuilder] Enable making CFF2 fonts with 'post' table format 2
Before this change all OTFs wound up with 'post' table format 3
This commit is contained in:
parent
30885c50f4
commit
b0710b829b
@ -690,8 +690,9 @@ class FontBuilder(object):
|
|||||||
"""Create a new `post` table and initialize it with default values,
|
"""Create a new `post` table and initialize it with default values,
|
||||||
which can be overridden by keyword arguments.
|
which can be overridden by keyword arguments.
|
||||||
"""
|
"""
|
||||||
|
isCFF2 = 'CFF2' in self.font
|
||||||
postTable = self._initTableWithValues("post", _postDefaults, values)
|
postTable = self._initTableWithValues("post", _postDefaults, values)
|
||||||
if self.isTTF and keepGlyphNames:
|
if (self.isTTF or isCFF2) and keepGlyphNames:
|
||||||
postTable.formatType = 2.0
|
postTable.formatType = 2.0
|
||||||
postTable.extraNames = []
|
postTable.extraNames = []
|
||||||
postTable.mapping = {}
|
postTable.mapping = {}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ttFont sfntVersion="OTTO" ttLibVersion="3.33">
|
<ttFont sfntVersion="OTTO" ttLibVersion="3.38">
|
||||||
|
|
||||||
<GlyphOrder>
|
<GlyphOrder>
|
||||||
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||||
<GlyphID id="0" name=".notdef"/>
|
<GlyphID id="0" name=".notdef"/>
|
||||||
<GlyphID id="1" name="glyph00001"/>
|
<GlyphID id="1" name=".null"/>
|
||||||
<GlyphID id="2" name="A"/>
|
<GlyphID id="2" name="A"/>
|
||||||
<GlyphID id="3" name="a"/>
|
<GlyphID id="3" name="a"/>
|
||||||
</GlyphOrder>
|
</GlyphOrder>
|
||||||
@ -13,12 +13,12 @@
|
|||||||
<!-- Most of this table will be recalculated by the compiler -->
|
<!-- Most of this table will be recalculated by the compiler -->
|
||||||
<tableVersion value="1.0"/>
|
<tableVersion value="1.0"/>
|
||||||
<fontRevision value="1.0"/>
|
<fontRevision value="1.0"/>
|
||||||
<checkSumAdjustment value="0xed07360f"/>
|
<checkSumAdjustment value="0x79eab779"/>
|
||||||
<magicNumber value="0x5f0f3cf5"/>
|
<magicNumber value="0x5f0f3cf5"/>
|
||||||
<flags value="00000000 00000011"/>
|
<flags value="00000000 00000011"/>
|
||||||
<unitsPerEm value="1000"/>
|
<unitsPerEm value="1000"/>
|
||||||
<created value="Wed Dec 5 11:55:26 2018"/>
|
<created value="Wed Mar 27 00:23:21 2019"/>
|
||||||
<modified value="Wed Dec 5 11:55:26 2018"/>
|
<modified value="Wed Mar 27 00:23:21 2019"/>
|
||||||
<xMin value="0"/>
|
<xMin value="0"/>
|
||||||
<yMin value="0"/>
|
<yMin value="0"/>
|
||||||
<xMax value="0"/>
|
<xMax value="0"/>
|
||||||
@ -110,9 +110,9 @@
|
|||||||
|
|
||||||
<hmtx>
|
<hmtx>
|
||||||
<mtx name=".notdef" width="600" lsb="0"/>
|
<mtx name=".notdef" width="600" lsb="0"/>
|
||||||
|
<mtx name=".null" width="600" lsb="0"/>
|
||||||
<mtx name="A" width="600" lsb="0"/>
|
<mtx name="A" width="600" lsb="0"/>
|
||||||
<mtx name="a" width="600" lsb="0"/>
|
<mtx name="a" width="600" lsb="0"/>
|
||||||
<mtx name="glyph00001" width="600" lsb="0"/>
|
|
||||||
</hmtx>
|
</hmtx>
|
||||||
|
|
||||||
<cmap>
|
<cmap>
|
||||||
@ -179,7 +179,7 @@
|
|||||||
</name>
|
</name>
|
||||||
|
|
||||||
<post>
|
<post>
|
||||||
<formatType value="3.0"/>
|
<formatType value="2.0"/>
|
||||||
<italicAngle value="0.0"/>
|
<italicAngle value="0.0"/>
|
||||||
<underlinePosition value="0"/>
|
<underlinePosition value="0"/>
|
||||||
<underlineThickness value="0"/>
|
<underlineThickness value="0"/>
|
||||||
@ -188,6 +188,18 @@
|
|||||||
<maxMemType42 value="0"/>
|
<maxMemType42 value="0"/>
|
||||||
<minMemType1 value="0"/>
|
<minMemType1 value="0"/>
|
||||||
<maxMemType1 value="0"/>
|
<maxMemType1 value="0"/>
|
||||||
|
<psNames>
|
||||||
|
<!-- This file uses unique glyph names based on the information
|
||||||
|
found in the 'post' table. Since these names might not be unique,
|
||||||
|
we have to invent artificial names in case of clashes. In order to
|
||||||
|
be able to retain the original information, we need a name to
|
||||||
|
ps name mapping for those cases where they differ. That's what
|
||||||
|
you see below.
|
||||||
|
-->
|
||||||
|
</psNames>
|
||||||
|
<extraNames>
|
||||||
|
<!-- following are the name that are not taken from the standard Mac glyph order -->
|
||||||
|
</extraNames>
|
||||||
</post>
|
</post>
|
||||||
|
|
||||||
<CFF2>
|
<CFF2>
|
||||||
@ -212,6 +224,13 @@
|
|||||||
67 66 33 67 67 hvcurveto
|
67 66 33 67 67 hvcurveto
|
||||||
-900 vlineto
|
-900 vlineto
|
||||||
</CharString>
|
</CharString>
|
||||||
|
<CharString name=".null">
|
||||||
|
100 100 rmoveto
|
||||||
|
900 vlineto
|
||||||
|
-67 67 66 -33 67 hhcurveto
|
||||||
|
67 66 33 67 67 hvcurveto
|
||||||
|
-900 vlineto
|
||||||
|
</CharString>
|
||||||
<CharString name="A">
|
<CharString name="A">
|
||||||
100 100 rmoveto
|
100 100 rmoveto
|
||||||
900 vlineto
|
900 vlineto
|
||||||
@ -229,13 +248,6 @@
|
|||||||
-400 -400 1 blend
|
-400 -400 1 blend
|
||||||
hlineto
|
hlineto
|
||||||
</CharString>
|
</CharString>
|
||||||
<CharString name="glyph00001">
|
|
||||||
100 100 rmoveto
|
|
||||||
900 vlineto
|
|
||||||
-67 67 66 -33 67 hhcurveto
|
|
||||||
67 66 33 67 67 hvcurveto
|
|
||||||
-900 vlineto
|
|
||||||
</CharString>
|
|
||||||
</CharStrings>
|
</CharStrings>
|
||||||
<VarStore Format="1">
|
<VarStore Format="1">
|
||||||
<Format value="1"/>
|
<Format value="1"/>
|
||||||
|
@ -2,14 +2,13 @@ from __future__ import print_function, division, absolute_import
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import shutil
|
import pytest
|
||||||
import re
|
import re
|
||||||
from fontTools.ttLib import TTFont
|
from fontTools.ttLib import TTFont
|
||||||
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
||||||
from fontTools.pens.t2CharStringPen import T2CharStringPen
|
from fontTools.pens.t2CharStringPen import T2CharStringPen
|
||||||
from fontTools.fontBuilder import FontBuilder
|
from fontTools.fontBuilder import FontBuilder
|
||||||
from fontTools.ttLib.tables.TupleVariation import TupleVariation
|
from fontTools.ttLib.tables.TupleVariation import TupleVariation
|
||||||
from fontTools.ttLib.tables._g_l_y_f import GlyphCoordinates
|
|
||||||
from fontTools.misc.psCharStrings import T2CharString
|
from fontTools.misc.psCharStrings import T2CharString
|
||||||
|
|
||||||
|
|
||||||
@ -53,6 +52,43 @@ def _setupFontBuilder(isTTF, unitsPerEm=1024):
|
|||||||
return fb, advanceWidths, nameStrings
|
return fb, advanceWidths, nameStrings
|
||||||
|
|
||||||
|
|
||||||
|
def _setupFontBuilderFvar(fb):
|
||||||
|
assert 'name' in fb.font, 'Must run setupNameTable() first.'
|
||||||
|
|
||||||
|
axes = [
|
||||||
|
('TEST', 0, 0, 100, "Test Axis"),
|
||||||
|
]
|
||||||
|
instances = [
|
||||||
|
dict(location=dict(TEST=0), stylename="TotallyNormal"),
|
||||||
|
dict(location=dict(TEST=100), stylename="TotallyTested"),
|
||||||
|
]
|
||||||
|
fb.setupFvar(axes, instances)
|
||||||
|
|
||||||
|
return fb
|
||||||
|
|
||||||
|
|
||||||
|
def _setupFontBuilderCFF2(fb):
|
||||||
|
assert 'fvar' in fb.font, 'Must run _setupFontBuilderFvar() first.'
|
||||||
|
|
||||||
|
pen = T2CharStringPen(None, None, CFF2=True)
|
||||||
|
drawTestGlyph(pen)
|
||||||
|
charString = pen.getCharString()
|
||||||
|
|
||||||
|
program = [
|
||||||
|
200, 200, -200, -200, 2, "blend", "rmoveto",
|
||||||
|
400, 400, 1, "blend", "hlineto",
|
||||||
|
400, 400, 1, "blend", "vlineto",
|
||||||
|
-400, -400, 1, "blend", "hlineto"
|
||||||
|
]
|
||||||
|
charStringVariable = T2CharString(program=program)
|
||||||
|
|
||||||
|
charStrings = {".notdef": charString, "A": charString,
|
||||||
|
"a": charStringVariable, ".null": charString}
|
||||||
|
fb.setupCFF2(charStrings, regions=[{"TEST": (0, 1, 1)}])
|
||||||
|
|
||||||
|
return fb
|
||||||
|
|
||||||
|
|
||||||
def _verifyOutput(outPath, tables=None):
|
def _verifyOutput(outPath, tables=None):
|
||||||
f = TTFont(outPath)
|
f = TTFont(outPath)
|
||||||
f.saveXML(outPath + ".ttx", tables=tables)
|
f.saveXML(outPath + ".ttx", tables=tables)
|
||||||
@ -191,32 +227,9 @@ def test_build_cff2(tmpdir):
|
|||||||
outPath = os.path.join(str(tmpdir), "test_var.otf")
|
outPath = os.path.join(str(tmpdir), "test_var.otf")
|
||||||
|
|
||||||
fb, advanceWidths, nameStrings = _setupFontBuilder(False, 1000)
|
fb, advanceWidths, nameStrings = _setupFontBuilder(False, 1000)
|
||||||
|
|
||||||
fb.setupNameTable(nameStrings)
|
fb.setupNameTable(nameStrings)
|
||||||
|
fb = _setupFontBuilderFvar(fb)
|
||||||
axes = [
|
fb = _setupFontBuilderCFF2(fb)
|
||||||
('TEST', 0, 0, 100, "Test Axis"),
|
|
||||||
]
|
|
||||||
instances = [
|
|
||||||
dict(location=dict(TEST=0), stylename="TotallyNormal"),
|
|
||||||
dict(location=dict(TEST=100), stylename="TotallyTested"),
|
|
||||||
]
|
|
||||||
fb.setupFvar(axes, instances)
|
|
||||||
|
|
||||||
pen = T2CharStringPen(None, None, CFF2=True)
|
|
||||||
drawTestGlyph(pen)
|
|
||||||
charString = pen.getCharString()
|
|
||||||
|
|
||||||
program = [
|
|
||||||
200, 200, -200, -200, 2, "blend", "rmoveto",
|
|
||||||
400, 400, 1, "blend", "hlineto",
|
|
||||||
400, 400, 1, "blend", "vlineto",
|
|
||||||
-400, -400, 1, "blend", "hlineto"
|
|
||||||
]
|
|
||||||
charStringVariable = T2CharString(program=program)
|
|
||||||
|
|
||||||
charStrings = {".notdef": charString, "A": charString, "a": charStringVariable, ".null": charString}
|
|
||||||
fb.setupCFF2(charStrings, regions=[{"TEST": (0, 1, 1)}])
|
|
||||||
|
|
||||||
metrics = {gn: (advanceWidth, 0) for gn, advanceWidth in advanceWidths.items()}
|
metrics = {gn: (advanceWidth, 0) for gn, advanceWidth in advanceWidths.items()}
|
||||||
fb.setupHorizontalMetrics(metrics)
|
fb.setupHorizontalMetrics(metrics)
|
||||||
@ -246,6 +259,31 @@ def test_setupNameTable_no_windows():
|
|||||||
assert not any(n for n in fb.font["name"].names if n.platformID == 3)
|
assert not any(n for n in fb.font["name"].names if n.platformID == 3)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('is_ttf, keep_glyph_names, make_cff2, post_format', [
|
||||||
|
(True, True, False, 2), # TTF with post table format 2.0
|
||||||
|
(True, False, False, 3), # TTF with post table format 3.0
|
||||||
|
(False, True, False, 3), # CFF with post table format 3.0
|
||||||
|
(False, False, False, 3), # CFF with post table format 3.0
|
||||||
|
(False, True, True, 2), # CFF2 with post table format 2.0
|
||||||
|
(False, False, True, 3), # CFF2 with post table format 3.0
|
||||||
|
])
|
||||||
|
def test_setupPost(is_ttf, keep_glyph_names, make_cff2, post_format):
|
||||||
|
fb, _, nameStrings = _setupFontBuilder(is_ttf)
|
||||||
|
|
||||||
|
if make_cff2:
|
||||||
|
fb.setupNameTable(nameStrings)
|
||||||
|
fb = _setupFontBuilderCFF2(_setupFontBuilderFvar(fb))
|
||||||
|
|
||||||
|
if keep_glyph_names:
|
||||||
|
fb.setupPost()
|
||||||
|
else:
|
||||||
|
fb.setupPost(keepGlyphNames=keep_glyph_names)
|
||||||
|
|
||||||
|
assert fb.isTTF is is_ttf
|
||||||
|
assert ('CFF2' in fb.font) is make_cff2
|
||||||
|
assert fb.font["post"].formatType == post_format
|
||||||
|
|
||||||
|
|
||||||
def test_unicodeVariationSequences(tmpdir):
|
def test_unicodeVariationSequences(tmpdir):
|
||||||
familyName = "UVSTestFont"
|
familyName = "UVSTestFont"
|
||||||
styleName = "Regular"
|
styleName = "Regular"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user