Show More
Commit Description:
fix wrong merge
Commit Description:
fix wrong merge
References:
File last commit:
Show/Diff file:
Action:
node_modules/fontkit/src/glyph/TTFGlyphEncoder.js
| 158 lines
| 4.0 KiB
| application/javascript
| JavascriptLexer
|
r789 | import r from 'restructure'; | |||
// Flags for simple glyphs | ||||
const ON_CURVE = 1 << 0; | ||||
const X_SHORT_VECTOR = 1 << 1; | ||||
const Y_SHORT_VECTOR = 1 << 2; | ||||
const REPEAT = 1 << 3; | ||||
const SAME_X = 1 << 4; | ||||
const SAME_Y = 1 << 5; | ||||
class Point { | ||||
static size(val) { | ||||
return val >= 0 && val <= 255 ? 1 : 2; | ||||
} | ||||
static encode(stream, value) { | ||||
if (value >= 0 && value <= 255) { | ||||
stream.writeUInt8(value); | ||||
} else { | ||||
stream.writeInt16BE(value); | ||||
} | ||||
} | ||||
} | ||||
let Glyf = new r.Struct({ | ||||
numberOfContours: r.int16, // if negative, this is a composite glyph | ||||
xMin: r.int16, | ||||
yMin: r.int16, | ||||
xMax: r.int16, | ||||
yMax: r.int16, | ||||
endPtsOfContours: new r.Array(r.uint16, 'numberOfContours'), | ||||
instructions: new r.Array(r.uint8, r.uint16), | ||||
flags: new r.Array(r.uint8, 0), | ||||
xPoints: new r.Array(Point, 0), | ||||
yPoints: new r.Array(Point, 0) | ||||
}); | ||||
/** | ||||
* Encodes TrueType glyph outlines | ||||
*/ | ||||
export default class TTFGlyphEncoder { | ||||
encodeSimple(path, instructions = []) { | ||||
let endPtsOfContours = []; | ||||
let xPoints = []; | ||||
let yPoints = []; | ||||
let flags = []; | ||||
let same = 0; | ||||
let lastX = 0, lastY = 0, lastFlag = 0; | ||||
let pointCount = 0; | ||||
for (let i = 0; i < path.commands.length; i++) { | ||||
let c = path.commands[i]; | ||||
for (let j = 0; j < c.args.length; j += 2) { | ||||
let x = c.args[j]; | ||||
let y = c.args[j + 1]; | ||||
let flag = 0; | ||||
// If the ending point of a quadratic curve is the midpoint | ||||
// between the control point and the control point of the next | ||||
// quadratic curve, we can omit the ending point. | ||||
if (c.command === 'quadraticCurveTo' && j === 2) { | ||||
let next = path.commands[i + 1]; | ||||
if (next && next.command === 'quadraticCurveTo') { | ||||
let midX = (lastX + next.args[0]) / 2; | ||||
let midY = (lastY + next.args[1]) / 2; | ||||
if (x === midX && y === midY) { | ||||
continue; | ||||
} | ||||
} | ||||
} | ||||
// All points except control points are on curve. | ||||
if (!(c.command === 'quadraticCurveTo' && j === 0)) { | ||||
flag |= ON_CURVE; | ||||
} | ||||
flag = this._encodePoint(x, lastX, xPoints, flag, X_SHORT_VECTOR, SAME_X); | ||||
flag = this._encodePoint(y, lastY, yPoints, flag, Y_SHORT_VECTOR, SAME_Y); | ||||
if (flag === lastFlag && same < 255) { | ||||
flags[flags.length - 1] |= REPEAT; | ||||
same++; | ||||
} else { | ||||
if (same > 0) { | ||||
flags.push(same); | ||||
same = 0; | ||||
} | ||||
flags.push(flag); | ||||
lastFlag = flag; | ||||
} | ||||
lastX = x; | ||||
lastY = y; | ||||
pointCount++; | ||||
} | ||||
if (c.command === 'closePath') { | ||||
endPtsOfContours.push(pointCount - 1); | ||||
} | ||||
} | ||||
// Close the path if the last command didn't already | ||||
if (path.commands.length > 1 && path.commands[path.commands.length - 1].command !== 'closePath') { | ||||
endPtsOfContours.push(pointCount - 1); | ||||
} | ||||
let bbox = path.bbox; | ||||
let glyf = { | ||||
numberOfContours: endPtsOfContours.length, | ||||
xMin: bbox.minX, | ||||
yMin: bbox.minY, | ||||
xMax: bbox.maxX, | ||||
yMax: bbox.maxY, | ||||
endPtsOfContours: endPtsOfContours, | ||||
instructions: instructions, | ||||
flags: flags, | ||||
xPoints: xPoints, | ||||
yPoints: yPoints | ||||
}; | ||||
let size = Glyf.size(glyf); | ||||
let tail = 4 - (size % 4); | ||||
let stream = new r.EncodeStream(size + tail); | ||||
Glyf.encode(stream, glyf); | ||||
// Align to 4-byte length | ||||
if (tail !== 0) { | ||||
stream.fill(0, tail); | ||||
} | ||||
return stream.buffer; | ||||
} | ||||
_encodePoint(value, last, points, flag, shortFlag, sameFlag) { | ||||
let diff = value - last; | ||||
if (value === last) { | ||||
flag |= sameFlag; | ||||
} else { | ||||
if (-255 <= diff && diff <= 255) { | ||||
flag |= shortFlag; | ||||
if (diff < 0) { | ||||
diff = -diff; | ||||
} else { | ||||
flag |= sameFlag; | ||||
} | ||||
} | ||||
points.push(diff); | ||||
} | ||||
return flag; | ||||
} | ||||
} | ||||