r中的现代文本功能

2021-03-07 10:59:51

我非常高兴地展示了几年的工作,跨越了Systemfonts,Textshing和Ragg套餐的工作。这些发布完成我们的努力来创建一种高质量的性能光栅图形设备,在每个操作系统上都有相同的方式工作。

此博客帖子介绍了RAGG字体渲染的改进,以便现在“只是作品”,无论你抛出什么。这包括:

以上所有内容都是除了ragg能够使用所有已安装的字体的事实之外。

要访问这些功能,您需要安装最新版本的RAGG:

但我邀请您阅读,以了解它是如何运作的,如何控制它,以及它作为用户的方式。

RAGG可以通过打开设备的内置设备直接以与内置设备(如PNG(),JPEG()和TIFF()相同的方式使用,运行一些代码呈现图形的代码,并在完成后再次关闭它dev.off()。 RAGG中的设备以AGG_为前缀,由它们生成的文件格式命名(例如,AGG_PNG())。

您可以通过将设备函数传递给设备参数(例如GGSAVE(Device = Agg_tiff))来使用带有GGSave()的RAGG。

您可以告诉Rstudio在Plots Pane中使用RAGG将后端设置为Global Options>一般>图形。

通过设置dev =&#34编织Rarkmdown文件时可以使用ragg; ragg_png"在代码块选项中。

使用新版本的RAGG,您将能够呈现诸如此类的绘图,并期望它只是为了工作:

图书馆(GGPLOT2)City_names< - c("东京(东京)""横滨(横浜)&#34 ;,"大阪(大厦市)&#34 ;, "名古屋(名字市)&#34 ;,"札幌(札幌市)&#34 ;,"神户(神戸市)&#34 ;,"京都(京都市)&#34 ;,"福冈(福州市)&#34 ;," kawasaki(川崎市)""埼玉(さいたま市)")main_cities")main_cities&lt ; - data.frame(name = city_names,lat = c(35.690,35.444,34.067,35.69,35.012,31.583,35.517,35.861,35.517,35.861),Lon = C(139.692,139.638,135.502,136.9,141.35,135.196 ,135.768,130.4,139.7,139.646))日本< - rnattalth :: ne_countries(scale = 10,country ="日本" returnclass =" sf")ggplot()+ geom_sf (数据=日本,填充=" forestgreen",color =" grey10" size = 0.2)+ ggrepel :: geom_label_repel(aes(lon,lat,label = name),data = main_cities,填充="#ffffff88",box.padding =单位(5," mm"))+ geom_point(aes( lon,lat),main_cities)+ ggtitle("日本最大城市的位置(日本)🇯🇵" )+ theme_void()+主题(panel.background = Element_Rect(" SteelBlue"),Plot.title = Element_Text(Margin = Margin(5,0,5,0))))

注意英语和日语中的毫不费力的文本组合,以及标题中的表情符号。如果这激起了你的兴趣,请继续阅读!

英语,Lingua Franca的编程,往往占据了编程中的文本相关的一切,从编码到渲染。这使得在大多数西方世界中使用的拉丁脚本,在许多文本渲染管道中最好的(或通常只有)支持的脚本。在R世界中,内置图形设备努力显示其他脚本(Linux上的开罗设备除外),这一直如此。它是关于时间(逾期,真的!)r中的图形系统变得更加包含哪些语言。因此,我宣布RAGG最终支持所有脚本。

要开始,我们将查看不同脚本(阿拉伯语,希伯来语和Sindhi)的样本,这会构成挑战,因为它们是从右到左写的:

Arabic_text< - "هذامستوبباللةالعربية"希伯来_Text< - "זהזהכתוברית" sindhi_text< - "هيسنسيةءلکيوويوفي" p< ggplot()+ geom_text(aes(x = 0,y = 3:1,label = c(阿拉伯语_text,hebrew_text,sindhi_text)),family =" Arial")+ expand_limits(y = c(0,4))preview_devices(p," rtl_example")

如果你不熟悉上面的语言,那么很难看出什么是正确的,什么是错误的。但是,您可以查看代码中的文本如何在浏览器中呈现,并将其与设备呈现进行比较。如果这样做,您可以看到希伯来语脚本在所有非RAGG设备(Linux上的开罗除外)中呈现错误的方向。对于阿拉伯语和Sindhi来说,甚至更难看出有什么问题,因为文本看起来根本不同。那是因为阿拉伯语和辛迪既广泛依赖文本替代规则和扎实;写的是一封信的方式批判性地依赖于它旁边的字母。尽管如此,通过与浏览器渲染进行比较,您可以看到Hebrew脚本上失败的同一设备在此处失败。

Linux上的开罗设备很好地处理此任务,正如我们上面所指出的那样。这是如何运作的,但只在一个操作系统上? CAIRO内置于大多数Linux发行版,并且旨在与Pango一起使用Linux用于布局文本的库。 R的开罗图形设备在所有平台上捆绑开罗,但由于在其他操作系统上建造它的挑战,不包括Pango。

如果在同一个句子中将左右和左右文本组合在一起,会发生什么?需要将字符串分成碎片,每个部分包含在一个方向上运行的文本,单独布置,然后将它们组合在一起

bidi_text< - "希伯来语(עִברִית)脚本\ nis左右" p< ggplot()+ geom_text(aes(x = 0,y = 0,label = bidi_text),family =" Arial")preview_devices(p," bidi_example")

鉴于大多数设备与RTL脚本斗争,它并不令人惊讶,它们在混合时也会失败。再次例外是ragg,以及Linux上的开罗。

支持上述一些非拉丁脚本的一部分是支持连接的支持(用单个新字形替换多个字形)。虽然Ligatures是对某些脚本正确渲染的要求,但是通常是字体的可选功能,以便支持不同的文本变体。更一般地,OpenType字体格式描述了很多功能,许多可选,它定义了可以打开或关闭的特定字形替换(一对一和多对一)或位置调整,并将影响看最终渲染的文字。其中一些功能是自动打开特定脚本的(例如,阿拉伯语所需的脱象),而其他特征则留下其他人为用户自行决定(例如表格编号)。作为为非拉丁脚本添加支持的工作的一部分,构建了支持所有OpenType功能的基础架构。当然,这要求使用的字体支持所请求的功能。

一些字体,如流行的Fira代码编程字体,请使用脱离属作为其吸引力的主要部分。这些现在按照RAGG预期工作:

代码< - " x< - y!= z" logo< - " Twitter" p< - ggplot()+ geom_text(aes(x = 0,y = 2,label = code),family =" fira code")+ geom_text(aes(x = 0,y = 1, label =徽标),family ="字体很棒5个品牌")+ expand_limits(y = c(0,3))preview_devices(p," def_features")

但是关于非默认功能呢? R r中图形引擎的功能在这里存在问题。在除了位置和字体之外,用户能够与要绘制的文本一起发送的文本非常少的信息,(粗体和斜体开/关)。因此,拥有支持高级OpenType功能的设备本身几乎没用,因为没有办法在您想要打开或关闭功能的绘图代码中指定。

要解决此限制,系统现在允许您注册字体变体,提供您可以使用的自定义名称来引用启用某些功能的字体:

图书馆(Systemfonts)register_variant(名称="蒙特塞拉特雷",family ="蒙特塞拉特",重量="半old" semibold",特征= font_feature(Ligatures ="自由判配",字母="型号")))

上面的代码基于Montserrat创建了一种新的字体,使用半代体重和打开标准简断和风格字母替换。现在,在您的文本绘图代码中,您所要做的就是指定"蒙特塞拉特·极端"作为字体系列和功能和重量将被使用。这仅适用于RAGG,因为其他设备都不在系统字体上构建,因此不知道如何访问注册字体:

ggplot()+ geom_text(aes(x = 0,y = 1,label ="本文肯定应该有所不同"),家庭="蒙特塞拉特",size = 6)+ geom_text( aes(x = 0,y = 0,标签="本文应该不同"),家庭="蒙特塞拉特雷" size = 6)+ expanc_limits(y = c( - 1,2))

我们可以看到,通过使用此字体注册,我们不仅可以访问正常和粗体以外的权重,还可以访问诸如“Th”的字形替换,以及用“t”,“f”看到的风格变化, “L”和“E”字形。

虽然很多可选的OpenType功能主要是实现呈现文本的特定风格外观的感兴趣的,但有些人对数据可视化具有更多重要性,例如与显示数字相关的数据可视化。它既可以强制均匀数字,以及使用Opotype的Font_feature的分数号的正确显示(使用font_feature(数字= c("表格""部分;零件"))。如只要字体支持它即可。所以当您想将最终波兰语添加到您的可视化时,这绝对是为了调查。

最近(以字体技术术语)开发是彩色字体的可用性,即字形具有指定颜色的字体。这种发展在很大程度上受到现代文本中的表情符号的无处不在的推动,而似乎表明Emojis一直存在,而且近来,世界尚未收敛到单一标准的颜色字体。 MacoS,Windows和Linux上的System Emoji字体都使用不同的字体技术来存储颜色字形,范围存储单个位图,以将每个字形存储为SVG。这是不确定的,使事情复杂化。为了增加伤害,表情符号通常会略大于周围文本,并以非常操作的方式略微降低的基线(这不适用于所有颜色字体;只有Emojis)。

为什么我告诉你这个?好吧,诚实,它主要是让你欣赏到现在只是工作的颜色字体(和扩展,Emojis)的事实:

Emojis< - "👩🏾💻🔥📊" p< ggplot()+ geom_label(aes(x = 0,y = 0,label = emojis),family ="苹果颜色表情符号")preview_devices(p," emoji" )

可以看到,失败范围从无法呈现任何东西,以便在单色中渲染。此外,看起来似乎设备难以弄清出格术的尺寸。一个额外的皱纹是,虽然在MacOS上的开罗能够在单色中渲染,但它无法获得正确的表情符号。这是因为emojis严重依赖韧皮,而“计算机上的黑皮肤”表情符号实际上是“女人”,“暗皮肤”和“计算机”表情符号的联系。

在上面的所有示例中,我们一直非常注意将字体面对设置为包含我们所需要的所有字形的字体。这并不总是实用的,特别是当您想混合Emojis和常规文本时。在混合拉丁语和CJK(中文,日语和韩语)文本时,它也是绝对的要求,因为它在单个字体中包含所有CJK字形是不可行的。但是,我们习惯于在系统级别工作的事情。无论我们选择哪个字体,似乎始终显示在例如术中。浏览器和文本编辑器。这是因为操作系统正在采用字体回退,这是当在所选择的字体中不存在字形时要用的替代字体的动作。如果我们在图形设备中有这一点,那不是很好吗?好吧,现在我们这样做!

exprack_text< - "这是英语,この文は日本语です" p< - ggplot()+ geom_text(aes(x = 0,y = 0,label = suppack_text),size = 2.5)preview_devices(p,"回退和#34;)

底线与RAGG一起,您现在不需要考虑在您选择的任何字体中丢失的字形(除非您要求系统上任何字体涵盖的字符)。

我们今天所表现出的大多数都是自自动作用的,并且可能(根据您在r中的脚本支持的先前挫折)似乎太好了。有没有捕获?并不真地。 SystemFonts,TextShaping和Ragg尽可能智能地塑造,并且只需采取额外的操作,如果需要。进一步的一切都很高速缓存,因此对性能的影响可以忽略不计。

我们没有触及的东西失踪。并非所有脚本都是LTR或RTL。少数尤其是亚洲脚本,是顶到底的。悲伤地尚未支持自上而下的脚本。这不是由于底层塑造技术的任何限制,而是由于R图形引擎的限制,这在API的关键位置假设水平文本。这意味着,直到更新图形引擎,它超出了图形设备的掌握以支持垂直文本。希望这是未来会改善的一个地区。

我希望您将欣赏这里描述的新功能。我要感谢所有帮助验证Twitter上的文本渲染的人。特别感谢Behdad esfahbod(http://behdad.org)在Harfbuzz,Fribidi,以及几乎所有其他潜在的现代字体渲染中的工作。他的帮助和支持是特别仁慈的。