@cantoo/fontkit 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -0
  3. package/dist/browser-module.mjs +13660 -0
  4. package/dist/browser-module.mjs.map +1 -0
  5. package/dist/browser.cjs +13689 -0
  6. package/dist/browser.cjs.map +1 -0
  7. package/dist/main.cjs +13712 -0
  8. package/dist/main.cjs.map +1 -0
  9. package/dist/module.mjs +13673 -0
  10. package/dist/module.mjs.map +1 -0
  11. package/package.json +99 -0
  12. package/src/CmapProcessor.js +285 -0
  13. package/src/DFont.js +113 -0
  14. package/src/TTFFont.js +621 -0
  15. package/src/TrueTypeCollection.js +65 -0
  16. package/src/WOFF2Font.js +222 -0
  17. package/src/WOFFFont.js +56 -0
  18. package/src/aat/AATFeatureMap.js +545 -0
  19. package/src/aat/AATLayoutEngine.js +48 -0
  20. package/src/aat/AATLookupTable.js +125 -0
  21. package/src/aat/AATMorxProcessor.js +429 -0
  22. package/src/aat/AATStateMachine.js +96 -0
  23. package/src/base.js +29 -0
  24. package/src/cff/CFFCharsets.js +99 -0
  25. package/src/cff/CFFDict.js +166 -0
  26. package/src/cff/CFFEncodings.js +48 -0
  27. package/src/cff/CFFFont.js +158 -0
  28. package/src/cff/CFFIndex.js +150 -0
  29. package/src/cff/CFFOperand.js +135 -0
  30. package/src/cff/CFFPointer.js +50 -0
  31. package/src/cff/CFFPrivateDict.js +39 -0
  32. package/src/cff/CFFStandardStrings.js +71 -0
  33. package/src/cff/CFFTop.js +236 -0
  34. package/src/decorators.js +36 -0
  35. package/src/encodings.js +219 -0
  36. package/src/fs.js +12 -0
  37. package/src/glyph/BBox.js +72 -0
  38. package/src/glyph/CBDTGlyph.js +9 -0
  39. package/src/glyph/CFFGlyph.js +635 -0
  40. package/src/glyph/COLRGlyph.js +108 -0
  41. package/src/glyph/Glyph.js +270 -0
  42. package/src/glyph/GlyphVariationProcessor.js +487 -0
  43. package/src/glyph/Path.js +257 -0
  44. package/src/glyph/SBIXGlyph.js +54 -0
  45. package/src/glyph/StandardNames.js +27 -0
  46. package/src/glyph/TTFGlyph.js +408 -0
  47. package/src/glyph/TTFGlyphEncoder.js +158 -0
  48. package/src/glyph/WOFF2Glyph.js +70 -0
  49. package/src/index.js +15 -0
  50. package/src/layout/GlyphPosition.js +30 -0
  51. package/src/layout/GlyphRun.js +108 -0
  52. package/src/layout/KernProcessor.js +97 -0
  53. package/src/layout/LayoutEngine.js +190 -0
  54. package/src/layout/Script.js +231 -0
  55. package/src/layout/UnicodeLayoutEngine.js +250 -0
  56. package/src/node.js +16 -0
  57. package/src/opentype/GPOSProcessor.js +311 -0
  58. package/src/opentype/GSUBProcessor.js +208 -0
  59. package/src/opentype/GlyphInfo.js +57 -0
  60. package/src/opentype/GlyphIterator.js +82 -0
  61. package/src/opentype/OTLayoutEngine.js +117 -0
  62. package/src/opentype/OTProcessor.js +472 -0
  63. package/src/opentype/ShapingPlan.js +121 -0
  64. package/src/opentype/shapers/ArabicShaper.js +124 -0
  65. package/src/opentype/shapers/DefaultShaper.js +116 -0
  66. package/src/opentype/shapers/HangulShaper.js +285 -0
  67. package/src/opentype/shapers/HebrewShaper.js +105 -0
  68. package/src/opentype/shapers/IndicShaper.js +914 -0
  69. package/src/opentype/shapers/ThaiShaper.js +238 -0
  70. package/src/opentype/shapers/UniversalShaper.js +186 -0
  71. package/src/opentype/shapers/data.trie +0 -0
  72. package/src/opentype/shapers/gen-indic.js +208 -0
  73. package/src/opentype/shapers/gen-use.js +287 -0
  74. package/src/opentype/shapers/generate-data.js +33 -0
  75. package/src/opentype/shapers/index.js +109 -0
  76. package/src/opentype/shapers/indic-data.js +175 -0
  77. package/src/opentype/shapers/indic.json +1 -0
  78. package/src/opentype/shapers/indic.machine +31 -0
  79. package/src/opentype/shapers/indic.trie +0 -0
  80. package/src/opentype/shapers/use.json +1 -0
  81. package/src/opentype/shapers/use.machine +44 -0
  82. package/src/opentype/shapers/use.trie +0 -0
  83. package/src/packages/unicode-properties/LICENSE +8 -0
  84. package/src/packages/unicode-properties/README.md +12 -0
  85. package/src/packages/unicode-properties/data-trie.js +1 -0
  86. package/src/packages/unicode-properties/data.js +1 -0
  87. package/src/packages/unicode-properties/data.json +1 -0
  88. package/src/packages/unicode-properties/data.trie +0 -0
  89. package/src/packages/unicode-properties/dist/index.cjs +257 -0
  90. package/src/packages/unicode-properties/dist/index.cjs.map +7 -0
  91. package/src/packages/unicode-properties/dist/index.mjs +234 -0
  92. package/src/packages/unicode-properties/dist/index.mjs.map +7 -0
  93. package/src/packages/unicode-properties/generate.js +107 -0
  94. package/src/packages/unicode-properties/index.js +184 -0
  95. package/src/packages/unicode-properties/package.json +50 -0
  96. package/src/packages/unicode-trie/LICENSE +8 -0
  97. package/src/packages/unicode-trie/README.md +13 -0
  98. package/src/packages/unicode-trie/builder.js +965 -0
  99. package/src/packages/unicode-trie/dist/builder.cjs +711 -0
  100. package/src/packages/unicode-trie/dist/builder.cjs.map +7 -0
  101. package/src/packages/unicode-trie/dist/builder.mjs +690 -0
  102. package/src/packages/unicode-trie/dist/builder.mjs.map +7 -0
  103. package/src/packages/unicode-trie/dist/index.cjs +112 -0
  104. package/src/packages/unicode-trie/dist/index.cjs.map +7 -0
  105. package/src/packages/unicode-trie/dist/index.mjs +91 -0
  106. package/src/packages/unicode-trie/dist/index.mjs.map +7 -0
  107. package/src/packages/unicode-trie/index.js +135 -0
  108. package/src/packages/unicode-trie/package.json +49 -0
  109. package/src/packages/unicode-trie/swap.js +21 -0
  110. package/src/subset/CFFSubset.js +176 -0
  111. package/src/subset/Subset.js +63 -0
  112. package/src/subset/TTFSubset.js +130 -0
  113. package/src/tables/BASE.js +78 -0
  114. package/src/tables/COLR.js +25 -0
  115. package/src/tables/CPAL.js +24 -0
  116. package/src/tables/DSIG.js +21 -0
  117. package/src/tables/EBDT.js +91 -0
  118. package/src/tables/EBLC.js +80 -0
  119. package/src/tables/GDEF.js +57 -0
  120. package/src/tables/GPOS.js +209 -0
  121. package/src/tables/GSUB.js +85 -0
  122. package/src/tables/HVAR.js +44 -0
  123. package/src/tables/JSTF.js +43 -0
  124. package/src/tables/LTSH.js +10 -0
  125. package/src/tables/OS2.js +84 -0
  126. package/src/tables/PCLT.js +21 -0
  127. package/src/tables/STAT.js +99 -0
  128. package/src/tables/VDMX.js +33 -0
  129. package/src/tables/VORG.js +14 -0
  130. package/src/tables/WOFF2Directory.js +73 -0
  131. package/src/tables/WOFFDirectory.js +37 -0
  132. package/src/tables/aat.js +157 -0
  133. package/src/tables/avar.js +19 -0
  134. package/src/tables/bsln.js +31 -0
  135. package/src/tables/cmap.js +127 -0
  136. package/src/tables/cvt.js +6 -0
  137. package/src/tables/directory.js +58 -0
  138. package/src/tables/feat.js +28 -0
  139. package/src/tables/fpgm.js +8 -0
  140. package/src/tables/fvar.js +31 -0
  141. package/src/tables/gasp.js +15 -0
  142. package/src/tables/glyf.js +4 -0
  143. package/src/tables/gvar.js +27 -0
  144. package/src/tables/hdmx.js +15 -0
  145. package/src/tables/head.js +25 -0
  146. package/src/tables/hhea.js +19 -0
  147. package/src/tables/hmtx.js +11 -0
  148. package/src/tables/index.js +119 -0
  149. package/src/tables/just.js +81 -0
  150. package/src/tables/kern.js +91 -0
  151. package/src/tables/loca.js +30 -0
  152. package/src/tables/maxp.js +20 -0
  153. package/src/tables/morx.js +79 -0
  154. package/src/tables/name.js +157 -0
  155. package/src/tables/opbd.js +15 -0
  156. package/src/tables/opentype.js +217 -0
  157. package/src/tables/post.js +34 -0
  158. package/src/tables/prep.js +6 -0
  159. package/src/tables/sbix.js +17 -0
  160. package/src/tables/variations.js +80 -0
  161. package/src/tables/vhea.js +19 -0
  162. package/src/tables/vmtx.js +12 -0
  163. package/src/utils.js +62 -0
@@ -0,0 +1,19 @@
1
+ import * as r from 'restructure';
2
+
3
+ // horizontal header
4
+ export default new r.Struct({
5
+ version: r.int32,
6
+ ascent: r.int16, // Distance from baseline of highest ascender
7
+ descent: r.int16, // Distance from baseline of lowest descender
8
+ lineGap: r.int16, // Typographic line gap
9
+ advanceWidthMax: r.uint16, // Maximum advance width value in 'hmtx' table
10
+ minLeftSideBearing: r.int16, // Maximum advance width value in 'hmtx' table
11
+ minRightSideBearing: r.int16, // Minimum right sidebearing value
12
+ xMaxExtent: r.int16,
13
+ caretSlopeRise: r.int16, // Used to calculate the slope of the cursor (rise/run); 1 for vertical
14
+ caretSlopeRun: r.int16, // 0 for vertical
15
+ caretOffset: r.int16, // Set to 0 for non-slanted fonts
16
+ reserved: new r.Reserved(r.int16, 4),
17
+ metricDataFormat: r.int16, // 0 for current format
18
+ numberOfMetrics: r.uint16 // Number of advance widths in 'hmtx' table
19
+ });
@@ -0,0 +1,11 @@
1
+ import * as r from 'restructure';
2
+
3
+ let HmtxEntry = new r.Struct({
4
+ advance: r.uint16,
5
+ bearing: r.int16
6
+ });
7
+
8
+ export default new r.Struct({
9
+ metrics: new r.LazyArray(HmtxEntry, t => t.parent.hhea.numberOfMetrics),
10
+ bearings: new r.LazyArray(r.int16, t => t.parent.maxp.numGlyphs - t.parent.hhea.numberOfMetrics)
11
+ });
@@ -0,0 +1,119 @@
1
+ let tables = {};
2
+ export default tables;
3
+
4
+ // Required Tables
5
+ import cmap from './cmap';
6
+ import head from './head';
7
+ import hhea from './hhea';
8
+ import hmtx from './hmtx';
9
+ import maxp from './maxp';
10
+ import name from './name';
11
+ import OS2 from './OS2';
12
+ import post from './post';
13
+
14
+ tables.cmap = cmap;
15
+ tables.head = head;
16
+ tables.hhea = hhea;
17
+ tables.hmtx = hmtx;
18
+ tables.maxp = maxp;
19
+ tables.name = name;
20
+ tables['OS/2'] = OS2;
21
+ tables.post = post;
22
+
23
+
24
+ // TrueType Outlines
25
+ import cvt from './cvt';
26
+ import fpgm from './fpgm';
27
+ import loca from './loca';
28
+ import prep from './prep';
29
+ import glyf from './glyf';
30
+
31
+ tables.fpgm = fpgm;
32
+ tables.loca = loca;
33
+ tables.prep = prep;
34
+ tables['cvt '] = cvt;
35
+ tables.glyf = glyf;
36
+
37
+
38
+ // PostScript Outlines
39
+ import CFFFont from '../cff/CFFFont';
40
+ import VORG from './VORG';
41
+
42
+ tables['CFF '] = CFFFont;
43
+ tables['CFF2'] = CFFFont;
44
+ tables.VORG = VORG;
45
+
46
+
47
+ // Bitmap Glyphs
48
+ import EBLC from './EBLC';
49
+ import sbix from './sbix';
50
+ import COLR from './COLR';
51
+ import CPAL from './CPAL';
52
+
53
+ tables.EBLC = EBLC;
54
+ tables.CBLC = tables.EBLC;
55
+ tables.sbix = sbix;
56
+ tables.COLR = COLR;
57
+ tables.CPAL = CPAL;
58
+
59
+
60
+ // Advanced OpenType Tables
61
+ import BASE from './BASE';
62
+ import GDEF from './GDEF';
63
+ import GPOS from './GPOS';
64
+ import GSUB from './GSUB';
65
+ import JSTF from './JSTF';
66
+
67
+ tables.BASE = BASE;
68
+ tables.GDEF = GDEF;
69
+ tables.GPOS = GPOS;
70
+ tables.GSUB = GSUB;
71
+ tables.JSTF = JSTF;
72
+
73
+ // OpenType variations tables
74
+ import HVAR from './HVAR';
75
+
76
+ tables.HVAR = HVAR;
77
+
78
+ // Other OpenType Tables
79
+ import DSIG from './DSIG';
80
+ import gasp from './gasp';
81
+ import hdmx from './hdmx';
82
+ import kern from './kern';
83
+ import LTSH from './LTSH';
84
+ import STAT from './STAT';
85
+ import PCLT from './PCLT';
86
+ import VDMX from './VDMX';
87
+ import vhea from './vhea';
88
+ import vmtx from './vmtx';
89
+
90
+ tables.DSIG = DSIG;
91
+ tables.gasp = gasp;
92
+ tables.hdmx = hdmx;
93
+ tables.kern = kern;
94
+ tables.LTSH = LTSH;
95
+ tables.STAT = STAT;
96
+ tables.PCLT = PCLT;
97
+ tables.VDMX = VDMX;
98
+ tables.vhea = vhea;
99
+ tables.vmtx = vmtx;
100
+
101
+
102
+ // Apple Advanced Typography Tables
103
+ import avar from './avar';
104
+ import bsln from './bsln';
105
+ import feat from './feat';
106
+ import fvar from './fvar';
107
+ import gvar from './gvar';
108
+ import just from './just';
109
+ import morx from './morx';
110
+ import opbd from './opbd';
111
+
112
+ tables.avar = avar;
113
+ tables.bsln = bsln;
114
+ tables.feat = feat;
115
+ tables.fvar = fvar;
116
+ tables.gvar = gvar;
117
+ tables.just = just;
118
+ tables.morx = morx;
119
+ tables.opbd = opbd;
@@ -0,0 +1,81 @@
1
+ import * as r from 'restructure';
2
+ import { LookupTable, StateTable1 } from './aat';
3
+
4
+ let ClassTable = new r.Struct({
5
+ length: r.uint16,
6
+ coverage: r.uint16,
7
+ subFeatureFlags: r.uint32,
8
+ stateTable: new StateTable1
9
+ });
10
+
11
+ let WidthDeltaRecord = new r.Struct({
12
+ justClass: r.uint32,
13
+ beforeGrowLimit: r.fixed32,
14
+ beforeShrinkLimit: r.fixed32,
15
+ afterGrowLimit: r.fixed32,
16
+ afterShrinkLimit: r.fixed32,
17
+ growFlags: r.uint16,
18
+ shrinkFlags: r.uint16
19
+ });
20
+
21
+ let WidthDeltaCluster = new r.Array(WidthDeltaRecord, r.uint32);
22
+
23
+ let ActionData = new r.VersionedStruct('actionType', {
24
+ 0: { // Decomposition action
25
+ lowerLimit: r.fixed32,
26
+ upperLimit: r.fixed32,
27
+ order: r.uint16,
28
+ glyphs: new r.Array(r.uint16, r.uint16)
29
+ },
30
+
31
+ 1: { // Unconditional add glyph action
32
+ addGlyph: r.uint16
33
+ },
34
+
35
+ 2: { // Conditional add glyph action
36
+ substThreshold: r.fixed32,
37
+ addGlyph: r.uint16,
38
+ substGlyph: r.uint16
39
+ },
40
+
41
+ 3: {}, // Stretch glyph action (no data, not supported by CoreText)
42
+
43
+ 4: { // Ductile glyph action (not supported by CoreText)
44
+ variationAxis: r.uint32,
45
+ minimumLimit: r.fixed32,
46
+ noStretchValue: r.fixed32,
47
+ maximumLimit: r.fixed32
48
+ },
49
+
50
+ 5: { // Repeated add glyph action
51
+ flags: r.uint16,
52
+ glyph: r.uint16
53
+ }
54
+ });
55
+
56
+ let Action = new r.Struct({
57
+ actionClass: r.uint16,
58
+ actionType: r.uint16,
59
+ actionLength: r.uint32,
60
+ actionData: ActionData,
61
+ padding: new r.Reserved(r.uint8, t => t.actionLength - t._currentOffset)
62
+ });
63
+
64
+ let PostcompensationAction = new r.Array(Action, r.uint32);
65
+ let PostCompensationTable = new r.Struct({
66
+ lookupTable: new LookupTable(new r.Pointer(r.uint16, PostcompensationAction))
67
+ });
68
+
69
+ let JustificationTable = new r.Struct({
70
+ classTable: new r.Pointer(r.uint16, ClassTable, { type: 'parent' }),
71
+ wdcOffset: r.uint16,
72
+ postCompensationTable: new r.Pointer(r.uint16, PostCompensationTable, { type: 'parent' }),
73
+ widthDeltaClusters: new LookupTable(new r.Pointer(r.uint16, WidthDeltaCluster, { type: 'parent', relativeTo: ctx => ctx.wdcOffset }))
74
+ });
75
+
76
+ export default new r.Struct({
77
+ version: r.uint32,
78
+ format: r.uint16,
79
+ horizontal: new r.Pointer(r.uint16, JustificationTable),
80
+ vertical: new r.Pointer(r.uint16, JustificationTable)
81
+ });
@@ -0,0 +1,91 @@
1
+ import * as r from 'restructure';
2
+
3
+ let KernPair = new r.Struct({
4
+ left: r.uint16,
5
+ right: r.uint16,
6
+ value: r.int16
7
+ });
8
+
9
+ let ClassTable = new r.Struct({
10
+ firstGlyph: r.uint16,
11
+ nGlyphs: r.uint16,
12
+ offsets: new r.Array(r.uint16, 'nGlyphs'),
13
+ max: t => t.offsets.length && Math.max.apply(Math, t.offsets)
14
+ });
15
+
16
+ let Kern2Array = new r.Struct({
17
+ off: t => t._startOffset - t.parent.parent._startOffset,
18
+ len: t => (((t.parent.leftTable.max - t.off) / t.parent.rowWidth) + 1) * (t.parent.rowWidth / 2),
19
+ values: new r.LazyArray(r.int16, 'len')
20
+ });
21
+
22
+ let KernSubtable = new r.VersionedStruct('format', {
23
+ 0: {
24
+ nPairs: r.uint16,
25
+ searchRange: r.uint16,
26
+ entrySelector: r.uint16,
27
+ rangeShift: r.uint16,
28
+ pairs: new r.Array(KernPair, 'nPairs')
29
+ },
30
+
31
+ 2: {
32
+ rowWidth: r.uint16,
33
+ leftTable: new r.Pointer(r.uint16, ClassTable, {type: 'parent'}),
34
+ rightTable: new r.Pointer(r.uint16, ClassTable, {type: 'parent'}),
35
+ array: new r.Pointer(r.uint16, Kern2Array, {type: 'parent'})
36
+ },
37
+
38
+ 3: {
39
+ glyphCount: r.uint16,
40
+ kernValueCount: r.uint8,
41
+ leftClassCount: r.uint8,
42
+ rightClassCount: r.uint8,
43
+ flags: r.uint8,
44
+ kernValue: new r.Array(r.int16, 'kernValueCount'),
45
+ leftClass: new r.Array(r.uint8, 'glyphCount'),
46
+ rightClass: new r.Array(r.uint8, 'glyphCount'),
47
+ kernIndex: new r.Array(r.uint8, t => t.leftClassCount * t.rightClassCount)
48
+ }
49
+ });
50
+
51
+ let KernTable = new r.VersionedStruct('version', {
52
+ 0: { // Microsoft uses this format
53
+ subVersion: r.uint16, // Microsoft has an extra sub-table version number
54
+ length: r.uint16, // Length of the subtable, in bytes
55
+ format: r.uint8, // Format of subtable
56
+ coverage: new r.Bitfield(r.uint8, [
57
+ 'horizontal', // 1 if table has horizontal data, 0 if vertical
58
+ 'minimum', // If set to 1, the table has minimum values. If set to 0, the table has kerning values.
59
+ 'crossStream', // If set to 1, kerning is perpendicular to the flow of the text
60
+ 'override' // If set to 1 the value in this table replaces the accumulated value
61
+ ]),
62
+ subtable: KernSubtable,
63
+ padding: new r.Reserved(r.uint8, t => t.length - t._currentOffset)
64
+ },
65
+ 1: { // Apple uses this format
66
+ length: r.uint32,
67
+ coverage: new r.Bitfield(r.uint8, [
68
+ null, null, null, null, null,
69
+ 'variation', // Set if table has variation kerning values
70
+ 'crossStream', // Set if table has cross-stream kerning values
71
+ 'vertical' // Set if table has vertical kerning values
72
+ ]),
73
+ format: r.uint8,
74
+ tupleIndex: r.uint16,
75
+ subtable: KernSubtable,
76
+ padding: new r.Reserved(r.uint8, t => t.length - t._currentOffset)
77
+ }
78
+ });
79
+
80
+ export default new r.VersionedStruct(r.uint16, {
81
+ 0: { // Microsoft Version
82
+ nTables: r.uint16,
83
+ tables: new r.Array(KernTable, 'nTables')
84
+ },
85
+
86
+ 1: { // Apple Version
87
+ reserved: new r.Reserved(r.uint16), // the other half of the version number
88
+ nTables: r.uint32,
89
+ tables: new r.Array(KernTable, 'nTables')
90
+ }
91
+ });
@@ -0,0 +1,30 @@
1
+ import * as r from 'restructure';
2
+
3
+ let loca = new r.VersionedStruct('head.indexToLocFormat', {
4
+ 0: {
5
+ offsets: new r.Array(r.uint16)
6
+ },
7
+ 1: {
8
+ offsets: new r.Array(r.uint32)
9
+ }
10
+ });
11
+
12
+ loca.process = function() {
13
+ if (this.version === 0 && !this._processed) {
14
+ for (let i = 0; i < this.offsets.length; i++) {
15
+ this.offsets[i] <<= 1;
16
+ }
17
+ this._processed = true;
18
+ }
19
+ };
20
+
21
+ loca.preEncode = function() {
22
+ if (this.version === 0 && this._processed !== false) {
23
+ for (let i = 0; i < this.offsets.length; i++) {
24
+ this.offsets[i] >>>= 1;
25
+ }
26
+ this._processed = false;
27
+ }
28
+ };
29
+
30
+ export default loca;
@@ -0,0 +1,20 @@
1
+ import * as r from 'restructure';
2
+
3
+ // maxiumum profile
4
+ export default new r.Struct({
5
+ version: r.int32,
6
+ numGlyphs: r.uint16, // The number of glyphs in the font
7
+ maxPoints: r.uint16, // Maximum points in a non-composite glyph
8
+ maxContours: r.uint16, // Maximum contours in a non-composite glyph
9
+ maxComponentPoints: r.uint16, // Maximum points in a composite glyph
10
+ maxComponentContours: r.uint16, // Maximum contours in a composite glyph
11
+ maxZones: r.uint16, // 1 if instructions do not use the twilight zone, 2 otherwise
12
+ maxTwilightPoints: r.uint16, // Maximum points used in Z0
13
+ maxStorage: r.uint16, // Number of Storage Area locations
14
+ maxFunctionDefs: r.uint16, // Number of FDEFs
15
+ maxInstructionDefs: r.uint16, // Number of IDEFs
16
+ maxStackElements: r.uint16, // Maximum stack depth
17
+ maxSizeOfInstructions: r.uint16, // Maximum byte count for glyph instructions
18
+ maxComponentElements: r.uint16, // Maximum number of components referenced at “top level” for any composite glyph
19
+ maxComponentDepth: r.uint16 // Maximum levels of recursion; 1 for simple components
20
+ });
@@ -0,0 +1,79 @@
1
+ import * as r from 'restructure';
2
+ import { UnboundedArray, LookupTable, StateTable } from './aat';
3
+
4
+ let LigatureData = {
5
+ action: r.uint16
6
+ };
7
+
8
+ let ContextualData = {
9
+ markIndex: r.uint16,
10
+ currentIndex: r.uint16
11
+ };
12
+
13
+ let InsertionData = {
14
+ currentInsertIndex: r.uint16,
15
+ markedInsertIndex: r.uint16
16
+ };
17
+
18
+ let SubstitutionTable = new r.Struct({
19
+ items: new UnboundedArray(new r.Pointer(r.uint32, new LookupTable))
20
+ });
21
+
22
+ let SubtableData = new r.VersionedStruct('type', {
23
+ 0: { // Indic Rearrangement Subtable
24
+ stateTable: new StateTable
25
+ },
26
+
27
+ 1: { // Contextual Glyph Substitution Subtable
28
+ stateTable: new StateTable(ContextualData),
29
+ substitutionTable: new r.Pointer(r.uint32, SubstitutionTable)
30
+ },
31
+
32
+ 2: { // Ligature subtable
33
+ stateTable: new StateTable(LigatureData),
34
+ ligatureActions: new r.Pointer(r.uint32, new UnboundedArray(r.uint32)),
35
+ components: new r.Pointer(r.uint32, new UnboundedArray(r.uint16)),
36
+ ligatureList: new r.Pointer(r.uint32, new UnboundedArray(r.uint16))
37
+ },
38
+
39
+ 4: { // Non-contextual Glyph Substitution Subtable
40
+ lookupTable: new LookupTable
41
+ },
42
+
43
+ 5: { // Glyph Insertion Subtable
44
+ stateTable: new StateTable(InsertionData),
45
+ insertionActions: new r.Pointer(r.uint32, new UnboundedArray(r.uint16))
46
+ }
47
+ });
48
+
49
+ let Subtable = new r.Struct({
50
+ length: r.uint32,
51
+ coverage: r.uint24,
52
+ type: r.uint8,
53
+ subFeatureFlags: r.uint32,
54
+ table: SubtableData,
55
+ padding: new r.Reserved(r.uint8, t => t.length - t._currentOffset)
56
+ });
57
+
58
+ let FeatureEntry = new r.Struct({
59
+ featureType: r.uint16,
60
+ featureSetting: r.uint16,
61
+ enableFlags: r.uint32,
62
+ disableFlags: r.uint32
63
+ });
64
+
65
+ let MorxChain = new r.Struct({
66
+ defaultFlags: r.uint32,
67
+ chainLength: r.uint32,
68
+ nFeatureEntries: r.uint32,
69
+ nSubtables: r.uint32,
70
+ features: new r.Array(FeatureEntry, 'nFeatureEntries'),
71
+ subtables: new r.Array(Subtable, 'nSubtables')
72
+ });
73
+
74
+ export default new r.Struct({
75
+ version: r.uint16,
76
+ unused: new r.Reserved(r.uint16),
77
+ nChains: r.uint32,
78
+ chains: new r.Array(MorxChain, 'nChains')
79
+ });
@@ -0,0 +1,157 @@
1
+ import * as r from 'restructure';
2
+ import {getEncoding, LANGUAGES} from '../encodings';
3
+
4
+ let NameRecord = new r.Struct({
5
+ platformID: r.uint16,
6
+ encodingID: r.uint16,
7
+ languageID: r.uint16,
8
+ nameID: r.uint16,
9
+ length: r.uint16,
10
+ string: new r.Pointer(r.uint16,
11
+ new r.String('length', t => getEncoding(t.platformID, t.encodingID, t.languageID)),
12
+ { type: 'parent', relativeTo: ctx => ctx.parent.stringOffset, allowNull: false }
13
+ )
14
+ });
15
+
16
+ let LangTagRecord = new r.Struct({
17
+ length: r.uint16,
18
+ tag: new r.Pointer(r.uint16, new r.String('length', 'utf16be'), {type: 'parent', relativeTo: ctx => ctx.stringOffset})
19
+ });
20
+
21
+ var NameTable = new r.VersionedStruct(r.uint16, {
22
+ 0: {
23
+ count: r.uint16,
24
+ stringOffset: r.uint16,
25
+ records: new r.Array(NameRecord, 'count')
26
+ },
27
+ 1: {
28
+ count: r.uint16,
29
+ stringOffset: r.uint16,
30
+ records: new r.Array(NameRecord, 'count'),
31
+ langTagCount: r.uint16,
32
+ langTags: new r.Array(LangTagRecord, 'langTagCount')
33
+ }
34
+ });
35
+
36
+ export default NameTable;
37
+
38
+ const NAMES = [
39
+ 'copyright',
40
+ 'fontFamily',
41
+ 'fontSubfamily',
42
+ 'uniqueSubfamily',
43
+ 'fullName',
44
+ 'version',
45
+ 'postscriptName', // Note: A font may have only one PostScript name and that name must be ASCII.
46
+ 'trademark',
47
+ 'manufacturer',
48
+ 'designer',
49
+ 'description',
50
+ 'vendorURL',
51
+ 'designerURL',
52
+ 'license',
53
+ 'licenseURL',
54
+ null, // reserved (nameID 15)
55
+ 'preferredFamily',
56
+ 'preferredSubfamily',
57
+ 'compatibleFull',
58
+ 'sampleText',
59
+ 'postscriptCIDFontName',
60
+ 'wwsFamilyName',
61
+ 'wwsSubfamilyName',
62
+ 'lightBackgroundPalette',
63
+ 'darkBackgroundPalette',
64
+ 'variationsPostScriptNamePrefix',
65
+ ];
66
+
67
+ function pushEnRecord(out, nameID, string) {
68
+ if (typeof string !== 'string') return;
69
+
70
+ out.push({
71
+ platformID: 3,
72
+ encodingID: 1,
73
+ languageID: 0x409,
74
+ nameID,
75
+ length: string.length * 2,
76
+ string
77
+ });
78
+ }
79
+
80
+ NameTable.process = function(_stream) {
81
+ let records = {fontFeatures: {}};
82
+
83
+ for (let record of this.records) {
84
+ let language = LANGUAGES[record.platformID][record.languageID];
85
+
86
+ if (language == null && this.langTags != null && record.languageID >= 0x8000) {
87
+ language = this.langTags[record.languageID - 0x8000].tag;
88
+ }
89
+
90
+ if (language == null) {
91
+ language = record.platformID + '-' + record.languageID;
92
+ }
93
+
94
+ // Single store keyed by nameID (feat/fvar look up fontFeatures[id]).
95
+ let byId = records.fontFeatures[record.nameID] || (records.fontFeatures[record.nameID] = {});
96
+ if (typeof record.string === 'string' || typeof byId[language] !== 'string') {
97
+ byId[language] = record.string;
98
+ }
99
+
100
+ // Alias standard / reserved IDs onto friendly keys (same object).
101
+ if (record.nameID >= 256) continue;
102
+
103
+ let name = NAMES[record.nameID];
104
+ if (name) {
105
+ records[name] = byId;
106
+ } else {
107
+ if (records.reservedNameID == null) records.reservedNameID = {};
108
+ records.reservedNameID[record.nameID] = byId;
109
+ }
110
+ }
111
+
112
+ this.records = records;
113
+ };
114
+
115
+ NameTable.preEncode = function() {
116
+ if (Array.isArray(this.records)) return;
117
+ this.version = 0;
118
+
119
+ let records = [];
120
+ for (let key in this.records) {
121
+ let val = this.records[key];
122
+
123
+ if (key === 'fontFeatures') {
124
+ // Mirrors of IDs < 256 are encoded via named/reserved keys above.
125
+ for (let id in val) {
126
+ if (+id >= 256) pushEnRecord(records, +id, val[id].en);
127
+ }
128
+ continue;
129
+ }
130
+
131
+ if (key === 'reservedNameID') {
132
+ for (let id in val) pushEnRecord(records, +id, val[id].en);
133
+ continue;
134
+ }
135
+
136
+ let nameID = NAMES.indexOf(key);
137
+ if (nameID < 0) continue;
138
+
139
+ pushEnRecord(records, nameID, val.en);
140
+
141
+ // Match historical behaviour: also write PostScript name for Mac platform.
142
+ if (key === 'postscriptName' && typeof val.en === 'string') {
143
+ records.push({
144
+ platformID: 1,
145
+ encodingID: 0,
146
+ languageID: 0,
147
+ nameID,
148
+ length: val.en.length,
149
+ string: val.en
150
+ });
151
+ }
152
+ }
153
+
154
+ this.records = records;
155
+ this.count = records.length;
156
+ this.stringOffset = NameTable.size(this, null, false);
157
+ };
@@ -0,0 +1,15 @@
1
+ import * as r from 'restructure';
2
+ import { LookupTable } from './aat';
3
+
4
+ let OpticalBounds = new r.Struct({
5
+ left: r.int16,
6
+ top: r.int16,
7
+ right: r.int16,
8
+ bottom: r.int16
9
+ });
10
+
11
+ export default new r.Struct({
12
+ version: r.fixed32,
13
+ format: r.uint16,
14
+ lookupTable: new LookupTable(OpticalBounds)
15
+ });