【问题标题】:OpenJDK 11 Swing monospaced font rendering problem on macOS Retina despite turned off fractional width尽管关闭了小数宽度,但 macOS Retina 上的 OpenJDK 11 Swing 等宽字体渲染问题
【发布时间】:2020-04-13 04:28:39
【问题描述】:

我正在尝试解决我正在开发的代码编辑器的问题,该问题仅在具有 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 像素。

更奇怪的是,这个问题是使用Graphics2D#drawString渲染AttributedText实例引起的。如果我转换为纯文本,使用g.setFont,OpenJDK 11 的渲染与 JDK 8 完全一样。所以它必须与渲染AttributedCharacterIterator 的特定实现有关。

显然我并没有因为这个错误而改变我的整个实现,所以我正在寻找一种解决方法(当然,除了要求用户选择不同的字体)。也许有一些系统属性...?


编辑:经过进一步的调试会话,我可以看到差异来自ExtendedTextSourceLabel#createGV 和更深层次的SunLayoutEngine#layout,然后调用本机代码,尽管字体罢工描述相同,在 JDK 8 中,字形数据中的 _positions 被设置为整数,而在 OpenJDK 11 中,它们被设置为小数(实际上也不是 0.5 的乘积,所以它似乎没有任何关系事实上,我们在 Retina 显示器上运行;也许,该字体由原生 macOS 字体支持)

【问题讨论】:

  • 我可以看到的“解决方法”是某些字体似乎有问题(Menlo,默认设置),而其他字体则没有(例如 IBM Plex Mono)。因此,可以捆绑一种开源字体,例如 IBM Plex Mono,register it with the local graphics environment,并使用该字体代替 "Monospaced"

标签: java macos swing retina-display font-rendering


【解决方案1】:

This 表明它取决于字体大小,而不是取决于字体是“原生”还是捆绑:

这是类路径上的 Inconsolata .ttf,字体大小为 32。相比之下,字体大小为 33:

此处报告的基于FontRenderContext#getStringBounds 的字体改进为 17.0 - 由灰色矩形可视化 - 但实际渲染稍微窄一些。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-24
    • 1970-01-01
    • 2019-09-19
    相关资源
    最近更新 更多