[OpenJDK 2D-Dev] RFR: 8263583: Emoji rendering on macOS

Dmitry Batrak dbatrak at openjdk.java.net
Mon Mar 15 10:31:36 UTC 2021

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.


Commit messages:
 - 8263583: Emoji rendering on macOS

Changes: https://git.openjdk.java.net/jdk/pull/3007/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=3007&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8263583
  Stats: 816 lines in 28 files changed: 677 ins; 29 del; 110 mod
  Patch: https://git.openjdk.java.net/jdk/pull/3007.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/3007/head:pull/3007

PR: https://git.openjdk.java.net/jdk/pull/3007

More information about the 2d-dev mailing list