Skip to content
This repository has been archived by the owner on Apr 7, 2024. It is now read-only.

NotoSansMono-MM.glyphs fails to build... is this a source issue? #122

Closed
marekjez86 opened this issue Jul 9, 2018 · 10 comments
Closed

NotoSansMono-MM.glyphs fails to build... is this a source issue? #122

marekjez86 opened this issue Jul 9, 2018 · 10 comments
Assignees

Comments

@marekjez86
Copy link
Contributor

marekjez86 commented Jul 9, 2018

I don't quite understand the message "Glyph ogonekcomb cannot be in both @MC_bottom and @MC_ogonek" because I cannot find text MC_ in the source file. What does it mean? What can I tell Monotype?

Mareks-iMac-Pro:noto-source marek$ ./build src/NotoSansMono-MM.glyphs
INFO:fontmake.font_project:Building master UFOs and designspace from Glyphs source
INFO:glyphsLib.classes:Parsing "src/NotoSansMono-MM.glyphs" file into
INFO:fontmake.font_project:Interpolating master UFOs from designspace
INFO:mutatorMath: Generating instance NotoSansMono-Thin.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-Light.ufo
INFO:mutatorMath: Generating instance NotoSansMono-Regular.ufo
INFO:mutatorMath: Generating instance NotoSansMono-Medium.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-Bold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-Black.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedThin.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedExtraLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensed.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedMedium.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedSemiBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedExtraBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-SemiCondensedBlack.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedThin.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedExtraLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-Condensed.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedMedium.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedSemiBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedExtraBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-CondensedBlack.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedThin.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedExtraLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedLight.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensed.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedMedium.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedSemiBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedExtraBold.ufo
INFO:mutatorMath: Generating instance NotoSansMono-ExtraCondensedBlack.ufo
INFO:fontmake.font_project:Applying instance data from designspace
INFO:fontmake.font_project:Building OTF for NotoSansMono-Thin
INFO:ufo2ft:Pre-processing glyphs
INFO:ufo2ft.filters:Running DecomposeComponentsFilter on NotoSansMono-Thin
INFO:ufo2ft.filters:Running RemoveOverlapsFilter on NotoSansMono-Thin
INFO:ufo2ft:Building OpenType tables
ERROR:ufo2ft.featureCompiler:Compilation failed! Inspect temporary file: '/var/folders/g1/hryyp93x7ngc4mft45_y0vzw0000gn/T/tmpiDBnUN'
Traceback (most recent call last):
File "/Users/marek/github/noto-source/env/bin/fontmake", line 11, in
sys.exit(main())
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/main.py", line 248, in main
project.run_from_glyphs(glyphs_path, **args)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/font_project.py", line 548, in run_from_glyphs
self.run_from_designspace(designspace_path, **kwargs)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/font_project.py", line 623, in run_from_designspace
**kwargs)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/font_project.py", line 656, in run_from_ufos
self.build_otfs(ufos, **kwargs)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/font_project.py", line 232, in build_otfs
self.save_otfs(ufos, **kwargs)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/misc/loggingTools.py", line 372, in wrapper
return func(*args, **kwds)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/font_project.py", line 395, in save_otfs
for font, ufo in zip(fonts, ufos):
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontmake/font_project.py", line 280, in iter_compile
yield compile_func(ufo, **options)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/ufo2ft/init.py", line 89, in compileOTF
featureCompilerClass=featureCompilerClass,
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/ufo2ft/init.py", line 230, in compileFeatures
return featureCompiler.compile()
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/ufo2ft/featureCompiler.py", line 131, in compile
self.buildTables()
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/ufo2ft/featureCompiler.py", line 252, in buildTables
self.ttFont, self.features, filename=path
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/builder.py", line 31, in addOpenTypeFeaturesFromString
addOpenTypeFeatures(font, featurefile, tables=tables)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/builder.py", line 22, in addOpenTypeFeatures
builder.build(tables=tables)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/builder.py", line 108, in build
self.parseTree.build(self)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/ast.py", line 260, in build
s.build(builder)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/ast.py", line 289, in build
Block.build(self, builder)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/ast.py", line 260, in build
s.build(builder)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/ast.py", line 328, in build
Block.build(self, builder)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/ast.py", line 260, in build
s.build(builder)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/ast.py", line 850, in build
builder.add_mark_base_pos(self.location, self.base.glyphSet(), self.marks)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/builder.py", line 967, in add_mark_base_pos
self.add_marks
(location, builder, marks)
File "/Users/marek/github/noto-source/env/lib/python2.7/site-packages/fontTools/feaLib/builder.py", line 963, in add_marks_
location)
fontTools.feaLib.error.FeatureLibError: :1110:9: Glyph ogonekcomb cannot be in both @MC_bottom and @MC_ogonek

@marekjez86
Copy link
Contributor Author

marekjez86 commented Jul 9, 2018

NotoSansMono.txt.zip

I realized that I need to look at this file. I'll start looking at it now.

@anthrotype
Copy link
Contributor

looks the same issue as this
googlefonts/ufo2ft#259 (comment)

i'll look into it tomorrow

@marekjez86
Copy link
Contributor Author

If I read the file right I get the following issues (only ogonekcomb was reported):

markClass ogonekcomb <anchor 0 0> @MC_bottom;
markClass ogonekcomb <anchor 0 10> @MC_ogonek;
markClass ogonekcomb.sc <anchor 0 0> @MC_bottom;
markClass ogonekcomb.sc <anchor 0 10> @MC_ogonek;

What's in the sources that causes these?

@marekjez86
Copy link
Contributor Author

@anthrotype : thanks for the response (and good night)

@anthrotype
Copy link
Contributor

anthrotype commented Jul 10, 2018

Those lines you quoted are generated by the ufo2ft MarkFeatureWriter from the anchors present in the UFO glyphs. The issue is that, for reasons unknown to me, the ogonekcomb and ogonekcomb.sc have both a _ogonek anchor and a _bottom one, which leads to that error in feaLib, because the same mark glyph cannot be present in more than one markClass within the same lookup subtable (in this case, a mark2base lookup in the auto-generated mark feature).

I would like to ask @punchcutter why is it necessary for ogonekcomb mark glyph to contain both "_ogonek" and "_bottom" anchors. In the same font, the base glyph "a", for example, has both a "bottom" and a "ogonek" anchor. So the question is which of the two is supposed to be the one that is used to attach the ogonekcomb glyph in the mark feature? It can't be both.

I also wonder in general how often this is the case with Glyphs.app, that a mark glyph contains more than one attaching anchor (i.e. prefixed with "_"), and how does Glyphs.app solves the ambiguity when generating the mark feature.

If I export NotoSansMono from Glyphs.app and inspect the generated features.fea, I can see that ogonekcomb is only added to the @mark_top markClass, but not also to a @mark_ogonek one. What the reasoning behind this?
Maybe @schriftgestalt or someone more familiar with Glyphs.app could help me understand.

One way to solve this issue, for me, would be to remove one of the two anchors from ogonekcomb and ogonekcomb.sc, leaving only either _bottom or _ogonek. Then the font should compile.
But I'm not sure whether we'd lose any other data by doing that.

Finally, note that these issues were only hidden in the previous MarkFeatureWriter implementation, which would output one lookup per markClass: thus, skipping over this issue of conflicting markClass definition per lookup. I'm not even sure what happens when a shaping engine has to apply two such mark positioning lookups one after the other: one says place a mark glyph at this anchor, the following one says, "no, use another anchor". The last would win, I guess. But that's not necessarily what the font designer intended.

@marekjez86
Copy link
Contributor Author

marekjez86 commented Jul 10, 2018

@anthrotype : thank you for looking at the issue and the investigation.
@schriftgestalt : could you help us understand the choice Glyphs.app makes? is there an error or warning generated in this case?
@punchcutter : while I believe you didn't develop the font (but I might be wrong), could you explain which one we should pick (and what message would you like a designer to see)?

@punchcutter
Copy link
Contributor

This is one of those things that can be really vague. The ogonek anchor can be used with components for automatic alignment, but then doesn't necessarily need to be in the GPOS. In this case a sequence like A ogonekcomb (U+0041 U+0328) is normalized to Aogonek (U+0104). If for some reason normalization does not happen we would be left with A + ogonekcomb and that would need anchors. In that case there's no way anybody can know without looking if the bottom anchor or ogonek anchor is what is needed for any particular glyph. The glyphs that have both bottom and ogonek anchors only need the ogonek anchor if combining with ogonek.

@schriftgestalt can explain better what's going on in Glyphs. I know Glyphs expects a certain kind of naming for top and bottom anchors, but is there explicit code that ignores the ogonek anchors? Or maybe a better question is do you have a list of the anchors that are used to generate mark and mkmk features? Like top, top0, top1, topright, etc? If ogonek isn't in that list then of course it gets ignored writing the mark feature, but if we don't know how Glyphs is handling the names then we can't match it.

@schriftgestalt
Copy link
Contributor

Glyphs looks at all anchors with an underscore, moves "_bottom" and "_top" (if present) to the top of the list and then picks the first in the list to use in the mark feature. So when we have "_ogonek" and "_bottom", the later wins.

@marekjez86
Copy link
Contributor Author

marekjez86 commented Jul 31, 2018

@anthrotype : could we do the same as "Glyphs looks at all anchors with an underscore, moves "_bottom" and "_top" (if present) to the top of the list and then picks the first in the list to use in the mark feature. So when we have "_ogonek" and "_bottom", the later wins." and allow Mono to build?

@anthrotype
Copy link
Contributor

Fixed by googlefonts/ufo2ft#276

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants