On Mon, 27 Apr 2026 20:07:41 GMT, Daniel Gredler <[email protected]> wrote:

> When rendering Thai text, scaling fonts via `deriveFont(float)` seems to 
> always work correctly. However, when the font is scaled via 
> `deriveFont(AffineTransform)`, the vowels above the main line of text are 
> misplaced, mangling the meaning of the text.
> 
> This appears to be caused by GPOS adjustments performed by HarfBuzz which are 
> calculated at the wrong scale if the full (point size + AffineTransform) 
> scale is not provided to HarfBuzz upon font creation.
> 
> The fix must change both the FFM and JNI HarfBuzz integration code, so it 
> looks a bit longer than it actually is. The FFM and JNI changes were made in 
> separate commits, so it might be helpful to review only the FFM changes in a 
> first pass, and then have a look at the corresponding JNI changes (which are 
> in a separate commit).
> 
> Some observations:
> 
> - jdk_font_create_hbp() needs to incorporate font transform scaling, not just 
> the font point size scaling
> - jdk_font_create_hbp() needs two independent font scales / point sizes (x 
> and y)
> - jdk_font_create_hbp() applies devTx, only for it to be removed in 
> store_layout_results(); we might as well leave devTx out from the start
> 
> Sequence of changes made to the FFM code:
> 
> - Replace SDCache.gtx (glyph transform = font transform without translation, 
> plus point size scaling, plus device transform) with SDCache.ftx (font 
> transform including translation, plus point size scaling)
> - Remove SDCache.delta (just keep translation components in new ftx field 
> instead)
> - Remove SDCache.dtx (never used)
> - Remove devScale from store_layout_results() parameters (dev scale no longer 
> included during layout, so doesn't need to be undone here)
> - Remove destroy function param from jdk_font_create_hbp() (never used, 
> always NULL)
> - Calculate x and y font point sizes in jdk_hb_shape (based on full font 
> transform, including font pt size), instead of using only font pt size
> - Pass these x and y point sizes into jdk_font_create_hbp()
> - Remove now-unused ptSize parameter from jdk_font_create_hbp()
> - Remove now-unused devScale parameter from jdk_font_create_hbp()
> - Remove now-unused ptSize parameter from jdk_hb_shape()
> - Remove now-unused ptSize parameter from HBShaper.shape()
> 
> Sequence of changes made to the JNI code:
> 
> - Remove destroy function from _hb_jdk_font_create(), not used just like in 
> FFM code
> - Use xPtSize and yPtSize in _hb_jdk_font_create(), instead of ptSize and 
> devScale
> - Remove devScale from storeGVData (not used during layout, so doesn't need 
> to be undone at the end)
> - Remove now...

JDK-8145901 has stuff in it I can't sanitize. 

This bug is from when we first integrated harfbuzz. My memory of this > 10 year 
old issue is extremely minimal.

The fix review thread is here
https://mail.openjdk.org/archives/list/[email protected]/thread/RULT6RB3SW7DUXBU6YGFJ5FVHEJ6YJCL/

The problem was over-lapping text (plain old Latin) in Unix printing (ie our 
postscript generation)
So testing that would be the reequirement

Based on my comment in that review I probably thought people could read the bug 
eval.
I'll paste the pertinent part of it here (below).

===

The font interface supplied to harfbuzz is setting the point size (scale)
based on the device size font. When printing, this is scaled from the
user size font by (typically) around 4X.
So when performing a kerning adjustment the affected glyphs are
moved accordingly.

But advances are being provided in user space and so the kerning
adjustment is too great relative to the advances.

Everything needs to be consistent. The easiest thing to do
is use the user space point size for the scale too.

The (maybe better) alternative is to make all the adjustments so that we
 - keep xPtSize as the scale
 - scale horizontal advance by xPtSize/ptSize
 - de-scale the resulting glyph positions by the same
 - make sure this is OK in the coretext code path too.
 This would seem to cover most of what is reported above but Swing still
does not "perfectly" print text due to using getJustifiedLayout after the fact.
===

-------------

PR Comment: https://git.openjdk.org/jdk/pull/30953#issuecomment-4330458476

Reply via email to