V4: Initial implementation of refactored character variant system

This commit is contained in:
be5invis 2020-10-26 01:33:33 -07:00
parent 58c472342b
commit c1c3ce79ee
88 changed files with 2870 additions and 2381 deletions

558
README.md
View file

@ -78,13 +78,35 @@ Since version 2.0, Iosevka would no longer support building via `makefile`. To i
<!-- BEGIN Section-Private-Build-Plan-Sample -->
<!-- THIS SECTION IS AUTOMATICALLY GENERATED. DO NOT EDIT. -->
[buildPlans.iosevka-custom] # <iosevka-custom> is your plan name
family = "Iosevka Custom" # Font menu family name
design = ["v-i-hooky", "v-l-hooky"] # Customize styles
# upright = ["upright-styles"] # Uncomment this line to set styles for upright only
# italic = ["italic-styles"] # Uncomment this line to set styles for italic only
# oblique = ["oblique-styles"] # Uncomment this line to set styles for oblique only
# hintParams = ["-a", "sss"] # Optional custom parameters for ttfautohint
[buildPlans.iosevka-custom] # <iosevka-custom> is your plan name
family = "Iosevka Custom" # Font menu family name
spacing = "normal" # Optional; Values: `normal`, `term`, `fontconfig-mono`, or `fixed`
serifs = "sans" # Optional; Values: `sans` or `slab`
digit-form = "lining" # Optional; Values `lining` or `olt-style`
###################################################################################################
# Configure variants
# Optional; Whether to inherit a `ss##` variant
[buildPlans.iosevka-custom.variants]
inherits = ["ss01"]
# Optional; Configure single character's variant
[buildPlans.iosevka-custom.variants.design]
g = 'singlestorey'
# Optional; Configure single character's variant for Upright and Oblique; Overrides [design]
[buildPlans.iosevka-custom.variants.upright]
i = 'zshaped'
l = 'zshaped'
# Optional; Configure single character's variant for Italic only; Overrides [design]
[buildPlans.iosevka-custom.variants.italic]
i = 'italic'
l = 'italic'
# End variant section
###################################################################################################
###################################################################################################
# Override default building weights
@ -194,7 +216,7 @@ Since version 2.0, Iosevka would no longer support building via `makefile`. To i
<!-- END Section-Private-Build-Plan-Sample -->
3. Run `npm run build -- contents::<your plan name>` and the built fonts would be avaliable in `dist/`. Aside from `contents::<plan>`, other options are:
@ -317,294 +339,292 @@ The current available styles for `design`/`upright`/`italic`/`oblique` options a
* Styles for individual characters. They are easy-to-understand names of the `cv##` styles, including:
* Styles for `a`:
* `v-a-doublestorey`, `cv01`: Double-storey `a` (default for Upright).
* `v-a-singlestorey`, `cv02`: Single-storey `a`.
* `v-a-singlestorey-tailed`, `VXBS`: Single-storey `a` with curly tail (default for Italic).
* `v-a-doublestorey-tailed`, `VXBU`: Double-storey `a` with curly tail.
* `v-a-singlestorey-earless-corner`, `VXCL`: Earless (cornered top-right) single-storey `a`.
* `v-a-singlestorey-earless-corner-tailed`, `VXCM`: Earless (cornered top-right) single-storey `a` with curly tail.
* `v-a-singlestorey-earless-rounded`, `VXCN`: Earless (rounded top-right) single-storey `a`.
* `v-a-singlestorey-earless-rounded-tailed`, `VXCO`: Earless (rounded top-right) single-storey `a` with curly tail.
* `v-a-doublestorey-toothless-corner`, `VXDM`: Toothless (cornered bottom-right) double-storey `a`.
* `v-a-doublestorey-toothless-rounded`, `VXDN`: Toothless (rounded bottom-right) double-storey `a`.
* Styles for `b`:
* `v-b-toothed`, `VXBK`: `b` with bottom-left tooth (default).
* `v-b-toothless-corner`, `VXBL`: `b` without bottom-left tooth, with a corner transition.
* `v-b-toothless-rounded`, `VXBM`: `b` without bottom-left tooth, with a rounded transition.
* Styles for `d`:
* `v-d-toothed`, `VXBN`: `d` with bottom-right tooth (default for Upright).
* `v-d-toothless-corner`, `VXBO`: `d` without bottom-right tooth, with a corner transition.
* `v-d-toothless-rounded`, `VXBP`: `d` without bottom-right tooth, with a rounded transition.
* `v-d-tailed`, `VXBQ`: `d` with a slightly tail bottom-right tail (default for Italic).
* Styles for `f`:
* `v-f-straight`, `cv52`: `f` without bottom hook (default for Sans Upright).
* `v-f-tailed`, `cv53`: `f` with a leftward bottom hook (default for Italic).
* `v-f-serifed`, `cv84`: `f` with bottom serif (default for Slab Upright).
* `v-f-straight-tailed`, `VXAD`: `f` with straight tail.
* `v-f-flat-hook`, `VXDD`: `f` with flat hook.
* `v-f-flat-hook-crossbar-at-x-height`, `VXEG`: `f` with flat hook and crossbar placed right at X-height.
* `v-f-flat-hook-serifed`, `VXEV`: `f` with flat hook and bottom serif.
* `v-f-flat-hook-serifed-crossbar-at-x-height`, `VXEW`: `f` with flat hook, bottom serif, and crossbar placed right at X-height.
* `v-f-flat-hook-round-tailed`, `VXEX`: `f` with flat hook.
* `v-f-flat-hook-round-tailed-crossbar-at-x-height`, `VXEY`: `f` with flat hook and crossbar placed right at X-height.
* `v-f-flat-hook-flat-tailed`, `VXEZ`: `f` with flat hook and bottom serif.
* `v-f-flat-hook-flat-tailed-crossbar-at-x-height`, `VXFA`: `f` with flat hook, bottom serif, and crossbar placed right at X-height.
* Styles for `g`:
* `v-g-doublestorey`, `cv11`: Double-storey `g`.
* `v-g-singlestorey`, `cv12`: Single-storey `g` (default).
* `v-g-opendoublestorey`, `cv24`: Open Double-storey `g`, like Trebuchet MS or Fira Code.
* `v-g-earless-corner`, `VXCW`: Earless (cornered top-right) single-storey `g`.
* `v-g-earless-rounded`, `VXCX`: Earless (rounded top-right) single-storey `g`.
* Styles for `h`:
* `v-h-straight`, `VXCB`: `h` with straight ending (default).
* `v-h-tailed`, `VXCC`: `h` with curly tailed ending.
* `v-h-motion-serifed-straight`, `VXEK`: `h` with straight ending.
* `v-h-motion-serifed-tailed`, `VXEL`: `h` with curly tailed ending.
* Styles for `i`:
* `v-i-serifed`, `cv03`: Serifed `i` (default for Upright).
* `v-i-italic`, `cv04`: Italic `i` (default for Italic).
* `v-i-hooky`, `cv05`: Hooky `i`.
* `v-i-zshaped`, `cv06`: Z-shaped `i`.
* `v-i-line`, `cv56`: `i` like a straight line.
* `v-i-tailed`, `cv88`: Tailed `i`.
* `v-i-hookybottom`, `VXAA`: `i` with a straight tail.
* `v-i-serifed-asymmetric`, `VXDK`: `i` with shorter top serif and full bottom serif.
* Styles for `j`:
* `v-j-line`, `cv57`: `j` like a straight line.
* `v-j-serifed`, `cv58`: `j` with top serif (default).
* `v-j-straight`, `cv98`: `j` without serif.
* `v-j-flat-hook-serifed`, `VXDE`: undefined.
* `v-j-flat-hook-serifless`, `VXDF`: undefined.
* Styles for `k`:
* `v-k-straight`, `cv68`: `k` with standard shape (default for Upright).
* `v-k-curly`, `cv69`: Slightly curly `k`, like Iosevka 2.x.
* `v-k-cursive`, `cv70`: `k` with a cursive loop (default for Italic).
* Styles for `l`:
* `v-l-serifed`, `cv07`: Serifed `l` (default for Upright).
* `v-l-italic`, `cv08`: Italic, cursive `l` (default for Italic).
* `v-l-hooky`, `cv09`: Hooky `l`.
* `v-l-zshaped`, `cv10`: Z-shaped `l`.
* `v-l-tailed`, `cv27`: `l` with a curved tail.
* `v-l-hookybottom`, `cv28`: `l` with a straight tail.
* `v-l-line`, `cv59`: `l` like a straight line.
* `v-l-serifed-asymmetric`, `VXDL`: `l` with shorter top serif and full bottom serif.
* Styles for `m`:
* `v-m-normal`, `cv25`: `m` with normal middle leg, touching the baseline (default).
* `v-m-shortleg`, `cv26`: `m` with shorter middle leg, like Ubuntu Mono.
* `v-m-tailed`, `VXCD`: `m` with normal middle leg, touching the baseline, and a curly tail.
* `v-m-shortleg-tailed`, `VXCE`: `m` with shorter middle leg, like Ubuntu Mono, and a curly tail.
* `v-m-earless-corner-double-arch`, `VXDU`: Earless (corner top-left) `m` with normal middle leg touching baseline.
* `v-m-earless-corner-double-arch-shortleg`, `VXDV`: Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono.
* `v-m-earless-corner-double-arch-tailed`, `VXDW`: Earless (corner top-left) `m` with normal middle leg touching baseline, and a curly tail.
* `v-m-earless-corner-double-arch-shortleg-tailed`, `VXDX`: Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail.
* `v-m-earless-rounded-double-arch`, `VXDY`: Earless (rounded top-left) `m` with normal middle leg touching baseline.
* `v-m-earless-rounded-double-arch-shortleg`, `VXDZ`: Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono.
* `v-m-earless-rounded-double-arch-tailed`, `VXEA`: Earless (rounded top-left) `m` with normal middle leg touching baseline, and a curly tail.
* `v-m-earless-rounded-double-arch-shortleg-tailed`, `VXEB`: Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail.
* `v-m-earless-single-arch`, `VXEC`: Earless (single-arch) `m` with normal middle leg touching baseline.
* `v-m-earless-single-arch-shortleg`, `VXED`: Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono.
* `v-m-earless-single-arch-tailed`, `VXEE`: Earless (single-arch) `m` with normal middle leg touching baseline, and a curly tail.
* `v-m-earless-single-arch-shortleg-tailed`, `VXEF`: Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail.
* `v-m-motion-serifed`, `VXEM`: `m` with motion serifs, normal middle leg touching baseline.
* `v-m-motion-serifed-shortleg`, `VXEN`: `m` with motion serifs, a shorter middle leg like Ubuntu Mono.
* `v-m-motion-serifed-tailed`, `VXEO`: `m` with motion serifs, normal middle leg touching baseline, and a curly tail.
* `v-m-motion-serifed-shortleg-tailed`, `VXEP`: `m` with motion serifs, a shorter middle leg like Ubuntu Mono, and a curly tail.
* Styles for `n`:
* `v-n-straight`, `VXCF`: `n` with straight ending (default).
* `v-n-tailed`, `VXCG`: `n` with a curly tail.
* `v-n-earless-corner-straight`, `VXDO`: Earless (corner top-left) `n` with straight ending.
* `v-n-earless-corner-tailed`, `VXDP`: Earless (corner top-left) `n` with a curly tail.
* `v-n-earless-rounded-straight`, `VXDQ`: Earless (rounded top-left) `n` with straight ending.
* `v-n-earless-rounded-tailed`, `VXDR`: Earless (rounded top-left) `n` with a curly tail.
* `v-n-motion-serifed-straight`, `VXEQ`: `n` with motion serifs and straight ending.
* `v-n-motion-serifed-tailed`, `VXER`: `n` with motion serifs and a curly tail.
* Styles for `p`:
* `v-p-eared`, `VXCP`: `p` with top-left ear (default).
* `v-p-earless-corner`, `VXCQ`: `p` without top-left ear (corner).
* `v-p-earless-rounded`, `VXCR`: `p` without top-left ear (rounded).
* `v-p-motion-serifed`, `VXES`: `p` with motion serifs.
* Styles for `q`:
* `v-q-straight`, `VXAZ`: `q` with straight bar (default).
* `v-q-tailed`, `VXBA`: `q` with tail.
* `v-q-earless-corner`, `VXCS`: Earless (cornered top-left) single-storey `q`.
* `v-q-earless-corner-tailed`, `VXCT`: Earless (cornered top-left) single-storey `q` with curly tail.
* `v-q-earless-rounded`, `VXCU`: Earless (rounded top-left) single-storey `q`.
* `v-q-earless-rounded-tailed`, `VXCV`: Earless (rounded top-left) single-storey `q` with curly tail.
* Styles for `r`:
* `v-r-straight`, `cv85`: Straight, serif-less `r` (default for Sans).
* `v-r-serifed`, `cv86`: `r` with serif at both top and bottom (default for Slab Upright).
* `v-r-top-serifed`, `cv87`: `r` with serifs at top-left only (default for Slab Italic).
* `v-r-earless-corner`, `VXDS`: Earless (corner top-left), serif-less `r`.
* `v-r-earless-rounded`, `VXDT`: Earless (rounded top-left), serif-less `r`.
* Styles for `t`:
* `v-t-standard`, `cv40`: Standard `t` shape (default).
* `v-t-cross`, `cv41`: Futura-like `t` shape.
* `v-t-flat-hook`, `VXDC`: `t` with flat hook.
* `v-t-hookless-asymmetric`, `VXEH`: `t` without hook and ony half the cross bar.
* `v-t-flat-hook-short-neck`, `VXEI`: `t` with flat hook and a slightly shorter neck.
* `v-t-flat-hook-short-neck2`, `VXEJ`: `t` with flat hook and a more shorter neck.
* Styles for `u`:
* `v-u-with-bar`, `cv89`: Normal `u` with right bar (default for Upright).
* `v-u-without-bar`, `cv90`: Normal `u` without right bar, like a smaller uppercase `U`.
* `v-u-tailed`, `VXBT`: `u` with right bar and a slightly curly tail (default for Italic).
* `v-u-motion-serifed`, `VXET`: Normal `u` with right bar and motion serifs.
* `v-u-motion-serifed-tailed`, `VXEU`: `u` with right bar, motion serifs and a slightly curly tail.
* Styles for `v`, `V`:
* `v-v-straight`, `cv71`: Standard, straight `V` and `v` (default).
* `v-v-curly`, `cv72`:  Slightly curly `V` and `v`, like Iosevka 2.x.
* Styles for `w`, `W`:
* `v-w-straight`, `cv75`: Standard, straight `W` and `w` (default).
* `v-w-curly`, `cv76`: Slightly curly `W` and `w`, like Iosevka 2.x.
* `v-w-straight-flat-top`, `VXCH`: Standard, straight `W` and `w`, and the middle is forced to be aligned the top.
* Styles for `x`, `X`:
* `v-x-straight`, `cv77`: Standard, straight `X` and `x` (default).
* `v-x-curly`, `cv78`: Slightly curly `X` and `x`, like Iosevka 2.x.
* Styles for `y`:
* `v-y-straight`, `cv48`: Letter `y` that is fully straight (default for Sans Upright).
* `v-y-cursive`, `cv49`: Cursive-like `y` (default for Italic).
* `v-y-curly`, `cv79`: More curly letter `y`, like Iosevka 2.x.
* `v-y-straight-turn`, `VXBF`: Letter `y` with straight upper and a tail turns leftward (default for Slab Upright).
* Styles for `z`:
* `v-z-standard`, `VXBD`: Standard `Z` and `z` (default).
* `v-z-with-crossbar`, `VXBE`: `Z` and `z` with a diagonal cross bar for better dsitinction with `2`.
* `v-z-with-horizontal-crossbar`, `VXBX`: `Z` and `z` with a horizontal cross bar for better dsitinction with `2`.
* Styles for `A`, `Λ`, `Δ`:
* `v-turn-v-straight`, `cv73`: Standard, straight `A`, `Λ`, `Δ` (default).
* `v-turn-v-curly`, `cv74`: Slightly curly `A`, `Λ`, `Δ`, like Iosevka 2.x.
* `turn-v = straight`, `cv01 = 1`: Standard, straight `A`, `Λ`, `Δ` (default).
* `turn-v = curly`, `cv01 = 2`: Slightly curly `A`, `Λ`, `Δ`, like Iosevka 2.x.
* Styles for `B`:
* `v-capital-b-standard`, `VXAP`: Standard `B` (default).
* `v-capital-b-more-asymmetric`, `VXAQ`: More asymmetric `B` to differentiate with `8`.
* `capital-b = standard`, `cv02 = 1`: Standard `B` (default).
* `capital-b = more-asymmetric`, `cv02 = 2`: More asymmetric `B` to differentiate with `8`.
* Styles for `D`:
* `v-capital-d-standard`, `VXBG`: Standard `D` (default).
* `v-capital-d-more-rounded`, `VXBH`: More rounded `D` to differentiate with `O`.
* `capital-d = standard`, `cv03 = 1`: Standard `D` (default).
* `capital-d = more-rounded`, `cv03 = 2`: More rounded `D` to differentiate with `O`.
* Styles for `G`:
* `v-capital-g-tooth`, `cv91`: Toothed G (default).
* `v-capital-g-toothless`, `cv92`: Toothless G.
* `capital-g = toothed`, `cv04 = 1`: Toothed G (default).
* `capital-g = toothless`, `cv04 = 2`: Toothless G.
* Styles for `J`:
* `v-capital-j-serifless`, `VXBY`: J without top serif.
* `v-capital-j-serifed`, `VXBZ`: J with top serif at left side (default).
* `v-capital-j-serifed-both-sides`, `VXDA`: J with symmetric at both sides.
* `v-capital-j-serifed-symmetric`, `VXDB`: J with symmetric at both sides and is symmetric.
* `capital-j = serifless`, `cv05 = 1`: J without top serif.
* `capital-j = serifed`, `cv05 = 2`: J with top serif at left side (default).
* `capital-j = serifed-both-sides`, `cv05 = 3`: J with symmetric at both sides.
* `capital-j = serifed-symmetric`, `cv05 = 4`: J with symmetric at both sides and is symmetric.
* Styles for `K`:
* `v-capital-k-straight`, `VXBR`: `K` with standard shape (default).
* `v-capital-k-curly`, `VXFB`: Slightly curly `K`, like Iosevka 2.x.
* `capital-k = straight`, `cv06 = 1`: `K` with standard shape (default).
* `capital-k = curly`, `cv06 = 2`: Slightly curly `K`, like Iosevka 2.x.
* Styles for `M`:
* `v-capital-m-hanging`, `VXCI`: `M` with middle being hanging off baseline (default).
* `v-capital-m-flat-bottom`, `VXCJ`: `M` with middle aligned to baseline.
* `capital-m = hanging`, `cv07 = 1`: `M` with middle being hanging off baseline (default).
* `capital-m = flat-bottom`, `cv07 = 2`: `M` with middle aligned to baseline.
* Styles for `Q`:
* `v-capital-q-taily`, `cv42`: `Q` with a curly tail (default).
* `v-capital-q-straight`, `cv43`: `Q` with a straight tail like in the old versions.
* `v-capital-q-crossing`, `VXCA`: `Q` with a tail crossing the ring.
* `capital-q = taily`, `cv08 = 1`: `Q` with a curly tail (default).
* `capital-q = straight`, `cv08 = 2`: `Q` with a straight tail like in the old versions.
* `capital-q = crossing`, `cv08 = 3`: `Q` with a tail crossing the ring.
* Styles for `R`:
* `v-capital-r-straight`, `cv82`: Standard, straight-leg `R` (default).
* `v-capital-r-curly`, `cv83`:  Slightly curly-legged `R`, like Iosevka 2.x.
* `capital-r = straight`, `cv09 = 1`: Standard, straight-leg `R` (default).
* `capital-r = curly`, `cv09 = 2`:  Slightly curly-legged `R`, like Iosevka 2.x.
* Styles for `Y`:
* `v-capital-y-straight`, `cv80`: Standard, straight `Y` (default).
* `v-capital-y-curly`, `cv81`: Slightly curly `Y`, like Iosevka 2.x.
* Styles for `0`:
* `v-zero-slashed`, `cv13`: Slashed Zero `0` (default).
* `v-zero-dotted`, `cv14`: Dotted Zero `0`.
* `v-zero-unslashed`, `cv15`: O-like `0`.
* `v-zero-reverse-slashed`, `cv93`: Reverse-slashed `0`.
* `v-zero-long-dotted`, `VXAB`: Long-dotted Zero `0` like Hack.
* Styles for `1`:
* `v-one-nobase`, `cv50`: `1` with bottom serif (default for Sans).
* `v-one-base`, `cv51`: `1` without bottom serif (default for Slab).
* `v-one-line`, `VXAM`: `1` drawn just like a straight line.
* Styles for `3`:
* `v-three-flattop`, `cv46`: Flat top `3` (Like Museo Sans / Montserrat).
* `v-three-twoarcs`, `cv47`: Arched top `3` (default).
* Styles for `4`:
* `v-four-closed`, `VXAR`: `4` with closed contour (default).
* `v-four-closed-non-crossing`, `VXAS`: `4` with closed contour but the horizontal bar does not overflow the vertical bar.
* `v-four-semi-open`, `VXAT`: `4` with semi-open contour.
* `v-four-semi-open-non-crossing`, `VXAU`: `4` with semi-open contour but the horizontal bar does not overflow the vertical bar.
* `v-four-open`, `VXAV`: `4` with open contour.
* `v-four-open-non-crossing`, `VXAW`: `4` with open contour but the horizontal bar does not overflow the vertical bar.
* Styles for `6`:
* `v-six-closed-contour`, `VXAE`: `6` with a more closed contour.
* `v-six-open-contour`, `VXAF`: `6` with a more open contour.
* `v-six-straight-bar`, `VXBB`: `6` with a straight bar (default).
* Styles for `7`:
* `v-seven-noserif`, `cv64`: `7` without serif (default for Sans).
* `v-seven-serifed`, `cv65`: `7` with initial serif (default for Slab).
* `v-seven-crossbar`, `VXAX`: `7` with crossbar.
* `v-seven-crossbar-serifed`, `VXAY`: `7` with crossbar and initial serif.
* Styles for `9`:
* `v-nine-closed-contour`, `cv96`: `9` with a more closed contour.
* `v-nine-open-contour`, `cv97`: `9` with a more open contour.
* `v-nine-straight-bar`, `VXBC`: `9` with a straight bar (default).
* `capital-y = straight`, `cv10 = 1`: Standard, straight `Y` (default).
* `capital-y = curly`, `cv10 = 2`: Slightly curly `Y`, like Iosevka 2.x.
* Styles for `a`:
* `a = doublestorey`, `cv11 = 1`: Double-storey `a` (default for Upright).
* `a = singlestorey`, `cv11 = 2`: Single-storey `a`.
* `a = singlestorey-tailed`, `cv11 = 3`: Single-storey `a` with curly tail (default for Italic).
* `a = doublestorey-tailed`, `cv11 = 4`: Double-storey `a` with curly tail.
* `a = singlestorey-earless-corner`, `cv11 = 5`: Earless (cornered top-right) single-storey `a`.
* `a = singlestorey-earless-corner-tailed`, `cv11 = 6`: Earless (cornered top-right) single-storey `a` with curly tail.
* `a = singlestorey-earless-rounded`, `cv11 = 7`: Earless (rounded top-right) single-storey `a`.
* `a = singlestorey-earless-rounded-tailed`, `cv11 = 8`: Earless (rounded top-right) single-storey `a` with curly tail.
* `a = doublestorey-toothless-corner`, `cv11 = 9`: Toothless (cornered bottom-right) double-storey `a`.
* `a = doublestorey-toothless-rounded`, `cv11 = 10`: Toothless (rounded bottom-right) double-storey `a`.
* Styles for `b`:
* `b = toothed`, `cv12 = 1`: `b` with bottom-left tooth (default).
* `b = toothless-corner`, `cv12 = 2`: `b` without bottom-left tooth, with a corner transition.
* `b = toothless-rounded`, `cv12 = 3`: `b` without bottom-left tooth, with a rounded transition.
* Styles for `d`:
* `d = toothed`, `cv13 = 1`: `d` with bottom-right tooth (default for Upright).
* `d = toothless-corner`, `cv13 = 2`: `d` without bottom-right tooth, with a corner transition.
* `d = toothless-rounded`, `cv13 = 3`: `d` without bottom-right tooth, with a rounded transition.
* `d = tailed`, `cv13 = 4`: `d` with a slightly tail bottom-right tail (default for Italic).
* Styles for `f`:
* `f = straight`, `cv14 = 1`: `f` without bottom hook (default for Sans Upright).
* `f = tailed`, `cv14 = 2`: `f` with a leftward bottom hook (default for Italic).
* `f = serifed`, `cv14 = 3`: `f` with bottom serif (default for Slab Upright).
* `f = straight-tailed`, `cv14 = 4`: `f` with straight tail.
* `f = flat-hook`, `cv14 = 5`: `f` with flat hook.
* `f = flat-hook-crossbar-at-x-height`, `cv14 = 6`: `f` with flat hook and crossbar placed right at X-height.
* `f = flat-hook-serifed`, `cv14 = 7`: `f` with flat hook and bottom serif.
* `f = flat-hook-serifed-crossbar-at-x-height`, `cv14 = 8`: `f` with flat hook, bottom serif, and crossbar placed right at X-height.
* `f = flat-hook-round-tailed`, `cv14 = 9`: `f` with flat hook.
* `f = flat-hook-round-tailed-crossbar-at-x-height`, `cv14 = 10`: `f` with flat hook and crossbar placed right at X-height.
* `f = flat-hook-flat-tailed`, `cv14 = 11`: `f` with flat hook and bottom serif.
* `f = flat-hook-flat-tailed-crossbar-at-x-height`, `cv14 = 12`: `f` with flat hook, bottom serif, and crossbar placed right at X-height.
* Styles for `g`:
* `g = singlestorey`, `cv15 = 1`: Single-storey `g` (default).
* `g = doublestorey`, `cv15 = 2`: Double-storey `g`.
* `g = opendoublestorey`, `cv15 = 3`: Open Double-storey `g`, like Trebuchet MS or Fira Code.
* `g = earless-corner`, `cv15 = 4`: Earless (cornered top-right) single-storey `g`.
* `g = earless-rounded`, `cv15 = 5`: Earless (rounded top-right) single-storey `g`.
* Styles for `h`:
* `h = straight`, `cv16 = 1`: `h` with straight ending (default).
* `h = tailed`, `cv16 = 2`: `h` with curly tailed ending.
* `h = motion-serifed-straight`, `cv16 = 3`: `h` with straight ending.
* `h = motion-serifed-tailed`, `cv16 = 4`: `h` with curly tailed ending.
* Styles for `i`:
* `i = serifed`, `cv17 = 1`: Serifed `i` (default for Upright).
* `i = italic`, `cv17 = 2`: Italic `i` (default for Italic).
* `i = hooky`, `cv17 = 3`: Hooky `i`.
* `i = line`, `cv17 = 4`: `i` like a straight line.
* `i = zshaped`, `cv17 = 5`: Z-shaped `i`.
* `i = tailed`, `cv17 = 6`: Tailed `i`.
* `i = hookybottom`, `cv17 = 7`: `i` with a straight tail.
* `i = serifed-asymmetric`, `cv17 = 8`: `i` with shorter top serif and full bottom serif.
* Styles for `j`:
* `j = line`, `cv18 = 1`: `j` like a straight line.
* `j = serifed`, `cv18 = 2`: `j` with top serif (default).
* `j = straight`, `cv18 = 3`: `j` without serif.
* `j = flat-hook-serifed`, `cv18 = 4`: undefined.
* `j = flat-hook-serifless`, `cv18 = 5`: undefined.
* Styles for `k`:
* `k = straight`, `cv19 = 1`: `k` with standard shape (default for Upright).
* `k = curly`, `cv19 = 2`: Slightly curly `k`, like Iosevka 2.x.
* `k = cursive`, `cv19 = 3`: `k` with a cursive loop (default for Italic).
* Styles for `l`:
* `l = hooky`, `cv20 = 1`: Hooky `l`.
* `l = zshaped`, `cv20 = 2`: Z-shaped `l`.
* `l = serifed`, `cv20 = 3`: Serifed `l` (default for Upright).
* `l = italic`, `cv20 = 4`: Italic, cursive `l` (default for Italic).
* `l = line`, `cv20 = 5`: `l` like a straight line.
* `l = tailed`, `cv20 = 6`: `l` with a curved tail.
* `l = hookybottom`, `cv20 = 7`: `l` with a straight tail.
* `l = serifed-asymmetric`, `cv20 = 8`: `l` with shorter top serif and full bottom serif.
* Styles for `m`:
* `m = normal`, `cv21 = 1`: `m` with normal middle leg, touching the baseline (default).
* `m = shortleg`, `cv21 = 2`: `m` with shorter middle leg, like Ubuntu Mono.
* `m = tailed`, `cv21 = 3`: `m` with normal middle leg, touching the baseline, and a curly tail.
* `m = shortleg-tailed`, `cv21 = 4`: `m` with shorter middle leg, like Ubuntu Mono, and a curly tail.
* `m = earless-corner-double-arch`, `cv21 = 5`: Earless (corner top-left) `m` with normal middle leg touching baseline.
* `m = earless-corner-double-arch-shortleg`, `cv21 = 6`: Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono.
* `m = earless-corner-double-arch-tailed`, `cv21 = 7`: Earless (corner top-left) `m` with normal middle leg touching baseline, and a curly tail.
* `m = earless-corner-double-arch-shortleg-tailed`, `cv21 = 8`: Earless (corner top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail.
* `m = earless-rounded-double-arch`, `cv21 = 9`: Earless (rounded top-left) `m` with normal middle leg touching baseline.
* `m = earless-rounded-double-arch-shortleg`, `cv21 = 10`: Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono.
* `m = earless-rounded-double-arch-tailed`, `cv21 = 11`: Earless (rounded top-left) `m` with normal middle leg touching baseline, and a curly tail.
* `m = earless-rounded-double-arch-shortleg-tailed`, `cv21 = 12`: Earless (rounded top-left) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail.
* `m = earless-single-arch`, `cv21 = 13`: Earless (single-arch) `m` with normal middle leg touching baseline.
* `m = earless-single-arch-shortleg`, `cv21 = 14`: Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono.
* `m = earless-single-arch-tailed`, `cv21 = 15`: Earless (single-arch) `m` with normal middle leg touching baseline, and a curly tail.
* `m = earless-single-arch-shortleg-tailed`, `cv21 = 16`: Earless (single-arch) `m` with a shorter middle leg like Ubuntu Mono, and a curly tail.
* `m = motion-serifed`, `cv21 = 17`: `m` with motion serifs, normal middle leg touching baseline.
* `m = motion-serifed-shortleg`, `cv21 = 18`: `m` with motion serifs, a shorter middle leg like Ubuntu Mono.
* `m = motion-serifed-tailed`, `cv21 = 19`: `m` with motion serifs, normal middle leg touching baseline, and a curly tail.
* `m = motion-serifed-shortleg-tailed`, `cv21 = 20`: `m` with motion serifs, a shorter middle leg like Ubuntu Mono, and a curly tail.
* Styles for `n`:
* `n = straight`, `cv22 = 1`: `n` with straight ending (default).
* `n = tailed`, `cv22 = 2`: `n` with a curly tail.
* `n = earless-corner-straight`, `cv22 = 3`: Earless (corner top-left) `n` with straight ending.
* `n = earless-corner-tailed`, `cv22 = 4`: Earless (corner top-left) `n` with a curly tail.
* `n = earless-rounded-straight`, `cv22 = 5`: Earless (rounded top-left) `n` with straight ending.
* `n = earless-rounded-tailed`, `cv22 = 6`: Earless (rounded top-left) `n` with a curly tail.
* `n = motion-serifed-straight`, `cv22 = 7`: `n` with motion serifs and straight ending.
* `n = motion-serifed-tailed`, `cv22 = 8`: `n` with motion serifs and a curly tail.
* Styles for `p`:
* `p = eared`, `cv23 = 1`: `p` with top-left ear (default).
* `p = earless-corner`, `cv23 = 2`: `p` without top-left ear (corner).
* `p = earless-rounded`, `cv23 = 3`: `p` without top-left ear (rounded).
* `p = motion-serifed`, `cv23 = 4`: `p` with motion serifs.
* Styles for `q`:
* `q = straight`, `cv24 = 1`: `q` with straight bar (default).
* `q = tailed`, `cv24 = 2`: `q` with tail.
* `q = earless-corner`, `cv24 = 3`: Earless (cornered top-left) single-storey `q`.
* `q = earless-corner-tailed`, `cv24 = 4`: Earless (cornered top-left) single-storey `q` with curly tail.
* `q = earless-rounded`, `cv24 = 5`: Earless (rounded top-left) single-storey `q`.
* `q = earless-rounded-tailed`, `cv24 = 6`: Earless (rounded top-left) single-storey `q` with curly tail.
* Styles for `r`:
* `r = straight`, `cv25 = 1`: Straight, serif-less `r` (default for Sans).
* `r = serifed`, `cv25 = 2`: `r` with serif at both top and bottom (default for Slab Upright).
* `r = top-serifed`, `cv25 = 3`: `r` with serifs at top-left only (default for Slab Italic).
* `r = earless-corner`, `cv25 = 4`: Earless (corner top-left), serif-less `r`.
* `r = earless-rounded`, `cv25 = 5`: Earless (rounded top-left), serif-less `r`.
* Styles for `t`:
* `t = standard`, `cv26 = 1`: Standard `t` shape (default).
* `t = cross`, `cv26 = 2`: Futura-like `t` shape.
* `t = flat-hook`, `cv26 = 3`: `t` with flat hook.
* `t = hookless-asymmetric`, `cv26 = 4`: `t` without hook and ony half the cross bar.
* `t = flat-hook-short-neck`, `cv26 = 5`: `t` with flat hook and a slightly shorter neck.
* `t = flat-hook-short-neck2`, `cv26 = 6`: `t` with flat hook and a more shorter neck.
* Styles for `u`:
* `u = with-bar`, `cv27 = 1`: Normal `u` with right bar (default for Upright).
* `u = without-bar`, `cv27 = 2`: Normal `u` without right bar, like a smaller uppercase `U`.
* `u = tailed`, `cv27 = 3`: `u` with right bar and a slightly curly tail (default for Italic).
* `u = motion-serifed`, `cv27 = 4`: Normal `u` with right bar and motion serifs.
* `u = motion-serifed-tailed`, `cv27 = 5`: `u` with right bar, motion serifs and a slightly curly tail.
* Styles for `v`, `V`:
* `v = straight`, `cv28 = 1`: Standard, straight `V` and `v` (default).
* `v = curly`, `cv28 = 2`:  Slightly curly `V` and `v`, like Iosevka 2.x.
* Styles for `w`, `W`:
* `w = straight`, `cv29 = 1`: Standard, straight `W` and `w` (default).
* `w = curly`, `cv29 = 2`: Slightly curly `W` and `w`, like Iosevka 2.x.
* `w = straight-flat-top`, `cv29 = 3`: Standard, straight `W` and `w`, and the middle is forced to be aligned the top.
* Styles for `x`, `X`:
* `x = straight`, `cv30 = 1`: Standard, straight `X` and `x` (default).
* `x = curly`, `cv30 = 2`: Slightly curly `X` and `x`, like Iosevka 2.x.
* Styles for `y`:
* `y = straight`, `cv31 = 1`: Letter `y` that is fully straight (default for Sans Upright).
* `y = straight-turn`, `cv31 = 2`: Letter `y` with straight upper and a tail turns leftward (default for Slab Upright).
* `y = curly`, `cv31 = 3`: More curly letter `y`, like Iosevka 2.x.
* `y = cursive`, `cv31 = 4`: Cursive-like `y` (default for Italic).
* Styles for `z`, `Z`:
* `z = standard`, `cv32 = 1`: Standard `Z` and `z` (default).
* `z = with-crossbar`, `cv32 = 2`: `Z` and `z` with a diagonal cross bar for better dsitinction with `2`.
* `z = with-horizontal-crossbar`, `cv32 = 3`: `Z` and `z` with a horizontal cross bar for better dsitinction with `2`.
* Styles for `ß`:
* `v-eszet-traditional`, `cv34`: Traditional, Fraktur-like Eszet.
* `v-eszet-sulzbacher`, `cv35`: A more modern, beta-like Eszet (default).
* `v-eszet-longs-s-lig`, `VXAC`: An Eszet shown as a ligature of long-S (`ſ`) and `s`.
* `eszet = traditional`, `cv33 = 1`: Traditional, Fraktur-like Eszet.
* `eszet = sulzbacher`, `cv33 = 2`: A more modern, beta-like Eszet (default).
* `eszet = longs-s-lig`, `cv33 = 3`: An Eszet shown as a ligature of long-S (`ſ`) and `s`.
* Styles for `λ`:
* `v-lambda-straight`, `cv94`: More-straight letter `λ` (default).
* `v-lambda-curly`, `cv95`: More curly letter `λ`, like Iosevka 2.x.
* `lambda = straight`, `cv34 = 1`: More-straight letter `λ` (default).
* `lambda = curly`, `cv34 = 2`: More curly letter `λ`, like Iosevka 2.x.
* Styles for `0`:
* `zero = slashed`, `cv35 = 1`: Slashed Zero `0` (default).
* `zero = dotted`, `cv35 = 2`: Dotted Zero `0`.
* `zero = unslashed`, `cv35 = 3`: O-like `0`.
* `zero = reverse-slashed`, `cv35 = 4`: Reverse-slashed `0`.
* `zero = long-dotted`, `cv35 = 5`: Long-dotted Zero `0` like Hack.
* Styles for `1`:
* `one = nobase`, `cv36 = 1`: `1` with bottom serif (default for Sans).
* `one = base`, `cv36 = 2`: `1` without bottom serif (default for Slab).
* `one = line`, `cv36 = 3`: `1` drawn just like a straight line.
* Styles for `3`:
* `three = flattop`, `cv37 = 1`: Flat top `3` (Like Museo Sans / Montserrat).
* `three = twoarcs`, `cv37 = 2`: Arched top `3` (default).
* Styles for `4`:
* `four = closed`, `cv38 = 1`: `4` with closed contour (default).
* `four = closed-non-crossing`, `cv38 = 2`: `4` with closed contour but the horizontal bar does not overflow the vertical bar.
* `four = semi-open`, `cv38 = 3`: `4` with semi-open contour.
* `four = semi-open-non-crossing`, `cv38 = 4`: `4` with semi-open contour but the horizontal bar does not overflow the vertical bar.
* `four = open`, `cv38 = 5`: `4` with open contour.
* `four = open-non-crossing`, `cv38 = 6`: `4` with open contour but the horizontal bar does not overflow the vertical bar.
* Styles for `6`:
* `six = closed-contour`, `cv40 = 1`: `6` with a more closed contour.
* `six = open-contour`, `cv40 = 2`: `6` with a more open contour.
* `six = straight-bar`, `cv40 = 3`: `6` with a straight bar (default).
* Styles for `7`:
* `seven = noserif`, `cv41 = 1`: `7` without serif (default for Sans).
* `seven = serifed`, `cv41 = 2`: `7` with initial serif (default for Slab).
* `seven = crossbar`, `cv41 = 3`: `7` with crossbar.
* `seven = crossbar-serifed`, `cv41 = 4`: `7` with crossbar and initial serif.
* Styles for `9`:
* `nine = closed-contour`, `cv42 = 1`: `9` with a more closed contour.
* `nine = open-contour`, `cv42 = 2`: `9` with a more open contour.
* `nine = straight-bar`, `cv42 = 3`: `9` with a straight bar (default).
* Styles for `~`:
* `v-tilde-high`, `cv16`: Higher tilde `~`.
* `v-tilde-low`, `cv17`: Lower tilde `~` (default).
* `tilde = high`, `cv43 = 1`: Higher tilde `~`.
* `tilde = low`, `cv43 = 2`: Lower tilde `~` (default).
* Styles for `*`:
* `v-asterisk-high`, `cv18`: Higher five-pointed asterisk `*` (default).
* `v-asterisk-low`, `cv19`: Lower five-pointed asterisk `*`.
* `v-asterisk-hexhigh`, `cv60`: Higher six-pointed asterisk `*`.
* `v-asterisk-hexlow`, `cv61`: Lower six-pointed asterisk `*`.
* `v-asterisk-flip-penta-high`, `VXBV`: Higher five-pointed and turned asterisk `*`.
* `v-asterisk-flip-penta-low`, `VXBW`: Lower five-pointed and turned asterisk `*`.
* `asterisk = high`, `cv44 = 1`: Higher five-pointed asterisk `*` (default).
* `asterisk = low`, `cv44 = 2`: Lower five-pointed asterisk `*`.
* `asterisk = hexhigh`, `cv44 = 3`: Higher six-pointed asterisk `*`.
* `asterisk = hexlow`, `cv44 = 4`: Lower six-pointed asterisk `*`.
* `asterisk = flip-penta-high`, `cv44 = 5`: Higher five-pointed and turned asterisk `*`.
* `asterisk = flip-penta-low`, `cv44 = 6`: Lower five-pointed and turned asterisk `*`.
* Styles for `_`:
* `v-underscore-high`, `cv20`: Higher underscore `_`, placed right below baseline (default).
* `v-underscore-low`, `cv21`: Lower underscore `_`, placed right above descender line.
* `v-underscore-above-baseline`, `cv99`: Extra-high `_`, placed right below baseline.
* `underscore = high`, `cv45 = 1`: Higher underscore `_`, placed right below baseline (default).
* `underscore = low`, `cv45 = 2`: Lower underscore `_`, placed right above descender line.
* `underscore = above-baseline`, `cv45 = 3`: Extra-high `_`, placed right below baseline.
* Styles for `¶`:
* `v-paragraph-high`, `cv22`: Higher paragraph symbol `¶` (default).
* `v-paragraph-low`, `cv23`: Lower paragraph symbol `¶`.
* `paragraph-sign = high`, `cv46 = 1`: Higher paragraph sign `¶` (default).
* `paragraph-sign = low`, `cv46 = 2`: Lower paragraph sign `¶`.
* Styles for `^`:
* `v-caret-high`, `cv29`: Higher circumflex `^` (default).
* `v-caret-low`, `cv30`: Lower circumflex `^`.
* `caret = high`, `cv47 = 1`: Higher circumflex `^` (default).
* `caret = low`, `cv47 = 2`: Lower circumflex `^`.
* Styles for `(`, `)`:
* `v-paren-normal`, `VXAN`: Parenthesis with normal contour (default).
* `v-paren-large-contour`, `VXAO`: Parenthesis with larger contour, like that in Monaco.
* `paren = normal`, `cv48 = 1`: Parenthesis with normal contour.
* `paren = large-contour`, `cv48 = 2`: Parenthesis with larger contour, like that in Monaco.
* Styles for `{`, `}`:
* `v-brace-straight`, `cv36`: More straight braces.
* `v-brace-curly`, `cv37`: More curly braces (default).
* `brace = straight`, `cv49 = 1`: More straight braces.
* `brace = curly`, `cv49 = 2`: More curly braces.
* Styles for `#`:
* `v-numbersign-upright`, `cv44`: Number sign with vertical bars (default).
* `v-numbersign-slanted`, `cv45`: Number sign with slanted bars.
* `v-numbersign-upright-open`, `VXBI`: Number sign with vertical bars and open inner.
* `v-numbersign-slanted-open`, `VXBJ`: Number sign with slanted bars and open inner.
* `number-sign = upright`, `cv50 = 1`: Number sign with vertical bars (default).
* `number-sign = slanted`, `cv50 = 2`: Number sign with slanted bars.
* `number-sign = upright-open`, `cv50 = 3`: Number sign with vertical bars and open inner.
* `number-sign = slanted-open`, `cv50 = 4`: Number sign with slanted bars and open inner.
* Styles for `&`:
* `v-ampersand-closed`, `VXAG`: Ampersand (`&`) with a closed contour (default).
* `v-ampersand-upper-open`, `VXAH`: Ampersand (`&`) with an open contour at upper half.
* `v-ampersand-lower-open`, `VXAI`: Ampersand (`&`) with an open contour at lower half.
* `v-ampersand-et`, `VXAJ`: Ampersand (`&`) drawn like a ligature of Ɛ and t.
* `v-ampersand-et-toothed`, `VXAK`: Ampersand (`&`) drawn like a ligature of Ɛ and t with tooth.
* `v-ampersand-flat-top`, `VXAL`: Ampersand (`&`) drawn with a flat top.
* `ampersand = closed`, `cv51 = 1`: Ampersand (`&`) with a closed contour (default).
* `ampersand = upper-open`, `cv51 = 2`: Ampersand (`&`) with an open contour at upper half.
* `ampersand = lower-open`, `cv51 = 3`: Ampersand (`&`) with an open contour at lower half.
* `ampersand = et`, `cv51 = 4`: Ampersand (`&`) drawn like a ligature of Ɛ and t.
* `ampersand = et-toothed`, `cv51 = 5`: Ampersand (`&`) drawn like a ligature of Ɛ and t with tooth.
* `ampersand = flat-top`, `cv51 = 6`: Ampersand (`&`) drawn with a flat top.
* Styles for `@`:
* `v-at-threefold`, `cv31`: The long, three-fold At symbol (`@`) (default).
* `v-at-fourfold`, `cv32`: The traditional, four-fold At symbol (`@`).
* `v-at-short`, `cv33`: The shorter, Fira-like At symbol (`@`).
* `at = threefold`, `cv52 = 1`: The long, three-fold At symbol (`@`) (default).
* `at = fourfold`, `cv52 = 2`: The traditional, four-fold At symbol (`@`).
* `at = short`, `cv52 = 3`: The shorter, Fira-like At symbol (`@`).
* Styles for `$`:
* `v-dollar-open`, `cv38`: Dollar symbol with open contour.
* `v-dollar-through`, `cv39`: Dollar symbol with strike-through vertical bar (default).
* `v-dollar-opencap`, `cv54`: Dollar symbol with open contour, not exceeding baseline and ascender.
* `v-dollar-throughcap`, `cv55`: Dollar symbol with strike-through vertical bar, not exceeding baseline and ascender.
* `dollar = open`, `cv53 = 1`: Dollar symbol with open contour.
* `dollar = through`, `cv53 = 2`: Dollar symbol with strike-through vertical bar (default).
* `dollar = opencap`, `cv53 = 3`: Dollar symbol with open contour, not exceeding baseline and ascender.
* `dollar = throughcap`, `cv53 = 4`: Dollar symbol with strike-through vertical bar, not exceeding baseline and ascender.
* Styles for `%`:
* `v-percent-dots`, `cv62`: Percent `%`, Per-mille `‰` and basis point `‱` using rectangular dots.
* `v-percent-rings`, `cv63`: Percent `%` with rings and broken bar; Per-mille `‰` and basis point `‱` with rings (default).
* `v-percent-rings-connected`, `VXCK`: Percent `%`, Per-mille `‰` and basis point `‱` using rings and continuous bar.
* `percent = dots`, `cv54 = 1`: Percent `%`, Per-mille `‰` and basis point `‱` using rectangular dots.
* `percent = rings`, `cv54 = 2`: Percent `%` with rings and broken bar; Per-mille `‰` and basis point `‱` with rings (default).
* `percent = rings-connected`, `cv54 = 3`: Percent `%`, Per-mille `‰` and basis point `‱` using rings and continuous bar.
* Styles for `|`:
* `v-bar-natural-slope`, `VXCY`: Bar punctuations (`|`) has a natural slope under italics and oblique (default).
* `v-bar-force-upright`, `VXCZ`: Bar punctuations (`|`) is forced upright under italics and oblique.
* Styles for `<=`, `>=`:
* `v-lig-ltgteq-flat`, `cv66`: The lower bar of `<=` and `>=` ligation is flat (default).
* `v-lig-ltgteq-slanted`, `cv67`: The lower bar of `<=` and `>=` ligation is slanted.
* `lig-ltgteq = flat`, `cv56 = 1`: The lower bar of `<=` and `>=` ligation is flat.
* `lig-ltgteq = slanted`, `cv56 = 2`: The lower bar of `<=` and `>=` ligation is slanted.
* Styles for `'`:
* `v-ascii-quote-straight`, `VXDG`: Show ASCII quote (`'`) as short vertical straight bar. (default).
* `v-ascii-quote-raised-comma`, `VXDH`: Show ASCII quote (`'`) as raised comma..
* Styles for ```:
* `v-ascii-grave-straight`, `VXDI`: Show ASCII grave (`` ` ``) as short diagonal straight bar. (default).
* `v-ascii-grave-raised-inverse-comma`, `VXDJ`: Show ASCII grave (`` ` ``) as raised comma..
* `ascii-single-quote = straight`, `cv57 = 1`: Show ASCII quote (`'`) as short vertical straight bar. (default).
* `ascii-single-quote = raised-comma`, `cv57 = 2`: Show ASCII quote (`'`) as raised comma..
* Styles for `` ` ``:
* `ascii-grave = straight`, `cv58 = 1`: Show ASCII grave (`` ` ``) as short diagonal straight bar. (default).
* `ascii-grave = raised-inverse-comma`, `cv58 = 2`: Show ASCII grave (`` ` ``) as raised comma..
<!-- END Section-Cherry-Picking-Styles -->

View file

@ -10,353 +10,459 @@ snapshotFamily = 'iosevka'
[buildPlans.iosevka-fixed]
family = "Iosevka Fixed"
design = ["sp-fixed"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on'
[buildPlans.iosevka-term]
family = "Iosevka Term"
design = ["sp-term"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on'
# Slab
[buildPlans.iosevka-slab]
family = "Iosevka Slab"
design = ["slab"]
serifs = "slab"
snapshotFamily = 'iosevka-slab'
[buildPlans.iosevka-fixed-slab]
family = "Iosevka Fixed Slab"
design = ["sp-fixed", "slab"]
serifs = "slab"
spacing = "fixed"
snapshotFamily = 'iosevka-slab'
snapshotFeature = '"NWID" on'
[buildPlans.iosevka-term-slab]
family = "Iosevka Term Slab"
design = ["sp-term", "slab"]
serifs = "slab"
spacing = "term"
snapshotFamily = 'iosevka-slab'
snapshotFeature = '"NWID" on'
# Curly
[buildPlans.iosevka-curly]
family = "Iosevka Curly"
design = ["ss20"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss20" on'
[buildPlans.iosevka-curly.variants]
inherits = ["ss20"]
[buildPlans.iosevka-fixed-curly]
family = "Iosevka Fixed Curly"
design = ["sp-fixed", "ss20"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss20" on'
[buildPlans.iosevka-fixed-curly.variants]
inherits = ["ss20"]
[buildPlans.iosevka-term-curly]
family = "Iosevka Term Curly"
design = ["sp-term", "ss20"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss20" on'
[buildPlans.iosevka-term-curly.variants]
inherits = ["ss20"]
# Curly Slab
[buildPlans.iosevka-curly-slab]
family = "Iosevka Curly Slab"
design = ["slab", "ss20"]
serifs = "slab"
snapshotFamily = 'iosevka-slab'
snapshotFeature = '"ss20" on'
[buildPlans.iosevka-curly-slab.variants]
inherits = ["ss20"]
[buildPlans.iosevka-fixed-curly-slab]
family = "Iosevka Fixed Curly Slab"
design = ["sp-fixed", "slab", "ss20"]
serifs = "slab"
spacing = "fixed"
snapshotFamily = 'iosevka-slab'
snapshotFeature = '"NWID" on, "ss20" on'
[buildPlans.iosevka-fixed-curly-slab.variants]
inherits = ["ss20"]
[buildPlans.iosevka-term-curly-slab]
family = "Iosevka Term Curly Slab"
design = ["sp-term", "slab", "ss20"]
serifs = "slab"
spacing = "term"
snapshotFamily = 'iosevka-slab'
snapshotFeature = '"NWID" on, "ss20" on'
[buildPlans.iosevka-term-curly-slab.variants]
inherits = ["ss20"]
###################################################################################################
# SSxx
[buildPlans.iosevka-ss01]
family = "Iosevka SS01"
design = ["ss01"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss01" on'
[buildPlans.iosevka-ss01.variants]
inherits = "ss01"
[buildPlans.iosevka-fixed-ss01]
family = "Iosevka Fixed SS01"
design = ["sp-fixed", "ss01"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss01" on'
[buildPlans.iosevka-fixed-ss01.variants]
inherits = ["ss01"]
[buildPlans.iosevka-term-ss01]
family = "Iosevka Term SS01"
design = ["sp-term", "ss01"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss01" on'
[buildPlans.iosevka-term-ss01.variants]
inherits = ["ss01"]
[buildPlans.iosevka-ss02]
family = "Iosevka SS02"
design = ["ss02"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss02" on'
[buildPlans.iosevka-ss02.variants]
inherits = "ss02"
[buildPlans.iosevka-fixed-ss02]
family = "Iosevka Fixed SS02"
design = ["sp-fixed", "ss02"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss02" on'
[buildPlans.iosevka-fixed-ss02.variants]
inherits = ["ss02"]
[buildPlans.iosevka-term-ss02]
family = "Iosevka Term SS02"
design = ["sp-term", "ss02"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss02" on'
[buildPlans.iosevka-term-ss02.variants]
inherits = ["ss02"]
[buildPlans.iosevka-ss03]
family = "Iosevka SS03"
design = ["ss03"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss03" on'
[buildPlans.iosevka-ss03.variants]
inherits = "ss03"
[buildPlans.iosevka-fixed-ss03]
family = "Iosevka Fixed SS03"
design = ["sp-fixed", "ss03"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss03" on'
[buildPlans.iosevka-fixed-ss03.variants]
inherits = ["ss03"]
[buildPlans.iosevka-term-ss03]
family = "Iosevka Term SS03"
design = ["sp-term", "ss03"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss03" on'
[buildPlans.iosevka-term-ss03.variants]
inherits = ["ss03"]
[buildPlans.iosevka-ss04]
family = "Iosevka SS04"
design = ["ss04"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss04" on'
[buildPlans.iosevka-ss04.variants]
inherits = "ss04"
[buildPlans.iosevka-fixed-ss04]
family = "Iosevka Fixed SS04"
design = ["sp-fixed", "ss04"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss04" on'
[buildPlans.iosevka-fixed-ss04.variants]
inherits = ["ss04"]
[buildPlans.iosevka-term-ss04]
family = "Iosevka Term SS04"
design = ["sp-term", "ss04"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss04" on'
[buildPlans.iosevka-term-ss04.variants]
inherits = ["ss04"]
[buildPlans.iosevka-ss05]
family = "Iosevka SS05"
design = ["ss05"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss05" on'
[buildPlans.iosevka-ss05.variants]
inherits = "ss05"
[buildPlans.iosevka-fixed-ss05]
family = "Iosevka Fixed SS05"
design = ["sp-fixed", "ss05"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss05" on'
[buildPlans.iosevka-fixed-ss05.variants]
inherits = ["ss05"]
[buildPlans.iosevka-term-ss05]
family = "Iosevka Term SS05"
design = ["sp-term", "ss05"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss05" on'
[buildPlans.iosevka-term-ss05.variants]
inherits = ["ss05"]
[buildPlans.iosevka-ss06]
family = "Iosevka SS06"
design = ["ss06"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss06" on'
[buildPlans.iosevka-ss06.variants]
inherits = "ss06"
[buildPlans.iosevka-fixed-ss06]
family = "Iosevka Fixed SS06"
design = ["sp-fixed", "ss06"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss06" on'
[buildPlans.iosevka-fixed-ss06.variants]
inherits = ["ss06"]
[buildPlans.iosevka-term-ss06]
family = "Iosevka Term SS06"
design = ["sp-term", "ss06"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss06" on'
[buildPlans.iosevka-term-ss06.variants]
inherits = ["ss06"]
[buildPlans.iosevka-ss07]
family = "Iosevka SS07"
design = ["ss07"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss07" on'
[buildPlans.iosevka-ss07.variants]
inherits = "ss07"
[buildPlans.iosevka-fixed-ss07]
family = "Iosevka Fixed SS07"
design = ["sp-fixed", "ss07"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss07" on'
[buildPlans.iosevka-fixed-ss07.variants]
inherits = ["ss07"]
[buildPlans.iosevka-term-ss07]
family = "Iosevka Term SS07"
design = ["sp-term", "ss07"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss07" on'
[buildPlans.iosevka-term-ss07.variants]
inherits = ["ss07"]
# The SS08 has curly bars, so apply ss20 first
[buildPlans.iosevka-ss08]
family = "Iosevka SS08"
design = ["ss08"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss08" on'
[buildPlans.iosevka-ss08.variants]
inherits = "ss08"
[buildPlans.iosevka-fixed-ss08]
family = "Iosevka Fixed SS08"
design = ["sp-fixed", "ss08"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss08" on'
[buildPlans.iosevka-fixed-ss08.variants]
inherits = ["ss08"]
[buildPlans.iosevka-term-ss08]
family = "Iosevka Term SS08"
design = ["sp-term", "ss08"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss08" on'
[buildPlans.iosevka-term-ss08.variants]
inherits = ["ss08"]
[buildPlans.iosevka-ss09]
family = "Iosevka SS09"
design = ["ss09"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss09" on'
[buildPlans.iosevka-ss09.variants]
inherits = "ss09"
[buildPlans.iosevka-fixed-ss09]
family = "Iosevka Fixed SS09"
design = ["sp-fixed", "ss09"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss09" on'
[buildPlans.iosevka-fixed-ss09.variants]
inherits = ["ss09"]
[buildPlans.iosevka-term-ss09]
family = "Iosevka Term SS09"
design = ["sp-term", "ss09"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss09" on'
[buildPlans.iosevka-term-ss09.variants]
inherits = ["ss09"]
[buildPlans.iosevka-ss10]
family = "Iosevka SS10"
design = ["ss10"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss10" on'
[buildPlans.iosevka-ss10.variants]
inherits = "ss10"
[buildPlans.iosevka-fixed-ss10]
family = "Iosevka Fixed SS10"
design = ["sp-fixed", "ss10"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss10" on'
[buildPlans.iosevka-fixed-ss10.variants]
inherits = ["ss10"]
[buildPlans.iosevka-term-ss10]
family = "Iosevka Term SS10"
design = ["sp-term", "ss10"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss10" on'
[buildPlans.iosevka-term-ss10.variants]
inherits = ["ss10"]
[buildPlans.iosevka-ss11]
family = "Iosevka SS11"
design = ["ss11"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss11" on'
[buildPlans.iosevka-ss11.variants]
inherits = "ss11"
[buildPlans.iosevka-fixed-ss11]
family = "Iosevka Fixed SS11"
design = ["sp-fixed", "ss11"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss11" on'
[buildPlans.iosevka-fixed-ss11.variants]
inherits = ["ss11"]
[buildPlans.iosevka-term-ss11]
family = "Iosevka Term SS11"
design = ["sp-term", "ss11"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss11" on'
[buildPlans.iosevka-term-ss11.variants]
inherits = ["ss11"]
[buildPlans.iosevka-ss12]
family = "Iosevka SS12"
design = ["ss12"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss12" on'
[buildPlans.iosevka-ss12.variants]
inherits = "ss12"
[buildPlans.iosevka-fixed-ss12]
family = "Iosevka Fixed SS12"
design = ["sp-fixed", "ss12"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss12" on'
[buildPlans.iosevka-fixed-ss12.variants]
inherits = ["ss12"]
[buildPlans.iosevka-term-ss12]
family = "Iosevka Term SS12"
design = ["sp-term", "ss12"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss12" on'
[buildPlans.iosevka-term-ss12.variants]
inherits = ["ss12"]
[buildPlans.iosevka-ss13]
family = "Iosevka SS13"
design = ["ss13"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss13" on'
[buildPlans.iosevka-ss13.variants]
inherits = "ss13"
[buildPlans.iosevka-fixed-ss13]
family = "Iosevka Fixed SS13"
design = ["sp-fixed", "ss13"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss13" on'
[buildPlans.iosevka-fixed-ss13.variants]
inherits = ["ss13"]
[buildPlans.iosevka-term-ss13]
family = "Iosevka Term SS13"
design = ["sp-term", "ss13"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss13" on'
[buildPlans.iosevka-term-ss13.variants]
inherits = ["ss13"]
[buildPlans.iosevka-ss14]
family = "Iosevka SS14"
design = ["ss14"]
snapshotFamily = 'iosevka'
snapshotFeature = '"ss14" on'
[buildPlans.iosevka-ss14.variants]
inherits = "ss14"
[buildPlans.iosevka-fixed-ss14]
family = "Iosevka Fixed SS14"
design = ["sp-fixed", "ss14"]
spacing = "fixed"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss14" on'
[buildPlans.iosevka-fixed-ss14.variants]
inherits = ["ss14"]
[buildPlans.iosevka-term-ss14]
family = "Iosevka Term SS14"
design = ["sp-term", "ss14"]
spacing = "term"
snapshotFamily = 'iosevka'
snapshotFeature = '"NWID" on, "ss14" on'
[buildPlans.iosevka-term-ss14.variants]
inherits = ["ss14"]
###################################################################################################
# Proportional families
[buildPlans.iosevka-aile]
family = "Iosevka Aile"
design = ["type", "v-at-fourfold", "v-j-narrow", 'v-capital-i-straight', 'v-capital-j-serifless', 'v-g-singlestorey', 'v-r-narrow', "no-cv-ss", "no-ligation", 'v-a-doublestorey', 'v-d-toothed', 'v-u-with-bar']
upright = ["v-i-line", "v-l-line", 'v-f-narrow', 'v-t-narrow']
italic = ["v-i-line", "v-l-line", 'v-f-narrow', 'v-t-narrow']
oblique = ["v-i-line", "v-l-line", 'v-f-narrow', 'v-t-narrow']
no-cv-ss = true
no-ligation = true
snapshotFamily = 'iosevka-aile'
quasiProportionalDiversity = 2
[buildPlans.iosevka-aile.variants.design]
at = 'fourfold'
j = 'narrow'
capital-i = 'straight'
capital-j = 'serifless'
g = 'singlestorey'
r = 'narrow'
a = 'doublestorey'
d = 'toothed'
u = 'with-bar'
[buildPlans.iosevka-aile.variants.upright]
i = 'line'
l = 'line'
f = 'narrow'
t = 'narrow'
[buildPlans.iosevka-aile.variants.italic]
i = 'line'
l = 'line'
f = 'narrow'
t = 'narrow'
[buildPlans.iosevka-aile.widths.normal]
shape = 576
menu = 5
@ -364,16 +470,26 @@ css = "normal"
[buildPlans.iosevka-etoile]
family = "Iosevka Etoile"
design = ["type", "slab", "v-at-fourfold", 'v-j-serifed', 'no-cv-ss', "no-ligation"]
upright = ['v-i-serifed', 'v-l-serifed']
italic = ['v-i-italic', 'v-l-italic']
oblique = ['v-i-serifed', 'v-l-serifed']
serifs = 'slab'
no-cv-ss = true
no-ligation = true
snapshotFamily = 'iosevka-etoile'
quasiProportionalDiversity = 1
[buildPlans.iosevka-etoile.variants.design]
at = 'fourfold'
j = 'serifed'
[buildPlans.iosevka-etoile.variants.upright]
i = 'serifed'
l = 'serifed'
[buildPlans.iosevka-etoile.variants.italic]
i = 'italic'
l = 'italic'
[buildPlans.iosevka-etoile.widths.normal]
shape = 576
menu = 5
@ -381,23 +497,38 @@ css = "normal"
[buildPlans.iosevka-sparkle]
family = "Iosevka Sparkle"
design = ["type", "v-at-fourfold", "v-j-narrow-serifed", "no-cv-ss", "no-ligation"]
upright = ['v-i-serifed', 'v-l-serifed', "v-f-serifed", "v-r-serifed"]
italic = ['v-i-italic', 'v-l-italic', "v-f-tailed", 'v-r-top-serifed']
oblique = ['v-i-serifed', 'v-l-serifed', "v-f-serifed", "v-r-serifed"]
no-cv-ss = true
no-ligation = true
snapshotFamily = 'iosevka-sparkle'
quasiProportionalDiversity = 1
[buildPlans.iosevka-sparkle.variants.design]
at = 'fourfold'
j = 'narrow-serifed'
[buildPlans.iosevka-sparkle.variants.upright]
i = 'serifed'
l = 'serifed'
f = 'serifed'
r = 'serifed'
[buildPlans.iosevka-sparkle.variants.italic]
i = 'italic'
l = 'italic'
f = 'tailed'
r = 'top-serifed'
[buildPlans.iosevka-sparkle.widths.normal]
shape = 576
menu = 5
css = "normal"
###################################################################################################
# Collect plans
[collectPlans.iosevka]
from = [
"iosevka",

View file

@ -12,19 +12,17 @@ glyph-module
glyph-block Common-Derivatives : begin
glyph-block-import CommonShapes : FlipAround
define [ApplyCv g follow para name transform omit] : begin
foreach [{k h} : pairs-of para.variants] : begin
local suffix h.(follow)
if (suffix && !(omit && omit.(k))) : begin
if (suffix && transform && transform.(suffix)) : set suffix transform.(suffix)
if (suffix && h.__cvmap && h.__cvmap.(follow)) : begin
local tag h.__cvmap.(follow)
[Cv tag].set g ([fallback name follow] + '.' + suffix)
define [ApplyCv g follow para name transform] : begin
foreach { kPrime prime } para.variants.primes : foreach h [prime.variants.values] : begin
local suffix : h.resolveFor para follow
if (suffix && transform && transform.(suffix)) : set suffix transform.(suffix)
if (suffix && h.tag && h.rank) : begin
[Cv h.tag h.rank].set g ([fallback name follow] + '.' + suffix)
define [select-variant] : params [name unicode [to-name name] transform omit [follow name]] : begin
define [select-variant] : params [name unicode [to-name name] transform [follow name]] : begin
if [not : glyph-is-needed name] : return nothing
local variant : variantSelector.(follow) || para.defaultVariant.(follow)
local variant para.variantSelector.(follow)
if [not variant] : begin
throw : new Error "Variant for \(name) is not assigned."
@ -32,7 +30,7 @@ glyph-block Common-Derivatives : begin
create-glyph [fallback to-name name] unicode : glyph-proc
include [refer-glyph (name + '.' + variant)] AS_BASE ALSO_METRICS
ApplyCv currentGlyph follow para name transform omit
ApplyCv currentGlyph follow para name transform
set this.autoRefPriority [query-glyph (name + '.' + variant)].autoRefPriority
define [italic-variant name unicode] : begin

View file

@ -3,7 +3,7 @@ $$include '../../meta/macros.ptl'
import '../../support/transform' as Transform
import [mix linreg clamp fallback] from '../../support/utils'
import [Cv AnyDerivingCv Radical] from '../../support/gr'
import [Radical] from '../../support/gr'
import [designParameters] from '../../meta/aesthetics'
import '../../support/point' as Point

View file

@ -26,7 +26,6 @@ define [tagged tag component] : begin
return component
export all : define [buildGlyphs para recursive recursiveCodes] : begin
define variantSelector para.variantSelector
local glyphStore : new GlyphStore
define metrics : calculateMetrics para
@ -112,7 +111,7 @@ export all : define [buildGlyphs para recursive recursiveCodes] : begin
define booleFns : BooleKit.SetupBuilders : object GlobalTransform Glyph
# IDKY, but wrapping "metrics" prevents Node.js on Arch modifying it.
define $$Capture$$ : object [metrics : Object.create metrics] $NamedParameterPair$ $donothing$ para recursive recursiveCodes variantSelector glyphStore $createAndSaveGlyphImpl$ spirofns booleFns MarkSet AS_BASE ALSO_METRICS pickHash buildGlyphs tagged DivFrame fontMetrics $assignUnicodeImpl$
define $$Capture$$ : object [metrics : Object.create metrics] $NamedParameterPair$ $donothing$ para recursive recursiveCodes glyphStore $createAndSaveGlyphImpl$ spirofns booleFns MarkSet AS_BASE ALSO_METRICS pickHash buildGlyphs tagged DivFrame fontMetrics $assignUnicodeImpl$
### HERE WE GO
run-glyph-module './common/shapes.js'

View file

@ -959,7 +959,7 @@ glyph-block Symbol-Punctuation-Slashes-And-Number-Sign : begin
create-glyph 'backslash.right' : glyph-proc
include : BackslashShape 0 (Middle + backslashWidth / 2)
do "numbersign"
do "number sign"
define nsTop : mix SymbolMid ParenTop 0.85
define nsBot : mix SymbolMid ParenBot 0.85
define fine : adviceBlackness 3.5
@ -977,11 +977,11 @@ glyph-block Symbol-Punctuation-Slashes-And-Number-Sign : begin
VBarRight (r - hsp - p * fine) nsBot nsTop fine
create-glyph 'numbersign.upright' : union
create-glyph 'numberSign.upright' : union
UprightHBars
UprightVBars 0
create-glyph 'numbersign.uprightOpen' : union
create-glyph 'numberSign.uprightOpen' : union
UprightVBars pFineOpen
difference
UprightHBars
@ -997,8 +997,8 @@ glyph-block Symbol-Punctuation-Slashes-And-Number-Sign : begin
SlashShape (l + x - w + p * fine) (l + x + w + p * fine) nsTop nsBot fine
SlashShape (r - x - w - p * fine) (r - x + w - p * fine) nsTop nsBot fine
create-glyph 'numbersign.slanted' : union [SlantedHBars] [SlantedVBars 0]
create-glyph 'numbersign.slantedOpen' : union
create-glyph 'numberSign.slanted' : union [SlantedHBars] [SlantedVBars 0]
create-glyph 'numberSign.slantedOpen' : union
SlantedVBars pFineOpen
difference
SlantedHBars
@ -1009,7 +1009,7 @@ glyph-block Symbol-Punctuation-Slashes-And-Number-Sign : begin
corner (l + x - w + pFineOpen * fine) nsBot
select-variant 'numbersign' '#'
select-variant 'numberSign' '#'
glyph-block Symbol-Punctuation-Dashes : begin

View file

@ -8,8 +8,8 @@ const Toml = require("@iarna/toml");
const BuildFont = require("./gen/build-font.js");
const Parameters = require("./support/parameters");
const FormVariantData = require("./support/variant-data");
const FormLigationData = require("./support/ligation-data");
const VariantData = require("./support/variant-data");
const ApplyLigationData = require("./support/ligation-data");
const { createGrDisplaySheet } = require("./support/gr");
module.exports = async function main(argv) {
@ -38,24 +38,9 @@ async function getParameters(argv) {
const rawVariantsData = await tryParseToml(VARIANTS_TOML);
const rawLigationData = await tryParseToml(LIGATIONS_TOML);
let para = {};
Parameters.apply(para, parametersData, ["iosevka"]);
Parameters.apply(para, parametersData, argv.preHives);
Parameters.apply(para, parametersData, ["shapeWeight"], { shapeWeight: argv.shape.weight });
Parameters.apply(para, parametersData, ["shapeWidth"], { shapeWidth: argv.shape.width });
Parameters.apply(para, parametersData, [`s-${argv.shape.slope}`]);
Parameters.apply(para, parametersData, [`diversity-${argv.shape.quasiProportionalDiversity}`]);
const variantsData = FormVariantData(rawVariantsData, para);
para.variants = variantsData;
para.variantSelector = {};
Parameters.apply(para.variantSelector, variantsData, ["default", ...argv.preHives]);
para.defaultVariant = variantsData.default;
const ligationData = FormLigationData(rawLigationData, para);
para.defaultBuildup = { ...ligationData.defaultBuildup };
para.ligation = {};
Parameters.apply(para.ligation, ligationData.hives, ["default", ...argv.preHives]);
let para = Parameters.init(parametersData, argv);
VariantData.apply(rawVariantsData, para, argv);
ApplyLigationData(rawLigationData, para, argv);
if (argv.excludedCharRanges) para.excludedCharRanges = argv.excludedCharRanges;
if (argv.compatibilityLigatures) para.compLig = argv.compatibilityLigatures;

View file

@ -182,7 +182,7 @@ define-macro glyph-block : syntax-rules
set externEnv.$glyphBlockVariableUsage$ variableSet
define captureImports `[metrics $NamedParameterPair$ $donothing$ para recursive
recursiveCodes variantSelector glyphStore $createAndSaveGlyphImpl$
recursiveCodes glyphStore $createAndSaveGlyphImpl$
spirofns booleFns MarkSet AS_BASE ALSO_METRICS pickHash
buildGlyphs tagged DivFrame fontMetrics $assignUnicodeImpl$]
define metricImports `[UPM HalfUPM Width SB CAP XH Descender Contrast SymbolMid ParenTop

View file

@ -1,9 +1,10 @@
import [add-lookup add-common-feature pick-feature add-feature-lookup pick-lookup BeginLookupBlock EndLookupBlock] from "./table-util"
import [AnyCv CvDecompose] from "../support/gr"
import [Cv AnyCv CvDecompose] from "../support/gr"
extern Set
define [FeatureName tag] : tag + '_cvss'
define [LookupName tag] : 'lookup_cvss_' + tag
define [CvLookupName tag] : 'lookup_cv_' + tag
define [SsLookupName tag] : 'lookup_ss_' + tag
export : define [buildCVSS sink para glyphStore] : begin
if [not para.enableCvSs] : return nothing
@ -17,34 +18,50 @@ export : define [buildCVSS sink para glyphStore] : begin
local parts : CvDecompose.get g
if (parts && parts.length) : set decompositions.(gid) parts
define lookupCvDecompose : add-lookup sink : object
define lookupNameCvDecompose : add-lookup sink : object
.type 'gsub_multiple'
.subtables : list decompositions
# cvxx
foreach {gn glyph} [glyphStore.namedEntries] : if [not : CvDecompose.get glyph] : begin
foreach {gn glyph} [glyphStore.namedEntries] : if [not : CvDecompose.get glyph] : do
foreach [gr : items-of : AnyCv.query glyph] : if gr.tag : begin
local lookupName : LookupName gr.tag
local lookupName : CvLookupName gr.tag
if [not : cvLookupNameSet.has lookupName] : begin
local feature : pick-feature sink [FeatureName gr.tag]
add-common-feature sink feature
local lookup : pick-lookup sink lookupName
begin {.type 'gsub_single' .subtables {{.}}}
add-feature-lookup feature lookupCvDecompose
begin {.type 'gsub_alternate' .subtables {{.}}}
add-feature-lookup feature lookupNameCvDecompose
add-feature-lookup feature lookupName
sink.lookupDep.push { lookupCvDecompose lookupName }
sink.lookupDep.push { lookupNameCvDecompose lookupName }
cvLookupNameSet.add lookupName
set [pick-lookup sink lookupName].subtables.0.(gn) [gr.get glyph]
local st [pick-lookup sink lookupName].subtables.0
if [not st.(gn)] : set st.(gn) { }
set st.(gn).(gr.rank - 1) : gr.get glyph
# ssxx
foreach [{name composition} : pairs-of para.variants] : begin
if (name.length === 4 && composition.__isComposite && [name.slice 0 2] === 'ss') : begin
local feature : pick-feature sink [FeatureName name]
add-common-feature sink feature
add-feature-lookup feature lookupCvDecompose
foreach [{ch tag} : pairs-of composition.__cvmap]
add-feature-lookup feature [LookupName tag]
foreach {name composition} para.variants.composites : if composition.tag : do
local feature : pick-feature sink [FeatureName composition.tag]
add-common-feature sink feature
add-feature-lookup feature lookupNameCvDecompose
local lookupNameSub : add-lookup sink {.type 'gsub_single' .subtables {{.}}}
sink.lookupDep.push { lookupNameCvDecompose lookupNameSub }
add-feature-lookup feature lookupNameSub
define st [pick-lookup sink lookupNameSub].subtables.0
local decomp : composition.decompose para para.variants.selectorTree
foreach { prime pv } [items-of decomp] : if (pv.tag && pv.rank) : begin
local gr : Cv pv.tag pv.rank
foreach {gn glyph} [glyphStore.namedEntries] : if [not : CvDecompose.get glyph] : begin
local substituted : gr.get glyph
if substituted : set st.(gn) substituted
# If there are holes in the alternates list, fill them
foreach lutn cvLookupNameSet : begin
local st [pick-lookup sink lutn].subtables.0
foreach { k v } [pairs-of st] : foreach idx [range 0 v.length] : if [not v.(idx)]
set v.(idx) k
EndLookupBlock rec sink

View file

@ -56,7 +56,7 @@ define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] :
define [acops] {'less' 'greater' 'hyphen' 'equal' 'plus'}
define [acskip] {
'slash' 'bar' 'at' 'ampersand' 'percent'
'numbersign' 'numbersign.upright' 'numbersign.slanted'
'numberSign' 'numberSign.upright' 'numberSign.slanted'
}
define dottyPunctuations : list
* "colon"
@ -79,7 +79,7 @@ define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] :
* 'plus'
* 'less'
* 'greater'
* 'numbersign'
* 'numberSign'
* 'slash'
* 'ampersand'
* 'asterisk'

View file

@ -34,7 +34,7 @@ define [buildGSUB para glyphStore markGlyphs] : begin
# Ligation
if para.enableLigation : do
define plm : objectAssign {.} para.defaultBuildup
define plm : objectAssign {.} para.ligation.defaultBuildup
if (para.ligation.caltBuildup && para.ligation.caltBuildup.length) : begin
set plm.calt para.ligation.caltBuildup
buildLigations gsub para plm

View file

@ -90,25 +90,27 @@ const Radical = {
};
const CvTagCache = new Map();
function Cv(tag) {
if (CvTagCache.has(tag)) return CvTagCache.get(tag);
function Cv(tag, rank) {
const key = tag + "#" + rank;
if (CvTagCache.has(key)) return CvTagCache.get(key);
const rel = {
tag,
rank,
get(glyph) {
if (glyph && glyph.related && glyph.related.cv) return glyph.related.cv[tag];
if (glyph && glyph.related && glyph.related.cv) return glyph.related.cv[key];
else return null;
},
set(glyph, toGid) {
if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph");
if (!glyph.related) glyph.related = {};
if (!glyph.related.cv) glyph.related.cv = {};
glyph.related.cv[tag] = toGid;
glyph.related.cv[key] = toGid;
},
amendName(name) {
return name + "." + tag;
return name + "." + key;
}
};
CvTagCache.set(tag, rel);
CvTagCache.set(key, rel);
return rel;
}
@ -125,8 +127,10 @@ const AnyCv = {
query(glyph) {
let ret = [];
if (glyph && glyph.related && glyph.related.cv) {
for (const tag in glyph.related.cv) {
const rel = Cv(tag);
for (const key in glyph.related.cv) {
const [tag, rankStr] = key.split("#");
const rank = parseInt(rankStr, 10);
const rel = Cv(tag, rank);
if (rel.get(glyph)) ret.push(rel);
}
}
@ -139,8 +143,10 @@ const AnyDerivingCv = {
query(glyph) {
let ret = [];
if (glyph && !DoNotDeriveVariants.get(glyph) && glyph.related && glyph.related.cv) {
for (const tag in glyph.related.cv) {
const rel = Cv(tag);
for (const key in glyph.related.cv) {
const [tag, rankStr] = key.split("#");
const rank = parseInt(rankStr, 10);
const rel = Cv(tag, rank);
if (rel.get(glyph)) ret.push(rel);
}
}

View file

@ -1,6 +1,8 @@
"use strict";
module.exports = function formVariantData(data, para) {
const Parameters = require("./parameters");
module.exports = function applyLigationData(data, para, argv) {
const optInBuildup = {};
const optOutBuildup = {};
@ -24,7 +26,11 @@ module.exports = function formVariantData(data, para) {
}
}
return { defaultBuildup: { ...optInBuildup, ...optOutBuildup }, hives };
para.ligation = {
defaultBuildup: { ...optInBuildup, ...optOutBuildup },
caltBuildup: []
};
if (argv.ligationBuildup) Parameters.apply(para.ligation, hives, [argv.ligationBuildup]);
};
function createBuildup(simple, buildup) {

View file

@ -2,11 +2,27 @@
const monotonicInterpolate = require("./monotonic-interpolate");
exports.init = initPara;
function initPara(data, argv) {
let para = {};
apply(para, data, ["iosevka"]);
if (argv.shape.serifs) apply(para, data, ["serifs-" + argv.shape.serifs]);
if (argv.shape.spacing) apply(para, data, ["spacing-" + argv.shape.spacing]);
if (argv.shape.digitForm) apply(para, data, ["digit-form-" + argv.shape.digitForm]);
apply(para, data, ["shapeWeight"], { shapeWeight: argv.shape.weight });
apply(para, data, ["shapeWidth"], { shapeWidth: argv.shape.width });
apply(para, data, [`s-${argv.shape.slope}`]);
apply(para, data, [`diversity-${argv.shape.quasiProportionalDiversity}`]);
if (argv.featureControl.noCvSs) para.enableCvSs = false;
if (argv.featureControl.noLigation) para.enableLigation = false;
return para;
}
exports.apply = apply;
function apply(sink, parametersData, styles, blendArgs) {
if (!styles) return;
for (const item of styles) intro(parametersData, item, blendArgs, sink);
}
exports.apply = apply;
function intro(source, style, blendArgs, sink) {
let hive = source[style];
@ -70,6 +86,23 @@ function hiveBlend(hive, value) {
return generatedHive;
}
exports.applyMetricOverride = applyMetricOverride;
function applyMetricOverride(para, mo) {
const overrideObj = { metricOverride: {} };
createMetricDataSet(overrideObj.metricOverride, mo);
apply(para, overrideObj, ["metricOverride"]);
}
function createMetricDataSet(sink, mo) {
for (const key in mo) {
if (metricOverrideHandlers[key]) {
metricOverrideHandlers[key](sink, key, mo[key]);
} else {
console.error(`Metric override key ${key} is not supported. Skipping it.`);
}
}
}
function numericFieldHandler(sink, key, x) {
if (x != null && isFinite(x)) sink[key] = x;
}
@ -91,18 +124,3 @@ const metricOverrideHandlers = {
multiplies: subObjectHandler,
adds: subObjectHandler
};
function createMetricDataSet(sink, mo) {
for (const key in mo) {
if (metricOverrideHandlers[key]) {
metricOverrideHandlers[key](sink, key, mo[key]);
} else {
console.error(`Metric override key ${key} is not supported. Skipping it.`);
}
}
}
function applyMetricOverride(para, mo) {
const overrideObj = { metricOverride: {} };
createMetricDataSet(overrideObj.metricOverride, mo);
apply(para, overrideObj, ["metricOverride"]);
}
exports.applyMetricOverride = applyMetricOverride;

View file

@ -1,73 +1,145 @@
"use strict";
const objectAssign = require("object-assign");
exports.apply = applyVariantData;
function applyVariantData(data, para, argv) {
const parsed = parseVariantsData(data);
let tagSet = new Set();
for (const prime of parsed.primes.values()) {
if (!prime.tag) continue;
if (!tagSet.has(prime.tag)) tagSet.add(prime.tag);
else throw new Error(`CV tag conflict: ${prime.tag}`);
}
function mergeVSHive(_target, source) {
if (!source) return _target;
let __cvmap = objectAssign({}, _target.__cvmap, source.__cvmap);
let target = objectAssign(_target, source);
target.__cvmap = __cvmap;
return target;
const variantSelector = {};
parsed.defaultComposite.resolve(para, parsed.selectorTree, parsed.composites, variantSelector);
if (argv.serif === "slab") {
const slabComp = parsed.composites.get("slab");
slabComp.resolve(para, parsed.selectorTree, parsed.composites, variantSelector);
}
if (argv.variants) {
const userComposite = new Composite("{user}", argv.variants);
userComposite.resolve(para, parsed.selectorTree, parsed.composites, variantSelector);
}
para.variants = {
selectorTree: parsed.selectorTree,
primes: parsed.primes,
composites: parsed.composites
};
para.variantSelector = variantSelector;
}
function produceComposite(vs, para, g) {
let sel = {};
if (g.design)
for (let h of g.design) {
sel = mergeVSHive(sel, vs[h]);
}
if (!para.isItalic && g.upright) {
for (let h of g.upright) {
sel = mergeVSHive(sel, vs[h]);
}
exports.parse = parseVariantsData;
function parseVariantsData(data) {
const primes = new Map();
const selectorTree = new SelectorTree();
for (const k in data.prime) {
const p = new Prime(k, data.prime[k]);
p.register(selectorTree);
primes.set(k, p);
}
if (para.isItalic && g.italic) {
for (let h of g.italic) {
sel = mergeVSHive(sel, vs[h]);
}
const defaultComposite = new Composite("{default}", data.default);
const composites = new Map();
for (const k in data.composite) {
const comp = new Composite(k, data.composite[k]);
composites.set(k, comp);
}
sel.__isComposite = true;
return sel;
return { selectorTree: selectorTree, primes, composites, defaultComposite };
}
module.exports = function formVariantData(data, para) {
const vs = {};
// simple selector
for (let k in data.simple) {
const varDef = data.simple[k];
const hive = {
...varDef.variant,
...(para.isItalic ? varDef.variantItalic : varDef.variantUpright)
};
vs[k] = hive;
class SelectorTree {
constructor() {
this.m_mapping = new Map();
}
get(kPrime, kVariant) {
if (!this.m_mapping.has(kPrime)) return undefined;
return this.m_mapping.get(kPrime).get(kVariant);
}
set(kPrime, kVariant, prime, variant) {
if (!this.m_mapping.has(kPrime)) this.m_mapping.set(kPrime, new Map());
this.m_mapping.get(kPrime).set(kVariant, [prime, variant]);
}
*[Symbol.iterator]() {
for (const m of this.m_mapping.values()) yield* m.values();
}
}
const tag = varDef.tag;
const tagUpright = varDef.tagUpright;
const tagItalic = varDef.tagItalic;
if (tag) {
let __cvmap = {};
for (let k in hive) __cvmap[k] = tag;
hive.__cvmap = __cvmap;
vs[tag] = hive;
class Composite {
constructor(key, cfg) {
this.key = key;
this.tag = cfg.tag;
this.description = cfg.description;
this.inherits = cfg.inherits;
this.design = cfg.design;
this.upright = cfg.upright;
this.italic = cfg.italic;
}
decompose(para, selTree) {
const ans = [];
const cfg = Object.assign({}, this.design, para.isItalic ? this.italic : this.upright);
for (const [k, v] of Object.entries(cfg)) {
const pv = selTree.get(k, v);
if (!pv) throw new Error(`Composite ${this.key} cannot be resolved: ${[k, v]}.`);
ans.push(pv);
}
return ans;
}
resolve(para, selTree, catalog, vs) {
if (this.inherits) {
for (const item of this.inherits) {
if (!catalog.has(item)) throw new Error(`Cannot find composite variant: ${item}`);
catalog.get(item).resolve(para, selTree, catalog, vs);
}
}
for (const [prime, variant] of this.decompose(para, selTree)) {
variant.resolve(para, vs);
}
}
}
class Prime {
constructor(key, cfg) {
this.key = key;
this.sampler = cfg.sampler;
this.tag = cfg.tag;
if (!cfg.variants) throw new Error(`Missing variants in ${key}`);
this.variants = new Map();
for (const varKey in cfg.variants) {
const variant = cfg.variants[varKey];
this.variants.set(varKey, new PrimeVariant(varKey, cfg.tag, variant));
}
}
register(tree) {
for (const [k, v] of this.variants) tree.set(this.key, k, this, v);
if (this.tag) {
for (const v of this.variants.values()) if (v.rank) tree.set(this.tag, v.rank, this, v);
}
}
}
class PrimeVariant {
constructor(key, tag, cfg) {
this.key = key;
this.tag = tag;
this.description = cfg.description;
this.rank = cfg.rank;
this.selector = cfg.selector;
this.selectorUpright = cfg.selectorUpright;
this.selectorItalic = cfg.selectorItalic;
}
resolveFor(para, gn) {
let vs = {};
this.resolve(para, vs);
return vs[gn];
}
resolve(para, vs) {
Object.assign(vs, this.selector);
if (para.isItalic) {
Object.assign(vs, this.selectorItalic);
} else {
if (tagItalic && para.isItalic) {
let __cvmap = {};
for (let k in hive) __cvmap[k] = tagItalic;
hive.__cvmap = __cvmap;
vs[tagItalic] = hive;
}
if (tagUpright && !para.isItalic) {
let __cvmap = {};
for (let k in hive) __cvmap[k] = tagUpright;
hive.__cvmap = __cvmap;
vs[tagUpright] = hive;
}
Object.assign(vs, this.selectorUpright);
}
}
// default selector
vs.default = produceComposite(vs, para, data.default);
// ss## selector
for (let k in data.composite) vs[k] = produceComposite(vs, para, data.composite[k]);
return vs;
};
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

After

Width:  |  Height:  |  Size: 372 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 364 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 KiB

After

Width:  |  Height:  |  Size: 387 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 176 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

After

Width:  |  Height:  |  Size: 310 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 965 KiB

After

Width:  |  Height:  |  Size: 965 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 321 KiB

After

Width:  |  Height:  |  Size: 321 KiB

Before After
Before After

View file

@ -1,6 +1,6 @@
{
"name": "iosevka",
"version": "3.7.1",
"version": "4.0.0-alpha.0",
"main": "./font-src/index.js",
"scripts": {
"build": "verda -f verdafile.js",

View file

@ -66,39 +66,32 @@ excludedCharRanges = []
# - 2+ : Full (3.x)
slab = 0
# Enable old-style digits by default?
defaultToOldStyleFigures = false
[verbose]
verbose = true
###### Slab variant
[slab]
[serifs-slab]
slab = 2
###### Spacings
# Terminal variant
[sp-term]
[spacing-term]
spacing = 0
# "FontFonfig Monospace"
[sp-force-monospace]
[spacing-fontconfig-mono]
spacing = 0
forceMonospace = true
# Fixed variant
[sp-fixed]
[spacing-fixed]
spacing = 0
enableLigation = false
forceMonospace = true
###### Disabling Ligation
[no-ligation]
enableLigation = false
[nolig] # For compatibility
enableLigation = false
###### Disabling CV/SS
[no-cv-ss]
enableCvSs = false
###### Slopes
[s-italic]
isItalic = true
@ -130,180 +123,8 @@ diversityI = 0.75
diversityII = 0.5
###### Old-style figures
[default-to-old-style-figures]
[digit-form-old-style]
defaultToOldStyleFigures = true
[default-to-old-style-digits]
defaultToOldStyleFigures = true
[default-to-lining-figures]
[digit-form-lining]
defaultToOldStyleFigures = false
[default-to-lining-digits]
defaultToOldStyleFigures = false
###################################################################################################
### Metric-override hives
### These hives are now discouraged in favor of 'metric-override' in build plans but they are
### still supported in version 3.x.
###### Leading
[leading-750]
leading = 750
[leading-1000]
leading = 1000
[leading-1250]
leading = 1250
[leading-1500]
leading = 1500
[leading-1750]
leading = 1750
[leading-2000]
leading = 2000
###### Win metric pad
[win-metric-pad-0]
winMetricAscenderPad = 0
winMetricDescenderPad = 0
[win-metric-pad-50]
winMetricAscenderPad = 50
winMetricDescenderPad = 50
[win-metric-pad-100]
winMetricAscenderPad = 100
winMetricDescenderPad = 100
[win-metric-pad-150]
winMetricAscenderPad = 150
winMetricDescenderPad = 150
[win-metric-pad-200]
winMetricAscenderPad = 200
winMetricDescenderPad = 200
[win-metric-pad-250]
winMetricAscenderPad = 250
winMetricDescenderPad = 250
[win-metric-pad-300]
winMetricAscenderPad = 300
winMetricDescenderPad = 300
###### Powerline
[powerline-scale-y-750]
powerlineScaleY = 0.75
[powerline-scale-y-875]
powerlineScaleY = 0.875
[powerline-scale-y-1000]
powerlineScaleY = 1
[powerline-scale-y-1125]
powerlineScaleY = 1.125
[powerline-scale-y-1250]
powerlineScaleY = 1.25
[powerline-scale-y-1375]
powerlineScaleY = 1.375
[powerline-scale-y-1500]
powerlineScaleY = 1.5
[powerline-scale-x-750]
powerlineScaleX = 0.75
[powerline-scale-x-875]
powerlineScaleX = 0.875
[powerline-scale-x-1000]
powerlineScaleX = 1
[powerline-scale-x-1125]
powerlineScaleX = 1.125
[powerline-scale-x-1250]
powerlineScaleX = 1.25
[powerline-scale-x-1375]
powerlineScaleX = 1.375
[powerline-scale-x-1500]
powerlineScaleX = 1.5
[powerline-shift-y-n500]
powerlineShiftY = -500
[powerline-shift-y-n450]
powerlineShiftY = -450
[powerline-shift-y-n400]
powerlineShiftY = -400
[powerline-shift-y-n350]
powerlineShiftY = -350
[powerline-shift-y-n300]
powerlineShiftY = -300
[powerline-shift-y-n250]
powerlineShiftY = -250
[powerline-shift-y-n200]
powerlineShiftY = -200
[powerline-shift-y-n150]
powerlineShiftY = -150
[powerline-shift-y-n100]
powerlineShiftY = -100
[powerline-shift-y-n50]
powerlineShiftY = -50
[powerline-shift-y-0]
powerlineShiftY = 0
[powerline-shift-y-p50]
powerlineShiftY = 50
[powerline-shift-y-p100]
powerlineShiftY = 100
[powerline-shift-y-p150]
powerlineShiftY = 150
[powerline-shift-y-p200]
powerlineShiftY = 200
[powerline-shift-y-p250]
powerlineShiftY = 250
[powerline-shift-y-p300]
powerlineShiftY = 300
[powerline-shift-y-p350]
powerlineShiftY = 350
[powerline-shift-y-p400]
powerlineShiftY = 400
[powerline-shift-y-p450]
powerlineShiftY = 450
[powerline-shift-y-p500]
powerlineShiftY = 500
[powerline-shift-x-n500]
powerlineShiftX = -500
[powerline-shift-x-n450]
powerlineShiftX = -450
[powerline-shift-x-n400]
powerlineShiftX = -400
[powerline-shift-x-n350]
powerlineShiftX = -350
[powerline-shift-x-n300]
powerlineShiftX = -300
[powerline-shift-x-n250]
powerlineShiftX = -250
[powerline-shift-x-n200]
powerlineShiftX = -200
[powerline-shift-x-n150]
powerlineShiftX = -150
[powerline-shift-x-n100]
powerlineShiftX = -100
[powerline-shift-x-n50]
powerlineShiftX = -50
[powerline-shift-x-0]
powerlineShiftX = 0
[powerline-shift-x-p50]
powerlineShiftX = 50
[powerline-shift-x-p100]
powerlineShiftX = 100
[powerline-shift-x-p150]
powerlineShiftX = 150
[powerline-shift-x-p200]
powerlineShiftX = 200
[powerline-shift-x-p250]
powerlineShiftX = 250
[powerline-shift-x-p300]
powerlineShiftX = 300
[powerline-shift-x-p350]
powerlineShiftX = 350
[powerline-shift-x-p400]
powerlineShiftX = 400
[powerline-shift-x-p450]
powerlineShiftX = 450
[powerline-shift-x-p500]
powerlineShiftX = 500
# Compatibility PUA ligature sample
# [[iosevka.compLig]]
# unicode = 57600 # 0xE100
# featureTag = 'XV00'
# sequence = '<*>'
# Exclude code points
[exclude-check-and-cross-symbol.appends]
excludedCharRanges = [[10003, 10008]]

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1,32 @@
[buildPlans.iosevka-custom] # <iosevka-custom> is your plan name
family = "Iosevka Custom" # Font menu family name
design = ["v-i-hooky", "v-l-hooky"] # Customize styles
# upright = ["upright-styles"] # Uncomment this line to set styles for upright only
# italic = ["italic-styles"] # Uncomment this line to set styles for italic only
# oblique = ["oblique-styles"] # Uncomment this line to set styles for oblique only
# hintParams = ["-a", "sss"] # Optional custom parameters for ttfautohint
[buildPlans.iosevka-custom] # <iosevka-custom> is your plan name
family = "Iosevka Custom" # Font menu family name
spacing = "normal" # Optional; Values: `normal`, `term`, `fontconfig-mono`, or `fixed`
serifs = "sans" # Optional; Values: `sans` or `slab`
digit-form = "lining" # Optional; Values `lining` or `olt-style`
###################################################################################################
# Configure variants
# Optional; Whether to inherit a `ss##` variant
[buildPlans.iosevka-custom.variants]
inherits = ["ss01"]
# Optional; Configure single character's variant
[buildPlans.iosevka-custom.variants.design]
g = 'singlestorey'
# Optional; Configure single character's variant for Upright and Oblique; Overrides [design]
[buildPlans.iosevka-custom.variants.upright]
i = 'zshaped'
l = 'zshaped'
# Optional; Configure single character's variant for Italic only; Overrides [design]
[buildPlans.iosevka-custom.variants.italic]
i = 'italic'
l = 'italic'
# End variant section
###################################################################################################
###################################################################################################
# Override default building weights

View file

@ -203,42 +203,34 @@ section.char-vars
box-sizing: border-box;
-webkit-column-break-inside: avoid;
> div.desc-group
> .triangle
display: block;
flex: none;
width: 5em;
padding: 0 1em 0 0;
justify-content: flex-end;
position: relative;
right: -0.025em;
width: 0.5em;
font-feature-settings: 'NWID' on;
font-weight: 200;
font-size: 2em;
margin-top: 0.5em;
width: 0.5em;
text-align: center;
margin-right: -0.0625em;
> .triangle
display: block;
&::before, &::after
content: '';
position: absolute;
right: calc(0.275em - 0.5px);
width: 1px;
background: #ddd;
&::before
top: 0;
height: 0.42em;
&::after
top: 0.85em;
bottom: 0;
right: -0.025em;
width: 0.5em;
font-feature-settings: 'NWID' on;
font-weight: 200;
font-size: 2em;
margin-top: 0.5em;
width: 0.5em;
text-align: center;
margin-right: -0.0625em;
&::before, &::after
content: '';
position: absolute;
right: calc(0.275em - 0.5px);
width: 1px;
background: #ddd;
&::before
top: 0;
height: 0.42em;
&::after
top: 0.85em;
bottom: 0;
> ol.group
list-style: none;
@ -248,6 +240,11 @@ section.char-vars
display: flex;
flex-wrap: wrap;
&.header
width: 5em;
justify-content: flex-end;
flex: none;
.desc-group
border: none;
margin: 0;
@ -266,12 +263,14 @@ section.char-vars
font-size: 0.75em;
display: block;
position: absolute;
width: auto;
width: 2em;
left: 50%;
top: 0.4375em;
margin-left: -1em;
margin-right: -1em;
font-weight: 400;
opacity: 0.75;
text-align: center;
&.ligature > .label.tag
&:before, &:after

View file

@ -1,31 +1,34 @@
<section id="charvars" class="char-vars">
<div class="hr">Character Variants</div>
<ol class="narrow">
<%_ for(const group of cvData) { _%>
<%_ for(const group of cvData) if(group.tag) { _%>
<li>
<div class="desc-group <%= group.ligatureSampler ? 'ligature' : 'char' %>">
<%_ if(group.ligatureSampler) { _%>
<%_ for(const text of group.descSampleText) { _%>
<div class="sample"><%= text %></div>
<ol class="group header">
<div class="desc-group <%= group.ligatureSampler ? 'ligature' : 'char' %>">
<div class="label tag"><%= group.tag %></div>
<%_ if(group.ligatureSampler) { _%>
<%_ for(const text of group.descSampleText) { _%>
<div class="sample"><%= text %></div>
<%_ } _%>
<%_ } else { _%>
<div class="sample"><%= group.descSampleText[0] %></div>
<%_ } _%>
<%_ } else { _%>
<div class="sample"><%= group.descSampleText[0] %></div>
<%_ } _%>
<div class="triangle">▹</div>
</div>
</div>
</ol>
<div class="triangle">▹</div>
<ol class="group">
<%_ for(const config of group.configs) if(config.tag) { _%>
<%_ for(const config of group.variants) if(config.rank) { _%>
<li class="desc-group <%= group.ligatureSampler || config.slopeHetero ? 'ligature' : 'char' %>">
<div class="label tag"><%= config.tag || config.tagItalic %></div>
<div class="label tag"><%= config.rank %></div>
<%_ if(group.ligatureSampler) { _%>
<%_ for(const text of group.descSampleText) { _%>
<div class="sample" style="font-feature-settings:'<%= config.tag %>'"><%= text %></div>
<div class="sample" style="font-feature-settings:'<%= group.tag %>' <%= config.rank %>"><%= text %></div>
<%_ } _%>
<%_ } else if(config.slopeHetero) { _%>
<div class="sample" style="font-feature-settings:'<%= config.tag %>'"><%= group.descSampleText[0] %></div>
<div class="sample italic" style="font-feature-settings:'<%= config.tag %>'"><%= group.descSampleText[0] %></div>
<div class="sample" style="font-feature-settings:'<%= group.tag %>' <%= config.rank %>"><%= group.descSampleText[0] %></div>
<div class="sample italic" style="font-feature-settings:'<%= group.tag %>' <%= config.rank %>"><%= group.descSampleText[0] %></div>
<%_ } else { _%>
<div class="sample" style="font-feature-settings:'<%= config.tag %>'"><%= group.descSampleText[0] %></div>
<div class="sample" style="font-feature-settings:'<%= group.tag %>' <%= config.rank %>"><%= group.descSampleText[0] %></div>
<%_ } _%>
</li>
<%_ } _%>

View file

@ -43,12 +43,19 @@ async function processCv() {
`* Styles for individual characters. They are easy-to-understand names of the \`cv##\` styles, including:\n`
);
for (const gr of variantsData.cvData) {
md.log(` * Styles for ${gr.descSampleText.map(c => `\`${c}\``).join(", ")}:`);
const sampleText = gr.descSampleText
.map(c => (c === "`" ? "`` ` ``" : `\`${c}\``))
.join(", ");
md.log(` * Styles for ${sampleText}:`);
const defaults = figureOutDefaults(variantsData, gr);
for (const config of gr.configs) {
const tag = config.tag || config.tagItalic;
for (const config of gr.variants) {
if (!config.rank) continue;
let selectorText = `\`${gr.key} = ${config.selector}\``;
if (gr.tag && config.rank) {
selectorText += `, \`${gr.tag} = ${config.rank}\``;
}
md.log(
` * \`${config.selector}\`, \`${tag}\`: ` +
` * ${selectorText}: ` +
`${config.description}${formatDefaults(config.selector, defaults)}.`
);
}
@ -111,42 +118,32 @@ function figureOutDefaults(variantsData, gr) {
desc: "Sans Upright",
mask: 1,
result: null,
selector: [...variantsData.default.design, ...variantsData.default.upright]
selector: [...variantsData.defaults.sansUpright.composition]
},
{
desc: "Sans Italic",
mask: 2,
result: null,
selector: [...variantsData.default.design, ...variantsData.default.italic]
selector: [...variantsData.defaults.sansItalic.composition]
},
{
desc: "Slab Upright",
mask: 4,
result: null,
selector: [
...variantsData.default.design,
...variantsData.default.upright,
...variantsData.slabDefaultOverride.design,
...variantsData.slabDefaultOverride.upright
]
selector: [...variantsData.defaults.slabUpright.composition]
},
{
desc: "Slab Italic",
mask: 8,
result: null,
selector: [
...variantsData.default.design,
...variantsData.default.italic,
...variantsData.slabDefaultOverride.design,
...variantsData.slabDefaultOverride.italic
]
selector: [...variantsData.defaults.slabItalic.composition]
}
];
for (const config of gr.configs) {
for (const variant of gr.variants) {
for (const dc of defaultConfigs)
for (const selector of dc.selector)
if (config.selector === selector) dc.result = config.selector;
if (variant.fullSelector === selector) dc.result = variant.selector;
}
return defaultConfigs;
}

View file

@ -1,78 +1,66 @@
"use strict";
const fs = require("fs-extra");
const path = require("path");
const toml = require("@iarna/toml");
const VariantDataParser = require("../../font-src/support/variant-data");
module.exports = async function () {
const variantsToml = await fs.readFile(
path.join(__dirname, "../../params/variants.toml"),
"utf8"
);
const variants = toml.parse(variantsToml);
const varDatRaw = toml.parse(variantsToml);
const varDatParsed = VariantDataParser.parse(varDatRaw);
const cvData = getCvData(variants);
const ssData = getSsData(variants, cvData);
const cvData = getCvData(varDatParsed);
const ssData = getSsData(varDatParsed);
const defaultCompData = getDefaultCompData(varDatParsed);
return {
cvData,
ssData,
default: variants.default,
slabDefaultOverride: variants.composite.slab
defaults: defaultCompData
};
};
function getCvData(variants) {
function getCvData(parsed) {
const samplerGroups = new Map();
for (const selector in variants.simple) {
let config = variants.simple[selector];
if (!config.sampler) continue;
config = { selector, ...config };
let gr = samplerGroups.get(config.sampler);
for (const [_keyPrime, prime] of parsed.primes) {
if (!prime.sampler) continue;
let gr = samplerGroups.get(prime.key);
if (!gr) {
gr = { configs: [] };
samplerGroups.set(config.sampler, gr);
gr = {
key: prime.key,
sampler: prime.sampler,
tag: prime.tag,
ligatureSampler: isLigatureSampler(prime),
descSampleText: isLigatureSampler(prime)
? prime.sampler.split(" ")
: [...prime.sampler],
variants: []
};
samplerGroups.set(prime.key, gr);
}
gr.configs.push({
selector,
tag: config.tag || null,
tagUpright: config.tagUpright || null,
tagItalic: config.tagItalic || null,
slopeHetero: !config.variant,
sampler: config.sampler,
description: config.description
});
for (const variant of prime.variants.values()) {
gr.variants.push({
selector: variant.key,
fullSelector: getSelectorKey(prime, variant),
rank: variant.rank,
description: variant.description
});
}
gr.variants.sort((a, b) => (a.rank || 0x7fffffff) - (b.rank || 0x7fffffff));
}
for (const [sampler, gr] of samplerGroups) {
gr.ligatureSampler = / /.test(sampler);
gr.descSampleText = gr.ligatureSampler ? sampler.split(" ") : [...sampler];
gr.configs.sort((a, b) => {
const ta = (a.tag || a.tagUpright || a.tagItalic || "").toLowerCase();
const tb = (b.tag || b.tagUpright || b.tagItalic || "").toLowerCase();
if (ta < tb) return -1;
if (ta > tb) return 1;
return 0;
});
gr.rank = rankOf(gr.descSampleText[0][0]);
}
return [...samplerGroups.values()].sort(compareSamplerGr);
return Array.from(samplerGroups.values());
}
function rankOf(initialChar) {
if ("a" <= initialChar && initialChar <= "z") return 3;
if ("A" <= initialChar && initialChar <= "Z") return 2;
if ("0" <= initialChar && initialChar <= "9") return 1;
return 0;
}
function compareSamplerGr(a, b) {
if (b.rank !== a.rank) return b.rank - a.rank;
if (a.rank) {
if (a.descSampleText[0][0] < b.descSampleText[0][0]) return -1;
if (a.descSampleText[0][0] > b.descSampleText[0][0]) return +1;
}
return 0;
}
const UPRIGHT = { isItalic: false };
const ITALIC = { isItalic: true };
function getSsData(variants, cvData) {
function getSsData(variants) {
const result = [
{
tag: "off",
@ -84,56 +72,66 @@ function getSsData(variants, cvData) {
hotCharSetItalic: []
}
];
const defaultUpright = buildupComposite(
cvData,
...variants.default.design,
...variants.default.upright
);
const defaultItalic = buildupComposite(
cvData,
...variants.default.design,
...variants.default.italic
);
for (const tag in variants.composite) {
if (!/^ss\d\d$/.test(tag)) continue;
const composition = variants.composite[tag];
const upright = buildupComposite(
cvData,
...(composition.design || []),
...(composition.upright || [])
);
const italic = buildupComposite(
cvData,
...(composition.design || []),
...(composition.italic || [])
);
const defaultUpright = buildupComposite(variants, UPRIGHT, variants.defaultComposite);
const defaultItalic = buildupComposite(variants, ITALIC, variants.defaultComposite);
for (const [key, composite] of variants.composites) {
if (!composite.tag) continue;
const upright = buildupComposite(variants, UPRIGHT, composite);
const italic = buildupComposite(variants, ITALIC, composite);
result.push({
tag,
tag: composite.tag,
effective: true,
description: composition.description,
uprightComposition: Array.from(upright.composition),
italicComposition: Array.from(italic.composition),
description: composite.description,
uprightComposition: upright.composition,
italicComposition: italic.composition,
hotCharSetUpright: Array.from(uniqueHotChars(defaultUpright, upright.hotChars)),
hotCharSetItalic: Array.from(uniqueHotChars(defaultItalic, italic.hotChars))
});
}
return result;
}
function buildupComposite(cvData, ..._cfg) {
const hch = new Map();
const cfg = new Set(_cfg);
for (const gr of cvData) {
if (gr.ligatureSampler) continue;
for (const config of gr.configs) {
if (cfg.has(config.selector)) {
for (const ch of gr.descSampleText) hch.set(ch, config.selector);
}
function getDefaultCompData(variants) {
return {
sansUpright: buildupComposite(variants, UPRIGHT, variants.defaultComposite),
sansItalic: buildupComposite(variants, ITALIC, variants.defaultComposite),
slabUpright: buildupComposite(
variants,
UPRIGHT,
variants.defaultComposite,
variants.composites.get("slab")
),
slabItalic: buildupComposite(
variants,
ITALIC,
variants.defaultComposite,
variants.composites.get("slab")
)
};
}
function getSelectorKey(prime, variant) {
return prime.key + "#" + variant.key;
}
function isLigatureSampler(prime) {
return / /.test(prime.sampler);
}
function buildupComposite(variants, para, ...composites) {
let compositionMap = new Map();
let hotChars = new Map();
for (const composite of composites) {
for (const [prime, variant] of composite.decompose(para, variants.selectorTree)) {
if (!prime.sampler || isLigatureSampler(prime)) continue;
const key = getSelectorKey(prime, variant);
for (const ch of prime.sampler) hotChars.set(ch, key);
compositionMap.set(prime.key, key);
}
}
return {
composition: [...cfg],
hotChars: hch
};
return { composition: Array.from(compositionMap.values()), hotChars };
}
function* uniqueHotChars(cfgDefault, cfgSS) {
for (const [hc, v] of cfgSS) {

View file

@ -194,14 +194,19 @@ const FontInfoOf = computed.group("metadata:font-info-of", async (target, fileNa
if (!bp) fail(`Build plan for '${fileName}' not found.` + whyBuildPlanIsnNotThere(fileName));
const sfi = getSuffixMapping(bp.weights, bp.slopes, bp.widths)[fi0.suffix];
const preHives = [...bp.pre.design, ...bp.pre[sfi.slope]];
return {
name: fileName,
// Hives
preHives,
variants: bp.variants || null,
featureControl: {
noCvSs: bp["no-cv-ss"] || false,
noLigation: bp["no-ligation"] || false
},
// Shape
shape: {
digitForm: bp["digit-form"] || "lining",
serifs: bp.serifs || null,
spacing: bp.spacing || null,
weight: sfi.shapeWeight,
slope: sfi.slope,
width: sfi.shapeWidth,