惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
G
Google Developers Blog
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
P
Proofpoint News Feed
V
Visual Studio Blog
爱范儿
爱范儿
The Cloudflare Blog
博客园 - 叶小钗
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
M
MIT News - Artificial intelligence
Microsoft Security Blog
Microsoft Security Blog
博客园 - 聂微东
H
Help Net Security
B
Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 【当耐特】
量子位
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

jdhao's digital space

Conversion between base64 and OpenCV or PIL Image 腾讯云对象存储博客图床开启 CDN 加速(不需要购买额外域名) Search and Replace in Multiple Files in Vim/Neovim Change Table Column Width in LaTeX Image or Table Side by Side in LaTeX LaTeX 并排显示图像或表格 Firenvim: Neovim inside Your Browser Content inside HTML tags missing in Latest Hugo? Creating Markdown Front Matter with Ultisnips Labelme JSON 标注格式转 voc XML 格式 Nifty Nvim Techniques That Make My Life Easier -- Series 6 macOS 下如何为视频制作字幕 Running Command Asynchronously inside Neovim Resolving Merge Conflict after Git Stash Pop Pylint: command not found? A Hands-on Experience with Neovim's Built-in LSP Support How to Convert PDF to Images with Imagemagick 互联网上常用缩略语集锦 File Backup in Neovim Converting PDF Pages to Images with Poppler Nifty Nvim Techniques That Make My Life Easier -- Series 5 Neovim Configuration for System-wide Use How to sort a list of tuple or list in Python -- lambda or itemgetter? Building A Vim Statusline from Scratch 人类第一颗原子弹爆炸始末 Distributed Training in PyTorch with Horovod Learning Expect Programming Essential Knowledge about SSH Nifty LaTeX Techniques -- Series 1 更改 Adsense 邮寄地址,重新寄送 PIN
The Mathematics behind Font Shapes --- Bézier Curves and ...
2018-11-27 · via jdhao's digital space

Steve Jobs once said that “technology alone is not enough”. He thinks that truly great products reside on the intersection of technology and liberal arts. He had also told a story about how he dropped Reed college and attended the calligraphy class, which had a great impact on the font he decided to adopt on Macintosh later1.

In my opinion, computer font is a great demonstration of arts and aesthetics combined seamless with technology. In this post, I try to understand the mathematics behind the beauty of font. Below is the Source Han Serif font designed by Google and Adobe.

You may have noticed already that most fonts in use nowadays can be resized to arbitrary size and still looks good and smooth. This kind of fonts are called outline fonts (or vector fonts), as opposed to the already deprecated bitmap fonts. The fonts we now use are mostly opentype fonts, which is an extension of the truetype font format2.

The word “outline” means that the shape of each glyph in a font is made up of straight and curved lines. Various fonts mainly use two major outline types — truetype outline and postscript outline. Truetype outlines are represented using quadratic Bézier curves, while postscript outlines are represented using cubic Bézier curves. Quadratic Bézier curve is a special case for cubic Bézier curve. As a result, quadratic curves can be converted to cubic curves without any loss of accuracy, while cubic curves can only be approximated by several quadratic curves.

Since opentype font can either use truetype or postscript outlines, we can convert truetype font to opentype format without loss of accuracy, but not the other way around3.

How does Bézier curves represent the font outline?

Bézier curves are parametric curves whose shapes are controlled by a parameter t and some on and off curve points. In this part, we focus on quadratic Bézier curves. The shape of quadratic curves are determined by two on-curve points (or end points) and one off-curve point. The off-curve point is used to control the shape of the curve. Suppose we have three points: \((A_x, A_y)\) (point A), \((B_x, B_y)\) (point B), and \((C_x, C_y)\) (point C). A and C are the end points and B is the control point. The parametric equation for the underlying curve is:

\[\begin{align} P_x &= (1-t)^2A_x + 2t(1-t)B_x + t^2C_x \\ P_y &= (1-t)^2A_y + 2t(1-t)B_y + t^2C_y \\ \end{align}\]

When parameter \(t\) is changed from 0 to 1 in the above equations, we can get all the points \((P_x, P_y)\) in the underling curve. That is, this curve can be uniquely determined once we know the position of point A, B and C.

See the figure above for an example of quadratic B-curve. In this example, A is \((1.0, 1.0)\), B is \((1.5, 2.0)\) and C is \((3.0, 1.5)\). The blue line is the generated curve when we change \(t\) from 0 to 1.

For a glyph in a font, its outline can be split into multiple small curves until it can be represented by B-curves4, which is in turn represented by three points. Ultimately, if we simplify things a bit, we can represent each glyph in a font with a set of points.

In the below image, I show the outline for character e from a font5:

In the above image, the character e is made up of two outlines. The red dots are the end points of B-curves and the cross symbols are the control points. You can see that for complex characters, the outline consists of a dozen small curves.

How are the characters filled?

Knowing only the glyph outline is not enough. How do we actually fill the characters, i.e., how do you decide what is inside the character and what is outside? In fact, there is a rule. Each point is given a unique number starting from zero. When you traverse the outline from lower number to higher number, the “inside” of character is always on your right. So the outer outline of a character is numbered clockwise and the inner outline is numbered counter-clockwise. See the below image for an example:

Furthermore, if one on-curve point is exactly in the center of two control points, it can be omitted without loss of information. So you may see there are several consecutive control points with no on-curve points in between. In the above image, for example, point 7, 8, 9 and 10 are both control points. More discussion regarding this issue can be found here.

Conclusion

In this post, I have roughly covered how font outline works, that is, how the glyph shapes for a font are represented. But how we should display or print the font at various size (usually measured in pt) is another long story. Hopefully, I will try to describe that on another posts soon.

References


  1. You can find a detailed discussion here.↩︎

  2. A good read about history of fonts can be found here↩︎

  3. But cubic curves can be approximated using quadratic curves with arbitary precisions. See here for more discussions.↩︎

  4. You can find more discussion here.↩︎

  5. You can use the well-known open source tool FontForge to check the character outlines of a font.↩︎