我正在尝试解决我正在开发的代码编辑器的问题,该问题仅在具有 Retina 显示屏的 Mac 上使用 OpenJDK 11 时出现。以下屏幕截图说明了这个问题。顶部是 OpenJDK 11(AdoptOpenJDK 11.0.5 HotSpot),底部是 JDK 8(我相信 Apple/Oracle JDK 8):
如您所见,OpenJDK 11 使字体更宽。这是一个大问题,因为我是FontRenderContext#getStringBounds
用来确定等宽列宽的。使用默认的等宽字体(看起来像Menlo)和 14 号字体,据报告这会使每个字符提前 8 个像素,这正确对应于 JDK 8 呈现,但不对应于 OpenJDK 11 呈现。更糟糕的是,似乎在后一种情况下,我们得到的不是整数个像素,而是 8.5 个像素(第一个非注释行包含 38 个字符,在 JDK 8 上它需要 38 * 8 * 2 = 608 个像素,但是在 OpenJDK 11 上大约 646 像素。
更奇怪的是,这个问题是由AttributedText
使用Graphics2D#drawString
. 如果我转换为纯文本,使用g.setFont
OpenJDK 11 的渲染与 JDK 8 完全相同。所以它必须与渲染的特定实现有关AttributedCharacterIterator
。
显然我并没有因为这个错误而改变我的整个实现,所以我正在寻找一种解决方法(当然,除了要求用户选择不同的字体)。也许有一些系统属性......?
编辑:经过一些进一步的调试会话后,我可以看到差异来自ExtendedTextSourceLabel#createGV
更深层次SunLayoutEngine#layout
,然后调用本机代码,尽管字体打击描述相同,但在 JDK 8_positions
中,字形数据设置为整数,而在 OpenJDK 11 中,它们被设置为小数(实际上也不是 的倍数0.5
,所以它似乎与我们在 Retina 显示器上运行的事实没有任何关系;也许,字体由本机 macOS 字体)