I finally figured out how to deal with hooks.

This commit is contained in:
be5invis 2015-11-07 07:51:42 +08:00
parent e854f0081b
commit d7fc33fc77
6 changed files with 47 additions and 37 deletions

View File

@ -21,6 +21,7 @@ define [bilinear x0 x1 y0 y1 z00 z01 z10 z11 x y] : linreg
* y1
linreg x0 z01 x1 z11 x
* y
define [clamp l h x] : if (x < l) l : if (x > h) h x
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
@ -167,7 +168,7 @@ define [buildFont para recursive] : begin
define OPERATORSTROKE : adviceBlackness 3.2
define SHOULDERFINE : [adviceBlackness 4] / 2
define [adviceSSmooth y sign] : y * 0.20 + STROKE * 0.25 + 0.0583 * (RIGHTSB - SB) + sign * globalTransform.yx * para.smoothadjust
define [adviceSSmooth y sign] : y * 0.22 + STROKE * 0.22 + 0.0583 * (RIGHTSB - SB) + sign * globalTransform.yx * para.smoothadjust
define [adviceGlottalStopSmooth y sign] : ((y - STROKE) * 0.25 + STROKE / 2) + sign * globalTransform.yx * para.smoothadjust
define [shoulderMidSlope _fine _stroke _dir] : 0.5 * CORRECTION_HX * ([fallback _stroke STROKE] - [fallback _fine SHOULDERFINE]) / [fallback _stroke STROKE] + [fallback _dir 1] * globalTransform.yx

View File

@ -122,7 +122,7 @@ define [subParts parts] : begin
foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true
# replace dotted-i and dotted-j with dotless equalivents
if ((parts.0 === glyphs.i || parts.0 === glyphs.cyrUkraniani) && hasMarkAbove) : parts.0 = glyphs.dotlessi
if ((parts.0 === glyphs.i || parts.0 === glyphs.cyrUkrainiani) && hasMarkAbove) : parts.0 = glyphs.dotlessi
if (parts.0 === glyphs.j && hasMarkAbove) : parts.0 = glyphs.dotlessj
# replace below marks with trailing marks

View File

@ -290,50 +290,59 @@ define [FlipAround x y sx sy] : glyph-construction
apply-transform : Italify
# Spiro shapes
define [sband sw rtl _tension _tangle _compression] : return {.type 'interpolate' .af [lambda [before after] : begin \\
local tension : fallback _tension 0.7
local compression : fallback _compression 1
local tensionw 0
local minangle : -para.italicangle / 180 * Math.PI
local maxangle : Math.atan2 (after.x - before.x) ([mix after.y before.y tension] - [mix before.y after.y tension])
set maxangle : Math.atan2 ([Math.sin maxangle] * compression) [Math.cos maxangle]
local p : fallback _tangle 0.25
local pts {}
local samples 32
foreach j [range 1 samples] : begin
local t : j / samples
local angle : mix minangle maxangle [bez3 0 p 1 1 : if (t < 1/2) (2 * t) (2 * (1 - t))]
local k : bez3 0 tensionw (1 - tensionw) 1 t
if rtl : k = 1 - k
pts.push : g2 [mix before.x after.x [bez3 0 0 1 1 t]] [mix before.y after.y [bez3 0 tension (1 - tension) 1 t]] [widths.heading ((1 - k) * STROKE) (k * STROKE) {.x [Math.cos angle] .y [Math.sin angle]}]
# throw 'w'
return pts
]}
define [determineMixR w v] : if (w == v) 0.5 ((w * w - [Math.sqrt : (2 * w - v) * v * w * w]) / ((v - w) * (v - w)))
define [hookstart y p f] : return {.type 'interpolate' .af [lambda [before after] : begin \\
define [determineMixR w v] : piecewise
(w <= v) 0.5
true ((w * w - [Math.sqrt : (2 * w - v) * v * w * w]) / ((v - w) * (v - w)))
define [calculateHook u w v p] : begin
if (w <= v) : return {0.5, 0}
local mixr : determineMixR w v
local mixrRho : clamp 0.97 1 (1 + (1 - w / (u * mixr)) / 15)
local k : w * (mixr - 1) / (mixr * [Math.sqrt : 2 * mixr - 1] * u)
local deltay : STROKE / [Math.sqrt : 1 + k * k]
local deltax : k * deltay
local winner (w - STROKE)
local vinner (v - STROKE + deltay)
if (winner <= 0 || vinner <= 0 || winner <= vinner) : return {[fallback p (mixrRho * mixr)], 0}
local mixrinner : determineMixR winner vinner
local skew : 1 / STROKE * (u * mixr - ((u - STROKE * CORRECTION_HX + deltax) * mixrinner + STROKE * CORRECTION_HX)) + globalTransform.yx
return {[fallback p (mixrRho * mixr)], skew}
define [hookstart y p] : return {.type 'interpolate' .af [lambda [before after] : begin \\
local atBottom : after.y > y
local ltr : after.x > before.x
before.x = before.x - OXHOOK * [if ltr (-1) 1]
local hv : archv
local mixr : determineMixR (after.y - y) (before.y - y)
local w : Math.abs (after.y - y)
local v : Math.abs (before.y - y)
local u : Math.abs (after.x - before.x)
local {mixr, skew} : calculateHook u w v p
local mx ([mix after.x before.x mixr] + [if atBottom 1 (-1)] * CORRECTION_OMIDS)
local hv : archv
return : list
g4.[if ltr "right" "left"].mid mx y f
g4.[if ltr "right" "left"].mid mx y [heading {
.y [if ltr 1 (-1)]
.x (skew * [if atBottom (-1) (1)]) }]
hv.af.call this {.x mx .y y} after hv
]}
define [hookend y p f dontextend] : return {.type 'interpolate' .af [lambda [before after] : begin \\
define [hookend y p] : return {.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 mixr : determineMixR (before.y - y) (after.y - y)
local w : Math.abs (before.y - y)
local v : Math.abs (after.y - y)
local u : Math.abs (after.x - before.x)
local {mixr, skew} : calculateHook u w v p
local mx ([mix before.x after.x mixr] + [if atBottom 1 (-1)] * CORRECTION_OMIDS)
if (!dontextend && atBottom && ltr) : begin
if (atBottom && ltr) : begin
after.x = after.x + TAILADJX * globalTransform.yx
after.y = after.y - TAILADJY * globalTransform.yx
local vh : arcvh
return : list
vh.af.call this before {.x mx .y y} vh
g4.[if ltr "right" "left"].mid mx y f
g4.[if ltr "right" "left"].mid mx y [heading {
.y [if ltr 1 (-1)]
.x (skew * [if atBottom 1 (-1)]) }]
]}
# Derived subfonts

View File

@ -136,7 +136,7 @@ define [SmallEShape top stroke barpos curly] : glyph-construction
flat.ai (SB + O) (top - SMALLSMOOTHA)
curl.ai (SB + O) (0 + SMALLSMOOTHB)
hookend O
g4 (RIGHTSB - O) HOOK
g4 (RIGHTSB - O) AHOOK
include : HBarBottom (SB + (stroke / 2)) (RIGHTSB - (stroke / 2)) barbottom stroke
create-glyph 'e' : glyph-construction

View File

@ -729,7 +729,7 @@ define [RevSmallEShape top stroke barpos] : glyph-construction
flat (RIGHTSB - O) (top - SMALLSMOOTHB)
curl (RIGHTSB - O) SMALLSMOOTHA
hookend O
g4 (SB + O) HOOK
g4 (SB + O) AHOOK
include : HBarBottom (SB + (stroke / 2)) (RIGHTSB - (stroke / 2)) barbottom stroke
create-glyph 'reve' : glyph-construction

View File

@ -1,7 +1,7 @@
[iosevka]
family = 'Iosevka'
version = '1.0-beta4'
codename = 'Yamanashi'
version = '1.0-beta5'
codename = 'Nekojishi'
copyright = 'Copyright (c) 2015 Belleve Invis.'
licence = '''This font software is licenced under the SIL Open Font Licence, Version 1.1. This is licence is avaliable with a FAQ at: http://scripts.sil.org/OFL. This font software is distributes on an 'AS IS' basis, without warranties or conditions of any kind, either express or implied. See the SIL Open Font licence fot the specific language, premissions and limitations governing your use of this font software.'''
@ -28,9 +28,9 @@ fivebarpos = 0.55
lllcrowdedness = 3.33333333
hook = 145
hook = 155
ahook = 130
shook = 90
shook = 130
jhook = 135
fhook = 120
rhook = 100