OpenType字库文件

来源:互联网 发布:js生成不重复随机数 编辑:程序博客网 时间:2024/05/17 08:03

OpenType字库文件

一个OpenType字库文件以表的格式包含有数据,这些数据包含一个TrueType或一个PostScript outline 字库。光栅化程序使用字库里包含的表中的数据来渲染TrueType或者PostScript glyph outline。这些支持数据中的一些无论在那种outline格式中都会用到;而一些支持数据则是特定于TrueType或者PostScript的。

文件名

依赖于字库中outline的种类,和创建者兼容那些本地没有提供OpenType支持的系统的欲望,OpenType字库的扩展名可能是.OTF或者.TTF。

  • 在所有的情况下,只包含CFF数据(没有TrueType outlines)的字库其扩展名总是.OTF。
  • 依赖于向后兼容更老的系统或者字库的前一个版本的欲望,包含有TrueType outlines的字库其扩展名可能是.OTF或者是.TTF。无论字库中是否包含有OpenType layout的表,TrueType Collection字库的扩展名应该为.TTC。

数据类型

OpenType字库文件中使用了下列的数据类型。所有的OpenType字库使用 Motorola-style字节序(大尾端):

Data TypeDescriptionBYTE8-bit 无符号整型.CHAR8-bit 有符号整型.USHORT16-bit 无符号整型.SHORT16-bit 有符号整型.UINT2424-bit 无符号整型.ULONG32-bit 无符号整型.LONG32-bit 有符号整型.Fixed32-bit 有符号定点数 (16.16)FUNITem空间最小可测量距离.FWORD以FUnits描述数量的16-bit 有符号整型(SHORT).UFWORD以FUnits描述数量的16-bit 无符号整型(SHORT).F2DOT1416-bit有符号定点数,其中低14 bits为小数部分(2.14).LONGDATETIME以1904年1月1日凌晨12:00开始计时的秒数形式的日期。这个值用一个有符号64-bit整数表示。Date Tag用于标识一个 script, language system, feature, 或 baseline的四unit8值的数组(length = 32 bits)。GlyphID

Glyph索引值,与uint16(length = 16 bits)相同

Offset相对于一个表的偏移,与uint16(length = 16 bits)相同,NULL offset = 0x0000

F2DOT14  格式由一个有符号的2的补码形式的定点部分和一个无符号的小数部分组成。为了计算实际值,可以取定点部分加上小数部分。2.14值的一些例子

Decimal ValueHex ValueMantissaFraction1.9999390x7fff116383/163841.750x7000112288/163840.0000610x000101/163840.00x000000/16384-0.0000610xffff-116383/16384-2.00x8000-20/16384

版本号

大多数表具有版本号,而且整个字库的版本号包含在表目录(Table Directory)中。注意,有两种不同的表版本号类型,它们中的每一个都有其自己的编号模式。USHORT版本号总是以零(0)开始。Fixed 版本号以一(1.0或0x00010000)开始,除非另行说明(EBDT,EBLC和EBSC表)。

实现的读取表的部分必须包含检查版本号的代码,以便于在格式发生了改变,继而版本号也改变了,而这个改变又不兼容的时候,老的实现可以优雅地拒绝新的版本。

当一个Fixed数被用于一个版本号,则高16 bits包含一个主版本号,而低16 bits包含一个次版本号。 Tables with non-zero minor version numbers always specify the literal value of the version number since the normal representation of Fixed numbers is not necessarily followed. 比如,'maxp'表的版本0.5的版本号为0x00005000,'vhea' 表的版本1.1的版本号为0x00011000。如果一个实现理解了一个主版本号,则它可以安全的处理读表的操作。次版本号表示的是对于格式的扩展,这些扩展对于那些不支持它们的实现是无法察觉的。

这个规则仅有的例外是偏移表(Offset Table)的sfnt版本。如下面的部分,'一个OpenType字库的组织',所描述的那样,它仅仅用来表示OpenType字库包含的是TrueType outline(一个1.0的值)还是CFF数据(tag 'OTTO')。

当一个USHORT 数被用来表示版本时,它应该被当作一个次版本号;比如,所有的格式变化都是可兼容的扩展。

一个OpenType字库的组织

OpenType格式的一个重要特征是TrueType sfnt “wrapper”,它提供了以一种通用的和可扩展的方式组织一组表的方法。

OpenType字库含有偏移表(Offset Table)。如果字库文件只包含一个字库,则偏移表(Offset Table)将以文件的0字节为起始位置。如果字库文件是一个TrueType集合,则每一个字库的偏移表(Offset Table)的起始点将在TTCHeader中说明。

TypeNameDescriptionFixedsfnt version0x00010000 for version 1.0.USHORTnumTables表的个数USHORTsearchRange(Maximum power of 2 <= numTables) x 16.USHORTentrySelectorLog2(maximum power of 2 <= numTables).USHORTrangeShiftNumTables x 16-searchRange.

Offset Table

包含TrueType outlines的OpenType字库应该使用1.0作为sfnt版本。包含CFF数据的OpenType字库应该使用tag 'OTTO'作为sfnt 版本号。

注意:Apple的TrueType字库specification允许使用'true'和'typ1'作为sfnt版本。这些版本tag不应该被用在那些包含OpenType表的字库中。

偏移表(Offset Table)后面紧跟着的便是表记录(TableRecord)项。表记录(Table Record)中的项必须以tag的升序排序。表记录(Table Record)中的偏移值以字库文件的开始处来计算。

TypeNameDescriptionULONGtag4 -byte identifier.ULONGcheckSumCheckSum for this table.ULONGoffsetOffset from beginning of TrueType font file.ULONGlengthLength of this table.

Table Record 

表记录(Table Record)使得一个特定的字库文件只包含他实际需要的那些表成为了可能。因而并没有一个标准的numTables值。Tags是给OpenType字库文件中的表分配的名字。所有的tag名称由四个字符组成。如果后面跟有所需数量的空格的话,名称包含少于4个的字符也可以的。一个字库中定义的所有的tag名称(比如,表名称,feature tags,language tags)必须由ASCII 值在32-126之间的可打印字符构建。

计算校验和

表的校验和是一个给定的表的longs的无符号和。在C中,下面的函数可用于计算一个校验和:

1ULONG
2CalcTableChecksum(ULONG *Table, ULONG Length)
3{
4ULONG Sum = 0L;
5ULONG *Endptr = Table+((Length+3) & ~3) / sizeof(ULONG);
6while (Table < EndPtr)
7    Sum += *Table++;
8return Sum;
9}

注意:这个函数暗含着一个表的长度必须是一个四字节的倍数。实际上,如果没有正确填充的话,一个字库不被认为是被正确的结构化了的。所有的表必须以四字节边界开始,而两个表之间剩余的任何空间则以0填充。表记录(table record)中所有的表的长度应该以它们的实际长度来记录(而不是它们填充后的长度)。

为了计算其本身包含有整个字库的checkSumAdjustment 项的‘head’表的校验和,可以像下面这样来做:

  1. 设置checkSumAdjustment 为0。
  2. 计算包含‘head’表在内的所有表的校验和,并将其值输入到表目录(table directory)中。
  3. 计算整个字库的校验和。
  4. 用16进制值B1B0AFBA减去那个值。
  5. 将结果存进checkSumAdjustment。

包含有整个字库的checkSumAdjustment 项的‘head’表的校验和在此时是不准确的。那不是问题。不要去改变它。一个应用程序要尝试去验证‘head’表没有被改动过的话,它应该计算不包含checkSumAdjustment 值时那个表的校验和,然后将结果和表目录中的项做比较。

TrueType集合

一个TrueType集合(TTC)是一种用一个文件结构来发布多个OpenType字库的手段。当要一起发布的字库共享许多共有的glyphs的时候,TrueType集合最有用。通过允许多个字库共享glyph集合,TTCs可以有效的节省文件空间。

比如,一组日语的字库可以每一个都有他们自己的kana glyphs的设计,却共享kanji glyphs的相同的设计。通过普通的OpenType字库文件,包含通用的kanji glyphs的仅有的方法就是将它们的glyph数据拷贝进每一个字库。由于kanji代表比kana更多的数据,这将导致大量glyph数据不经济的复制。TTCs被定义出来以解决这个问题。

CFF光栅化程序目前还不支持TTC文件。

TTC文件结构

一个TrueType集合文件包含一个TTCHeader表,在表目录(Table Directories)中包含一个或多个偏移表(Offset Tables),和一定数量的OpenType表。TTCHeader必须要位于TTC文件的开始位置。

TTC文件必须为每一个字库包含一个完整的偏移表(Offset Tables)和表目录(Table Directory)。一个TTC文件表目录(Table Directory)与一个TTF文件的表目录(Table Directory)具有完全相同的格式。一个TTC文件中的所有的表目录(Table Directories)中的表偏移量,都是相对于TTC文件的起始位置计算的。

一个TTC文件中的每一个OpenType表通过每个使用了那些表的字库的偏移表(Offset Table)表目录(Table Directory)来引用。有些OpenType表必须出现多次,TTC中包含的字库每个一次;而其他的表可能由TTC中的多个字库共享。

比如,考虑一个结合了两个日语字库(Font1和Font2)的TTC文件。两个字库具有不同的kana的设计(Kana1和Kana2),但使用了相同的kanji的设计。那个TTC文件中包含有一个单一的‘glyf’表,其中同时包含有kana和kanji的设计;两个字库的表目录(Table Directory)都指向这个‘glyf’表。但每一个字库的表目录(Table Directory)指向不同的‘cmap’表,‘cmap’表确定了使用的glyph的集合。Font1的'cmap'表为kana glyphs指向 'loca'和 'glyf'表的Kana1区域,同时为kanji glyphs指向kanji区域。Font2的'cmap'表为kana glyphs指向 'loca'和 'glyf'表的Kana2区域,同时为kanji glyphs指向相同的kanji区域。

那些每个字库都应该有其唯一的一份拷贝的表,是那些被系统用来识别字库和它的字符映射的表,包括 'cmap','name',和'OS/2'。那些应该由TTC中的字库共享的表,是那些定义了glyph和指令数据或者使用glyph索引来访问数据的表: 'glyf','loca''hmtx''hdmx''LTSH', 'cvt ', 'fpgm', 'prep', 'EBLC', 'EBDT''EBSC''maxp',等等。实际上两个或多个字库中具有相同数据的任何表均可以共享。

Microsoft 有一个工具来帮助创建.TTC文件。过程包括紧密注意一个字库文件中的glyph重新编号的问题及‘camp’表和其他可能导致的side effects的地方。被合并的字库必须还含有兼容的TrueType指令-即,他们的预定程序(preprograms),函数定义,和控制值必须没有冲突。

TrueType集合文件使用文件名后缀.TTC。

TTC头

有两种版本的TTC头:版本1.0用于不含有数字签名的TTC文件。版本2.0可被用于包含或者不包含数字签名的TTC文件——如果没有签名,则版本2.0头的最后3个成员被留为null。

如果使用了一个数字签名,文件的DSIG表必须是TTC文件中的最后一个表。一个TTC文件中的签名被预期为Format 1签名。

TTCHeader表的目的为定位一个TTC文件内的不同的偏移表(Offset Table)。TTCHeader位于TTC文件的起始位置(offset = 0)。它由一个标识用的tag,一个版本号,一个文件中的OpenType字库的个数值,和一个到每一个偏移表(Offset Table)的偏移量所组成的数组组成。

TypeNameDescriptionTAGTTCTagTrueType Collection ID string: 'ttcf'FIXEDVersionVersion of the TTC Header (1.0), 0x00010000ULONGnumFontsNumber of fonts in TTCULONGOffsetTable[numFonts]Array of offsets to the OffsetTable for each font from the beginning of the file

TTC Header Version 1.0

TypeNameDescriptionTAGTTCTagTrueType Collection ID string: 'ttcf'FIXEDVersionVersion of the TTC Header (2.0), 0x00020000ULONGnumFontsNumber of fonts in TTCULONGOffsetTable[numFonts]Array of offsets to the OffsetTable for each font from the beginning of the fileULONGulDsigTagTag indicating that a DSIG table exists, 0x44534947 ('DSIG') (null if no signature)ULONGulDsigLengthThe length (in bytes) of the DSIG table (null if no signature)ULONGulDsigOffsetThe offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature)

TTC Header Version 2.0

字库表

如果表都被适当的填充而每一个都以4-byte边界为起始位置,则光栅化程序有一个简单得多的次数来遍历表。强烈建议所有的表都是long对齐并用0填充的。

OpenType表

一个OpenType文件中,无论是TrueType还是PostScript outline都会被用到的表,下面的表是功能正常的字库所必须的:

Required Tables

TagNamecmapCharacter to glyph mappingheadFont headerhheaHorizontal headerhmtxHorizontal metricsmaxpMaximum profilenameNaming tableOS/2OS/2 and Windows specific metricspostPostScript information

对于基于TrueType outlines的OpenType字库,需要用到下面的表:

TrueType Outlines相关的表

TagNamecvtControl Value TablefpgmFont programglyfGlyph datalocaIndex to locationprepCVT Program

PostScript字库扩展定义了一个新的表的集合,其中包含特定于PostScript字库的数据,用于替换上面所列的表:

PostScript Outlines相关的表

TagNameCFFPostScript font program (compact font format)VORGVertical Origin

It is strongly recommended that CFF OpenType fonts that are used for vertical writing include a  Vertical Origin ('VORG') table . Multiple Master support in OpenType, has been discontinued as of version 1.3 of the specification. The 'fvar', 'MMSD', 'MMFX' tables have hence been removed.

Bitmap Glyphs相关的表

TagNameEBDTEmbedded bitmap dataEBLCEmbedded bitmap location dataEBSCEmbedded bitmap scaling data

OpenType fonts may also contain bitmaps of glyphs, in addition to outlines. Hand-tuned bitmaps are especially useful in OpenType fonts for representing complex glyphs at very small sizes. If a bitmap for a particular size is provided in a font, it will be used by the system instead of the outline when rendering the glyph. (Note: ATM does not currently support hinted bitmaps in OpenType fonts.) 

也有一些可选的支持竖直布局和其他高级排版功能的表:

高级排版的表

TagNameBASEBaseline dataGDEFGlyph definition dataGPOSGlyph positioning dataGSUBGlyph substitution dataJSTFJustification data

关于通用表格式的信息,请参考 OpenType布局通用表格式 .

其他的OpenType表

TagNameDSIGDigital signaturegaspGrid-fitting/Scan-conversionhdmxHorizontal device metricskernKerningLTSHLinear threshold dataPCLTPCL 5 dataVDMXVertical device metricsvheaVertical Metrics headervmtxVertical Metrics

OpenType字库组织的例子

以Microsoft提供的一个蒙古文字库monbaiti.ttf为例,来看一下OpenType字库文件的组织:


首先,我们从字库文件的开头12个字节中解出来Offset表:

类型FixedUSHORT
USHORT
USHORT
USHORT
字段sfnt version
numTables
searchRange
entrySelector
rangeShift
实际值0x00010000 = 1.0
0x0016 = 220x01000x00040x0060

由Offset表中,我们可以看到,字库文件中主要包含22个表。接下来,我们从字库文件开头的部分中解出这所有的22个Table Record项出来:

类型ULONG
ULONG
ULONG
ULONG
字段名tag
checkSum
offset
length

0x44534947 = 'DSIG'0x1A87C0690x000555880x00001B58 = 7000
0x47444546 = 'GDEF'0x0DFA14EF0x00049EFC0x0000002A = 42
0x47504F53 = 'GPOS'0x07E10A6E
0x00049F28
0x000005AA = 1450
0x47535542 = 'GSUB'0x674E50BC0x0004A4D40x0000B0B2 = 45234
0x4C545348 = 'LTSH'0xAD5940F60x00001EC80x00000724
0x4F532F32 = 'OS/2'0x42A220F40x000001E80x00000060
0x56444D58 = 'VDMX'0x6B1372990x000025EC0x000005E0
0x636D6170 = 'cmap'0xBCF6EB3F0x0000A5380x00000788 = 1928
0x63767420 = 'cvt'0x2EB025CC0x0000B3E40x000000DA
0x6670676D = 'fpgm'0x76BD44C40x0000ACC00x00000623
0x67617370 = 'gasp'0x001800090x00049EEC0x00000010
0x676C7966 = 'glyf'0xD7ADBAED0x0000D1440x00035810 = 219152
0x68646D78 = 'hdmx'0x692F55A80x00002BCC0x0000796C
0x68656164 = 'head'0xA47B1BEA0x0000016C0x00000036
0x68686561 = 'hhea'0x0E390CA20x000001A40x00000024
0x686D7476 = 'hmtx'0x6FC3C6560x000002480x00001C7E
0x6B65726E = 'kern'0xFC78FC050x000429540x000001E0 = 480
0x6C6F6361 = 'loca'0x0D27C5940x0000B4C00x00001C84
0x6D617870 = 'maxp'0x08E707ED0x000001C80x00000020
0x6E616D65 = 'name'0xBA5115FF0x00042B340x000009D0
0x706F7374 = 'post'0x9827F1270x000435040x000069E8
0x70726570 = 'prep'0xA5E5A72F0x0000B2E40x00000100

GDEF,GSUB和GPOS表是OpenType高级排版最重要的几个表,因而值得我们重点关注。 而根据offset值,则可以看出来head表是紧紧跟着这22个TableRecord的那个表。

Done。

0 0
原创粉丝点击