@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,14 @@
1
+ import * as r from 'restructure';
2
+
3
+ let VerticalOrigin = new r.Struct({
4
+ glyphIndex: r.uint16,
5
+ vertOriginY: r.int16
6
+ });
7
+
8
+ export default new r.Struct({
9
+ majorVersion: r.uint16,
10
+ minorVersion: r.uint16,
11
+ defaultVertOriginY: r.int16,
12
+ numVertOriginYMetrics: r.uint16,
13
+ metrics: new r.Array(VerticalOrigin, 'numVertOriginYMetrics')
14
+ });
@@ -0,0 +1,73 @@
1
+ import * as r from 'restructure';
2
+
3
+ const Base128 = {
4
+ decode(stream) {
5
+ let result = 0;
6
+ let iterable = [0, 1, 2, 3, 4];
7
+ for (let j = 0; j < iterable.length; j++) {
8
+ let code = stream.readUInt8();
9
+
10
+ // If any of the top seven bits are set then we're about to overflow.
11
+ if (result & 0xe0000000) {
12
+ throw new Error('Overflow');
13
+ }
14
+
15
+ result = (result << 7) | (code & 0x7f);
16
+ if ((code & 0x80) === 0) {
17
+ return result;
18
+ }
19
+ }
20
+
21
+ throw new Error('Bad base 128 number');
22
+ }
23
+ };
24
+
25
+ let knownTags = [
26
+ 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 'name', 'OS/2', 'post', 'cvt ',
27
+ 'fpgm', 'glyf', 'loca', 'prep', 'CFF ', 'VORG', 'EBDT', 'EBLC', 'gasp',
28
+ 'hdmx', 'kern', 'LTSH', 'PCLT', 'VDMX', 'vhea', 'vmtx', 'BASE', 'GDEF',
29
+ 'GPOS', 'GSUB', 'EBSC', 'JSTF', 'MATH', 'CBDT', 'CBLC', 'COLR', 'CPAL',
30
+ 'SVG ', 'sbix', 'acnt', 'avar', 'bdat', 'bloc', 'bsln', 'cvar', 'fdsc',
31
+ 'feat', 'fmtx', 'fvar', 'gvar', 'hsty', 'just', 'lcar', 'mort', 'morx',
32
+ 'opbd', 'prop', 'trak', 'Zapf', 'Silf', 'Glat', 'Gloc', 'Feat', 'Sill'
33
+ ];
34
+
35
+ let WOFF2DirectoryEntry = new r.Struct({
36
+ flags: r.uint8,
37
+ customTag: new r.Optional(new r.String(4), t => (t.flags & 0x3f) === 0x3f),
38
+ tag: t => t.customTag || knownTags[t.flags & 0x3f],// || (() => { throw new Error(`Bad tag: ${flags & 0x3f}`); })(); },
39
+ length: Base128,
40
+ transformVersion: t => (t.flags >>> 6) & 0x03,
41
+ transformed: t => (t.tag === 'glyf' || t.tag === 'loca') ? t.transformVersion === 0 : t.transformVersion !== 0,
42
+ transformLength: new r.Optional(Base128, t => t.transformed)
43
+ });
44
+
45
+ let WOFF2Directory = new r.Struct({
46
+ tag: new r.String(4), // should be 'wOF2'
47
+ flavor: r.uint32,
48
+ length: r.uint32,
49
+ numTables: r.uint16,
50
+ reserved: new r.Reserved(r.uint16),
51
+ totalSfntSize: r.uint32,
52
+ totalCompressedSize: r.uint32,
53
+ majorVersion: r.uint16,
54
+ minorVersion: r.uint16,
55
+ metaOffset: r.uint32,
56
+ metaLength: r.uint32,
57
+ metaOrigLength: r.uint32,
58
+ privOffset: r.uint32,
59
+ privLength: r.uint32,
60
+ tables: new r.Array(WOFF2DirectoryEntry, 'numTables')
61
+ });
62
+
63
+ WOFF2Directory.process = function() {
64
+ let tables = {};
65
+ for (let i = 0; i < this.tables.length; i++) {
66
+ let table = this.tables[i];
67
+ tables[table.tag] = table;
68
+ }
69
+
70
+ return this.tables = tables;
71
+ };
72
+
73
+ export default WOFF2Directory;
@@ -0,0 +1,37 @@
1
+ import * as r from 'restructure';
2
+
3
+ let WOFFDirectoryEntry = new r.Struct({
4
+ tag: new r.String(4),
5
+ offset: new r.Pointer(r.uint32, 'void', {type: 'global'}),
6
+ compLength: r.uint32,
7
+ length: r.uint32,
8
+ origChecksum: r.uint32
9
+ });
10
+
11
+ let WOFFDirectory = new r.Struct({
12
+ tag: new r.String(4), // should be 'wOFF'
13
+ flavor: r.uint32,
14
+ length: r.uint32,
15
+ numTables: r.uint16,
16
+ reserved: new r.Reserved(r.uint16),
17
+ totalSfntSize: r.uint32,
18
+ majorVersion: r.uint16,
19
+ minorVersion: r.uint16,
20
+ metaOffset: r.uint32,
21
+ metaLength: r.uint32,
22
+ metaOrigLength: r.uint32,
23
+ privOffset: r.uint32,
24
+ privLength: r.uint32,
25
+ tables: new r.Array(WOFFDirectoryEntry, 'numTables')
26
+ });
27
+
28
+ WOFFDirectory.process = function() {
29
+ let tables = {};
30
+ for (let table of this.tables) {
31
+ tables[table.tag] = table;
32
+ }
33
+
34
+ this.tables = tables;
35
+ };
36
+
37
+ export default WOFFDirectory;
@@ -0,0 +1,157 @@
1
+ import * as r from 'restructure';
2
+
3
+ class UnboundedArrayAccessor {
4
+ constructor(type, stream, parent) {
5
+ this.type = type;
6
+ this.stream = stream;
7
+ this.parent = parent;
8
+ this.base = this.stream.pos;
9
+ this._items = [];
10
+ }
11
+
12
+ getItem(index) {
13
+ if (this._items[index] == null) {
14
+ let pos = this.stream.pos;
15
+ this.stream.pos = this.base + this.type.size(null, this.parent) * index;
16
+ this._items[index] = this.type.decode(this.stream, this.parent);
17
+ this.stream.pos = pos;
18
+ }
19
+
20
+ return this._items[index];
21
+ }
22
+
23
+ inspect() {
24
+ return `[UnboundedArray ${this.type.constructor.name}]`;
25
+ }
26
+ }
27
+
28
+ export class UnboundedArray extends r.Array {
29
+ constructor(type) {
30
+ super(type, 0);
31
+ }
32
+
33
+ decode(stream, parent) {
34
+ return new UnboundedArrayAccessor(this.type, stream, parent);
35
+ }
36
+ }
37
+
38
+ export let LookupTable = function(ValueType = r.uint16) {
39
+ // Helper class that makes internal structures invisible to pointers
40
+ class Shadow {
41
+ constructor(type) {
42
+ this.type = type;
43
+ }
44
+
45
+ decode(stream, ctx) {
46
+ ctx = ctx.parent.parent;
47
+ return this.type.decode(stream, ctx);
48
+ }
49
+
50
+ size(val, ctx) {
51
+ ctx = ctx.parent.parent;
52
+ return this.type.size(val, ctx);
53
+ }
54
+
55
+ encode(stream, val, ctx) {
56
+ ctx = ctx.parent.parent;
57
+ return this.type.encode(stream, val, ctx);
58
+ }
59
+ }
60
+
61
+ ValueType = new Shadow(ValueType);
62
+
63
+ let BinarySearchHeader = new r.Struct({
64
+ unitSize: r.uint16,
65
+ nUnits: r.uint16,
66
+ searchRange: r.uint16,
67
+ entrySelector: r.uint16,
68
+ rangeShift: r.uint16
69
+ });
70
+
71
+ let LookupSegmentSingle = new r.Struct({
72
+ lastGlyph: r.uint16,
73
+ firstGlyph: r.uint16,
74
+ value: ValueType
75
+ });
76
+
77
+ let LookupSegmentArray = new r.Struct({
78
+ lastGlyph: r.uint16,
79
+ firstGlyph: r.uint16,
80
+ values: new r.Pointer(r.uint16, new r.Array(ValueType, t => t.lastGlyph - t.firstGlyph + 1), {type: 'parent'})
81
+ });
82
+
83
+ let LookupSingle = new r.Struct({
84
+ glyph: r.uint16,
85
+ value: ValueType
86
+ });
87
+
88
+ return new r.VersionedStruct(r.uint16, {
89
+ 0: {
90
+ values: new UnboundedArray(ValueType) // length == number of glyphs maybe?
91
+ },
92
+ 2: {
93
+ binarySearchHeader: BinarySearchHeader,
94
+ segments: new r.Array(LookupSegmentSingle, t => t.binarySearchHeader.nUnits)
95
+ },
96
+ 4: {
97
+ binarySearchHeader: BinarySearchHeader,
98
+ segments: new r.Array(LookupSegmentArray, t => t.binarySearchHeader.nUnits)
99
+ },
100
+ 6: {
101
+ binarySearchHeader: BinarySearchHeader,
102
+ segments: new r.Array(LookupSingle, t => t.binarySearchHeader.nUnits)
103
+ },
104
+ 8: {
105
+ firstGlyph: r.uint16,
106
+ count: r.uint16,
107
+ values: new r.Array(ValueType, 'count')
108
+ }
109
+ });
110
+ };
111
+
112
+ export function StateTable(entryData = {}, lookupType = r.uint16) {
113
+ let entry = Object.assign({
114
+ newState: r.uint16,
115
+ flags: r.uint16
116
+ }, entryData);
117
+
118
+ let Entry = new r.Struct(entry);
119
+ let StateArray = new UnboundedArray(new r.Array(r.uint16, t => t.nClasses));
120
+
121
+ let StateHeader = new r.Struct({
122
+ nClasses: r.uint32,
123
+ classTable: new r.Pointer(r.uint32, new LookupTable(lookupType)),
124
+ stateArray: new r.Pointer(r.uint32, StateArray),
125
+ entryTable: new r.Pointer(r.uint32, new UnboundedArray(Entry))
126
+ });
127
+
128
+ return StateHeader;
129
+ }
130
+
131
+ // This is the old version of the StateTable structure
132
+ export function StateTable1(entryData = {}, _lookupType = r.uint16) {
133
+ let ClassLookupTable = new r.Struct({
134
+ version() { return 8; }, // simulate LookupTable
135
+ firstGlyph: r.uint16,
136
+ values: new r.Array(r.uint8, r.uint16)
137
+ });
138
+
139
+ let entry = Object.assign({
140
+ newStateOffset: r.uint16,
141
+ // convert offset to stateArray index
142
+ newState: t => (t.newStateOffset - (t.parent.stateArray.base - t.parent._startOffset)) / t.parent.nClasses,
143
+ flags: r.uint16
144
+ }, entryData);
145
+
146
+ let Entry = new r.Struct(entry);
147
+ let StateArray = new UnboundedArray(new r.Array(r.uint8, t => t.nClasses));
148
+
149
+ let StateHeader1 = new r.Struct({
150
+ nClasses: r.uint16,
151
+ classTable: new r.Pointer(r.uint16, ClassLookupTable),
152
+ stateArray: new r.Pointer(r.uint16, StateArray),
153
+ entryTable: new r.Pointer(r.uint16, new UnboundedArray(Entry))
154
+ });
155
+
156
+ return StateHeader1;
157
+ }
@@ -0,0 +1,19 @@
1
+ import * as r from 'restructure';
2
+
3
+ let shortFrac = new r.Fixed(16, 'BE', 14);
4
+
5
+ let Correspondence = new r.Struct({
6
+ fromCoord: shortFrac,
7
+ toCoord: shortFrac
8
+ });
9
+
10
+ let Segment = new r.Struct({
11
+ pairCount: r.uint16,
12
+ correspondence: new r.Array(Correspondence, 'pairCount')
13
+ });
14
+
15
+ export default new r.Struct({
16
+ version: r.fixed32,
17
+ axisCount: r.uint32,
18
+ segment: new r.Array(Segment, 'axisCount')
19
+ });
@@ -0,0 +1,31 @@
1
+ import * as r from 'restructure';
2
+ import { LookupTable } from './aat';
3
+
4
+ let BslnSubtable = new r.VersionedStruct('format', {
5
+ 0: { // Distance-based, no mapping
6
+ deltas: new r.Array(r.int16, 32)
7
+ },
8
+
9
+ 1: { // Distance-based, with mapping
10
+ deltas: new r.Array(r.int16, 32),
11
+ mappingData: new LookupTable(r.uint16)
12
+ },
13
+
14
+ 2: { // Control point-based, no mapping
15
+ standardGlyph: r.uint16,
16
+ controlPoints: new r.Array(r.uint16, 32)
17
+ },
18
+
19
+ 3: { // Control point-based, with mapping
20
+ standardGlyph: r.uint16,
21
+ controlPoints: new r.Array(r.uint16, 32),
22
+ mappingData: new LookupTable(r.uint16)
23
+ }
24
+ });
25
+
26
+ export default new r.Struct({
27
+ version: r.fixed32,
28
+ format: r.uint16,
29
+ defaultBaseline: r.uint16,
30
+ subtable: BslnSubtable
31
+ });
@@ -0,0 +1,127 @@
1
+ import * as r from 'restructure';
2
+
3
+ let SubHeader = new r.Struct({
4
+ firstCode: r.uint16,
5
+ entryCount: r.uint16,
6
+ idDelta: r.int16,
7
+ idRangeOffset: r.uint16
8
+ });
9
+
10
+ let CmapGroup = new r.Struct({
11
+ startCharCode: r.uint32,
12
+ endCharCode: r.uint32,
13
+ glyphID: r.uint32
14
+ });
15
+
16
+ let UnicodeValueRange = new r.Struct({
17
+ startUnicodeValue: r.uint24,
18
+ additionalCount: r.uint8
19
+ });
20
+
21
+ let UVSMapping = new r.Struct({
22
+ unicodeValue: r.uint24,
23
+ glyphID: r.uint16
24
+ });
25
+
26
+ let DefaultUVS = new r.Array(UnicodeValueRange, r.uint32);
27
+ let NonDefaultUVS = new r.Array(UVSMapping, r.uint32);
28
+
29
+ let VarSelectorRecord = new r.Struct({
30
+ varSelector: r.uint24,
31
+ defaultUVS: new r.Pointer(r.uint32, DefaultUVS, {type: 'parent'}),
32
+ nonDefaultUVS: new r.Pointer(r.uint32, NonDefaultUVS, {type: 'parent'})
33
+ });
34
+
35
+ let CmapSubtable = new r.VersionedStruct(r.uint16, {
36
+ 0: { // Byte encoding
37
+ length: r.uint16, // Total table length in bytes (set to 262 for format 0)
38
+ language: r.uint16, // Language code for this encoding subtable, or zero if language-independent
39
+ codeMap: new r.LazyArray(r.uint8, 256)
40
+ },
41
+
42
+ 2: { // High-byte mapping (CJK)
43
+ length: r.uint16,
44
+ language: r.uint16,
45
+ subHeaderKeys: new r.Array(r.uint16, 256),
46
+ subHeaderCount: t => Math.max.apply(Math, t.subHeaderKeys),
47
+ subHeaders: new r.LazyArray(SubHeader, 'subHeaderCount'),
48
+ glyphIndexArray: new r.LazyArray(r.uint16, 'subHeaderCount')
49
+ },
50
+
51
+ 4: { // Segment mapping to delta values
52
+ length: r.uint16, // Total table length in bytes
53
+ language: r.uint16, // Language code
54
+ segCountX2: r.uint16,
55
+ segCount: t => t.segCountX2 >> 1,
56
+ searchRange: r.uint16,
57
+ entrySelector: r.uint16,
58
+ rangeShift: r.uint16,
59
+ endCode: new r.LazyArray(r.uint16, 'segCount'),
60
+ reservedPad: new r.Reserved(r.uint16), // This value should be zero
61
+ startCode: new r.LazyArray(r.uint16, 'segCount'),
62
+ idDelta: new r.LazyArray(r.int16, 'segCount'),
63
+ idRangeOffset: new r.LazyArray(r.uint16, 'segCount'),
64
+ glyphIndexArray: new r.LazyArray(r.uint16, t => (t.length - t._currentOffset) / 2)
65
+ },
66
+
67
+ 6: { // Trimmed table
68
+ length: r.uint16,
69
+ language: r.uint16,
70
+ firstCode: r.uint16,
71
+ entryCount: r.uint16,
72
+ glyphIndices: new r.LazyArray(r.uint16, 'entryCount')
73
+ },
74
+
75
+ 8: { // mixed 16-bit and 32-bit coverage
76
+ reserved: new r.Reserved(r.uint16),
77
+ length: r.uint32,
78
+ language: r.uint16,
79
+ is32: new r.LazyArray(r.uint8, 8192),
80
+ nGroups: r.uint32,
81
+ groups: new r.LazyArray(CmapGroup, 'nGroups')
82
+ },
83
+
84
+ 10: { // Trimmed Array
85
+ reserved: new r.Reserved(r.uint16),
86
+ length: r.uint32,
87
+ language: r.uint32,
88
+ firstCode: r.uint32,
89
+ entryCount: r.uint32,
90
+ glyphIndices: new r.LazyArray(r.uint16, 'numChars')
91
+ },
92
+
93
+ 12: { // Segmented coverage
94
+ reserved: new r.Reserved(r.uint16),
95
+ length: r.uint32,
96
+ language: r.uint32,
97
+ nGroups: r.uint32,
98
+ groups: new r.LazyArray(CmapGroup, 'nGroups')
99
+ },
100
+
101
+ 13: { // Many-to-one range mappings (same as 12 except for group.startGlyphID)
102
+ reserved: new r.Reserved(r.uint16),
103
+ length: r.uint32,
104
+ language: r.uint32,
105
+ nGroups: r.uint32,
106
+ groups: new r.LazyArray(CmapGroup, 'nGroups')
107
+ },
108
+
109
+ 14: { // Unicode Variation Sequences
110
+ length: r.uint32,
111
+ numRecords: r.uint32,
112
+ varSelectors: new r.LazyArray(VarSelectorRecord, 'numRecords')
113
+ }
114
+ });
115
+
116
+ let CmapEntry = new r.Struct({
117
+ platformID: r.uint16, // Platform identifier
118
+ encodingID: r.uint16, // Platform-specific encoding identifier
119
+ table: new r.Pointer(r.uint32, CmapSubtable, {type: 'parent', lazy: true})
120
+ });
121
+
122
+ // character to glyph mapping
123
+ export default new r.Struct({
124
+ version: r.uint16,
125
+ numSubtables: r.uint16,
126
+ tables: new r.Array(CmapEntry, 'numSubtables')
127
+ });
@@ -0,0 +1,6 @@
1
+ import * as r from 'restructure';
2
+
3
+ // An array of predefined values accessible by instructions
4
+ export default new r.Struct({
5
+ controlValues: new r.Array(r.int16)
6
+ });
@@ -0,0 +1,58 @@
1
+ import * as r from 'restructure';
2
+ import Tables from './';
3
+
4
+ let TableEntry = new r.Struct({
5
+ tag: new r.String(4),
6
+ checkSum: r.uint32,
7
+ offset: new r.Pointer(r.uint32, 'void', { type: 'global' }),
8
+ length: r.uint32
9
+ });
10
+
11
+ let Directory = new r.Struct({
12
+ tag: new r.String(4),
13
+ numTables: r.uint16,
14
+ searchRange: r.uint16,
15
+ entrySelector: r.uint16,
16
+ rangeShift: r.uint16,
17
+ tables: new r.Array(TableEntry, 'numTables')
18
+ });
19
+
20
+ Directory.process = function() {
21
+ let tables = {};
22
+ for (let table of this.tables) {
23
+ tables[table.tag] = table;
24
+ }
25
+
26
+ this.tables = tables;
27
+ };
28
+
29
+ Directory.preEncode = function() {
30
+ if (!Array.isArray(this.tables)) {
31
+ let tables = [];
32
+ for (let tag in this.tables) {
33
+ let table = this.tables[tag];
34
+ if (table) {
35
+ tables.push({
36
+ tag: tag,
37
+ checkSum: 0,
38
+ offset: new r.VoidPointer(Tables[tag], table),
39
+ length: Tables[tag].size(table)
40
+ });
41
+ }
42
+ }
43
+
44
+ this.tables = tables;
45
+ }
46
+
47
+ this.tag = 'true';
48
+ this.numTables = this.tables.length;
49
+
50
+ let maxExponentFor2 = Math.floor((Math.log(this.numTables) / Math.LN2));
51
+ let maxPowerOf2 = Math.pow(2, maxExponentFor2);
52
+
53
+ this.searchRange = maxPowerOf2 * 16;
54
+ this.entrySelector = Math.log(maxPowerOf2) / Math.LN2;
55
+ this.rangeShift = this.numTables * 16 - this.searchRange;
56
+ };
57
+
58
+ export default Directory;
@@ -0,0 +1,28 @@
1
+ import * as r from 'restructure';
2
+
3
+ let Setting = new r.Struct({
4
+ setting: r.uint16,
5
+ nameIndex: r.int16,
6
+ name: t => t.parent.parent.parent.name.records.fontFeatures[t.nameIndex]
7
+ });
8
+
9
+ let FeatureName = new r.Struct({
10
+ feature: r.uint16,
11
+ nSettings: r.uint16,
12
+ settingTable: new r.Pointer(r.uint32, new r.Array(Setting, 'nSettings'), { type: 'parent' }),
13
+ featureFlags: new r.Bitfield(r.uint8, [
14
+ null, null, null, null, null, null,
15
+ 'hasDefault', 'exclusive'
16
+ ]),
17
+ defaultSetting: r.uint8,
18
+ nameIndex: r.int16,
19
+ name: t => t.parent.parent.name.records.fontFeatures[t.nameIndex]
20
+ });
21
+
22
+ export default new r.Struct({
23
+ version: r.fixed32,
24
+ featureNameCount: r.uint16,
25
+ reserved1: new r.Reserved(r.uint16),
26
+ reserved2: new r.Reserved(r.uint32),
27
+ featureNames: new r.Array(FeatureName, 'featureNameCount')
28
+ });
@@ -0,0 +1,8 @@
1
+ import * as r from 'restructure';
2
+
3
+ // A list of instructions that are executed once when a font is first used.
4
+ // These instructions are known as the font program. The main use of this table
5
+ // is for the definition of functions that are used in many different glyph programs.
6
+ export default new r.Struct({
7
+ instructions: new r.Array(r.uint8)
8
+ });
@@ -0,0 +1,31 @@
1
+ import * as r from 'restructure';
2
+
3
+ let Axis = new r.Struct({
4
+ axisTag: new r.String(4),
5
+ minValue: r.fixed32,
6
+ defaultValue: r.fixed32,
7
+ maxValue: r.fixed32,
8
+ flags: r.uint16,
9
+ nameID: r.uint16,
10
+ name: t => t.parent.parent.name.records.fontFeatures[t.nameID]
11
+ });
12
+
13
+ let Instance = new r.Struct({
14
+ nameID: r.uint16,
15
+ name: t => t.parent.parent.name.records.fontFeatures[t.nameID],
16
+ flags: r.uint16,
17
+ coord: new r.Array(r.fixed32, t => t.parent.axisCount),
18
+ postscriptNameID: new r.Optional(r.uint16, t => t.parent.instanceSize - t._currentOffset > 0)
19
+ });
20
+
21
+ export default new r.Struct({
22
+ version: r.fixed32,
23
+ offsetToData: r.uint16,
24
+ countSizePairs: r.uint16,
25
+ axisCount: r.uint16,
26
+ axisSize: r.uint16,
27
+ instanceCount: r.uint16,
28
+ instanceSize: r.uint16,
29
+ axis: new r.Array(Axis, 'axisCount'),
30
+ instance: new r.Array(Instance, 'instanceCount')
31
+ });
@@ -0,0 +1,15 @@
1
+ import * as r from 'restructure';
2
+
3
+ let GaspRange = new r.Struct({
4
+ rangeMaxPPEM: r.uint16, // Upper limit of range, in ppem
5
+ rangeGaspBehavior: new r.Bitfield(r.uint16, [ // Flags describing desired rasterizer behavior
6
+ 'grayscale', 'gridfit',
7
+ 'symmetricSmoothing', 'symmetricGridfit' // only in version 1, for ClearType
8
+ ])
9
+ });
10
+
11
+ export default new r.Struct({
12
+ version: r.uint16, // set to 0
13
+ numRanges: r.uint16,
14
+ gaspRanges: new r.Array(GaspRange, 'numRanges') // Sorted by ppem
15
+ });
@@ -0,0 +1,4 @@
1
+ import * as r from 'restructure';
2
+
3
+ // only used for encoding
4
+ export default new r.Array(new r.Buffer);
@@ -0,0 +1,27 @@
1
+ import * as r from 'restructure';
2
+
3
+ let shortFrac = new r.Fixed(16, 'BE', 14);
4
+ class Offset {
5
+ static decode(stream, parent) {
6
+ // In short format, offsets are multiplied by 2.
7
+ // This doesn't seem to be documented by Apple, but it
8
+ // is implemented this way in Freetype.
9
+ return parent.flags
10
+ ? stream.readUInt32BE()
11
+ : stream.readUInt16BE() * 2;
12
+ }
13
+ }
14
+
15
+ let gvar = new r.Struct({
16
+ version: r.uint16,
17
+ reserved: new r.Reserved(r.uint16),
18
+ axisCount: r.uint16,
19
+ globalCoordCount: r.uint16,
20
+ globalCoords: new r.Pointer(r.uint32, new r.Array(new r.Array(shortFrac, 'axisCount'), 'globalCoordCount')),
21
+ glyphCount: r.uint16,
22
+ flags: r.uint16,
23
+ offsetToData: r.uint32,
24
+ offsets: new r.Array(new r.Pointer(Offset, 'void', { relativeTo: ctx => ctx.offsetToData, allowNull: false }), t => t.glyphCount + 1)
25
+ });
26
+
27
+ export default gvar;
@@ -0,0 +1,15 @@
1
+ import * as r from 'restructure';
2
+
3
+ let DeviceRecord = new r.Struct({
4
+ pixelSize: r.uint8,
5
+ maximumWidth: r.uint8,
6
+ widths: new r.Array(r.uint8, t => t.parent.parent.maxp.numGlyphs)
7
+ });
8
+
9
+ // The Horizontal Device Metrics table stores integer advance widths scaled to particular pixel sizes
10
+ export default new r.Struct({
11
+ version: r.uint16,
12
+ numRecords: r.int16,
13
+ sizeDeviceRecord: r.int32,
14
+ records: new r.Array(DeviceRecord, 'numRecords')
15
+ });
@@ -0,0 +1,25 @@
1
+ import * as r from 'restructure';
2
+
3
+ // font header
4
+ export default new r.Struct({
5
+ version: r.int32, // 0x00010000 (version 1.0)
6
+ revision: r.int32, // set by font manufacturer
7
+ checkSumAdjustment: r.uint32,
8
+ magicNumber: r.uint32, // set to 0x5F0F3CF5
9
+ flags: r.uint16,
10
+ unitsPerEm: r.uint16, // range from 64 to 16384
11
+ created: new r.Array(r.int32, 2),
12
+ modified: new r.Array(r.int32, 2),
13
+ xMin: r.int16, // for all glyph bounding boxes
14
+ yMin: r.int16, // for all glyph bounding boxes
15
+ xMax: r.int16, // for all glyph bounding boxes
16
+ yMax: r.int16, // for all glyph bounding boxes
17
+ macStyle: new r.Bitfield(r.uint16, [
18
+ 'bold', 'italic', 'underline', 'outline',
19
+ 'shadow', 'condensed', 'extended'
20
+ ]),
21
+ lowestRecPPEM: r.uint16, // smallest readable size in pixels
22
+ fontDirectionHint: r.int16,
23
+ indexToLocFormat: r.int16, // 0 for short offsets, 1 for long
24
+ glyphDataFormat: r.int16 // 0 for current format
25
+ });