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

Allow multiple anchor classes per mark glyph in the mark feature #416

Merged
merged 12 commits into from Nov 20, 2020

Conversation

belluzj
Copy link
Collaborator

@belluzj belluzj commented Oct 30, 2020

Hello, this PR aims to fix #303

While the tests should be green, I'm not sure that I'm not introducing regressions for people who rely on very precise implementation of the Glyphs.app "tricks" with ordering _bottom and _top before others. With the new version of the code, all mark anchors are output, and if there are conflicts the last one will win, not necessarily the one Glyphs.app was picking. For example, if /a and /acutecomb can be attached through both a top/_top and an accent/_accent mark pairs, before it would only output top/_top, now it will output both in different lookups, and probably the last lookup will win (or who knows what will happen actually).

Also, @anthrotype you said you had a patch at some point using the classifier, but I haven't been able to see how to apply the classifier to the problem. I'm using a graph coloring instead. Does that sound OK? How would that be solved instead using the classifier?

Thanks in advance for some reviews!

@madig
Copy link
Collaborator

madig commented Nov 2, 2020

(Side-note: if this can potentially break files made with Glyphs' expectations, maybe we need an "anchor strategy" lib key?)

@google-cla
Copy link

google-cla bot commented Nov 2, 2020

We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google.
In order to pass this check, please resolve this problem and then comment @googlebot I fixed it.. If the bot doesn't comment, it means it doesn't think anything has changed.

ℹ️ Googlers: Go here for more info.

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 2, 2020

@googlebot I fixed it.

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 Jany, I like how you framed this as a graph colouring problem.
I left some comments.

Lib/ufo2ft/featureWriters/markFeatureWriter.py Outdated Show resolved Hide resolved
Lib/ufo2ft/featureWriters/markFeatureWriter.py Outdated Show resolved Hide resolved
Lib/ufo2ft/featureWriters/markFeatureWriter.py Outdated Show resolved Hide resolved
@moyogo
Copy link
Collaborator

moyogo commented Nov 3, 2020

By the way, technically at the OpenType level, these could be in a single lookup, they just need to be in different subtables. Having to have them in different lookups is an AFDKO restriction: adobe-type-tools/afdko#106 (comment)

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 4, 2020

Here is my investigation to confirm @khaledhosny's explanation of how the two conflicting lookups would work. I added the test UFO in commit 03feba7, compiled it with fontmake using this work-in-progress version of ufo2ft to get the two conflicting lookups, took a few screenshots, then swapped the two lookups in TTX, and tested again. See results below:

image

image
image

image image image image

$ hb-shape --shapers=ot master_ttf/MultipleAnchorClassesConflict.ttf -u 00E6,0301
[ae=0+973|acutecomb=0@-141,-10+0]

image

image image image image

$ hb-shape --shapers=ot master_ttf/MultipleAnchorClassesConflict#1.ttf -u 00E6,0301
[ae=0+973|acutecomb=0@-530,-11+0]

@anthrotype
Copy link
Member

technically at the OpenType level, these could be in a single lookup, they just need to be in different subtables

That's a good point. Can we see if we can instead use the subtable statement to force a break-up instead of having to define separate lookups? I think if we did that, then I believe the first subtable that matches would win.

@moyogo
Copy link
Collaborator

moyogo commented Nov 4, 2020

technically at the OpenType level, these could be in a single lookup, they just need to be in different subtables

That's a good point. Can we see if we can instead use the subtable statement to force a break-up instead of having to define separate lookups? I think if we did that, then I believe the first subtable that matches would win.

We would need to update the OpenType Feature File Specification. I think feaLib will raise an error at this point.

@khaledhosny
Copy link
Collaborator

Just confirming that I built the font from #303 with this PR and my original issue is now fixed, thanks @belluzj!

khaledhosny added a commit to aliftype/reem-kufi that referenced this pull request Nov 11, 2020
@belluzj
Copy link
Collaborator Author

belluzj commented Nov 13, 2020

I think I'm done now. If that's OK I'd rather keep generating several lookups for the time being rather than trying to implement subtable breaks in feaLib etc.

@khaledhosny
Copy link
Collaborator

I think I'm done now. If that's OK I'd rather keep generating several lookups for the time being rather than trying to implement subtable breaks in feaLib etc.

feaLib supports subtable breaks almost everywhere.

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 13, 2020

Ah ok, I didn't try anything because Denis was suggesting otherwise in his comment here: #416 (comment)

What do you think? Would this be better as subtables instead of lookups? (provided the subtables work out of the box)

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 13, 2020

I just pushed a version that uses subtable breaks instead of multiple lookups. @khaledhosny could you please check whether it still solves your issue on your font from #303?

@khaledhosny
Copy link
Collaborator

I just pushed a version that uses subtable breaks instead of multiple lookups. @khaledhosny could you please check whether it still solves your issue on your font from #303?

I get actually an error, apparently this is one of the few remaining places where feaLib does not support explicit subtable break!

I get also the new warning for too many glyphs. It seems to be heavy-handed. It might look ambiguous but it is intentional. May be an INFO would be better?

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 16, 2020

I reverted the subtable commit, so that it's still in the history in case someone wants to look into supporting that.

I get also the new warning for too many glyphs. It seems to be heavy-handed. It might look ambiguous but it is intentional. May be an INFO would be better?

I looked into your warnings, they're mostly due to the madda-ar being able to attach to both hamzaAbove and markAbove. It seems to me that the warning is warranted, unless there's something I don't understand. For example, in the situation below, where do you expect the madda to go? Is the "correct"/intended madda position made obvious by another rule that I'm not aware of?

image

image

This is what I get from compiling the font and typing ىٓ:

image

But it could also have been this:

image

@khaledhosny
Copy link
Collaborator

I can work around it, but I also don’t see why it warrants a warning. ufo2ft is generating perfectly valid feature code that builds perfectly valid GPOS lookups. There may or may not be legitimate reasons for having such duplication and a warning is too much IMO (it comes mostly from the very limited way both UFO and Glyphs handle anchors, giving the designer limited control).

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 16, 2020

My point of view here is that ufo2ft doesn't know what you mean (maybe because the UFO format doesn't have enough information, but really whatever the reason is), so it will do something random; and even if the result is valid fea/GPOS, it's still "undefined behaviour" in a way, and I think that's not a good situation in general and is noteworthy enough for a warning.

I also think that the ambiguous situation can happen for two reasons:

  1. as in your case, you know what you're doing and you want to keep the situation as is even though ufo2ft can't promise to put the mark in what you consider the "right" place;
  2. in other potential situations, the designers would introduce this kind of ambiguity by mistake and would like to be told if they're feeding ufo2ft with unclear information, and then would want to fix the situation to make sure their marks go in the same place reliably.

I imagine that situation number 2. would be the most common one and I'd like to take care of it in priority. In that situation the ambiguity is a mistake and ufo2ft is expected to warn (loudly enough) that it's going to have to take random decisions.

Does that make sense? @anthrotype @moyogo what do you think?

I'm happy to put the warning as info if my understanding of the situation is incorrect

@khaledhosny
Copy link
Collaborator

That is why I’m in favor in alphabetic sort of the lookups, this way if the order is not what I want I can carefully rename the anchors. Little control, but better than no control at all.

I’d keep warnings when something is wrong but ufo2ft still can produce some output (otherwise it would be an error), which is not the case here.

@anthrotype
Copy link
Member

I get actually an error, apparently this is one of the few remaining places where feaLib does not support explicit subtable break!

can you please open an issue in fonttools upstream about this so we don't forget? thanks

@@ -239,8 +339,7 @@ class MarkFeatureWriter(BaseFeatureWriter):

# Glyphs moves "_bottom" and "_top" (if present) to the top of
# the list and then picks the first to use in the mark feature.
# https://github.com/googlei18n/noto-source/issues/122
# #issuecomment-403952188
# https://github.com/googlei18n/noto-source/issues/122#issuecomment-403952188
anchorSortKey = {"_bottom": -2, "_top": -1}
Copy link
Member

Choose a reason for hiding this comment

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

this anchorSortKey doesn't seem to be used any more.

Copy link
Member

Choose a reason for hiding this comment

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

what's the order now? You said that the last lookup wins. Should we not place _bottom and _top last so that they win and we don't change existing fonts that may rely on this "feature"? Maybe we can sort alphabetically (like khaled is suggesting) but do an exception for those two.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I implemented what you suggested above.

@anthrotype
Copy link
Member

I'm ok to demote the logging message to an INFO level and simply inform about the potential ambiguity. We can document that the multiple markPos lookups will follow a predefined order (alphabetic + special case for legacy bottom/top anchors).

@belluzj
Copy link
Collaborator Author

belluzj commented Nov 18, 2020

I demoted the warning to INFO.

@@ -59,6 +78,26 @@ class MarkToLigaPos(AbstractMarkPos):

Statement = ast.MarkLigPosStatement

def warnIfAmbiguous(self, log):
Copy link
Member

Choose a reason for hiding this comment

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

the two warnIfAmbiguous methods look almost identical, they could be probably factored out and reused

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

@belluzj belluzj removed the request for review from madig November 20, 2020 11:10
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.

Thank you Jany for working on this! LGTM

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.

MarkFeatureWriter does not allow multiple anchor marks on the same glyph
5 participants