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
This commit is contained in:
Belleve 2024-03-18 17:37:17 -10:00 committed by GitHub
parent f28a26504a
commit 733f56fe79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 225 additions and 177 deletions

View file

@ -1,4 +1,6 @@
* Fix height of block quadrants (`U+2596`..`U+259F`) (#2240). * 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 LATIN {CAPITAL|SMALL} LETTER GHA (`U+01A2`..`U+01A3`) respond to variants of `q` (`cv41`).
* Make the behavior of serifs of `U+027F` automatic. * Make the behavior of serifs of `U+027F` automatic.
* Fix side bearings of `U+29E2` under Quasi-Proportional. * Fix side bearings of `U+29E2` under Quasi-Proportional.

80
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "@iosevka/monorepo", "name": "@iosevka/monorepo",
"version": "29.0.2", "version": "29.0.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@iosevka/monorepo", "name": "@iosevka/monorepo",
"version": "29.0.2", "version": "29.0.3",
"workspaces": [ "workspaces": [
"packages/*", "packages/*",
"tools/*" "tools/*"
@ -4310,16 +4310,16 @@
}, },
"packages/font": { "packages/font": {
"name": "@iosevka/font", "name": "@iosevka/font",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@iosevka/font-glyphs": "29.0.2", "@iosevka/font-glyphs": "29.0.3",
"@iosevka/font-otl": "29.0.2", "@iosevka/font-otl": "29.0.3",
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@iosevka/geometry-cache": "29.0.2", "@iosevka/geometry-cache": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"@iosevka/param": "29.0.2", "@iosevka/param": "29.0.3",
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"harfbuzzjs": "^0.3.4", "harfbuzzjs": "^0.3.4",
"ot-builder": "^1.7.3", "ot-builder": "^1.7.3",
"semver": "^7.6.0" "semver": "^7.6.0"
@ -4327,100 +4327,100 @@
}, },
"packages/font-glyphs": { "packages/font-glyphs": {
"name": "@iosevka/font-glyphs", "name": "@iosevka/font-glyphs",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/font-kits": "29.0.2", "@iosevka/font-kits": "29.0.3",
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@iosevka/geometry-cache": "29.0.2", "@iosevka/geometry-cache": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"typo-geom": "^0.15.1" "typo-geom": "^0.15.1"
} }
}, },
"packages/font-kits": { "packages/font-kits": {
"name": "@iosevka/font-kits", "name": "@iosevka/font-kits",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"@iosevka/util": "29.0.2" "@iosevka/util": "29.0.3"
} }
}, },
"packages/font-otl": { "packages/font-otl": {
"name": "@iosevka/font-otl", "name": "@iosevka/font-otl",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/font-glyphs": "29.0.2", "@iosevka/font-glyphs": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"toposort": "^2.0.2" "toposort": "^2.0.2"
} }
}, },
"packages/geometry": { "packages/geometry": {
"name": "@iosevka/geometry", "name": "@iosevka/geometry",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"spiro": "^3.0.0", "spiro": "^3.0.0",
"typo-geom": "^0.15.1" "typo-geom": "^0.15.1"
} }
}, },
"packages/geometry-cache": { "packages/geometry-cache": {
"name": "@iosevka/geometry-cache", "name": "@iosevka/geometry-cache",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@msgpack/msgpack": "^2.8.0" "@msgpack/msgpack": "^2.8.0"
} }
}, },
"packages/glyph": { "packages/glyph": {
"name": "@iosevka/glyph", "name": "@iosevka/glyph",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/geometry": "29.0.2" "@iosevka/geometry": "29.0.3"
} }
}, },
"packages/param": { "packages/param": {
"name": "@iosevka/param", "name": "@iosevka/param",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/util": "29.0.2" "@iosevka/util": "29.0.3"
} }
}, },
"packages/util": { "packages/util": {
"name": "@iosevka/util", "name": "@iosevka/util",
"version": "29.0.2" "version": "29.0.3"
}, },
"tools/amend-readme": { "tools/amend-readme": {
"name": "@iosevka/amend-readme", "name": "@iosevka/amend-readme",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@iosevka/param": "29.0.2", "@iosevka/param": "29.0.3",
"@unicode/unicode-15.1.0": "^1.5.2" "@unicode/unicode-15.1.0": "^1.5.2"
} }
}, },
"tools/data-export": { "tools/data-export": {
"name": "@iosevka/data-export", "name": "@iosevka/data-export",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@iosevka/param": "29.0.2", "@iosevka/param": "29.0.3",
"@unicode/unicode-15.1.0": "^1.5.2", "@unicode/unicode-15.1.0": "^1.5.2",
"cldr": "^7.5.0" "cldr": "^7.5.0"
} }
}, },
"tools/generate-samples": { "tools/generate-samples": {
"name": "@iosevka/generate-samples", "name": "@iosevka/generate-samples",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/data-export": "29.0.2" "@iosevka/data-export": "29.0.3"
} }
}, },
"tools/misc": { "tools/misc": {
"name": "@iosevka/misc", "name": "@iosevka/misc",
"version": "29.0.2", "version": "29.0.3",
"dependencies": { "dependencies": {
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"semver": "^7.6.0", "semver": "^7.6.0",
"wawoff2": "^2.0.1" "wawoff2": "^2.0.1"
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/monorepo", "name": "@iosevka/monorepo",
"version": "29.0.2", "version": "29.0.3",
"workspaces": [ "workspaces": [
"packages/*", "packages/*",
"tools/*" "tools/*"

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/font-glyphs", "name": "@iosevka/font-glyphs",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs", ".": "./src/index.mjs",
@ -8,11 +8,11 @@
"./unicode-knowledge": "./src/meta/unicode-knowledge.mjs" "./unicode-knowledge": "./src/meta/unicode-knowledge.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/font-kits": "29.0.2", "@iosevka/font-kits": "29.0.3",
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@iosevka/geometry-cache": "29.0.2", "@iosevka/geometry-cache": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"typo-geom": "^0.15.1" "typo-geom": "^0.15.1"
} }
} }

View file

@ -160,33 +160,38 @@ glyph-block CommonShapes : begin
glyph-block-export DotStrokeAt glyph-block-export DotStrokeAt
define [DotStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s true define [DotStrokeAt x y r s] : RingStroke (y + r) (y - r) (x - r) (x + r) s true
glyph-block-export CircleRing glyph-block-export Circle
define [CircleRing u d l r transformShiftOnly] : glyph-proc define Circle : namespace
local giz currentGlyph.gizmo export : define Outline : namespace
include : new-glyph : glyph-proc export : define [At x y r] : Ellipse.Outline.AtDimens (y + r) (y - r) (x - r) (x + r)
local my ((u + d) / 2) export : define [DotAt x y r] : Ellipse.Outline.AtDimens (y + r) (y - r) (x - r) (x + r) true
local mx ((l + r) / 2)
currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz] glyph-block-export Ellipse
include : spiro-outline define Ellipse : namespace
begin [lambda : set this.gizmo currentGlyph.gizmo] export : define Outline : namespace
g4 mx d export : define [AtDimens u d l r transformShiftOnly] : glyph-proc
archv 32 2.0 local giz currentGlyph.gizmo
g4 l my include : new-glyph : glyph-proc
arcvh 32 2.0 local my ((u + d) / 2)
g4 mx u local mx ((l + r) / 2)
archv 32 2.0 currentGlyph.gizmo = [if transformShiftOnly [Transform.Id] giz]
g4 r my include : spiro-outline
arcvh 32 2.0 begin [lambda : set this.gizmo currentGlyph.gizmo]
close g4 mx d
if transformShiftOnly : begin archv 32 2.0
local {.x mx1 .y my1} : giz.apply {.x mx .y my} g4 l my
include : Translate (mx1 - mx) (my1 - my) arcvh 32 2.0
glyph-block-export CircleRingAt g4 mx u
define [CircleRingAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) archv 32 2.0
glyph-block-export CircleDotAt g4 r my
define [CircleDotAt x y r] : CircleRing (y + r) (y - r) (x - r) (x + r) true arcvh 32 2.0
glyph-block-export RoundStrokeTerminalAt close
define [RoundStrokeTerminalAt x y r] : CircleRing (y + r) (y - r) (x - [HSwToV r]) (x + [HSwToV r]) true 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 glyph-block-export OShapeT
define [OShapeT sink u d l r _width _ada _adb] : begin define [OShapeT sink u d l r _width _ada _adb] : begin

View file

@ -89,7 +89,7 @@ define-macro flex-params : syntax-rules
local {lamBodyLeader :: lamBodyStatements} lam.2 local {lamBodyLeader :: lamBodyStatements} lam.2
local finalStatements {} local finalStatements {}
foreach stmt [items-of lamBodyStatements] : begin foreach stmt [items-of lamBodyStatements] : begin
if ([Array.isArray stmt] && stmt.0 == 'local-parameter') if ([Array.isArray stmt] && stmt.0 == 'local-parameter')
: then : begin : then : begin
@ -190,11 +190,11 @@ define-macro glyph-block-import : syntax-rules
define allExports : object define allExports : object
Common-Derivatives `[select-variant orthographic-italic orthographic-slanted Common-Derivatives `[select-variant orthographic-italic orthographic-slanted
refer-glyph query-glyph alias turned HDual HCombine VDual VCombine derive-glyphs 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] derive-multi-part-glyphs DeriveMeshT link-gr]
CommonShapes `[no-shape tagged KnotAdj Rect SquareAt Ring RingAt DotAt RingStroke 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 OShapeT OShape OShapeOutline OShapeFlatTB HSerif VSerif NeedSlab NeedNotItalic HBar
HOverlayBar VBar FlatSlashShape hookstart hookend Ungizmo Regizmo FlipAround ScaleAround HOverlayBar VBar FlatSlashShape hookstart hookend Ungizmo Regizmo FlipAround ScaleAround
Realign ForceUpright DiagCor NameUni PointingTo with-transform clear-geometry Realign ForceUpright DiagCor NameUni PointingTo with-transform clear-geometry

View file

@ -362,7 +362,7 @@ glyph-block Symbol-Arrow : for-width-kinds WideWidth1
SemiHookArrowBar x1 y1 x2 y2 halfBarWidth halfTerminal (-headWidth) 2 SemiHookArrowBar x1 y1 x2 y2 halfBarWidth halfTerminal (-headWidth) 2
define RoundArrow : namespace 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 define [Bar x1 y1 x2 y2 sw] : begin
return : PointingTo x1 y1 x2 y2 : lambda [mag] : union return : PointingTo x1 y1 x2 y2 : lambda [mag] : union

View file

@ -35,7 +35,7 @@ glyph-block Symbol-Geometric-Dice : for-width-kinds WideWidth1
define yBottom : mix yBottomEx yTopEx (1 / 5) define yBottom : mix yBottomEx yTopEx (1 / 5)
define yTop : mix yBottomEx yTopEx (4 / 5) define yTop : mix yBottomEx yTopEx (4 / 5)
foreach { px py } [items-of dots] : begin foreach { px py } [items-of dots] : begin
include : CircleDotAt include : Circle.Outline.DotAt
mix xLeft xRight (px / 2) mix xLeft xRight (px / 2)
mix yBottom yTop (py / 2) mix yBottom yTop (py / 2)
begin dr begin dr
@ -43,7 +43,7 @@ glyph-block Symbol-Geometric-Dice : for-width-kinds WideWidth1
create-glyph [MangleName 'dottedWhiteTriangle'] [MangleUnicode 0x25EC] : glyph-proc create-glyph [MangleName 'dottedWhiteTriangle'] [MangleUnicode 0x25EC] : glyph-proc
set-width Geom.Width set-width Geom.Width
include : refer-glyph : MangleName 'whiteTriangleUp' 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 Symbol-Geometric-Dotted : for-width-kinds WideWidth4
glyph-block-import CommonShapes 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 angle : Math.PI * 2 * j / n
local cx : Geom.MidX + (Geom.Right - Geom.MidX) * [Math.cos angle] local cx : Geom.MidX + (Geom.Right - Geom.MidX) * [Math.cos angle]
local cy : Geom.MidY + (Geom.Right - Geom.MidX) * [Math.sin 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 create-glyph [MangleName 'dottedSquare'] [MangleUnicode 0x2B1A] : glyph-proc
set-width Geom.Width set-width Geom.Width
@ -76,7 +76,7 @@ glyph-block Symbol-Geometric-Dotted : for-width-kinds WideWidth4
Bot : Geom.Bot + fine Bot : Geom.Bot + fine
foreach j [range 0 n] : begin foreach j [range 0 n] : begin
local t : j / n local t : j / n
include : CircleRingAt box.Left [mix box.Bot box.Top t] fine include : Circle.Outline.At box.Left [mix box.Bot box.Top t] fine
include : CircleRingAt [mix box.Left box.Right t] box.Top fine include : Circle.Outline.At [mix box.Left box.Right t] box.Top fine
include : CircleRingAt box.Right [mix box.Top box.Bot t] fine include : Circle.Outline.At box.Right [mix box.Top box.Bot t] fine
include : CircleRingAt [mix box.Right box.Left t] box.Bot fine include : Circle.Outline.At [mix box.Right box.Left t] box.Bot fine

View file

@ -2,7 +2,10 @@
$$include '../meta/macros.ptl' $$include '../meta/macros.ptl'
import [TransformedGeometry ContourSetGeometry] from "@iosevka/geometry"
import [Point] from "@iosevka/geometry/point"
import [Box] from "@iosevka/geometry/box" import [Box] from "@iosevka/geometry/box"
import [Transform] from "@iosevka/geometry/transform"
import [mix linreg clamp fallback] from "@iosevka/util" import [mix linreg clamp fallback] from "@iosevka/util"
import [DesignParameters] from "../meta/aesthetics.mjs" import [DesignParameters] from "../meta/aesthetics.mjs"
@ -161,26 +164,63 @@ glyph-block Symbol-Letter : begin
alias 'letterLike/kelvinSign' 0x212A 'K' alias 'letterLike/kelvinSign' 0x212A 'K'
create-glyph 'estimated' 0x212E : glyph-proc for-width-kinds WideWidth1 : begin
include : MarkSet.capital create-glyph [MangleName 'estimated'] [MangleUnicode 0x212E] : glyph-proc
local fineArc : CAP * 0.0300 set-width MosaicWidth
local fineBar : CAP * 0.0278
local thickBarWidth : (0.183 / [Math.sqrt 0.9]) * [Math.sqrt (CAP * (RightSB - SB))] local cx 500
define smA : ArchDepthAOf (ArchDepth * (CAP / XH)) Width local cy 450
define smB : ArchDepthBOf (ArchDepth * (CAP / XH)) Width local r1 (846 / 2)
include : union local yGapSize 263
HBar.b SB RightSB (CAP * 0.5) fineBar local sw 183
difference local r2 85
union local r3 13
difference local swCenter 25
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) # Scale and transform
intersection local desiredHeight : if FMosaicWide CAP XH
OShapeOutline.NoOvershoot CAP 0 SB RightSB fineArc smA smB local s : Math.min (desiredHeight / (2 * cy)) ((MosaicWidth - SB) / (2 * cx))
union local glyphCenter : currentGlyph.gizmo.applyXY (MosaicWidth / 2) (desiredHeight / 2)
Rect CAP 0 SB (SB + thickBarWidth) local tfm : Transform.Combine
Rect CAP (CAP * 0.5) (RightSB - thickBarWidth) RightSB Transform.Translate (-cx) (-cy)
Rect (CAP * 0.5) (CAP * 0.208) Middle Width 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 create-glyph 'mathAleph' 0x2135 : glyph-proc
include : MarkSet.capital include : MarkSet.capital

View file

@ -30,7 +30,7 @@ glyph-block Symbol-Pictograph-Checking-Marks : begin
set-width MosaicWidth set-width MosaicWidth
include : dispiro include : dispiro
widths.center sw 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 alsoThru 0.5 0.4
g4 [mix ptSB ptRSB 0.4] [mix ptBot ptTop 0.05] [heading Downward] g4 [mix ptSB ptRSB 0.4] [mix ptBot ptTop 0.05] [heading Downward]
include : dispiro include : dispiro

View file

@ -24,7 +24,7 @@ glyph-block Symbol-Geometric-Clock : for-width-kinds WideWidth1
set-width MosaicWidth set-width MosaicWidth
include : RingStrokeAt Geom.MidX Geom.MidY Geom.Size mediumSw 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) local minAngle : 2 * Math.PI * (min / 60)
include : dispiro include : dispiro
corner Geom.MidX Geom.MidY [widths.center lightSw] corner Geom.MidX Geom.MidY [widths.center lightSw]

View file

@ -45,10 +45,10 @@ glyph-block Symbol-Pictograph-IEC-Power-And-Playback : for-width-kinds WideWidth
refer-glyph [MangleName 'powerOff'] refer-glyph [MangleName 'powerOff']
spiro-outline spiro-outline
corner df.middle SymbolMid corner df.middle SymbolMid
corner (df.middle - gap * 2 - [HSwToV GeometryStroke]) (SymbolMid + squareRadiusFW * 2) corner (df.middle - gap * 4 - [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)
Rect Rect
SymbolMid + 1.5 * squareRadiusFW SymbolMid + 1.125 * squareRadiusFW
SymbolMid - 0.0 * squareRadiusFW SymbolMid - 0.0 * squareRadiusFW
df.middle - [HSwToV : 0.5 * GeometryStroke] df.middle - [HSwToV : 0.5 * GeometryStroke]
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 create-glyph [MangleName 'powerSleep'] [MangleUnicode 0x23FE] : glyph-proc
set-width df.width set-width df.width
include : difference include : difference
CircleRingAt df.middle SymbolMid squareRadiusFW Circle.Outline.At df.middle SymbolMid squareRadiusFW
CircleRingAt Circle.Outline.At
df.middle + squareRadiusFW * 0.5 df.middle + squareRadiusFW * 0.5
SymbolMid + squareRadiusFW * 0.35 SymbolMid + squareRadiusFW * 0.35
squareRadiusFW * 1.1 squareRadiusFW * 1.1

View file

@ -37,8 +37,8 @@ glyph-block Symbol-Pictograph-Stick-Figure : begin
corner z1.x z1.y corner z1.x z1.y
corner z2.x z2.y corner z2.x z2.y
if cl : include : CircleDotAt z1.x z1.y (sw / 2) if cl : include : Circle.Outline.DotAt z1.x z1.y (sw / 2)
if cr : include : CircleDotAt z2.x z2.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 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] 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] flat [mix z2.x zc.x 0.001] [mix z2.y zc.y 0.001]
curl z2.x z2.y curl z2.x z2.y
if cl : include : CircleDotAt z1.x z1.y (sw / 2) if cl : include : Circle.Outline.DotAt z1.x z1.y (sw / 2)
if cr : include : CircleDotAt z2.x z2.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 [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 export : define [ArcHV h1 v1 h2 v2 cl cr] : ArcImpl 0 h1 v1 h2 v2 cl cr

View file

@ -1,14 +1,14 @@
{ {
"name": "@iosevka/font-kits", "name": "@iosevka/font-kits",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
"./boole-kit": "./src/boole-kit.mjs", "./boole-kit": "./src/boole-kit.mjs",
"./spiro-kit": "./src/spiro-kit.mjs" "./spiro-kit": "./src/spiro-kit.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"@iosevka/util": "29.0.2" "@iosevka/util": "29.0.3"
} }
} }

View file

@ -17,12 +17,12 @@ class BooleImpl {
const g1 = new Glyph(); const g1 = new Glyph();
g1.gizmo = forwardGizmo; g1.gizmo = forwardGizmo;
g1.include(operand); g1.include(operand);
operandGeometries.push(new TransformedGeometry(g1.geometry, backwardGizmo)); operandGeometries.push(new TransformedGeometry(backwardGizmo, g1.geometry));
} }
return glyph.includeGeometry( return glyph.includeGeometry(
new TransformedGeometry( new TransformedGeometry(
new BooleanGeometry(this.operator, operandGeometries),
forwardGizmo, forwardGizmo,
new BooleanGeometry(this.operator, operandGeometries),
), ),
); );
} }

View file

@ -1,13 +1,13 @@
{ {
"name": "@iosevka/font-otl", "name": "@iosevka/font-otl",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs" ".": "./src/index.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/font-glyphs": "29.0.2", "@iosevka/font-glyphs": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"toposort": "^2.0.2" "toposort": "^2.0.2"
} }
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/font", "name": "@iosevka/font",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs", ".": "./src/index.mjs",
@ -10,13 +10,13 @@
}, },
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@iosevka/font-glyphs": "29.0.2", "@iosevka/font-glyphs": "29.0.3",
"@iosevka/font-otl": "29.0.2", "@iosevka/font-otl": "29.0.3",
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@iosevka/geometry-cache": "29.0.2", "@iosevka/geometry-cache": "29.0.3",
"@iosevka/glyph": "29.0.2", "@iosevka/glyph": "29.0.3",
"@iosevka/param": "29.0.2", "@iosevka/param": "29.0.3",
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"harfbuzzjs": "^0.3.4", "harfbuzzjs": "^0.3.4",
"ot-builder": "^1.7.3", "ot-builder": "^1.7.3",
"semver": "^7.6.0" "semver": "^7.6.0"

View file

@ -318,8 +318,8 @@ function alterGeometryAndOptimize(collection) {
} }
cluster.representative.glyph.geometry = new Geometry.TransformedGeometry( cluster.representative.glyph.geometry = new Geometry.TransformedGeometry(
gT.geometry,
Transform.Translate(cluster.representative.x, cluster.representative.y), Transform.Translate(cluster.representative.x, cluster.representative.y),
gT.geometry,
); );
for (const [g, tf] of cluster.aliases) { for (const [g, tf] of cluster.aliases) {

View file

@ -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 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); const tfForward = g.gizmo ? g.gizmo : new Transform(1, +skew, 0, 1, 0, 0);
gSimplified = new Geom.TransformedGeometry( gSimplified = new Geom.TransformedGeometry(
new Geom.SimplifyGeometry(new Geom.TransformedGeometry(g.geometry, tfBack)),
tfForward, tfForward,
new Geom.SimplifyGeometry(new Geom.TransformedGeometry(tfBack, g.geometry)),
); );
} else { } else {
gSimplified = new Geom.SimplifyGeometry(g.geometry); gSimplified = new Geom.SimplifyGeometry(g.geometry);

View file

@ -1,12 +1,12 @@
{ {
"name": "@iosevka/geometry-cache", "name": "@iosevka/geometry-cache",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs" ".": "./src/index.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/geometry": "29.0.2", "@iosevka/geometry": "29.0.3",
"@msgpack/msgpack": "^2.8.0" "@msgpack/msgpack": "^2.8.0"
} }
} }

View file

@ -4,7 +4,7 @@ import zlib from "zlib";
import * as CurveUtil from "@iosevka/geometry/curve-util"; import * as CurveUtil from "@iosevka/geometry/curve-util";
import { encode, decode } from "@msgpack/msgpack"; import { encode, decode } from "@msgpack/msgpack";
const Edition = 36; const Edition = 37;
const MAX_AGE = 16; const MAX_AGE = 16;
class GfEntry { class GfEntry {
constructor(age, value) { constructor(age, value) {

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/geometry", "name": "@iosevka/geometry",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs", ".": "./src/index.mjs",
@ -13,7 +13,7 @@
"./spiro-control": "./src/spiro-control.mjs" "./spiro-control": "./src/spiro-control.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/util": "29.0.2", "@iosevka/util": "29.0.3",
"spiro": "^3.0.0", "spiro": "^3.0.0",
"typo-geom": "^0.15.1" "typo-geom": "^0.15.1"
} }

View file

@ -23,8 +23,8 @@ function convertContourToArcs(contour) {
switch (z.type) { switch (z.type) {
case Point.Type.CubicStart: { case Point.Type.CubicStart: {
const z1 = z; const z1 = z;
const z2 = contour[j + 1]; const z2 = contour[(j + 1) % contour.length];
const z3 = contour[j + 2]; const z3 = contour[(j + 2) % contour.length];
newContour.push( newContour.push(
new TypoGeom.Arcs.Bez3( new TypoGeom.Arcs.Bez3(
z0, z0,
@ -39,7 +39,7 @@ function convertContourToArcs(contour) {
} }
case Point.Type.Quadratic: { case Point.Type.Quadratic: {
const zc = z; const zc = z;
let zf = contour[j + 1] || contour[0]; let zf = contour[(j + 1) % contour.length];
const zfIsCorner = zf.type === Point.Type.contour; const zfIsCorner = zf.type === Point.Type.contour;
if (!zfIsCorner) zf = Point.from(Point.Type.Corner, zc).mix(0.5, zf); if (!zfIsCorner) zf = Point.from(Point.Type.Corner, zc).mix(0.5, zf);
newContour.push( newContour.push(

View file

@ -202,8 +202,8 @@ export class ReferenceGeometry extends GeometryBase {
} }
unwrap() { unwrap() {
return new TransformedGeometry( return new TransformedGeometry(
this.m_glyph.geometry,
Transform.Translate(this.m_x, this.m_y), Transform.Translate(this.m_x, this.m_y),
this.m_glyph.geometry,
); );
} }
toContours() { toContours() {
@ -267,11 +267,16 @@ export class TaggedGeometry extends GeometryBase {
} }
export class TransformedGeometry extends GeometryBase { export class TransformedGeometry extends GeometryBase {
constructor(g, tfm) { constructor(tfm, g) {
super(); super();
this.m_geom = g;
this.m_transform = tfm; this.m_transform = tfm;
this.m_geom = g;
} }
withTransform(tfm) {
return new TransformedGeometry(Transform.Combine(this.m_transform, tfm), this.m_geom);
}
toContours() { toContours() {
let result = []; let result = [];
for (const c of this.m_geom.toContours()) { for (const c of this.m_geom.toContours()) {
@ -296,7 +301,7 @@ export class TransformedGeometry extends GeometryBase {
filterTag(fn) { filterTag(fn) {
const e = this.m_geom.filterTag(fn); const e = this.m_geom.filterTag(fn);
if (!e) return null; if (!e) return null;
return new TransformedGeometry(e, this.m_transform); return new TransformedGeometry(this.m_transform, e);
} }
measureComplexity() { measureComplexity() {
return ( return (
@ -308,26 +313,16 @@ export class TransformedGeometry extends GeometryBase {
const unwrapped = this.m_geom.unlinkReferences(); const unwrapped = this.m_geom.unlinkReferences();
if (Transform.isIdentity(this.m_transform)) { if (Transform.isIdentity(this.m_transform)) {
return unwrapped; return unwrapped;
} else if ( } else if (unwrapped instanceof TransformedGeometry) {
unwrapped instanceof TransformedGeometry && return unwrapped.withTransform(this.m_transform);
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 { } else {
return new TransformedGeometry(unwrapped, this.m_transform); return new TransformedGeometry(this.m_transform, unwrapped);
} }
} }
toShapeStringOrNull() { toShapeStringOrNull() {
const sTarget = this.m_geom.toShapeStringOrNull(); const sTarget = this.m_geom.toShapeStringOrNull();
if (!sTarget) return null; 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() { toContours() {
// Produce simplified arcs // 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( let arcs = TypoGeom.Boolean.removeOverlap(
CurveUtil.convertShapeToArcs(nonTransformedGeometry.toContours()), CurveUtil.convertShapeToArcs(nonTransformedGeometry.toContours()),
TypoGeom.Boolean.PolyFillType.pftNonZero, TypoGeom.Boolean.PolyFillType.pftNonZero,

View file

@ -83,6 +83,11 @@ export class Transform {
static isPositive(tfm) { static isPositive(tfm) {
return tfm.xx * tfm.yy - tfm.xy * tfm.yx > 0; 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) { static Combine(...tfms) {
let z00 = new Vec2(0, 0); let z00 = new Vec2(0, 0);
let z10 = new Vec2(1, 0); let z10 = new Vec2(1, 0);

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/glyph", "name": "@iosevka/glyph",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/glyph.mjs", ".": "./src/glyph.mjs",
@ -9,6 +9,6 @@
"./relation": "./src/relation.mjs" "./relation": "./src/relation.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/geometry": "29.0.2" "@iosevka/geometry": "29.0.3"
} }
} }

View file

@ -4,6 +4,7 @@ import * as Geom from "@iosevka/geometry";
import { Anchor } from "@iosevka/geometry/anchor"; import { Anchor } from "@iosevka/geometry/anchor";
import { Vec2 } from "@iosevka/geometry/point"; import { Vec2 } from "@iosevka/geometry/point";
import { Transform } from "@iosevka/geometry/transform"; import { Transform } from "@iosevka/geometry/transform";
import { ScheduleLeaningMark } from "./relation.mjs"; import { ScheduleLeaningMark } from "./relation.mjs";
export class Glyph { export class Glyph {
@ -124,7 +125,7 @@ export class Glyph {
this.includeGeometry(new Geom.ReferenceGeometry(g, shiftX, shiftY)); this.includeGeometry(new Geom.ReferenceGeometry(g, shiftX, shiftY));
} else { } else {
this.includeGeometry( 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)); this.includeGeometry(new Geom.ContourSetGeometry(cs));
} }
applyTransform(tfm, alsoAnchors) { applyTransform(tfm, alsoAnchors) {
this.geometry = new Geom.TransformedGeometry(this.geometry, tfm); this.geometry = new Geom.TransformedGeometry(tfm, this.geometry);
if (alsoAnchors) { if (alsoAnchors) {
for (const k in this.baseAnchors) for (const k in this.baseAnchors)
this.baseAnchors[k] = Anchor.transform(tfm, this.baseAnchors[k]); this.baseAnchors[k] = Anchor.transform(tfm, this.baseAnchors[k]);

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/param", "name": "@iosevka/param",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs", ".": "./src/index.mjs",
@ -9,6 +9,6 @@
"./metric-override": "./src/metric-override.mjs" "./metric-override": "./src/metric-override.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/util": "29.0.2" "@iosevka/util": "29.0.3"
} }
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/util", "name": "@iosevka/util",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs", ".": "./src/index.mjs",

View file

@ -1,13 +1,13 @@
{ {
"name": "@iosevka/amend-readme", "name": "@iosevka/amend-readme",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs" ".": "./src/index.mjs"
}, },
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@iosevka/param": "29.0.2", "@iosevka/param": "29.0.3",
"@unicode/unicode-15.1.0": "^1.5.2" "@unicode/unicode-15.1.0": "^1.5.2"
} }
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "@iosevka/data-export", "name": "@iosevka/data-export",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs", ".": "./src/index.mjs",
@ -10,7 +10,7 @@
}, },
"dependencies": { "dependencies": {
"@iarna/toml": "^2.2.5", "@iarna/toml": "^2.2.5",
"@iosevka/param": "29.0.2", "@iosevka/param": "29.0.3",
"@unicode/unicode-15.1.0": "^1.5.2", "@unicode/unicode-15.1.0": "^1.5.2",
"cldr": "^7.5.0" "cldr": "^7.5.0"
} }

View file

@ -1,11 +1,11 @@
{ {
"name": "@iosevka/generate-samples", "name": "@iosevka/generate-samples",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"exports": { "exports": {
".": "./src/index.mjs" ".": "./src/index.mjs"
}, },
"dependencies": { "dependencies": {
"@iosevka/data-export": "29.0.2" "@iosevka/data-export": "29.0.3"
} }
} }

View file

@ -1,10 +1,10 @@
{ {
"name": "@iosevka/misc", "name": "@iosevka/misc",
"version": "29.0.2", "version": "29.0.3",
"private": true, "private": true,
"dependencies": { "dependencies": {
"semver": "^7.6.0", "semver": "^7.6.0",
"wawoff2": "^2.0.1", "wawoff2": "^2.0.1",
"@iosevka/util": "29.0.2" "@iosevka/util": "29.0.3"
} }
} }