Optimized shapes of /c, /e, /P, /R, /D, /two and /five with spiro.

This commit is contained in:
be5invis 2015-08-17 23:03:59 +08:00
parent 71345e9926
commit 0a005cae57
7 changed files with 133 additions and 78 deletions

View File

@ -109,6 +109,7 @@ define [buildFont para recursive] : begin {
define KAPPA para.kappa
define COKAPPA : 1 - KAPPA
define BKAPPA : para.bkappa || KAPPA + 0.1
define KAPPA_SPIRO_ARC : KAPPA + 0.1
define CKAPPA : para.ckappa || BKAPPA
define COBKAPPA : 1 - BKAPPA
define KAPPA_HOOK : fallback para.kappa_hook [BKAPPA + 0.1]
@ -223,7 +224,13 @@ define [buildFont para recursive] : begin {
return a
}
define [VIRTUAL] : this.points.[this.points.length - 1].subdivided = true
define [afInterpolate before after args] : g2 [mix before.x after.x args.rx] [mix before.y after.y args.ry] VIRTUAL
define [afInterpolate before after args] : g4 [mix before.x after.x args.rx] [mix before.y after.y args.ry] VIRTUAL
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] VIRTUAL
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)
@ -233,9 +240,35 @@ define [buildFont para recursive] : begin {
define [prepare f] (.type 'prepare' .af f)
define [widths l r] : lambda [] : this.set-width l r
define [controls rx ry] (.type 'interpolate' .rx rx .ry ry .af afInterpolate)
define [archv] : controls [1 - [3 * [1 - BKAPPA] + 1] / 8] [[3 * [1 - CKAPPA] + 1] / 8]
define [arcvh] : controls [[3 * [1 - BKAPPA] + 1] / 8] [1 - [3 * [1 - CKAPPA] + 1] / 8]
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 [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
@ -259,7 +292,7 @@ define [buildFont para recursive] : begin {
}
if closed : knots.pop
set knots : flatten knots
s.set-samples 1
s.set-samples 2
libspiro.spiroToBezierOnContext knots closed s
if lastaf : lastaf.call s
return s

View File

@ -355,4 +355,16 @@ define [vdual newid unicode id spacing] : create-glyph [fallback newid : 'double
}
apply-transform : Translate 0 [spacing / 2]
apply-transform : Italify
}
}
define [hookend y] (.type 'interpolate' .af [lambda [before after] : begin {
local atBottom : before.y > y
local ltr : after.x > before.x
after.x = after.x + OXHOOK * [if ltr [-1] 1]
local vh : arcvh
local mx [[mix before.x after.x SBALANCE] + [if atBottom 1 [-1]] * OMIDCOR_S]
return : list {
vh.af.call this before (.x mx .y y) vh
g4 mx y
}
}])

View File

@ -238,41 +238,36 @@ create-glyph 'D' : glyph-construction {
local dsmooth [SMOOTH * 1.35]
local bsmooth [SMOOTH * 1.1]
include : create-stroke
:.start-from SB 0
:.heads-to UPWARD
:.set-width 0 STROKE
:.line-to SB CAP
:.heads-to UPWARD
include : VBarLeft SB 0 CAP
include : create-stroke
:.start-from [SB - O] 0
:.heads-to RIGHTWARD
:.set-width STROKE 0
:.line-to [RIGHTSB - bsmooth] 0
:.arc-hv-to RIGHTSB dsmooth
:.line-to RIGHTSB [CAP - dsmooth]
:.arc-vh-to [RIGHTSB - bsmooth] CAP
:.line-to [SB - O] CAP
:.heads-to LEFTWARD
include : spiro {
widths.rhs
flat [SB - O] CAP [heading RIGHTWARD]
curl [RIGHTSB - bsmooth] CAP
archv
flat RIGHTSB [CAP - dsmooth - [SMOOTHB - SMOOTH]]
curl RIGHTSB [dsmooth + [SMOOTHA - SMOOTH]]
arcvh
flat [RIGHTSB - bsmooth] 0
curl [SB - O] 0 [heading LEFTWARD]
}
}
define [PShape top] : glyph-construction {
local bowlTop [top * 1]
local bowlBottom [[top - STROKE] * 0.55 - HALFSTROKE]
local turn : mix bowlTop bowlBottom 0.5
local turn : mix bowlTop bowlBottom [SMOOTHB / [SMOOTHA + SMOOTHB]]
local turnRadius : [bowlTop - bowlBottom] / 2
include : create-stroke
:.start-from [SB * 1.25 - O] bowlTop
:.heads-to RIGHTWARD
:.set-width 0 STROKE
:.line-to [RIGHTSB - turnRadius] bowlTop
:.arc-hv-to [RIGHTSB - O] turn
:.arc-vh-to [RIGHTSB - turnRadius] bowlBottom
:.line-to [SB * 1.25 - O] bowlBottom
:.heads-to LEFTWARD
include : spiro {
widths.rhs
flat [SB * 1.25 - O] bowlTop [heading RIGHTWARD]
curl [RIGHTSB - turnRadius - OMIDCOR_S] bowlTop
archv
g4 [RIGHTSB - O] turn
arcvh
flat [RIGHTSB - turnRadius + OMIDCOR_S] bowlBottom
curl [SB * 1.25 - O] bowlBottom [heading LEFTWARD]
}
include : VBarLeft SB 0 top
}
define [RShape top] : glyph-construction {
@ -345,15 +340,7 @@ create-glyph 'O' : glyph-construction {
assign-unicode 'O'
include capitalMarks
include : create-stroke
:.start-from [MIDDLE - OMIDCOR_S] CAPO
:.set-width STROKE 0
:.arc-hv-to SB [CAP - SMOOTHA]
:.line-to SB SMOOTHB
:.arc-vh-to [MIDDLE + OMIDCOR_S] O
:.arc-hv-to RIGHTSB SMOOTHA
:.line-to RIGHTSB [CAP - SMOOTHB]
:.arc-vh-to [MIDDLE - OMIDCOR_S] CAPO
include : smallo CAP 0 SB RIGHTSB nothing SMOOTHA SMOOTHB
}
create-glyph 'Q' : glyph-construction {

View File

@ -107,26 +107,34 @@ create-glyph 'c' : glyph-construction {
assign-unicode 'c'
include eMarks
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 : spiro {
widths.lhs
g4 [RIGHTSB - OXHOOK] [XH - HOOK]
g4 [[mix SB RIGHTSB SBALANCE] - OMIDCOR_S] [XH - O]
archv
flat [SB + O] [XH - SMALLSMOOTHA]
curl [SB + O] [0 + SMALLSMOOTHB]
hookend O
g4 [RIGHTSB + TAILADJX * globalTransform.yx] [HOOK - TAILADJY * globalTransform.yx]
}
}
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 : 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 : spiro {
widths.lhs
flat [RIGHTSB - O] barbottom [heading UPWARD]
curl [RIGHTSB - O] [top - SMALLSMOOTHB]
arcvh
g4 [MIDDLE - OMIDCOR_S] [XH - O]
archv
flat [SB + O] [XH - SMALLSMOOTHA]
curl [SB + O] [0 + SMALLSMOOTHB]
hookend O
g4 [RIGHTSB + TAILADJX * globalTransform.yx - O] [HOOK - TAILADJY * globalTransform.yx]
}
include : create-stroke
:.start-from [SB + [stroke / 2]] barbottom
:.set-width stroke 0
@ -146,15 +154,20 @@ create-glyph 'e.italic' : glyph-construction {
local barbottom [XH * EBARPOS]
include : create-stroke
:.start-from [SB + O + STROKE] barbottom
:.set-width STROKE 0
:.arc-hv-to [RIGHTSB - O] [XH - SMALLSMOOTHB * 0.95]
:.arc-vh-to [MIDDLE - OMIDCOR_S] XO
:.arc-hv-to [SB + O] [XH - SMALLSMOOTHA]
:.line-to [SB + O] SMALLSMOOTHB
:.set-samples 4
include : EHookLower 0 SMALLSMOOTHB HOOK
include : spiro {
widths.lhs
g4 [SB + O + STROKE] barbottom
archv 8
g4 [RIGHTSB - O] [XH - SMALLSMOOTHB * 0.95]
#complexThru [alsothru 0.015 0.4] [arcvh]
arcvh 8
g4 [MIDDLE - OMIDCOR_S] [XH - O]
archv
flat [SB + O] [XH - SMALLSMOOTHA]
curl [SB + O] [0 + SMALLSMOOTHB]
hookend O
g4 [RIGHTSB + TAILADJX * globalTransform.yx - O] [HOOK - TAILADJY * globalTransform.yx]
}
}
create-glyph 'e' : glyph-construction {
set-width WIDTH

View File

@ -50,9 +50,17 @@ create-glyph 'two' : glyph-construction {
set-width WIDTH
assign-unicode '2'
include : twoHookUpper CAP SMOOTHB HOOK
include : sStrand STROKE [CAP - SMOOTHB]
include : spiro {
widths.rhs
g4 [SB + OXHOOK] [CAP - HOOK]
g4 [[mix RIGHTSB SB SBALANCE] - OMIDCOR_S] CAPO
archv
g4 RIGHTSB [CAP - SMOOTHB]
alsothruthem : list (0.0125 0.1) (0.5 [0.475 + 0.4 * HALFSTROKE / [CAP - SMOOTHB - STROKE]])
flat [SB + STROKE * ITALICCOR] STROKE
curl [SB + STROKE * ITALICCOR] HALFSTROKE
}
include : create-stroke
:.start-from SB 0
:.set-width STROKE 0
@ -119,13 +127,14 @@ create-glyph 'five' : glyph-construction {
local ycurly : [CAP * FIVEBARPOS + STROKE] / 2 - HALFSTROKE * globalTransform.yx
local xleft : SB + TBALANCE * [0.6 - globalTransform.yx * 2]
include : sHookLower 0 ycurly HOOK
include : create-stroke
:.start-from RIGHTSB ycurly
:.set-width STROKE 0
:.arc-vh-to [MIDDLE - OMIDCOR_S] [CAP * FIVEBARPOS + STROKE]
:.line-to xleft [CAP * FIVEBARPOS + STROKE]
:.heads-to LEFTWARD
include : spiro {
widths.rhs
flat xleft [CAP * FIVEBARPOS + STROKE] [heading RIGHTWARD]
curl [MIDDLE - OMIDCOR_S] [CAP * FIVEBARPOS + STROKE]
g4 RIGHTSB ycurly
hookend O
g4 SB HOOK
}
include : VBarLeft xleft [CAP * FIVEBARPOS + STROKE] CAP
include : HBarTop xleft [RIGHTSB - TBALANCE / 2] CAP
}

View File

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

View File

@ -56,7 +56,7 @@ define [Stroke.prototype.set-width d1 d2] : begin {
}
else {
this.defaultd1 = d1
this.defualtd2 = d2
this.defaultd2 = d2
}
}
return this