本文介绍了使用 Cufon 进行网页字体渲染的一般方法和技巧,并以此为基准,介绍了 Cufon 技术的主要实现原理和这一原理的可能应用领域 这是一篇关于 Cufon 技术的小文章。什么是 Cufon 呢?简单的说,Cufon 是一个用来替代 sIFR 框架,实现在网页中对文字字体进行渲染功能的纯 JavaScript 开源类库。 那么为什么要使用 Cufon 呢?这要从 Web 开发人员,所经常面对的一种“冲突”,即“字体(Font Family)冲突”开始讲起。 通常的这一冲突总是爆发于 Web 页面的设计者(Designer)和开发者(Coder)之间。在很多场合下,Web 页面的设计者都会倾向于在他们的页面设计稿中,为文字附加使用一些“特殊”的字体和特效,以此来展示他们卓越的设计能力。 如下图 1 所示,是某设计者为公司 A 所设计的一个公司简介页面(部分)。在其中为了突出公司的“亲和力”,设计者使用了一种名为 Baroque Script 的手写字体。 图 1. 设计者为网站所设计的公司简介效果图(部分) ![]() 无疑的这一设计将会让开发人员“抓狂”。因为与此同时,A 公司雇主明确的告诉了开发人员,公司简介的内容需要可以通过后台管理程序进行修改,并实时的显示到相应的页面上。 这也就意味着,即使开发人员可以如下代码所示通过编写脚本,来实时输出公司简介的内容,并指定这一内容使用“Baroque Script”字体进行显示,也是无法“完美”的实现设计初衷的。 清单 1. 无效的 font-family 字体指定
因为在大部分的浏览器上,并不会安装有 Baroque Script 字体。因此在这些浏览器上系统会主动“忽略”掉代码中关于 font-family 的说明,转而使用缺省字体进行输出,如下图 2 所示。 图 2. 在没有安装 Baroque Script 字体浏览器上的公司简介输出效果 ![]() 当然随着 Web 标准的发展,关于这一问题现在也已经有了一个“官方”的解决方案,那就是通过 CSS3 标准下的 @font-face 属性来指定和引入非缺省字体,如下代码所示。 清单 2. 通过 @font-face 引入外部字体
完整的实现则可以参考范例 1.htm。显然的,这一解决方案会成为今后在此类问题上一个主流的处理方法。但是不幸的是,截止到目前为止其却并没有获得很多浏览器,尤其是 IE 系列浏览器的完整支持。而与之相较本文所将介绍的 Cufon 方案,目前在“普适性”上较 @font-face 方案则是要广泛许多,下表 1 则给出了二者在浏览器支持方面的一个比较,以供读者参考。 表 1. Cufon 和 @font-face 方案普适性比较一览表
那么面对这一冲突,Cufon 究竟是如何解决非缺省字体显示的问题的呢?
引入 Cufon 作为一种基于 JavaScript 的网页字体引入方案, Cufon 的核心功能是通过一个名为“cufon-yui.js”的 JavaScript 类库,提供给开发人员的。因此使用 Cufon 技术的第一步,当然就是在 Web 页面中引入这一类库,如下代码所示。 清单 3. 引入 Cufon 核心库
创建并引入字体文件 这是使用 Cufon 技术的另一个关键所在。显然的对于初次接触 Cufon 技术的读者而言,这并不是一个容易理解的概念,那么什么是 Cufon 字体文件呢? 简言之 Cufon 字体文件,就是按照 Cufon 所提出的字体描述标准,创建形成的一种字体文件。 而和其他字体创建标准如 TrueType、OpenType 等不同的是,按照 Cufon 标准所形成的这一文件本身,就是一个标准的 JavaScript 脚本文件,这也就意味着其也可以通过 <script /> 标记引入到当前页面下,并交由 Cufon 类库进行解析和处理。 这真是一个“伟大”的创意!虽然其也面临着一个天然的障碍,那就是大部分的字体创建者并不会根据 Cufon 标准,来发布他们的字体文件。比如在上例中所使用的 Baroque Script 字体就是一种 TrueType 标准字体。因此显然的,如果我们希望某一字体可以为 Cufon 类库所处理,那么开发人员首先面临的问题,就是如何将使用其他标准描述的字体文件,转换为 Cufon 字体文件。这对大部分的开发人员而言当然是一个非常艰难的工作。 所幸的是 Cufon 已经为开发人员,准备了相应的在线工具 http://cufon./generate/,来实现这一转换过程。而目前工具所可以转换的字体标准则包括了 TrueType、FreeType2、OpenType、PostScript Font 等多种,应该说这几乎囊括了当前主流的一些字体创建标准,Cufon 的普适性由是可见一斑。 工具的使用其实并不复杂,笔者就不赘述了。以 Baroque Script 字体为例,在使用这一工具产生了相应的 Cufon 标准的字体文件“Baroque_Script_400.font.js”后,就可以通过如下代码所示的形式将其引入到 Web 页面中待用了。 清单 4. 引入 Cufon 字体文件
为标记附加 Cufon 转换 在完成了上述的两项准备工作后,事实上使用 Cufon 类库来实现对字体的渲染是非常简单的,这仅仅牵涉到了 Cufon 类库所提供的一个核心方法,即 Cufon.replace 方法,如下代码所示。 清单 5. 使用 Cufon.replace 方法对标记字体进行渲染
其中参数值“p”表示,在本例中 Cufon 将对整个 Web 页面下所有 <p /> 标记对象下的文本,实施字体渲染处理。 当然在更多的应用场合,我们可能还会需要对某一特定标记,进行字体的渲染。在这方面 Cufon.replace 方法也给予了较好的支持。下表 2 给出了方法所支持标记符写作规则及对应意义,以供读者根据实际情况进行选用。从中读者也不难发现,这一规范和 CSS 下选择符的书写语法是非常接近的。 表 2. Cufon.replace 方法选择符参数值语法规范(部分)
至此这一简单的应用便开发完成了。完整的源代码读者可以参考范例 2.htm。将其部署到对应 Web 目录下,并在浏览器中进行查看,笔者相信读者是会得到如图 1 所示的显示效果的。
当然真实的应用,并不会总如范例 2.htm 那么简单,为了更好的适应各种网页字体渲染的要求,Cufon 框架也提供了各种方法来辅助开发者实现其目标。下面笔者就择其一二,向读者进行一个简单的介绍。 通过范例 2.htm 读者可以看到,Cufon 不仅能够针对标记文字进行字体的渲染,而且更为重要的是,这种渲染显然还参考了标记所对应的 CSS 风格 font-size,这对于实际的 Web 应用开发当然是非常重要的,也是 Cufon 技术的一个“特色”所在。 而与此同时,为了可以更为精确的控制在进行字体渲染时所使用的字体风格,Cufon 还提供了“配置项(Option)”这一概念,来帮助开发者直接在 Cufon 方法中指定相应字体风格值,如下表 3 所示。 表 3. Cufon 常用配置项和 CSS 风格名称对照表
而在 Cufon 中设定相关字体渲染配置项值的方法,则主要有以下两个。
这是 Cufon 应用的另一大特色。在同一个页面中,Cufon 可以为不同的标记对象,提供不同的字体渲染效果,这对于实际的 Web 应用而言,当然是非常常见的一个需求。 而 Cufon 对此功能的支持则仍然是通过配置项来完成的。在 Cufon 中开发着可以通过指定配置项“fontFamily”,来确定对应标记对象所需要使用的字体。 比如在范例 4.htm 中,除前例所使用的 Baroque Script 字体外,笔者还引入了另一个由 TrueType 字体 Whiteboard Modern Demo 所形成的 Cufon 字体文件 Modern_Demo_font.js,并分别用这两种字体,渲染了文档中 id 属性值为“id1”和“id2”的两个标记,如下代码所示。 清单 9. 使用不同的字体渲染标记
其产生的效果则可如下图 3 所示。 图 3. 在同一 Web 页面中使用多种字体进行渲染 ![]() 细心的读者可能会从上图 3 中发现有这样一个问题,即在范例 4.htm 中,<h1 id="id2" /> 标记的文本应该是“It is a ID 2”,而并非如图所示的“It is a ID”,为什么会发生这样的情况呢? 要解释清楚这一问题其实并不困难,这牵涉到了 Cufon 在处理字符问题上的一个策略,即 Cufon 会“忽略”掉不存在于其字体文件中的字符。 比如在 Whiteboard Modern Demo 字体中,并没有包含针对字符“2”的书写方法,因此自然的当 Cufon 在使用这一字体显示字符时,如果遇到需要输出“2”的情形,其就会主动的将其“忽略”处理,这也就是为什么运行范例 4.htm,会出现如图 3 所示情形的原因所在。 而除此之外,Cufon 在处理字体问题时,还有另外的几项重要的策略和原则,在此一并列出,以供读者使用时参考。
换言之,即使某一字体是所有系统中都携带的,但只要其没有通过 Cufon 所要求的方式进行引入,那么这种字体就不能在 Cufon 中使用,否则的话,Cufon 会因为引发错误而终止所有相关 JavaScript 脚本的执行。文后的 5.htm 给出了在这方面的一个范例,以供读者参考。
通过上文的介绍和演示,读者对于 Cufon 所展现出来的魔力以及在应用中的相关注意事项,应该是有了一个大致的了解了。那么 Cufon 是如何实现这一魔法的呢? 事实上如果读者所使用的浏览器恰好 Firefox 的话,那么当运行前述 Cufon 范例时,浏览器的表现其实是会“泄露”Cufon 的秘密所在的。如下图 4 所示,在 Firefox 浏览器上,如果读者使用鼠标右键,单击经 Cufon 渲染的文字,就可以发现这些文字,现在“竟然”已经可以按照图片模式进行查看和存储了。 图 4. 在 Firefox 下将 Cufon 渲染文字存储为图片 ![]() 这无疑暗示了,Cufon 技术的实现策略其实就是以一定标准,在网页相关位置上“画”出了所需要显示的文字字符,并同时替换原先区域所需要显示的文字。 而这自然就牵涉到了一个非常重要的问题,即如何“直接”在网页上实现“作画”呢?总体来看目前业界比较成熟的方案,有以下 三种。
Cufon 使用的正是上述第三种解决方案。当然囿于篇幅所限,笔者是无法向读者尽述 Cufon 使用这一方案,实现字体渲染的种种细节的。在此笔者则将通过另外一个实例,即构建统一的 Web 统计图表引擎实例,来帮助读者了解 Cufon 框架背后所隐藏的这一技术要点。在笔者看来,虽然这两个应用在目标上大相径庭,但其所采用的基本策略和方法则是非常类似的。 和 Cufon 的设计者在开发之初,为 Cufon 准备 Cufon 字体文件描述规范类似,我们开发 Web 统计图表引擎的第一步,也为 Web 统计图表准备相应的描述规范。以二维饼图为例,这一规范可能会被表述为如下所示的形式。
而根据这一规范所形成的一个饼图描述范例,则可如下代码所示。 清单 10. 饼图描述实例
至于其他的统计图表,当然也是可以如上所述整理形成相关的描述规范的,这部分工作将作为一个练习,供有兴趣的读者补充完成并实现,在此笔者就不多加赘述了。 在制定了相关图表的绘制规范后,下面要做的则是和 Cufon 一样,向其他开发人员提供统计图表绘制的方法,以帮助他们在实际应用中实现相关图像的绘制。 在此我们不妨将整个绘制接口对象命名为 StatisticalGraph,绘制方法命名为 draw,如下代码所示。 清单 11. 接口对象声明
其中,相关参数的基本含义可如下表 4 所示。 表 4. StatisticalGraph.draw 方法参数说明
在规定了整个应用接口后,我们就将使用 VML、Canvas、SVG 等 Web 页面图形绘画方案,来实现统计图表的绘画了。在此之前则不妨来首先了解一下,这些方案在浏览器应用环境上的差别,如下表 5 所示。 表 5. 浏览器 Web 页面绘图方案支持情况一览表
显然的对于统计图表的绘画应用而言,使用 VML+Canvas 联合的方案是一个具有最大普适性的策略,而这事实上也正是 Cufon 所采用的图形绘画的解决方案。 仍然以饼图绘制为例。由这一策略出发,读者是不难理解如下代码所示的绘制基本业务逻辑的。 清单 12. 饼图绘画接口
那么如何来实现代码中所给出的两个绘制接口 _drawVMLPie 和 _drawCanvasPie 呢?在此,我们则不妨从 _drawCanvasPie 的一些实现细节开始起,来逐步的了解在这一过程中,所普遍适用的一些开发原则和技巧。 了解 Canvas 首先需要简单的介绍一下 Canvas 本身,这实际上是一个由 HTML 5 标准所正式支持的 HTML 标记。因此,对于支持 Canvas 标记的浏览器而言,使用 Canvas 标记和使用其他传统 HTML 标记是没有任何不同的。 而在 HTML 5 中,一个 Canvas 标记所代表的就是一个独立的绘画区间。而一般的我们则将这一绘画区间称之为“画布”。 确立坐标系 显然的对于所有绘图而言,在画布上确立坐标系,都应该是整个绘图工作的第一步,Canvas 自然也不例外。而与传统意义上的二维平面坐标系不同,Canvas 坐标系的纵轴方向是自上而下的,缺省则将使用画布的左上角置为整个坐标系的(0,0)原点。 据此并根据前述说明,读者是不难完成如下代码所示的 Canvas 画布创建代码的,在此 Options 配置项“width”和“height”所代表的,则分别是整个画布的宽度和高度。 清单 13. 创建 Canvas 绘画区域
创建画笔对象 在创建了 Canvas 对象后,我们并不能直接在 Canvas 画布上进心绘画,而是需要通过创建一个一个画笔对象,才能够实现在 Canvas 画布上的绘画。这一画笔对象的创建方法也非常简单,如下代码所示,其中,“2d”表明在此处将使用二维平面模式进行绘画。 清单 14. 创建画笔
绘画并填充扇形区域 那么,我们又该如何使用画笔对象,进行统计图表如饼图的绘画呢?从几何学角度来讲每个饼图其实都是由若干个扇形所组成的,所以饼图绘画的核心,其实也就在于每一个扇形的作画上。而对于 Canvas 而言以下两点则是需要读者特别了解的。
当然,结合一定的数学知识,尤其是三角函数知识,笔者相信这一问题其实并不难解决。为方便起见,笔者在此将通过代码注解的方式,向读者来介绍在这一过程中的一些关键所在,以供读者参考。 清单 15. 绘画并填充扇形
完整的代码实现读者可以参阅范例 7.htm,代码的运行效果,则可如下图 5 所示。 图 5. 使用统计图引擎绘画饼图 ![]() 至此 Canvas 下的饼图显示引擎就已基本开发完成了。当然根据应用的需要,我们还可以继续扩展这一引擎,比如在范例 8.htm 中,笔者就在现有引擎基础上,增加了两个扇形区域数据描述属性 offset_x 和 offset_y 属性,来分别表示该扇形区域的水平和垂直偏移量,而应用这一新引擎所产生的执行效果,则可如下图 6 所示。显然的对于某些需要突出显示某个区域的饼图统计图表而言,这将是很好的一种表达方式。 图 6. Firefox 下增加了偏移量控制的饼图 ![]() 在了解了 Canvas 下绘制统计图的主要方法和技巧后,再去理解同样的功能在 VML 下的实现,显然将要顺畅许多。有鉴于此,我在此就不对其实现细节和流程进行说明了,而仅将就这一开发中的几个关键开发点略作提示,以供读者参考。
在 VML 规范下,任意的一个普通 HTML 标记,都可以视为 VML 下的一个独立的 “画布”而存在,而 VML 语言则相当于是 Canvas 的画笔对象,可以为这一画布提供各种各样的绘画方式。比如,我们可以使用 <line /> 标记来实现从坐标(0,0)到(100,0)的直线段的绘画,如下代码所示。 清单 16. VML 基本应用范例
因此,在 VML 下动态创建图形的过程,其实也就是动态创建 VML 语言标记并将其附加到画布(即某一标记)下的过程,这二者是完全一致的。
这是 VML 应用另外一个与众不同之处。在 VML 的规范中,开发者如果希望使用 VML 技术来进行页面的绘画,则不仅仅需要如一般 XML 语言一样,在 Web 文档中引入这一语言的名称空间(VML 的名称空间为“urn:schemas-microsoft-com:vml”),还需要确保所有 VML 标记,具有值为“url(#default#VML)”的 behavior 风格。否则的话,IE 浏览器是不会对其进行解析和处理的。这也正是读者可以在大部分 VML 应用中,看到有类似如下代码所示的 CSS 风格说明的原因所在。 清单 17. 需要为标记增加 behavior 风格,才能为 IE 解析
其余的开发技巧,应该说就和 Canvas 对象无异了,读者可参阅范例 7.htm 进行了解,在此笔者就不多赘述了。而在饼图引擎的基础上,笔者相信,读者也是一定可以完成其他统计图表的引擎开发工作的。 至此,关于 Cufon 及其基本实现原理便已经向读者介绍完毕了。而显然的由于 Cufon 引擎的实现原理,就是将文字描述转化为图形,那么在相关算法的支持下,我们是一定能够在 Cufon 的基础上,实现关于文字的更为丰富的渲染的。而事实上 Cufon 也已经开始了这方面的工作。比如利用现有的 Cufon 类库,开发者就可以通过为 Cufon.replace 方法,配置一个特殊的 color 配置项值“-linear-gradient( 颜色 1, 颜色 2, … , 颜色 n)”,来实现文字的颜色从颜色 1 到颜色 n 的渐变。笔者相信,随着 Cufon 的不断发展,类似这样的渲染实现是会越来越多的,而笔者也欢迎对此有兴趣的读者,来我一起来进行有关的研究和探讨。
|
|
来自: 命運之輪 > 《UI、UX、UED》