[feaLib] Support size feature
This commit is contained in:
parent
6e291cf705
commit
40be0e6f3a
@ -596,3 +596,17 @@ class FeatureNameStatement(NameRecord):
|
||||
def build(self, builder):
|
||||
NameRecord.build(self, builder)
|
||||
builder.add_featureName(self.location, self.nameID)
|
||||
|
||||
|
||||
class SizeParameters(Statement):
|
||||
def __init__(self, location, DesignSize, SubfamilyID, RangeStart,
|
||||
RangeEnd):
|
||||
Statement.__init__(self, location)
|
||||
self.DesignSize = DesignSize
|
||||
self.SubfamilyID = SubfamilyID
|
||||
self.RangeStart = RangeStart
|
||||
self.RangeEnd = RangeEnd
|
||||
|
||||
def build(self, builder):
|
||||
builder.set_size_parameters(self.location, self.DesignSize,
|
||||
self.SubfamilyID, self.RangeStart, self.RangeEnd)
|
||||
|
@ -38,6 +38,8 @@ class Builder(object):
|
||||
# for 'featureNames'
|
||||
self.featureNames_ = []
|
||||
self.featureNames_ids_ = {}
|
||||
# for feature 'size'
|
||||
self.size_parameters_ = None
|
||||
# for table 'head'
|
||||
self.fontRevision_ = None # 2.71
|
||||
# for table 'name'
|
||||
@ -169,7 +171,15 @@ class Builder(object):
|
||||
|
||||
def buildFeatureParams(self, tag):
|
||||
params = None
|
||||
if tag in self.featureNames_:
|
||||
if tag == "size":
|
||||
params = otTables.FeatureParamsSize()
|
||||
params.DesignSize, params.SubfamilyID, params.RangeStart, \
|
||||
params.RangeEnd = self.size_parameters_
|
||||
if tag in self.featureNames_ids_:
|
||||
params.SubfamilyNameID = self.featureNames_ids_[tag]
|
||||
else:
|
||||
params.SubfamilyNameID = 0
|
||||
elif tag in self.featureNames_:
|
||||
assert tag in self.featureNames_ids_
|
||||
params = otTables.FeatureParamsStylisticSet()
|
||||
params.Version = 0
|
||||
@ -293,7 +303,9 @@ class Builder(object):
|
||||
# rules will have no lookup_index while building GPOS tables.
|
||||
lookup_indices = tuple([l.lookup_index for l in lookups
|
||||
if l.lookup_index is not None])
|
||||
if len(lookup_indices) == 0:
|
||||
|
||||
size_feature = (tag == "GPOS" and feature_tag == "size")
|
||||
if len(lookup_indices) == 0 and not size_feature:
|
||||
continue
|
||||
|
||||
feature_key = (feature_tag, lookup_indices)
|
||||
@ -554,6 +566,17 @@ class Builder(object):
|
||||
def add_featureName(self, location, tag):
|
||||
self.featureNames_.append(tag)
|
||||
|
||||
def set_size_parameters(self, location, DesignSize, SubfamilyID,
|
||||
RangeStart, RangeEnd):
|
||||
if self.cur_feature_name_ != 'size':
|
||||
raise FeatureLibError(
|
||||
"Parameters statements are not allowed "
|
||||
"within \"feature %s\"" % self.cur_feature_name_, location)
|
||||
self.size_parameters_ = [DesignSize, SubfamilyID, RangeStart, RangeEnd]
|
||||
for script, lang in self.language_systems:
|
||||
key = (script, lang, self.cur_feature_name_)
|
||||
self.features_.setdefault(key, [])
|
||||
|
||||
def add_ligature_subst(self, location,
|
||||
prefix, glyphs, suffix, replacement, forceChain):
|
||||
if prefix or suffix or forceChain:
|
||||
|
@ -56,10 +56,10 @@ class BuilderTest(unittest.TestCase):
|
||||
spec4h1 spec5d1 spec5d2 spec5fi1 spec5fi2 spec5fi3 spec5fi4
|
||||
spec5f_ii_1 spec5f_ii_2 spec5f_ii_3 spec5f_ii_4
|
||||
spec5h1 spec6b_ii spec6d2 spec6e spec6f
|
||||
spec6h_ii spec6h_iii_1 spec6h_iii_3d spec8a spec8c
|
||||
spec6h_ii spec6h_iii_1 spec6h_iii_3d spec8a spec8b spec8c
|
||||
spec9b spec9c1 spec9c2 spec9c3 spec9e
|
||||
bug453 bug463 bug501 bug502 bug505 bug506 bug509 bug512
|
||||
name
|
||||
name size size2
|
||||
""".split()
|
||||
|
||||
def __init__(self, methodName):
|
||||
|
@ -663,6 +663,29 @@ class Parser(object):
|
||||
self.expect_symbol_(";")
|
||||
return ast.SubtableStatement(location)
|
||||
|
||||
def parse_size_parameters_(self):
|
||||
assert self.is_cur_keyword_("parameters")
|
||||
location = self.cur_token_location_
|
||||
DesignSize = self.expect_decipoint_()
|
||||
SubfamilyID = self.expect_number_()
|
||||
RangeStart = 0
|
||||
RangeEnd = 0
|
||||
if self.next_token_type_ in (Lexer.NUMBER, Lexer.FLOAT) or \
|
||||
SubfamilyID != 0:
|
||||
RangeStart = self.expect_decipoint_()
|
||||
RangeEnd = self.expect_decipoint_()
|
||||
|
||||
self.expect_symbol_(";")
|
||||
return ast.SizeParameters(location, DesignSize, SubfamilyID,
|
||||
RangeStart, RangeEnd)
|
||||
|
||||
def parse_size_menuname_(self):
|
||||
assert self.is_cur_keyword_("sizemenuname")
|
||||
location = self.cur_token_location_
|
||||
platformID, platEncID, langID, string = self.parse_name_()
|
||||
return ast.FeatureNameStatement(location, "size", platformID,
|
||||
platEncID, langID, string)
|
||||
|
||||
def parse_table_(self):
|
||||
assert self.is_cur_keyword_("table")
|
||||
location, name = self.cur_token_location_, self.expect_tag_()
|
||||
@ -889,13 +912,15 @@ class Parser(object):
|
||||
if tag in ["ss%02d" % i for i in range(1, 20+1)]:
|
||||
stylisticset = tag
|
||||
|
||||
size_feature = (tag == "size")
|
||||
|
||||
use_extension = False
|
||||
if self.next_token_ == "useExtension":
|
||||
self.expect_keyword_("useExtension")
|
||||
use_extension = True
|
||||
|
||||
block = ast.FeatureBlock(location, tag, use_extension)
|
||||
self.parse_block_(block, vertical, stylisticset)
|
||||
self.parse_block_(block, vertical, stylisticset, size_feature)
|
||||
return block
|
||||
|
||||
def parse_feature_reference_(self):
|
||||
@ -938,7 +963,8 @@ class Parser(object):
|
||||
location)
|
||||
return ast.FontRevisionStatement(location, version)
|
||||
|
||||
def parse_block_(self, block, vertical, stylisticset=None):
|
||||
def parse_block_(self, block, vertical, stylisticset=None,
|
||||
size_feature=False):
|
||||
self.expect_symbol_("{")
|
||||
for symtab in self.symbol_tables_:
|
||||
symtab.enter_scope()
|
||||
@ -978,6 +1004,10 @@ class Parser(object):
|
||||
statements.append(self.parse_valuerecord_definition_(vertical))
|
||||
elif stylisticset and self.is_cur_keyword_("featureNames"):
|
||||
statements.extend(self.parse_featureNames_(stylisticset))
|
||||
elif size_feature and self.is_cur_keyword_("parameters"):
|
||||
statements.append(self.parse_size_parameters_())
|
||||
elif size_feature and self.is_cur_keyword_("sizemenuname"):
|
||||
statements.append(self.parse_size_menuname_())
|
||||
elif self.cur_token_ == ";":
|
||||
continue
|
||||
else:
|
||||
@ -1097,6 +1127,15 @@ class Parser(object):
|
||||
raise FeatureLibError("Expected a floating-point number",
|
||||
self.cur_token_location_)
|
||||
|
||||
def expect_decipoint_(self):
|
||||
if self.next_token_type_ == Lexer.FLOAT:
|
||||
return self.expect_float_()
|
||||
elif self.next_token_type_ is Lexer.NUMBER:
|
||||
return self.expect_number_() / 10
|
||||
else:
|
||||
raise FeatureLibError("Expected an integer or floating-point number",
|
||||
self.cur_token_location_)
|
||||
|
||||
def expect_string_(self):
|
||||
self.advance_lexer_()
|
||||
if self.cur_token_type_ is Lexer.STRING:
|
||||
|
3
Lib/fontTools/feaLib/testdata/size.fea
vendored
Normal file
3
Lib/fontTools/feaLib/testdata/size.fea
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
feature size {
|
||||
parameters 10.0 0 0 0;
|
||||
} size;
|
41
Lib/fontTools/feaLib/testdata/size.ttx
vendored
Normal file
41
Lib/fontTools/feaLib/testdata/size.ttx
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont>
|
||||
|
||||
<GPOS>
|
||||
<Version value="1.0"/>
|
||||
<ScriptList>
|
||||
<!-- ScriptCount=1 -->
|
||||
<ScriptRecord index="0">
|
||||
<ScriptTag value="DFLT"/>
|
||||
<Script>
|
||||
<DefaultLangSys>
|
||||
<ReqFeatureIndex value="65535"/>
|
||||
<!-- FeatureCount=1 -->
|
||||
<FeatureIndex index="0" value="0"/>
|
||||
</DefaultLangSys>
|
||||
<!-- LangSysCount=0 -->
|
||||
</Script>
|
||||
</ScriptRecord>
|
||||
</ScriptList>
|
||||
<FeatureList>
|
||||
<!-- FeatureCount=1 -->
|
||||
<FeatureRecord index="0">
|
||||
<FeatureTag value="size"/>
|
||||
<Feature>
|
||||
<FeatureParamsSize>
|
||||
<DesignSize value="10.0"/>
|
||||
<SubfamilyID value="0"/>
|
||||
<SubfamilyNameID value="0"/>
|
||||
<RangeStart value="0.0"/>
|
||||
<RangeEnd value="0.0"/>
|
||||
</FeatureParamsSize>
|
||||
<!-- LookupCount=0 -->
|
||||
</Feature>
|
||||
</FeatureRecord>
|
||||
</FeatureList>
|
||||
<LookupList>
|
||||
<!-- LookupCount=0 -->
|
||||
</LookupList>
|
||||
</GPOS>
|
||||
|
||||
</ttFont>
|
3
Lib/fontTools/feaLib/testdata/size2.fea
vendored
Normal file
3
Lib/fontTools/feaLib/testdata/size2.fea
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
feature size {
|
||||
parameters 10.0 0;
|
||||
} size;
|
41
Lib/fontTools/feaLib/testdata/size2.ttx
vendored
Normal file
41
Lib/fontTools/feaLib/testdata/size2.ttx
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont>
|
||||
|
||||
<GPOS>
|
||||
<Version value="1.0"/>
|
||||
<ScriptList>
|
||||
<!-- ScriptCount=1 -->
|
||||
<ScriptRecord index="0">
|
||||
<ScriptTag value="DFLT"/>
|
||||
<Script>
|
||||
<DefaultLangSys>
|
||||
<ReqFeatureIndex value="65535"/>
|
||||
<!-- FeatureCount=1 -->
|
||||
<FeatureIndex index="0" value="0"/>
|
||||
</DefaultLangSys>
|
||||
<!-- LangSysCount=0 -->
|
||||
</Script>
|
||||
</ScriptRecord>
|
||||
</ScriptList>
|
||||
<FeatureList>
|
||||
<!-- FeatureCount=1 -->
|
||||
<FeatureRecord index="0">
|
||||
<FeatureTag value="size"/>
|
||||
<Feature>
|
||||
<FeatureParamsSize>
|
||||
<DesignSize value="10.0"/>
|
||||
<SubfamilyID value="0"/>
|
||||
<SubfamilyNameID value="0"/>
|
||||
<RangeStart value="0"/>
|
||||
<RangeEnd value="0"/>
|
||||
</FeatureParamsSize>
|
||||
<!-- LookupCount=0 -->
|
||||
</Feature>
|
||||
</FeatureRecord>
|
||||
</FeatureList>
|
||||
<LookupList>
|
||||
<!-- LookupCount=0 -->
|
||||
</LookupList>
|
||||
</GPOS>
|
||||
|
||||
</ttFont>
|
9
Lib/fontTools/feaLib/testdata/spec8b.fea
vendored
Normal file
9
Lib/fontTools/feaLib/testdata/spec8b.fea
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
feature size {
|
||||
parameters 100 # design size (decipoints)
|
||||
3 # subfamily identifier
|
||||
80 # range start (exclusive, decipoints)
|
||||
139; # range end (inclusive, decipoints)
|
||||
sizemenuname "Win MinionPro Size Name";
|
||||
sizemenuname 1 "Mac MinionPro Size Name";
|
||||
sizemenuname 1 21 0 "Mac MinionPro Size Name";
|
||||
} size;
|
53
Lib/fontTools/feaLib/testdata/spec8b.ttx
vendored
Normal file
53
Lib/fontTools/feaLib/testdata/spec8b.ttx
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ttFont>
|
||||
|
||||
<name>
|
||||
<namerecord nameID="256" platformID="3" platEncID="1" langID="0x409">
|
||||
Win MinionPro Size Name
|
||||
</namerecord>
|
||||
<namerecord nameID="256" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
Mac MinionPro Size Name
|
||||
</namerecord>
|
||||
<namerecord nameID="256" platformID="1" platEncID="21" langID="0x0" unicode="True">
|
||||
Mac MinionPro Size Name
|
||||
</namerecord>
|
||||
</name>
|
||||
|
||||
<GPOS>
|
||||
<Version value="1.0"/>
|
||||
<ScriptList>
|
||||
<!-- ScriptCount=1 -->
|
||||
<ScriptRecord index="0">
|
||||
<ScriptTag value="DFLT"/>
|
||||
<Script>
|
||||
<DefaultLangSys>
|
||||
<ReqFeatureIndex value="65535"/>
|
||||
<!-- FeatureCount=1 -->
|
||||
<FeatureIndex index="0" value="0"/>
|
||||
</DefaultLangSys>
|
||||
<!-- LangSysCount=0 -->
|
||||
</Script>
|
||||
</ScriptRecord>
|
||||
</ScriptList>
|
||||
<FeatureList>
|
||||
<!-- FeatureCount=1 -->
|
||||
<FeatureRecord index="0">
|
||||
<FeatureTag value="size"/>
|
||||
<Feature>
|
||||
<FeatureParamsSize>
|
||||
<DesignSize value="10.0"/>
|
||||
<SubfamilyID value="3"/>
|
||||
<SubfamilyNameID value="256"/>
|
||||
<RangeStart value="8.0"/>
|
||||
<RangeEnd value="13.9"/>
|
||||
</FeatureParamsSize>
|
||||
<!-- LookupCount=0 -->
|
||||
</Feature>
|
||||
</FeatureRecord>
|
||||
</FeatureList>
|
||||
<LookupList>
|
||||
<!-- LookupCount=0 -->
|
||||
</LookupList>
|
||||
</GPOS>
|
||||
|
||||
</ttFont>
|
Loading…
x
Reference in New Issue
Block a user