化繁为简、性能提升 -- 在WPF程序使用Freetype库心得

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

本人使用WPF开发了一款OFD阅读器显示字体是阅读器中最重要的功能。处理字体显示有多种方案几易其稿最终选用Freetype方案。本文对WPF中如何使用Freetype做简单描述。

OFD中有两种字体嵌入字体和非嵌入字体。1 非嵌入字体就是只提供字体名称不提供字体对应的文件。2嵌入字体提供字体文件字体名称是啥并不影响显示。由于阅读器中需要显示大量文本必须采用最优的方式显示否则性能难以满足要求。

WPF字体显示有多种方案。 通常可以将文本呈现分为三层

  1. 直接使用 Glyphs 和 GlyphRun 对象。
  2. 使用 FormattedText 对象。
  3. 使用高级控件如 TextBlock 和 FlowDocument 对象。

第三种方案显然不合适可行的只有第一和第二种方案。对于嵌入字体必须采用第一种方案非嵌入字体可以采用第一和第二种方案。总之可以采用第三种方案解决一切字体问题。

但是本人在使用GlyphRun 过程中遇到很多奇怪的问题有两方面原因导致的

      1越底层的功能使用的人越少缺少相应资料。

        2微软在开放底层功能上犹抱琵琶半遮面导致使用过程中不知所以然遇到问题难以解决。

本人开发的OFD阅读器最初采用了WPF自带字体方案遇到很多坑还有一些坑无论如何也解决不了。痛定思痛决定采用Freetype库显示字体经过一番折腾终于成功了。

历经曲折获得一番感悟微软为了使开发者开发更方便屏蔽了太多底层的东西这导致开发人员遇到问题时无所适从。不要紧盯着微软不放另辟蹊径反而柳暗花明又一村。

使用Freetype显示字体前需要弄明白字体的本质字体的本质就是一系列曲线和对应的unicode编码显示字体就是画曲线和画一条直线、圆等没有区别。 unicode编码是为了交互用的从阅读器上复制一行字其实就是复制字体的unicode编码。字体除了这些属性以外还有很多概念字体高度、行间距、baseline、原点等。

使用Freetype就需要获取每个字体对应的曲线和字体相关的一些列属性。但是Freetype是用c语言开发的导出的函数接口难以与c#交互需要在Freetype的基础上再次封装以方便c#调用。以获取字体对应的曲线为例阐述如何进一步封装Freetype。

我们见到的曲线多种多样但是从底层来看所有的曲线可分为两类直线和贝塞尔曲线。这些恰好对应OFD的图形对象PathObject看下图

OFD文件中一段图形对象

阅读器处理PathObject时就需要解析这些字符串生成对应的曲线。Freetype也需要从字库中解析出曲线其对应的函数是非常复杂的摘录一段函数

很显然c#无法直接使用考虑PathObject的描述方式本人眼前一亮何不将字体曲线描述为PathObject方式对外输出字符串。函数接口定义如下

extern "C" FREETYPELIB_EXPORT INT32 Freetype_GetTextPath(UINT64 handle,
    UINT32 nGlyphIndex, INT32 fontSize, char* textPath, INT32 textPathLen);

textPath包含曲线信息其格式与OFD中的PathObject规范一致我们就可以用处理PathObject的方式处理字体。
WPF显示曲线使用PathGeometry需要将textPath转换为PathGeometry。再而我们就可以使用WPF类DrawingContext画出曲线

class DrawingContext
{
public abstract void DrawGeometry(Brush brush, Pen pen, Geometry geometry);
 ......
}

至此字体就可以显示出来了。通过这一番操作我们也对字体的本质有更加深刻的了解。前文只是简单对显示字体做了讲述要正确处理字体还有大量的工作要做。

Freetype性能如何

功能正常了下一步关心的问题就是性能。为了提高性能从FreeType获取字体的PathGeometry时做缓冲同一个字体下次显示时直接使用上次的字体生成的PathGeometry不再从Freetype获取字体。
本人做了简单的对比测试Freetype性能要高于使用FormattedText方案性能大概提升三倍与GlyphRun方案没做对比。

总结 使用FreeType库可以使我们更好的理解底层处理逻辑更好的理解字体的本质。抓住了本质就能直面问题解决问题就顺畅很多。不同的库、不同函数都有它的应用场景当微软提供的库不再适合当前应用时大胆的使用新库反而可能使我们快速走出困局

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6