From 733f56fe79fbb7dbb57195ed03cf1add9aadd984 Mon Sep 17 00:00:00 2001 From: Belleve Date: Mon, 18 Mar 2024 17:37:17 -1000 Subject: [PATCH] Fix the design of the ESTIMATED SYMBOL (`U+212E`) to match its spec; Refine design of POWER SYMBOL (`U+23FB`) and HEAVY CHECK MARK (`U+2714`) (#2245) * Make estimated sign match its spec * Refine power standby symbol * Check mark refinement * Doc * fmt --- changes/29.0.3.md | 2 + package-lock.json | 80 +++++++++---------- package.json | 2 +- packages/font-glyphs/package.json | 12 +-- packages/font-glyphs/src/common/shapes.ptl | 59 +++++++------- packages/font-glyphs/src/meta/macros.ptl | 6 +- packages/font-glyphs/src/symbol/arrow.ptl | 2 +- .../src/symbol/geometric/dotted.ptl | 14 ++-- packages/font-glyphs/src/symbol/letter.ptl | 80 ++++++++++++++----- .../src/symbol/pictograph/checking-marks.ptl | 2 +- .../src/symbol/pictograph/clock.ptl | 2 +- .../pictograph/iec-power-and-playback.ptl | 10 +-- .../src/symbol/pictograph/stick-figure.ptl | 8 +- packages/font-kits/package.json | 8 +- packages/font-kits/src/boole-kit.mjs | 4 +- packages/font-otl/package.json | 6 +- packages/font/package.json | 16 ++-- packages/font/src/finalize/gc.mjs | 2 +- packages/font/src/finalize/glyphs.mjs | 2 +- packages/geometry-cache/package.json | 4 +- packages/geometry-cache/src/index.mjs | 2 +- packages/geometry/package.json | 4 +- packages/geometry/src/curve-util.mjs | 6 +- packages/geometry/src/index.mjs | 33 ++++---- packages/geometry/src/transform.mjs | 5 ++ packages/glyph/package.json | 4 +- packages/glyph/src/glyph.mjs | 5 +- packages/param/package.json | 4 +- packages/util/package.json | 2 +- tools/amend-readme/package.json | 4 +- tools/data-export/package.json | 4 +- tools/generate-samples/package.json | 4 +- tools/misc/package.json | 4 +- 33 files changed, 225 insertions(+), 177 deletions(-) diff --git a/changes/29.0.3.md b/changes/29.0.3.md index 34cc7193c..215a941fe 100644 --- a/changes/29.0.3.md +++ b/changes/29.0.3.md @@ -1,4 +1,6 @@ * Fix height of block quadrants (`U+2596`..`U+259F`) (#2240). +* Fix the design of the ESTIMATED SYMBOL (`U+212E`) to match its spec (#2243). +* Refine design of POWER SYMBOL (`U+23FB`) and HEAVY CHECK MARK (`U+2714`) (#2243). * Make LATIN {CAPITAL|SMALL} LETTER GHA (`U+01A2`..`U+01A3`) respond to variants of `q` (`cv41`). * Make the behavior of serifs of `U+027F` automatic. * Fix side bearings of `U+29E2` under Quasi-Proportional. diff --git a/package-lock.json b/package-lock.json index d7d3cb396..29ff702bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@iosevka/monorepo", - "version": "29.0.2", + "version": "29.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@iosevka/monorepo", - "version": "29.0.2", + "version": "29.0.3", "workspaces": [ "packages/*", "tools/*" @@ -4310,16 +4310,16 @@ }, "packages/font": { "name": "@iosevka/font", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { "@iarna/toml": "^2.2.5", - "@iosevka/font-glyphs": "29.0.2", - "@iosevka/font-otl": "29.0.2", - "@iosevka/geometry": "29.0.2", - "@iosevka/geometry-cache": "29.0.2", - "@iosevka/glyph": "29.0.2", - "@iosevka/param": "29.0.2", - "@iosevka/util": "29.0.2", + "@iosevka/font-glyphs": "29.0.3", + "@iosevka/font-otl": "29.0.3", + "@iosevka/geometry": "29.0.3", + "@iosevka/geometry-cache": "29.0.3", + "@iosevka/glyph": "29.0.3", + "@iosevka/param": "29.0.3", + "@iosevka/util": "29.0.3", "harfbuzzjs": "^0.3.4", "ot-builder": "^1.7.3", "semver": "^7.6.0" @@ -4327,100 +4327,100 @@ }, "packages/font-glyphs": { "name": "@iosevka/font-glyphs", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/font-kits": "29.0.2", - "@iosevka/geometry": "29.0.2", - "@iosevka/geometry-cache": "29.0.2", - "@iosevka/glyph": "29.0.2", - "@iosevka/util": "29.0.2", + "@iosevka/font-kits": "29.0.3", + "@iosevka/geometry": "29.0.3", + "@iosevka/geometry-cache": "29.0.3", + "@iosevka/glyph": "29.0.3", + "@iosevka/util": "29.0.3", "typo-geom": "^0.15.1" } }, "packages/font-kits": { "name": "@iosevka/font-kits", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/geometry": "29.0.2", - "@iosevka/glyph": "29.0.2", - "@iosevka/util": "29.0.2" + "@iosevka/geometry": "29.0.3", + "@iosevka/glyph": "29.0.3", + "@iosevka/util": "29.0.3" } }, "packages/font-otl": { "name": "@iosevka/font-otl", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/font-glyphs": "29.0.2", - "@iosevka/glyph": "29.0.2", + "@iosevka/font-glyphs": "29.0.3", + "@iosevka/glyph": "29.0.3", "toposort": "^2.0.2" } }, "packages/geometry": { "name": "@iosevka/geometry", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/util": "29.0.2", + "@iosevka/util": "29.0.3", "spiro": "^3.0.0", "typo-geom": "^0.15.1" } }, "packages/geometry-cache": { "name": "@iosevka/geometry-cache", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/geometry": "29.0.2", + "@iosevka/geometry": "29.0.3", "@msgpack/msgpack": "^2.8.0" } }, "packages/glyph": { "name": "@iosevka/glyph", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/geometry": "29.0.2" + "@iosevka/geometry": "29.0.3" } }, "packages/param": { "name": "@iosevka/param", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/util": "29.0.2" + "@iosevka/util": "29.0.3" } }, "packages/util": { "name": "@iosevka/util", - "version": "29.0.2" + "version": "29.0.3" }, "tools/amend-readme": { "name": "@iosevka/amend-readme", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { "@iarna/toml": "^2.2.5", - "@iosevka/param": "29.0.2", + "@iosevka/param": "29.0.3", "@unicode/unicode-15.1.0": "^1.5.2" } }, "tools/data-export": { "name": "@iosevka/data-export", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { "@iarna/toml": "^2.2.5", - "@iosevka/param": "29.0.2", + "@iosevka/param": "29.0.3", "@unicode/unicode-15.1.0": "^1.5.2", "cldr": "^7.5.0" } }, "tools/generate-samples": { "name": "@iosevka/generate-samples", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/data-export": "29.0.2" + "@iosevka/data-export": "29.0.3" } }, "tools/misc": { "name": "@iosevka/misc", - "version": "29.0.2", + "version": "29.0.3", "dependencies": { - "@iosevka/util": "29.0.2", + "@iosevka/util": "29.0.3", "semver": "^7.6.0", "wawoff2": "^2.0.1" } diff --git a/package.json b/package.json index d07b6bbe0..84eaf21cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/monorepo", - "version": "29.0.2", + "version": "29.0.3", "workspaces": [ "packages/*", "tools/*" diff --git a/packages/font-glyphs/package.json b/packages/font-glyphs/package.json index e6fbf08b4..5a81f5971 100644 --- a/packages/font-glyphs/package.json +++ b/packages/font-glyphs/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/font-glyphs", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs", @@ -8,11 +8,11 @@ "./unicode-knowledge": "./src/meta/unicode-knowledge.mjs" }, "dependencies": { - "@iosevka/font-kits": "29.0.2", - "@iosevka/geometry": "29.0.2", - "@iosevka/geometry-cache": "29.0.2", - "@iosevka/glyph": "29.0.2", - "@iosevka/util": "29.0.2", + "@iosevka/font-kits": "29.0.3", + "@iosevka/geometry": "29.0.3", + "@iosevka/geometry-cache": "29.0.3", + "@iosevka/glyph": "29.0.3", + "@iosevka/util": "29.0.3", "typo-geom": "^0.15.1" } } diff --git a/packages/font-glyphs/src/common/shapes.ptl b/packages/font-glyphs/src/common/shapes.ptl index f3b2e4230..5c4f29659 100644 --- a/packages/font-glyphs/src/common/shapes.ptl +++ b/packages/font-glyphs/src/common/shapes.ptl @@ -160,33 +160,38 @@ glyph-block CommonShapes : begin glyph-block-export DotStrokeAt define [DotStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s true - glyph-block-export CircleRing - define [CircleRing u d l r transformShiftOnly] : glyph-proc - local giz currentGlyph.gizmo - include : new-glyph : glyph-proc - local my ((u + d) / 2) - local mx ((l + r) / 2) - currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz] - include : spiro-outline - begin [lambda : set this.gizmo currentGlyph.gizmo] - g4 mx d - archv 32 2.0 - g4 l my - arcvh 32 2.0 - g4 mx u - archv 32 2.0 - g4 r my - arcvh 32 2.0 - close - if transformShiftOnly : begin - local {.x mx1 .y my1} : giz.apply {.x mx .y my} - include : Translate (mx1 - mx) (my1 - my) - glyph-block-export CircleRingAt - define [CircleRingAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) - glyph-block-export CircleDotAt - define [CircleDotAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) true - glyph-block-export RoundStrokeTerminalAt - define [RoundStrokeTerminalAt x y r] : CircleRing (y + r) (y - r) (x - [HSwToV r]) (x + [HSwToV r]) true + glyph-block-export Circle + define Circle : namespace + export : define Outline : namespace + export : define [At x y r] : Ellipse.Outline.AtDimens (y + r) (y - r) (x - r) (x + r) + export : define [DotAt x y r] : Ellipse.Outline.AtDimens (y + r) (y - r) (x - r) (x + r) true + + glyph-block-export Ellipse + define Ellipse : namespace + export : define Outline : namespace + export : define [AtDimens u d l r transformShiftOnly] : glyph-proc + local giz currentGlyph.gizmo + include : new-glyph : glyph-proc + local my ((u + d) / 2) + local mx ((l + r) / 2) + currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz] + include : spiro-outline + begin [lambda : set this.gizmo currentGlyph.gizmo] + g4 mx d + archv 32 2.0 + g4 l my + arcvh 32 2.0 + g4 mx u + archv 32 2.0 + g4 r my + arcvh 32 2.0 + close + if transformShiftOnly : begin + local {.x mx1 .y my1} : giz.apply {.x mx .y my} + include : Translate (mx1 - mx) (my1 - my) + export : define [At x y rx ry] : AtDimens (y + ry) (y - ry) (x - rx) (x + rx) + export : define [DotAt x y rx ry] : AtDimens (y + ry) (y - ry) (x - rx) (x + rx) true + export : define [RoundStrokeTerminalAt x y r] : AtDimens (y + r) (y - r) (x - [HSwToV r]) (x + [HSwToV r]) true glyph-block-export OShapeT define [OShapeT sink u d l r _width _ada _adb] : begin diff --git a/packages/font-glyphs/src/meta/macros.ptl b/packages/font-glyphs/src/meta/macros.ptl index 7b5778cdd..6b77f57b1 100644 --- a/packages/font-glyphs/src/meta/macros.ptl +++ b/packages/font-glyphs/src/meta/macros.ptl @@ -89,7 +89,7 @@ define-macro flex-params : syntax-rules local {lamBodyLeader :: lamBodyStatements} lam.2 local finalStatements {} - + foreach stmt [items-of lamBodyStatements] : begin if ([Array.isArray stmt] && stmt.0 == 'local-parameter') : then : begin @@ -190,11 +190,11 @@ define-macro glyph-block-import : syntax-rules define allExports : object Common-Derivatives `[select-variant orthographic-italic orthographic-slanted refer-glyph query-glyph alias turned HDual HCombine VDual VCombine derive-glyphs - derive-composites link-reduced-variant alias-reduced-variant HalfAdvance + derive-composites link-reduced-variant alias-reduced-variant HalfAdvance derive-multi-part-glyphs DeriveMeshT link-gr] CommonShapes `[no-shape tagged KnotAdj Rect SquareAt Ring RingAt DotAt RingStroke - RingStrokeAt DotStrokeAt CircleRing CircleRingAt CircleDotAt RoundStrokeTerminalAt + RingStrokeAt DotStrokeAt Circle Ellipse OShapeT OShape OShapeOutline OShapeFlatTB HSerif VSerif NeedSlab NeedNotItalic HBar HOverlayBar VBar FlatSlashShape hookstart hookend Ungizmo Regizmo FlipAround ScaleAround Realign ForceUpright DiagCor NameUni PointingTo with-transform clear-geometry diff --git a/packages/font-glyphs/src/symbol/arrow.ptl b/packages/font-glyphs/src/symbol/arrow.ptl index e9849bcda..557cd7cd8 100644 --- a/packages/font-glyphs/src/symbol/arrow.ptl +++ b/packages/font-glyphs/src/symbol/arrow.ptl @@ -362,7 +362,7 @@ glyph-block Symbol-Arrow : for-width-kinds WideWidth1 SemiHookArrowBar x1 y1 x2 y2 halfBarWidth halfTerminal (-headWidth) 2 define RoundArrow : namespace - define [Blob x y sw] : RoundStrokeTerminalAt x y (sw / 2) + define [Blob x y sw] : Ellipse.Outline.RoundStrokeTerminalAt x y (sw / 2) define [Bar x1 y1 x2 y2 sw] : begin return : PointingTo x1 y1 x2 y2 : lambda [mag] : union diff --git a/packages/font-glyphs/src/symbol/geometric/dotted.ptl b/packages/font-glyphs/src/symbol/geometric/dotted.ptl index a4b70636c..ff3456b46 100644 --- a/packages/font-glyphs/src/symbol/geometric/dotted.ptl +++ b/packages/font-glyphs/src/symbol/geometric/dotted.ptl @@ -35,7 +35,7 @@ glyph-block Symbol-Geometric-Dice : for-width-kinds WideWidth1 define yBottom : mix yBottomEx yTopEx (1 / 5) define yTop : mix yBottomEx yTopEx (4 / 5) foreach { px py } [items-of dots] : begin - include : CircleDotAt + include : Circle.Outline.DotAt mix xLeft xRight (px / 2) mix yBottom yTop (py / 2) begin dr @@ -43,7 +43,7 @@ glyph-block Symbol-Geometric-Dice : for-width-kinds WideWidth1 create-glyph [MangleName 'dottedWhiteTriangle'] [MangleUnicode 0x25EC] : glyph-proc set-width Geom.Width include : refer-glyph : MangleName 'whiteTriangleUp' - include : CircleDotAt Geom.MidX (Geom.MidY - Geom.Size / 3) [Math.min (Geom.Width / 8 ) PeriodRadius] + include : Circle.Outline.DotAt Geom.MidX (Geom.MidY - Geom.Size / 3) [Math.min (Geom.Width / 8 ) PeriodRadius] glyph-block Symbol-Geometric-Dotted : for-width-kinds WideWidth4 glyph-block-import CommonShapes @@ -62,7 +62,7 @@ glyph-block Symbol-Geometric-Dotted : for-width-kinds WideWidth4 local angle : Math.PI * 2 * j / n local cx : Geom.MidX + (Geom.Right - Geom.MidX) * [Math.cos angle] local cy : Geom.MidY + (Geom.Right - Geom.MidX) * [Math.sin angle] - include : CircleRingAt cx cy fine + include : Circle.Outline.At cx cy fine create-glyph [MangleName 'dottedSquare'] [MangleUnicode 0x2B1A] : glyph-proc set-width Geom.Width @@ -76,7 +76,7 @@ glyph-block Symbol-Geometric-Dotted : for-width-kinds WideWidth4 Bot : Geom.Bot + fine foreach j [range 0 n] : begin local t : j / n - include : CircleRingAt box.Left [mix box.Bot box.Top t] fine - include : CircleRingAt [mix box.Left box.Right t] box.Top fine - include : CircleRingAt box.Right [mix box.Top box.Bot t] fine - include : CircleRingAt [mix box.Right box.Left t] box.Bot fine + include : Circle.Outline.At box.Left [mix box.Bot box.Top t] fine + include : Circle.Outline.At [mix box.Left box.Right t] box.Top fine + include : Circle.Outline.At box.Right [mix box.Top box.Bot t] fine + include : Circle.Outline.At [mix box.Right box.Left t] box.Bot fine diff --git a/packages/font-glyphs/src/symbol/letter.ptl b/packages/font-glyphs/src/symbol/letter.ptl index 659ec7c4b..12ddbf70c 100644 --- a/packages/font-glyphs/src/symbol/letter.ptl +++ b/packages/font-glyphs/src/symbol/letter.ptl @@ -2,7 +2,10 @@ $$include '../meta/macros.ptl' +import [TransformedGeometry ContourSetGeometry] from "@iosevka/geometry" +import [Point] from "@iosevka/geometry/point" import [Box] from "@iosevka/geometry/box" +import [Transform] from "@iosevka/geometry/transform" import [mix linreg clamp fallback] from "@iosevka/util" import [DesignParameters] from "../meta/aesthetics.mjs" @@ -161,26 +164,63 @@ glyph-block Symbol-Letter : begin alias 'letterLike/kelvinSign' 0x212A 'K' - create-glyph 'estimated' 0x212E : glyph-proc - include : MarkSet.capital - local fineArc : CAP * 0.0300 - local fineBar : CAP * 0.0278 - local thickBarWidth : (0.183 / [Math.sqrt 0.9]) * [Math.sqrt (CAP * (RightSB - SB))] - define smA : ArchDepthAOf (ArchDepth * (CAP / XH)) Width - define smB : ArchDepthBOf (ArchDepth * (CAP / XH)) Width - include : union - HBar.b SB RightSB (CAP * 0.5) fineBar - difference - union - difference - OShapeOutline CAP 0 SB RightSB fineArc smA smB - OShapeOutline (CAP - fineArc) (0 + fineArc) [mix SB RightSB 0.077] [mix RightSB SB 0.077] fineArc (smA - fineArc) (smB - fineArc) - intersection - OShapeOutline.NoOvershoot CAP 0 SB RightSB fineArc smA smB - union - Rect CAP 0 SB (SB + thickBarWidth) - Rect CAP (CAP * 0.5) (RightSB - thickBarWidth) RightSB - Rect (CAP * 0.5) (CAP * 0.208) Middle Width + for-width-kinds WideWidth1 : begin + create-glyph [MangleName 'estimated'] [MangleUnicode 0x212E] : glyph-proc + set-width MosaicWidth + + local cx 500 + local cy 450 + local r1 (846 / 2) + local yGapSize 263 + local sw 183 + local r2 85 + local r3 13 + local swCenter 25 + + # Scale and transform + local desiredHeight : if FMosaicWide CAP XH + local s : Math.min (desiredHeight / (2 * cy)) ((MosaicWidth - SB) / (2 * cx)) + local glyphCenter : currentGlyph.gizmo.applyXY (MosaicWidth / 2) (desiredHeight / 2) + local tfm : Transform.Combine + Transform.Translate (-cx) (-cy) + Transform.Scale s s + Transform.Translate glyphCenter.x glyphCenter.y + + # Center of inner round corner, as well as the limit X for the inner circle edge + local xLargeRc : sw + r2 + local yLargeRc : cy - [Math.sqrt ((r1 - r2) * (r1 - r2) - (cx - sw - r2) * (cx - sw - r2))] + local xInnerCircleLimit : cx - (cx - xLargeRc) * (r1 / (r1 - r2)) + + include : ForceUpright + include : difference [Ellipse.Outline.At cx cy cx cy] + # Inner arcs + intersection [Circle.Outline.At cx cy r1] : union + Rect (2 * cy) (2 * cy - yLargeRc) xInnerCircleLimit (2 * cx - xInnerCircleLimit) + Rect yLargeRc (-1) xInnerCircleLimit cx + Rect (cy - yGapSize) (-1) (cx - 1) (2 * cx) + + # Large round corners + Circle.Outline.At xLargeRc yLargeRc r2 + Circle.Outline.At xLargeRc (2 * cy - yLargeRc) r2 + Circle.Outline.At (2 * cx - xLargeRc) (2 * cy - yLargeRc) r2 + + # Small round corners + Circle.Outline.At (sw + r3) (cy + swCenter + r3) r3 + Circle.Outline.At (2 * cx - sw - r3) (cy + swCenter + r3) r3 + Circle.Outline.At (sw + r3) (cy - r3) r3 + + # Top inner opening + Rect (2 * cy - yLargeRc) (cy + swCenter + r3) sw (2 * cx - sw) + Rect (cy + swCenter + r3 + 1) (cy + swCenter) (sw + r3) (2 * cx - sw - r3) + + # Bottom-left opening + Rect (cy - r3) yLargeRc sw cx + Rect cy (cy - r3 - 1) (sw + r3) cx + + # Bottom-right opening + Rect cy (cy - yGapSize) (cx - 1) (2 * cx) + + include tfm create-glyph 'mathAleph' 0x2135 : glyph-proc include : MarkSet.capital diff --git a/packages/font-glyphs/src/symbol/pictograph/checking-marks.ptl b/packages/font-glyphs/src/symbol/pictograph/checking-marks.ptl index 845fc90a3..643be50c2 100644 --- a/packages/font-glyphs/src/symbol/pictograph/checking-marks.ptl +++ b/packages/font-glyphs/src/symbol/pictograph/checking-marks.ptl @@ -30,7 +30,7 @@ glyph-block Symbol-Pictograph-Checking-Marks : begin set-width MosaicWidth include : dispiro widths.center sw - g4 ptSB [mix ptBot ptTop 0.46] + g4 ptSB ([mix ptBot ptTop 0.46] + 0.5 * sw) alsoThru 0.5 0.4 g4 [mix ptSB ptRSB 0.4] [mix ptBot ptTop 0.05] [heading Downward] include : dispiro diff --git a/packages/font-glyphs/src/symbol/pictograph/clock.ptl b/packages/font-glyphs/src/symbol/pictograph/clock.ptl index 46c9ab93b..458834b05 100644 --- a/packages/font-glyphs/src/symbol/pictograph/clock.ptl +++ b/packages/font-glyphs/src/symbol/pictograph/clock.ptl @@ -24,7 +24,7 @@ glyph-block Symbol-Geometric-Clock : for-width-kinds WideWidth1 set-width MosaicWidth include : RingStrokeAt Geom.MidX Geom.MidY Geom.Size mediumSw - include : CircleRingAt Geom.MidX Geom.MidY [Math.max (0.6 * mediumSw) (0.1 * Geom.Size)] + include : Circle.Outline.At Geom.MidX Geom.MidY [Math.max (0.6 * mediumSw) (0.1 * Geom.Size)] local minAngle : 2 * Math.PI * (min / 60) include : dispiro corner Geom.MidX Geom.MidY [widths.center lightSw] diff --git a/packages/font-glyphs/src/symbol/pictograph/iec-power-and-playback.ptl b/packages/font-glyphs/src/symbol/pictograph/iec-power-and-playback.ptl index 2bbc61d2b..9762a91b3 100644 --- a/packages/font-glyphs/src/symbol/pictograph/iec-power-and-playback.ptl +++ b/packages/font-glyphs/src/symbol/pictograph/iec-power-and-playback.ptl @@ -45,10 +45,10 @@ glyph-block Symbol-Pictograph-IEC-Power-And-Playback : for-width-kinds WideWidth refer-glyph [MangleName 'powerOff'] spiro-outline corner df.middle SymbolMid - corner (df.middle - gap * 2 - [HSwToV GeometryStroke]) (SymbolMid + squareRadiusFW * 2) - corner (df.middle + gap * 2 + [HSwToV GeometryStroke]) (SymbolMid + squareRadiusFW * 2) + corner (df.middle - gap * 4 - [HSwToV GeometryStroke]) (SymbolMid + squareRadiusFW * 2) + corner (df.middle + gap * 4 + [HSwToV GeometryStroke]) (SymbolMid + squareRadiusFW * 2) Rect - SymbolMid + 1.5 * squareRadiusFW + SymbolMid + 1.125 * squareRadiusFW SymbolMid - 0.0 * squareRadiusFW df.middle - [HSwToV : 0.5 * GeometryStroke] df.middle + [HSwToV : 0.5 * GeometryStroke] @@ -56,8 +56,8 @@ glyph-block Symbol-Pictograph-IEC-Power-And-Playback : for-width-kinds WideWidth create-glyph [MangleName 'powerSleep'] [MangleUnicode 0x23FE] : glyph-proc set-width df.width include : difference - CircleRingAt df.middle SymbolMid squareRadiusFW - CircleRingAt + Circle.Outline.At df.middle SymbolMid squareRadiusFW + Circle.Outline.At df.middle + squareRadiusFW * 0.5 SymbolMid + squareRadiusFW * 0.35 squareRadiusFW * 1.1 diff --git a/packages/font-glyphs/src/symbol/pictograph/stick-figure.ptl b/packages/font-glyphs/src/symbol/pictograph/stick-figure.ptl index b32924cb9..bfad6ec45 100644 --- a/packages/font-glyphs/src/symbol/pictograph/stick-figure.ptl +++ b/packages/font-glyphs/src/symbol/pictograph/stick-figure.ptl @@ -37,8 +37,8 @@ glyph-block Symbol-Pictograph-Stick-Figure : begin corner z1.x z1.y corner z2.x z2.y - if cl : include : CircleDotAt z1.x z1.y (sw / 2) - if cr : include : CircleDotAt z2.x z2.y (sw / 2) + if cl : include : Circle.Outline.DotAt z1.x z1.y (sw / 2) + if cr : include : Circle.Outline.DotAt z2.x z2.y (sw / 2) define [ArcImpl mode h1 v1 h2 v2 cl cr] : glyph-proc local z1 : tfm.applyXY [mix box.left box.right h1] [mix box.bottom box.top v1] @@ -67,8 +67,8 @@ glyph-block Symbol-Pictograph-Stick-Figure : begin flat [mix z2.x zc.x 0.001] [mix z2.y zc.y 0.001] curl z2.x z2.y - if cl : include : CircleDotAt z1.x z1.y (sw / 2) - if cr : include : CircleDotAt z2.x z2.y (sw / 2) + if cl : include : Circle.Outline.DotAt z1.x z1.y (sw / 2) + if cr : include : Circle.Outline.DotAt z2.x z2.y (sw / 2) export : define [ArcVH h1 v1 h2 v2 cl cr] : ArcImpl 1 h1 v1 h2 v2 cl cr export : define [ArcHV h1 v1 h2 v2 cl cr] : ArcImpl 0 h1 v1 h2 v2 cl cr diff --git a/packages/font-kits/package.json b/packages/font-kits/package.json index 8a7c26df7..792c6a9c7 100644 --- a/packages/font-kits/package.json +++ b/packages/font-kits/package.json @@ -1,14 +1,14 @@ { "name": "@iosevka/font-kits", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { "./boole-kit": "./src/boole-kit.mjs", "./spiro-kit": "./src/spiro-kit.mjs" }, "dependencies": { - "@iosevka/geometry": "29.0.2", - "@iosevka/glyph": "29.0.2", - "@iosevka/util": "29.0.2" + "@iosevka/geometry": "29.0.3", + "@iosevka/glyph": "29.0.3", + "@iosevka/util": "29.0.3" } } diff --git a/packages/font-kits/src/boole-kit.mjs b/packages/font-kits/src/boole-kit.mjs index c0c528492..0c35c08a8 100644 --- a/packages/font-kits/src/boole-kit.mjs +++ b/packages/font-kits/src/boole-kit.mjs @@ -17,12 +17,12 @@ class BooleImpl { const g1 = new Glyph(); g1.gizmo = forwardGizmo; g1.include(operand); - operandGeometries.push(new TransformedGeometry(g1.geometry, backwardGizmo)); + operandGeometries.push(new TransformedGeometry(backwardGizmo, g1.geometry)); } return glyph.includeGeometry( new TransformedGeometry( - new BooleanGeometry(this.operator, operandGeometries), forwardGizmo, + new BooleanGeometry(this.operator, operandGeometries), ), ); } diff --git a/packages/font-otl/package.json b/packages/font-otl/package.json index 3d580a3be..bd3ba6734 100644 --- a/packages/font-otl/package.json +++ b/packages/font-otl/package.json @@ -1,13 +1,13 @@ { "name": "@iosevka/font-otl", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs" }, "dependencies": { - "@iosevka/font-glyphs": "29.0.2", - "@iosevka/glyph": "29.0.2", + "@iosevka/font-glyphs": "29.0.3", + "@iosevka/glyph": "29.0.3", "toposort": "^2.0.2" } } diff --git a/packages/font/package.json b/packages/font/package.json index ad837d91b..8176a03fe 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/font", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs", @@ -10,13 +10,13 @@ }, "dependencies": { "@iarna/toml": "^2.2.5", - "@iosevka/font-glyphs": "29.0.2", - "@iosevka/font-otl": "29.0.2", - "@iosevka/geometry": "29.0.2", - "@iosevka/geometry-cache": "29.0.2", - "@iosevka/glyph": "29.0.2", - "@iosevka/param": "29.0.2", - "@iosevka/util": "29.0.2", + "@iosevka/font-glyphs": "29.0.3", + "@iosevka/font-otl": "29.0.3", + "@iosevka/geometry": "29.0.3", + "@iosevka/geometry-cache": "29.0.3", + "@iosevka/glyph": "29.0.3", + "@iosevka/param": "29.0.3", + "@iosevka/util": "29.0.3", "harfbuzzjs": "^0.3.4", "ot-builder": "^1.7.3", "semver": "^7.6.0" diff --git a/packages/font/src/finalize/gc.mjs b/packages/font/src/finalize/gc.mjs index e22afd7cf..172c0db9d 100644 --- a/packages/font/src/finalize/gc.mjs +++ b/packages/font/src/finalize/gc.mjs @@ -318,8 +318,8 @@ function alterGeometryAndOptimize(collection) { } cluster.representative.glyph.geometry = new Geometry.TransformedGeometry( - gT.geometry, Transform.Translate(cluster.representative.x, cluster.representative.y), + gT.geometry, ); for (const [g, tf] of cluster.aliases) { diff --git a/packages/font/src/finalize/glyphs.mjs b/packages/font/src/finalize/glyphs.mjs index 7dafc6c8b..b3ff30bd2 100644 --- a/packages/font/src/finalize/glyphs.mjs +++ b/packages/font/src/finalize/glyphs.mjs @@ -64,8 +64,8 @@ function flattenSimpleGlyph(cache, skew, g) { 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 = new Geom.TransformedGeometry( - new Geom.SimplifyGeometry(new Geom.TransformedGeometry(g.geometry, tfBack)), tfForward, + new Geom.SimplifyGeometry(new Geom.TransformedGeometry(tfBack, g.geometry)), ); } else { gSimplified = new Geom.SimplifyGeometry(g.geometry); diff --git a/packages/geometry-cache/package.json b/packages/geometry-cache/package.json index 9df087e2b..41ce60f6b 100644 --- a/packages/geometry-cache/package.json +++ b/packages/geometry-cache/package.json @@ -1,12 +1,12 @@ { "name": "@iosevka/geometry-cache", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs" }, "dependencies": { - "@iosevka/geometry": "29.0.2", + "@iosevka/geometry": "29.0.3", "@msgpack/msgpack": "^2.8.0" } } diff --git a/packages/geometry-cache/src/index.mjs b/packages/geometry-cache/src/index.mjs index e3a920b95..3de4dd2c7 100644 --- a/packages/geometry-cache/src/index.mjs +++ b/packages/geometry-cache/src/index.mjs @@ -4,7 +4,7 @@ import zlib from "zlib"; import * as CurveUtil from "@iosevka/geometry/curve-util"; import { encode, decode } from "@msgpack/msgpack"; -const Edition = 36; +const Edition = 37; const MAX_AGE = 16; class GfEntry { constructor(age, value) { diff --git a/packages/geometry/package.json b/packages/geometry/package.json index 8270259da..fcae76397 100644 --- a/packages/geometry/package.json +++ b/packages/geometry/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/geometry", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs", @@ -13,7 +13,7 @@ "./spiro-control": "./src/spiro-control.mjs" }, "dependencies": { - "@iosevka/util": "29.0.2", + "@iosevka/util": "29.0.3", "spiro": "^3.0.0", "typo-geom": "^0.15.1" } diff --git a/packages/geometry/src/curve-util.mjs b/packages/geometry/src/curve-util.mjs index c72636233..6d653023d 100644 --- a/packages/geometry/src/curve-util.mjs +++ b/packages/geometry/src/curve-util.mjs @@ -23,8 +23,8 @@ function convertContourToArcs(contour) { switch (z.type) { case Point.Type.CubicStart: { const z1 = z; - const z2 = contour[j + 1]; - const z3 = contour[j + 2]; + const z2 = contour[(j + 1) % contour.length]; + const z3 = contour[(j + 2) % contour.length]; newContour.push( new TypoGeom.Arcs.Bez3( z0, @@ -39,7 +39,7 @@ function convertContourToArcs(contour) { } case Point.Type.Quadratic: { const zc = z; - let zf = contour[j + 1] || contour[0]; + let zf = contour[(j + 1) % contour.length]; const zfIsCorner = zf.type === Point.Type.contour; if (!zfIsCorner) zf = Point.from(Point.Type.Corner, zc).mix(0.5, zf); newContour.push( diff --git a/packages/geometry/src/index.mjs b/packages/geometry/src/index.mjs index 4f88f0ed4..5010a6ba2 100644 --- a/packages/geometry/src/index.mjs +++ b/packages/geometry/src/index.mjs @@ -202,8 +202,8 @@ export class ReferenceGeometry extends GeometryBase { } unwrap() { return new TransformedGeometry( - this.m_glyph.geometry, Transform.Translate(this.m_x, this.m_y), + this.m_glyph.geometry, ); } toContours() { @@ -267,11 +267,16 @@ export class TaggedGeometry extends GeometryBase { } export class TransformedGeometry extends GeometryBase { - constructor(g, tfm) { + constructor(tfm, g) { super(); - this.m_geom = g; this.m_transform = tfm; + this.m_geom = g; } + + withTransform(tfm) { + return new TransformedGeometry(Transform.Combine(this.m_transform, tfm), this.m_geom); + } + toContours() { let result = []; for (const c of this.m_geom.toContours()) { @@ -296,7 +301,7 @@ export class TransformedGeometry extends GeometryBase { filterTag(fn) { const e = this.m_geom.filterTag(fn); if (!e) return null; - return new TransformedGeometry(e, this.m_transform); + return new TransformedGeometry(this.m_transform, e); } measureComplexity() { return ( @@ -308,26 +313,16 @@ export class TransformedGeometry extends GeometryBase { const unwrapped = this.m_geom.unlinkReferences(); if (Transform.isIdentity(this.m_transform)) { return unwrapped; - } else if ( - unwrapped instanceof TransformedGeometry && - Transform.isTranslate(this.m_transform) && - Transform.isTranslate(unwrapped.m_transform) - ) { - return new TransformedGeometry( - unwrapped.m_geom, - Transform.Translate( - this.m_transform.tx + unwrapped.m_transform.tx, - this.m_transform.ty + unwrapped.m_transform.ty, - ), - ); + } else if (unwrapped instanceof TransformedGeometry) { + return unwrapped.withTransform(this.m_transform); } else { - return new TransformedGeometry(unwrapped, this.m_transform); + return new TransformedGeometry(this.m_transform, unwrapped); } } toShapeStringOrNull() { const sTarget = this.m_geom.toShapeStringOrNull(); if (!sTarget) return null; - return Format.struct("TransformedGeometry", sTarget, Format.gizmo(this.m_transform)); + return Format.struct("TransformedGeometry", Format.gizmo(this.m_transform), sTarget); } } @@ -544,7 +539,7 @@ export class StrokeGeometry extends GeometryBase { toContours() { // Produce simplified arcs - const nonTransformedGeometry = new TransformedGeometry(this.m_geom, this.m_gizmo.inverse()); + const nonTransformedGeometry = new TransformedGeometry(this.m_gizmo.inverse(), this.m_geom); let arcs = TypoGeom.Boolean.removeOverlap( CurveUtil.convertShapeToArcs(nonTransformedGeometry.toContours()), TypoGeom.Boolean.PolyFillType.pftNonZero, diff --git a/packages/geometry/src/transform.mjs b/packages/geometry/src/transform.mjs index 3ce281b76..5d1e98b00 100644 --- a/packages/geometry/src/transform.mjs +++ b/packages/geometry/src/transform.mjs @@ -83,6 +83,11 @@ export class Transform { static isPositive(tfm) { return tfm.xx * tfm.yy - tfm.xy * tfm.yx > 0; } + static Scale(sx, sy) { + return new Transform(sx, 0, 0, sy, 0, 0); + } + + /** Combine the transfoems, in application order */ static Combine(...tfms) { let z00 = new Vec2(0, 0); let z10 = new Vec2(1, 0); diff --git a/packages/glyph/package.json b/packages/glyph/package.json index 0ee948be8..ffb8e9a7e 100644 --- a/packages/glyph/package.json +++ b/packages/glyph/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/glyph", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/glyph.mjs", @@ -9,6 +9,6 @@ "./relation": "./src/relation.mjs" }, "dependencies": { - "@iosevka/geometry": "29.0.2" + "@iosevka/geometry": "29.0.3" } } diff --git a/packages/glyph/src/glyph.mjs b/packages/glyph/src/glyph.mjs index fe069b50a..7cdf0771b 100644 --- a/packages/glyph/src/glyph.mjs +++ b/packages/glyph/src/glyph.mjs @@ -4,6 +4,7 @@ import * as Geom from "@iosevka/geometry"; import { Anchor } from "@iosevka/geometry/anchor"; import { Vec2 } from "@iosevka/geometry/point"; import { Transform } from "@iosevka/geometry/transform"; + import { ScheduleLeaningMark } from "./relation.mjs"; export class Glyph { @@ -124,7 +125,7 @@ export class Glyph { this.includeGeometry(new Geom.ReferenceGeometry(g, shiftX, shiftY)); } else { this.includeGeometry( - new Geom.TransformedGeometry(g.geometry, Transform.Translate(shiftX, shiftY)), + new Geom.TransformedGeometry(Transform.Translate(shiftX, shiftY), g.geometry), ); } } @@ -138,7 +139,7 @@ export class Glyph { this.includeGeometry(new Geom.ContourSetGeometry(cs)); } applyTransform(tfm, alsoAnchors) { - this.geometry = new Geom.TransformedGeometry(this.geometry, tfm); + this.geometry = new Geom.TransformedGeometry(tfm, this.geometry); if (alsoAnchors) { for (const k in this.baseAnchors) this.baseAnchors[k] = Anchor.transform(tfm, this.baseAnchors[k]); diff --git a/packages/param/package.json b/packages/param/package.json index ddbbbc3f1..f35dc4705 100644 --- a/packages/param/package.json +++ b/packages/param/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/param", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs", @@ -9,6 +9,6 @@ "./metric-override": "./src/metric-override.mjs" }, "dependencies": { - "@iosevka/util": "29.0.2" + "@iosevka/util": "29.0.3" } } diff --git a/packages/util/package.json b/packages/util/package.json index 63d4787d7..a140fcf86 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/util", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs", diff --git a/tools/amend-readme/package.json b/tools/amend-readme/package.json index 3651576b6..090b8da39 100644 --- a/tools/amend-readme/package.json +++ b/tools/amend-readme/package.json @@ -1,13 +1,13 @@ { "name": "@iosevka/amend-readme", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs" }, "dependencies": { "@iarna/toml": "^2.2.5", - "@iosevka/param": "29.0.2", + "@iosevka/param": "29.0.3", "@unicode/unicode-15.1.0": "^1.5.2" } } diff --git a/tools/data-export/package.json b/tools/data-export/package.json index de5612faa..36e7565d2 100644 --- a/tools/data-export/package.json +++ b/tools/data-export/package.json @@ -1,6 +1,6 @@ { "name": "@iosevka/data-export", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs", @@ -10,7 +10,7 @@ }, "dependencies": { "@iarna/toml": "^2.2.5", - "@iosevka/param": "29.0.2", + "@iosevka/param": "29.0.3", "@unicode/unicode-15.1.0": "^1.5.2", "cldr": "^7.5.0" } diff --git a/tools/generate-samples/package.json b/tools/generate-samples/package.json index 138a2bebc..9fb2747db 100644 --- a/tools/generate-samples/package.json +++ b/tools/generate-samples/package.json @@ -1,11 +1,11 @@ { "name": "@iosevka/generate-samples", - "version": "29.0.2", + "version": "29.0.3", "private": true, "exports": { ".": "./src/index.mjs" }, "dependencies": { - "@iosevka/data-export": "29.0.2" + "@iosevka/data-export": "29.0.3" } } diff --git a/tools/misc/package.json b/tools/misc/package.json index b6c5c2a61..82526b019 100644 --- a/tools/misc/package.json +++ b/tools/misc/package.json @@ -1,10 +1,10 @@ { "name": "@iosevka/misc", - "version": "29.0.2", + "version": "29.0.3", "private": true, "dependencies": { "semver": "^7.6.0", "wawoff2": "^2.0.1", - "@iosevka/util": "29.0.2" + "@iosevka/util": "29.0.3" } }