Move font building related files to font-src
This commit is contained in:
parent
9a2f862631
commit
c48bc20aa2
56 changed files with 18 additions and 18 deletions
199
font-src/gen/kits/spiro-kit.ptl
Normal file
199
font-src/gen/kits/spiro-kit.ptl
Normal file
|
@ -0,0 +1,199 @@
|
|||
import 'spiro' as SpiroJs
|
||||
import '../../support/spiro-expand' as SpiroExpansionContext
|
||||
import '../../support/curve-util' as CurveUtil
|
||||
import '../../support/transform' as Transform
|
||||
import '../../support/utils' as [object fallback mix bez2 bez3]
|
||||
|
||||
export : define [SetupBuilders args] : begin
|
||||
define [object para Glyph Contrast globalTransform Stroke Superness] args
|
||||
|
||||
define [g4 x y f] {.x x .y y .type 'g4' .af f}
|
||||
define [g2 x y f] {.x x .y y .type 'g2' .af f}
|
||||
define [corner x y f] {.x x .y y .type 'corner' .af f}
|
||||
define [flat x y f] {.x x .y y .type 'left' .af f}
|
||||
define [curl x y f] {.x x .y y .type 'right' .af f}
|
||||
define [close f] {.type 'close' .af f}
|
||||
define [end f] {.type 'end' .af f}
|
||||
|
||||
define straight {.l flat .r curl}
|
||||
|
||||
#directional bi-knots
|
||||
let
|
||||
directions {{.name 'up' .x 0 .y 1}, {.name 'down' .x 0 .y (-1)}, {.name 'left' .x (-1) .y 0}, {.name 'right' .x 1 .y 0}}
|
||||
adhensions {{.name 'start' .l 0 .r 0.01}, {.name 'mid', .l (-0.005) .r 0.005}, {.name 'end', .l (-0.01) .r 0}}
|
||||
knottypes {g4, g2, corner, straight}
|
||||
foreach [direction : items-of directions] : let [d direction] : begin
|
||||
foreach [knottype : items-of knottypes] : let [kt knottype] : begin
|
||||
set kt.(d.name) {.}
|
||||
foreach [adh : items-of adhensions] : let [a adh] : begin
|
||||
set kt.(d.name).(a.name) : lambda [x y f] : list
|
||||
[fallback kt.l kt] (x + d.x * a.l) (y + d.y * a.l) f
|
||||
[fallback kt.r kt] (x + d.x * a.r) (y + d.y * a.r) f
|
||||
|
||||
# Aux functions
|
||||
define [widths l r] : lambda [] : if this.setWidth : this.setWidth l r
|
||||
define [widths.lhs w] : widths [fallback w Stroke] 0
|
||||
define [widths.rhs w] : widths 0 [fallback w Stroke]
|
||||
define [widths.center w] : widths ([fallback w Stroke] / 2) ([fallback w Stroke] / 2)
|
||||
|
||||
# Gizmo handler
|
||||
define [disable-gizmo] : lambda [] : set this.gizmo [Transform.Id]
|
||||
define [disable-contrast] : lambda [] : set this.contrast 1
|
||||
|
||||
define [heading d] : lambda [] : if (this.headsTo) : this.headsTo d
|
||||
define [widths.heading l r d] : lambda [] : begin
|
||||
if this.setWidth : this.setWidth l r
|
||||
if this.headsTo : this.headsTo d
|
||||
define [widths.lhs.heading w d] : lambda [] : begin
|
||||
if this.setWidth : this.setWidth [fallback w Stroke] 0
|
||||
if this.headsTo : this.headsTo d
|
||||
define [widths.rhs.heading w d] : lambda [] : begin
|
||||
if this.setWidth : this.setWidth 0 [fallback w Stroke]
|
||||
if this.headsTo : this.headsTo d
|
||||
define [widths.center.heading w d] : lambda [] : begin
|
||||
if this.setWidth : this.setWidth ([fallback w Stroke] / 2) ([fallback w Stroke] / 2)
|
||||
if this.headsTo : this.headsTo d
|
||||
define [unimportant] : begin
|
||||
if (this.points && this.points.length && this.points.(this.points.length - 1)) : this.points.(this.points.length - 1).subdivided = true
|
||||
if (this.controlKnots && this.controlKnots.length && this.controlKnots.(this.controlKnots.length - 1)) : this.controlKnots.(this.controlKnots.length - 1).unimportant = true
|
||||
define [important] nothing
|
||||
|
||||
# Interpolation pesudoknots
|
||||
define [afInterpolate before after args] : g4
|
||||
mix before.x after.x args.rx
|
||||
mix before.y after.y args.ry
|
||||
fallback args.raf unimportant
|
||||
define [afInterpolateG2 before after args] : g2
|
||||
mix before.x after.x args.rx
|
||||
mix before.y after.y args.ry
|
||||
fallback args.raf unimportant
|
||||
define [afInterpolateThem before after args] : begin
|
||||
local innerKnots {}
|
||||
foreach {rx ry rt} [items-of args.rs] : innerKnots.push : [fallback args.ty g2]
|
||||
mix before.x after.x rx
|
||||
mix before.y after.y ry
|
||||
piecewise
|
||||
(args.raf && args.raf.blend && (rt != nothing)) [args.raf.blend rt]
|
||||
args.raf args.raf
|
||||
true unimportant
|
||||
return innerKnots
|
||||
|
||||
define [alsoThru rx ry raf] {.type 'interpolate' .rx rx .ry ry .raf raf .af afInterpolate}
|
||||
set alsoThru.g2 : lambda [rx ry raf] {.type 'interpolate' .rx rx .ry ry .raf raf .af afInterpolateG2}
|
||||
define [alsoThruThem rs raf ty] {.type 'interpolate' .rs rs .raf raf .ty ty .af afInterpolateThem}
|
||||
define [bezControlsImpl x1 y1 x2 y2 samples raf ty] : begin
|
||||
local rs {}
|
||||
foreach j [range 1 samples] : rs.push : list
|
||||
bez3 0 x1 x2 1 (j / samples)
|
||||
bez3 0 y1 y2 1 (j / samples)
|
||||
j / samples
|
||||
alsoThruThem rs raf
|
||||
define [bezcontrols x1 y1 x2 y2 _samples raf]
|
||||
bezControlsImpl x1 y1 x2 y2 [fallback _samples 3] raf
|
||||
define [quadcontrols x1 y1 _samples raf]
|
||||
bezControlsImpl (x1 * 2 / 3) (y1 * 2 / 3) [mix 1 x1 (2 / 3)] [mix 1 y1 (2 / 3)] [fallback _samples 3] raf
|
||||
set quadcontrols.g4 : lambda [x1 y1 _samples raf]
|
||||
bezControlsImpl (x1 * 2 / 3) (y1 * 2 / 3) [mix 1 x1 (2 / 3)] [mix 1 y1 (2 / 3)] [fallback _samples 3] raf g4
|
||||
|
||||
define DEFAULT_STEPS 6
|
||||
define {jhv, jvh} : let [cache {}] : begin
|
||||
local [build samples _superness] : begin
|
||||
local superness : fallback _superness Superness
|
||||
local hv {}
|
||||
local vh {}
|
||||
foreach [j : range 1 samples] : begin
|
||||
local theta : j / samples * Math.PI / 2
|
||||
local c : Math.pow [Math.cos theta] (2 / superness)
|
||||
local s : Math.pow [Math.sin theta] (2 / superness)
|
||||
hv.push { s (1 - c) }
|
||||
vh.push { (1 - c) s }
|
||||
return {.hv hv .vh vh}
|
||||
local [hv samples _superness] : begin
|
||||
if (_superness) : return [build samples _superness].hv
|
||||
if (!cache.(samples)) : set cache.(samples) : build samples _superness
|
||||
return cache.(samples).hv
|
||||
local [vh samples _superness] : begin
|
||||
if (_superness) : return [build samples _superness].vh
|
||||
if (!cache.(samples)) : set cache.(samples) : build samples _superness
|
||||
return cache.(samples).vh
|
||||
list hv vh
|
||||
define [archv samples superness] : alsoThruThem [jhv [fallback samples DEFAULT_STEPS] superness]
|
||||
define [arcvh samples superness] : alsoThruThem [jvh [fallback samples DEFAULT_STEPS] superness]
|
||||
|
||||
define [complexThru] : begin
|
||||
local a : {}.slice.call arguments
|
||||
return {.type 'interpolate' .af [lambda [before after args] : begin \\
|
||||
local ks {}
|
||||
foreach knot [items-of a] : ks.push [knot.af.call this before after knot]
|
||||
return ks
|
||||
]}
|
||||
define [flatten knots] : begin
|
||||
local a {}
|
||||
foreach p [items-of knots] : piecewise
|
||||
(p <@ Array) : set a : a.concat [flatten p]
|
||||
true : a.push p
|
||||
return a
|
||||
define [prepareSpiroKnots _knots s] : begin
|
||||
local closed false
|
||||
local lastafs {}
|
||||
local knots _knots
|
||||
while (knots.0 && knots.0 <@ Function) : begin
|
||||
knots.0.call s
|
||||
set knots : knots.slice 1
|
||||
while (knots.(knots.length - 1) && (knots.(knots.length - 1).type === 'close' || knots.(knots.length - 1).type === 'end')) : begin
|
||||
set closed : knots.(knots.length - 1).type === 'close'
|
||||
lastafs.push knots.(knots.length - 1).af
|
||||
set knots : knots.slice 0 (-1)
|
||||
set knots : flatten knots
|
||||
if closed : knots.push knots.0
|
||||
foreach j [range 0 knots.length] : if (knots.(j) && knots.(j).type === 'interpolate') : begin
|
||||
set knots.(j) : knots.(j).af.call s knots.(j - 1) knots.(j + 1) knots.(j)
|
||||
if closed : knots.pop
|
||||
return {.knots [flatten knots] .closed closed .lastafs lastafs}
|
||||
|
||||
define QUAD false
|
||||
define PRECISION 0.5
|
||||
define [dispiro] : let [args : {}.slice.call arguments 0] : lambda [dontinc] : begin
|
||||
local s : new SpiroExpansionContext
|
||||
set s.gizmo : this.gizmo || globalTransform
|
||||
local {.knots knots .closed closed .lastafs lastafs} : prepareSpiroKnots [{}.slice.call args 0] s
|
||||
foreach knot [items-of knots] : let [ty knot.type] [af knot.af] : begin
|
||||
set knot.af : lambda [] : begin
|
||||
this.setType ty
|
||||
if af : af.apply this args
|
||||
SpiroJs.spiroToArcsOnContext knots closed s
|
||||
foreach af [items-of lastafs] : if af : af.call s
|
||||
|
||||
local {.lhs lhs .rhs rhs} : s.expand [fallback s.contrast Contrast]
|
||||
if closed : then
|
||||
local g : new CurveUtil.ArcFlattener
|
||||
SpiroJs.spiroToBezierOnContext [lhs.slice 0 (-1)] true g QUAD PRECISION
|
||||
local lhsContour g.contours.0
|
||||
set g.contours {}
|
||||
SpiroJs.spiroToBezierOnContext [rhs.reverse :.slice 0 (-1)] true g QUAD PRECISION
|
||||
local rhsContour g.contours.0
|
||||
set g.contours {[lhsContour.concat rhsContour]}
|
||||
: else : begin
|
||||
local g : new CurveUtil.ArcFlattener
|
||||
lhs.0.type = rhs.0.type = lhs.(lhs.length - 1).type = rhs.(rhs.length - 1).type = 'corner'
|
||||
SpiroJs.spiroToBezierOnContext [lhs.concat : rhs.reverse] true g QUAD PRECISION
|
||||
|
||||
set g.knots knots
|
||||
set g.lhsKnots lhs
|
||||
set g.rhsKnots rhs
|
||||
this.includeGeometry g 0 0
|
||||
return g
|
||||
|
||||
define [spiro-outline] : let [k : {}.slice.call arguments 0] : lambda [dontinc] : begin
|
||||
local g : new CurveUtil.ArcFlattener (this.gizmo || globalTransform)
|
||||
local {.knots knots .closed closed .lastafs lastafs} : prepareSpiroKnots k g
|
||||
SpiroJs.spiroToBezierOnContext knots closed g QUAD PRECISION
|
||||
foreach af [items-of lastafs] : if af : af.call g
|
||||
this.includeGeometry g 0 0
|
||||
return g
|
||||
|
||||
return [object
|
||||
g4 g2 corner flat curl close end straight
|
||||
widths disable-gizmo disable-contrast heading unimportant important
|
||||
alsoThru alsoThruThem bezcontrols quadcontrols archv arcvh complexThru
|
||||
dispiro spiro-outline]
|
Loading…
Add table
Add a link
Reference in a new issue