diff --git a/changes/31.7.1.md b/changes/31.7.1.md new file mode 100644 index 0000000000..69118287b4 --- /dev/null +++ b/changes/31.7.1.md @@ -0,0 +1 @@ +* Fix internal seams of variants of outlined letters U+1CCE6 and U+1CCEF (#2509). diff --git a/packages/font-glyphs/src/letter/latin/upper-q.ptl b/packages/font-glyphs/src/letter/latin/upper-q.ptl index b68e8d9fbe..d9eb246423 100644 --- a/packages/font-glyphs/src/letter/latin/upper-q.ptl +++ b/packages/font-glyphs/src/letter/latin/upper-q.ptl @@ -19,8 +19,7 @@ glyph-block Letter-Latin-Upper-Q : begin define [QHorizontalTailedBody df top sw] : begin define fine : mix ShoulderFine sw 0.125 return : dispiro - flat (df.middle - sw * TanSlope + O) (sw - fine) [widths.lhs fine] - curl [arch.adjust-x.bot df.middle fine] (sw - fine) + g4.right.mid [arch.adjust-x.bot df.middle fine] (sw - fine) [widths.lhs fine] archv flat df.rightSB ArchDepthA [widths.lhs sw] curl df.rightSB (top - ArchDepthB) @@ -28,7 +27,8 @@ glyph-block Letter-Latin-Upper-Q : begin flat df.leftSB (top - ArchDepthA) curl df.leftSB ArchDepthB arcvh - straight.right.end [arch.adjust-x.bot df.middle] 0 + flat [arch.adjust-x.bot df.middle] 0 + curl df.rightSB 0 define [QOpenSwashyBody df top] : glyph-proc define fine : AdviceStroke 3.5 @@ -125,10 +125,6 @@ glyph-block Letter-Latin-Upper-Q : begin VBar.m df.middle [mix Descender HalfStroke 1.75] 0 sw VBar.m df.middle 0 TailDepth - define [QHorizontalTail df tio sw] : dispiro - flat [arch.adjust-x.bot df.middle] 0 [widths.lhs : AdviceStroke 3] - curl [mix df.rightSB df.width 0.5] 0 - define detachedTailGap : Math.max (-0.25 * Descender) [AdviceStroke 12] define yObliqueTailStart : 0 - detachedTailGap - Stroke * 0.875 define yObliqueTailEnd : [mix 0 Descender 0.75] - Stroke * 0.5 @@ -159,7 +155,7 @@ glyph-block Letter-Latin-Upper-Q : begin crossing { QStdBody [AdviceStroke 4] QCrossing 'capital' 'e' } crossingBaseline { QStdBody [AdviceStroke 4] QCrossingBaseline 'capital' 'e' } verticalCrossing { QStdBody QInnerVertSw QVerticalCrossing 'capDesc' 'p' } - horizontalTailed { QHorizontalTailedBody [AdviceStroke 3] QHorizontalTail 'capital' 'e' } + horizontalTailed { QHorizontalTailedBody [AdviceStroke 3] no-shape 'capital' 'e' } detachedTailed { QStdBody Stroke QDetachedTail 'capDesc' 'p' } detachedBendTailed { QStdBody Stroke QDetachedBendTail 'capDesc' 'p' } openSwash { QOpenSwashyBody Stroke QSwashyTail 'capDesc' 'p' } diff --git a/packages/font-glyphs/src/letter/latin/x.ptl b/packages/font-glyphs/src/letter/latin/x.ptl index dba0d5da93..fd4a91a610 100644 --- a/packages/font-glyphs/src/letter/latin/x.ptl +++ b/packages/font-glyphs/src/letter/latin/x.ptl @@ -13,41 +13,43 @@ glyph-block Letter-Latin-X : begin glyph-block-import Letter-Shared-Shapes : CyrDescender PalatalHook glyph-block-export HalfXStrand - define [HalfXStrand stb fSlab _leftx lefty rightx righty turn pStraight tension _sw] : glyph-proc + define [HalfXStrand stb fSlab _xOuter yOuter xCenter yCenter turn pStraight tension _sw _pConn] : glyph-proc local sw : fallback _sw Stroke - local sbCor : if stb ([StrokeWidthBlend 1 6] * OX * ([Math.abs (lefty - righty)] / CAP)) 0 - local leftx : _leftx + ([HSwToV : 0.5 * sw] + [Math.max (-SideJut) sbCor]) * [if (rightx > _leftx) 1 (-1)] + local sbCor : if stb ([StrokeWidthBlend 1 6] * OX * ([Math.abs (yOuter - yCenter)] / CAP)) 0 + local xOuter : _xOuter + ([HSwToV : 0.5 * sw] + [Math.max (-SideJut) sbCor]) * [if (xCenter > _xOuter) 1 (-1)] if stb : begin - local hst : (0.5 * sw) * [DiagCor (righty - lefty) (rightx - leftx) 0 0] + local hst : (0.5 * sw) * [DiagCor (yCenter - yOuter) (xCenter - xOuter) 0 0] local hse : (0.5 * sw) * [Math.min 0.97 ([AdviceStroke 3] / Stroke)] - local leftx2 : _leftx + ([HSwToV hst] + [Math.max (-SideJut) sbCor]) * [if (rightx > _leftx) 1 (-1)] + local xOuterAdjusted : _xOuter + ([HSwToV hst] + [Math.max (-SideJut) sbCor]) * [if (xCenter > _xOuter) 1 (-1)] include : dispiro - corner leftx2 lefty [widths.heading hst hst [if (lefty < righty) Upward Downward]] - corner rightx righty [widths.center : 2 * hse] + corner xOuterAdjusted yOuter [widths.heading hst hst [if (yOuter < yCenter) Upward Downward]] + corner xCenter yCenter [widths.center : 2 * hse] : else : begin - local height : Math.abs (lefty - righty) + local height : Math.abs (yOuter - yCenter) local slabClearance : if fSlab ((sw / Stroke) * [AdviceStroke2 2 3 height]) 0 - local turnyleft : mix lefty righty [if fSlab [Math.max turn (slabClearance / height)] turn] - local cyleft : mix turnyleft righty tension - local straightxleft : mix leftx rightx pStraight - local straightyleft : mix cyleft righty pStraight + local turnyOuter : mix yOuter yCenter [if fSlab [Math.max turn (slabClearance / height)] turn] + local cyOuter : mix turnyOuter yCenter tension + local straightXOuter : mix xOuter xCenter pStraight + local straightYOuter : mix cyOuter yCenter pStraight + local xCenterAdj : mix xCenter xOuter [fallback _pConn 0] + local yCenterAdj : mix yCenter cyOuter [fallback _pConn 0] include : dispiro widths.center sw - flat leftx lefty [heading [if (lefty < righty) Upward Downward]] - curl leftx turnyleft [heading [if (lefty < righty) Upward Downward]] - quadControls 0 ((cyleft - turnyleft) / (straightyleft - turnyleft)) 24 - flat straightxleft straightyleft - curl rightx righty + flat xOuter yOuter [heading [if (yOuter < yCenter) Upward Downward]] + curl xOuter turnyOuter [heading [if (yOuter < yCenter) Upward Downward]] + quadControls 0 ((cyOuter - turnyOuter) / (straightYOuter - turnyOuter)) 24 + flat straightXOuter straightYOuter + curl xCenterAdj yCenterAdj glyph-block-export XStrand - define [XStrand stb slab _leftx lefty _rightx righty turn pStraight tension _sw] : glyph-proc - local middlex : mix _leftx _rightx 0.5 - local middley : mix lefty righty 0.5 + define [XStrand stb slab xLeft yLeft xRight yRight turn pStraight tension _sw] : glyph-proc + local xMid : mix xLeft xRight 0.5 + local yMid : mix yLeft yRight 0.5 - include : HalfXStrand stb slab _leftx lefty middlex middley turn pStraight tension _sw - include : HalfXStrand stb slab _rightx righty middlex middley turn pStraight tension _sw + include : HalfXStrand stb slab xLeft yLeft xMid yMid turn pStraight tension _sw (-0.001) + include : HalfXStrand stb slab xRight yRight xMid yMid turn pStraight tension _sw (-0.001) define [XChanceryStrand sign leftX leftY rightX rightY fHalf _sw] : begin local sw : fallback _sw Stroke diff --git a/packages/font/src/cleanup/glyphs.mjs b/packages/font/src/cleanup/glyphs.mjs index 58f7c3ed8c..2746bf3a21 100644 --- a/packages/font/src/cleanup/glyphs.mjs +++ b/packages/font/src/cleanup/glyphs.mjs @@ -20,19 +20,8 @@ function regulateGlyphStore(cache, para, skew, glyphStore) { function flattenSimpleGlyph(cache, para, skew, g) { try { - let gSimplified; - const needsTransform = g.gizmo ? !Transform.isTranslate(g.gizmo) : skew != 0; - if (needsTransform) { - const tfBack = g.gizmo ? g.gizmo.inverse() : new Transform(1, -skew, 0, 1, 0, 0); - const tfForward = g.gizmo ? g.gizmo : new Transform(1, +skew, 0, 1, 0, 0); - gSimplified = Geom.TransformedGeometry.create( - tfForward, - new Geom.SimplifyGeometry(Geom.TransformedGeometry.create(tfBack, g.geometry)), - ); - } else { - gSimplified = new Geom.SimplifyGeometry(g.geometry); - } - + if (!g.gizmo) throw new TypeError("No gizmo"); + const gSimplified = Geom.SimplifyGeometry.wrapWithGizmo(g.geometry, g.gizmo); const cs = gSimplified.toContours({ cache }); g.clearGeometry(); g.includeContours(cs); diff --git a/packages/geometry-cache/src/index.mjs b/packages/geometry-cache/src/index.mjs index c8698f214d..a1f32b4e67 100644 --- a/packages/geometry-cache/src/index.mjs +++ b/packages/geometry-cache/src/index.mjs @@ -5,7 +5,7 @@ import zlib from "zlib"; import * as CurveUtil from "@iosevka/geometry/curve-util"; import { encode, decode } from "@msgpack/msgpack"; -const Edition = 45; +const Edition = 46; const MAX_AGE = 16; class GfEntry { constructor(age, value) { diff --git a/packages/geometry/src/index.mjs b/packages/geometry/src/index.mjs index ddf8292102..e1af727361 100644 --- a/packages/geometry/src/index.mjs +++ b/packages/geometry/src/index.mjs @@ -771,6 +771,18 @@ export class SimplifyGeometry extends CachedGeometry { h.embed(this.m_geom); h.endStruct(); } + + static wrapWithGizmo(g, gizmo) { + const needsTransform = !Transform.isTranslate(gizmo); + if (needsTransform) { + return new TransformedGeometry( + gizmo, + new SimplifyGeometry(new TransformedGeometry(gizmo.inverse(), g)), + ); + } else { + return new SimplifyGeometry(g); + } + } } // Utility functions