I am trying to fix a problem with a code editor I am developing that only appears when using OpenJDK 11 on a Mac with Retina display. The following screenshots illustrate the probem. Top is OpenJDK 11 (AdoptOpenJDK 11.0.5 HotSpot), bottom is JDK 8 (I believe Apple/Oracle JDK 8):
As you can see, OpenJDK 11 renders the font wider. This is a big problem, because I am using FontRenderContext#getStringBounds
to determine the monospace column width. With the default monospace font (looks like Menlo) and font size 14, this is reported to advance 8 pixels per character, which correctly corresponds to the JDK 8 rendering but not to the OpenJDK 11 rendering. What's worse, it seems that in the latter case, we do not get an integer number of pixels, but 8.5 pixels (the first non-comment line contains 38 characters, it takes 38 * 8 * 2 = 608 pixels on JDK 8, but around 646 pixels on OpenJDK 11.
What's even more strange is that this problem is caused by rendering AttributedText
instances using Graphics2D#drawString
. If I convert to plain text, use g.setFont
, OpenJDK 11 renders exactly like JDK 8. So it must have to do with particular implementation of rendering AttributedCharacterIterator
.
Obviously I am not changing my whole implementation because of this bug, so I am looking for a workaround (other than asking the user to select a different font, of course). Perhaps there are some system properties...?
Edit: After some further debugging session, I can see that the difference comes out of ExtendedTextSourceLabel#createGV
and deeper down SunLayoutEngine#layout
which then calls into native code, where despite the same font strike description, in JDK 8 the _positions
in the glyph data are set to integer numbers, whereas in OpenJDK 11 they are set to fractional numbers (and also actually not multiplies of 0.5
, so it doesn't appear to have anything to do with the fact that we are running on a Retina display; perhaps though, that the font is backed by a native macOS font)
This shows that it depends on the font size, not on whether a font is "native" or bundled:
This is with the Inconsolata .ttf on the class path, at font size 32. In comparison, font size 33:
Here the reported font advancement, based on
FontRenderContext#getStringBounds
, is 17.0 -- visualised by the gray rectangles -- but the actual rendering is slightly more narrow.