如何将转换为在 Windows 95 中的 TrueType 标志符号索引的 Unicode 字符代码

作者: admin 分类: 屏幕取词 发布时间: 2013-04-02 08:37 ė2,803 浏览数 6没有评论
文章转自王牌软件
站长推荐:NSetup一键部署软件
一键式完成美化安装包制作,自动增量升级,数据统计,数字签名。应对各种复杂场景,脚本模块化拆分,常规复杂的脚本代码,图形化设置。无需专业的研发经验,轻松完成项目部署。(www.nsetup.cn)

http://support.microsoft.com/kb/241020

文章编号: 241020 – 查看本文应用于的产品
系统提示注意:本篇文章的内容适用于其他版本的 Windows (不包括您正在使用的版本) 。本篇文章的内容可能不适用您的电脑。浏览 Windows 8 帮助和支持中心

概要

应用程序通常通过在一个单词的字符串中指定的字符代码绘制 Unicode 文本。使用 TrueType 字体时,则操作系统将这些字符代码转换为 TrueType 标志符号索引 (时标志符号,它绘制)。应用程序可能需要转换到标志符号索引的字符代码。这篇文章的示例源代码,讨论如何从 TrueType 字体文件获取标志符号索引。

更多信息

绘制到设备上的字符在 Windows 中涉及到的字符图形 (一个标志符号) 的字体取决于索引映射的字符代码。当使用 TrueType 字体时,这些索引被称为标志符号索引。
TrueType 字体文件有一种灵活的、 面向表的文件格式。这种文件格式的灵活性支持到各自的标志符号的字符代码各种字符编码 (或映射)。一种这种编码方式可以为 Unicode 到标志符号索引。
Microsoft Windows 操作系统中使用 TrueType 字体文件,几乎始终是 Unicode 编码。即使 Windows 95 (和 Windows 3.1 到其前置任务版本) 使用 TrueType 字体作为其内部编码使用 Unicode 标准。Unicode 标准和 TrueType 字体文件,请参阅本指南的详细信息的参考部分。
作为两个单独的条目点导出函数的 Win32 应用程序编程接口 (API)。第一个具有基本的函数名称附加的”A”;第二个具有基本的函数名称的附加的”W”。字符组 (或 ANSI) 的字符串编码这些入口点支持和 Unicode (或宽字符) 编码,分别。平台 SDK 头文件定义的”A”或”W”的变量,这取决于使用的 UNICODE 宏,为基本函数名称,但可以直接引用任何一个 variant 类型的值。
Win32 API 中的 Windows 95 或更高版本中的函数中的大多数支持功能的 ANSI 版本。ANSI API,除了是还支持有限子集的 Unicode 支持的功能,如TextOutWlstrlenW,等等。在 Windows 95 和其后续任务的 Unicode 支持,请参见引用部分的详细信息。
这一组 Unicode 或宽字符函数支持编写有限的 Unicode 支持的应用程序。正如 ANSI 应用程序可能需要使用标志符号索引,Unicode 支持的应用程序可能需要对它们的访问也。当应用程序使用的 TrueType 字体文件,某些高级的功能,如果应用程序所需的标志符号定义,或者如果它需要实现的解决办法或功能不在操作系统中存在 ; 否则为,就会发生这样的情况。
ANSI 应用程序可以使用GetCharacterPlacementA函数来转换的字符代码,标志符号索引的一个字节的字符串。如果应用程序使用 Unicode 字符串编码,并且它在 Windows NT 上运行,则GetCharacterPlacement函数的宽字符版本。在 Windows 95 中,因此,没有从 Unicode 转换为标志符号索引的 API 未实现GetCharacterPlacementW函数。
若要转换到 TrueType 标志符号索引的 Unicode 字符的代码,应用程序必须检索表格中的标志符号索引 Unicode 编码的数据。可以通过调用GetFontData Win32 函数来获取 TrueType 字体文件中的数据。此函数可返回一个未处理的字节的缓冲区,但它可以提取该缓冲区相对于命名 TrueType 表的开始。该函数也作用于当前实现设备上下文 (DC) 中的 TrueType 字体文件。这些功能使该函数查找字体文件和分析其表目录定位到相应的表比更有用。
标志符号索引 Unicode 编码,位于目录中的 TrueType 字体文件标记为”cmap”,是包含字体文件的字符映射表的标记名称。此表可能包含一个或多个选的子表的不同的映射。
紧跟”cmap”表中的初始的无符号短值是每一种编码 TrueType 字体文件包含的目录。TrueType 规范,Unicode 编码都位于标有 PlatformId 值为 3 和 SpecificId 的值为 1 的子表。该规范还定义了引用此 3-1 编码格式 4 子表子表。用来为 3 PlatformId 和 SpecificId 0 (零) 的编码也是格式 4 编码,但字体文件通常解释为符号的字体文件。每个符号的字体的建议 TrueType 规范中,人们预计该编码包含字符代码从 Unicode 专用区。
格式 4 子表是稀疏数组。为了适应所需的 16 位 Unicode 标准的 64k 项,格式 4 子表分成收集相邻的字符序列。段由受该范围的字符的第一个和最后一个字符代码值定义。段的集合由一套并行数组存储在子表中: 一个用于范围 (startCount),另一个 (endCount) 的范围的结束字符的起始字符。段数组是一种分类的字符代码的潜在映射,不实际映射。
标志符号索引到的映射需要从子表,称为 idRangeOffset 的第三个并行数组的使用。这决定了这两种方法还可用于计算最终的标志符号索引。第一种方法使用一个简单的增量值来计算从字符代码中的标志符号索引。第二种方法使用到中间的标志符号 Id 表查找。如果此表中的值为零,则没有标志符号 ;否则,将使用的值到最终的标志符号索引的计算机。查阅表格是一种表示集合跨越一段的不连续的字符代码的有效途径。
余额的这篇文章介绍了如何从 TrueType 字体文件获取 TrueType 标志符号索引。已进行了以下假设: 转换应用程序的域控制器当前所选的 true Type 字体、 当前字符串编码为 Unicode,和 TrueType 字体文件具有 Unicode 字符映射表 (”cmap”格式 4 子表)。
注意: 这种技术用于获取标志符号索引将适用于 Windows NT ;但是, GetCharacterPlacement函数的 Unicode 版本已实现,因为它通常是不必要。如果 Windows 95 中应用程序的字符串不是 Unicode,它可以调用GetCharacterPlacementA函数将转换为标志符号索引相反。
本文结尾处的完整源代码。在文章的文本,进行大量的源代码引用。请参阅示例源代码,以检查在其完整的上下文中相关的参照。

可能性和结束

若要使用 TrueType 字体文件中的数据,许多数据类型问题必须得到充分理解。TrueType 规范,在字体文件中的所有表都定义为基本数据类型的集合。规范还定义的基数据类型,但它们很好地与某些 Windows 平台 SDK 所定义的基础数据类型相对应。
TrueType 字体文件是字节压缩的这意味着所有数据类型都位于在文件中的字节偏移量。特定的填充字节包含在表定义中 (如果适用) 的规格。大多数编译器允许,有时会默认为字节边界以外的其他结构上的对齐方式。这意味着定义”C”语言结构,以模仿表的定义可能不兼容。
如有可能,来表示表,则此示例代码使用的结构定义。要正常工作,必须编译代码并且字节结构对齐如确保通过 pack 杂注的示例代码使用。
保证字节装箱,即使只在一个结构中读取表不正确。TrueType 字体文件使用”大字节序”或摩托罗拉样式字节排序,而英特尔的微处理器使用”小字节序”字节排序。这意味着所有大于从 TrueType 字体文件中获取一个字节必须有个字节的数据交换。交换字节为单位),可使数据兼容与英特尔的微处理器。SWAPWORD 和 SWAPLONG 宏定义提供了一个工具,以便执行此操作。

定义

“Cmap”表中的 TrueType 字体文件包含多个子表 ;其中的每个定义不同的编码。若要找到各个子表,该代码示例还定义了一个方便的名为 CMAPHEADERSIZE。宏是子表目录的开头的偏移量计算方便。该宏将返回用来存储在”cmap”表中的”cmap”表版本和各个子表数的两个无符号短数据类型的大小:

每个编码的子表主”cmap”表中有一个目录条目。这是由结构定义 _CMapEncoding 表示在源代码中。此结构包含两个 ID 字段,用来区分每个子表,并从”cmap”表中的子表所在的位置开始的偏移量:

Win32 API 中的GetFontData函数采用一个 dword 值参数,作为表名。这样做的原因 TrueType 规范定义表名称为 4 字节标记序列。若要正确地打包到GetFontData函数调用的 dword 值参数的表名称,该代码示例定义一个名为 MAKETABLENAME。宏的工作方式通过按顺序将四个表名称标记的单个字节值转移到 dword 值数据类型:

Unicode 编码的子表标记为 3 PlatformId 和 SpecificId 的 1。这”3-1″编码是根据 TrueType 规范格式 4 子表。在源代码中定义是一种结构,_CMap4,它对应于格式 4 子表的前七位的数据类型加上一个符号的一个符号的短整型数组。数组表示子表定义多个无符号短阵列组成的平衡。通过结构定义中包含的数组符号,定义一个方便的地址到无符号的短数组的开始位置。数组符号然后用于使用它们从第一个数组的偏移量计算其他数组的起始地址。当更大的内存缓冲区包含完整的子表,来取消引用一个无符号的短数组强制转换时,这非常有用:

进程

该代码示例实现了这两个基本任务: Unicode”cmap”子字体文件和子表,以查找 Unicode 字符代码 TrueType 标志符号索引的搜索,从表中检索。
若要从给出一个 DC 的 TrueType 字体文件检索表数据,该代码使用GetFontData函数。此函数需要到 DC TrueType 字体文件处于选中状态。若要检索表数据按指定的 TrueType 表进行索引,表 4 字节标记名称必须打包到一个 dword 值。因为我们只是想从”cmap”表中获取数据,代码示例定义了一个全局的 dword 值,dwCmapName,它汇集了”cmap”标记。编码对GetFontData函数的所有调用都使用全局 dwCmapName 变量。
GetTTUnicodeCoverage函数是 Unicode”cmap”子表中检索的源代码。它被声明为:

此函数可检索完整 Unicode 子表 TrueType 的”cmap”表中。如果使用的缓冲区太小,调用 (即,大小为零) 个 pBuffer 参数声明通过 cbSize 或 NULL 参数,它运行失败并返回 FALSE。当以这种方式失败时,它将计算并返回在 pcbNeeded 参数中所需的缓冲区大小。如果此函数成功,填充 pBuffer 参数并放在 pcbNeeded 参数中复制的字节数。
此函数首先搜索子表将包含 Unicode 编码,或者”编码 3-1″或”3-0″编码。TrueType 规范的”cmap”数据类型一章中定义,这些都是格式 4 各个子表。
如果函数会查找 Unicode 编码,它使用GetFontFormat4Header函数来检索格式 4 子表中的前七个元素。然后,该代码计算返回整个 Unicode 子表所需的缓冲区大小。如果缓冲区太小或不提供,大小返回给调用方,这样他们可以分配一个适当大小的缓冲区并重新调用函数。
如果由调用方提供的缓冲区不够大,示例代码然后使用GetFontFormat4Subtable函数来检索整个子表。此函数正确地重新排序以适应英特尔微处理器的字节数。如果子表检索已成功完成,结果将被复制到调用者的缓冲区中。如果未成功完成,该代码将不会修改用户的缓冲区中,并可以安全地返回失败。通过将设置为零的字节为单位) 需要的参数,它未能向缓冲区中复制字节为单位),并可以区分这种失败的缓冲区空间不足,可以指示代码示例。
一旦已获得 Unicode 子表,使用它可以要检索的字符的代码的标志符号索引,或者为了实现大量其他有用的功能。
将 Unicode 字符代码转换到标志符号索引的示例代码的GetTTUnicodeGlyphIndex函数中完成:

此函数具有较简单的界面,要求仅将句柄的 DC,hdc ;其中包含的 true Type 字体和 Unicode 字符代码将转换的频道。成功时,该函数将返回 ch 的标志符号索引。如果 Unicode 字符代码不在中的编码 (即,某个文件夹下没有任何标志符号) 返回缺少的标志符号索引值为零。
它第一次通过分配缓冲区和调用GetTTUnicodeCoverage函数来检索 Unicode 子表。如果发生错误,该示例代码无法通过返回缺失标志符号索引进行调用。在这种情况下,故障可能意味着 DC 不包含 TrueType 字体,或者 TrueType 字体不包含适当的 Unicode 子表。
接下来,该代码将尝试查找 Unicode 字符代码中的编码。每个格式 4 子表引用中的 TrueType 规范的”cmap”数据类型章中执行搜索。FindFormat4Segment函数进行线性搜索子表中的代码段。如果任何代码段不方括号此字符代码,然后该字体文件不包含编码并因此没有任何标志符号。该代码然后返回缺失标志符号的索引。
标志符号索引的查询出现在GetTTUnicodeGlyphIndex函数的最后一个部分。有两种方法来查找特定的标志符号的标志符号索引。这两种情况下使用 idRangeOffset 阵列,通过检查在其中找到的字符代码段的序号索引处的值。
第一种情况下,如果位于段 idRangeOffset 数组的索引处的值为零,该代码取消引用具有相同的数组索引的 idDelta 数组中,并将转换为使用取模运算的标志符号索引:

第二种情况下,段的序号索引处的值是索引的标志符号索引查找表中的一部分。隐蔽索引这一轮,在 idRangeOffset 元素中使用的值的地址根据的顺序和位置的各个子表的数组,返回的中间的 ID 值。TrueType 规范的格式 4 子表一章中,索引的机制进行了说明。如果非零值,此值然后添加到 idDelta 值并转换使用取模运算 ;否则为没有任何标志符号并返回缺失标志符号索引:

其他有用的函数可从 Unicode 子表的解码。例如,此示例代码实现调用的函数:

此函数会添加格式 4 子表,以查找 Unicode 字符代码在 TrueType 字体文件中表示的总数中的每个段所涵盖的字符组成。但是请注意此函数必须测试每个单个字符代码,如果涉及一段使用的标志符号 ID 数组的映射,而不是连续的。
这也是指导您请注意不一定为标志符号的字体文件中包含的数字等效的 Unicode 字符编码映射到一个标志符号的计数。如果 Unicode 编码映射到同一个标志符号的多个字符代码,则可能存在更少的标志符号。也可能是多个字形字体文件中的映射建议比。例如: TrueType 打开 (现在称为 OpenType 版式) 表定义标志符号索引替换到多个备用标志符号。
GetTTUnicodeGlyphIndex函数还可用于实现的函数,以确定给定的 TrueType 字体中是否包含给定的 Unicode 字符代码的标志符号。只需调用GetTTUnicodeGlyphIndex函数中使用的字符代码,并测试缺失标志符号索引 (值为 0) 与等同的返回。

实施简介

此示例代码被编写为清楚起见,解释。它不非常适合重复使用,因为它在分配和检索 TrueType 表每次调用时的公共函数。用于实际应用程序中,是一种很好的优化,缓存的 Unicode 编码 TrueType 字体文件,只要它仍然在 DC 中。应用程序可以进行比较以查看 DC 到选定的字体是否相同的 TrueType 字体文件缓存,并将字体文件的校验和值进行比较。此校验和位于 TrueType 字体文件,该文件的开头的表目录中,并可以通过使用GetFontData函数来检索。请参见”表目录”下数据类型一章来查找字体文件的校验和 TrueType 规范的讨论。

完整的源代码

参考

在 Unicode 标准的详细信息,请参阅:

Unicode 协会。Unicode 标准 2.0 版。阅读,马萨诸塞州,艾迪逊 Wesley 开发人员按,1996年。ISBN 0-201-48345-9。
在 internet 上: Unicode 协会 (http://www.unicode.org)

() http://www.unicode.org

有关其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:

210341

() http://support.microsoft.com/kb/210341/EN-US/

在 Windows 95 和 Windows 98 中的信息: Unicode 支持

对于 TrueType 规范的详细信息,请参阅:

Microsoft TrueType Specifications (http://www.microsoft.com/typography/tt/tt.htm)

      (http://www.microsoft.com/typography/tt/tt.htm)

Microsoft TrueType 规范 (http://www.microsoft.com/typography/tt/tt.htm)



只回答业务咨询点击这里给我发消息 点击这里给我发消息

学习日记,兼职软件设计,软件修改,毕业设计。

本文出自 学习日记,转载时请注明出处及相应链接。

本文永久链接: https://www.softwareace.cn/?p=304

0

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">


Ɣ回顶部

无觅相关文章插件,快速提升流量