diff --git a/glyphs/common-shapes.patel b/glyphs/common-shapes.patel index 4ff50e5..c6b9479 100644 --- a/glyphs/common-shapes.patel +++ b/glyphs/common-shapes.patel @@ -356,13 +356,27 @@ 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 { +define [hookstart y] (.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 mx [[mix after.x before.x SBALANCE] + [if atBottom 1 [-1]] * OMIDCOR_S] + return : list { + g4 mx y + hv.af.call this (.x mx .y y) after hv + } +}]) +define [hookend y dontextend] (.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] + if [!dontextend && atBottom && ltr] : begin { + after.x = after.x + TAILADJX * globalTransform.yx + after.y = after.y - TAILADJY * globalTransform.yx + } return : list { vh.af.call this before (.x mx .y y) vh g4 mx y diff --git a/glyphs/latin-basic-capital.patel b/glyphs/latin-basic-capital.patel index 76375f8..12fa9db 100644 --- a/glyphs/latin-basic-capital.patel +++ b/glyphs/latin-basic-capital.patel @@ -193,35 +193,30 @@ define [BShape top] : glyph-construction { local tkappa [COKAPPA - 0.22] local bkappa [COKAPPA - 0.2] - local turntop : [top + [bowl - STROKE]] / 2 - local turnbottom : bowl / 2 - - include : create-stroke - :.start-from [SB - O] top - :.heads-to RIGHTWARD - :.set-width 0 STROKE - :.line-to [RIGHTSB - SB * 0.5 - turnbottom] top - :.arc-hv-to [RIGHTSB - SB * 0.5] turntop - :.arc-vh-to [RIGHTSB - SB * 0.5 - turnbottom] [bowl - STROKE] - :.line-to [SB - O] [bowl - STROKE] - :.heads-to LEFTWARD - - include : create-stroke - :.start-from [SB - O] 0 - :.heads-to RIGHTWARD - :.set-width STROKE 0 - :.line-to [RIGHTSB - turnbottom] 0 - :.arc-hv-to RIGHTSB turnbottom - :.arc-vh-to [RIGHTSB - turnbottom] bowl - :.line-to [SB - O] bowl - :.heads-to LEFTWARD - - include : create-stroke - :.start-from SB 0 - :.heads-to UPWARD - :.set-width 0 STROKE - :.line-to SB top - :.heads-to UPWARD + local turntop : [top - [bowl - STROKE]] * 0.5 + local turnbottom : bowl * 0.45 + + include : spiro { + widths.rhs + flat [SB - O] top [heading RIGHTWARD] + curl [RIGHTSB - SB * 0.5 - turntop - OMIDCOR_S] top + archv + g4 [RIGHTSB - SB * 0.5 - O] [mix top [bowl - STROKE] [SMOOTHB / [SMOOTHA + SMOOTHB]]] + arcvh + flat [RIGHTSB - SB * 0.5 - turntop + OMIDCOR_S] [bowl - STROKE] + curl [SB - O] [bowl - STROKE] [heading LEFTWARD] + } + include : spiro { + widths.rhs + flat [SB - O] bowl [heading RIGHTWARD] + curl [RIGHTSB - turnbottom - OMIDCOR_S] bowl + archv + g4 [RIGHTSB - O] [mix bowl 0 [SMOOTHB / [SMOOTHA + SMOOTHB]]] + arcvh + flat [RIGHTSB - turnbottom + OMIDCOR_S] 0 + curl [SB - O] 0 [heading LEFTWARD] + } + include : VBarLeft SB 0 top } create-glyph 'B' : glyph-construction { set-width WIDTH @@ -257,7 +252,7 @@ define [PShape top] : glyph-construction { local bowlBottom [[top - STROKE] * 0.55 - HALFSTROKE] local turn : mix bowlTop bowlBottom [SMOOTHB / [SMOOTHA + SMOOTHB]] - local turnRadius : [bowlTop - bowlBottom] / 2 + local turnRadius : [bowlTop - bowlBottom] * 0.45 include : spiro { widths.rhs flat [SB * 1.25 - O] bowlTop [heading RIGHTWARD] @@ -268,7 +263,7 @@ define [PShape top] : glyph-construction { flat [RIGHTSB - turnRadius + OMIDCOR_S] bowlBottom curl [SB * 1.25 - O] bowlBottom [heading LEFTWARD] } - include : VBarLeft SB 0 top + include : VBarLeft [SB * 1.25] 0 top } define [RShape top] : glyph-construction { include : PShape top @@ -300,14 +295,15 @@ create-glyph 'C' : glyph-construction { assign-unicode 'C' include capitalMarks - include : create-stroke - :.start-from [RIGHTSB - OXHOOK] [CAP - HOOK] - :.set-width STROKE 0 - :.curve-to [MIDDLE + KAPPA_HOOK * [MIDDLE - para.sb]] CAPO [MIDDLE - OMIDCOR_S] CAPO - :.arc-hv-to SB [CAP - SMOOTHA] - :.line-to SB SMOOTHB - :.arc-vh-to [MIDDLE + OMIDCOR_S] O - :.curve-to [MIDDLE + ITALICCORS + KAPPA_HOOK * [MIDDLE - SB]] O [RIGHTSB - OXHOOK] HOOK + include : spiro { + widths.lhs + g4 RIGHTSB [CAP - HOOK] + hookstart CAPO + flat SB [CAP - SMOOTHA] + curl SB SMOOTHB + hookend O + g4 RIGHTSB HOOK + } } define [GShape top sma smb] : glyph-construction { include : create-stroke diff --git a/glyphs/latin-basic-lower.patel b/glyphs/latin-basic-lower.patel index 22a3e3f..59341be 100644 --- a/glyphs/latin-basic-lower.patel +++ b/glyphs/latin-basic-lower.patel @@ -109,13 +109,12 @@ create-glyph 'c' : glyph-construction { include : spiro { widths.lhs - g4 [RIGHTSB - OXHOOK] [XH - HOOK] - g4 [[mix SB RIGHTSB SBALANCE] - OMIDCOR_S] [XH - O] - archv + g4 RIGHTSB [XH - HOOK] + hookstart XO flat [SB + O] [XH - SMALLSMOOTHA] curl [SB + O] [0 + SMALLSMOOTHB] hookend O - g4 [RIGHTSB + TAILADJX * globalTransform.yx] [HOOK - TAILADJY * globalTransform.yx] + g4 RIGHTSB HOOK } } define [SmallEShape top stroke barpos] : glyph-construction { @@ -133,7 +132,7 @@ define [SmallEShape top stroke barpos] : glyph-construction { flat [SB + O] [XH - SMALLSMOOTHA] curl [SB + O] [0 + SMALLSMOOTHB] hookend O - g4 [RIGHTSB + TAILADJX * globalTransform.yx - O] [HOOK - TAILADJY * globalTransform.yx] + g4 [RIGHTSB - O] HOOK } include : create-stroke :.start-from [SB + [stroke / 2]] barbottom @@ -166,7 +165,7 @@ create-glyph 'e.italic' : glyph-construction { flat [SB + O] [XH - SMALLSMOOTHA] curl [SB + O] [0 + SMALLSMOOTHB] hookend O - g4 [RIGHTSB + TAILADJX * globalTransform.yx - O] [HOOK - TAILADJY * globalTransform.yx] + g4 [RIGHTSB - O] HOOK } } create-glyph 'e' : glyph-construction { diff --git a/glyphs/numbers.patel b/glyphs/numbers.patel index 56f020f..7c28d17 100644 --- a/glyphs/numbers.patel +++ b/glyphs/numbers.patel @@ -176,25 +176,25 @@ create-glyph 'eight' : glyph-construction { set-width WIDTH assign-unicode '8' - local sma : SMOOTHA * 0.975 - local smb : SMOOTHB * 0.975 + local sma : SMOOTHA * 0.975 + ITALICCORS * ITALICCOR + local smb : SMOOTHB * 0.975 - ITALICCORS * ITALICCOR local p 0.96 - include : xsStrand [mix RIGHTSB SB p] [CAP - sma * p] RIGHTSB sma - include : xsStrand SB smb [mix SB RIGHTSB p] [CAP - smb * p] - - include : create-stroke - :.start-from [mix SB RIGHTSB p] [CAP - smb * p] - :.set-width STROKE 0 - :.arc-vh-to [MIDDLE - OMIDCOR_S] [CAP - O] - :.arc-hv-to [mix RIGHTSB SB p] [CAP - sma * p] - - include : create-stroke - :.start-from SB smb - :.set-width STROKE 0 - :.arc-vh-to [MIDDLE + OMIDCOR_S] O - :.arc-hv-to RIGHTSB sma + include : spiro { + widths.lhs + g4 [MIDDLE - OMIDCOR_S + ITALICCORS] [CAP - O - STROKE] + archv 1 + g4 [[mix SB RIGHTSB p] - STROKE] [CAP - smb * p] + g4 [SB + STROKE] smb [widths 0 STROKE] + arcvh 1 + g4 [MIDDLE + OMIDCOR_S - ITALICCORS] [O + STROKE] + archv 1 + g4 [RIGHTSB - STROKE] sma [widths 0 STROKE] + g4 [[mix RIGHTSB SB p] + STROKE] [CAP - sma * p] [widths STROKE 0] + arcvh 1 + close + } } create-glyph 'nine' : glyph-construction { diff --git a/pass2-finalize.py b/pass2-finalize.py index c33528c..55c198b 100644 --- a/pass2-finalize.py +++ b/pass2-finalize.py @@ -7,6 +7,8 @@ font = fontforge.open(source) font.selection.all() font.removeOverlap() font.em = 1000 +font.round() +font.removeOverlap() font.simplify(1) font.addExtrema() font.canonicalContours() diff --git a/support/glyph.patel b/support/glyph.patel index 39ad8e6..77d8dd3 100644 --- a/support/glyph.patel +++ b/support/glyph.patel @@ -107,7 +107,7 @@ define [Glyph.prototype.put-shapes contours] : begin { define [Glyph.prototype.include component copyAnchors] : begin { local glyph : match component { [aFunction it] : return : component.call this - [Stroke.is it] (.contours [component.to-outline 0 0]) + [Stroke.is it] (.contours [component.to-outline]) (:: contours) (.contours contours) otherwise component } diff --git a/support/stroke.patel b/support/stroke.patel index f810ae3..fa7137b 100644 --- a/support/stroke.patel +++ b/support/stroke.patel @@ -140,8 +140,15 @@ define [computeOffsetPoint curve t j sl foffset fpdx fpdy] : begin { } define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { - local d1s ([set d1 [if [this.points.0.d1 >= 0] this.points.0.d1 this.defaultd1]]) - local d2s ([set d2 [if [this.points.0.d2 >= 0] this.points.0.d2 this.defaultd2]]) + local width : [d1 || this.defaultd1] + [d2 || this.defaultd2] + local bias : [d1 || this.defaultd1] - [d2 || this.defaultd2] + if [this.points.0.d1 >= 0 && this.points.0.d2 >= 0] : begin { + local width : this.points.0.d1 + this.points.0.d2 + local bias : this.points.0.d1 - this.points.0.d2 + } + + local widths (width) + local biases (bias) local pdxs (0) local pdys (0) local ts (0) @@ -163,8 +170,12 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { if [not p1.subdivided] : begin { ts.push arcLengthSofar brk.[subSegments.length - 1] = true - d1s.push : set d1 [if [p1.d1 >= 0] p1.d1 d1] - d2s.push : set d2 [if [p1.d2 >= 0] p1.d2 d2] + if [p1.d1 >= 0 && p1.d2 >= 0] : begin { + set width : p1.d1 + p1.d2 + set bias : p1.d1 - p1.d2 + } + widths.push width + biases.push bias local normalpt : seg.normal 1 pdxs.push : if [p1.pdx !== nothing] [p1.pdx - normalpt.x] 0 pdys.push : if [p1.pdy !== nothing] [p1.pdy - normalpt.y] 0 @@ -179,8 +190,12 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { if [not p3.subdivided] : begin { ts.push arcLengthSofar brk.[subSegments.length - 1] = true - d1s.push : set d1 [if [p3.d1 >= 0] p3.d1 d1] - d2s.push : set d2 [if [p3.d2 >= 0] p3.d2 d2] + if [p3.d1 >= 0 && p3.d2 >= 0] : begin { + set width : p3.d1 + p3.d2 + set bias : p3.d1 - p3.d2 + } + widths.push width + biases.push bias local normalpt : seg.normal 1 pdxs.push : if [p3.pdx !== nothing] [p3.pdx - normalpt.x] 0 pdys.push : if [p3.pdy !== nothing] [p3.pdy - normalpt.y] 0 @@ -195,8 +210,12 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { if [not p2.subdivided] : begin { ts.push arcLengthSofar brk.[subSegments.length - 1] = true - d1s.push : set d1 [if [p2.d1 >= 0] p2.d1 d1] - d2s.push : set d2 [if [p2.d2 >= 0] p2.d2 d2] + if [p2.d1 >= 0 && p2.d2 >= 0] : begin { + set width : p2.d1 + p2.d2 + set bias : p2.d1 - p2.d2 + } + widths.push width + biases.push bias local normalpt : seg.normal 1 pdxs.push : if [p2.pdx !== nothing] [p2.pdx - normalpt.x] 0 pdys.push : if [p2.pdy !== nothing] [p2.pdy - normalpt.y] 0 @@ -209,8 +228,10 @@ define [Stroke.prototype.to-outline d1 d2 _samples straight] : begin { if [this.points.0.pdx !== nothing] : set pdxs.0 [this.points.0.pdx - [subSegments.0.normal 0].x] if [this.points.0.pdy !== nothing] : set pdys.0 [this.points.0.pdy - [subSegments.0.normal 0].y] - local f1 : smooth [xs-array ts] [ys-array d1s] - local f2 : smooth [xs-array ts] [ys-array [d2s.map [[x] -> [-x]]]] + local fWidth : smooth [xs-array ts] [ys-array widths] + local fBias : smooth [xs-array ts] [ys-array biases] + local [f1 t] : [[fWidth t] + [fBias t]] / 2 + local [f2 t] : - [[fWidth t] - [fBias t]] / 2 local fpdx : smooth [xs-array ts] [ys-array pdxs] local fpdy : smooth [xs-array ts] [ys-array pdys]