A bug in JDK code means that sometimes we store the
user space advance on the glyph image, so when blitting
the glyphs are overlapped. Because we may also subsequently
access this value to retrieve advance, then metrics
may also be incorrect.
It is a specific case of 6685312 which was not covered
in that fix, the scenario being :
- The app is running on Windows
- it is displaying LCD text
- the graphics transform is a scaling transform
- the resulting device text is scaled to > 48 pixels
- getGlyphMetrics() is called before getGlyphAdvance or any rendering.
I believe GlyphVector and TextLayout are the most usual
cases where the latter occurs.
The reason behind is as follows. When we use the windows native
rasteriser for LCD glyphs, we also "fix up" the glyph device
advance to be compatible with T2K. This may be an abundance of
caution, but some glyph advances were marginally different.
[[Likely this is due to Windows consulting the hdmx table,
whereas JDK instead consults the rasteriser. We should revisit
this but too, but that's an issue for another day]].
Since advance is returned to the app scaled back to user space
coordinates, we can't store that in the glyph, we need the
device advance. This can be reproduced when
glyphs are > 48 pixels because we then store that in an
advances array without at the same time creating the image,
unless it was also requested.
So when the image is subsequently created it consults that
array which will have user advance, not device advance.
One fix is to make accesses to those advance arrays
- be consistent in storing user advance
- re-apply device transform as needed.
However this is making that code unduly complex for what
for a single caller. I think it may be safer to up front
identify the case when there's a scale and skip looking
or updating the advances arrays.