Skip to content

Commit

Permalink
Update restructure to version 2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
carlobeltrame authored and diegomura committed Jul 11, 2022
1 parent 331e8fa commit 9188a73
Show file tree
Hide file tree
Showing 5 changed files with 491 additions and 0 deletions.
44 changes: 44 additions & 0 deletions packages/fontkit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@react-pdf/fontkit",
"version": "2.1.1",
"description": "An advanced font engine for Node and the browser",
"repository": {
"type": "git",
"url": "https://github.com/diegomura/react-pdf.git",
"directory": "packages/fontkit"
},
"scripts": {
"watch": "rimraf ./lib && rollup -c -w",
"build": "npm run trie:data && npm run trie:use && npm run trie:indic && rollup -c",
"trie:use": "babel-node src/opentype/shapers/gen-use.js",
"trie:indic": "babel-node src/opentype/shapers/gen-indic.js",
"trie:data": "babel-node src/opentype/shapers/generate-data.js"
},
"main": "lib/fontkit.cjs.js",
"module": "lib/fontkit.es.js",
"browser": {
"./lib/fontkit.es.js": "./lib/fontkit.browser.es.js",
"./lib/fontkit.cjs.js": "./lib/fontkit.browser.cjs.js"
},
"files": [
"lib"
],
"author": "Devon Govett <[email protected]>",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.16.4",
"brotli": "^1.2.0",
"clone": "^1.0.4",
"deep-equal": "^1.0.0",
"dfa": "^1.2.0",
"restructure": "^2.0.1",
"tiny-inflate": "^1.0.2",
"unicode-properties": "^1.4.1",
"unicode-trie": "^0.3.0"
},
"devDependencies": {
"codepoints": "^1.2.0",
"concat-stream": "^1.4.6",
"iconv-lite": "^0.4.13"
}
}
209 changes: 209 additions & 0 deletions packages/fontkit/src/tables/GPOS.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import r from 'restructure';
import {ScriptList, FeatureList, LookupList, Coverage, ClassDef, Device, Context, ChainingContext} from './opentype';
import {FeatureVariations} from './variations';

let ValueFormat = new r.Bitfield(r.uint16, [
'xPlacement', 'yPlacement',
'xAdvance', 'yAdvance',
'xPlaDevice', 'yPlaDevice',
'xAdvDevice', 'yAdvDevice'
]);

let types = {
xPlacement: r.int16,
yPlacement: r.int16,
xAdvance: r.int16,
yAdvance: r.int16,
xPlaDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }),
yPlaDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }),
xAdvDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel }),
yAdvDevice: new r.Pointer(r.uint16, Device, { type: 'global', relativeTo: ctx => ctx.rel })
};

class ValueRecord {
constructor(key = 'valueFormat') {
this.key = key;
}

buildStruct(parent) {
let struct = parent;
while (!struct[this.key] && struct.parent) {
struct = struct.parent;
}

if (!struct[this.key]) return;

let fields = {};
fields.rel = () => struct._startOffset;

let format = struct[this.key];
for (let key in format) {
if (format[key]) {
fields[key] = types[key];
}
}

return new r.Struct(fields);
}

size(val, ctx) {
return this.buildStruct(ctx).size(val, ctx);
}

decode(stream, parent) {
let res = this.buildStruct(parent).decode(stream, parent);
delete res.rel;
return res;
}
}

let PairValueRecord = new r.Struct({
secondGlyph: r.uint16,
value1: new ValueRecord('valueFormat1'),
value2: new ValueRecord('valueFormat2')
});

let PairSet = new r.Array(PairValueRecord, r.uint16);

let Class2Record = new r.Struct({
value1: new ValueRecord('valueFormat1'),
value2: new ValueRecord('valueFormat2')
});

let Anchor = new r.VersionedStruct(r.uint16, {
1: { // Design units only
xCoordinate: r.int16,
yCoordinate: r.int16
},

2: { // Design units plus contour point
xCoordinate: r.int16,
yCoordinate: r.int16,
anchorPoint: r.uint16
},

3: { // Design units plus Device tables
xCoordinate: r.int16,
yCoordinate: r.int16,
xDeviceTable: new r.Pointer(r.uint16, Device),
yDeviceTable: new r.Pointer(r.uint16, Device)
}
});

let EntryExitRecord = new r.Struct({
entryAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'}),
exitAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'})
});

let MarkRecord = new r.Struct({
class: r.uint16,
markAnchor: new r.Pointer(r.uint16, Anchor, {type: 'parent'})
});

let MarkArray = new r.Array(MarkRecord, r.uint16);

let BaseRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.classCount);
let BaseArray = new r.Array(BaseRecord, r.uint16);

let ComponentRecord = new r.Array(new r.Pointer(r.uint16, Anchor), t => t.parent.parent.classCount);
let LigatureAttach = new r.Array(ComponentRecord, r.uint16);
let LigatureArray = new r.Array(new r.Pointer(r.uint16, LigatureAttach), r.uint16);

let GPOSLookup = new r.VersionedStruct('lookupType', {
1: new r.VersionedStruct(r.uint16, { // Single Adjustment
1: { // Single positioning value
coverage: new r.Pointer(r.uint16, Coverage),
valueFormat: ValueFormat,
value: new ValueRecord()
},
2: {
coverage: new r.Pointer(r.uint16, Coverage),
valueFormat: ValueFormat,
valueCount: r.uint16,
values: new r.LazyArray(new ValueRecord(), 'valueCount')
}
}),

2: new r.VersionedStruct(r.uint16, { // Pair Adjustment Positioning
1: { // Adjustments for glyph pairs
coverage: new r.Pointer(r.uint16, Coverage),
valueFormat1: ValueFormat,
valueFormat2: ValueFormat,
pairSetCount: r.uint16,
pairSets: new r.LazyArray(new r.Pointer(r.uint16, PairSet), 'pairSetCount')
},

2: { // Class pair adjustment
coverage: new r.Pointer(r.uint16, Coverage),
valueFormat1: ValueFormat,
valueFormat2: ValueFormat,
classDef1: new r.Pointer(r.uint16, ClassDef),
classDef2: new r.Pointer(r.uint16, ClassDef),
class1Count: r.uint16,
class2Count: r.uint16,
classRecords: new r.LazyArray(new r.LazyArray(Class2Record, 'class2Count'), 'class1Count')
}
}),

3: { // Cursive Attachment Positioning
format: r.uint16,
coverage: new r.Pointer(r.uint16, Coverage),
entryExitCount: r.uint16,
entryExitRecords: new r.Array(EntryExitRecord, 'entryExitCount')
},

4: { // MarkToBase Attachment Positioning
format: r.uint16,
markCoverage: new r.Pointer(r.uint16, Coverage),
baseCoverage: new r.Pointer(r.uint16, Coverage),
classCount: r.uint16,
markArray: new r.Pointer(r.uint16, MarkArray),
baseArray: new r.Pointer(r.uint16, BaseArray)
},

5: { // MarkToLigature Attachment Positioning
format: r.uint16,
markCoverage: new r.Pointer(r.uint16, Coverage),
ligatureCoverage: new r.Pointer(r.uint16, Coverage),
classCount: r.uint16,
markArray: new r.Pointer(r.uint16, MarkArray),
ligatureArray: new r.Pointer(r.uint16, LigatureArray)
},

6: { // MarkToMark Attachment Positioning
format: r.uint16,
mark1Coverage: new r.Pointer(r.uint16, Coverage),
mark2Coverage: new r.Pointer(r.uint16, Coverage),
classCount: r.uint16,
mark1Array: new r.Pointer(r.uint16, MarkArray),
mark2Array: new r.Pointer(r.uint16, BaseArray)
},

7: Context, // Contextual positioning
8: ChainingContext, // Chaining contextual positioning

9: { // Extension Positioning
posFormat: r.uint16,
lookupType: r.uint16, // cannot also be 9
extension: new r.Pointer(r.uint32, undefined)
}
});

// Fix circular reference
GPOSLookup.versions[9].extension.type = GPOSLookup;

export default new r.VersionedStruct(r.uint32, {
header: {
scriptList: new r.Pointer(r.uint16, ScriptList),
featureList: new r.Pointer(r.uint16, FeatureList),
lookupList: new r.Pointer(r.uint16, new LookupList(GPOSLookup))
},

0x00010000: {},
0x00010001: {
featureVariations: new r.Pointer(r.uint32, FeatureVariations)
}
});

// export GPOSLookup for JSTF table
export { GPOSLookup };
27 changes: 27 additions & 0 deletions packages/fontkit/src/tables/gvar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import r from 'restructure';

let shortFrac = new r.Fixed(16, 'BE', 14);
class Offset {
static decode(stream, parent) {
// In short format, offsets are multiplied by 2.
// This doesn't seem to be documented by Apple, but it
// is implemented this way in Freetype.
return parent.flags
? stream.readUInt32BE()
: stream.readUInt16BE() * 2;
}
}

let gvar = new r.Struct({
version: r.uint16,
reserved: new r.Reserved(r.uint16),
axisCount: r.uint16,
globalCoordCount: r.uint16,
globalCoords: new r.Pointer(r.uint32, new r.Array(new r.Array(shortFrac, 'axisCount'), 'globalCoordCount')),
glyphCount: r.uint16,
flags: r.uint16,
offsetToData: r.uint32,
offsets: new r.Array(new r.Pointer(Offset, 'void', { relativeTo: ctx => ctx.offsetToData, allowNull: false }), t => t.glyphCount + 1)
});

export default gvar;
81 changes: 81 additions & 0 deletions packages/fontkit/src/tables/just.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import r from 'restructure';
import { LookupTable, StateTable1 } from './aat';

let ClassTable = new r.Struct({
length: r.uint16,
coverage: r.uint16,
subFeatureFlags: r.uint32,
stateTable: new StateTable1
});

let WidthDeltaRecord = new r.Struct({
justClass: r.uint32,
beforeGrowLimit: r.fixed32,
beforeShrinkLimit: r.fixed32,
afterGrowLimit: r.fixed32,
afterShrinkLimit: r.fixed32,
growFlags: r.uint16,
shrinkFlags: r.uint16
});

let WidthDeltaCluster = new r.Array(WidthDeltaRecord, r.uint32);

let ActionData = new r.VersionedStruct('actionType', {
0: { // Decomposition action
lowerLimit: r.fixed32,
upperLimit: r.fixed32,
order: r.uint16,
glyphs: new r.Array(r.uint16, r.uint16)
},

1: { // Unconditional add glyph action
addGlyph: r.uint16
},

2: { // Conditional add glyph action
substThreshold: r.fixed32,
addGlyph: r.uint16,
substGlyph: r.uint16
},

3: {}, // Stretch glyph action (no data, not supported by CoreText)

4: { // Ductile glyph action (not supported by CoreText)
variationAxis: r.uint32,
minimumLimit: r.fixed32,
noStretchValue: r.fixed32,
maximumLimit: r.fixed32
},

5: { // Repeated add glyph action
flags: r.uint16,
glyph: r.uint16
}
});

let Action = new r.Struct({
actionClass: r.uint16,
actionType: r.uint16,
actionLength: r.uint32,
actionData: ActionData,
padding: new r.Reserved(r.uint8, t => t.actionLength - t._currentOffset)
});

let PostcompensationAction = new r.Array(Action, r.uint32);
let PostCompensationTable = new r.Struct({
lookupTable: new LookupTable(new r.Pointer(r.uint16, PostcompensationAction))
});

let JustificationTable = new r.Struct({
classTable: new r.Pointer(r.uint16, ClassTable, { type: 'parent' }),
wdcOffset: r.uint16,
postCompensationTable: new r.Pointer(r.uint16, PostCompensationTable, { type: 'parent' }),
widthDeltaClusters: new LookupTable(new r.Pointer(r.uint16, WidthDeltaCluster, { type: 'parent', relativeTo: ctx => ctx.wdcOffset }))
});

export default new r.Struct({
version: r.uint32,
format: r.uint16,
horizontal: new r.Pointer(r.uint16, JustificationTable),
vertical: new r.Pointer(r.uint16, JustificationTable)
});
Loading

0 comments on commit 9188a73

Please sign in to comment.