Rebuilt /U, /J, /m, /n, etc... with spiros.

This commit is contained in:
be5invis 2015-08-18 06:38:58 +08:00
parent 9ef872033f
commit 3b7c951e76
11 changed files with 247 additions and 230 deletions

View file

@ -214,91 +214,6 @@ define [buildFont para recursive] : begin {
set font.'OS/2'.sxHeight XH set font.'OS/2'.sxHeight XH
set font.post.italicAnvle [0 - para.italicangle] set font.post.italicAnvle [0 - para.italicangle]
### Spiro constructions
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 [unimportant] : this.points.[this.points.length - 1].subdivided = true
define [afInterpolate before after args] : g4 [mix before.x after.x args.rx] [mix before.y after.y args.ry] unimportant
define [bez3 a b c d t] : [1 - t] * [1 - t] * [1 - t] * a + 3 * [1 - t] * [1 - t] * t * b +3 * t * t * [1 - t] * c + t * t * t * d
define [afInterpolateThem before after args] : begin {
local knots ()
foreach (rx ry) [items-of args.rs] : knots.push : g4 [mix before.x after.x rx] [mix before.y after.y ry] unimportant
return knots
}
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 [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 [prepare f] (.type 'prepare' .af f)
define [widths l r] : lambda [] : this.set-width l r
define [widths.lhs w] : prepare : widths [fallback w STROKE] 0
define [widths.rhs w] : prepare : widths 0 [fallback w STROKE]
define [widths.center w] : prepare : widths [[fallback w STROKE] / 2] [[fallback w STROKE] / 2]
define [widths.heading l r d] : lambda [] : begin { this.set-width l r; this.heads-to d }
define [heading d] : lambda [] : this.heads-to d
define [alsothru rx ry] (.type 'interpolate' .rx rx .ry ry .af afInterpolate)
define [alsothruthem rs] (.type 'interpolate' .rs rs .af afInterpolateThem)
define [bezcontrols x1 y1 x2 y2 _samples] : begin {
local samples : fallback _samples 2
local tiny 0.01
local rs (([bez3 0 x1 x2 1 tiny] [bez3 0 y1 y2 1 tiny]))
foreach j [range 1 samples] : rs.push : list {
bez3 0 x1 x2 1 [mix tiny [1 - tiny] [j / samples]]
bez3 0 y1 y2 1 [mix tiny [1 - tiny] [j / samples]]
}
rs.push ([bez3 0 x1 x2 1 [1 - tiny]] [bez3 0 y1 y2 1 [1 - tiny]])
alsothruthem rs
}
define [archv samples] : bezcontrols KAPPA_SPIRO_ARC 0 1 [1 - KAPPA_SPIRO_ARC] samples
define [arcvh samples] : bezcontrols 0 KAPPA_SPIRO_ARC [1 - KAPPA_SPIRO_ARC] 1 samples
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 [spiro] : begin {
local s : new Stroke
s.set-transform globalTransform
local knots : ().slice.call arguments 0
local closed false
local lastaf
if [knots.0 && knots.0.type === 'prepare'] : begin {
knots.0.af.call s
set knots : knots.slice 1
}
if [knots.[knots.length - 1] && knots.[knots.length - 1].type === 'close'] : begin {
set closed true
set lastaf 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
set knots : flatten knots
s.set-samples 2
libspiro.spiroToBezierOnContext knots closed s
if lastaf : lastaf.call s
return s
}
### Necessary macros ### Necessary macros
define-macro glyph-construction : syntax-rules { define-macro glyph-construction : syntax-rules {
@`[glyph-construction @::steps] ('.syntactic-closure' @`[lambda [] [begin { @`[glyph-construction @::steps] ('.syntactic-closure' @`[lambda [] [begin {
@ -397,6 +312,101 @@ define [buildFont para recursive] : begin {
include glyphs`oldid AS_BASE include glyphs`oldid AS_BASE
} }
### Spiro constructions
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 [unimportant] : if [this.points && this.points.length && this.points.[this.points.length - 1]] : this.points.[this.points.length - 1].subdivided = true
define [afInterpolate before after args] : g4 [mix before.x after.x args.rx] [mix before.y after.y args.ry] unimportant
define [bez3 a b c d t] : [1 - t] * [1 - t] * [1 - t] * a + 3 * [1 - t] * [1 - t] * t * b +3 * t * t * [1 - t] * c + t * t * t * d
define [afInterpolateThem before after args] : begin {
local knots ()
foreach (rx ry) [items-of args.rs] : knots.push : g4 [mix before.x after.x rx] [mix before.y after.y ry] unimportant
return knots
}
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 [prepare f] (.type 'prepare' .af f)
define [widths l r] : lambda [] : this.set-width l r
define [widths.lhs w] : prepare : widths [fallback w STROKE] 0
define [widths.rhs w] : prepare : widths 0 [fallback w STROKE]
define [widths.center w] : prepare : widths [[fallback w STROKE] / 2] [[fallback w STROKE] / 2]
define [widths.heading l r d] : lambda [] : begin { this.set-width l r; this.heads-to d }
define [heading d] : lambda [] : this.heads-to d
define [alsothru rx ry] (.type 'interpolate' .rx rx .ry ry .af afInterpolate)
define [alsothruthem rs] (.type 'interpolate' .rs rs .af afInterpolateThem)
define [bezcontrols x1 y1 x2 y2 _samples notiny] : begin {
local samples : fallback _samples 2
local tiny 0.005
local rs ()
if [not notiny] : rs.push ([bez3 0 x1 x2 1 tiny] [bez3 0 y1 y2 1 tiny])
foreach j [range 1 samples] : rs.push : list {
bez3 0 x1 x2 1 [mix tiny [1 - tiny] [j / samples]]
bez3 0 y1 y2 1 [mix tiny [1 - tiny] [j / samples]]
}
if [not notiny] : rs.push ([bez3 0 x1 x2 1 [1 - tiny]] [bez3 0 y1 y2 1 [1 - tiny]])
alsothruthem rs
}
define [quadcontrols x1 y1 samples] : bezcontrols [x1 * 2 / 3] [y1 * 2 / 3] [mix 1 x1 [2 / 3]] [mix 1 y1 [2 / 3]] samples
define [archv samples notiny] : bezcontrols KAPPA_SPIRO_ARC 0 1 [1 - KAPPA_SPIRO_ARC] samples notiny
define [arcvh samples notiny] : bezcontrols 0 KAPPA_SPIRO_ARC [1 - KAPPA_SPIRO_ARC] 1 samples notiny
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 [prepareSpiroKnots knots s] : begin {
local closed false
local lastafs ()
while [knots.0 && knots.0.type === 'prepare'] : begin {
knots.0.af.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 [spiro] : begin {
local s : new Stroke
s.set-transform globalTransform
s.set-samples 1
local (.knots knots .closed closed .lastafs lastafs) : prepareSpiroKnots [().slice.call arguments 0] s
libspiro.spiroToBezierOnContext knots closed s
foreach af : [items-of lastafs] : if af : af.call s
return s
}
define [spiro-outline] : let [k : ().slice.call arguments 0] : glyph-construction {
local (.knots knots .closed closed .lastafs lastafs) : prepareSpiroKnots k this
libspiro.spiroToBezierOnContext knots closed this
foreach af : [items-of lastafs] : if af : af.call this
}
###### HERE WE GO! ###### HERE WE GO!
create-glyph 'space' : glyph-construction { create-glyph 'space' : glyph-construction {

View file

@ -160,29 +160,44 @@ define [xStrand _leftx lefty _rightx righty turn straight tension] : begin {
:.concat : halfXStrand _rightx righty middlex middley turn straight tension :.concat : halfXStrand _rightx righty middlex middley turn straight tension
} }
define [nShoulder left middle right fine _top _bottom _sma _smb _wide] : begin { define [nShoulder left middle right fine _top _bottom _sma _smb _wide] : glyph-construction {
local top : fallback _top XH local top : fallback _top XH
local bottom : fallback _bottom 0 local bottom : fallback _bottom 0
local sma : fallback _sma SMALLSMOOTHA local sma : fallback _sma SMALLSMOOTHA
local smb : fallback _smb SMALLSMOOTHB local smb : fallback _smb SMALLSMOOTHB
local stroke : fallback _wide STROKE local stroke : fallback _wide STROKE
local band : new Stroke include : spiro {
:.set-transform globalTransform widths.lhs stroke
:.start-from right bottom flat right bottom [heading UPWARD]
:.heads-to UPWARD curl right [top - smb]
:.set-width stroke 0 arcvh
:.line-to right [top - smb] g4 middle [top - O] [heading LEFTWARD]
:.arc-vh-to middle [top - O] }
:.heads-to LEFTWARD start-from middle [top - O - stroke]
:.to-outline arc-hv-to left [top - sma]
local shoulder : new Stroke line-to [left - fine] [top - sma]
:.set-transform globalTransform arc-vh-to middle [top - O]
:.start-from middle [top - O - stroke] }
:.arc-hv-to left [top - sma]
:.line-to [left - fine] [top - sma]
:.arc-vh-to middle [top - O]
return : band.concat (shoulder.points) define [mShoulderSpiro left right top bottom width fine] : glyph-construction {
local fix : ITALICCORS * ITALICCOR * width / STROKE
include : spiro-outline {
corner [right - width * ITALICCOR] bottom
curl [right - width * ITALICCOR] [top - SMALLSMOOTHB + fix]
arcvh 8 'no-tiny'
g2 [mix left [right - width * ITALICCOR] 0.5] [top - O - width]
archv 8 'no-tiny'
flat left [top - SMALLSMOOTHA - fix]
corner left [top - SMALLSMOOTHA - fix - 1]
corner [left - fine] [top - SMALLSMOOTHA - 1]
curl [left - fine] [top - SMALLSMOOTHA]
arcvh 8 'no-tiny'
g2 [mix [left - fine * ITALICCOR] right 0.5] [top - O]
archv 8 'no-tiny'
flat right [top - SMALLSMOOTHB]
corner right bottom
close
}
} }
define [XSHookUpper top left _middle right smooth hook _stroke] : glyph-construction { define [XSHookUpper top left _middle right smooth hook _stroke] : glyph-construction {
@ -356,29 +371,31 @@ define [vdual newid unicode id spacing] : create-glyph [fallback newid : 'double
apply-transform : Translate 0 [spacing / 2] apply-transform : Translate 0 [spacing / 2]
apply-transform : Italify apply-transform : Italify
} }
define [hookstart y] (.type 'interpolate' .af [lambda [before after] : begin { define [hookstart y p f] (.type 'interpolate' .af [lambda [before after] : begin {
local atBottom : after.y > y local atBottom : after.y > y
local ltr : after.x > before.x local ltr : after.x > before.x
before.x = before.x - OXHOOK * [if ltr [-1] 1] before.x = before.x - OXHOOK * [if ltr [-1] 1]
local hv : archv local hv : archv
local mx [[mix after.x before.x SBALANCE] + [if atBottom 1 [-1]] * OMIDCOR_S] local mixr : fallback p : linreg 1 0.5 [SMALLSMOOTH / HOOK] 0.53 [[after.y - y] / [before.y - y]]
local mx [[mix after.x before.x mixr] + [if atBottom 1 [-1]] * OMIDCOR_S]
return : list { return : list {
g4 mx y g4 mx y f
hv.af.call this (.x mx .y y) after hv hv.af.call this (.x mx .y y) after hv
} }
}]) }])
define [hookend y dontextend] (.type 'interpolate' .af [lambda [before after] : begin { define [hookend y p f dontextend] (.type 'interpolate' .af [lambda [before after] : begin {
local atBottom : before.y > y local atBottom : before.y > y
local ltr : after.x > before.x local ltr : after.x > before.x
after.x = after.x + OXHOOK * [if ltr [-1] 1] after.x = after.x + OXHOOK * [if ltr [-1] 1]
local vh : arcvh local vh : arcvh
local mx [[mix before.x after.x SBALANCE] + [if atBottom 1 [-1]] * OMIDCOR_S] local mixr : fallback p : linreg 1 0.5 [SMALLSMOOTH / HOOK] 0.53 [[before.y - y] / [after.y - y]]
local mx [[mix before.x after.x mixr] + [if atBottom 1 [-1]] * OMIDCOR_S]
if [!dontextend && atBottom && ltr] : begin { if [!dontextend && atBottom && ltr] : begin {
after.x = after.x + TAILADJX * globalTransform.yx after.x = after.x + TAILADJX * globalTransform.yx
after.y = after.y - TAILADJY * globalTransform.yx after.y = after.y - TAILADJY * globalTransform.yx
} }
return : list { return : list {
vh.af.call this before (.x mx .y y) vh vh.af.call this before (.x mx .y y) vh
g4 mx y g4 mx y f
} }
}]) }])

View file

@ -434,15 +434,16 @@ create-glyph 'sigmafinal' : glyph-construction {
create-glyph 'upsilon' : glyph-construction { create-glyph 'upsilon' : glyph-construction {
assign-unicode 0x3C5 assign-unicode 0x3C5
include eMarks include eMarks
include : create-stroke include : spiro {
:.start-from SB XH widths.lhs
:.heads-to DOWNWARD flat SB XH [heading DOWNWARD]
:.set-width STROKE 0 curl SB SMALLSMOOTHB
:.line-to SB SMALLSMOOTHB arcvh
:.arc-vh-to [MIDDLE + OMIDCOR_S] O g4 [MIDDLE + OMIDCOR_S] O
:.arc-hv-to RIGHTSB SMALLSMOOTHA archv
:.line-to RIGHTSB XH flat RIGHTSB SMALLSMOOTHA
:.heads-to UPWARD curl RIGHTSB XH [heading UPWARD]
}
} }
create-glyph 'tau' : glyph-construction { create-glyph 'tau' : glyph-construction {
assign-unicode 0x3C4 assign-unicode 0x3C4

View file

@ -354,15 +354,16 @@ create-glyph 'Q' : glyph-construction {
reverse-last reverse-last
} }
define [UShape top bottom stroke] : glyph-construction { define [UShape top bottom stroke] : glyph-construction {
include : create-stroke include : spiro {
:.start-from SB top widths.lhs
:.heads-to DOWNWARD flat SB top [heading DOWNWARD]
:.set-width [fallback stroke STROKE] 0 curl SB [bottom + SMOOTHB]
:.line-to SB [bottom + SMOOTHB] arcvh
:.arc-vh-to [MIDDLE + OMIDCOR_S] [bottom + O] g4 [MIDDLE + OMIDCOR_S] [bottom + O]
:.arc-hv-to RIGHTSB [bottom + SMOOTHA] archv
:.line-to RIGHTSB top flat RIGHTSB [bottom + SMOOTHA]
:.heads-to UPWARD curl RIGHTSB top [heading UPWARD]
}
} }
create-glyph 'U' : glyph-construction { create-glyph 'U' : glyph-construction {
set-width WIDTH set-width WIDTH
@ -503,12 +504,14 @@ create-glyph 'J.straight' : glyph-construction {
local smooth : HOOK + 0.75 * STROKE local smooth : HOOK + 0.75 * STROKE
local hookx [0.5 * SB + OXHOOK] local hookx [0.5 * SB + OXHOOK]
include : create-stroke include : spiro {
:.start-from [RIGHTSB - JBALANCE] CAP :.set-width 0 STROKE :.heads-to DOWNWARD widths.rhs
:.line-to [RIGHTSB - JBALANCE] smooth flat [RIGHTSB - JBALANCE] CAP [heading DOWNWARD]
:.arc-vh-to [mix hookx [RIGHTSB - JBALANCE] 0.5] O :.heads-to LEFTWARD curl [RIGHTSB - JBALANCE] smooth
:.curve-to [MIDDLE - kappa * [MIDDLE - SB] - SB * 0.5] O hookx HOOK hookend O
g4 hookx HOOK
}
} }
create-glyph 'J.shorthook' : glyph-construction { create-glyph 'J.shorthook' : glyph-construction {
set-width WIDTH set-width WIDTH

View file

@ -179,20 +179,22 @@ create-glyph 'e' : glyph-construction {
} }
} }
define [SmallTShape top bot] : glyph-construction { define [SmallTShape top bot] : glyph-construction {
local center [MIDDLE - TBALANCE - HALFSTROKE] local center : MIDDLE - TBALANCE + HALFSTROKE
local hookx [center + [WIDTH - SB * 2] * 0.78 - OXHOOK + TAILADJX * globalTransform.yx] local hookx [center - STROKE * 2 + [WIDTH - SB * 2] * 0.8 - OXHOOK + TAILADJX * globalTransform.yx]
local turn : mix center hookx [0.5 + globalTransform.yx * 0.5] local turn : [mix center hookx 0.5] + OMIDCOR_S - ITALICCORS
local smb : [turn - center] * 1.1 local smb : [turn - center] * 1.2
include : create-stroke include : spiro {
:.start-from center top widths.rhs
:.set-width STROKE 0 flat center top [heading DOWNWARD]
:.heads-to DOWNWARD curl center [bot + smb + STROKE]
:.line-to center [bot + smb] arcvh
:.arc-vh-to turn [bot + O] g4 turn [bot + O + STROKE]
:.curve-to [turn + [KAPPA_HOOK + TAILADJKAPPA * globalTransform.yx + 0.1] * [hookx - turn]] [bot + O] hookx [bot + HOOK - TAILADJY * globalTransform.yx] quadcontrols [KAPPA_HOOK + TAILADJKAPPA * globalTransform.yx + 0.1] 0
g4 hookx [bot + HOOK + STROKE * 0.24]
}
include : HBarTop [center + HALFSTROKE - LONGJUT + TBALANCE2] [center + HALFSTROKE + LONGJUT + TBALANCE2] [top * XH / CAP] include : HBarTop [center - HALFSTROKE - LONGJUT + TBALANCE2] [center - HALFSTROKE + LONGJUT + TBALANCE2] [top * XH / CAP]
} }
create-glyph 't' : glyph-construction { create-glyph 't' : glyph-construction {
set-width WIDTH set-width WIDTH
@ -291,28 +293,10 @@ create-glyph 'm' : glyph-construction {
include eMarks include eMarks
local sw : adviceBlackness 3.5 local sw : adviceBlackness 3.5
local m1 : [MIDDLE + SB + sw * 0.25] / 2 local m1 : mix [SB + O] [MIDDLE + sw / 2 * ITALICCOR] 0.5
local m2 : m1 + [MIDDLE - sw / 2 - SB] local m2 : mix [RIGHTSB - O] [MIDDLE - sw / 2 * ITALICCOR] 0.5
include : create-stroke include : mShoulderSpiro [SB + O + sw] [MIDDLE + sw / 2 * ITALICCOR] XH 0 sw [sw * 0.4]
:.start-from [MIDDLE - sw / 2] 0 include : mShoulderSpiro [MIDDLE + sw * 0.48 * ITALICCOR] [RIGHTSB - O] XH 0 sw [sw * 0.8]
:.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] [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
:.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] [XH - SMALLSMOOTHA]
:.heads-to DOWNWARD
:.set-width 0 [sw * 0.4]
include : create-stroke include : create-stroke
:.start-from [SB + O] 0 :.start-from [SB + O] 0
:.heads-to UPWARD :.heads-to UPWARD
@ -361,13 +345,13 @@ create-glyph 'dotlessi.italic' : glyph-construction {
local left : MIDDLE - HALFSTROKE local left : MIDDLE - HALFSTROKE
local right : mix SB RIGHTSB 1.1 local right : mix SB RIGHTSB 1.1
local middle : mix left right 0.55 local middle : mix left right 0.55
include : create-stroke include : spiro {
:.start-from left XH widths.lhs
:.set-width STROKE 0 flat left XH [heading DOWNWARD]
:.heads-to DOWNWARD curl left [SMALLSMOOTHB * 0.7]
:.line-to left [SMALLSMOOTHB * 0.7] hookend O
:.arc-vh-to [middle + OMIDCOR_S] O BKAPPA CKAPPA g4 right [SHOOK * 0.8]
:.curve-to [middle + [KAPPA_HOOK + TAILADJKAPPA * globalTransform.yx] * [right - middle]] O [right - OXHOOK + TAILADJX * globalTransform.yx] [SHOOK * 0.8 - TAILADJY * globalTransform.yx] }
include : create-stroke include : create-stroke
:.start-from [left - LONGJUT + ILBALANCE + HALFSTROKE] XH :.start-from [left - LONGJUT + ILBALANCE + HALFSTROKE] XH
:.set-width 0 STROKE :.set-width 0 STROKE
@ -390,12 +374,13 @@ create-glyph 'dotlessj.straight' : glyph-construction {
include pMarks include pMarks
set-anchor 'above' BASE [MIDDLE + JBALANCE] XH set-anchor 'above' BASE [MIDDLE + JBALANCE] XH
set-anchor 'overlay' BASE [MIDDLE + JBALANCE] [XH / 2] set-anchor 'overlay' BASE [MIDDLE + JBALANCE] [XH / 2]
include : create-stroke include : spiro {
:.start-from [MIDDLE + JBALANCE] XH widths.center
:.heads-to DOWNWARD flat [MIDDLE + JBALANCE] XH [heading DOWNWARD]
:.set-width HALFSTROKE HALFSTROKE curl [MIDDLE + JBALANCE] 0
:.line-to [MIDDLE + JBALANCE] 0 arcvh 3
:.arc-vh-to [MIDDLE + DESCENDER * 0.85] [DESCENDER + HALFSTROKE] g4 [MIDDLE + DESCENDER * 0.85] [DESCENDER + HALFSTROKE]
}
} }
create-glyph 'dotlessj.serifed' : glyph-construction { create-glyph 'dotlessj.serifed' : glyph-construction {
dont-export dont-export
@ -448,13 +433,13 @@ create-glyph 'l.italic' : glyph-construction {
local left : mix SB RIGHTSB 0.3 local left : mix SB RIGHTSB 0.3
local right : mix SB RIGHTSB 1.1 local right : mix SB RIGHTSB 1.1
local middle : mix left right 0.54 local middle : mix left right 0.54
include : create-stroke include : spiro {
:.start-from left CAP widths.lhs
:.set-width STROKE 0 flat left CAP [heading DOWNWARD]
:.heads-to DOWNWARD curl left [SMALLSMOOTHB * 0.75]
:.line-to left [SMALLSMOOTHB * 0.75] hookend O
:.arc-vh-to [middle + OMIDCOR_S] O BKAPPA CKAPPA g4 right SHOOK
:.curve-to [middle + [KAPPA_HOOK + TAILADJKAPPA * globalTransform.yx] * [right - middle]] O [right - OXHOOK + TAILADJX * globalTransform.yx] [SHOOK - TAILADJY * globalTransform.yx] }
include : create-stroke include : create-stroke
:.start-from SB CAP :.start-from SB CAP
:.set-width 0 STROKE :.set-width 0 STROKE
@ -650,19 +635,17 @@ create-glyph 'r' : glyph-construction {
assign-unicode 'r' assign-unicode 'r'
include eMarks include eMarks
local rhookx : RIGHTSB + JBALANCE / 2 local rhookx : RIGHTSB + JBALANCE / 2 - STROKE
local rmiddle : [mix [SB + RBALANCE + STROKE] [rhookx - HALFSTROKE] 0.5] - OMIDCOR_S local rmiddle : [mix [SB + RBALANCE + STROKE] [rhookx - HALFSTROKE] 0.5] - OMIDCOR_S
local barright : SB + STROKE * ITALICCOR + RBALANCE
include : create-stroke include : spiro {
:.start-from rhookx [XH - RHOOK] widths.rhs
:.set-width STROKE 0 g4 rhookx [XH - RHOOK - STROKE * 0.5]
:.curve-to [mix rmiddle rhookx KAPPA_RHOOK] XO rmiddle XO g4 [mix barright rhookx 0.52] [XO - STROKE] [heading LEFTWARD]
include : create-stroke archv
:.start-from [rmiddle + ITALICCORS] [XO - STROKE] flat barright [XH - SMALLSMOOTHA] [widths 0 [STROKE * 0.3]]
:.set-width 0 STROKE curl barright [XH - SMALLSMOOTHA - 1]
:.arc-hv-to [SB + STROKE * ITALICCOR + RBALANCE] [XH - SMALLSMOOTHA] }
:.heads-to DOWNWARD
:.set-width 0 [STROKE * 0.3]
include : create-stroke include : create-stroke
:.start-from [SB + RBALANCE] 0 :.start-from [SB + RBALANCE] 0
:.heads-to UPWARD :.heads-to UPWARD

View file

@ -50,13 +50,14 @@ create-glyph 'two' : glyph-construction {
set-width WIDTH set-width WIDTH
assign-unicode '2' assign-unicode '2'
local smb : SMOOTHB * 1
include : spiro { include : spiro {
widths.rhs widths.rhs
g4 [SB + OXHOOK] [CAP - HOOK] g4 [SB + OXHOOK] [CAP - HOOK]
g4 [[mix RIGHTSB SB SBALANCE] - OMIDCOR_S] CAPO g4 [[mix RIGHTSB SB SBALANCE] - OMIDCOR_S] CAPO
archv archv 4
g4 RIGHTSB [CAP - SMOOTHB] g4 RIGHTSB [CAP - smb]
alsothruthem : list (0.0125 0.1) (0.5 [0.475 + 0.4 * HALFSTROKE / [CAP - SMOOTHB - STROKE]]) alsothruthem : list (0.5 [0.475 + 0.4 * HALFSTROKE / [CAP - smb - STROKE]])
flat [SB + STROKE * ITALICCOR] STROKE flat [SB + STROKE * ITALICCOR] STROKE
curl [SB + STROKE * ITALICCOR] HALFSTROKE curl [SB + STROKE * ITALICCOR] HALFSTROKE
} }
@ -74,21 +75,25 @@ create-glyph 'three' : glyph-construction {
set-width WIDTH set-width WIDTH
assign-unicode '3' assign-unicode '3'
local threeRadius [CAPMIDDLE + HALFSTROKE - SMOOTH] local barcenter : CAP * 0.52
local threeRadius : [CAPMIDDLE + HALFSTROKE - SMOOTH] * 1.1
include : twoHookUpper CAP SMOOTHB HOOK include : spiro {
include : sHookLower 0 SMOOTHA HOOK widths.rhs
g4 SB [CAP - HOOK]
include : create-stroke hookstart CAPO
:.start-from RIGHTSB [CAP - SMOOTHB] g4 RIGHTSB [CAP - [SMOOTHB * [CAP - barcenter] / CAPMIDDLE]]
:.set-width 0 STROKE arcvh
:.arc-vh-to [RIGHTSB - threeRadius] [CAPMIDDLE - HALFSTROKE] flat [RIGHTSB - threeRadius] [barcenter - HALFSTROKE] [heading LEFTWARD]
:.heads-to LEFTWARD }
include : create-stroke include : spiro {
:.start-from RIGHTSB SMOOTHA widths.lhs
:.set-width STROKE 0 g4 SB HOOK
:.arc-vh-to [RIGHTSB - threeRadius] [CAPMIDDLE + HALFSTROKE] hookstart O
:.heads-to LEFTWARD g4 RIGHTSB [SMOOTHA * barcenter / CAPMIDDLE]
arcvh
flat [RIGHTSB - threeRadius] [barcenter + HALFSTROKE] [heading LEFTWARD]
}
} }
create-glyph 'four' : glyph-construction { create-glyph 'four' : glyph-construction {
@ -124,18 +129,18 @@ create-glyph 'five' : glyph-construction {
set-width WIDTH set-width WIDTH
assign-unicode '5' assign-unicode '5'
local ycurly : [CAP * FIVEBARPOS + STROKE] / 2 - HALFSTROKE * globalTransform.yx local ycurly : mix 0 [CAP * FIVEBARPOS + HALFSTROKE] [SMOOTHA / [SMOOTHA + SMOOTHB]]
local xleft : SB + TBALANCE * [0.6 - globalTransform.yx * 2] local xleft : SB + TBALANCE * [0.6 - globalTransform.yx * 2]
include : spiro { include : spiro {
widths.rhs widths.rhs
flat xleft [CAP * FIVEBARPOS + STROKE] [heading RIGHTWARD] flat xleft [CAP * FIVEBARPOS + HALFSTROKE] [heading RIGHTWARD]
curl [MIDDLE - OMIDCOR_S] [CAP * FIVEBARPOS + STROKE] curl [[mix SB RIGHTSB 0.4] - OMIDCOR_S] [CAP * FIVEBARPOS + HALFSTROKE]
g4 RIGHTSB ycurly g4 RIGHTSB ycurly
hookend O hookend O
g4 SB HOOK g4 SB HOOK
} }
include : VBarLeft xleft [CAP * FIVEBARPOS + STROKE] CAP include : VBarLeft xleft [CAP * FIVEBARPOS + HALFSTROKE] CAP
include : HBarTop xleft [RIGHTSB - TBALANCE / 2] CAP include : HBarTop xleft [RIGHTSB - TBALANCE / 2] CAP
} }

View file

@ -33,9 +33,9 @@ create-glyph 'ampersand' : glyph-construction {
flat [RIGHTSB - O - STROKE * ITALICCOR] CAPMIDDLE [heading DOWNWARD] flat [RIGHTSB - O - STROKE * ITALICCOR] CAPMIDDLE [heading DOWNWARD]
curl [RIGHTSB - O - STROKE * ITALICCOR] [SMOOTHA + ITALICCOR * ITALICCORS] curl [RIGHTSB - O - STROKE * ITALICCOR] [SMOOTHA + ITALICCOR * ITALICCORS]
arcvh arcvh
g4 MIDDLE [O + STROKE] g4 MIDDLE [O + fine] [widths fine 0]
archv archv
g4 [SB + O + STROKE * ITALICCOR] [SMOOTHB - ITALICCOR * ITALICCORS] g4 [SB + O + fine * ITALICCOR] [SMOOTHB - ITALICCOR * ITALICCORS]
g4 [[mix SB RIGHTSB p] - fine * ITALICCOR] [CAP - SMOOTHB * pr + ITALICCOR * ITALICCORS * [fine / STROKE]] [widths 0 fine] g4 [[mix SB RIGHTSB p] - fine * ITALICCOR] [CAP - SMOOTHB * pr + ITALICCOR * ITALICCORS * [fine / STROKE]] [widths 0 fine]
arcvh arcvh
g4 [[mix SB RIGHTSB [mix p l 0.5]] - OMIDCOR_S + ITALICCORS] [CAPO - fine] g4 [[mix SB RIGHTSB [mix p l 0.5]] - OMIDCOR_S + ITALICCORS] [CAPO - fine]

View file

@ -13,7 +13,7 @@ define regular (
.barpos 0.52 .barpos 0.52
.ebarpos 0.45 .ebarpos 0.45
.gbarpos 0.35 .gbarpos 0.35
.fivebarpos 0.49 .fivebarpos 0.55
.hook 145 .hook 145
.ahook 130 .ahook 130

View file

@ -6,11 +6,7 @@ font = fontforge.open(source)
font.selection.all() font.selection.all()
font.removeOverlap() font.removeOverlap()
font.em = 1000
font.round()
font.removeOverlap()
font.simplify(1) font.simplify(1)
font.addExtrema()
font.canonicalContours() font.canonicalContours()
font.canonicalStart() font.canonicalStart()
font.generate(sys.argv[2], flags = ("short-post", "opentype")) font.generate(sys.argv[2], flags = ("short-post", "opentype"))

View file

@ -48,10 +48,12 @@ define [Glyph.prototype.start-from x y] : begin {
this.contours.push ([tp this.gizmo (.x x .y y .onCurve true)]) this.contours.push ([tp this.gizmo (.x x .y y .onCurve true)])
return this return this
} }
Glyph.prototype.moveTo = Glyph.prototype.start-from
define [Glyph.prototype.line-to x y] : begin { define [Glyph.prototype.line-to x y] : begin {
this.contours`[this.contours.length - 1].push [tp this.gizmo (.x x .y y .onCurve true)] this.contours`[this.contours.length - 1].push [tp this.gizmo (.x x .y y .onCurve true)]
return this return this
} }
Glyph.prototype.lineTo = Glyph.prototype.line-to
define [Glyph.prototype.curve-control x y] : begin { define [Glyph.prototype.curve-control x y] : begin {
this.contours`[this.contours.length - 1].push [tp this.gizmo (.x x .y y .onCurve false)] this.contours`[this.contours.length - 1].push [tp this.gizmo (.x x .y y .onCurve false)]
return this return this
@ -77,11 +79,11 @@ define [Glyph.prototype.arc-hv-to x y kappa] : begin {
define [Glyph.prototype.cubic-to x1 y1 x2 y2 x y] : begin { define [Glyph.prototype.cubic-to x1 y1 x2 y2 x y] : begin {
local lastContour this.contours`[this.contours.length - 1] local lastContour this.contours`[this.contours.length - 1]
local lastPoint lastContour`[lastContour.length - 1] local lastPoint lastContour`[lastContour.length - 1]
local last : utp this.gizmo lastPoint local segments : bezierCubic2Q2 lastPoint [tp this.gizmo (.x x1 .y y1)] [tp this.gizmo (.x x2 .y y2)] [tp this.gizmo (.x x .y y)]
local segments [bezierCubic2Q2 last (.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] : lastContour.push (.x xc .y yc) (.x xf .y yf .onCurve true)
foreach (p0 (.x xc .y yc) (.x xf .y yf)) [items-of segments] : this.curve-to xc yc xf yf
return this return this
} }
Glyph.prototype.cubicTo = Glyph.prototype.cubic-to
define [Glyph.prototype.reverse-last] : begin { define [Glyph.prototype.reverse-last] : begin {
this.contours.[this.contours.length - 1] = [this.contours.[this.contours.length - 1].reverse] this.contours.[this.contours.length - 1] = [this.contours.[this.contours.length - 1].reverse]
} }

View file

@ -244,7 +244,7 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin {
local segLength : curve.length local segLength : curve.length
local segLengths (0) local segLengths (0)
local samples : Math.min maxSamples : Math.max minSamples : Math.ceil : segLength / 150 local samples : Math.min maxSamples : Math.max minSamples : Math.ceil : segLength / 100
foreach sample [range 1 till samples] : begin { foreach sample [range 1 till samples] : begin {
segLengths.push : curve.split 0 [sample / samples] :.length segLengths.push : curve.split 0 [sample / samples] :.length