找回密码
 立即注册
首页 业界区 业界 一文读懂字体文件

一文读懂字体文件

忆雏闲 3 天前
这篇文章是从0到1自定义富文本渲染的原理篇之一,此外你还可能感兴趣:
更多内容欢迎关注公众号:非专业程序员Ping

  • 一文读懂字符与编码
  • 一文读懂字符、字形、字体
  • 一文读懂字体文件
  • 从0到1自定义文字排版引擎:原理篇
  • 逆向分析CoreText中的字体级联/Font Fallback机制
  • 新手小白也能看懂的LLDB技巧/逆向技巧
  • 深入理解iOS CoreText API
一、引言

在开始阅读本文之前,推荐先阅读字符(Character)、字形(Glyph)、字体的区别理解基本概念。
如果你对字符与Unicode的相关概念还不理解,推荐阅读字符与编码
前文,我们介绍了字符(Character)、字形(Glyph)、字体的区别,这里我们再来实际分析一个字体文件中到底有什么,这有利于我们后续理解文字排版引擎的工作原理和流程。
macOS上系统字体路径一般为/System/Library/Fonts/,可以看到有文件后缀有ttc和ttf,二者有什么区别呢?
1).ttf (TrueType Font)
ttf表示这是一个单字体文件,每个 .ttf 文件通常只对应一个字体样式(例如 Microsoft YaHei Regular
2).ttc (TrueType Collection)
ttc表示这是一个字体集合文件,内部可以包含多个 TrueType 字体(多个 .ttf 打包在一起),这些字体通常共享某些表(比如 glyph 轮廓、cmap),减少冗余,提高存储效率,常用于一个 Typeface 的多个变体(Regular, Bold, Italic, Light…)
上面提到了TrueType,与之对应的还有OpenType,二者其实都是字体类型标准,简单理解就是OpenType是TrueType的扩展,OpenType支持更多的特性,比如:连字、RTL、上下标等。
OpenType一般以otf为后缀,但也不能简单的根据文件名后缀区分二者,文件扩展名只是习惯,并不能完全说明内部格式,真正的区别还是要看字体表结构,比如OpenType有GSUB、GPOS、GDEF等扩展表。
下面,我们来真正解析一个字体文件,看里面有什么,可以通过如下命令行将字体解析成XML。
  1. # 对于ttf文件
  2. ttx NewYork.ttf
  3. # ttc文件是个字体集合,需要明确指明要提取哪个index的字体
  4. ttx -y 0 Times.ttc
复制代码
二、Font文件解析

我们以NewYork.ttf文件为例,如下是NewYork.ttf中的表
1.png

2.1 GlyphOrder
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
GlyphOrder定义glyphID与glyphName的映射。
2.2 head

Font Header,存储一些全局信息;关注几个值:
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
1)unitsPerEm
字体表里的数值一般都很大(见后文),其单位并不是像素值,而是 em unit,表示2048 units = 1 em = 设计的字高,比如当字体在屏幕上以 16px 渲染时,1 em = 16px,其他数值可按比例换算
2.3 hhea

Horizontal Typesetting Header,横向排版信息,关注几个值
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
1)ascent & descent
假设字体大小16,unitsPerEm如上为2048,则按比例换算:ascent = 1950/2048 * 16 ≈ 15.2,descent ≈ 494/2048 * 16 ≈ 3.8。
需要注意,OS_2表中也有ascent、descent的定义,这是因为不同平台会读取不同表中的ascent、descent,比如macOS、iOS一般使用hhea中的值,Windows一般使用OS_2表中的usWinAscent、usWinDescent,专业排版软件(如InDesign)一般用OS_2表中的sTypoAscender、sTypoDescender。
Q:对于同一个Font,ascent、descent的值是固定的吗?
这个问题的答案需要加定语,对于同一个Font,在同一个平台上,ascent、descent是固定的。
Q:为什么descent值是负数?
可以理解成规范,TrueType/OpenType的规范里,descent是负数,表示基线(baseline)以下延伸的高度。
2.4 maxp
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
定义字体里 glyph 的数量,以及一些最大值参数。
2.5 OS_2
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
参见Apple文档,关注几个值:
1)ySubscriptXSize & ySubscriptYSize & ySubscriptXOffset & ySubscriptYOffset
下标的大小和偏移
2)ySuperscriptXSize & ySuperscriptYSize & ySuperscriptXOffset & ySuperscriptYOffset
上标的大小和偏移
3)yStrikeoutSize & yStrikeoutPosition
删除线的粗细和垂直位置
4)ulUnicodeRange1 & ulUnicodeRange2 & ulUnicodeRange3 & ulUnicodeRange4
ulUnicodeRange表示该字体支持的Unicode范围,用ulUnicodeRange1 … ulUnicodeRange4 这 4 个 32 位字段来表示,总共 128 个 bit,对应 128 个 Unicode Block,如果某 bit = 1,表示字体支持该区块中的至少一些字符,映射表见:https://learn.microsoft.com/en-us/typography/opentype/spec/os2#ur 。
Windows系统通常用 ulUnicodeRange 来看一个字体是否支持某Unicode;macOS/iOS系统一般用 cmap 表(精确的字符映射),ulUnicodeRange只作为辅助信息;浏览器排版一般直接查 cmap,但 ulUnicodeRange 有时也用于字体 fallback 策略。
5)sTypoAscender & sTypoDescender & usWinAscent & usWinDescent
如前文所述,不同系统会取不同的值作为ascent、descent
2.6 hmtx
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
Horizontal Metrics,记录每个 glyph 的 advance width 和left side bearing。
简单理解排版引擎绘制字形的流程是:将字形放在当前点 + lsb 偏移位置进行绘制,画完后,将光标向右移动 advanceWidth,准备绘制下一个字形。
2.7 cmap
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder><GlyphOrder>
  88. <GlyphID id="0" name=".notdef"/>
  89. <GlyphID id="1" name=".null"/>
  90. <GlyphID id="2" name="nonmarkingreturn"/>
  91. <GlyphID id="3" name="space"/>
  92. <GlyphID id="4" name="A"/>
  93. <head>
  94. <unitsPerEm value="2048"/>
  95. <hhea>
  96. <descent value="-494"/>
  97. <lineGap value="0"/>
  98. <minLeftSideBearing value="-693"/>
  99. <minRightSideBearing value="-693"/>
  100. <maxp>
  101. <numGlyphs value="1811"/>
  102. <OS_2>
  103. <ySubscriptXSize value="650"/>
  104. <ySubscriptYSize value="600"/>
  105. <ySubscriptXOffset value="0"/>
  106. <ySubscriptYOffset value="75"/>
  107. <ySuperscriptXSize value="650"/>
  108. <ySuperscriptYSize value="600"/>
  109. <ySuperscriptXOffset value="0"/>
  110. <ySuperscriptYOffset value="350"/>
  111. <yStrikeoutSize value="12"/>
  112. <yStrikeoutPosition value="620"/>
  113. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  114. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  115. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  116. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  117. <sTypoAscender value="1950"/>
  118. <sTypoDescender value="-494"/>
  119. <sTypoLineGap value="0"/>
  120. <usWinAscent value="1950"/>
  121. <usWinDescent value="494"/>
  122. <hmtx>
  123. <mtx name=".notdef" width="2048" lsb="199"/>
  124. <mtx name=".null" width="0" lsb="0"/>
  125. <mtx name="A" width="1244" lsb="-16"/>
  126. <glyf>
  127. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  128. <contour>
  129. <pt x="1086" y="213" on="1"/>
  130. <pt x="1113" y="137" on="0"/>
  131. <pt x="1161" y="50" on="0"/>
  132. <pt x="1219" y="9" on="0"/>
  133. <pt x="1260" y="1" on="1"/>
  134. <pt x="1260" y="0" on="1"/>
  135. <pt x="793" y="0" on="1"/>
  136. <pt x="793" y="1" on="1"/>
  137. <pt x="845" y="7" on="0"/>
  138. <pt x="897" y="54" on="0"/>
  139. <pt x="899" y="143" on="0"/>
  140. <pt x="874" y="213" on="1"/>
  141. <pt x="528" y="1200" on="1"/>
  142. <pt x="528" y="1200" on="1"/>
  143. <pt x="220" y="292" on="1"/>
  144. <pt x="184" y="186" on="0"/>
  145. <pt x="170" y="66" on="0"/>
  146. <pt x="224" y="11" on="0"/>
  147. <pt x="290" y="1" on="1"/>
  148. <pt x="290" y="0" on="1"/>
  149. <pt x="-16" y="0" on="1"/>
  150. <pt x="-16" y="1" on="1"/>
  151. <pt x="27" y="9" on="0"/>
  152. <pt x="89" y="59" on="0"/>
  153. <pt x="151" y="181" on="0"/>
  154. <pt x="193" y="297" on="1"/>
  155. <pt x="614" y="1444" on="1"/>
  156. <pt x="648" y="1444" on="1"/>
  157. </contour>
  158. <contour>
  159. <pt x="290" y="532" on="1"/>
  160. <pt x="294" y="544" on="1"/>
  161. <pt x="859" y="544" on="1"/>
  162. <pt x="860" y="532" on="1"/>
  163. </contour>
  164. <instructions/>
  165. </TTGlyph>
  166. ...
  167. </glyf>
  168. </hmtx>
  169. </OS_2>
  170. </maxp>
  171. </hhea>
  172. </head>
  173. </GlyphOrder>
复制代码
Character to Glyph Mapping,定义 Unicode code point → glyph ID 的映射,cmap表中能精确的查到该Font支持哪些Unicode。
2.8 glyf
  1. <GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
Glyph Data,真正的字形轮廓(矢量点、轮廓、控制点);cmap 表负责把 Unicode 字符映射到 glyphID,而 glyf 表告诉渲染系统该 glyph 的具体形状。
2.9 name
  1. © 2017-2024 Apple Inc. All rights reserved..New YorkRegular.New York; 20.0d1e1; 2024-05-06.New York20.0d1e1.NewYork-Regular<GlyphOrder>
  2. <GlyphID id="0" name=".notdef"/>
  3. <GlyphID id="1" name=".null"/>
  4. <GlyphID id="2" name="nonmarkingreturn"/>
  5. <GlyphID id="3" name="space"/>
  6. <GlyphID id="4" name="A"/>
  7. <head>
  8. <unitsPerEm value="2048"/>
  9. <hhea>
  10. <descent value="-494"/>
  11. <lineGap value="0"/>
  12. <minLeftSideBearing value="-693"/>
  13. <minRightSideBearing value="-693"/>
  14. <maxp>
  15. <numGlyphs value="1811"/>
  16. <OS_2>
  17. <ySubscriptXSize value="650"/>
  18. <ySubscriptYSize value="600"/>
  19. <ySubscriptXOffset value="0"/>
  20. <ySubscriptYOffset value="75"/>
  21. <ySuperscriptXSize value="650"/>
  22. <ySuperscriptYSize value="600"/>
  23. <ySuperscriptXOffset value="0"/>
  24. <ySuperscriptYOffset value="350"/>
  25. <yStrikeoutSize value="12"/>
  26. <yStrikeoutPosition value="620"/>
  27. <ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
  28. <ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
  29. <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
  30. <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
  31. <sTypoAscender value="1950"/>
  32. <sTypoDescender value="-494"/>
  33. <sTypoLineGap value="0"/>
  34. <usWinAscent value="1950"/>
  35. <usWinDescent value="494"/>
  36. <hmtx>
  37. <mtx name=".notdef" width="2048" lsb="199"/>
  38. <mtx name=".null" width="0" lsb="0"/>
  39. <mtx name="A" width="1244" lsb="-16"/>
  40. <glyf>
  41. <TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
  42. <contour>
  43. <pt x="1086" y="213" on="1"/>
  44. <pt x="1113" y="137" on="0"/>
  45. <pt x="1161" y="50" on="0"/>
  46. <pt x="1219" y="9" on="0"/>
  47. <pt x="1260" y="1" on="1"/>
  48. <pt x="1260" y="0" on="1"/>
  49. <pt x="793" y="0" on="1"/>
  50. <pt x="793" y="1" on="1"/>
  51. <pt x="845" y="7" on="0"/>
  52. <pt x="897" y="54" on="0"/>
  53. <pt x="899" y="143" on="0"/>
  54. <pt x="874" y="213" on="1"/>
  55. <pt x="528" y="1200" on="1"/>
  56. <pt x="528" y="1200" on="1"/>
  57. <pt x="220" y="292" on="1"/>
  58. <pt x="184" y="186" on="0"/>
  59. <pt x="170" y="66" on="0"/>
  60. <pt x="224" y="11" on="0"/>
  61. <pt x="290" y="1" on="1"/>
  62. <pt x="290" y="0" on="1"/>
  63. <pt x="-16" y="0" on="1"/>
  64. <pt x="-16" y="1" on="1"/>
  65. <pt x="27" y="9" on="0"/>
  66. <pt x="89" y="59" on="0"/>
  67. <pt x="151" y="181" on="0"/>
  68. <pt x="193" y="297" on="1"/>
  69. <pt x="614" y="1444" on="1"/>
  70. <pt x="648" y="1444" on="1"/>
  71. </contour>
  72. <contour>
  73. <pt x="290" y="532" on="1"/>
  74. <pt x="294" y="544" on="1"/>
  75. <pt x="859" y="544" on="1"/>
  76. <pt x="860" y="532" on="1"/>
  77. </contour>
  78. <instructions/>
  79. </TTGlyph>
  80. ...
  81. </glyf>
  82. </hmtx>
  83. </OS_2>
  84. </maxp>
  85. </hhea>
  86. </head>
  87. </GlyphOrder>
复制代码
name表中定义的是字体名称、字体家族、PostScript Name、厂商信息等。
nameID对应的含义如下:
nameID含义0Copyright notice1Font Family name(字体家族名,比如 New York)2Font Subfamily name(字重/样式,比如 RegularBold)3Unique font identifier(唯一ID,通常包含厂商名+版本号)4Full font name(family + subfamily,比如 New York Regular)5Version string6PostScript name(唯一的、无空格的名字)<GlyphOrder>
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name=".null"/>
<GlyphID id="2" name="nonmarkingreturn"/>
<GlyphID id="3" name="space"/>
<GlyphID id="4" name="A"/>
<head>
<unitsPerEm value="2048"/>
<hhea>


<descent value="-494"/>
<lineGap value="0"/>

<minLeftSideBearing value="-693"/>
<minRightSideBearing value="-693"/>
<maxp>
<numGlyphs value="1811"/>
<OS_2>

<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>


<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>


<yStrikeoutSize value="12"/>
<yStrikeoutPosition value="620"/>


<ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
<ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>


<sTypoAscender value="1950"/>
<sTypoDescender value="-494"/>
<sTypoLineGap value="0"/>


<usWinAscent value="1950"/>
<usWinDescent value="494"/>
<hmtx>
<mtx name=".notdef" width="2048" lsb="199"/>
<mtx name=".null" width="0" lsb="0"/>
<mtx name="A" width="1244" lsb="-16"/>
<glyf>
<TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
<contour>
<pt x="1086" y="213" on="1"/>
<pt x="1113" y="137" on="0"/>
<pt x="1161" y="50" on="0"/>
<pt x="1219" y="9" on="0"/>
<pt x="1260" y="1" on="1"/>
<pt x="1260" y="0" on="1"/>
<pt x="793" y="0" on="1"/>
<pt x="793" y="1" on="1"/>
<pt x="845" y="7" on="0"/>
<pt x="897" y="54" on="0"/>
<pt x="899" y="143" on="0"/>
<pt x="874" y="213" on="1"/>
<pt x="528" y="1200" on="1"/>
<pt x="528" y="1200" on="1"/>
<pt x="220" y="292" on="1"/>
<pt x="184" y="186" on="0"/>
<pt x="170" y="66" on="0"/>
<pt x="224" y="11" on="0"/>
<pt x="290" y="1" on="1"/>
<pt x="290" y="0" on="1"/>
<pt x="-16" y="0" on="1"/>
<pt x="-16" y="1" on="1"/>
<pt x="27" y="9" on="0"/>
<pt x="89" y="59" on="0"/>
<pt x="151" y="181" on="0"/>
<pt x="193" y="297" on="1"/>
<pt x="614" y="1444" on="1"/>
<pt x="648" y="1444" on="1"/>
</contour>
<contour>
<pt x="290" y="532" on="1"/>
<pt x="294" y="544" on="1"/>
<pt x="859" y="544" on="1"/>
<pt x="860" y="532" on="1"/>
</contour>
<instructions/>
</TTGlyph>
...
</glyf>
</hmtx>
</OS_2>
</maxp>
</hhea>
</head>
</GlyphOrder><GlyphOrder>
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name=".null"/>
<GlyphID id="2" name="nonmarkingreturn"/>
<GlyphID id="3" name="space"/>
<GlyphID id="4" name="A"/>
<head>
<unitsPerEm value="2048"/>
<hhea>


<descent value="-494"/>
<lineGap value="0"/>

<minLeftSideBearing value="-693"/>
<minRightSideBearing value="-693"/>
<maxp>
<numGlyphs value="1811"/>
<OS_2>

<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>


<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>


<yStrikeoutSize value="12"/>
<yStrikeoutPosition value="620"/>


<ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
<ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>


<sTypoAscender value="1950"/>
<sTypoDescender value="-494"/>
<sTypoLineGap value="0"/>


<usWinAscent value="1950"/>
<usWinDescent value="494"/>
<hmtx>
<mtx name=".notdef" width="2048" lsb="199"/>
<mtx name=".null" width="0" lsb="0"/>
<mtx name="A" width="1244" lsb="-16"/>
<glyf>
<TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
<contour>
<pt x="1086" y="213" on="1"/>
<pt x="1113" y="137" on="0"/>
<pt x="1161" y="50" on="0"/>
<pt x="1219" y="9" on="0"/>
<pt x="1260" y="1" on="1"/>
<pt x="1260" y="0" on="1"/>
<pt x="793" y="0" on="1"/>
<pt x="793" y="1" on="1"/>
<pt x="845" y="7" on="0"/>
<pt x="897" y="54" on="0"/>
<pt x="899" y="143" on="0"/>
<pt x="874" y="213" on="1"/>
<pt x="528" y="1200" on="1"/>
<pt x="528" y="1200" on="1"/>
<pt x="220" y="292" on="1"/>
<pt x="184" y="186" on="0"/>
<pt x="170" y="66" on="0"/>
<pt x="224" y="11" on="0"/>
<pt x="290" y="1" on="1"/>
<pt x="290" y="0" on="1"/>
<pt x="-16" y="0" on="1"/>
<pt x="-16" y="1" on="1"/>
<pt x="27" y="9" on="0"/>
<pt x="89" y="59" on="0"/>
<pt x="151" y="181" on="0"/>
<pt x="193" y="297" on="1"/>
<pt x="614" y="1444" on="1"/>
<pt x="648" y="1444" on="1"/>
</contour>
<contour>
<pt x="290" y="532" on="1"/>
<pt x="294" y="544" on="1"/>
<pt x="859" y="544" on="1"/>
<pt x="860" y="532" on="1"/>
</contour>
<instructions/>
</TTGlyph>
...
</glyf>
</hmtx>
</OS_2>
</maxp>
</hhea>
</head>
</GlyphOrder>这里需要重点介绍下PostScript Name:PostScript Name是字体在一个系统里的唯一标识,是单个字符串,不允许有空格,一般是 FamilyName-StyleName 形式,比如:.NewYork-Regular,Helvetica-Bold,NotoSansCJKsc-Regular等。
在CoreText的API里,一般都要求传PostScript Name,比如:CTFontCreateWithName
2.10 GDEF

Glyph Definition Table,简单理解GDEF表就是是GPOS / GSUB的辅助表,比如GPOS和 GSUB需要知道「哪些字形是 mark、哪些能连接、哪些有变体」等信息,这些元数据就是放在GDEF 表里的。
2.11 GPOS

Glyph Positioning Table,控制字形的相对位置(如kerning、上下标等),比如「A + V」之间要减少间距,或者音标放在元音正上方等。
2.12 GSUB

Glyph Substitution Table,控制字形替换(连字、、阿拉伯文变体、直角引号换弯引号等),比如f + i → fi,'quoteleft' → ‘等。
2.13 HVAR & MVAR & avar & fvar & gvar<GlyphOrder>
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name=".null"/>
<GlyphID id="2" name="nonmarkingreturn"/>
<GlyphID id="3" name="space"/>
<GlyphID id="4" name="A"/>
<head>
<unitsPerEm value="2048"/>
<hhea>


<descent value="-494"/>
<lineGap value="0"/>

<minLeftSideBearing value="-693"/>
<minRightSideBearing value="-693"/>
<maxp>
<numGlyphs value="1811"/>
<OS_2>

<ySubscriptXSize value="650"/>
<ySubscriptYSize value="600"/>
<ySubscriptXOffset value="0"/>
<ySubscriptYOffset value="75"/>


<ySuperscriptXSize value="650"/>
<ySuperscriptYSize value="600"/>
<ySuperscriptXOffset value="0"/>
<ySuperscriptYOffset value="350"/>


<yStrikeoutSize value="12"/>
<yStrikeoutPosition value="620"/>


<ulUnicodeRange1 value="10100001 00000000 00000010 11111111"/>
<ulUnicodeRange2 value="00000010 00000000 00100000 01011110"/>
<ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
<ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>


<sTypoAscender value="1950"/>
<sTypoDescender value="-494"/>
<sTypoLineGap value="0"/>


<usWinAscent value="1950"/>
<usWinDescent value="494"/>
<hmtx>
<mtx name=".notdef" width="2048" lsb="199"/>
<mtx name=".null" width="0" lsb="0"/>
<mtx name="A" width="1244" lsb="-16"/>
<glyf>
<TTGlyph name="A" xMin="-16" yMin="0" xMax="1260" yMax="1444">
<contour>
<pt x="1086" y="213" on="1"/>
<pt x="1113" y="137" on="0"/>
<pt x="1161" y="50" on="0"/>
<pt x="1219" y="9" on="0"/>
<pt x="1260" y="1" on="1"/>
<pt x="1260" y="0" on="1"/>
<pt x="793" y="0" on="1"/>
<pt x="793" y="1" on="1"/>
<pt x="845" y="7" on="0"/>
<pt x="897" y="54" on="0"/>
<pt x="899" y="143" on="0"/>
<pt x="874" y="213" on="1"/>
<pt x="528" y="1200" on="1"/>
<pt x="528" y="1200" on="1"/>
<pt x="220" y="292" on="1"/>
<pt x="184" y="186" on="0"/>
<pt x="170" y="66" on="0"/>
<pt x="224" y="11" on="0"/>
<pt x="290" y="1" on="1"/>
<pt x="290" y="0" on="1"/>
<pt x="-16" y="0" on="1"/>
<pt x="-16" y="1" on="1"/>
<pt x="27" y="9" on="0"/>
<pt x="89" y="59" on="0"/>
<pt x="151" y="181" on="0"/>
<pt x="193" y="297" on="1"/>
<pt x="614" y="1444" on="1"/>
<pt x="648" y="1444" on="1"/>
</contour>
<contour>
<pt x="290" y="532" on="1"/>
<pt x="294" y="544" on="1"/>
<pt x="859" y="544" on="1"/>
<pt x="860" y="532" on="1"/>
</contour>
<instructions/>
</TTGlyph>
...
</glyf>
</hmtx>
</OS_2>
</maxp>
</hhea>
</head>
</GlyphOrder>


这几个表是用于转换可变字体的,可变字体不在本文范围内,不再详述。
<blockquote>
更多精彩内容欢迎关注
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册