Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate GSUB5/GPOS7 lookups (See #1856) #2016

Merged
merged 14 commits into from
Jul 11, 2020

Conversation

simoncozens
Copy link
Collaborator

Done in fairly small steps. Note that the ClassContextualRuleset object which this introduces is also going to be used when choosing the appropriate format representation of contextual lookups, so this is also the start of the contextual optimizer.

Currently unused but will be super helpful for optimizing the formats of contextual lookups.

* Splits the rules of a class contextual lookup based on explicit subtable breaks
* Returns various properties on the ruleset to help determine appropriate layout format.
* (More properties, such as "touched glyphs", planned - will be added when needed.)
It's a bit gross, but I'm blaming OpenType for that. I'm doing this now because otherwise it would be even more repetitive once we start adding format 1 Rule and Ruleset subtables.
@simoncozens
Copy link
Collaborator Author

I now have another couple of commits on top of this which add Format 1 subtables where possible, but will save that for another PR as and when this one gets merged.

Copy link
Member

@anthrotype anthrotype left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks Simon. I just had a quick look, I only left some stylistic comments below.
I see you adjusted/renamed some tests since they now use the non-chaining contextual types (they were indeed non-chaining types disguised as chaining). But maybe we should add similar tests to ensure the code keeps working with the chaining ones as well.

# Do we have any prefixes/suffixes? If this is False for all
# rulesets, we can express the whole lookup as GPOS5/GSUB7.
for (prefix, glyphs, suffix, lookups) in self.rules:
if len(prefix) > 0 or len(suffix) > 0: return True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if statement split over two lines, please

# we can express this subtable as a Format 1.
for (prefix, glyphs, suffix, lookups) in self.rules:
for coverage in (prefix, glyphs, suffix):
if any([len(x) > 1 for x in coverage]):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if any([len(x) > 1 for x in coverage]):
if any(len(x) > 1 for x in coverage):

return True
return False

def format2Classdefs(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def format2Classdefs(self):
def format2ClassDefs(self):


def format2Classdefs(self):
PREFIX, GLYPHS, SUFFIX = 0,1,2
classdefbuilders = []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
classdefbuilders = []
classDefBuilders = []

I think we should stick to one style for the entire module. If the rest uses camelCase, then new code should follow.

def rulesets(self):
# Return a list of ChainContextRuleset objects, taking explicit
# subtable breaks into account
ruleset = [ ChainContextualRuleset() ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's no reason to add spaces to square brackets, it's just distracting. I know the rest of the codebase is not consistent, but for at least new code let's stick to black formatting so we don't waste time over style.

Suggested change
ruleset = [ ChainContextualRuleset() ]
ruleset = [ChainContextualRuleset()]

st.Format = 3
chaining = False
rulesets = self.rulesets()
chaining = any([ruleset.hasPrefixOrSuffix for ruleset in rulesets])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
chaining = any([ruleset.hasPrefixOrSuffix for ruleset in rulesets])
chaining = any(ruleset.hasPrefixOrSuffix for ruleset in rulesets)

if lookupList is not None:
if not isinstance(lookupList, list):
# Can happen with synthesised lookups
lookupList = [ lookupList ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lookupList = [ lookupList ]
lookupList = [lookupList]

font = ttLib.TTFont()
font.setGlyphOrder(["a","b","c","d","A","B","C","D","E"])
sb = builder.ChainContextSubstBuilder(font, None)
prefix = [ ["a"], ["b"] ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
prefix = [ ["a"], ["b"] ]
prefix = [["a"], ["b"]]

and all the following lines as well

prefix = [ ["A"] ]
input_ = [ ["E"] ]
sb.rules.append((prefix, input_, suffix, lookups))
input_ = [ ["C","D"] ]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
input_ = [ ["C","D"] ]
input_ = [["C", "D"]]

suffix = []
sb.rules.append((prefix, input_, suffix, lookups))
input_ = [ ["C","D"] ]
sb.rules.append((prefix, input_, suffix, lookups))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's hard to track the state of the prefix, input_, suffix local variables as you mutate them inside the test. maybe spell out the content of each every time you append a new rule (even if it means repeating the same string literals) so it's clear what rules contain what.

@simoncozens simoncozens merged commit cbe6d3a into fonttools:master Jul 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants