news 2026/4/18 8:04:35

HarfBuzz概览

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarfBuzz概览

本文主要介绍:

1)什么是HarfBuzz

2)HarfBuzz名称来源

3)为什么需要HarfBuzz

4)HarfBuzz能做什么

5)HarfBuzz不能做什么

6)哪些平台在使用HarfBuzz

可以直接跳转感兴趣部分阅读。

一、什么是HarfBuzz

HarfBuzz 是一个用 C++ 编写的文字塑形引擎(Text Shaping),即将字符序列转换成字形序列(Glyph)。

二、HarfBuzz的名称来源

HarfBuzz的作者是Behdad Esfahbod(贝赫达德·埃斯法赫博德),HarfBuzz的命名最初来自于该作者​对 OpenType 的波斯语翻译​。

三、为什么需要HarfBuzz

我们回答清楚以下几个问题,「为什么需要HarfBuzz」这个问题就理解了。

1)一段字符串从输入到上屏,需要经历哪些过程?

可以用下面这张图概括:详细的流程可以参考从0到1自定义文字排版引擎:原理篇

在这里插入图片描述

图中红色部分就是HarfBuzz所能做的事情。

Text Shaping/文本塑形就是将一串 Unicode 字符码点(Codepoints),根据字体中的规则,转换为一串有序的字形(Glyphs)序列及其位置信息的过程。

2)为什么不能把字符串里的字符直接从字体文件里拿出来画在屏幕上?

在一文读懂Fon文件一文中,我们知道了Font文件中存储着字符的位图信息,那能直接取出每个字符的位图进行绘制吗,答案当然是不可以!

举几个例子:

例子一:

在 Tamil(泰米尔语)语言规则中,当字母“ட”后接元音符号“ு”时,这一对字符必须替换为单个字形“டு”,即字符序列 “ட,ு” 需要用字体中的单个“டு”字形来替代。

例子二:

在配置了连字 feature 的应用中,当遇到 f 和 i 相遇时,在很多英文字体中会合并成一个单独的 fi 字形。

以上这些连字、重排、字形替换等处理,都是在Shaping阶段完成的。

四、HarfBuzz能做什么

1)塑形

沿用上面对塑形的解释:HarfBuzz可以将一串 Unicode 字符码点(Codepoints),根据字体中的规则,转换为一串有序的字形(Glyphs)序列及其位置信息。

可以用下面这张图来概括HarfBuzz的塑形流程:

在这里插入图片描述

图片来自:https://mrandri19.github.io/2019/07/24/modern-text-rendering-linux-overview.html

可以看出

​HarfBuzz的输入是​:字体文件 + 分段好的字符

​HarfBuzz的输出是​:字形信息(Glyph)、position、kerning等

2)字体处理

除了核心的塑形功能,HarfBuzz还提供了访问其他字体功能的函数,比如:GSUB和GPOS表,可变字体,彩色字体,字体子集化等。

五、HarfBuzz不能做什么

1)HarfBuzz 不会处理双向文本问题

如果想排版LTR、RTL(如希伯来语、阿拉伯语)混排的字符串,需要确保在提交给HarfBuzz的输入中,字符串的顺序是一致的。

也就是在将文本输入HarfBuzz之前,需要进行分段。

2)HarfBuzz无法处理包含不同字体属性的文本

比如,对于字符串“a huge breakfast”,其中“huge”希望是斜体,那么我们需要向 HarfBuzz 分开发送三个字符串:

使用罗马字体的a

使用斜体字体的huge

以及再次使用罗马字体的breakfast。

同样,如果在字符串中包含不同的字体、字号、字体样式、语言或方向,那么需要独立地对每个文本段进行塑形。

HarfBuzz在处理字符串时要求字符串具有相同的属性。

3)HarfBuzz不会处理换行、连字符或对齐

HarfBuzz会​将字符串排列在一条理论上长度无限的单行上,​如果想找出文本中可能的单词、句子和换行点,需要使用ICU库的断句函数。

六、哪些平台在使用HarfBuzz

在这里插入图片描述

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 18:43:38

MPK(Mirage Persistent Kernel)源码笔记(2)--- 多层结构化图模型

00 概要Mirage 使用 uGraph 来指定在 GPU 上执行张量程序。uGraph 包含多个级别的层次化图,以表示在内核、块和线程级别的计算。下图是GQA对应的μGraphs,显示了一个用于计算GQA的 uGraph。我们用它作为运行示例来解释 uGraph 的关键组成部分。mugraph_g…

作者头像 李华
网站建设 2026/4/14 6:17:25

0x3f第十天复习(考研日2)(9.18-12.30,14.00-15.00)

二叉搜索树验证 前序2min ac4min ac4min ac1min ac二叉搜索树验证 中序 6min x 基本没问题,记得 每次递归都要return 结果 6min ac 4min ac3min ac二叉搜索树验证 后序 30min x 最后return min(lmin,x), max(rmax,x) 还是有点没理解 15min ac 10min x还是不理解 (r…

作者头像 李华
网站建设 2026/4/9 8:14:01

医疗AI智能体架构设计:六大核心模块与七种专业智能体类型全解析

文章介绍了医疗AI智能体的六大核心模块框架:感知、对话接口、交互系统、工具集成、记忆学习和推理,以及七种专业智能体类型的特点与应用场景。这一模块化架构旨在构建安全、可解释且自适应的医疗AI系统,推动人工智能在医疗领域的深度应用&…

作者头像 李华
网站建设 2026/4/17 6:38:33

js函数声明和函数表达式的理解

在JS中,函数声明会被提升,这意味着函数可以在声明之前被调用。当你使用函数声明的方式定义函数: function resizeFn() {...}整个函数声明会被提升到作用域的顶部。这意味着在整个作用域内,无论函数在何处声明,都可以在声明前调用。函数声明会…

作者头像 李华
网站建设 2026/4/18 3:27:40

奶奶都能看懂的 C++ —— vector 与迭代器

但是在讲解它之前,我们需要先了解迭代的对象是什么。常见的一种,叫做 vector。vector 类型使用可变有序序列我们知道,数学里,vector 是向量的意思。但 C 里的向量和它不太一样。它的含义是,具有可变元素个数的有序对象…

作者头像 李华