前言
最近在做一款激光打标控制的产品,我的思路是将所有的图元矢量化,但是当做到文字矢量化的时候,真是让我想破了脑袋,后来搜索得知了GetGlyphOutline,就是一个WINAPI,众所周知,WINAPI大都需要一个HDC,但是我使用的Qt,这样就出现了几个问题:
- Qt中的控件有些是直接渲染的,很难直接获取控件句柄-
- 不跨平台,以后这一块还是要重写
- VC的各种变量类型写在Qt里面,调试起来真是一团糟
做了些实验以后,发现这种方法实在是缘木求鱼,然后轻易地搜索到了freeType这一款优秀的字体引擎,下面我们就开始对freetype的探索。
所需基本知识点
trueType字体的一些基本概念
字体(font):不同字符图像的集合
字体外观(font face):一个外观对应一个(.ttf)文件,但是一个字体家族可能占用多个字体文件,因为它包括多种外观,比如字体族Arial,它包括两种外观,于是就有 arial.ttf对应Arial Regular外观,ariali.ttf对应Arial Italic外观,我们习惯把Arial Regular也称为一种字体,实际上它只是一种字体外观
字体文件的基本结构:一般里面有一个或多个字符图(charmap),不同的字符图一般标识不同的平台,所以在一种平台上一般只有一种字符图,这个字符图可以宏观简单的理解为一个key-value,key-字符索引一般就是字符对应编码的编码值,value(字符构成)在truetype一般是对其矢量图形的描述,我们只要将字符编码对应的矢量图形描述得到,就可以进行随心所欲的处理了
trueType字体的基本构成
首现说一下字体轮廓,拿我自己解析出来的一个例子来说吧(这是俺的大名:)):
渲染出来的矢量还是不错的!
轮廓线就是字体轮廓中一条条的封闭曲线:
红色箭头标注的就是字体轮廓线,共有两条;每条轮廓线又由其他直线或曲线组成:
- 直线
- 二次Bezier曲线
- freetype官方说明字体曲线可能包含有(三次Bezier曲线),但经过我的实验以及其他官方资料,truetype字体并不含有三次Bezier曲线
besier曲线定义
由于此处只用到一次贝塞尔(有界直线)和二次贝塞尔曲线
给定点P0、P1,线性bezier曲线只是一条两点之间的直线。这条线由下式给出,且其等同于线性插值。
二次方bezier曲线的路径由给定点P0、P1、P2的函数B(t)追踪:
按照上述插值规则,如果t分割的足够密,就可以得到平滑的曲线