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 * y1
linreg x0 z01 x1 z11 x linreg x0 z01 x1 z11 x
* y * 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) 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 OPERATORSTROKE : adviceBlackness 3.2
define SHOULDERFINE : [adviceBlackness 4] / 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 [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 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 foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true
# replace dotted-i and dotted-j with dotless equalivents # 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 if (parts.0 === glyphs.j && hasMarkAbove) : parts.0 = glyphs.dotlessj
# replace below marks with trailing marks # replace below marks with trailing marks

View file

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

View file

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

View file

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

View file

@ -1,7 +1,7 @@
[iosevka] [iosevka]
family = 'Iosevka' family = 'Iosevka'
version = '1.0-beta4' version = '1.0-beta5'
codename = 'Yamanashi' codename = 'Nekojishi'
copyright = 'Copyright (c) 2015 Belleve Invis.' 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.''' 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 lllcrowdedness = 3.33333333
hook = 145 hook = 155
ahook = 130 ahook = 130
shook = 90 shook = 130
jhook = 135 jhook = 135
fhook = 120 fhook = 120
rhook = 100 rhook = 100