[nonelab] Copied glyphs can't do everything until being inserted into a font
From Victor Gaultney:
"I’ve been using fontParts to write some scripts with general success so far. However I’m finding that BaseGlyph.copy() doesn’t create what I expect. The docs say, for example, that a new glyph object is created, and that things like unicodes, contours, components are copied. I can also use a pen to draw into that object, and even modify things like unicodes. I can use font.setitem(name,newglyphobject) to insert the copied and modified glyph into the font. All good.
However some other things don’t work. I can’t get copyofglyph.bounds (TypeError: 'NoneType' object is not subscriptable) . If I try copyofglyph.decompose() I get an error that it’s not iterable. Those work fine if I insert the copied glyph object into the font and then use those methods on the inserted glyph."
One old way to fix some of the mentioned issues was to setParent of the glyph to the font in Robofab but it's gone in FontParts. I guess we could have a copy of a glyph only for some operations that are not destructive to the actual glyph and if that glyph is a composite then it needs to have a parent or set of glyphs for decomposing the components. This copied glyph doesn't need to be inserted in the font, it's only in the memory. What issues this would cause that made it removed?
Edit: setParent is not gone in FontParts, it's deprecated but still.
I think the glyph.layer property is the replacement of the setParent() method. However, I can't get that to work:
from fontParts.world import OpenFont
f = OpenFont("font.ufo")
g = f["agrave"]
g2 = g.copy()
g2.layer = g.layer
g2.decompose()
TypeError: argument of type 'NoneType' is not iterable
it does not work cause the naked objects has no layer set... and the decomposing in fe defcon happens elsewhere.
I would recommend to have a copy pen without components:
from fontParts.world import OpenFont, RGlyph
from fontTools.pens.basePen import BasePen
f = OpenFont("font.ufo")
g = f["agrave"]
g2 = RGlyph()
class MyCopyDecomposingPen(BasePen):
def __init__(self, glyphSet, outPen):
super(MyCopyPen, self).__init__(glyphSet)
self._moveTo = outPen.moveTo
self._lineTo = outPen.lineTo
self._curveToOne = outPen.curveTo
self._closePath = outPen.closePath
self._endPath = outPen.endPath
pen = MyCopyDecomposingPen(f, g2.getPen())
g.draw(pen)
print(g2.bounds)
or use pen to calculate the bounds, where you can provide any kind of glyphSet:
from fontTools.pens.boundsPen import BoundsPen
pen = BoundsPen(f)
g2 = g.copy()
g2.draw(pen)
print(pen.bounds)
it does not work cause the naked objects has no layer set... and the decomposing in fe defcon happens elsewhere.
How is that not a bug?
its a bug :)
only decomposing should happen in fontParts instead of leaving it to the implementation (on fontshell its defcon)
this one: https://github.com/robotools/fontParts/blob/master/Lib/fontParts/base/component.py#L322-L326 is for the implementation
this one does almost nothing towards the implementation: https://github.com/robotools/fontParts/blob/master/Lib/fontParts/base/glyph.py#L116-L117
It's a bug, PRs welcome!