UNSOLVED Python overwriting glyph; RF GlyphInfoPane error



  • RF 3.5
    Big Sur 11.0.1

    I am working on a plugin for copying layers between files. I have run across an error (included below) when copying glyphs multiple times.

    I have reduced the repro to these steps using the following script:

    font1 = CurrentFont()
    
    font2 = OpenFont(showInterface=False)
    
    for glyph in font2:
    	font1.defaultLayer[glyph.name] = glyph
    
    1. Open new/blank font.
    2. Run the below copy script, choosing a second font. In my case, I used a new font that contains only an exclamation glyph on foreground.
    3. Select the newly copied exclamation/whichever glyph in GlyphInfoPane.
    4. Repeat step 2, same font. The twice copied glyph sorts to the bottom of the GlyphInfoPane for some reason?
    5. Repeat step 3. This error is thrown:
    Observer '<lib.UI.inspector.glyphInfoPane.GlyphInfoPane object at 0x14b192a50>' with '_currentGlyphChanged' failed: An observer is only allowed to have one callback for a given notification + observable combination. notification=Lib.Changed, observable={'com.defcon.sortDescriptor': [{'ascending': 'Latin-1', 'type': 'characterSet'}], 'com.robofont.generateFeaturesWithFontTools': False, 'com.typemytype.robofont.compileSettings.autohint': True, 'com.typemytype.robofont.compileSettings.checkOutlines': False, 'com.typemytype.robofont.compileSettings.createDummyDSIG': True, 'com.typemytype.robofont.compileSettings.decompose': False, 'com.typemytype.robofont.compileSettings.generateFormat': 0, 'com.typemytype.robofont.compileSettings.releaseMode': False, 'com.typemytype.robofont.italicSlantOffset': 0, 'com.typemytype.robofont.segmentType': 'curve', 'com.typemytype.robofont.shouldAddPointsInSplineConversion': 1, 'com.typemytype.robofont.smartSets.uniqueKey': '5204840272', 'public.glyphOrder': ['space', 'quotesingle', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', 'sterling', 'currency', 'yen', 'brokenbar', 'section', 'dieresis', 'copyright', 'ordfeminine', 'guillemetleft', 'logicalnot', 'registered', 'macron', 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute', 'mu', 'paragraph', 'periodcentered', 'cedilla', 'onesuperior', 'ordmasculine', 'guillemetright', 'onequarter', 'onehalf', 'threequarters', 'questiondown', 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', 'Adieresis', 'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Eth', 'Ntilde', 'Ograve', 'Oacute', 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn', 'germandbls', 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis', 'aring', 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis', 'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde', 'ograve', 'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', 'oslash', 'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', 'thorn', 'ydieresis', 'dotlessi', 'circumflex', 'caron', 'breve', 'dotaccent', 'ring', 'ogonek', 'tilde', 'hungarumlaut', 'quoteleft', 'quoteright', 'minus', 'exclam'], 'public.postscriptNames': {}, 'public.skipExportGlyphs': []} , observer=<lib.UI.inspector.glyphInfoPane.GlyphInfoPane object at 0x14b192a50>, existing method=libChanged, adding method=libChanged
    Traceback (most recent call last):
      File "lib/eventTools/eventManager.pyc", line 132, in callObserver_withMethod_forEvent_withInfo_
      File "lib/UI/inspector/basePane.pyc", line 88, in _currentGlyphChanged
      File "lib/UI/inspector/basePane.pyc", line 58, in _subscribeGlyph
      File "lib/UI/inspector/glyphInfoPane.pyc", line 359, in subscribeGlyph
      File "/Applications/RoboFont.app/Contents/Resources/lib/python3.7/defcon/objects/base.py", line 101, in addObserver
      File "/Applications/RoboFont.app/Contents/Resources/lib/python3.7/defcon/tools/notifications.py", line 82, in addObserver
    AssertionError: An observer is only allowed to have one callback for a given notification + observable combination. notification=Lib.Changed, observable={'com.defcon.sortDescriptor': [{'ascending': 'Latin-1', 'type': 'characterSet'}], 'com.robofont.generateFeaturesWithFontTools': False, 'com.typemytype.robofont.compileSettings.autohint': True, 'com.typemytype.robofont.compileSettings.checkOutlines': False, 'com.typemytype.robofont.compileSettings.createDummyDSIG': True, 'com.typemytype.robofont.compileSettings.decompose': False, 'com.typemytype.robofont.compileSettings.generateFormat': 0, 'com.typemytype.robofont.compileSettings.releaseMode': False, 'com.typemytype.robofont.italicSlantOffset': 0, 'com.typemytype.robofont.segmentType': 'curve', 'com.typemytype.robofont.shouldAddPointsInSplineConversion': 1, 'com.typemytype.robofont.smartSets.uniqueKey': '5204840272', 'public.glyphOrder': ['space', 'quotesingle', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', 'sterling', 'currency', 'yen', 'brokenbar', 'section', 'dieresis', 'copyright', 'ordfeminine', 'guillemetleft', 'logicalnot', 'registered', 'macron', 'degree', 'plusminus', 'twosuperior', 'threesuperior', 'acute', 'mu', 'paragraph', 'periodcentered', 'cedilla', 'onesuperior', 'ordmasculine', 'guillemetright', 'onequarter', 'onehalf', 'threequarters', 'questiondown', 'Agrave', 'Aacute', 'Acircumflex', 'Atilde', 'Adieresis', 'Aring', 'AE', 'Ccedilla', 'Egrave', 'Eacute', 'Ecircumflex', 'Edieresis', 'Igrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Eth', 'Ntilde', 'Ograve', 'Oacute', 'Ocircumflex', 'Otilde', 'Odieresis', 'multiply', 'Oslash', 'Ugrave', 'Uacute', 'Ucircumflex', 'Udieresis', 'Yacute', 'Thorn', 'germandbls', 'agrave', 'aacute', 'acircumflex', 'atilde', 'adieresis', 'aring', 'ae', 'ccedilla', 'egrave', 'eacute', 'ecircumflex', 'edieresis', 'igrave', 'iacute', 'icircumflex', 'idieresis', 'eth', 'ntilde', 'ograve', 'oacute', 'ocircumflex', 'otilde', 'odieresis', 'divide', 'oslash', 'ugrave', 'uacute', 'ucircumflex', 'udieresis', 'yacute', 'thorn', 'ydieresis', 'dotlessi', 'circumflex', 'caron', 'breve', 'dotaccent', 'ring', 'ogonek', 'tilde', 'hungarumlaut', 'quoteleft', 'quoteright', 'minus', 'exclam'], 'public.postscriptNames': {}, 'public.skipExportGlyphs': []} , observer=<lib.UI.inspector.glyphInfoPane.GlyphInfoPane object at 0x14b192a50>, existing method=libChanged, adding method=libChanged
    Observer '<lib.UI.inspector.guidelinesPane.GuidelinesPane object at 0x116925fd0>' with '_currentGlyphChanged' failed: An observer is only allowed to have one callback for a given notification + observable combination. notification=Font.GuidelinesChanged, observable=<lib.fontObjects.doodleFont.DoodleFont object at 0x136c74550> , observer=<lib.UI.inspector.guidelinesPane.GuidelinesPane object at 0x116925fd0>, existing method=fontGuidelinesChanged, adding method=fontGuidelinesChanged
    Traceback (most recent call last):
      File "lib/eventTools/eventManager.pyc", line 132, in callObserver_withMethod_forEvent_withInfo_
      File "lib/UI/inspector/basePane.pyc", line 88, in _currentGlyphChanged
      File "lib/UI/inspector/basePane.pyc", line 58, in _subscribeGlyph
      File "lib/UI/inspector/guidelinesPane.pyc", line 152, in subscribeGlyph
      File "/Applications/RoboFont.app/Contents/Resources/lib/python3.7/defcon/objects/base.py", line 101, in addObserver
      File "/Applications/RoboFont.app/Contents/Resources/lib/python3.7/defcon/tools/notifications.py", line 82, in addObserver
    AssertionError: An observer is only allowed to have one callback for a given notification + observable combination. notification=Font.GuidelinesChanged, observable=<lib.fontObjects.doodleFont.DoodleFont object at 0x136c74550> , observer=<lib.UI.inspector.guidelinesPane.GuidelinesPane object at 0x116925fd0>, existing method=fontGuidelinesChanged, adding method=fontGuidelinesChanged
    


  • @rdmcmurray

    I realized the resorting in step 4 is normal behavior, derp.


  • admin

    what font1.defaultLayer[glyph.name] = glyph does:

    • check if the glyph already exists: if it exist it will be removed from that layer: so that the reason why the glyph is at the end of the glyph order in the font overview. (as that glyph is also removed from the glyph order)
    • create a new glyph
    • draw the given glyph in the newly created glyph

    I cannot reproduce the error, based on your instructions. I will flag this to investigate.


Log in to reply