[OpenJDK 2D-Dev] RFR: 8263583: Emoji rendering on macOS
prr at openjdk.java.net
Mon Mar 15 23:50:13 UTC 2021
On Mon, 15 Mar 2021 15:59:36 GMT, Alexey Ushakov <avu at openjdk.org> wrote:
>> This is the implementation used by JetBrains Runtime for the last 4 years, after some cleanup, and with one problem,
>> found while preparing the pull request, fixed.
>> Even though typical scenarios for a UI application should be covered, it's not a complete solution. In particular, emoji-s
>> still won't be rendered for large font sizes (more than 100pt), and for non-trivial composite/painting modes.
>> Notable implementation details are listed below.
>> **Glyph image generation**
>> Deprecated CGContextShowGlyphsAtPoint function, used by JDK on macOS to render text, cannot render emojis,
>> CTFontDrawGlyphs is used instead. It ignores the scale component of text transformation matrix, so a 'real-sized'
>> CTFont object should be passed to it. The same sizing procedure is done when calculating glyph metrics, because they
>> are not scaled proportionally with font size (as they do for vector fonts).
>> **Glyph image storage**
>> Existing GlyphInfo structure is used to store color glyph image. Color glyph can be distinguished by having 4 bytes
>> of storage per pixel. Color components are stored in pre-multiplied alpha format.
>> **Glyph rendering**
>> Previously, GlyphList instance always contained glyphs in the same format (solid, grayscale or LCD), determined by the
>> effective rendering hint. Now the renderers must be prepared to GlyphList having 'normal' glyphs interspersed with
>> color glyphs (they can appear due to font fallback). This isn't a problem for OpenGL renderer (used for on-screen painting),
>> but GlyphListLoopPipe-based renderers (used for off-screen painting) needed an adjustment to be able to operate on
>> specific segments of GlyphList.
>> As an incidental optimization, calculation of GlyphList bounds ('getBounds' method) is performed now only when needed
>> (most text renderers don't need this information).
>> Speaking of the actual rendering of the glyph image, it's done by the straightforward glDrawPixels call in OpenGL renderer,
>> and by re-using existing Blit primitive in off-screen renderers.
>> There's no good way to test the new functionality automatically, but I've added a test verifying that 'something' is
>> rendered for the emoji character, when painting to BufferedImage.
>> Existing tests pass after the change.
> Looks good
Initial testing it looks OK with OpenGL but it renders as garbage with the metal pipeline.
I'd guess metal isn't expecting 4bpp and the stride is wrong.
Since metal is now integrated this should be fixed before this change can be pushed.
More information about the 2d-dev