Godot游戏引擎中复杂的文本布局进度报告

2020-11-10 19:46:43

这是我为Godot4.0所做的复杂文本布局工作的第二部分,重点是字体和用户界面镜像。

有关CTL建议和反馈的详细信息,请参见GitHub上的戈多-提案#1180、戈多-提案#1181、戈多-提案#1182和戈多-提案#1183。

自从字体处理转移到TextServer后,Godot Font和相关类做了一些实质性的更改:

BitmapFont、DynamicFont和DynamicFontData被移除,取而代之的是由TextServer支持的通用字体和字体数据资源。这为自定义文本服务器提供了更清晰的字体后备/替换,并且可以在不更改界面的情况下公开不同类型的字体,例如直接访问系统字体。

新的Font类提供了绘制和测量多行文本以及应用对齐方式的新函数。

字体和轮廓大小是Font实例的属性,它们被移到绘图函数和主题常量的参数中。这允许更改RichTextLabel控件中单个绘制调用、控件或文本跨度的字体大小,而无需创建新的Font实例。

从内存缓冲区加载字体数据的函数向GDScript和GDNative公开。

每个FontData都有一个支持的脚本(书写系统)和语言的关联列表。对于TrueType/OpenType字体,脚本列表是从OS2表自动填充的,但它并不总是精确的。

对于具有特定脚本和语言的每个文本串,TextServer将尝试按以下顺序使用字体:

许多拉丁字体在科学文本中只有一组有限的希腊字符(这些字体通常在OS2表格中设置了希腊文字支持标志),但它并不总是足以显示希腊文本。添加完全支持希腊语的单独字体,并在主字体中禁用希腊语支持,将防止TextServer混合不同字体的字符。

TrueType/OpenType字体表格没有稀有/古老文字(例如埃及象形文字)的标志,手动启用脚本支持将加快字体替换速度。

一些语言使用相同的文字,但字体风格不同(例如,Kufic、Naskh和Nastaʼlīq书写风格首选用于书写不同的阿拉伯语;或者在不同地区使用繁体中文和中日韩变体-繁体中文、简体中文、日语和韩语)。通过设置语言覆盖,可以无缝地对不同语言的文本使用相同的字体堆栈,并获得所需的样式。

用于";μ";的字体不正确:用于";μ";的字体正确:设置了Language属性的标签使用相同的字体实例:cjk变体,使用相同字体实例的标签:

此外,新的字体和文本服务器的BiDi和Shape功能可以使用可变字体(有关可变字体支持PR,请参阅Godot#43030):

在Theme、Control和Window类中添加了控制字体大小的函数:

主题函数:CLEAR_FONT_SIZE、GET_FONT_SIZE、GET_FONT_SIZE_LIST、HAS_FONT_SIZE、SET_FONT_SIZE以与现有字体函数类似的方式控制字体大小。特定值-1可用作取消设置/默认设置(与字体的NULL效果相同)。

为了确保内容易于理解,从右到左的书面语言的用户界面应该从右到左排列。UI&34;镜像提供了一种方便的方式来实现这一点,而无需为RTL和LTR语言设计单独的接口。

在大多数情况下,用户界面镜像应该自动发生,不需要用户执行任何操作,也不需要了解RTL编写系统。

每个控件都有一个Layout_Direction属性来控制镜像。它可以设置为继承(使用与父控件相同的方向,与根控件的自动相同)、自动(方向根据当前区域设置确定)或强制设置为RTL或LTR。

在上面的屏幕截图上,绿色和蓝色的指南针控件分别被强制为LTR和RTL布局,红色容器被设置为AUTO,而UI的其余部分使用继承的(默认设置)方向。

映射子控件在容器中的水平顺序,以及树/项列表控件中的项。

使用内部控件元素的镜像顺序(例如,OptionButton下拉按钮、复选框对齐、列表列顺序、树项目图标和连接线对齐等),在某些情况下,镜像控件使用单独的主题样式。

Unicode BiDi算法是为处理自然文本而设计的,它不能处理具有更高级别顺序的文本,如文件名、URI、电子邮件地址、正则表达式或源代码。

STRUCTED_TEXT_BIDI_OVERRIDE属性和_STRUCTED_TEXT_PARSER回调被添加到All Text控件以处理此问题。

例如,上面屏幕截图中目录结构的路径将显示错误(顶行编辑控件)。文件类型结构化文本覆盖将文本分割成多个片段,然后分别对每个片段应用BiDi算法,以正确显示任何语言的目录名,并保留正确的文件夹顺序(底线编辑控件)。

自定义回调提供了覆盖其他类型结构化文本的BiDi的方法。例如,下面的代码使用:作为分隔符拆分文本,对每个部分应用BiDi,并以相反的顺序显示它们。BiDi覆盖可以与任何控件一起使用,包括输入域(LineEdit、TextEdit)。

Func_Structed_text_parser(args,text):var range=[];var Offset=0,for t in text。Split(";:";):var var text_Offset=Offset+t.long(),在文本范围内添加文本。Push_front(Vector2i(Offset,Text_Offset)#Add text for Text range。ush_front(Vector2i(Text_Offset,Text_Offset+1)#。

Language属性(仅适用于带有文本的控件):覆盖该节点的区域设置:控制特定于语言的换行规则、OpenType本地化形式、形状和字体替换。

OpenType_Feature属性(仅适用于带有文本的控件):控制节点的OpenType字体功能,例如要使用的连字类型、数字样式、小型大写等。(完整的标准标签列表,字体也可以有自定义功能)。

用户界面镜像、字体、主题和控件更改:Godot#41100(提交5到8个,PR会定期调整基数以跟上上游的更改,确切的提交散列可能会有所不同)。

下一部分将重点介绍对特定控件和RichTextLabel BBCode的更改。