From 6923d74c0f1d98ad99d21cf7d0f90d8ca907a4a2 Mon Sep 17 00:00:00 2001 From: Belleve Date: Tue, 2 Apr 2024 06:34:16 -1000 Subject: [PATCH] Fix broken geometry of tailed `i`/`l` under heavy oblique quasi-proportional (#2274) * Fix broken geometry of tailed `i`/`l` under heavy oblique quasi-proportional. * Fix remaining broken geometries --- changes/29.0.6.md | 1 + packages/font-glyphs/src/common/shapes.ptl | 12 ++++++--- .../font-glyphs/src/letter/latin/lower-a.ptl | 2 +- .../font-glyphs/src/letter/latin/lower-il.ptl | 4 +-- packages/geometry/src/curve-util.mjs | 25 ++++++++++++++----- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/changes/29.0.6.md b/changes/29.0.6.md index 095f85a89..5058b6b71 100644 --- a/changes/29.0.6.md +++ b/changes/29.0.6.md @@ -4,3 +4,4 @@ * Make presence of descender serif automatic for LATIN CAPTITAL LETTER BETA (`U+A7B4`). * Remove tailless variants for TURNED GREEK SMALL LETTER IOTA (`U+2129`). * Make presence of top-right serif automatic for CYRILLIC SMALL LIGATURE EN GHE (`U+04A5`) under `cyrl/en`=`tailed-top-left-serifed`. +* Fix broken geometry of tailed `i`/`l` under heavy oblique quasi-proportional. diff --git a/packages/font-glyphs/src/common/shapes.ptl b/packages/font-glyphs/src/common/shapes.ptl index 5c4f29659..7f5b37d9b 100644 --- a/packages/font-glyphs/src/common/shapes.ptl +++ b/packages/font-glyphs/src/common/shapes.ptl @@ -430,12 +430,12 @@ glyph-block CommonShapes : begin define nHookSegments 12 define [HookShape toStraight toFinish isStart args] : begin - local [object y tight sw swItalicAdj noAdjTerminalY turnSlope] args + local [object y tight sw swItalicAdj noAdjTerminalY turnSlope isTail] args local atBottom : toStraight.y > y local ltr : if isStart (toFinish.x < toStraight.x) (toFinish.x > toStraight.x) local dtu : if isStart (y > toFinish.y) (y < toFinish.y) - local doSwash : !tight && !isStart && atBottom && para.isItalic && [if (para.slopeAngle >= 0) ltr [not ltr]] + local doSwash : !tight && !isStart && atBottom && (para.isItalic || isTail) && [if (para.slopeAngle >= 0) ltr [not ltr]] local superness : if tight DesignParameters.tightHookSuperness DesignParameters.superness # Adjust terminal's position if necessary @@ -527,7 +527,9 @@ glyph-block CommonShapes : begin local-parameter : swItalicAdj -- sw local-parameter : noAdjTerminalY -- false local-parameter : turnSlope -- nothing - return : Interpolator hookStartBlender : object y tight sw swItalicAdj noAdjTerminalY turnSlope + local-parameter : isTail -- false + return : Interpolator hookStartBlender + object y tight sw swItalicAdj noAdjTerminalY turnSlope isTail glyph-block-export hookend define flex-params [hookend] : begin @@ -537,7 +539,9 @@ glyph-block CommonShapes : begin local-parameter : swItalicAdj -- sw local-parameter : noAdjTerminalY -- false local-parameter : turnSlope -- nothing - return : Interpolator hookEndBlender : object y tight sw swItalicAdj noAdjTerminalY turnSlope + local-parameter : isTail -- false + return : Interpolator hookEndBlender + object y tight sw swItalicAdj noAdjTerminalY turnSlope isTail glyph-block-export Ungizmo define [Ungizmo] : glyph-proc diff --git a/packages/font-glyphs/src/letter/latin/lower-a.ptl b/packages/font-glyphs/src/letter/latin/lower-a.ptl index 27c1ad434..8c9efa9a6 100644 --- a/packages/font-glyphs/src/letter/latin/lower-a.ptl +++ b/packages/font-glyphs/src/letter/latin/lower-a.ptl @@ -65,7 +65,7 @@ glyph-block Letter-Latin-Lower-A : begin [if isMask corner flat] (df.rightSB + O) bartop [heading Leftward] curl barSmooth bartop archv - g4 (df.leftSB + OX) (bowlArcY1 - [HSwToV Stroke] * leftSlopeS) [heading {.x HVContrast .y leftSlope}] + g4 (df.leftSB + OX) (bowlArcY1 - [HSwToV Stroke] * leftSlope) [heading {.x HVContrast .y leftSlope}] arcvh match kind 0 : list diff --git a/packages/font-glyphs/src/letter/latin/lower-il.ptl b/packages/font-glyphs/src/letter/latin/lower-il.ptl index 2a06c7f0a..56acc3fa9 100644 --- a/packages/font-glyphs/src/letter/latin/lower-il.ptl +++ b/packages/font-glyphs/src/letter/latin/lower-il.ptl @@ -66,14 +66,14 @@ glyph-block Letter-Latin-Lower-I : begin local shift : TailedDotlessIShift df local left : xMiddle - [HSwToV : 0.5 * df.mvs] local right : mix df.leftSB df.rightSB (1.1 - shift) - local rightTerm : Math.max right (left + HookX + df.mvs) + local rightTerm : Math.max right (left + HVContrast * (df.mvs + 1.1 * fine)) (left + HVContrast * df.mvs + HookX) local middle : mix left right (0.55 * df.div) local hookDepth : Math.max (df.mvs * 0.9) (Hook * [StrokeWidthBlend 0.85 1] * df.div) include : dispiro widths.lhs df.mvs flat left top [heading Downward] curl left (SmallArchDepthB * 0.8) - hookend O (turnSlope -- (0.25 * (Stroke - fine) / Stroke)) + hookend O (turnSlope -- (0.25 * (Stroke - fine) / Stroke)) (isTail -- true) g4 rightTerm hookDepth [widths.lhs fine] local xDot : xMiddle + [StrokeWidthBlend 0.25 0] * TanSlope * df.width diff --git a/packages/geometry/src/curve-util.mjs b/packages/geometry/src/curve-util.mjs index 6d653023d..8c5153352 100644 --- a/packages/geometry/src/curve-util.mjs +++ b/packages/geometry/src/curve-util.mjs @@ -187,14 +187,27 @@ export class RoundCapCurve { const r = mix(this.r0, this.r1, t); const theta = mix(this.theta0, this.theta1, t); - return { - x: centerX + r * Math.cos(theta) * this.contrast, - y: centerY + r * Math.sin(theta), - }; + return new Vec2( + centerX + r * Math.cos(theta) * this.contrast, + centerY + r * Math.sin(theta), + ); } derivative(t) { - // TODO: calculate an exact form instead of using finite difference - return derivativeFromFiniteDifference(this, t); + const theta = mix(this.theta0, this.theta1, t); + const r = mix(this.r0, this.r1, t); + const dx = + this.center1.x - + this.center0.x + + this.contrast * + ((this.r1 - this.r0) * Math.cos(theta) - + (this.theta1 - this.theta0) * r * Math.sin(theta)); + const dy = + this.center1.y - + this.center0.y + + ((this.r1 - this.r0) * Math.sin(theta) + + (this.theta1 - this.theta0) * r * Math.cos(theta)); + + return new Vec2(dx, dy); } }