ttf
- opentype
- sfnt-housed字体使用了与ttf相同的数据结构如OpenType(otf)字体
- ttf使用Bezier曲线表示字形
- Bezier点坐标必须在[-16384 16383]范围, 宽度最好是2的幂次方速度快,如2048
- ((设备每英寸的像素点/72)*pointSize)/网格最大宽度如2048 为一个单位距离的像素点数
- ttf字体数据类型 float16、16:16定点数、short、ushort、2:14定点数、long loong时间
- ttf文件由一系列表组成, 第一个表是表目录表, 表的第一个字段为uint32的tag
- ttf必须表
- ‘cmap’ 字符到字形的映射表
- ‘glyf’ 字形数据表
- ‘head’ 字体全局信息表头,位图字体可以没有换用bhed
- ‘hhea’ 水平显示全局表头,部分字段必须与hmtx一致
- ‘hmtx’ 水平显示数据头
- ‘loca’ 每个字形相对于字形表头的偏移
- ‘maxp’ 全局、表数据最大值信息
- ‘name’ 信息表,非程序使用,可以是说明、联系信息等
- ‘post’ PostScript打印信息
- ttf可选表
- ‘cvt ‘ 控制值表
- ‘fpgm’ 字体命令表
- ‘hdmx’ 水平设备数据
- ‘kern’ 字间距调整
- ‘OS/2’ 专为OS/2系统使用
- ‘prep’ 控制值命令表 ```C typedef struct { char fScalertype[4]; //表示如何解释字形数据 //’true’(0x74727565) ios、macos TrueType字体===0x00010000 //0x00010000 windows、adobe TrueType字体===’true’ //’typ1’(0x74797031) PostScript 字体采用ttf包装sfnt-housed字体 //’OTTO’(0x4F54544F) 具有PostScript轮廓的OpenType字体 // 采用’CFF ‘表而不是’glyf’表 UInt16 fNumTables; //表数量不包括文件目录表本身 UInt16 fSearchRange; //(2的幂次方<=fNumTables)sizeof(TableEntry) UInt16 fEntrySelector; //fSearchRange的2的幂本身 UInt16 fRangeShift; //fNumTablessizeof(TableEntry)-fSearchRange TableEntry tableEntry[0]; //表描述结构,按照tag升序排序 } FontHeader; //文件目录表 typedef struct { char fTag[4]; //’cmap’、’glyf’、… uint fCheckSum; //校验和 uint fOffset; // uint fLength; } TableEntry; typedef struct { UInt16 version; //0 UInt16 sub_table_num; //字符到字形map有多种字符编码对应字形map TableCMAPsub subs[0]; //子表描述结构,先platform_id升序再platform_spc_id } TableCMAP; typedef struct { UInt16 platform_id; //平台id //0 Unicode // 0 Version 1.0 semantics // 1 Version 1.1 semantics // 2 ISO 10646 1993 semantics (deprecated) // 3 Unicode 2.0 or later semantics (BMP only) // 4 Unicode 2.0 or later semantics // 5 Unicode Variation Sequences // 6 Last Resort //1 Macintosh //3 Microsoft // 0 Symbol // 1 Unicode BMP-only (UCS-2) // 2 Shift-JIS // 3 PRC // 4 BigFive // 5 Johab // 10 Unicode UCS-4 UInt16 platform_spc_id;//平台子id UInt32 offset; //TableCMAMapHeader 偏移量 } TableCMAPsub; typedef struct { UInt16 format; //map格式 //0 支持 Macintosh 标准字符到字形映射 //2 支持对日语、中文和韩语有用的混合 8/16 位映射 //4 用于16位映射(支持数字不连续的字符) //6 用于密集的(字符数字都连续)16位映射 BMP-only //8 混合 16/32 位映射,假设16与32前16位没有重合 //10类似6的32位编码 //12类似4的32位编码 //13结构与12完全相同,但所有段内的字符都映射到startGlyphCode而不递增 //14结构用于变体字形,部分是矢量部分是位图 …. } TableCMAMapHeader; typedef struct { UInt16 format; //4 UInt16 length; //表整体字节长度 UInt16 language; //platformID=Macintosh使用,其它0 UInt16 segCountX2; //2 * segCount(map大小) UInt16 searchRange; //2 * (2*FLOOR(log2(segCount))) UInt16 entrySelector; //log2(searchRange/2) UInt16 rangeShift; //(2 * segCount) - searchRange UInt16 endCode[segCount];//每段中最大的字符编码, last = 0xFFFF. UInt16 reservedPad; //未使用设置0 UInt16 startCode[segCount];//每段中最小的字符编码 UInt16 idDelta[segCount];//字形真实index偏移 UInt16 idRangeOffset[segCount];//字形索引数组相对自己的偏移 UInt16 glyphIndexArray[0];//字形在本段中的index的index } TableCMAMapHeader4; if (idRangeOffset[i] != 0) { glyphIndex=((UInt16)(((char)(idRangeOffset+i))+idRangeOffset[i]+(c-startCode[i])2))[0]; glyphIndex += idDelta[i]; } else { glyphIndex = idDelta[glyphIndex] + c; } typedef struct { UInt16 format; //12 UInt16 reserved; //未使用设置0 UInt32 length; //表整体字节长度 UInt32 language; //platformID=Macintosh使用,其它0 UInt32 nGroups; //Number of TableCMAMapGroup12 } TableCMAMapHeader12; typedef struct { UInt32 startCharCode; //每段中最小的字符编码 UInt32 endCharCode; //每段中最大的字符编码 UInt32 startGlyphCode; //最小的字符编码对应的字形index,递增 } TableCMAMapGroup12;
- ttf必须表
typedef struct { int16 numberOfContours;//>=0简单字形, <0复合字形 UInt16 xMin; UInt16 yMin; UInt16 xMax; UInt16 yMax; union { TableGLYFSimple s[0]; TableGLYFCompound c[0]; }; } TableGLYF; typedef struct { UInt16 endPtsOfContours[x];//每个曲线最后一个点的索引 UInt16 iLength; //指令个数 UInt8 instructions[iLength]; UInt8 flags[<n]; //flag 数组 //bit 0 点是否在曲线上 //bit 1 x坐标是否是8bit //bit 2 y坐标是否是8bit //bit 3 是否重复此flag, 如果重复下一个字节是重复次数,减少flag长度 //bit 4 x是8bit是否正数,x是16bit是否与前一x值相同, //bit 5 y是8bit是否正数,y是16bit是否与前一y值相同, UInt8|UInt16 xCoordinates[n]; //每个点的x偏移,第一个相对于(0,0) UInt8|UInt16 yCoordinates[n]; //每个点的y偏移,第一个相对于(0,0) } TableGLYFSimple; typedef struct { UInt16 flags; //flags //bit 0 xparam|yparam是否16bit //bit 1 xparam|yparam是否是xy坐标的位置,否则为积分的参数 //bit 2 如果bit1是坐标,是否四舍五入对齐网络 //bit 3 是否有特殊的比例变化,否则为1.0 //bit 5 是否有其它字形跟随 //bit 6 x方向是否使用与y方向不同的缩放比例 //bit 7 是否使用2x2来缩放 //bit 8 是否使用最后一个子字形的instructions命令 //bit 9 是否使用字形的metrics //bit 10 是否字符重叠 UInt16 glyphIndex; //子字形的index UInt8|UInt16 xparam; UInt8|UInt16 yparam; } TableGLYFCompound;
typedef struct {
UInt32 version; //16:16 0x00010000=1.0
UInt32 fontRevision; //字形版本
UInt32 checkSumAdjustment; //sum->self->sum->0xB1B0AFBA-sum
UInt32 magicNumber; //===0x5F0F3CF5
UInt16 flags;
//bit 0 - y = 0 做为基线
//bit 1 - x position of left most black bit is LSB
//bit 2 - 缩放后点大小与实际大小不同
//bit 3 - 使用整数
//bit 4 - 微软的字体缩放器
//bit 5 - 如果水平字体y = 0作为基线,垂直字体 x = 0 作为基线
//bit 7 - 是否需要布局
//bit 8 - AAT字体(Apple Advanced Typography)是否需要默认变形效果
//bit 9 - 强制从右到左的字形
//bit 10- 印度风格的重排字体
//bits 11-13 Adobe 专用
//bit 14- 字体逻辑代码通用字形,如未定义字体0、最后一个字形等
UInt16 unitsPerEm; //网络边长[64 16384]
UInt64 created; //创建时间
UInt64 longDateTime; //修改时间
UInt32 xMin; //所有字形中的最小x位置
UInt32 yMin; //所有字形中的最小y位置
UInt32 xMax; //所有字形中的最大x位置
UInt32 yMax; //所有字形中的最大y位置
UInt16 macStyle;
//bit 0 粗体
//bit 1 斜体
//bit 2 下划线
//bit 3 轮廓线
//bit 4 阴影
//bit 5 窄字体
//bit 6 扩展字体
UInt16 lowestRecPPEM; //最小可读尺寸
UInt16 fontDirectionHint;
//0 混合方向字形
//1 仅支持从左到右
//2 对从左到右支持较好
//-1 仅支持从右到左
//-2 对从右到左支持较好
UInt16 indexToLocFormat; //loca表中偏移值类型,0短偏移u16*2,1长偏移u32
UInt16 glyphDataFormat; //数据格式类型,当前只有0
} TableHead;
typedef struct { UInt32 version; //16:16 0x00010000 (1.0) UInt16 ascent; //最高点与基线的距离 UInt16 descent; //最低点与基线的距离 UInt16 lineGap; //排版线间距 UInt16 advanceWidthMax; //水平字间距最大值,必须与hmtx的值相同 UInt16 minLeftSideBearing; //左边空白最小值,必须与hmtx的值相同 UInt16 minRightSideBearing; //右边空白最小值,必须与hmtx的值相同 UInt16 xMaxExtent; //max(lsb + (xMax-xMin)) int16 caretSlopeRise; //插入提示符斜率分子, 1且下面的值为0垂直显示 int16 caretSlopeRun; //插入提示符斜率分母, 1且上面的值为0水平显示 UInt16 caretOffset; //插入提示符偏移值, 非倾斜字体设置为0 int16 reserved[4]; int16 metricDataFormat; //距离单位类型, 目前只有0 UInt16 numOfLongHorMetrics; //hmtx数组的size,没有hhea就无法使用hmtx } TableHHea; //tan(a)=caretSlopeRise/caretSlopeRun
typedef struct { struct { UInt16 advanceWidth; //字体最左侧到最右侧的宽度 int16 leftSideBearing; //字体最左侧在网格中空多少 } hMetrics[numOfLongHorMetrics];//等宽字体只有一条 UInt16 leftSideBearing[]; //混合等宽字体,advanceWidth等于最后一条的 } TableHmtx; typedef struct { UInt16|UInt32 offsets[n]; //n=字形个数+1,如果没有未定义字符0,1偏移都是0 } TableLoca;
typedef struct { UInt32 version; //16:16 0x00010000=1.0 UInt16 numGlyphs; //字形个数 UInt16 maxPoints; //非复合字形中最大的点数 UInt16 maxContours; //非复合字形中最大的轮廓数 UInt16 maxComponentPoints; //复合字形中最大的点数 UInt16 maxComponentContours; //复合字形中最大的轮廓数 UInt16 maxZones; //最大区域数,使用Z0为2,不使用为1,一般2 UInt16 maxTwilightPoints; //Z0区域最大点数 UInt16 maxStorage; //最大存储位置数 UInt16 maxFunctionDefs; //函数个数 UInt16 maxInstructionDefs; //指令个数 UInt16 maxStackElements; //最大堆栈深度 UInt16 maxSizeOfInstructions; //字形中指令的最大字节数 UInt16 maxComponentElements; //用于创建复合字形的简单字形数 UInt16 maxComponentDepth; //单个复合字形最大的简单字形数,0没有复合字形<=16 } TableMaxp; typedef struct { UInt32 version; //16:16 0x00005000=0.5 UInt16 numGlyphs; //字形个数 } TableCFFMaxp;
typedef struct {
UInt16 platformID; //平台ID
//0 Unicode UTF-16BE编码
//1 Macintosh QuickDraw编码.
//3 Microsoft zencoding.
UInt16 platformSpecificID; //平台子ID
//Unicode
//0 Version 1.0 semantics
//1 Version 1.1 semantics
//2 ISO 10646 1993 semantics (deprecated)
//3 Unicode 2.0 or later semantics (BMP only)
//4 Unicode 2.0 or later semantics (non-BMP)
//Macintosh
//0-Roman 1-Japanese 2-Traditional Chinese 3-Korean
//4-Arabic 5-Hebrew 6-Greek 7-Russian 8-RSymbol
//9-Devanagari 10-Gurmukhi 11-Gujarati 12-Oriya
//13-Bengali 14-Tamil 15-Telugu 16-Kannada
//17-Malayalam 18-Sinhalese 19-Burmese
//20-Khmer 21-Thai 22-Laotian 23-Georgian 24-Armenian
//25-Simplified Chinese 26-Tibetan 27-Mongolian
//28-Geez 29-Slavic 30-Vietnamese 31-Sindhi
UInt16 languageID;
//Macintosh
//0-English 1-French 2-German 3-Italian 4-Dutch
//5-Swedish 6-Spanish 7-Danish 8-Portuguese
//9-Norwegian 10-Hebrew 11-Japanese 12-Arabic
//13-Finnish 14-Greek 15-Icelandic
//16-Maltese 17-Turkish 18-Croatian
//19-Chinese(traditional) 20-Urdu 21-Hindi
//22-Thai 23-Korean 24-Lithuanian 25-Polish
//26-Hungarian 27-Estonian 28-Latvian 29-Sami
//30-Faroese 31-Farsi/Persian 32-Russian
//33-Chinese(simplified)34-Flemish 35-Irish Gaelic
//36-Albanian 37-Romanian 38-Czech 39-Slovak
//40-Slovenian 41-Yiddish 42-Serbian 43-Macedonian
//44-Bulgarian 45-Ukrainian46-Byelorussian
//47-Uzbek 48-Kazakh 49-Azerbaijani(Cyrillic script)
//50-Azerbaijani(Arabic script) 51-Armenian 52-Georgian
//53-Moldavian 54-Kirghiz 55-Tajiki 56-Turkmen
//57-Mongolian(Mongolian script)58-Mongolian(Cyrillic script)
//59-Pashto 60-Kurdish 61-Kashmiri 62-Sindhi 63-Tibetan
//64-Nepali 65-Sanskrit 66-Marathi 67-Bengali 68-Assamese
//69-Gujarati 70-Punjabi 71-Oriya 72-Malayalam
//73-Kannada 74-Tamil 75-Telugu 76-Sinhalese
//77-Burmese 78-Khmer 79-Lao 80-Vietnamese
//81-Indonesian 82-Tagalog 83-Malay(Roman script)
//84-Malay(Arabic script) 85-Amharic 86-Tigrinya
//87-Galla 88-Somali 89-Swahili 90-Kinyarwanda/Ruanda
//91-Rundi 92-Nyanja/Chewa 93-Malagasy 94-Esperanto
//128-Welsh 129-Basque 130-Catalan 131-Latin 132-Quechua
//133-Guarani 134-Aymara 135-Tatar 136-Uighur
//137-Dzongkha 138-Javanese(Roman script)
//139-Sundanese(Roman script) 140-Galician
//141-Afrikaans 142-Breton 143-Inuktitut
//144-Scottish Gaelic 145-Manx Gaelic
//146-Irish Gaelic(with dot above) 147-Tongan
//148-Greek(polytonic) 149-Greenlandic
//150-Azerbaijani(Roman script)
UInt16 nameID;
//0-Copyright notice 1-Font Family 2-Font Subfamily
//3-字体唯一子类型标识 4-字体全名 5-版本
//6-PostScript字体名,不随版本修改,<=63个ASCII[21 7E]不含各种括号% /
//7-商标 8-公司名称 9-设计师名字 10-描述简介
//11-公司URL 12-设计师URL 13-许可协议 14-许可协议URL
//15-未使用 16-首选Font Faimily 17-首选字体style
//18-字体全名 19-样例文本 20–24留给OpenType
//25-变体PostScript名称前缀 26–255留给未来扩展
//256–32767字体自定义字段
UInt16 length; //文本字节长度
UInt16 offset; //文本相对于stringOffset的偏移
} TableNameNode;
typedef struct {
UInt16 format; //表格式目前只有0
UInt16 count; //文本条数
UInt16 stringOffset; //文本字符串开始的位置
TableNameNode nameRecord[0] //文本Node数组
} TableName;
typedef struct { UInt32 format; //16:16 表格式 //1, 2(有子表), 2.5(有子表), 3, 4(有子表) UInt32 italicAngle; //16:16 以度为单位的倾斜角度 UInt16 underlinePosition; //下划线位置 UInt16 underlineThickness; //下划线粗细 UInt32 isFixedPitch; //0非等宽字体,其它值等宽字体 UInt32 minMemType42; //作为Type42字体时最小内存使用量 UInt32 maxMemType42; //作为Type42字体时最大内存使用量 UInt32 minMemType1; //作为Type1字体时最小内存使用量 UInt32 maxMemType1; //作为Type1字体时最大内存使用量 } TablePost; ```