justvanrossum / fontgoggles

FontGoggles: Visual OTL Preview and QA

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem with certain COLRv1 glyphs in Noto-COLRv1.ttf

yarmola opened this issue Β· comments

I am trying to paste a unicode string which contains character with codepoint above BMP (this one: πŸŽ›). App does not like it (glyph flashes, then sample rendering disappears and text editing UI becomes unusable until app restart)

Screenshot 2022-09-21 at 13 57 06

I am experimenting with Noto Color Emoji font from here:
https://github.com/googlefonts/noto-emoji

I get the same with my totally different implementation of blackrenderer using cairo. Other glyphs are fine, but when I view this one and lots of others I get flashing or nothing.

Traceback (most recent call last):
File "/Users/somebody/glyph_viewer.py", line 530, in OnPaint
self.brFont.drawGlyph(self.currentGlyphName, cairoCanvas,
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 166, in drawGlyph
self._drawGlyphCOLRv1(glyph, canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 191, in _drawGlyphCOLRv1
self._drawPaint(glyph.Paint, canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 211, in _drawPaint
drawHandler(paint, canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 219, in _drawPaintColrLayers
self._drawPaint(self.colrLayersV1.Paint[i], canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 211, in _drawPaint
drawHandler(paint, canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 353, in _drawPaintComposite
self._drawPaint(paint.BackdropPaint, canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 211, in _drawPaint
drawHandler(paint, canvas)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/font.py", line 223, in _drawPaintSolid
canvas.drawPathSolid(self.currentPath, color)
File "/Users/somebody/somevenv/lib/python3.10/site-packages/blackrenderer/backends/cairo.py", line 105, in drawPathSolid
path.replay(self._pen)
AttributeError: 'NoneType' object has no attribute 'replay'

That may be the same error, I'll have a look.

Definitely a bug in blackrenderer, though I get yet another error:

Traceback (most recent call last):
  File "/Users/just/code/git/BlackFoundry/black-renderer/venv/bin/blackrenderer", line 33, in <module>
    sys.exit(load_entry_point('blackrenderer', 'console_scripts', 'blackrenderer')())
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/__main__.py", line 43, in main
    renderText(
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/render.py", line 78, in renderText
    font.drawGlyph(glyph.name, canvas, palette=palette)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 166, in drawGlyph
    self._drawGlyphCOLRv1(glyph, canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 191, in _drawGlyphCOLRv1
    self._drawPaint(glyph.Paint, canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 211, in _drawPaint
    drawHandler(paint, canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 219, in _drawPaintColrLayers
    self._drawPaint(self.colrLayersV1.Paint[i], canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 211, in _drawPaint
    drawHandler(paint, canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 353, in _drawPaintComposite
    self._drawPaint(paint.BackdropPaint, canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 211, in _drawPaint
    drawHandler(paint, canvas)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/font.py", line 223, in _drawPaintSolid
    canvas.drawPathSolid(self.currentPath, color)
  File "/Users/just/code/git/BlackFoundry/black-renderer/Lib/blackrenderer/backends/skia.py", line 104, in drawPathSolid
    self.canvas.drawPath(path.path, paint)
AttributeError: 'NoneType' object has no attribute 'path'

But FontGoggles should also not crash like that when it encounters a blackrenderer bug.

Ah, but that's the same exact error, just a different backend. At the point drawPaintSolid is called the path is None in both cases. cairo tries to replay the path, skia tries to access path.path.

I don't know what non-BMP has to do with it. πŸŽ› 🎟 🎫 all fail for me, but everything else seems fine from what I can tell so far.

Probably it is this particular glyph. It is built using the COLRv1 composition operator COMPOSITE_SRC_IN, but "backend" is empty. It does not look good (font-side) and I am investigating it (and will open issue in Noto Color Emoji if I find something), but I don't think renderer should crash.

@yarmola, there'a already more discussion and analysis over at BlackFoundryCom/black-renderer#116. The font is fine, but blackrenderer doesn't implement this case correctly.

hey Yuri, the backround is not empy, it's simply unbounded, which is valid and spec'ed here: https://learn.microsoft.com/en-us/typography/opentype/spec/colr#metrics-and-boundedness-of-color-glyphs-using-version-1-formats

Right, thanks!

Funny that in the sample above in the spec

They have unbounded gradient fill in "source" part of the composite operator while in the real font it is in the "backdrop" part (and it makes more sense).

I checked SVG origin of this glyph and it has "group" of objects with assigned transparency.
Anyway, I think I should move to the black renderer repo with this, I believe the issue related to FontGoggles is clear :)

They have unbounded gradient fill in "source" part of the composite operator while in the real font it is in the "backdrop" part (and it makes more sense).

good point, we should fix that actually. Mind filing an issue for this on the https://github.com/googlefonts/colr-gradients-spec repo?

This should be fixed in FontGoggle 1.7.0: https://github.com/justvanrossum/fontgoggles/releases

They have unbounded gradient fill in "source" part of the composite operator while in the real font it is in the "backdrop" part (and it makes more sense).

good point, we should fix that actually. Mind filing an issue for this on the https://github.com/googlefonts/colr-gradients-spec repo?

No, please open an issue on the COLR page of the OT spec. (For the figure in the spec, an SVG with feComposite was used to create the example, it in that SVG the rectangle with the alpha gradient is the destination (in2 attribute), not the source (in attribute).) If source and destination are reversed (as currently in the spec's figure), then the result would be the black alpha-gradient rectangle clipped to the circle.

For COMPOSITE_SRC_IN, the PaintComposite is bounded if either the source or destination is bounded. That's implicit in the definition in the CSS spec. If some library is failing because the source graphic is unbounded even though the destination graphic is bounded, then that would seem to be either a bug in that library or a limitation of that library that implementations using it need to work around.