@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,222 @@
1
+ import * as r from 'restructure';
2
+ import brotli from 'brotli/decompress.js';
3
+ import TTFFont from './TTFFont';
4
+ import TTFGlyph, { Point } from './glyph/TTFGlyph';
5
+ import WOFF2Glyph from './glyph/WOFF2Glyph';
6
+ import WOFF2Directory from './tables/WOFF2Directory';
7
+ import { asciiDecoder } from './utils';
8
+
9
+ /**
10
+ * Subclass of TTFFont that represents a TTF/OTF font compressed by WOFF2
11
+ * See spec here: http://www.w3.org/TR/WOFF2/
12
+ */
13
+ export default class WOFF2Font extends TTFFont {
14
+ type = 'WOFF2';
15
+
16
+ static probe(buffer) {
17
+ return asciiDecoder.decode(buffer.slice(0, 4)) === 'wOF2';
18
+ }
19
+
20
+ _decodeDirectory() {
21
+ this.directory = WOFF2Directory.decode(this.stream);
22
+ this._dataPos = this.stream.pos;
23
+ }
24
+
25
+ _decompress() {
26
+ // decompress data and setup table offsets if we haven't already
27
+ if (!this._decompressed) {
28
+ this.stream.pos = this._dataPos;
29
+ let buffer = this.stream.readBuffer(this.directory.totalCompressedSize);
30
+
31
+ let decompressedSize = 0;
32
+ for (let tag in this.directory.tables) {
33
+ let entry = this.directory.tables[tag];
34
+ entry.offset = decompressedSize;
35
+ decompressedSize += (entry.transformLength != null) ? entry.transformLength : entry.length;
36
+ }
37
+
38
+ let decompressed = brotli(buffer, decompressedSize);
39
+ if (!decompressed) {
40
+ throw new Error('Error decoding compressed data in WOFF2');
41
+ }
42
+
43
+ this.stream = new r.DecodeStream(decompressed);
44
+ this._decompressed = true;
45
+ }
46
+ }
47
+
48
+ _decodeTable(table) {
49
+ this._decompress();
50
+ return super._decodeTable(table);
51
+ }
52
+
53
+ // Override this method to get a glyph and return our
54
+ // custom subclass if there is a glyf table.
55
+ _getBaseGlyph(glyph, characters = []) {
56
+ let cached = this._glyphs[glyph];
57
+ if (cached?._getContours) {
58
+ return cached;
59
+ }
60
+
61
+ if (this.directory.tables.glyf && this.directory.tables.glyf.transformed) {
62
+ if (!this._transformedGlyphs) { this._transformGlyfTable(); }
63
+ let outline = new WOFF2Glyph(glyph, characters, this);
64
+ if (!cached) {
65
+ this._glyphs[glyph] = outline;
66
+ }
67
+ return outline;
68
+ }
69
+
70
+ return super._getBaseGlyph(glyph, characters);
71
+ }
72
+
73
+ _transformGlyfTable() {
74
+ this._decompress();
75
+ this.stream.pos = this.directory.tables.glyf.offset;
76
+ let table = GlyfTable.decode(this.stream);
77
+ let glyphs = [];
78
+
79
+ for (let index = 0; index < table.numGlyphs; index++) {
80
+ let glyph = {};
81
+ let nContours = table.nContours.readInt16BE();
82
+ glyph.numberOfContours = nContours;
83
+
84
+ if (nContours > 0) { // simple glyph
85
+ let nPoints = [];
86
+ let totalPoints = 0;
87
+
88
+ for (let i = 0; i < nContours; i++) {
89
+ let r = read255UInt16(table.nPoints);
90
+ totalPoints += r;
91
+ nPoints.push(totalPoints);
92
+ }
93
+
94
+ glyph.points = decodeTriplet(table.flags, table.glyphs, totalPoints);
95
+ for (let i = 0; i < nContours; i++) {
96
+ glyph.points[nPoints[i] - 1].endContour = true;
97
+ }
98
+
99
+ read255UInt16(table.glyphs);
100
+
101
+ } else if (nContours < 0) { // composite glyph
102
+ let haveInstructions = TTFGlyph.prototype._decodeComposite.call({ _font: this }, glyph, table.composites);
103
+ if (haveInstructions) {
104
+ read255UInt16(table.glyphs);
105
+ }
106
+ }
107
+
108
+ glyphs.push(glyph);
109
+ }
110
+
111
+ this._transformedGlyphs = glyphs;
112
+ }
113
+ }
114
+
115
+ // Special class that accepts a length and returns a sub-stream for that data
116
+ class Substream {
117
+ constructor(length) {
118
+ this.length = length;
119
+ this._buf = new r.Buffer(length);
120
+ }
121
+
122
+ decode(stream, parent) {
123
+ return new r.DecodeStream(this._buf.decode(stream, parent));
124
+ }
125
+ }
126
+
127
+ // This struct represents the entire glyf table
128
+ let GlyfTable = new r.Struct({
129
+ version: r.uint32,
130
+ numGlyphs: r.uint16,
131
+ indexFormat: r.uint16,
132
+ nContourStreamSize: r.uint32,
133
+ nPointsStreamSize: r.uint32,
134
+ flagStreamSize: r.uint32,
135
+ glyphStreamSize: r.uint32,
136
+ compositeStreamSize: r.uint32,
137
+ bboxStreamSize: r.uint32,
138
+ instructionStreamSize: r.uint32,
139
+ nContours: new Substream('nContourStreamSize'),
140
+ nPoints: new Substream('nPointsStreamSize'),
141
+ flags: new Substream('flagStreamSize'),
142
+ glyphs: new Substream('glyphStreamSize'),
143
+ composites: new Substream('compositeStreamSize'),
144
+ bboxes: new Substream('bboxStreamSize'),
145
+ instructions: new Substream('instructionStreamSize')
146
+ });
147
+
148
+ const WORD_CODE = 253;
149
+ const ONE_MORE_BYTE_CODE2 = 254;
150
+ const ONE_MORE_BYTE_CODE1 = 255;
151
+ const LOWEST_U_CODE = 253;
152
+
153
+ function read255UInt16(stream) {
154
+ let code = stream.readUInt8();
155
+
156
+ if (code === WORD_CODE) {
157
+ return stream.readUInt16BE();
158
+ }
159
+
160
+ if (code === ONE_MORE_BYTE_CODE1) {
161
+ return stream.readUInt8() + LOWEST_U_CODE;
162
+ }
163
+
164
+ if (code === ONE_MORE_BYTE_CODE2) {
165
+ return stream.readUInt8() + LOWEST_U_CODE * 2;
166
+ }
167
+
168
+ return code;
169
+ }
170
+
171
+ function withSign(flag, baseval) {
172
+ return flag & 1 ? baseval : -baseval;
173
+ }
174
+
175
+ function decodeTriplet(flags, glyphs, nPoints) {
176
+ let y;
177
+ let x = y = 0;
178
+ let res = [];
179
+
180
+ for (let i = 0; i < nPoints; i++) {
181
+ let dx, dy;
182
+ let flag = flags.readUInt8();
183
+ let onCurve = !(flag >> 7);
184
+ flag &= 0x7f;
185
+
186
+ if (flag < 10) {
187
+ dx = 0;
188
+ dy = withSign(flag, ((flag & 14) << 7) + glyphs.readUInt8());
189
+
190
+ } else if (flag < 20) {
191
+ dx = withSign(flag, (((flag - 10) & 14) << 7) + glyphs.readUInt8());
192
+ dy = 0;
193
+
194
+ } else if (flag < 84) {
195
+ let b0 = flag - 20;
196
+ let b1 = glyphs.readUInt8();
197
+ dx = withSign(flag, 1 + (b0 & 0x30) + (b1 >> 4));
198
+ dy = withSign(flag >> 1, 1 + ((b0 & 0x0c) << 2) + (b1 & 0x0f));
199
+
200
+ } else if (flag < 120) {
201
+ let b0 = flag - 84;
202
+ dx = withSign(flag, 1 + ((b0 / 12) << 8) + glyphs.readUInt8());
203
+ dy = withSign(flag >> 1, 1 + (((b0 % 12) >> 2) << 8) + glyphs.readUInt8());
204
+
205
+ } else if (flag < 124) {
206
+ let b1 = glyphs.readUInt8();
207
+ let b2 = glyphs.readUInt8();
208
+ dx = withSign(flag, (b1 << 4) + (b2 >> 4));
209
+ dy = withSign(flag >> 1, ((b2 & 0x0f) << 8) + glyphs.readUInt8());
210
+
211
+ } else {
212
+ dx = withSign(flag, glyphs.readUInt16BE());
213
+ dy = withSign(flag >> 1, glyphs.readUInt16BE());
214
+ }
215
+
216
+ x += dx;
217
+ y += dy;
218
+ res.push(new Point(onCurve, false, x, y));
219
+ }
220
+
221
+ return res;
222
+ }
@@ -0,0 +1,56 @@
1
+ import TTFFont from './TTFFont';
2
+ import WOFFDirectory from './tables/WOFFDirectory';
3
+ import { unzlibSync } from 'fflate';
4
+ import * as r from 'restructure';
5
+ import { asciiDecoder } from './utils';
6
+
7
+ export default class WOFFFont extends TTFFont {
8
+ type = 'WOFF';
9
+
10
+ static probe(buffer) {
11
+ return asciiDecoder.decode(buffer.slice(0, 4)) === 'wOFF';
12
+ }
13
+
14
+ _decodeDirectory() {
15
+ this.directory = WOFFDirectory.decode(this.stream, { _startOffset: 0 });
16
+ }
17
+
18
+ _decodeTable(table) {
19
+ this._decompress();
20
+ return super._decodeTable(table);
21
+ }
22
+
23
+ // Inflate all tables into one stream so internal offsets (e.g. gvar) stay
24
+ // valid against this.stream — same reason WOFF2Font decompresses up front.
25
+ _decompress() {
26
+ if (this._decompressed) {
27
+ return;
28
+ }
29
+
30
+ let totalSize = 0;
31
+ let layout = [];
32
+ for (let tag in this.directory.tables) {
33
+ let entry = this.directory.tables[tag];
34
+ layout.push({ entry, newOffset: totalSize });
35
+ totalSize = (totalSize + entry.length + 3) & ~3;
36
+ }
37
+
38
+ let buffer = new Uint8Array(totalSize);
39
+ for (let { entry, newOffset } of layout) {
40
+ this.stream.pos = entry.offset;
41
+ let data;
42
+ if (entry.compLength < entry.length) {
43
+ data = unzlibSync(this.stream.readBuffer(entry.compLength), {
44
+ out: new Uint8Array(entry.length)
45
+ });
46
+ } else {
47
+ data = this.stream.readBuffer(entry.length);
48
+ }
49
+ buffer.set(data, newOffset);
50
+ entry.offset = newOffset;
51
+ }
52
+
53
+ this.stream = new r.DecodeStream(buffer);
54
+ this._decompressed = true;
55
+ }
56
+ }