define bezierCubic2Q2 [require 'node-sfnt/lib/math/bezierCubic2Q2'] define tp [require './transform'].transformPoint define Stroke [require './stroke'].Stroke define id ( .xx 1 .yx 0 .xy 0 .yy 1 .x 0 .y 0 ) define [Glyph name] : begin { set this.name name set this.unicode () set this.contours () set this.advanceWidth 500 set this.gizmo ( .xx 1 .yx 0 .xy 0 .yy 1 .x 0 .y 0 ) return nothing } define [Glyph.prototype.set-width w] : begin { this.advanceWidth = w return this } define [Glyph.prototype.assign-unicode u] : begin { this.unicode.push : piecewise { [[typeof u] === 'string'] : u.charCodeAt 0 true u } return this } define [Glyph.prototype.start-from x y] : begin { this.contours.push ([tp this.gizmo (.x x .y y .onCurve true)]) return this } define [Glyph.prototype.line-to x y] : begin { this.contours`[this.contours.length - 1].push [tp this.gizmo (.x x .y y .onCurve true)] return this } define [Glyph.prototype.curve-to xc yc x y] : begin { this.contours`[this.contours.length - 1].push [tp this.gizmo (.x xc .y yc .onCurve false)] [tp this.gizmo (.x x .y y .onCurve true)] return this } define [Glyph.prototype.cubic-to x1 y1 x2 y2 x y] : begin { local lastContour this.contours`[this.contours.length - 1] local lastPoint lastContour`[lastContour.length - 1] local segments [bezierCubic2Q2 lastPoint (.x x1 .y y1) (.x x2 .y y2) (.x x .y y)] foreach (p0 (.x xc .y yc) (.x xf .y yf)) [items-of segments] : this.curve-to xc yc xf yf return this } define [Glyph.prototype.reverse-last] : begin { this.contours.[this.contours.length - 1] = [this.contours.[this.contours.length - 1].reverse] } define [Glyph.prototype.put-shapes contours] : begin { # do not double-transform local t this.gizmo set this.gizmo id foreach contour [items-of contours] : begin { this.start-from contour.0.x contour.0.y for [local j 1] [j < contour.length] [inc j] : begin { local point contour`j if point.cubic [begin { local p2 contour`[j + 1] local p3 contour`[j + 2] this.cubic-to point.x point.y p2.x p2.y p3.x p3.y j = j + 2 }] [if point.onCurve [this.line-to point.x point.y] [begin { local p2 contour`[j + 1] this.curve-to point.x point.y p2.x p2.y j = j + 1 }]] } } set this.gizmo t return this } define [Glyph.prototype.include-glyph glyph] : this.put-shapes glyph.contours define [Glyph.prototype.create-stroke] : begin { local s : new Stroke s.gizmo = [Object.create this.gizmo] return s } exports.Glyph = Glyph