Skip to content

JEP 263: HiDPI Graphics on Windows and Linux | 在 Windows 和 Linux 上支持 HiDPI 图形

摘要

在 Windows 和 Linux 上实现 HiDPI 图形。

动机

开发者和用户对在 HiDPI 显示器上运行的应用程序有一些基本期望:

  • Windows 和 GUI 组件应根据平台建议具有适当的大小,

  • 无论 HiDPI 设置的默认缩放如何,文本应保持清晰,且

  • 图标和图像应平滑,并且最好具有适合显示器像素密度的细节。

不幸的是,即使在 HiDPI 显示器上,Java 应用程序仍然基于像素在 Windows 和 Linux 上进行大小和呈现,这些显示器的像素密度可能是传统显示器的 2 到 3 倍。这导致 GUI 组件和窗口小了 2 到 3 倍,因此无法阅读或有效地交互。

JDK 已经支持在 Mac OS X 上的 HiDPI“视网膜显示器”,并以适当的尺寸为显示屏的密度提供清晰的文本和图像。Mac 的“视网膜”支持已经为支持所有平台上的 HiDPI 显示器提供了相当多的基础工作,但是各个平台处理 HiDPI 的方式存在差异,这意味着还需要进一步工作来推广 Mac 上的工作。

现在应该为 Windows 和 Linux 平台提供同样的自动缩放和调整大小功能。

描述

Windows 上的 HiDPI

Windows 控制面板提供了许多途径,让用户在桌面上请求对组件和窗口进行缩放(自 Windows XP 以来以各种形式提供)。某些操作系统版本还提供了自动缩放未声明为“DPI-aware”的应用程序的功能。对于“DPI-unaware”应用程序的默认缩放可能会导致许多视觉伪像,包括模糊的窗口、不准确的布局和被裁剪的文本,因此 Java 运行时长期以来已经声明自己是“DPI-aware”,以避免模糊和布局问题。然而,根据 DPI 进行内容缩放并不是一项简单的任务,而且由于大多数显示器密度只需要进行 25% 的小幅缩放,因此决定忽略推荐的缩放准则和策略,继续以 1:1 像素缩放渲染 AWT 和 Swing 组件,并且 JDK 应用程序稍微小于标准尺寸,但文本和图形清晰。

然而,最近,显示器的像素密度大幅增加,现在很容易找到像素密度是当初做出这些决策时常见显示器密度的 2 到 3 倍的笔记本电脑。因此,这些较新的 Windows 机器上的 Java 应用程序有时可能会非常小,以至于无法使用 - 这不再是“稍微小一点对比模糊窗口”的情况,因此我们需要正确地缩放应用程序窗口。

Windows API 提供了度量、机制和指南来编写 DPI-aware 应用程序,使 UI 在各种 DPI 显示设置下具有一致的外观,并响应用户为使 UI 足够大以便用户可以舒适地与 UI 组件交互的偏好设置。

Windows Direct2D 图形 API 会自动遵循系统 DPI,使用 DIPs(设备无关像素)来表示坐标,使位图具有 DPI,并通过考虑 DPI 正确缩放它们。然而,AWT 和 Swing 库不是基于 Direct2D 图形 API 构建的。

Windows 7 及更高版本提供了许多方法来获取桌面的水平和垂直 DPI,包括GetDesktopDpi方法,在 Windows 8.1 中还有GetDpiForMonitor方法和WM_DPICHANGED消息。这些值可以用于在 AWT/Swing 库中支持 HiDPI 的情况下缩放窗口大小、鼠标坐标和字体。必要的缩放支持已经存在于 Java2D 渲染层中,但我们需要将这些值广告给 Swing 和 AWT,并更新它们的组件以识别和尊重缩放因子。这种支持包括确保期望的渲染比例因子提供给 Java2D Graphics对象,使用适当的缩放因子对中间渲染图像进行渲染,并重新审查关于渲染调用中的坐标如何映射到像素的任何假设。

Linux 上的 HiDPI

GTK+ 3 库已经实现了 HiDPI 支持。在使用 HiDPI 显示器时,GTK 库会自动缩放应用程序。

而 Java2D 和 AWT 使用的是不支持 HiDPI 的 XLib 库。因此,当前的 Java 应用程序在 Linux 上的 HiDPI 显示器上可能会看起来是 2 到 3 倍太小。

此外,任何使用 GTK 外观样式的 Java 应用程序在 GTK 库中获得 HiDPI 支持时,窗口和其他组件的大小可能与已经放大 2-3 倍以满足 HiDPI 要求的 GTK 组件匹配。这可能导致一些问题,比如JDK-8058742中所描述的问题。

替代方案

开发人员在 HiDPI 显示器上运行时可以手动缩放应用程序中的所有 GUI 元素,但这需要对应用程序进行大量的重构工作,并且 Swing 和 AWT 组件不适合从外部尝试缩放它们。

测试

以下测试应在 HiDPI 显示器上进行。最好使用各种屏幕缩放比例 - 192 DPI 和 144 DPI 是一个很好的最小支持矩阵。请注意,可以使用 Windows 控制面板将非常高的 DPI 显示器设置为较低的人工 DPI,因此不一定需要额外的系统,但测试运行之间必须重新配置它们。此外,在 Windows 上更改 DPI 通常需要重新启动以使新的 DPI 对应用程序可见。

在 Windows 上,可以在控制面板中设置 DPI 设置。不同版本的控制面板和允许的设置存在于 Windows 7、Windows 8.1 和较旧的 Windows 版本中,但它们都倾向于向应用程序提供相同类型的信息(X 和 Y 的指定 DPI),因此当前不需要在控制面板的变化下进行额外的测试,这只是影响测试环境配置方式的细节。

在 Linux 上,可以使用 GDK_SCALE 环境变量来模拟 DPI 设置,用于 GTK+ 3,或使用 GNOME 3 的 scaling-factor 设置。

应检查以下内容:

  • 文本不应模糊
  • 组件(标签和按钮)中的文本不应被裁剪
  • AWT/Swing上的UI组件布局应保持合理(即无重叠或奇怪的间隙)
  • 当应用程序或测试用例提供时,应在 AWT/Swing 对话框和组件上使用高分辨率图标
  • 应用程序应正确处理鼠标事件
  • 应用程序的大小应与良好行为的 DPI-aware 本地应用程序类似

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.