Android 4.2.2字体渲染流程

由「大屏幕Android设备字体模糊」引发一研究,陆续接触了skia,huwui,freetype,harfbuzz等等名词。有些能够通过运行一些例子直观地了解了其原理。

到目前为至,如何开始似乎已经不再那么的重要了,因为最开始的需求描述往往是最可笑的,但是同时也是最直观的。

关于最后要达到的程度,如今我已经学会制定自己的计划了,就如邓公在越 战中规划一样不含糊。绕了这么大的弯,对于字体渲染的研究最后的目标是能使用skia或者hwuiopentype字体显示到LCD上,看得到呈现的效果。必要情况下代码中找到关于hintingantialiasing的内容,这是总体规划。

  • 关于Opentype 一个ttf或者otf字体文件中到底存放的是什么信息,使用最通俗的语言描述出来。
  • 关于harfbuzz输入输出信息到底包含哪些信息,能够图形展示出来。
  • 关于skiahwui,能够将其直接输出到framebuffer中。
  • 关于freetype,通俗的语言描述出,最好能够图示出来。

 

通过读Android’s Font Renderer-Efficient text rendering with OpenGL ES当调用Canvas.drawText()的时候顺序是这样的:1.先将用户的数据转递为TextLayoutCanche 它会返回一串数字、符号标识,还有x/y 坐标集合。2.TextLayoutCanche返回信息传输为libhwui以绘制文本。这是整体流程。其中

  • TextLayoutCache 是基于freetype/harfbuzz or icu.TextLayoutCache的字体渲染排版工具,输入是一个字体和一个JavaUTF-16的字符串,输出是一个带有x/y坐标的字形列表。
  • Libhwui是基于OpenGL的硬绘图库,将TextLayoutCache返回的信息绘制出来。

这个文章写成了回忆录了,想到哪里写到哪里吧。

回想这个问题之初,怀疑的是LCD驱动哪里没有配置好,为了证明不是LCD驱动问题,将Recovery的显示文字的效果呈现给他们看,Recovery显示的文字没有丝毫的模糊,才排除了LCD的问题。现在看来因为Recovery中显示文字使用的是点阵字体,优点是清晰。

 

在研究的不得志的情况下,意外看到了一种Android终端的字体显示优化方法及系统这个TCL为申请的专利,让我感受到了我并不是在一个无人区中也不是在吹毛求疵,因为这种情况确实是存在。其实之前很早就想到去电子商场看看「Android一体机」的字体显示效果如何?因为一体机的屏幕也是比较大的,也会是一个参考。这给了我鼓舞。

 

其实在执行了Android中添加思源字体/NotoSansCJK/SourceHanSans后,字体效果已经明显好转了,但是由于说不出一个原由,似乎就是运气且显得不够专业,就趁机深入进来直到能说出个123来。对于这一简单改变却有了明显的效果这里AdobeFreeType提供字体光栅处理技术的说明更有说服力一些

,文中提到:

Adobe CFF引擎具有丰富的功能,比如纵向增加一个额外像素,帮助众多字形分离字干。增加字干的宽度以提高对比度但又不糊成一团。当没有足够的像素时,智能地舍弃对特定字干的hint。这些都将有助于提高CFF字体的可读性。

 

在过去十年里CFF字体在桌面系统广受欢迎,但在网页和移动设备上主要使用的是TrueType字体。这也反映了在传统低分辨率、黑白显示背景下,具有更多hint信息的TrueType字体可以展现更好的效果。

Source Han Sans正是OpenType/CFF类型的字体,这是其wiki上的介绍。但是这只是成功的一半,Adobe CFF-Engine已经添加到Freetype 2.5版本中了。

2013-06-19

FreeType 2.5 has been released. A major new feature is support for color embedded bitmaps (eg. color emoji), contributed by Behdad Esfahbod on behalf of Google.

 Additionally, Adobe's CFF engine is now the default, which makes a good reason to change from the 2.4.x to the 2.5.x series.

From: http://www.freetype.org/

如果高于这个版本的Freetype已经存在于Android源码中了,那说明这个特性就发挥出来了,但是我只能查到android-4.4.2_r1中升级到这个版本了。

 

以前不理解Google难道不知道这种情况吗?为什么不加以处理,无视低PPILCD使用者?从它和Adobe合作了推出CFF类型的Souce Han字体以及CFF引擎的加入都是在解决这个问题。


一直不死心于Adobe的CFF Engine,如果应用上会有多牛呀,我还在支持看就是想要知道如果把它应用上了应该有多牛,会不会让字体变得和Win7上的雅黑一样锐利,毕竟「锐利」是我目前唯一的目标。尽管在知乎上的大牛们都说Mac的那种模糊化的好,Windows上的这种只为LCD专做的字体不好。但我也坚持以清晰为唯一目的。说了这么多,在不断熟悉了Freetype后,这个CFF在其中的演变大概是这样的,在Android4.2.2使用的2.4.2版本中并没有出现,不过在随后的版本中出现了Adobe CFF Engine在2.5.2版本中成熟了,花费一天时间将其移植到了Android4.2.2中,等待着奇迹出现,其实也没有改太多东西仅仅是把Android.mk中添加了一些源文件。重新编译Rom,烧写机器,上个厕所再回来看结果。


结果是完全想是把原来的思源字体显示的还算细的效果给弄没了,只是比原来DroidSansFallback.ttf中的好一些,变得颜色更深了一些了。情况就是这样,有点小小的失望。


再然后,见到棺材了所以也落泪了,心也甘情愿了。选择了Freetype 自身CFF Engine + NotoSansHans.otf来实现锐利的Win7的ClearType效果。这个事,算了是一个了结吧。从熟悉Freetype到了解了字体的各个特性,花了大概一个月的时间,也算是了解了字体从抽象到最后到屏幕上经历了哪些阶段。收集了不少的Demo,git。


  • 字库ttf/otf:字库文件,其中存放了字形的轮廓信息,还会有更高级的Hintting和抗锯齿信息。
  • Freetype:将字体光栅化。将uicode代表的字形码从ttf或者otf字库中取出字的轮廓,输出的是一个位图。其中Hinting和抗锯齿都是都美化输出的结果信息,使其更好看一些。
  • harfbuzz:将字体排列,最明显的从右到左的排列就是harfbuzz实现的。
  • skia:软件实现的绘图库。已经将其直接绘制到了Framebuffer上。
  • hwui:是代替skia实现基于gpu的绘图和描字的库。

以前总结的小知识:

Font hinting(微调):https://en.wikipedia.org/wiki/Font_hinting
1.No hinting.
2.Basic
3.Moterate
4.Maximum

Antialiasing(反锯齿_也指渲染策略):https://en.wikipedia.org/wiki/Spatial_anti-aliasing
1.No antialiasing        无边缘平滑
2.Grayscale antialiasing 灰度边缘平滑
3.Subpixel antialiasing  次像素平滑


你可能感兴趣的:(android,freetype,Skia,harfbuzz)