diff --git a/buildglyphs.patel b/buildglyphs.patel index 026c8cdc0..94fa57595 100644 --- a/buildglyphs.patel +++ b/buildglyphs.patel @@ -2,45 +2,6 @@ define Glyph [require './support/glyph'].Glyph define Stroke [require './support/stroke'].Stroke define tp [require './support/transform'].transformPoint define inverse [require './support/transform'].inverse -define unspiro : let [s2b [require 'libspiro-js'].spiroToBezierOnContext] : function [c closed pts] [s2b pts closed c] - -### Spiro functions -define [PREPARE f] (.type 'prepare' .af f) -define [CLOSE f] (.type 'close' .af f) -define [SETWIDTH l r] : function [] : this.set-width l r -define [HEADS d] : function [] : this.heads-to d -define [WIDTHHEADS l r d] : function [] : begin [this.set-width l r] [this.heads-to d] -define [SAMPLES n] : lambda [] : this.set-samples n -define [VIRTUAL] : this.points.[this.points.length - 1].subdivided = true -define [reverse a] : a.reverse - -define [flatpts pts] : begin { - local ans () - foreach p [items-of pts] : piecewise { - [p <@ Array] : set ans : ans.concat [flatpts p] - true : ans.push p - } - return ans -} -define [spiro pts] : begin { - local s : new Stroke - local points : ().slice.call arguments 0 - local closed false - local lastaf null - if [points.0 && points.0.type === 'prepare'] : begin { - points.0.af.call s - set points : points.slice 1 - } - if [points.[points.length - 1] && points.[points.length - 1].type === 'close'] : begin { - set lastaf points.[points.length - 1].af - set points : points.slice 0 [-1] - set closed true - } - unspiro s closed [flatpts points] - if lastaf : lastaf.call s - s.set-samples 2 - return s -} ### COMMON FUNCTIONS @@ -116,43 +77,6 @@ define [buildFont para recursive] : begin { define globalTransform : Italify para.italicAngle define ITALICCOR : 1 / [Math.sqrt [1 - globalTransform.yx * globalTransform.yx]] - define [G4 _x _y f] : begin { - local (.x x .y y) : tp globalTransform (.x _x .y _y) - return (.x x .y y .type 'g4' .af f) - } - define [G2 _x _y f] : begin { - local (.x x .y y) : tp globalTransform (.x _x .y _y) - return (.x x .y y .type 'g2' .af f) - } - define [LEFT _x _y f] : begin { - local (.x x .y y) : tp globalTransform (.x _x .y _y) - return (.x x .y y .type 'left' .af f) - } - define [RIGHT _x _y f] : begin { - local (.x x .y y) : tp globalTransform (.x _x .y _y) - return (.x x .y y .type 'right' .af f) - } - define [CAP_RTL x y _radius f] : begin { - local radius : fallback _radius [RIGHTSB - SB - STROKE] - local shift : radius * [1 - [Math.cos : Math.asin [0.25 / radius]]] - return : list { - G4 [x + 0.25] [y - shift] VIRTUAL - G4 x y f - G4 [x - 0.25] [y - shift] VIRTUAL - } - } - define [CAP_LTR x y r f] : [CAP_RTL x y r f].reverse - define [CUP_RTL x y _radius f] : begin { - local radius : fallback _radius [RIGHTSB - SB - STROKE] - local shift : radius * [1 - [Math.cos : Math.asin [0.25 / radius]]] - return : list { - G4 [x + 0.25] [y + shift] VIRTUAL - G4 x y f - G4 [x - 0.25] [y + shift] VIRTUAL - } - } - define [CUP_LTR x y r f] : [CUP_RTL x y r f].reverse - define UPWARD (.x [-ITALICCOR] .y 0) define DOWNWARD (.x ITALICCOR .y 0) define RIGHTWARD (.x globalTransform.yx .y 1) @@ -340,7 +264,7 @@ define [buildFont para recursive] : begin { define [create-glyph name actions] : piecewise { [name && actions] : begin { if [pickHash && [not pickHash.(name)]] : return nothing -# process.stderr.write : "Building /" + name + [if recursive " (recursive)" ""] + " for " + para.family + ' ' + para.style + "\n" + process.stderr.write : "Building /" + name + [if recursive " (recursive)" ""] + " for " + para.family + ' ' + para.style + "\n" set dependencyProfile`name () define glyphObject [new Glyph name] glyphObject.set-width WIDTH diff --git a/glyphs/common-shapes.patel b/glyphs/common-shapes.patel index 1288e1412..79ba08544 100644 --- a/glyphs/common-shapes.patel +++ b/glyphs/common-shapes.patel @@ -213,36 +213,6 @@ define [EHookLower bottom smooth hook _middle _stroke _o] : XSHookLower bottom [ define [CHookLower bottom smooth hook _middle _stroke _o] : XSHookLower bottom [RIGHTSB + TAILADJX * globalTransform.yx] _middle [SB + [fallback _o O]] smooth [hook - TAILADJY * globalTransform.yx] _stroke define [RevEHookLower bottom smooth hook _middle _stroke _o] : XSHookLower bottom SB _middle [RIGHTSB - [fallback _o O]] smooth hook _stroke -define [SpiroGeneralHookUpper conn free smooth y hook connectType fconn ffree tension refsmooth] : begin { - set tension : fallback tension 0 - set refsmooth : fallback refsmooth smooth - local dist : free - conn - local radius : dist * dist / [[2.6 + tension] * refsmooth] - return : flatpts : list { - G4 free [y - hook] ffree - [if [free > conn] CAP_RTL CAP_LTR] [[mix conn free SBALANCE] - OMIDCOR_S] y radius - [fallback connectType G4] conn [y - smooth] fconn - } -} -define [SpiroGeneralHookLower conn free smooth y hook connectType fconn ffree tension refsmooth] : begin { - set tension : fallback tension 0 - set refsmooth : fallback refsmooth smooth - local dist : free - conn - local radius : dist * dist / [[2.6 + tension] * refsmooth] - return : flatpts : list { - G4 free [y + hook] ffree - [if [free > conn] CUP_RTL CUP_LTR] [[mix conn free SBALANCE] - OMIDCOR_S] y radius - [fallback connectType G4] conn [y + smooth] fconn - } -} - -define [SpiroCHookUpper l r y connectType s] : begin { - return : SpiroGeneralHookUpper [l + O] r SMALLSMOOTHA [y - O] HOOK connectType nothing nothing 0 SMALLSMOOTH -} -define [SpiroCHookLower l r y connectType s] : list { - return : reverse : SpiroGeneralHookLower [l + O] r SMALLSMOOTHB [y + O] HOOK connectType nothing nothing 0 SMALLSMOOTH -} - define [smallo u d l r _width _sma _smb] : glyph-construction { local middle : [l + r] / 2 local width : fallback _width STROKE @@ -251,50 +221,31 @@ define [smallo u d l r _width _sma _smb] : glyph-construction { local mc : OMIDCOR * width if [u - d > sma + smb] { then : begin { - include : spiro { - G4 [middle - mc] [u - O] [SETWIDTH width 0] - LEFT [l + O] [u - sma] - RIGHT [l + O] [d + smb] - G4 [middle + mc] [d + O] - LEFT [r - O] [d + sma] - RIGHT [r - O] [u - smb] - CLOSE [SAMPLES 2] - } + include : create-stroke + :.set-transform globalTransform + :.start-from [middle - mc] [u - O] + :.set-width width 0 + :.arc-hv-to [l + O] [u - sma] + :.line-to [l + O] [d + smb] + :.arc-vh-to [middle + mc] [d + O] + :.arc-hv-to [r - O] [d + sma] + :.line-to [r - O] [u - smb] + :.arc-vh-to [middle - mc] [u - O] } else : begin { local ymiddlea : mix d u [smb / [sma + smb]] local ymiddleb : mix d u [sma / [sma + smb]] - include : spiro { - G4 [middle - mc] [u - O] [SETWIDTH width 0] - G4 [l + O] ymiddlea - G4 [middle + mc] [d + O] - G4 [r - O] ymiddleb - CLOSE [SAMPLES 2] - } + include : create-stroke + :.set-transform globalTransform + :.start-from [middle - mc] [u - O] + :.set-width width 0 + :.arc-hv-to [l + O] ymiddlea + :.arc-vh-to [middle + mc] [d + O] + :.arc-hv-to [r - O] ymiddleb + :.arc-vh-to [middle - mc] [u - O] } } } -define [SmalloAlt u d l r _width _sma _smb] : glyph-construction { - local middle : [l + r] / 2 - local width : fallback _width STROKE - local sma : fallback _sma SMALLSMOOTHA - local smb : fallback _smb SMALLSMOOTHB - local mc : OMIDCOR * width - local rho 0.77 - local ymiddlea : mix d u [smb / [sma + smb]] - local ymiddleb : mix d u [sma / [sma + smb]] - include : spiro { - G4 [middle - mc] [u - O] [SETWIDTH width 0] - G4 [mix middle l rho] [mix ymiddlea u rho] - G4 [l + O] ymiddlea - G4 [mix middle l rho] [mix ymiddlea d rho] - G4 [middle + mc] [d + O] - G4 [mix middle r rho] [mix ymiddleb d rho] - G4 [r - O] ymiddleb - G4 [mix middle r rho] [mix ymiddleb u rho] - CLOSE [SAMPLES 2] - } -} define [HBar xleft xright y _fine] : glyph-construction { local fine : [fallback _fine STROKE] / 2 diff --git a/glyphs/latin-basic-lower.patel b/glyphs/latin-basic-lower.patel index 82d189804..e0c25ba6c 100644 --- a/glyphs/latin-basic-lower.patel +++ b/glyphs/latin-basic-lower.patel @@ -77,7 +77,7 @@ create-glyph 'g' : glyph-construction { assign-unicode 'g' include pMarks - include : SmalloAlt XH [XH * GBARPOS] SB [RIGHTSB - 0.3 * SB] + include : smallo XH [XH * GBARPOS - O] SB [RIGHTSB - 0.3 * SB] local gleftx [SB * 0.8 + O] local grightx [RIGHTSB + SB * 0.1 - O] @@ -106,29 +106,27 @@ create-glyph 'c' : glyph-construction { set-width WIDTH assign-unicode 'c' include eMarks - include : spiro { - PREPARE [SETWIDTH STROKE 0] - SpiroCHookUpper SB RIGHTSB XH LEFT - SpiroCHookLower SB RIGHTSB 0 RIGHT - } -# include : CHookLower 0 SMALLSMOOTHB HOOK -# include : CHookUpper XH SMALLSMOOTHA HOOK -# include : create-stroke -# :.start-from [SB + O] [XH - SMALLSMOOTHA] :.set-width STROKE 0 -# :.line-to [SB + O] SMALLSMOOTHB + + include : CHookLower 0 SMALLSMOOTHB HOOK + include : CHookUpper XH SMALLSMOOTHA HOOK + include : create-stroke + :.start-from [SB + O] [XH - SMALLSMOOTHA] :.set-width STROKE 0 + :.line-to [SB + O] SMALLSMOOTHB } define [SmallEShape top stroke barpos] : glyph-construction { local barbottom [top * [fallback barpos EBARPOS]] local hookx [RIGHTSB - OXHOOK + TAILADJX * globalTransform.yx] local hookmiddle : [mix [SB + O] hookx 0.55] + OMIDCOR_S - include : spiro { - LEFT [RIGHTSB - O] barbottom [WIDTHHEADS stroke 0 UPWARD] - RIGHT [RIGHTSB - O] [top - SMALLSMOOTHB] - G4 [MIDDLE - OMIDCOR_S] [top - O] - LEFT [SB + O] [top - SMALLSMOOTHA] - SpiroCHookLower SB RIGHTSB 0 RIGHT - } + include : create-stroke + :.start-from [RIGHTSB - O] barbottom + :.heads-to UPWARD + :.set-width stroke 0 + :.line-to [RIGHTSB - O] [top - SMALLSMOOTHB] + :.arc-vh-to MIDDLE [top - O] + :.arc-hv-to [SB + O] [top - SMALLSMOOTHA] + :.line-to [SB + O] SMALLSMOOTHB + include : EHookLower 0 SMALLSMOOTHB SHOOK [mix SB RIGHTSB SBALANCE] stroke include : create-stroke :.start-from [SB + [stroke / 2]] barbottom :.set-width stroke 0 @@ -173,14 +171,14 @@ define [SmallTShape top bot] : glyph-construction { local hookx [center + [WIDTH - SB * 2] * 0.78 - OXHOOK + TAILADJX * globalTransform.yx] local turn : mix center hookx [0.5 + globalTransform.yx * 0.5] local smb : [turn - center] * 1.1 - local rho 0.77 - include : spiro { - LEFT center top [WIDTHHEADS STROKE 0 DOWNWARD] - RIGHT center [bot + smb] - CUP_LTR turn [bot + O] [[hookx - center] * 0.6] - G2 hookx [bot + HOOK - TAILADJY * globalTransform.yx] - } + include : create-stroke + :.start-from center top + :.set-width STROKE 0 + :.heads-to DOWNWARD + :.line-to center [bot + smb] + :.arc-vh-to turn [bot + O] + :.curve-to [turn + [KAPPA_HOOK + TAILADJKAPPA * globalTransform.yx + 0.1] * [hookx - turn]] [bot + O] hookx [bot + HOOK - TAILADJY * globalTransform.yx] include : HBarTop [center + HALFSTROKE - LONGJUT + TBALANCE2] [center + HALFSTROKE + LONGJUT + TBALANCE2] [top * XH / CAP] } @@ -285,24 +283,22 @@ create-glyph 'm' : glyph-construction { local m2 : m1 + [MIDDLE - sw / 2 - SB] include : create-stroke :.start-from [MIDDLE - sw / 2] 0 - :.set-width 0 sw - :.heads-to UPWARD + :.set-width 0 sw :.heads-to UPWARD :.line-to [MIDDLE - sw / 2] [XH - SMALLSMOOTHA] :.arc-vh-to m1 [XO - STROKE] :.set-width 0 STROKE :.heads-to LEFTWARD - :.arc-hv-to [SB + sw * 0.75 * ITALICCOR] [XH - SMALLSMOOTHA] + :.arc-hv-to [SB + sw * 0.75] [XH - SMALLSMOOTHA] :.heads-to DOWNWARD :.set-width 0 [sw * 0.4] include : create-stroke :.start-from [RIGHTSB - sw - O] 0 - :.set-width 0 sw - :.heads-to UPWARD + :.set-width 0 sw :.heads-to UPWARD :.line-to [RIGHTSB - sw - O] [XH - SMALLSMOOTHA] :.arc-vh-to m2 [XO - STROKE] :.set-width 0 STROKE :.heads-to LEFTWARD - :.arc-hv-to [MIDDLE + sw * 0.25 * ITALICCOR] [XH - SMALLSMOOTHA] + :.arc-hv-to [MIDDLE + sw * 0.25] [XH - SMALLSMOOTHA] :.heads-to DOWNWARD :.set-width 0 [sw * 0.4] include : create-stroke diff --git a/pass1-cleanup.py b/pass1-cleanup.py index 397ec9c74..be98fc293 100644 --- a/pass1-cleanup.py +++ b/pass1-cleanup.py @@ -21,7 +21,6 @@ font.removeOverlap() font.addExtrema() font.simplify(2) font.layers["Fore"].is_quadratic = False -font.addExtrema() font.simplify(6, ("smoothcurves", "removesingletonpoints", "setstarttoextremum"), 0.2) font.canonicalContours() font.canonicalStart() diff --git a/pass2-finalize.py b/pass2-finalize.py index 3eea89e2e..b6e51bb70 100644 --- a/pass2-finalize.py +++ b/pass2-finalize.py @@ -7,8 +7,7 @@ font = fontforge.open(source) font.selection.all() font.removeOverlap() font.em = 1000 -font.addExtrema() -font.simplify(0.1) +font.simplify(1) font.canonicalContours() font.canonicalStart() font.generate(sys.argv[2], flags = ("short-post", "opentype")) \ No newline at end of file diff --git a/support/stroke.patel b/support/stroke.patel index b0d24f9e7..995a4ac2c 100644 --- a/support/stroke.patel +++ b/support/stroke.patel @@ -6,7 +6,11 @@ define utp [require './transform'].untransform define [fallback] : for [local j 0] [j < arguments.length] [inc j] : if [arguments`j !== nothing] : return arguments`j -define [xs-array a] ([a.0 - 1] :: [a.concat ([a`[a.length - 1] + 1])]) +define [xs-array low high] : begin { + local a () + for [local j [low - 1]] [j <= high] [inc j] : a.push j + return a +} define [ys-array a] (a.0 :: [a.concat (a`[a.length - 1])]) define SAMPLES 3 @@ -29,8 +33,6 @@ define [Stroke] : begin { .x 0 .y 0 ) - this.defaultD1 = 0 - this.defaultD2 = 0 return this } define Stroke.is : object { @@ -49,16 +51,8 @@ define [Stroke.bindParameters para] : begin { } define [Stroke.prototype.set-width d1 d2] : begin { local point this.points`[this.points.length - 1] - if point { - then { - point.d1 = d1 - point.d2 = d2 - } - else { - this.defaultD1 = d1 - this.defaultD2 = d2 - } - } + point.d1 = d1 + point.d2 = d2 return this } define [Stroke.prototype.heads-to x y] : begin { @@ -75,28 +69,18 @@ define [Stroke.prototype.start-from x y] : begin { this.points = ([tp this.gizmo (.x x .y y .onCurve true)]) return this } -define Stroke.prototype.moveTo Stroke.prototype.start-from -define [Stroke.prototype.line-to x y subdivided] : begin { - this.points.push [tp this.gizmo (.x x .y y .onCurve true .subdivided subdivided)] +define [Stroke.prototype.line-to x y] : begin { + this.points.push [tp this.gizmo (.x x .y y .onCurve true)] return this } -define Stroke.prototype.lineTo Stroke.prototype.line-to -define [Stroke.prototype.curve-to xc yc x y subdivided] : begin { - this.points.push { - tp this.gizmo (.x xc .y yc .onCurve false) - tp this.gizmo (.x x .y y .onCurve true .subdivided subdivided) - } +define [Stroke.prototype.curve-to xc yc x y] : begin { + this.points.push [tp this.gizmo (.x xc .y yc .onCurve false)] [tp this.gizmo (.x x .y y .onCurve true)] return this } -define [Stroke.prototype.cubic-to x1 y1 x2 y2 x y subdivided] : begin { - this.points.push { - tp this.gizmo (.x x1 .y y1 .onCurve false .cubic true) - tp this.gizmo (.x x2 .y y2 .onCurve false .cubic true) - tp this.gizmo (.x x .y y .onCurve true .subdivided subdivided) - } +define [Stroke.prototype.cubic-to x1 y1 x2 y2 x y] : begin { + this.points.push [tp this.gizmo (.x x1 .y y1 .onCurve false .cubic true)] [tp this.gizmo (.x x2 .y y2 .onCurve false .cubic true)] [tp this.gizmo (.x x .y y .onCurve true)] return this } -define Stroke.prototype.cubicTo Stroke.prototype.cubic-to define [Stroke.prototype.arc-vh-to x y _kappah _kappav] : begin { local kappah : fallback _kappah BKAPPA local kappav : fallback _kappav _kappah CKAPPA @@ -136,74 +120,55 @@ define [near a b c] : begin { local dist : Math.max [Math.abs [a.y - c.y]] [Math.abs [a.x - c.x]] return : [Math.abs [b.y - my]] < dist && [Math.abs [b.x - mx]] < dist } -define [computeOffsetPoint curve t j sl foffset fpdx fpdy] : begin { - local onpoint : curve.compute [[t - j] / sl] - local normal : curve.normal [[t - j] / sl] +define [computeOffsetPoint curve t j foffset fpdx fpdy] : begin { + local onpoint : curve.compute [t - j] + local normal : curve.normal [t - j] return (.x onpoint.x + [foffset t] * [normal.x + [fpdx t]] .y onpoint.y + [foffset t] * [normal.y + [fpdy t]]) } define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { - - local ts (0) - local d1s ([set d1 [if [this.points.0.d1 >= 0] this.points.0.d1 this.defaultD1]]) - local d2s ([set d2 [if [this.points.0.d2 >= 0] [-this.points.0.d2] this.defaultD2]]) + local d1s ([set d1 [if [this.points.0.d1 >= 0] this.points.0.d1 d1]]) + local d2s ([set d2 [if [this.points.0.d2 >= 0] this.points.0.d2 d2]]) local pdxs (0) local pdys (0) - local notSubdivideds () local samples : fallback _samples this.samples SAMPLES local shapes () local subSegments () local p0 this.points.0 - local arclengthSofar 0 for [local j 1] [j < this.points.length] [inc j] : begin { local p1 this.points`j piecewise { p1.onCurve : begin { subSegments.push : local seg : new Bezier p0.x p0.y [[p0.x + p1.x] / 2] [[p0.y + p1.y] / 2] p1.x p1.y - arclengthSofar = arclengthSofar + [seg.length] - if [not p1.subdivided] : begin { - ts.push arclengthSofar - d1s.push : set d1 [if [p1.d1 >= 0] p1.d1 d1] - d2s.push : set d2 [if [p1.d2 >= 0] [-p1.d2] d2] - local normalpt : seg.normal 1 - pdxs.push : if [p1.pdx !== nothing] [p1.pdx - normalpt.x] 0 - pdys.push : if [p1.pdy !== nothing] [p1.pdy - normalpt.y] 0 - set notSubdivideds.[subSegments.length - 1] true - } + d1s.push : set d1 [if [p1.d1 >= 0] p1.d1 d1] + d2s.push : set d2 [if [p1.d2 >= 0] p1.d2 d2] + local normalpt : seg.normal 1 + pdxs.push : if [p1.pdx !== nothing] [p1.pdx - normalpt.x] 0 + pdys.push : if [p1.pdy !== nothing] [p1.pdy - normalpt.y] 0 p0 = p1 } p1.cubic : begin { local p2 this.points`[j + 1] local p3 this.points`[j + 2] subSegments.push : local seg : new Bezier p0.x p0.y p1.x p1.y p2.x p2.y p3.x p3.y - arclengthSofar = arclengthSofar + [seg.length] - if [not p3.subdivided] : begin { - ts.push arclengthSofar - d1s.push : set d1 [if [p3.d1 >= 0] p3.d1 d1] - d2s.push : set d2 [if [p3.d2 >= 0] [-p3.d2] d2] - local normalpt : seg.normal 1 - pdxs.push : if [p3.pdx !== nothing] [p3.pdx - normalpt.x] 0 - pdys.push : if [p3.pdy !== nothing] [p3.pdy - normalpt.y] 0 - set notSubdivideds.[subSegments.length - 1] true - } + d1s.push : set d1 [if [p3.d1 >= 0] p3.d1 d1] + d2s.push : set d2 [if [p3.d2 >= 0] p3.d2 d2] + local normalpt : seg.normal 1 + pdxs.push : if [p3.pdx !== nothing] [p3.pdx - normalpt.x] 0 + pdys.push : if [p3.pdy !== nothing] [p3.pdy - normalpt.y] 0 p0 = p3 j = j + 2 } true : begin { local p2 this.points`[j + 1] subSegments.push : local seg : new Bezier p0.x p0.y p1.x p1.y p2.x p2.y - arclengthSofar = arclengthSofar + [seg.length] - if [not p2.subdivided] : begin { - ts.push arclengthSofar - d1s.push : set d1 [if [p2.d1 >= 0] p2.d1 d1] - d2s.push : set d2 [if [p2.d2 >= 0] [-p2.d2] d2] - local normalpt : seg.normal 1 - pdxs.push : if [p2.pdx !== nothing] [p2.pdx - normalpt.x] 0 - pdys.push : if [p2.pdy !== nothing] [p2.pdy - normalpt.y] 0 - set notSubdivideds.[subSegments.length - 1] true - } + d1s.push : set d1 [if [p2.d1 >= 0] p2.d1 d1] + d2s.push : set d2 [if [p2.d2 >= 0] p2.d2 d2] + local normalpt : seg.normal 1 + pdxs.push : if [p2.pdx !== nothing] [p2.pdx - normalpt.x] 0 + pdys.push : if [p2.pdy !== nothing] [p2.pdy - normalpt.y] 0 p0 = p2 j = j + 1 } @@ -212,44 +177,43 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { if [this.points.0.pdx !== nothing] : set pdxs.0 [this.points.0.pdx - [subSegments.0.normal 0].x] if [this.points.0.pdy !== nothing] : set pdys.0 [this.points.0.pdy - [subSegments.0.normal 0].y] - local f1 : smooth [xs-array ts] [ys-array d1s] - local f2 : smooth [xs-array ts] [ys-array d2s] - local fpdx : smooth [xs-array ts] [ys-array pdxs] - local fpdy : smooth [xs-array ts] [ys-array pdys] + local f1 : smooth [xs-array 0 d1s.length] [ys-array d1s] + local f2 : smooth [xs-array 0 d2s.length] [ys-array [d2s.map [[x] -> [-x]]]] + local fpdx : smooth [xs-array 0 d1s.length] [ys-array pdxs] + local fpdy : smooth [xs-array 0 d2s.length] [ys-array pdys] local left () local right () - set arclengthSofar 0 for [local j 0] [j < subSegments.length] [inc j] : begin { local curve subSegments`j - local segLength : curve.length + local arcLength : curve.length local segLengths (0) foreach sample [range 1 till samples] : begin { segLengths.push : curve.split 0 [sample / samples] :.length } - left.push [begin [local last [computeOffsetPoint curve arclengthSofar arclengthSofar segLength f1 fpdx fpdy]] (.x last.x .y last.y .onCurve true)] - right.push [begin [local last [computeOffsetPoint curve arclengthSofar arclengthSofar segLength f2 fpdx fpdy]] (.x last.x .y last.y .onCurve true)] + left.push [begin [local last [computeOffsetPoint curve j j f1 fpdx fpdy]] (.x last.x .y last.y .onCurve true)] + right.push [begin [local last [computeOffsetPoint curve j j f2 fpdx fpdy]] (.x last.x .y last.y .onCurve true)] foreach sample [range 0 samples] : begin { - local t : arclengthSofar + segLengths.(sample) - local tn : arclengthSofar + segLengths.[sample + 1] + local t : j + segLengths.(sample) / arcLength + local tn : j + segLengths.[sample + 1] / arcLength - local lthis : computeOffsetPoint curve t arclengthSofar segLength f1 fpdx fpdy - local rthis : computeOffsetPoint curve t arclengthSofar segLength f2 fpdx fpdy - local lnext : computeOffsetPoint curve tn arclengthSofar segLength f1 fpdx fpdy - local rnext : computeOffsetPoint curve tn arclengthSofar segLength f2 fpdx fpdy - local lnthis1 : computeOffsetPoint curve [t + TINY] arclengthSofar segLength f1 fpdx fpdy - local rnthis1 : computeOffsetPoint curve [t + TINY] arclengthSofar segLength f2 fpdx fpdy - local lnnext1 : computeOffsetPoint curve [tn - TINY] arclengthSofar segLength f1 fpdx fpdy - local rnnext1 : computeOffsetPoint curve [tn - TINY] arclengthSofar segLength f2 fpdx fpdy - local lnthis2 : computeOffsetPoint curve [t + 2 * TINY] arclengthSofar segLength f1 fpdx fpdy - local rnthis2 : computeOffsetPoint curve [t + 2 * TINY] arclengthSofar segLength f2 fpdx fpdy - local lnnext2 : computeOffsetPoint curve [tn - 2 * TINY] arclengthSofar segLength f1 fpdx fpdy - local rnnext2 : computeOffsetPoint curve [tn - 2 * TINY] arclengthSofar segLength f2 fpdx fpdy - local lnthis3 : computeOffsetPoint curve [t + 3 * TINY] arclengthSofar segLength f1 fpdx fpdy - local rnthis3 : computeOffsetPoint curve [t + 3 * TINY] arclengthSofar segLength f2 fpdx fpdy - local lnnext3 : computeOffsetPoint curve [tn - 3 * TINY] arclengthSofar segLength f1 fpdx fpdy - local rnnext3 : computeOffsetPoint curve [tn - 3 * TINY] arclengthSofar segLength f2 fpdx fpdy + local lthis : computeOffsetPoint curve t j f1 fpdx fpdy + local rthis : computeOffsetPoint curve t j f2 fpdx fpdy + local lnext : computeOffsetPoint curve tn j f1 fpdx fpdy + local rnext : computeOffsetPoint curve tn j f2 fpdx fpdy + local lnthis1 : computeOffsetPoint curve [t + TINY] j f1 fpdx fpdy + local rnthis1 : computeOffsetPoint curve [t + TINY] j f2 fpdx fpdy + local lnnext1 : computeOffsetPoint curve [tn - TINY] j f1 fpdx fpdy + local rnnext1 : computeOffsetPoint curve [tn - TINY] j f2 fpdx fpdy + local lnthis2 : computeOffsetPoint curve [t + 2 * TINY] j f1 fpdx fpdy + local rnthis2 : computeOffsetPoint curve [t + 2 * TINY] j f2 fpdx fpdy + local lnnext2 : computeOffsetPoint curve [tn - 2 * TINY] j f1 fpdx fpdy + local rnnext2 : computeOffsetPoint curve [tn - 2 * TINY] j f2 fpdx fpdy + local lnthis3 : computeOffsetPoint curve [t + 3 * TINY] j f1 fpdx fpdy + local rnthis3 : computeOffsetPoint curve [t + 3 * TINY] j f2 fpdx fpdy + local lnnext3 : computeOffsetPoint curve [tn - 3 * TINY] j f1 fpdx fpdy + local rnnext3 : computeOffsetPoint curve [tn - 3 * TINY] j f2 fpdx fpdy local dlthis [dforward lthis lnthis1 lnthis2 lnthis3] local drthis [dforward rthis rnthis1 rnthis2 rnthis3] @@ -270,14 +234,6 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { right.push (.x rnext.x .y rnext.y .onCurve true) }] } - arclengthSofar = arclengthSofar + segLength - if notSubdivideds.(j) : begin { - shapes.push : left.concat [right.reverse] - set left () - set right () - } - } - if [left.length + right.length > 2] : begin { shapes.push : left.concat [right.reverse] set left () set right () diff --git a/support/transform.js b/support/transform.js index 88ec28994..0b35a4776 100644 --- a/support/transform.js +++ b/support/transform.js @@ -3,8 +3,7 @@ exports.transformPoint = function(tfm, pt){ x : pt.x * tfm.xx + pt.y * tfm.yx + tfm.x, y : pt.x * tfm.xy + pt.y * tfm.yy + tfm.y, onCurve: pt.onCurve, - cubic: pt.cubic, - subdivided: pt.subdivided + cubic: pt.cubic } } exports.inverse = function(tfm){ @@ -26,7 +25,6 @@ exports.untransform = function(tfm, pt){ x : (xx * tfm.yy - yy * tfm.yx) / denom, y : (yy * tfm.xx - xx * tfm.xy) / denom, onCurve: pt.onCurve, - cubic: pt.cubic, - subdivided: pt.subdivided + cubic: pt.cubic } } \ No newline at end of file