Issue with composite glyph matrix transformations
I'm trying to generate a ligature glyph and apply a transformation to (either) each individual glyph, or to the entire composite, e.g.:
N_A_F = N@1,0,0,1,0,0 & A@1,0,0,1,0,0 & F@1,0,0,1,0,0
Realizing that transformation does nothing, any matrix transformation results in the same error:
...
File "/Users/jackjennings/code/jackjennings/DiplomacyMono/lib/glyph_construction.py", line 28, in _construct
constructionGlyph = GlyphConstructionBuilder(construction, font)
File "/Users/jackjennings/.local/share/virtualenvs/DiplomacyMono-43UJTNI5/lib/python3.7/site-packages/glyphConstruction.py", line 1075, in GlyphConstructionBuilder
component, transformMatrix = parsePositions(baseMarkGlyph, markGlyph, font, markTransformMap, advanceWidth, advanceHeight)
File "/Users/jackjennings/.local/share/virtualenvs/DiplomacyMono-43UJTNI5/lib/python3.7/site-packages/glyphConstruction.py", line 590, in parsePositions
if baseGlyphX in font and baseGlyphY in font:
File "/Users/jackjennings/.local/share/virtualenvs/DiplomacyMono-43UJTNI5/lib/python3.7/site-packages/fontParts/base/layer.py", line 169, in __contains__
name = normalizers.normalizeGlyphName(name)
File "/Users/jackjennings/.local/share/virtualenvs/DiplomacyMono-43UJTNI5/lib/python3.7/site-packages/fontParts/base/normalizers.py", line 293, in normalizeGlyphName
% type(value).__name__)
TypeError: Glyph names must be strings, not NoneType.
Here's the script that I'm using:
font = RFont(path)
for construction in constructions:
constructionGlyph = GlyphConstructionBuilder(construction, font)
glyph = font.newGlyph(constructionGlyph.name)
glyph.clear()
glyph.markColor = constructionGlyph.markColor
glyph.note = constructionGlyph.note
glyph.unicode = constructionGlyph.unicode
glyph.width = constructionGlyph.width
constructionGlyph.draw(glyph.getPen())
font.save()
Is the syntax for the construction wrong?
Ah, can you not put a transformation on the first glyph? I thought that I tried putting it only on the last. One and that not working, but I’ll try again in the morning.
This seems to be solved along the way...
and you should be able to add a transformation matrix to the first baseglyph
please confirm and close
thanks!!
I’m trying to use a similar construction recipe, and getting a similar error.
It’s failing on this recipe:
ratio = colon@1,0,0,1,60,68
With this traceback:
Traceback (most recent call last):
File "build_glyphs_recipes-selected_fonts.py", line 74, in <module>
File "/Users/stephennixon/Library/Application Support/RoboFont/plugins/GlyphConstruction.roboFontExt/lib/glyphConstruction.py", line 1179, in GlyphConstructionBuilder
File "/Users/stephennixon/Library/Application Support/RoboFont/plugins/GlyphConstruction.roboFontExt/lib/glyphConstruction.py", line 621, in parsePositions
File "/Applications/RoboFont.app/Contents/Resources/lib/python3.7/fontParts/base/layer.py", line 169, in __contains__
File "/Applications/RoboFont.app/Contents/Resources/lib/python3.7/fontParts/base/normalizers.py", line 304, in normalizeGlyphName
TypeError: Glyph names must be strings, not NoneType.
From this script:
'''
Build accented glyphs in RoboFont3 using Glyph Construction.
'''
from vanilla.dialogs import *
from glyphConstruction import ParseGlyphConstructionListFromString, GlyphConstructionBuilder
files = getFile("Select files to build glyphs in", allowsMultipleSelection=True, fileTypes=["ufo"])
# Set to False to open fonts with RoboFont UI (e.g. to visually check changes before saving)
skipInterface = True
for file in files:
if skipInterface:
font = OpenFont(file, showInterface=False)
else:
font = OpenFont(file, showInterface=True)
# SPECIFIC TO RATIO GLYPH
leftMargin = font["colon"].leftMargin
raiseBy = round((font.info.capHeight - font["colon"].bounds[3]) / 2)
txt = f'ratio = colon@1,0,0,1,{leftMargin},{raiseBy}'
constructions = ParseGlyphConstructionListFromString(txt)
# collect glyphs to ignore if they already exist in the font
ignoreExisting = [L.split('=')[0].strip()[1:] for L in txt.split('\n') if L.startswith('?')]
print(constructions)
# iterate over all glyph constructions
for construction in constructions:
print(construction, font)
# build a construction glyph
constructionGlyph = GlyphConstructionBuilder(construction, font)
# if the construction for this glyph was preceded by `?`
# and the glyph already exists in the font, skip it
if constructionGlyph.name in font and constructionGlyph.name in ignoreExisting:
continue
# get the destination glyph in the font
glyph = font.newGlyph(constructionGlyph.name, clear=True)
# draw the construction glyph into the destination glyph
constructionGlyph.draw(glyph.getPen())
# copy construction glyph attributes to the destination glyph
glyph.name = constructionGlyph.name
glyph.unicode = constructionGlyph.unicode
glyph.width = constructionGlyph.width
glyph.markColor = 0, 0, 1, 0.5
# if no unicode was given, try to set it automatically
if glyph.unicode is None:
glyph.autoUnicodes()
if skipInterface:
font.save()
font.close()
For now, I’m just adding a simple workaround to the script, adding these lines just after making the glyph and adding a markColor:
# SPECIFIC TO RATIO GLYPH
if glyph.name == "ratio":
for component in glyph.components:
component.moveBy((0, raiseBy))