Show More
Commit Description:
merge
Commit Description:
merge
References:
File last commit:
Show/Diff file:
Action:
node_modules/fontkit/src/cff/CFFIndex.js
| 150 lines
| 3.2 KiB
| application/javascript
| JavascriptGenshiLexer
|
r789 | import r from 'restructure'; | |||
export default class CFFIndex { | ||||
constructor(type) { | ||||
this.type = type; | ||||
} | ||||
getCFFVersion(ctx) { | ||||
while (ctx && !ctx.hdrSize) { | ||||
ctx = ctx.parent; | ||||
} | ||||
return ctx ? ctx.version : -1; | ||||
} | ||||
decode(stream, parent) { | ||||
let version = this.getCFFVersion(parent); | ||||
let count = version >= 2 | ||||
? stream.readUInt32BE() | ||||
: stream.readUInt16BE(); | ||||
if (count === 0) { | ||||
return []; | ||||
} | ||||
let offSize = stream.readUInt8(); | ||||
let offsetType; | ||||
if (offSize === 1) { | ||||
offsetType = r.uint8; | ||||
} else if (offSize === 2) { | ||||
offsetType = r.uint16; | ||||
} else if (offSize === 3) { | ||||
offsetType = r.uint24; | ||||
} else if (offSize === 4) { | ||||
offsetType = r.uint32; | ||||
} else { | ||||
throw new Error(`Bad offset size in CFFIndex: ${offSize} ${stream.pos}`); | ||||
} | ||||
let ret = []; | ||||
let startPos = stream.pos + ((count + 1) * offSize) - 1; | ||||
let start = offsetType.decode(stream); | ||||
for (let i = 0; i < count; i++) { | ||||
let end = offsetType.decode(stream); | ||||
if (this.type != null) { | ||||
let pos = stream.pos; | ||||
stream.pos = startPos + start; | ||||
parent.length = end - start; | ||||
ret.push(this.type.decode(stream, parent)); | ||||
stream.pos = pos; | ||||
} else { | ||||
ret.push({ | ||||
offset: startPos + start, | ||||
length: end - start | ||||
}); | ||||
} | ||||
start = end; | ||||
} | ||||
stream.pos = startPos + start; | ||||
return ret; | ||||
} | ||||
size(arr, parent) { | ||||
let size = 2; | ||||
if (arr.length === 0) { | ||||
return size; | ||||
} | ||||
let type = this.type || new r.Buffer; | ||||
// find maximum offset to detminine offset type | ||||
let offset = 1; | ||||
for (let i = 0; i < arr.length; i++) { | ||||
let item = arr[i]; | ||||
offset += type.size(item, parent); | ||||
} | ||||
let offsetType; | ||||
if (offset <= 0xff) { | ||||
offsetType = r.uint8; | ||||
} else if (offset <= 0xffff) { | ||||
offsetType = r.uint16; | ||||
} else if (offset <= 0xffffff) { | ||||
offsetType = r.uint24; | ||||
} else if (offset <= 0xffffffff) { | ||||
offsetType = r.uint32; | ||||
} else { | ||||
throw new Error("Bad offset in CFFIndex"); | ||||
} | ||||
size += 1 + offsetType.size() * (arr.length + 1); | ||||
size += offset - 1; | ||||
return size; | ||||
} | ||||
encode(stream, arr, parent) { | ||||
stream.writeUInt16BE(arr.length); | ||||
if (arr.length === 0) { | ||||
return; | ||||
} | ||||
let type = this.type || new r.Buffer; | ||||
// find maximum offset to detminine offset type | ||||
let sizes = []; | ||||
let offset = 1; | ||||
for (let item of arr) { | ||||
let s = type.size(item, parent); | ||||
sizes.push(s); | ||||
offset += s; | ||||
} | ||||
let offsetType; | ||||
if (offset <= 0xff) { | ||||
offsetType = r.uint8; | ||||
} else if (offset <= 0xffff) { | ||||
offsetType = r.uint16; | ||||
} else if (offset <= 0xffffff) { | ||||
offsetType = r.uint24; | ||||
} else if (offset <= 0xffffffff) { | ||||
offsetType = r.uint32; | ||||
} else { | ||||
throw new Error("Bad offset in CFFIndex"); | ||||
} | ||||
// write offset size | ||||
stream.writeUInt8(offsetType.size()); | ||||
// write elements | ||||
offset = 1; | ||||
offsetType.encode(stream, offset); | ||||
for (let size of sizes) { | ||||
offset += size; | ||||
offsetType.encode(stream, offset); | ||||
} | ||||
for (let item of arr) { | ||||
type.encode(stream, item, parent); | ||||
} | ||||
return; | ||||
} | ||||
} | ||||