[feaLib] Support hhea table

This commit is contained in:
Khaled Hosny 2016-04-09 17:42:38 +02:00
parent a61b31a917
commit 5ceaa43d27
6 changed files with 83 additions and 2 deletions

View File

@ -631,3 +631,13 @@ class OS2Field(Statement):
def build(self, builder): def build(self, builder):
builder.add_os2_field(self.key, self.value) builder.add_os2_field(self.key, self.value)
class HheaField(Statement):
def __init__(self, location, key, value):
Statement.__init__(self, location)
self.key = key
self.value = value
def build(self, builder):
builder.add_hhea_field(self.key, self.value)

View File

@ -69,12 +69,15 @@ class Builder(object):
self.markFilterSets_ = {} # frozenset({"acute", "grave"}) --> 4 self.markFilterSets_ = {} # frozenset({"acute", "grave"}) --> 4
# for table 'OS/2' # for table 'OS/2'
self.os2_ = {} self.os2_ = {}
# for table 'hhea'
self.hhea_ = {}
def build(self): def build(self):
self.parseTree = Parser(self.file).parse() self.parseTree = Parser(self.file).parse()
self.parseTree.build(self) self.parseTree.build(self)
self.build_feature_aalt_() self.build_feature_aalt_()
self.build_head() self.build_head()
self.build_hhea()
self.build_name() self.build_name()
self.build_OS_2() self.build_OS_2()
for tag in ('GPOS', 'GSUB'): for tag in ('GPOS', 'GSUB'):
@ -185,6 +188,23 @@ class Builder(object):
table.created = table.modified = 3406620153 # 2011-12-13 11:22:33 table.created = table.modified = 3406620153 # 2011-12-13 11:22:33
table.fontRevision = self.fontRevision_ table.fontRevision = self.fontRevision_
def build_hhea(self):
if not self.hhea_:
return
table = self.font.get("hhea")
if not table: # this only happens for unit tests
table = self.font["hhea"] = getTableClass("hhea")()
table.decompile(b"\0" * 36, self.font)
table.tableVersion = 1.0
if "caretoffset" in self.hhea_:
table.caretOffset = self.hhea_["caretoffset"]
if "ascender" in self.hhea_:
table.ascent = self.hhea_["ascender"]
if "descender" in self.hhea_:
table.descent = self.hhea_["descender"]
if "linegap" in self.hhea_:
table.lineGap = self.hhea_["linegap"]
def get_user_name_id(self, table): def get_user_name_id(self, table):
# Try to find first unused font-specific name id # Try to find first unused font-specific name id
nameIDs = [name.nameID for name in table.names] nameIDs = [name.nameID for name in table.names]
@ -922,6 +942,9 @@ class Builder(object):
def add_os2_field(self, key, value): def add_os2_field(self, key, value):
self.os2_[key] = value self.os2_[key] = value
def add_hhea_field(self, key, value):
self.hhea_[key] = value
def makeOpenTypeAnchor(anchor): def makeOpenTypeAnchor(anchor):
"""ast.Anchor --> otTables.Anchor""" """ast.Anchor --> otTables.Anchor"""

View File

@ -57,7 +57,7 @@ class BuilderTest(unittest.TestCase):
spec5f_ii_1 spec5f_ii_2 spec5f_ii_3 spec5f_ii_4 spec5f_ii_1 spec5f_ii_2 spec5f_ii_3 spec5f_ii_4
spec5h1 spec6b_ii spec6d2 spec6e spec6f spec5h1 spec6b_ii spec6d2 spec6e spec6f
spec6h_ii spec6h_iii_1 spec6h_iii_3d spec8a spec8b spec8c spec6h_ii spec6h_iii_1 spec6h_iii_3d spec8a spec8b spec8c
spec9a spec9b spec9c1 spec9c2 spec9c3 spec9e spec9f spec9a spec9b spec9c1 spec9c2 spec9c3 spec9d spec9e spec9f
bug453 bug463 bug501 bug502 bug505 bug506 bug509 bug512 bug453 bug463 bug501 bug502 bug505 bug506 bug509 bug512
name size size2 name size size2
""".split() """.split()
@ -104,7 +104,7 @@ class BuilderTest(unittest.TestCase):
def expect_ttx(self, font, expected_ttx): def expect_ttx(self, font, expected_ttx):
path = self.temp_path(suffix=".ttx") path = self.temp_path(suffix=".ttx")
font.saveXML(path, tables=['head', 'name', 'BASE', 'GDEF', 'GSUB', font.saveXML(path, tables=['head', 'name', 'BASE', 'GDEF', 'GSUB',
'GPOS', 'OS/2']) 'GPOS', 'OS/2', 'hhea'])
actual = self.read_ttx(path) actual = self.read_ttx(path)
expected = self.read_ttx(expected_ttx) expected = self.read_ttx(expected_ttx)
if actual != expected: if actual != expected:

View File

@ -698,6 +698,7 @@ class Parser(object):
handler = { handler = {
"GDEF": self.parse_table_GDEF_, "GDEF": self.parse_table_GDEF_,
"head": self.parse_table_head_, "head": self.parse_table_head_,
"hhea": self.parse_table_hhea_,
"name": self.parse_table_name_, "name": self.parse_table_name_,
"BASE": self.parse_table_BASE_, "BASE": self.parse_table_BASE_,
"OS/2": self.parse_table_OS_2_, "OS/2": self.parse_table_OS_2_,
@ -743,6 +744,23 @@ class Parser(object):
raise FeatureLibError("Expected FontRevision", raise FeatureLibError("Expected FontRevision",
self.cur_token_location_) self.cur_token_location_)
def parse_table_hhea_(self, table):
statements = table.statements
fields = ("CaretOffset", "Ascender", "Descender", "LineGap")
while self.next_token_ != "}":
self.advance_lexer_()
if self.cur_token_type_ is Lexer.NAME and self.cur_token_ in fields:
key = self.cur_token_.lower()
value = self.expect_number_()
statements.append(
ast.HheaField(self.cur_token_location_, key, value))
elif self.cur_token_ == ";":
continue
else:
raise FeatureLibError("Expected CaretOffset, Ascender, "
"Descender or LineGap",
self.cur_token_location_)
def parse_table_name_(self, table): def parse_table_name_(self, table):
statements = table.statements statements = table.statements
while self.next_token_ != "}": while self.next_token_ != "}":

View File

@ -0,0 +1,6 @@
table hhea {
CaretOffset -50;
Ascender 800;
Descender 200;
LineGap 200;
} hhea;

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont>
<hhea>
<tableVersion value="1.0"/>
<ascent value="800"/>
<descent value="200"/>
<lineGap value="200"/>
<advanceWidthMax value="0"/>
<minLeftSideBearing value="0"/>
<minRightSideBearing value="0"/>
<xMaxExtent value="0"/>
<caretSlopeRise value="0"/>
<caretSlopeRun value="0"/>
<caretOffset value="-50"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="0"/>
</hhea>
</ttFont>