Linux.ChinaUnix
ChinaUnix | Linux首页 | 新闻 | 博客 | 文章 | 专栏 | 新手 | 方案 | 图书 | 下载 | 人才 | 手册 | wiki | 搜索
会员: 密码: 免费注册 | 忘记密码 | 会员登录 | 搜索 | 帮助
[保留] [ZT]ttf文件结构解析
首页 ? CU论坛 ? Linux ? 汇总贴列表 ? 嵌入式开发 ? 请选择您要去的论坛 ← >新手园地 >系统管理 >网络问题 >硬件支持 >内核问题 >系统互操作专区 >中文支持 >桌面与办公 >影音娱乐 >网络工具 >编程问题 >内核源码 >CPU与编译器 >嵌入式开发 >驱动开发 >数据库应用 >服务器应用 >安全防护 >集和虚拟机 >开源业界与评论 >贴图娱乐 >红茶馆 >文档专区 >下载共享 >Linux书友会 >Linux人才交流 >Linux站务交流===============→ 操作系统技术交流区 ← >BSD >Solaris >SCO UNIX >HP-UX >AIX >IBM AS400应用论坛 >Tru64 UNIX >IRIX >Mac OS X → 行业解决方案交流区 ← > 金融行业 > 电信行业 > 互联网行业 > 医卫行业 > 制造行业 > 信息安全 > 教育行业 > 媒体娱乐行业 > 电子政务 > 交通行业 → 程序设计交流区 ← >C/C++ >Shell >Java >Php >Perl >Python >Web开发 >软件工程 >中间件技术 >GUI编程 >软件配置管理 >VOIP开发技术 → 网管技术交流区 ← >网络安全 >网络技术 >Cisco技术 >存储备份之家 >服务器及硬件技术 → 数据库技术交流区 ← >MySQL >PostgreSQL >Oracle >Informix >Sybase >DB2 → 应用技术专题交流区 ← >Web服务器 >Mail服务器 >FTP服务器 >DNS服务器 >Proxy
服务器 >LDAP >VPN >Lotus >Samba → IT综合交流区 ← >IT业界新闻与评论 >IT职业生涯 >IT培训与认证 >IT二手大厅 >IT图书与评论 → IT人的休闲生活交流区 ← >清茶斋 >运动地带 >快乐数码摄影 >影音文字 >English Forum >游戏玩家 >旅游天下 >贴图娱乐 >红茶馆 >IT爱车族 → 站务及频道交流区 ← >站务交流 >版主会议室 >Linux站务交流 >Linux版主会议室 >博客站务交流区 >下载频道交流区 >CU活动专区 最近访问的论坛 ...
CU组织网友参观思科公司!请速报名! | AMD四核皓龙处理技术与应用 | 时代冠军主机588元/两年| 赠书计划:《Linux 2.6内核标准教程》
?? 上一主题 | 下一主题 ?? [打印] [订阅] [收藏] [本帖文本页] [推荐此主题给朋友,立即获积分]
本主题由 bitmilong 于 2008-7-23 21:54 加入精华
T-bagwell
风云使者
失恋
UID:652739
注册:2007-12-10
最后登录: 2008-12-02
帖子:691
精华:11
可用积分:1074 (家境小康)
信誉积分:0
专家积分:33 (本版:33)
空间积分:0
推广积分:0
状态:...在线...
[资料] [站内短信] [Blog]
[推广获积分] 1楼 发表于 2008-7-23 17:13
pafone 发表于 - 2008-5-22 15:39:00
[Copy to clipboard] [ - ]CODE:
TrueType字体通常包含在单个TrueType字体
文件中,其文件后缀为.TTF。OpenType字体是以类似 于TrueType字体的格式编码的POSTSCRIPT字体。OPENTYPE字体使用.OTF文件后缀。OPENTYPE还允许把多个OPENTYPE字体组合在一个文件中以利于数据共享。这些字体被称为TrueType字体集(TrueType
collection),其文件后缀为.TTC。
TrueType字体用machintosh的轮廓字体资源的格式编码,有一个唯一的标记名"sfnt"。windows没有macintosh的位图字体资源格式,字体目录
包含了字体格式的版本号和几个表,每个表都有一个tableentry结构项,tableentry结构包含了资源标记、校验和、偏移量和每个表的大小。下面是TrueType字体目录的c语言定义:
typedef sturct
{
char tag[4];
ULONG checkSum;
ULONG offset;
ULONG length;
}TableEntry;
typedef struct
{
Fixed sfntversion; //0x10000 for version 1.0
USHORT numTables;
USHORT searchRange;
USHORT entrySelector;
USHORT rangeShift;
TableEntry entries[1];//variable number of TableEntry
}TableDirectory;
TrueType 字体中的所有数据都使用big-endian编码,最高位字节在最前面(因为TrueType字体最初是由apple公司定义的,而apple公司的os运行在motorola的cpu上)。如果一人TrueType字体以00
01 00 00 ,00 17开头,我们就可以知道它的格式是轮廓字体资源("sfnt")版本1.0的格式,有23个表。
TableDirectory结构的最后一个字段是可变长度的tableentry结构的数组,安体中的每个表对应其中一项。TrueType字体中的每个表都保存了不同的逻辑信息-----如图元中数据、字符到图元的映射、字距调整信息等等。有表是必须的,有些是可选的。下表列出了TrueType字体中常见的表。
head 字体头 字体的全局信息
cmap 字符代码到图元的映射 把字符代码映射为图元索引
glyf 图元数据 图元轮廓定义以及网格调整指令
maxp 最大需求表 字体中所需内存分配情况的汇总数据
mmtx 水平规格 图元水平规格
loca 位置表索引 把元索引转换为图元的位置
name 命名表 版权说明、字体名、字体族名、风格名等等
hmtx 水平布局 字体水平布局星系:上高、下高、行间距、最大前进宽度、最小左支撑、最小右支撑
kerm 字距调整表 字距调整对的数组
post PostScript信息 所有图元的PostScript FontInfo目录项和PostScript名
PCLT PCL 5数据 HP PCL 5Printer Language 的字体信息:字体数、宽度、x高度、风格、记号集等等
OS/2 OS/2和Windows特有的规格 TrueType字体所需的规格集
在TableDirectory结构中,所有的TableEntry结构都必须根据它们的标记名排序。比如,cmap必须出现在head前,而head必须在glyf前。但是实际的表可以出现在TrueType字体文件中的任意位置。
Win32API 提供了一个应用程序可用于查询原始TrueType字体信息的函数:
DWORD GetFontData(HDC hDC,DWORD
dwTable ,DWORD dwOffset, LPVOID lpbBuffer ,DWORD
cbData);
GetFontData函数可以用于查询设备上下文中当前逻辑字体所对应的TrueType字体,因此传递的不是逻辑字体句柄,而是设备上下文句柄。你可以查询整个TrueType文件基是文件中的一个表。要查询整个文件的话dwTable参数应该为0;否则,应该传递要查询的表的四字符标记的DWORD格式。参数dwOffset是要查询的表中的起始偏移,要查询整个表的话应该为0;参数;pvBuffer是缓冲区的地址,cbData是缓冲区的大小。如果最后个参数为NULL和0,GetFontData函数返回字体文件或表的大小;就会把到的数据拷贝到应用程序所提供的缓冲区中。
下面的例和查询整个TrueType字体的原始数据:
TableDirctory * GetTrueTypeFont (HDC hDC ,DWORD &nFontSize)
{
//query font size
nFontSize=GetFontData(hDC,0,0,NULL,0);
TableDirectory * pFont =(TableDirectory *)new BYTE(nFontSize);
if (pFont==NULL)
return NULL;
GetFontData(hDC,0,0,pFont,nFontSize);
return pFont;
}
GetFontData使得应用程序能够在自己的文档中内嵌TrueType字体,以确保这些文档能在没有相应字体的其他机器上显示。它的做法是允许应用程序查询字体数据,然后写入到文档中作为文档的一部分,在文档被打于时再安装该字体以确保文档能以创建时同样的方式显示。比如,Windows
NT/2000的假脱机程序在打印到远端服务器时会在假脱机文件中内嵌入TrueType字体以保证文档能在
另一台机器上正确地打印。
一旦接受到TrueType字体的原始数据,它的头中的TableDirectory结构很容易分析。需要检查的只有版本号和表的数目,然后就可以检查单个的表。我们来看一些重要的和有趣的表。
1.字体头
字体头表(head表)中包含了TrueType字体的全局信息。下面是字体头表的结构。
typedef sturct
{
Fixed Table;//x00010000 ro version 1.0
Fixed fontRevision;//Set by font manufacturer.
ULONG checkSumAdjustment;
ULONG magicNumer; //Set to 0x5f0f3cf5
USHORT flags;
unicode在线工具USHORT unitsPerEm; //Valid range is from 16 to 16384
longDT created; //International date (8-byte field).
longDT modified; //International date (8-byte field).
FWord xMin; //For all glyph bounding boxes.
FWord yMin; //For all glyph bounding boxes.
FWord xMax; //For all glyph bounding boxes.
FWord xMax; //For all glyph bounding boxes.
USHORT macStyle;
USHORT lowestRecPPEM; //Smallest readable size in pixels.
SHORT fontDirctionHint;
SHORT indexToLocFormat; //0 for short offsets ,1 for long.
SHORT glyphDataFormat; //0 for current format.
}Table_head;
字体的历史记录在三个字段中:字全版本号、字体最初创建时间和字体最后修改时间。有8 个字节用于记录时间戳,记录的是从1904年1月1日午夜12:00开始的秒数,因此我们不用担心y2k问题,或是什么y2m问题。
字体设
计时是针对一个参考网格设计的,该网格被称为em-square,字体中的图元用网格中的坐标表示。因此em-squrare的大小决定胃该字体的图元被缩放的方式,同时也反映胃该字体的质量。字体头中保存了每个em-square的格数和能
包含所有图元的边界框。Em-square的有效值是从16到16384,常见的值是2048、4096和8192。比如,Windings字体的em-square的格数是2048,图元的边界框是[0,-432,2783,1841]。
字体头表中的其他信息包括最小可读像素大小、字体方向、在位置表中图元索引的格式和图元数据格式等等。
最大需求表
TrueType字体是一种非常灵活的数据结构,它可以包含可变数目的图元,每个图元可以有不同数目的控制点,甚至还可以有数量可变的图元指令。最大需求表的目的是告知字体栅格器(rasterizer)对内存的需求,以便
在出来字体前分配合适大小的内存。因为性能对字体栅格器非常重要,像MFC的CAarray那样需要频繁进行数据拷贝操作的动态增长的数据结构不合要求。下面是maxp表的结构。
typedef struct
{
Fixed Version;//0x00010000 for version 1.0.
USHORT numGlypha; //Number of glyphs in the font .
USHORT maxPoints; //Max points in noncomposite glyph .
RSHORT maxContours; //Max contours in noncomposite glyph.
USHORT maxCompositePoints;//Max points in a composite glyph.
USHORT maxCompositeContours; //Max contours in a composite glyph.
USHORT maxZones;// 1 if not use the twilight zone [Z0],
//or 2 if so use Z0;2 in most cases.
USHORT max TwilightPoints ;/ Maximum points used in Z0.
USHORT maxStorage; //Number of storage area locations.
USHORT maxFunctionDefs; //Number of FDEFs.
USHORT maxStackElements; //Number of depth.
USHORT maxSizeOfInstructions; //Max byte count for glyph inst.
USHORT maxComponentElements; //Max number top components refernced.
USHORT maxComponentDepth; //Max levels of recursion.
}Table_maxp;
numGlyphs字段保存了字体中图元的总数,这决定了到位置表的图元索引的数量,可以用于严正图元索引的有效性。TrueType字体中的每个图元都可以是合成图元或简单图元。简单图元可以有一条或多大体上轮廓中国,条用一些控制点定义。合成图元用几个其他图元的组合来定义。maxPoints\maxCountors\maxCompositePoints
maxCompositeContours这几个字段说明了图元定义的复杂度。
除了图元的定义,TrueType字体还使用了图元指令用于提示字体扫描器如何对控制点进行调整以得到更均衡更漂亮的光栅化后的图元。图元指令也可以出现在字体程序表(fpgm表)以及控制值程序表(“prep”)的全局字体层中。TrueType图元指令是一个伪计算机字节指令,该机类似于Java的虚拟机,这些指令可以用堆栈计算机执行。MaxStackElements
maxSizeOfInstructions两个字段同志堆栈
计算机这些指令的复杂度。
以Windings字体为例,该字体有226个图元,图元最多有47条轮廓线,简单图元最多有268个点,合成图元最多有141个点,合成图元最多有14条轮廓线,最坏情况下需要492层堆栈,最长的指令有1119个字节。
字符到图元索引的映射表(cmap表)定义了从不同代码页中的字符 代码到图元索引的映射关系,这是在TrueType字体中存取图元信息的关键。cmap表包含几个了表以支持不同的平台和不同的字符编码方案。
下面是cmap表的结构。
typedef struct
{
USHORT Platform; //platform ID
USHORT EncodingID; //encoding ID
ULONG TableOffset ;//offset to encoding table
typedef struct {
WCHAR wcLow;
USHORT cGlyphs;
}
typedef struct
{
DWORD cbThis; //sizeof (GLYPHSET)+sizeof(WCRANGE)+(cRanges-1)
DWORD flAccel;
DWORD cGlyphsSupported;
DWORD cRanges;
WCRANGE ranges[1]; //ranges[cRanges]
}GLYPHSET;
DWORD GetFontUnicodeRanges(HDC hDC,LPGLYPHSET lpgs);
DWORD GetGlyphIndices(HDC hDC,LPCTSTR lpstr,int c ,LPWORD pgi,DWORD fl);
通常一种字体只提供UNICODE字符集中的字符的一个子集。这些字符可以被分组为多个区域,cmap映射表中就是这么做的。GetFontUnicodeRanges函数在一个GLYPHSET结构中返回支持的图元的数量、支持的UNICODE区域的数量以及设备上下文中字体的这些区域的详细信息。GLYPHSET是一个可变长的结构
,其大小取决于所支持的UNICODE区域的数量。因此,和Win32 API中支持可变长结构一样, GetFontUnicodeRanges函数通常需要调用两 次。第一次调用时得到以NULL指针作为最后一莜参数,GDI会返回所需窨的大小。调用者然后分配所需的内存,再次调用以得到真正的数据。这两
种情况下,GetFontUnicodeRanges函数都会返回保存整个结构所需的数据大小。MSDN文档可能还是错误地描述成了如果第二个参数是NULL,GetFontUnicodeRanges函数返回指向GLYPHSET结构的指针。
下面是用于查询上下文中当前字体GLYPHSET结构的一个简单函数。
GLYPHSET *QueryUnicodeRanges(HDC hDC)
{
//query for size
DWORD size=GetFontUnicodeRanges(hDC,NULL);
if (size==0) return NULL;
GLYPHSET *pGlyphSet=(GLYPHSET *)new BYTE(size);
//get real data
pGlyphSet->cbThis=size;
size=GetFontUnicodeRanges(hDC,pGlyphSet);
return pGlyphSet;
}
如果在一些Windows TrueType字体上试着调用GetFontUnicodeRanges函数,你会发现这些字体通常支持1000个以上的图元,这些图元被分成几百个UNICODE区域。比如,“Times
New Roman”有我143个图元,分布在145个区域中,和一个区域是0x20到0x7f,即可打印的7位ASCII代码区域。
GetFontUnicodeRanges函数只使用了TrueType字体“cmap”表的一部分部分信息,即从UNICODE到图元索引的映射域。GetGlyphIndices函数则能真正使用这些映射关系把一个字符串
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论