SOLVED Renaming the glyph problem



  • Hi,

    I'm renaming all glyphs in CurrentFont based on glyphNameFormatter.reader.u2n.

    To do that I'm using RFont.rename(oldname,newname) script. After a few months of using this code, I have the following throwback (so far I saw it only on one, healthy-looking ufo):

    File "unicodeStuff.py", line 57, in doit
      File "lib/fontObjects/fontPartsWrappers.pyc", line 1649, in renameGlyph
      File "lib/fontObjects/fontPartsWrappers.pyc", line 1318, in renameGlyph
      File "lib/fontObjects/doodleLayer.pyc", line 181, in renameGlyph
      File "/Applications/TypeDesign/RoboFont3.app/Contents/Resources/lib/python3.6/defcon/objects/layer.py", line 262, in __getitem__
      File "lib/fontObjects/doodleLayer.pyc", line 58, in loadGlyph
      File "/Applications/TypeDesign/RoboFont3.app/Contents/Resources/lib/python3.6/defcon/objects/layer.py", line 179, in loadGlyph
    KeyError: 'uni2611 not in layer'
    

    I was trying everything, I have rewritten the script with a different slightly approach over five times. It throws the same message, with around five different glyphs that throw an error (it depends on the version of my script).

    I cannot find the issue in the font.

    Before the running script, the glyph that causes the error exists in the font. Later it eighter completely disappear, or if I write its name in the search console, the RF crashes.

    Any suggestions?



  • This post was helpful to me – thanks @RafaŁ-Buchner and @frederik!

    It took me a bit to get everything working, so I thought I'd post my updates here for the next person who needs it.

    # a script to find glyphs with unicode names and give them human-readable names
    # started from https://forum.robofont.com/topic/624/renaming-the-glyph-problem/6
    
    
    from glyphNameFormatter.reader import u2n, n2u, u2U
    from vanilla.dialogs import *
    import pprint
    
    def updateGlyphName(f):
        f.features.text = feaText
    
    
    def getNameFromUnicode(g):
        name = u2n(g.unicode)
        return name
    
    
    def getReadableNames(font):
        renamingDict = {}
        for glyph in font:
            old_name = glyph.name
    
            if "uni" in old_name:  # and "." not in old_name:
                new_name = getNameFromUnicode(glyph)
    
                if new_name is None:
                    continue
                else:
                    if new_name not in renamingDict.keys():
                        if new_name != old_name:
                            renamingDict[old_name] = new_name
                        for glyph2 in font:
                            if glyph2.name.split(".")[0] == old_name:
                                old_name2 = glyph2.name
                                new_name2 = glyph2.name.replace(old_name, new_name)
                                if new_name2 not in renamingDict.keys():
                                    if new_name2 != old_name2:
                                        renamingDict[old_name2] = new_name2
        pprint.pprint(renamingDict)
        renamingDictKeys = list(renamingDict.keys())
    
        for old in reversed(renamingDictKeys):
            if old in font.keys():
                glyph = font[old]
                if len(glyph.contours) != 0:
                    font.renameGlyph(old, renamingDict[old])
                    print("\t", old, "→", renamingDict[old])
                    for glyph2 in font:
                        for comp in glyph2.components:
                            if comp.baseGlyph == old:
                                comp.baseGlyph = renamingDict[old]
    
                    renamingDictKeys.remove(old)
    
        for old in reversed(renamingDictKeys):
            glyph = font[old]
            if len(glyph.contours) == 0:
                font.renameGlyph(old, renamingDict[old])
                print("\t", old, "→", renamingDict[old])
                for glyph2 in font:
                    for comp in glyph2.components:
                        if comp.baseGlyph == old:
                            comp.baseGlyph = renamingDict[old]
    
    # allows you to select one or multiple UFOs
    
    inputFonts = getFile(
        "select UFOs", allowsMultipleSelection=True, fileTypes=["ufo"])
    
    for fontPath in inputFonts:
        # set showInterface to True if you wish to see the font window
        f = OpenFont(fontPath, showInterface=False)
    
        print("----------------------------------\n")
        print("----------------------------------\n")
        print(f.path, "\n")
        print("----------------------------------\n")
    
        getReadableNames(f)
    
        # comment these out to test run
        f.save()
        f.close()
    
    


  • shit, it was much easier than I thought,
    I should feel a bit ashamed. Thanks


  • admin

    removing the renaming 'old' glyph name from your reducedRenamingDictKeys list, on the first rename, will help


  • admin

    When renaming a glyph (line 32) the old glyph name does not exist anymore (line 38).

    (side note: keys() from a dictionary are always unique, see line 25)



  • ofcourse

    from glyphNameFormatter.reader import u2n, n2u, u2U
    def getNameFromUnicode(g):
        name = u2n(g.unicode)
        return name
        
    def doit(font):
        renamingDict = {}
        for glyph in font:
            old_name = glyph.name
            new_name = getNameFromUnicode(glyph)
    
            if new_name is None:
                continue
            else:
                if new_name not in renamingDict.keys():
                    if new_name != old_name:
                        renamingDict[old_name] = new_name
                    for glyph2 in font:
                        if glyph2.name.split(".")[0] == old_name:
                            old_name2 = glyph2.name
                            new_name2 = glyph2.name.replace(old_name,new_name)
                            if new_name2 not in renamingDict.keys():
                                if new_name2 != old_name2:
                                    renamingDict[old_name2] = new_name2
        reducedRenamingDictKeys = list(set(list(renamingDict.keys())))
        
        for old in reducedRenamingDictKeys:
            if old in font.keys():
                glyph = font[old]
                if len(glyph.contours) != 0:
                    font.renameGlyph(old,renamingDict[old])
                    for glyph2 in font:
                        for comp in glyph2.components:
                            if comp.baseGlyph == old:
                                comp.baseGlyph = renamingDict[old]
        for old in reducedRenamingDictKeys:
            
            glyph = font[old]
            if len(glyph.contours) == 0:
        
                font.renameGlyph(old,renamingDict[old])
                for glyph2 in font:
                    for comp in glyph2.components:
                        if comp.baseGlyph == old:
                            comp.baseGlyph = renamingDict[old]
        
    font = CurrentFont()
    doit(font)
    

  • admin

    do you have an example script that causes this issue?


Log in to reply