GlyphConstruction icon indicating copy to clipboard operation
GlyphConstruction copied to clipboard

Issue with composite glyph matrix transformations

Open jackjennings opened this issue 6 years ago • 4 comments

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?

jackjennings avatar Jun 02 '19 01:06 jackjennings

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.

jackjennings avatar Jun 02 '19 07:06 jackjennings

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!!

typemytype avatar Jan 20 '20 22:01 typemytype

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()

arrowtype avatar Oct 13 '21 02:10 arrowtype

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))

arrowtype avatar Oct 13 '21 02:10 arrowtype