So should we have OOP?

This commit is contained in:
be5invis 2016-02-04 06:55:33 +08:00
parent c686715797
commit c07e07ed7e
3 changed files with 358 additions and 365 deletions

View File

@ -3,7 +3,7 @@
"version": "1.7.3",
"main": "./generate.js",
"dependencies": {
"patel": ">=0.27.0",
"patel": ">=0.27.2",
"node-sfnt": ">=0.0.20",
"bezier-js": "*",
"yargs": "*",

View File

@ -17,7 +17,15 @@ define [ratio l r m] : if [l === r] 0 ((m - l) / (r - l))
define [byx a b] : a - b
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
export all : define [Glyph name] : begin
define [closepoint p q t] : begin
return : [Math.abs (p.x - q.x)] <= t && [Math.abs (p.y - q.y)] <= t
define [oncurveRemovable a b c t] : begin
local xm : (a.x + c.x) / 2
local ym : (a.y + c.y) / 2
return : [not a.onCurve] && b.onCurve && [not c.onCurve] && [not a.cubic] && [not c.cubic] && (a.x <= b.x && b.x <= c.x || a.x >= b.x && b.x >= c.x) && (a.y <= b.y && b.y <= c.y || a.y >= b.y && b.y >= c.y) && [Math.abs (b.x - xm)] <= (t / 2) && [Math.abs (b.y - ym)] <= (t / 2)
export all : class Glyph
public [new name] : begin
set this.name name
set this.unicode {}
set this.contours {}
@ -27,41 +35,40 @@ export all : define [Glyph name] : begin
set this.dependencies {}
set this.defaultTag null
return nothing
static is {.unapply [function [obj arity] [if (obj <@ Glyph) {obj} null]]}
define Glyph.is {.unapply [function [obj arity] [if (obj <@ Glyph) {obj} null]]}
define [Glyph.prototype.set-width w] : begin
public [set-width w] : begin
this.advanceWidth = w
return this
define [Glyph.prototype.assign-unicode u] : begin
public [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
public [start-from x y] : begin
local contour {[Point.transformed this.gizmo x y true]}
set contour.tag this.defaultTag
this.contours.push contour
return this
Glyph.prototype.moveTo = Glyph.prototype.start-from
public moveTo Type.prototype.start-from
define [Glyph.prototype.line-to x y] : begin
public [line-to x y] : begin
this.contours.((this.contours.length - 1)).push [Point.transformed this.gizmo x y true]
return this
Glyph.prototype.lineTo = Glyph.prototype.line-to
public lineTo Type.prototype.line-to
define [Glyph.prototype.curve-control x y] : begin
public [curve-control x y] : begin
this.contours.((this.contours.length - 1)).push [tp this.gizmo [new Point x y false]]
return this
define [Glyph.prototype.curve-to xc yc x y] : begin
public [curve-to xc yc x y] : begin
this.contours.((this.contours.length - 1)).push [Point.transformed this.gizmo xc yc false] [Point.transformed this.gizmo x y true]
return this
Glyph.prototype.curveTo = Glyph.prototype.curve-to
public curveTo Type.prototype.curve-to
define [Glyph.prototype.cubic-to x1 y1 x2 y2 x y] : begin
public [cubic-to x1 y1 x2 y2 x y] : begin
#local lastContour this.contours.(this.contours.length - 1)
#local lastPoint : utp this.gizmo lastContour.(lastContour.length - 1)
#local segments : bezierCubic2Q2 lastPoint {.x x1 .y y1} {.x x2 .y y2} {.x x .y y}
@ -71,27 +78,27 @@ define [Glyph.prototype.cubic-to x1 y1 x2 y2 x y] : begin
Point.transformed this.gizmo x2 y2 false true
Point.transformed this.gizmo x y true
return this
Glyph.prototype.cubicTo = Glyph.prototype.cubic-to
public cubicTo Type.prototype.cubic-to
define [Glyph.prototype.reverse-last] : begin
public [reverse-last] : begin
if [this.contours && this.contours.(this.contours.length - 1)] : begin
this.contours.(this.contours.length - 1) = [this.contours.(this.contours.length - 1).reverse]
return this
Glyph.prototype.reverseLast = Glyph.prototype.reverse-last
public reverseLast Type.prototype.reverse-last
define [Glyph.prototype.tag-contour tag n] : begin
public [tag-contour tag n] : begin
if this.contours : begin
local lastContour this.contours.(this.contours.length - 1)
if lastContour : if tag : set lastContour.tag tag
return this
define [Glyph.prototype.retag-contour oldtag newtag] : begin
public [retag-contour oldtag newtag] : begin
if this.contours : foreach [c : items-of this.contours] : if (c.tag === oldtag) : set c.tag newtag
return this
define [Glyph.prototype.eject-contour tag] : begin
public [eject-contour tag] : begin
set this.contours : this.contours.filter : lambda [c] (c.tag !== tag)
return this
define [Glyph.prototype.include component copyAnchors] : begin
public [include component copyAnchors] : begin
piecewise
(component <@ Function) : begin
local t this.defaultTag
@ -145,13 +152,13 @@ define [Glyph.prototype.include component copyAnchors] : begin
glyph.dependencies : this.dependencies = [this.dependencies.concat glyph.dependencies]
return this
define [Glyph.prototype.apply-transform transform alsoAnchors] : begin
public [apply-transform transform alsoAnchors] : begin
foreach [c : items-of this.contours] : foreach [j : range 0 c.length] : set c.(j) : tp transform c.(j)
if alsoAnchors : foreach key [items-of [Object.keys this.anchors]] : begin
set this.anchors.(key) : Anchor.transform transform this.anchors.(key)
return this
define [Glyph.prototype.set-anchor id type x y mbx mby] : begin
public [set-anchor id type x y mbx mby] : begin
xytransform this.gizmo x y
if (mbx !== nothing && mby !== nothing)
: then : begin
@ -160,14 +167,7 @@ define [Glyph.prototype.set-anchor id type x y mbx mby] : begin
: else : set this.anchors.(id) : new Anchor x y type
return this
define [closepoint p q t] : begin
return : [Math.abs (p.x - q.x)] <= t && [Math.abs (p.y - q.y)] <= t
define [oncurveRemovable a b c t] : begin
local xm : (a.x + c.x) / 2
local ym : (a.y + c.y) / 2
return : [not a.onCurve] && b.onCurve && [not c.onCurve] && [not a.cubic] && [not c.cubic] && (a.x <= b.x && b.x <= c.x || a.x >= b.x && b.x >= c.x) && (a.y <= b.y && b.y <= c.y || a.y >= b.y && b.y >= c.y) && [Math.abs (b.x - xm)] <= (t / 2) && [Math.abs (b.y - ym)] <= (t / 2)
define [Glyph.prototype.cleanup t] : begin
public [cleanup t] : begin
foreach c [range 0 this.contours.length] : begin
local ocontour this.contours.(c)
# add infections

View File

@ -11,20 +11,23 @@ define-macro xytransform : syntax-rules
set @y : @t * @tfm.xy + @y * @tfm.yy + @tfm.y
]
export all : define [SpiroExpansionContext] : begin
define [normalY angle] : Math.sin angle
define [normalX angle vex] : [Math.cos angle] * vex
export all : class SpiroExpansionContext
public [new] : begin
set this.gizmo [Transform.Id]
set this.controlKnots {}
set this.defaultd1 0
set this.defaultd2 0
return nothing
define [SpiroExpansionContext.prototype.moveTo x y unimportant] : begin
public [moveTo x y unimportant] : begin
if unimportant : return nothing
# Transform incoming knots using gizmo
xytransform this.gizmo x y
this.controlKnots.push {.x x .y y .type 'g4' .d1 this.defaultd1 .d2 this.defaultd2}
define [SpiroExpansionContext.prototype.lineTo x y unimportant] : begin
public [lineTo x y unimportant] : begin
local lastKnot this.controlKnots.(this.controlKnots.length - 1)
xytransform this.gizmo x y
local thisKnot {.x x .y y .type 'g4' .d1 lastKnot.d1 .d2 lastKnot.d2}
@ -34,7 +37,7 @@ define [SpiroExpansionContext.prototype.lineTo x y unimportant] : begin
if (lastKnot.normalAngle === nothing) : set lastKnot.normalAngle normalAngle
if [not unimportant] : this.controlKnots.push thisKnot
define [SpiroExpansionContext.prototype.cubicTo x1 y1 x2 y2 x y unimportant] : begin
public [cubicTo x1 y1 x2 y2 x y unimportant] : begin
local lastKnot this.controlKnots.(this.controlKnots.length - 1)
xytransform this.gizmo x1 y1
xytransform this.gizmo x2 y2
@ -48,34 +51,24 @@ define [SpiroExpansionContext.prototype.cubicTo x1 y1 x2 y2 x y unimportant] : b
set thisKnot.normalAngle normalAngle
this.controlKnots.push thisKnot
define [SpiroExpansionContext.prototype.set-width l r] : begin
public [set-width l r] : begin
local lastKnot this.controlKnots.(this.controlKnots.length - 1)
if lastKnot : then
lastKnot.d1 = l; lastKnot.d2 = r
: else
this.defaultd1 = l; this.defaultd2 = r
define [SpiroExpansionContext.prototype.heads-to direction] : begin
public [heads-to direction] : begin
local lastKnot this.controlKnots.(this.controlKnots.length - 1)
if lastKnot : begin
lastKnot.proposedNormal = direction
define [SpiroExpansionContext.prototype.set-type type] : begin
public [set-type type] : begin
local lastKnot this.controlKnots.(this.controlKnots.length - 1)
if lastKnot : begin
lastKnot.type = type
define [shortestAngle end start] : begin
local a : (end - start) % (Math.PI * 2)
if (a > Math.PI / 2) : a = a - Math.PI
return a
define [normalY angle] : Math.sin angle
define [normalX angle vex] : [Math.cos angle] * vex
define [SpiroExpansionContext.prototype.expand contrast] : begin
public [expand contrast] : begin
local lhs {}
local rhs {}
@ -100,7 +93,7 @@ define [SpiroExpansionContext.prototype.expand contrast] : begin
local fd2 : smooth js d2s
local fdx : smooth js dxs
local fdy : smooth js dys
# console.log deltaAngles
# console.log deltaAngles
# interpolate important knots
foreach j [range 0 this.controlKnots.length] : begin