GTK 4.14 中的辅助功能改进

GTK 4.14 在辅助功能方面带来了各种改进,特别是对于显示复杂、格式化文本的应用程序;对于 WebKitGTK;以及对于通知。

可访问文本接口

4.0 版本的辅助功能重写为 GTK 提供的部件(如 GtkTextView)中的复杂、可选择和格式化文本提供了一个实现,但是树外的部件无法做到这一点,因为在我们讨论 AT(辅助技术)实际需要什么以及我们研究非 Linux 实现时,API 保持私有。对于 GTK 4.14,我们终于有了一个公共接口,树外的部件可以实现该接口,以向 AT 提供复杂、格式化的文本:GtkAccessibleText

GtkAccessibleText 允许部件在给定偏移量处提供文本内容;应用于内容的文本属性;以及通知辅助技术文本、插入符位置或选择边界的变化。

实现 GtkAccessibleText 的文本部件应在以下情况下通知 AT

文本属性主要由应用程序实现——无论是在命名还是序列化方面;GTK 为各种工具包和辅助技术已经使用的常见文本属性提供支持,并且它们在 API 参考中作为 GTK_ACCESSIBLE_ATTRIBUTE_* 前缀下的常量提供。

GtkAccessibleText 接口是实现虚拟终端辅助功能的必要条件;最常见的基于 GTK 的虚拟终端库 VTE,由于 Christian Hergert 的努力,已被移植到 GTK4,并且在 GNOME 46 中将通过新的 GTK 接口支持辅助功能。

桥接 AT-SPI 树

在某些情况下,库或应用程序会使用 AT-SPI 实现自己的可访问树,无论是在同一进程中还是在进程外。WebKitGTK 就是这样一个库,它从单独进程中的 Web 树生成可访问的对象树。这些进程不使用 GTK,因此它们不能使用 GtkAccessible API 来描述其内容。

感谢 Georges Stavracas 的工作,GTK 现在可以将这些可访问的对象树桥接到 GTK 部件的下面,允许 AT 从 UI 使用 WebKit 导航到网页中。

目前,与 GTK 中其余的辅助功能 API 一样,这特定于 Linux 上的 AT-SPI 协议,这意味着希望利用它的库和应用程序需要确保该 API 在编译时可用,方法是通过使用 pkg-config 文件和单独的 C 标头,类似于公开打印 API 的方式。

通知

使用与当前部件的焦点分离的应用内通知的应用程序,如 libadwaita 中的 AdwToast,现在可以通过 gtk_accessible_announce() 方法将通知消息发送到 AT,这要归功于 Lukáš Tyrychtr,其方式尊重当前的 AT 输出。

其他改进

GTK 4.12 确保计算出的可访问标签和描述与 ARIA 规范保持同步;GTK 4.14 通过删除特殊情况和重复项来迭代这些改进。

感谢来自 The Document Foundation 的 Michael Weghorn 的工作,为与文本相关的可访问对象提供了新的角色,如段落和注释,以及在辅助功能 API 的 AT-SPI 实现中的各种修复。

感谢许多人的贡献,GTK4 中的辅助功能支持正在每个周期逐步改进;理想情况下,这些改进还应为工具包和辅助技术共享提供更好、更高效的协议。

我们仍在探索为其他辅助功能平台(如 UIAutomation)以及其他库(如 AccessKit)添加后端的可能性。

关于分数比例、字体和提示

GTK 4.14 即将发布,其中包含今年早些时候引入的新渲染器。

新的渲染器对分数缩放的支持得到了很大改进——在我的系统上,我现在使用 125% 的缩放而不是“大文本”设置,我发现这对于我的需求来说效果很好。

神奇的数字

自 4.0 以来,GTK 一直在提倡线性布局。

其想法是,我们只需将字形放置在坐标告诉我们的位置,如果这是一个像素之间的某个分数位置,那就这样,我们可以很好地在该偏移量处渲染轮廓。这种方法有效——如果您的输出设备具有足够高的分辨率(任何高于 240 dpi 的分辨率都可以)。可悲的是,我们生活在一个大多数笔记本电脑屏幕都没有这种分辨率的世界,因此我们不能仅仅忽略像素。

因此,我们添加了 gtk-hint-font-metrics 设置,该设置强制文本布局将内容舍入到整数位置。这不太适合分数缩放,因为舍入发生在应用程序像素中,而我们真正需要的是整数设备像素位置才能产生清晰的结果。

应用程序像素与设备像素

常见的分数比例是 125%、150%、175%、200% 和 225%。在这些比例下(200% 除外),大多数应用程序像素边界与设备像素边界不对齐。

现在怎么办?

新的渲染器为我们提供了一个机会,可以重新审视字体渲染的主题,并对提示选项的机制进行一些研究,以及它们如何从 GTK 通过 Pango 和 cairo 传递下来,然后最终作为渲染目标 + 加载标志的组合出现在 freetype 中。

提示样式和抗锯齿选项转换为渲染模式和加载标志

新的渲染器认识到,在字形方面有两种基本的操作模式

  • 优化统一间距
  • 优化清晰渲染

前者导致亚像素定位和无提示渲染,后者导致提示渲染和放置在整数像素位置的字形(因为这是自动提示器所期望的)。

我们通过查看字体选项来确定我们处于哪种情况。如果它们告诉我们进行提示,我们将字形位置在 y 方向上舍入到整数设备像素。为什么只在 y 方向?自动提示器仅在垂直方向上应用提示,而水平方向是亚像素位置的更高分辨率最能发挥作用的地方。如果我们不提示,那么我们对 x 和 y 都使用亚像素位置,就像旧的渲染器一样(值得注意的是,新的渲染器在设备像素中使用亚像素位置)。

比较

文本渲染差异总是很细微,并且在某种程度上取决于品味和偏好。因此,这些屏幕截图应该谨慎对待——最好自己尝试一下新的渲染器。

在 125% 处渲染的文本,旧的渲染器
在 125% 处渲染的文本,新的渲染器

这两个渲染都是在 125% 的比例下完成的,启用了提示(但请注意,旧的渲染器通过在 200% 处渲染并依靠合成器来缩小比例来处理 125%)。

下面是一些细节:T 和 e 的水平条在各行之间保持一致,即使我们仍然允许字形在水平方向上移动亚像素位置。

一致的垂直放置
T 和 e 的实例,旧的渲染器
T 和 e 的实例,新的渲染器

总结

GTK 4.14 中的新渲染器应该产生更清晰的字体渲染,尤其是在分数缩放的情况下。

请试用一下,并告诉我们您的想法。

更新:关于亚像素渲染

我应该预料到会出现这个问题,所以这里有一个快速的答案

我们在 GTK 4 中不使用亚像素渲染(也称为 Cleartype 或 rgb 抗锯齿),因为我们的合成不具有组件 alpha。我们的字体抗锯齿始终是灰度。请注意,亚像素渲染与亚像素定位是不同的。