@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.
- package/LICENSE +21 -0
- package/README.md +274 -0
- package/dist/browser-module.mjs +13660 -0
- package/dist/browser-module.mjs.map +1 -0
- package/dist/browser.cjs +13689 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/main.cjs +13712 -0
- package/dist/main.cjs.map +1 -0
- package/dist/module.mjs +13673 -0
- package/dist/module.mjs.map +1 -0
- package/package.json +99 -0
- package/src/CmapProcessor.js +285 -0
- package/src/DFont.js +113 -0
- package/src/TTFFont.js +621 -0
- package/src/TrueTypeCollection.js +65 -0
- package/src/WOFF2Font.js +222 -0
- package/src/WOFFFont.js +56 -0
- package/src/aat/AATFeatureMap.js +545 -0
- package/src/aat/AATLayoutEngine.js +48 -0
- package/src/aat/AATLookupTable.js +125 -0
- package/src/aat/AATMorxProcessor.js +429 -0
- package/src/aat/AATStateMachine.js +96 -0
- package/src/base.js +29 -0
- package/src/cff/CFFCharsets.js +99 -0
- package/src/cff/CFFDict.js +166 -0
- package/src/cff/CFFEncodings.js +48 -0
- package/src/cff/CFFFont.js +158 -0
- package/src/cff/CFFIndex.js +150 -0
- package/src/cff/CFFOperand.js +135 -0
- package/src/cff/CFFPointer.js +50 -0
- package/src/cff/CFFPrivateDict.js +39 -0
- package/src/cff/CFFStandardStrings.js +71 -0
- package/src/cff/CFFTop.js +236 -0
- package/src/decorators.js +36 -0
- package/src/encodings.js +219 -0
- package/src/fs.js +12 -0
- package/src/glyph/BBox.js +72 -0
- package/src/glyph/CBDTGlyph.js +9 -0
- package/src/glyph/CFFGlyph.js +635 -0
- package/src/glyph/COLRGlyph.js +108 -0
- package/src/glyph/Glyph.js +270 -0
- package/src/glyph/GlyphVariationProcessor.js +487 -0
- package/src/glyph/Path.js +257 -0
- package/src/glyph/SBIXGlyph.js +54 -0
- package/src/glyph/StandardNames.js +27 -0
- package/src/glyph/TTFGlyph.js +408 -0
- package/src/glyph/TTFGlyphEncoder.js +158 -0
- package/src/glyph/WOFF2Glyph.js +70 -0
- package/src/index.js +15 -0
- package/src/layout/GlyphPosition.js +30 -0
- package/src/layout/GlyphRun.js +108 -0
- package/src/layout/KernProcessor.js +97 -0
- package/src/layout/LayoutEngine.js +190 -0
- package/src/layout/Script.js +231 -0
- package/src/layout/UnicodeLayoutEngine.js +250 -0
- package/src/node.js +16 -0
- package/src/opentype/GPOSProcessor.js +311 -0
- package/src/opentype/GSUBProcessor.js +208 -0
- package/src/opentype/GlyphInfo.js +57 -0
- package/src/opentype/GlyphIterator.js +82 -0
- package/src/opentype/OTLayoutEngine.js +117 -0
- package/src/opentype/OTProcessor.js +472 -0
- package/src/opentype/ShapingPlan.js +121 -0
- package/src/opentype/shapers/ArabicShaper.js +124 -0
- package/src/opentype/shapers/DefaultShaper.js +116 -0
- package/src/opentype/shapers/HangulShaper.js +285 -0
- package/src/opentype/shapers/HebrewShaper.js +105 -0
- package/src/opentype/shapers/IndicShaper.js +914 -0
- package/src/opentype/shapers/ThaiShaper.js +238 -0
- package/src/opentype/shapers/UniversalShaper.js +186 -0
- package/src/opentype/shapers/data.trie +0 -0
- package/src/opentype/shapers/gen-indic.js +208 -0
- package/src/opentype/shapers/gen-use.js +287 -0
- package/src/opentype/shapers/generate-data.js +33 -0
- package/src/opentype/shapers/index.js +109 -0
- package/src/opentype/shapers/indic-data.js +175 -0
- package/src/opentype/shapers/indic.json +1 -0
- package/src/opentype/shapers/indic.machine +31 -0
- package/src/opentype/shapers/indic.trie +0 -0
- package/src/opentype/shapers/use.json +1 -0
- package/src/opentype/shapers/use.machine +44 -0
- package/src/opentype/shapers/use.trie +0 -0
- package/src/packages/unicode-properties/LICENSE +8 -0
- package/src/packages/unicode-properties/README.md +12 -0
- package/src/packages/unicode-properties/data-trie.js +1 -0
- package/src/packages/unicode-properties/data.js +1 -0
- package/src/packages/unicode-properties/data.json +1 -0
- package/src/packages/unicode-properties/data.trie +0 -0
- package/src/packages/unicode-properties/dist/index.cjs +257 -0
- package/src/packages/unicode-properties/dist/index.cjs.map +7 -0
- package/src/packages/unicode-properties/dist/index.mjs +234 -0
- package/src/packages/unicode-properties/dist/index.mjs.map +7 -0
- package/src/packages/unicode-properties/generate.js +107 -0
- package/src/packages/unicode-properties/index.js +184 -0
- package/src/packages/unicode-properties/package.json +50 -0
- package/src/packages/unicode-trie/LICENSE +8 -0
- package/src/packages/unicode-trie/README.md +13 -0
- package/src/packages/unicode-trie/builder.js +965 -0
- package/src/packages/unicode-trie/dist/builder.cjs +711 -0
- package/src/packages/unicode-trie/dist/builder.cjs.map +7 -0
- package/src/packages/unicode-trie/dist/builder.mjs +690 -0
- package/src/packages/unicode-trie/dist/builder.mjs.map +7 -0
- package/src/packages/unicode-trie/dist/index.cjs +112 -0
- package/src/packages/unicode-trie/dist/index.cjs.map +7 -0
- package/src/packages/unicode-trie/dist/index.mjs +91 -0
- package/src/packages/unicode-trie/dist/index.mjs.map +7 -0
- package/src/packages/unicode-trie/index.js +135 -0
- package/src/packages/unicode-trie/package.json +49 -0
- package/src/packages/unicode-trie/swap.js +21 -0
- package/src/subset/CFFSubset.js +176 -0
- package/src/subset/Subset.js +63 -0
- package/src/subset/TTFSubset.js +130 -0
- package/src/tables/BASE.js +78 -0
- package/src/tables/COLR.js +25 -0
- package/src/tables/CPAL.js +24 -0
- package/src/tables/DSIG.js +21 -0
- package/src/tables/EBDT.js +91 -0
- package/src/tables/EBLC.js +80 -0
- package/src/tables/GDEF.js +57 -0
- package/src/tables/GPOS.js +209 -0
- package/src/tables/GSUB.js +85 -0
- package/src/tables/HVAR.js +44 -0
- package/src/tables/JSTF.js +43 -0
- package/src/tables/LTSH.js +10 -0
- package/src/tables/OS2.js +84 -0
- package/src/tables/PCLT.js +21 -0
- package/src/tables/STAT.js +99 -0
- package/src/tables/VDMX.js +33 -0
- package/src/tables/VORG.js +14 -0
- package/src/tables/WOFF2Directory.js +73 -0
- package/src/tables/WOFFDirectory.js +37 -0
- package/src/tables/aat.js +157 -0
- package/src/tables/avar.js +19 -0
- package/src/tables/bsln.js +31 -0
- package/src/tables/cmap.js +127 -0
- package/src/tables/cvt.js +6 -0
- package/src/tables/directory.js +58 -0
- package/src/tables/feat.js +28 -0
- package/src/tables/fpgm.js +8 -0
- package/src/tables/fvar.js +31 -0
- package/src/tables/gasp.js +15 -0
- package/src/tables/glyf.js +4 -0
- package/src/tables/gvar.js +27 -0
- package/src/tables/hdmx.js +15 -0
- package/src/tables/head.js +25 -0
- package/src/tables/hhea.js +19 -0
- package/src/tables/hmtx.js +11 -0
- package/src/tables/index.js +119 -0
- package/src/tables/just.js +81 -0
- package/src/tables/kern.js +91 -0
- package/src/tables/loca.js +30 -0
- package/src/tables/maxp.js +20 -0
- package/src/tables/morx.js +79 -0
- package/src/tables/name.js +157 -0
- package/src/tables/opbd.js +15 -0
- package/src/tables/opentype.js +217 -0
- package/src/tables/post.js +34 -0
- package/src/tables/prep.js +6 -0
- package/src/tables/sbix.js +17 -0
- package/src/tables/variations.js +80 -0
- package/src/tables/vhea.js +19 -0
- package/src/tables/vmtx.js +12 -0
- 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
|
+
});
|