Show More
Commit Description:
fig bugs in login report
Commit Description:
fig bugs in login report
References:
File last commit:
Show/Diff file:
Action:
node_modules/fontkit/src/aat/AATStateMachine.js
| 96 lines
| 2.6 KiB
| application/javascript
| JavascriptLexer
|
r789 | import AATLookupTable from './AATLookupTable'; | |||
const START_OF_TEXT_STATE = 0; | ||||
const START_OF_LINE_STATE = 1; | ||||
const END_OF_TEXT_CLASS = 0; | ||||
const OUT_OF_BOUNDS_CLASS = 1; | ||||
const DELETED_GLYPH_CLASS = 2; | ||||
const END_OF_LINE_CLASS = 3; | ||||
const DONT_ADVANCE = 0x4000; | ||||
export default class AATStateMachine { | ||||
constructor(stateTable) { | ||||
this.stateTable = stateTable; | ||||
this.lookupTable = new AATLookupTable(stateTable.classTable); | ||||
} | ||||
process(glyphs, reverse, processEntry) { | ||||
let currentState = START_OF_TEXT_STATE; // START_OF_LINE_STATE is used for kashida glyph insertions sometimes I think? | ||||
let index = reverse ? glyphs.length - 1 : 0; | ||||
let dir = reverse ? -1 : 1; | ||||
while ((dir === 1 && index <= glyphs.length) || (dir === -1 && index >= -1)) { | ||||
let glyph = null; | ||||
let classCode = OUT_OF_BOUNDS_CLASS; | ||||
let shouldAdvance = true; | ||||
if (index === glyphs.length || index === -1) { | ||||
classCode = END_OF_TEXT_CLASS; | ||||
} else { | ||||
glyph = glyphs[index]; | ||||
if (glyph.id === 0xffff) { // deleted glyph | ||||
classCode = DELETED_GLYPH_CLASS; | ||||
} else { | ||||
classCode = this.lookupTable.lookup(glyph.id); | ||||
if (classCode == null) { | ||||
classCode = OUT_OF_BOUNDS_CLASS; | ||||
} | ||||
} | ||||
} | ||||
let row = this.stateTable.stateArray.getItem(currentState); | ||||
let entryIndex = row[classCode]; | ||||
let entry = this.stateTable.entryTable.getItem(entryIndex); | ||||
if (classCode !== END_OF_TEXT_CLASS && classCode !== DELETED_GLYPH_CLASS) { | ||||
processEntry(glyph, entry, index); | ||||
shouldAdvance = !(entry.flags & DONT_ADVANCE); | ||||
} | ||||
currentState = entry.newState; | ||||
if (shouldAdvance) { | ||||
index += dir; | ||||
} | ||||
} | ||||
return glyphs; | ||||
} | ||||
/** | ||||
* Performs a depth-first traversal of the glyph strings | ||||
* represented by the state machine. | ||||
*/ | ||||
traverse(opts, state = 0, visited = new Set) { | ||||
if (visited.has(state)) { | ||||
return; | ||||
} | ||||
visited.add(state); | ||||
let {nClasses, stateArray, entryTable} = this.stateTable; | ||||
let row = stateArray.getItem(state); | ||||
// Skip predefined classes | ||||
for (let classCode = 4; classCode < nClasses; classCode++) { | ||||
let entryIndex = row[classCode]; | ||||
let entry = entryTable.getItem(entryIndex); | ||||
// Try all glyphs in the class | ||||
for (let glyph of this.lookupTable.glyphsForValue(classCode)) { | ||||
if (opts.enter) { | ||||
opts.enter(glyph, entry); | ||||
} | ||||
if (entry.newState !== 0) { | ||||
this.traverse(opts, entry.newState, visited); | ||||
} | ||||
if (opts.exit) { | ||||
opts.exit(glyph, entry); | ||||
} | ||||
} | ||||
} | ||||
} | ||||
} | ||||