摘要 X渲染扩展(X Render Extension)提供了一个新的基于客户方字形(glyph)和字体管理的字形渲染体系结构这个扩展设计在解决了许多相关技术难题的同时也把光栅化字体配置字体以及定制字体使用的责任交给了每一个X客户程序 编写Xft库是为了给X应用程序提供一个能访问FreeType字体光栅化引擎和X渲染扩展的便于使用的接口鑒于FreeType没有提供配置和定制字体的功能Xft也担负了这一任务Xft提供了新的字体命名约定复杂而精密的字体匹配和选择机制并对相关功能进行充分的抽象从而使得一般应用程序既能够从使用X渲染扩展的文本输出获得益处又能在不支持这一扩展的X服务器上正常工作 引言 X渲染扩展[Pac]把访问字体文件和生成字形图像的功能从X服务器移到了X客户一方采用客户方字形管理的X应用程序在以下几个方面有优势可以访问字体文件的所有细节应用程序可以指定特有字体渐增的光栅化处理(incremental rasterization)并且有可能与其他部件共享字体例如打印机此外鑒于底层的渲染机制基于图像而非字形字形的光栅化技术乃至字体文件格式本身都不再依赖于X服务器的能力所以现在新字体技术的集成速度可以跟得上独立应用程序的开发而不必遥遥无期地等待新的X服务器增强技术 当X服务器不再负责管理字体文件的访问和字形生成就需要一个新的函数库在客户方完成相应的任务由于X渲染扩展在设计上支持消锯齿(antialiased)图形这个新的函数库需要支持高质量的消锯齿字形光栅化 FreeType项目[TT]开发了一个完整的字体光栅化引擎不仅支持大多数轮廓字体格式还支持标准的X PCF位图字体X渲染扩展接收字形图像并使之在屏幕上显现为了让应用程序能在屏幕上显现高质量的文本所需要做的就是在FreeType和X渲染扩展之间放置一层薄薄的粘合代码 对于不支持渲染扩展的X服务器这个函数库还需要提供访问核心字体(使用原始X核心协议访问的字体)的能力这就使得应用程序能在转向新函数库时仍然支持老式X服务器 FreeType库没有指定如何定位字体文件而是需要应用程序提供字体文件名这就把配置和定制可用字体集合的负担放在了FreeType库以外因此这个新的粘合层也需要提供一些配置功能以便在桌面环境中应用 X渲染扩展字形管理 X渲染扩展提出了几个简单抽象供应用程序管理字形每个Glyph结构包括一个覆盖字形外形的alpha掩码(一个描述不透明值的矩形映象)从alpha掩码原点到名义字符原点的偏移量到下一字形的位移(包括垂直和水平的偏移量)GlyphSet结构则包含了一个字形结构的集合应用程序使用一个位的索引对字形集进行编号 应用程序绘制文本时把一个GlyphSet标识符以及一系列针对该GlyphSet的索引发送到X服务器X服务器通过对指定位置使用字形结构中的偏移量调整确定绘制位置并渲染alpha掩码来完成对每个字形的处理后续字形的绘制位置则是通过在当前原点加上位移向量实现正如X核心协议中的PolyText请求在同一个请求中可以对字形序列作出调整位置改变GlyphSet等变动从而使得一个复杂的字符串在一次操作中完成渲染 为了覆盖世界上更多的民族操作系统支持的语言和区域集合不断扩展伴随这种扩展大多数字体中包含的字形数也大大增加当今流行的轮廓字体中会包含几千个字形十多年前渐增式渲染字形被看作一种合理的优化现在已成为各种字体机制中的基本组成部分以尽可能减少每种字体占用的内存并缩短访问一种新字体时所需的时间X渲染扩展通过允许在需要时把一个Glyph加入已存在的GlyphSet提供了这种渐增式渲染支持由于在添加Glyph的过程中没有任何从X服务器到X客户的信息流这一过程可以完全异步进行这种异步性保证了即使面对一个高网络延迟的环境仍有可接受的性能表现 当应用程序传送它们需要显示的字形图像时X服务器通过在任何可能情况下共享相同字形来节省内存 FreeType库 FreeType项目的初衷是要构建一个自由的TrueType字体光栅化器FreeType的第一版提供了与现有系统相当的高质量TrueType光栅化器FreeType的第二版对内部结构进行了一般化以支持更多字体格式除了支持TypeOpenType和CID等众多轮廓字体格式FreeType现在还支持X的标准PCF格式(可移植编译格式)的位图字体 FreeType不仅提供光栅化以及度量字形的接口还提供存取字体文件内各种形式的字距调整和字形替换等表格的机制这就在基础字体含有相应表格的前提下使应用程序能够获得在各种区域中定位字形所必需的数据 既然FreeType项目明确地要构建一个通用的字体函数库在XFree开发一个新函数库的负担就可以大大减轻因为可以直接采用现有系统并提供粘合代码改变FreeType数据结构使之使用X渲染扩展的要求这固然使得应用程序需要面对FreeType函数库可能的变化但考虑到FreeType是一个成熟的项目相对于完全由XFree开发一个新函数库的情形这种变化的严重性大概会轻很多 字体命名和配置不属于FreeType函数库这些杂务交给了应用程序考虑到FreeType应用于各种环境有些甚至没有文件系统为保证FreeType得到最大程度应用并独立于系统策略这种设计思想是适当的提供这些支持成为Xft实现中最困难的部分并且其中一部分可能很快就被替换 XLFD命名 X核心协议规定了用非结构化字符串命名字体的方法X逻辑字体描述(XLFD)[SG]用于在字符串名格式中加入结构信息在开发X时用于桌面计算的轮廓字体还是一个相对新奇的事务所以X核心协议和XLFD都是基于位图字体设计的当围绕缩放字体命名的语法和语义加入XLFD时基于XLFD的开发已经进行了相当长的时期 XLFD中字体命名语法的意图在于仅通过名字就可以向应用程序提供足够的字体信息这样就可以在不访问字体数据情况下进行字体选择和字体列表表示 XLFD还提供了使用包含?和*的名字打开字体的标准策略使用这类名字时选中的字体将是第一个匹配的字体即使用相同模式请求列出字体时返回的第一个不幸的是X服务器保存字体名时为了高效搜索会在各字体目录中进行内部排序所以不能保证*的默认值是合理的例如当在字体名的weight字段使用*时X服务器会把bold字体列在normal字体之前 这个策略真正失败之处在从point(点值)尺寸到pixel(像素)尺寸的映射XLFD在字体名中分别提供了两个轴向上的pixel尺寸point尺寸和resolution(解析度)标准的X字体按照解析度分别存放dpi和dpi下各自存放着与该解析度匹配的各种点值尺寸的字体其他字体目录下一般是为了在dpi屏幕光栅化 协议指导X服务器按照在字体路径(译注font path应指配置文件中相应节)中出现的顺序去搜索字体目录这就使字体路径决定了对解析度的倾向性如果dpi的目录列在前面当应用程序在字体名的resolution字段用*时只要在dpi目录下存在匹配字体就会使用该字体否则才去尝试dpi的字体 应用程序如果在字体名中仅指定point尺寸而在resolution字段使用*那么最终将会得到一组随即尺寸的字体那些在dpi目录下发现的字体按照dpi屏幕光栅化其他字体则按照dpi屏幕光栅化从而会显得小一些 最终的结果是XLFD的字体匹配充满了危险应用程序经常列出所有可用字体(作出选择)然后提交完整XLFD字体名(译注不含?和*)给X服务器 XLFD的另一个问题是在字体名中包含了字形的平均宽度字段对于需要在不同总体宽度的字体中进行选择的应用程序而言这是个非常有用的信息而且对位图字体也很容易计算但是对轮廓字体除非在指定尺寸下对每个字形进行光栅化计算该字段值不能算出仅仅列出一个特定尺寸下所有的可用字体就会导致光栅化每一个字体的每一个字形 XLFD提供了关于可用字体的有用信息出列平均宽度这些信息都是容易计算并交付应用程序的使用XLFD的应用程序应该在本地管理XLFD字体名而不要依赖服务器方字体匹配也就是通过列出可用字体收集信息再利用这些信息构造完整字体名 鑒于XLFD没有提供一种按照语义匹配的合理方案需要有新方案允许在应用程序给定一组约束情况下基础的字体系统能够定位一个适当的字体这样的系统需要有足够的灵活性以便能够包含现在不能预料的新字体特性也不需要应用程序完全指定字体的方方面面 设计一个新函数库 Xft在三个方面与环境交互通过编程接口与应用程序交互通过配置文件与系统交互通过让用户指定字体名与用户交互虽然这三方面在函数库中紧密相关但从设计角度来说它们是分离的 应用程序接口设计 Xft的首要目标是把FreeType的输出和X渲染扩展结合起来但是为了Xft能作为现有的Xlib文本输出例程的替代物而被人接受其次要目标包括支持核心X字体尽管这样做可能以损失应用程序功能为代价 由于FreeType不提供字体选择功能所以Xft的一部分要进行字体匹配采用现有的XLFD机制会极大地限制字体匹配地能力所以Xft提出了一种新格式这种选择机制被设计为总能匹配某种字体允许应用程序假设适当地字体存在避免在每个级别上都要考虑失败回落 另一个要求是函数库要提供 |