More refactor
This commit is contained in:
parent
09d80208a8
commit
2890a4cd00
16 changed files with 1085 additions and 1436 deletions
|
@ -695,7 +695,7 @@ i = "serifless"
|
|||
j = "flat-hook-serifless"
|
||||
k = "straight-serifless"
|
||||
l = "serifless"
|
||||
r = "compact"
|
||||
r = "compact-serifless"
|
||||
t = "flat-hook"
|
||||
u = "toothed-serifless"
|
||||
w = "straight-flat-top-serifless"
|
||||
|
@ -727,7 +727,7 @@ i = "serifed"
|
|||
j = "flat-hook-serifed"
|
||||
k = "straight-serifless"
|
||||
l = "serifed"
|
||||
r = "compact"
|
||||
r = "compact-serifless"
|
||||
t = "flat-hook"
|
||||
u = "toothed-serifless"
|
||||
w = "straight-flat-top-serifless"
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
* \[**BREAKING**\] Add taller slash, broken slash and broken zero variants for Zero. As a result, current variants are reordered (#1307, #1509, #1678).
|
||||
* \[**BREAKING**\] Add above-baseline crossed variant for Q. As a result, current variants are reordered (#1533).
|
||||
* \[**BREAKING**\] Rectify the variant atlas. As a result, if a character's variant list has motion-serifed, then it will have serifless and serifed variants: the serifed-ness will no longer be controlled by SLAB variable. The characters influenced are `M`, `N`, `P`, `R`, `U`, `V`, `W`, `b`, `h`, `m`, `n`, `p`, `q`, `u`, `v`, `w`, `y`.
|
||||
* \[**BREAKING**\] Reordered the variants of the following letters:
|
||||
* \[**BREAKING**\] Renamed and/or reordered the variants of the following letters:
|
||||
- `K`, `k`, Cyrillic Ka.
|
||||
- `r`.
|
||||
- `W`, `w`.
|
||||
* Add Characters:
|
||||
- CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN (`U+29BC`).
|
||||
- CIRCLED WHITE BULLET (`U+29BE`).
|
||||
|
|
|
@ -8,18 +8,11 @@ import [DesignParameters] from"../meta/aesthetics.mjs"
|
|||
|
||||
extern isFinite
|
||||
|
||||
import [mix linreg clamp fallback] from"../support/utils.mjs"
|
||||
import [mix linreg clamp fallback $NamedParameterPair$] from"../support/utils.mjs"
|
||||
import [calculateMetrics setFontMetrics GenDivFrame] from"../meta/aesthetics.mjs"
|
||||
|
||||
$$include '../meta/macros.ptl'
|
||||
|
||||
define [$NamedParameterPair$ l r] : begin
|
||||
set this.left l
|
||||
set this.right r
|
||||
return this
|
||||
|
||||
define [$DoNothing$] nothing
|
||||
|
||||
export : define [buildGlyphs para recursive] : begin
|
||||
local glyphStore : new GlyphStore
|
||||
|
||||
|
@ -110,7 +103,6 @@ export : define [buildGlyphs para recursive] : begin
|
|||
$assignUnicodeImpl$
|
||||
$defineGlyphBlockImpl$
|
||||
$execState$
|
||||
$DoNothing$
|
||||
Metrics : Object.assign {.} Metrics
|
||||
para
|
||||
recursive
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$$include '../../../meta/macros.ptl'
|
||||
|
||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||
import [mix linreg clamp fallback SuffixCfg] from"../../../support/utils.mjs"
|
||||
import [Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs"
|
||||
|
||||
glyph-module
|
||||
|
@ -149,29 +149,38 @@ glyph-block Letter-Latin-Lower-R : begin
|
|||
curl (xBar - Stroke * HVContrast) 0 [heading Downward]
|
||||
if doBottomSerif : include : rBottomSerif 0
|
||||
|
||||
define SmallRConfig : object
|
||||
'serifless' { StandardShape dfN rStraight { 0 0 } }
|
||||
'serifed' { StandardShape dfN rSerifed { 1 1 } }
|
||||
'topSerifed' { StandardShape dfN rSerifed { 1 0 } }
|
||||
'baseSerifed' { StandardShape dfN rSerifed { 0 1 } }
|
||||
'earlessCorner' { EarlessCornerShape dfN rEarless { 0 0 } }
|
||||
'earlessCornerSerifed' { EarlessCornerShape dfN rEarless { 0 1 } }
|
||||
'earlessRounded' { EarlessRoundedShape dfN rEarless { 0 0 } }
|
||||
'earlessRoundedSerifed' { EarlessRoundedShape dfN rEarless { 0 1 } }
|
||||
'hookless' { CompactShape dfN rNarrow { 0 0 } }
|
||||
'hooklessSerifed' { CompactShape dfN rNarrowSerifed { 1 1 } }
|
||||
'hooklessTopSerifed' { CompactShape dfN rNarrowSerifed { 1 0 } }
|
||||
'hooklessBaseSerifed' { CompactShape dfN rNarrowSerifed { 0 1 } }
|
||||
'compact' { CompactShape dfR rNarrow { 0 0 } }
|
||||
'compactSerifed' { CompactShape dfR rNarrowSerifed { 1 1 } }
|
||||
'compactTopSerifed' { CompactShape dfR rNarrowSerifed { 1 0 } }
|
||||
'compactBaseSerifed' { CompactShape dfR rNarrowSerifed { 0 1 } }
|
||||
'cornerHooked' { CornerHookShape dfN rCornerHooked { 0 0 } }
|
||||
'cornerHookedSerifed' { CornerHookShape dfN rCornerHookedSerifed { 1 1 } }
|
||||
'cornerHookedTopSerifed' { CornerHookShape dfN rCornerHookedSerifed { 1 0 } }
|
||||
'cornerHookedBaseSerifed' { CornerHookShape dfN rCornerHookedSerifed { 0 1 } }
|
||||
define [FlapHooklessShape df md doTopSerif doBottomSerif] : glyph-proc
|
||||
define [object xBar rBottomSerif xArchMiddle setMarks] : RDim df md
|
||||
set-base-anchor 'overlay' (xBar - 0.5 * Stroke * HVContrast) (XH / 2)
|
||||
include : setMarks doTopSerif
|
||||
include : dispiro
|
||||
widths.lhs
|
||||
g4.left.start (xArchMiddle - CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]) (XH - O)
|
||||
archv
|
||||
flat (xBar - Stroke * HVContrast) (XH - SmallArchDepthA)
|
||||
curl (xBar - Stroke * HVContrast) 0 [heading Downward]
|
||||
if doBottomSerif : include : rBottomSerif 0
|
||||
|
||||
foreach { suffix { F df mode { doTS doBS } } } [Object.entries SmallRConfig] : do
|
||||
define SmallRConfig : SuffixCfg.weave
|
||||
# Body
|
||||
object
|
||||
'' { StandardShape dfN rStraight }
|
||||
earlessCorner { EarlessCornerShape dfN rEarless }
|
||||
earlessRounded { EarlessRoundedShape dfN rEarless }
|
||||
hookless { CompactShape dfN rNarrow }
|
||||
cornerHooked { CornerHookShape dfN rCornerHooked }
|
||||
compact { CompactShape dfR rNarrow }
|
||||
hooklessFlap { FlapHooklessShape dfN rNarrow }
|
||||
compactFlap { FlapHooklessShape dfR rNarrow }
|
||||
|
||||
# Serifs
|
||||
object
|
||||
serifless { 0 0 }
|
||||
topSerifed { 1 0 }
|
||||
baseSerifed { 0 1 }
|
||||
serifed { 1 1 }
|
||||
|
||||
foreach { suffix { {F df mode} {doTS doBS} } } [pairs-of SmallRConfig] : do
|
||||
create-glyph "r.\(suffix)" : glyph-proc
|
||||
set-width df.width
|
||||
include : df.markSet.e
|
||||
|
@ -256,34 +265,5 @@ glyph-block Letter-Latin-Lower-R : begin
|
|||
include : dfR.markSet.e
|
||||
include : BBRShape dfN rStraight 0 0
|
||||
|
||||
|
||||
create-glyph 'rFlap.serifless' : glyph-proc
|
||||
set-width dfN.width
|
||||
include : dfN.markSet.e
|
||||
define [object rBottomSerif] : RDim dfN rEarless
|
||||
include : EarlessRoundedShape dfN rEarless 0 0
|
||||
create-forked-glyph 'rFlap.serifed' : rBottomSerif 0
|
||||
|
||||
define [rFlapHooklessShape df] : glyph-proc
|
||||
include : df.markSet.e
|
||||
define [object xBar rBottomSerif xArchMiddle] : RDim df rNarrow
|
||||
set-base-anchor 'overlay' (xBar - 0.5 * Stroke * HVContrast) (XH / 2)
|
||||
include : dispiro
|
||||
widths.lhs
|
||||
g4.left.start (xArchMiddle - CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]) (XH - O)
|
||||
archv
|
||||
flat (xBar - Stroke * HVContrast) (XH - SmallArchDepthA)
|
||||
curl (xBar - Stroke * HVContrast) 0 [heading Downward]
|
||||
if SLAB : include : rBottomSerif 0
|
||||
|
||||
create-glyph 'rFlap.hookless' : glyph-proc
|
||||
set-width dfN.width
|
||||
include : rFlapHooklessShape dfN
|
||||
|
||||
create-glyph 'rFlap.compact' : glyph-proc
|
||||
set-width dfR.width
|
||||
include : rFlapHooklessShape dfR
|
||||
|
||||
select-variant 'rFlap' 0x27E
|
||||
|
||||
select-variant 'rFlap' 0x27E (shapeFrom -- 'r')
|
||||
CreateAccentedComposition 'rFlapTildeOver' 0x1D73 'rFlap' 'tildeOver'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$$include '../../../meta/macros.ptl'
|
||||
|
||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||
import [mix fallback SuffixCfg] from"../../../support/utils.mjs"
|
||||
import [Dotless CvDecompose] from"../../../support/gr.mjs"
|
||||
|
||||
glyph-module
|
||||
|
@ -207,26 +207,19 @@ glyph-block Letter-Latin-Lower-T : begin
|
|||
include : VBar.m df.middle 0 top
|
||||
include : HCrossBar.top df.middle (df.middle + df.div * LongJut) yCrossBar
|
||||
|
||||
define SmallTConfig : object
|
||||
standard { [DivFrame 1] Standard Ascender }
|
||||
diagonalTailed { dfNarrowT DiagTail Ascender }
|
||||
flatHook { dfNarrowT Flat Ascender }
|
||||
cross { dfNarrowT Cross Ascender }
|
||||
hooklessAsymmetric { dfNarrowT HooklessAsymmetric Ascender }
|
||||
define SmallTConfig :SuffixCfg.weave
|
||||
object # body
|
||||
standard { [DivFrame 1] Standard }
|
||||
diagonalTailed { dfNarrowT DiagTail }
|
||||
flatHook { dfNarrowT Flat }
|
||||
cross { dfNarrowT Cross }
|
||||
hooklessAsymmetric { dfNarrowT HooklessAsymmetric }
|
||||
object # height
|
||||
"" Ascender
|
||||
shortNeck yShortNeck1
|
||||
shortNeck2 yShortNeck2
|
||||
|
||||
standardShortNeck { [DivFrame 1] Standard yShortNeck1 }
|
||||
diagonalTailedShortNeck { dfNarrowT DiagTail yShortNeck1 }
|
||||
flatHookShortNeck { dfNarrowT Flat yShortNeck1 }
|
||||
crossShortNeck { dfNarrowT Cross yShortNeck1 }
|
||||
hooklessAsymmetricShortNeck { dfNarrowT HooklessAsymmetric yShortNeck1 }
|
||||
|
||||
standardShortNeck2 { [DivFrame 1] Standard yShortNeck2 }
|
||||
diagonalTailedShortNeck2 { dfNarrowT DiagTail yShortNeck2 }
|
||||
flatHookShortNeck2 { dfNarrowT Flat yShortNeck2 }
|
||||
crossShortNeck2 { dfNarrowT Cross yShortNeck2 }
|
||||
hooklessAsymmetricShortNeck2 { dfNarrowT HooklessAsymmetric yShortNeck2 }
|
||||
|
||||
foreach { suffix { df Style top } } [Object.entries SmallTConfig] : do
|
||||
foreach { suffix { {df Style} top } } [pairs-of SmallTConfig] : do
|
||||
create-glyph "t.\(suffix)" : glyph-proc
|
||||
set-width df.width
|
||||
include : df.markSet.b
|
||||
|
@ -399,4 +392,4 @@ glyph-block Letter-Latin-Lower-T : begin
|
|||
xLeft + (BBD / 2) + LongJut + TBalance2
|
||||
begin yCrossBar
|
||||
begin BBS
|
||||
Rect Ascender 0 xLeft (xLeft + BBD)
|
||||
Rect Ascender 0 xLeft (xLeft + BBD)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$$include '../../../meta/macros.ptl'
|
||||
|
||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||
import [mix fallback SuffixCfg] from"../../../support/utils.mjs"
|
||||
import [Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs"
|
||||
|
||||
glyph-module
|
||||
|
@ -323,43 +323,32 @@ glyph-block Letter-Latin-W : begin
|
|||
define [WCursiveImpl df top bodyType serifsType] : WCursiveImplImpl false df top bodyType serifsType
|
||||
define [WHookTopCursive df top bodyType serifsType] : WCursiveImplImpl true df top bodyType serifsType
|
||||
|
||||
define WConfig : object
|
||||
cyrlCapialOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA SERIFS-CYRL-OMEGA }
|
||||
cyrlSmallOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA SERIFS-CURSIVE }
|
||||
define WConfig : SuffixCfg.weave
|
||||
# Body
|
||||
object
|
||||
straight { WShapeImpl WHooktopShape FORM-STRAIGHT }
|
||||
straightAsymmetric { WShapeImpl WHooktopShape FORM-ASYMMETRIC }
|
||||
straightDoubleV { WShapeImpl WHooktopShape FORM-DOUBLE-V }
|
||||
straightFlatTop { WShapeImpl WHooktopShape FORM-FLAT-TOP }
|
||||
straightVerticalSides { WVertSides WVSHookTopShape FORM-STRAIGHT }
|
||||
curly { WShapeImpl WHooktopShape FORM-CURLY }
|
||||
cursive { WCursiveImpl WHookTopCursive FORM-CURLY }
|
||||
cyrlCapialOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA }
|
||||
cyrlSmallOmega { WShapeImpl WHooktopShape FORM-CYRL-OMEGA }
|
||||
|
||||
straightAsymmetric { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-ASYMMETRIC }
|
||||
straightDoubleV { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-DOUBLE-V }
|
||||
straightFlatTop { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-AUTO }
|
||||
straight { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-AUTO }
|
||||
straightVerticalSides { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-AUTO }
|
||||
curly { WShapeImpl WHooktopShape FORM-CURLY SERIFS-AUTO }
|
||||
cursive { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-CURSIVE }
|
||||
# Serifs
|
||||
function [body] : if (body == 'cyrlCapialOmega' || body == 'cyrlSmallOmega')
|
||||
then : object ["" SERIFS-CYRL-OMEGA]
|
||||
else : object
|
||||
serifless SERIFS-NONE
|
||||
motionSerifed SERIFS-MOTION
|
||||
serifed : match body
|
||||
[Just 'straightAsymmetric'] SERIFS-ASYMMETRIC-ALL
|
||||
[Just 'straightDoubleV'] SERIFS-DOUBLE-V-ALL
|
||||
[Just 'cursive'] SERIFS-MOTION
|
||||
__ SERIFS-ALL
|
||||
|
||||
straightAsymmetricSerifless { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-NONE }
|
||||
straightDoubleVSerifless { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-NONE }
|
||||
straightFlatTopSerifless { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-NONE }
|
||||
straightVerticalSidesSerifless { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-NONE }
|
||||
straightSerifless { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-NONE }
|
||||
curlySerifless { WShapeImpl WHooktopShape FORM-CURLY SERIFS-NONE }
|
||||
cursiveSerifless { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-NONE }
|
||||
|
||||
straightAsymmetricMotionSerifed { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-MOTION }
|
||||
straightDoubleVMotionSerifed { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-MOTION }
|
||||
straightFlatTopMotionSerifed { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-MOTION }
|
||||
straightVerticalSidesMotionSerifed { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-MOTION }
|
||||
straightMotionSerifed { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-MOTION }
|
||||
curlyMotionSerifed { WShapeImpl WHooktopShape FORM-CURLY SERIFS-MOTION }
|
||||
cursiveMotionSerifed { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-MOTION }
|
||||
|
||||
straightAsymmetricSerifed { WShapeImpl WHooktopShape FORM-ASYMMETRIC SERIFS-ASYMMETRIC-ALL }
|
||||
straightDoubleVSerifed { WShapeImpl WHooktopShape FORM-DOUBLE-V SERIFS-DOUBLE-V-ALL }
|
||||
straightFlatTopSerifed { WShapeImpl WHooktopShape FORM-FLAT-TOP SERIFS-ALL }
|
||||
straightVerticalSidesSerifed { WVertSides WVSHookTopShape FORM-STRAIGHT SERIFS-ALL }
|
||||
straightSerifed { WShapeImpl WHooktopShape FORM-STRAIGHT SERIFS-ALL }
|
||||
curlySerifed { WShapeImpl WHooktopShape FORM-CURLY SERIFS-ALL }
|
||||
cursiveSerifed { WCursiveImpl WHookTopCursive FORM-CURLY SERIFS-MOTION }
|
||||
|
||||
foreach { suffix { implT hookTopImplT bodyType slabType } } [Object.entries WConfig] : do
|
||||
foreach { suffix { {implT hookTopImplT bodyType} slabType } } [pairs-of WConfig] : do
|
||||
create-glyph "W.\(suffix)" : glyph-proc
|
||||
local df : DivFrame para.diversityM 3
|
||||
set-width df.width
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
$$include '../../meta/macros.ptl'
|
||||
|
||||
import [mix linreg clamp fallback] from"../../support/utils.mjs"
|
||||
import [mix clamp fallback SuffixCfg] from"../../support/utils.mjs"
|
||||
import [AnyCv getGrMesh VS01] from"../../support/gr.mjs"
|
||||
|
||||
glyph-module
|
||||
|
@ -105,8 +105,8 @@ glyph-block Digits-Zero : begin
|
|||
define [BrokenVerticalBar top] : difference
|
||||
VBar.m Middle (0 + O) (top - O) [Math.min (CircleInnerWidth * 0.375) OverlayStroke]
|
||||
intersection
|
||||
MaskAbove (top * (1/2 + 1/16))
|
||||
MaskBelow (top * (1/2 - 1/16))
|
||||
MaskAbove (top * (1/2 - 1/16))
|
||||
MaskBelow (top * (1/2 + 1/16))
|
||||
|
||||
define [ZeroDotShape top] : begin
|
||||
local halfDotWidth : Math.min DotRadius (CircleInnerWidth / 4)
|
||||
|
@ -150,50 +150,48 @@ glyph-block Digits-Zero : begin
|
|||
Middle + halfDotWidth - OX
|
||||
begin 0
|
||||
|
||||
define ZeroConfig : object
|
||||
'unslashed' { null null }
|
||||
'slashed' { ZeroSlash null }
|
||||
'reverseSlashed' { ZeroRevSlash null }
|
||||
'tallSlashed' { ZeroTallSlash null }
|
||||
'tallReverseSlashed' { ZeroTallRevSlash null }
|
||||
'dotted' { ZeroDotShape null }
|
||||
'longDotted' { ZeroLongDotShape null }
|
||||
'slashedSplit' { ZeroSlash InsetShape }
|
||||
'reverseSlashedSplit' { ZeroRevSlash InsetShape }
|
||||
'brokenSlash' { BrokenTallSlash null }
|
||||
'brokenReverseSlash' { BrokenTallRevSlash null }
|
||||
'brokenVerticalBar' { BrokenVerticalBar null }
|
||||
'slashedCutout' { CutoutSlash Cutout }
|
||||
'reverseSlashedCutout' { CutoutRevSlash Cutout }
|
||||
'tallSlashedCutout' { CutoutTallSlash Cutout }
|
||||
'tallReverseSlashedCutout' { CutoutTallRevSlash Cutout }
|
||||
'verticalBarCutout' { CutoutVerticalBar Cutout }
|
||||
'topRightCutout' { TopRightCutoutSlash Cutout }
|
||||
define ZeroConfig : SuffixCfg.weave
|
||||
object # outline shape
|
||||
'' { ZeroOutlineShape ZeroOutlineMask }
|
||||
'oval' { ZeroOvalShape ZeroOvalMask }
|
||||
object # overlay/cutout
|
||||
'unslashed' { null null }
|
||||
'slashed' { ZeroSlash null }
|
||||
'reverseSlashed' { ZeroRevSlash null }
|
||||
'tallSlashed' { ZeroTallSlash null }
|
||||
'tallReverseSlashed' { ZeroTallRevSlash null }
|
||||
'dotted' { ZeroDotShape null }
|
||||
'longDotted' { ZeroLongDotShape null }
|
||||
'slashedSplit' { ZeroSlash InsetShape }
|
||||
'reverseSlashedSplit' { ZeroRevSlash InsetShape }
|
||||
'brokenSlash' { BrokenTallSlash null }
|
||||
'brokenReverseSlash' { BrokenTallRevSlash null }
|
||||
'brokenVerticalBar' { BrokenVerticalBar null }
|
||||
'slashedCutout' { CutoutSlash Cutout }
|
||||
'reverseSlashedCutout' { CutoutRevSlash Cutout }
|
||||
'tallSlashedCutout' { CutoutTallSlash Cutout }
|
||||
'tallReverseSlashedCutout' { CutoutTallRevSlash Cutout }
|
||||
'verticalBarCutout' { CutoutVerticalBar Cutout }
|
||||
'topRightCutout' { TopRightCutoutSlash Cutout }
|
||||
|
||||
define Shapes : object
|
||||
'' { ZeroOutlineShape ZeroOutlineMask }
|
||||
'Oval' { ZeroOvalShape ZeroOvalMask }
|
||||
|
||||
define Infixes : object
|
||||
define Heights : object
|
||||
'lnum' { CAP [function [] : MarkSet.capital] }
|
||||
'onum' { OnumHeight [function [] : OnumMarks.e] }
|
||||
|
||||
foreach { shapeSuffix { Outline Mask } } [Object.entries Shapes] : begin
|
||||
foreach { infix { height Marks } } [Object.entries Infixes] : begin
|
||||
local zeroShape : Outline height
|
||||
foreach { suffix { Overlay Postproc } } [Object.entries ZeroConfig] : begin
|
||||
create-glyph "zero.\(infix).\(suffix)\(shapeSuffix)" : glyph-proc
|
||||
include : Marks
|
||||
|
||||
local overlayShape : if Overlay [Overlay height] null
|
||||
if Postproc
|
||||
: then : begin
|
||||
include : Postproc zeroShape overlayShape Mask height
|
||||
: else : begin
|
||||
include zeroShape
|
||||
if Overlay : if Mask
|
||||
include : intersection overlayShape : Mask height
|
||||
include overlayShape
|
||||
foreach { suffix { {Outline Mask} {Overlay Postproc} } } [pairs-of ZeroConfig] : begin
|
||||
foreach { infix { height Marks } } [pairs-of Heights] : begin
|
||||
create-glyph "zero.\(infix).\(suffix)" : glyph-proc
|
||||
include : Marks
|
||||
local zeroShape : Outline height
|
||||
local overlayShape : if Overlay [Overlay height] null
|
||||
if Postproc
|
||||
: then : begin
|
||||
include : Postproc zeroShape overlayShape Mask height
|
||||
: else : begin
|
||||
include zeroShape
|
||||
if Overlay : if Mask
|
||||
include : intersection overlayShape : Mask height
|
||||
include overlayShape
|
||||
|
||||
select-variant 'zero.lnum' [CodeLnum '0'] (follow -- 'zero')
|
||||
select-variant 'zero.onum' [CodeOnum '0'] (follow -- 'zero')
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
### Autoarg macro
|
||||
define-operator "--" 890 'right' : syntax-rules
|
||||
`(@l -- @r) [atom l] : dirty `[new $NamedParameterPair$ @{".quote" [formOf l]} @r]
|
||||
`(@{".quote" l} -- @r) : dirty `[new $NamedParameterPair$ @l @r]
|
||||
|
||||
### Arbitrary pair operator
|
||||
define-operator "~>" 880 'right' : syntax-rules
|
||||
`(@l ~> @r) `{.left @l .right @r}
|
||||
|
||||
### Macro for identity match
|
||||
define-macro Just : begin
|
||||
|
@ -30,7 +35,7 @@ define-macro params : syntax-rules
|
|||
local declarations `[begin]
|
||||
local namedAssigns `[begin]
|
||||
local indexAssigns `[begin]
|
||||
local tearDowns `[begin]
|
||||
local tearDowns `[begin]
|
||||
|
||||
local j 0
|
||||
foreach [pf : items-of : formOf _pairs] : begin
|
||||
|
@ -204,14 +209,13 @@ define-macro glyph-block : syntax-rules
|
|||
([typeof form] === "string") : set variableSet.(form) true
|
||||
|
||||
traceBody body
|
||||
traceBody `[$NamedParameterPair$ $DoNothing$ $createAndSaveGlyphImpl$ $assignUnicodeImpl$]
|
||||
traceBody `[$NamedParameterPair$ $createAndSaveGlyphImpl$ $assignUnicodeImpl$ $execState$]
|
||||
|
||||
set externEnv.$glyphBlockVariableUsage$ variableSet
|
||||
|
||||
define captureImports `[$createAndSaveGlyphImpl$ $NamedParameterPair$
|
||||
$assignUnicodeImpl$ $DoNothing$ $execState$
|
||||
Metrics para recursive glyphStore glyph-is-needed SpiroFns BooleFns MarkSet AS_BASE
|
||||
ALSO_METRICS buildGlyphs tagged DivFrame fontMetrics]
|
||||
define captureImports `[$createAndSaveGlyphImpl$ $NamedParameterPair$ $assignUnicodeImpl$
|
||||
$execState$ Metrics para recursive glyphStore glyph-is-needed SpiroFns BooleFns
|
||||
MarkSet AS_BASE ALSO_METRICS buildGlyphs tagged DivFrame fontMetrics]
|
||||
|
||||
define metricImports `[DesignParameters UPM HalfUPM Width SB CAP XH Ascender Descender
|
||||
Contrast SymbolMid ParenTop ParenBot OperTop OperBot TackTop TackBot PlusTop PlusBot
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
$$include '../meta/macros.ptl'
|
||||
|
||||
import [AddCommonFeature AddFeature AddLookup AddFeatureLookup ChainRuleBuilder BeginLookupBlock EndLookupBlock UkMapToLookup UkMap2ToLookup] from"./table-util.mjs"
|
||||
import [AnyCv Dotless TieMark TieGlyph OgonekTrY IsSuperscript IsSubscript] from"../support/gr.mjs"
|
||||
import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs"
|
||||
|
||||
extern Set
|
||||
|
||||
define-operator "~>" 880 'right' : syntax-rules
|
||||
`(@l ~> @r) `{.left @l .right @r}
|
||||
|
||||
define-macro Ccmp-Group : syntax-rules
|
||||
`[Ccmp-Group @description @body]
|
||||
dirty `[$ExecCcmpGroup$ [function [export-lookup chain-rule] @[formOf body]]]
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
$$include '../meta/macros.ptl'
|
||||
|
||||
import [AddLookup AddCommonFeature PickCommonFeature AddFeatureLookup PickLookup BeginLookupBlock EndLookupBlock ChainRuleBuilder] from"./table-util.mjs"
|
||||
import [Cv AnyCv CvDecompose RightDependentLink RightDependentTrigger] from"../support/gr.mjs"
|
||||
|
||||
|
@ -5,8 +7,6 @@ extern Map
|
|||
extern Set
|
||||
|
||||
define look-around null
|
||||
define-operator "~>" 880 'right' : syntax-rules
|
||||
`(@l ~> @r) `{.left @l .right @r}
|
||||
|
||||
define [FeatureName tag] : tag + '_cvss'
|
||||
define [SsLookupName tag] : 'lookup_ss_' + tag
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
$$include '../meta/macros.ptl'
|
||||
|
||||
import [AddCommonFeature AddFeature AddLookup BeginLookupBlock EndLookupBlock ChainRuleBuilder] from"./table-util.mjs"
|
||||
import [NumeratorForm DenominatorForm] from"../support/gr.mjs"
|
||||
|
||||
define-operator "~>" 880 'right' : syntax-rules
|
||||
`(@l ~> @r) `{.left @l .right @r}
|
||||
|
||||
# Name-driven feature pairs
|
||||
export : define [buildFrac sink glyphStore] : begin
|
||||
local rec : BeginLookupBlock sink
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
$$include '../meta/macros.ptl'
|
||||
|
||||
import [AddCommonFeature AddFeature ChainRuleBuilder BeginLookupBlock EndLookupBlock] from"./table-util.mjs"
|
||||
extern Map
|
||||
extern Set
|
||||
|
||||
define-operator "~>" 880 'right' : syntax-rules
|
||||
`(@l ~> @r) `{.left @l .right @r}
|
||||
|
||||
define [arrowBarX s] : lambda [t] : t.map : lambda [x] "\(x).arrowBar.\(s)"
|
||||
define [lsx s] : lambda [t] : t.map : lambda [x] "\(x).lig.\(s)"
|
||||
define [csx s] : lambda [t] : t.map : lambda [x] "\(x).\(s)"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import [AddCommonFeature AddFeature AddLookup ChainRuleBuilder QueryRelatedGlyphs BeginLookupBlock EndLookupBlock] from"./table-util.mjs"
|
||||
$$include '../meta/macros.ptl'
|
||||
|
||||
define-operator "~>" 880 'right' : syntax-rules
|
||||
`(@l ~> @r) `{.left @l .right @r}
|
||||
import [AddCommonFeature AddFeature AddLookup ChainRuleBuilder QueryRelatedGlyphs BeginLookupBlock EndLookupBlock] from"./table-util.mjs"
|
||||
|
||||
export : define [buildGsubThousands sink para] : begin
|
||||
local rec : BeginLookupBlock sink
|
||||
|
|
|
@ -34,28 +34,49 @@ export function joinCamel(a, b) {
|
|||
return a + b[0].toUpperCase() + b.slice(1);
|
||||
}
|
||||
|
||||
function joinSuffixListImpl(sink, k, v, configs) {
|
||||
function joinSuffixListImpl(sink, k, v, telescope, configs) {
|
||||
if (!configs.length) {
|
||||
sink[k] = v;
|
||||
return;
|
||||
}
|
||||
|
||||
for (const [keySuffix, valueSuffix] of Object.entries(configs[0])) {
|
||||
let [item, ...rest] = configs;
|
||||
if (item instanceof Function) item = item(...telescope);
|
||||
if (!item) return;
|
||||
|
||||
for (const [keySuffix, valueSuffix] of Object.entries(item)) {
|
||||
const k1 = joinCamel(k, keySuffix);
|
||||
const v1 = [...v, valueSuffix];
|
||||
joinSuffixListImpl(sink, k1, v1, configs.slice(1));
|
||||
const telescope1 = [...telescope, keySuffix];
|
||||
joinSuffixListImpl(sink, k1, v1, telescope1, rest);
|
||||
}
|
||||
}
|
||||
|
||||
export const SuffixCfg = {
|
||||
weave: function (...configs) {
|
||||
let ans = {};
|
||||
joinSuffixListImpl(ans, "", [], configs);
|
||||
joinSuffixListImpl(ans, "", [], [], configs);
|
||||
return ans;
|
||||
},
|
||||
combine: function (...configs) {
|
||||
let ans = {};
|
||||
for (const item of configs) for (const [k, v] of Object.entries(item)) ans[k] = v;
|
||||
return ans;
|
||||
},
|
||||
collect: function (pairs) {
|
||||
let ans = {};
|
||||
for (const pair of pairs) {
|
||||
if (pair) ans[pair.left] = pair.right;
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
export class $NamedParameterPair$ {
|
||||
constructor(l, r) {
|
||||
this.left = l;
|
||||
this.right = r;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,55 +261,36 @@ class VbStageAlternative {
|
|||
this.key = key;
|
||||
this.rank = raw.rank;
|
||||
this.next = raw.next;
|
||||
if (key !== "*") this.keySuffix = raw.keySuffix ?? key;
|
||||
this.descriptionSuffix = raw.descriptionSuffix;
|
||||
this.descriptionJoiner = raw.descriptionJoiner || "with";
|
||||
this.mode = raw.mode;
|
||||
this.disableIf = raw.disableIf;
|
||||
this.selectorSuffix = raw.selectorSuffix;
|
||||
if (key !== "*") this.keyAffix = raw.keyAffix ?? key;
|
||||
this.descriptionAffix = raw.descriptionAffix;
|
||||
this.descriptionJoiner = raw.descriptionJoiner || "with";
|
||||
this.selectorAffix = raw.selectorAffix;
|
||||
}
|
||||
fallback(defaultAlternative) {
|
||||
this.next = this.next || defaultAlternative.next;
|
||||
this.keySuffix = this.keySuffix || defaultAlternative.keySuffix;
|
||||
this.descriptionSuffix = this.descriptionSuffix || defaultAlternative.descriptionSuffix;
|
||||
this.mode = this.mode || defaultAlternative.mode || "append";
|
||||
this.keyAffix = this.keyAffix || defaultAlternative.keyAffix;
|
||||
this.descriptionAffix = this.descriptionAffix || defaultAlternative.descriptionAffix;
|
||||
this.descriptionJoiner = this.descriptionJoiner || defaultAlternative.descriptionJoiner;
|
||||
this.disableIf = this.disableIf || defaultAlternative.disableIf;
|
||||
this.selectorSuffix = this.selectorSuffix || defaultAlternative.selectorSuffix;
|
||||
}
|
||||
|
||||
tryAccept(globalState, localState) {
|
||||
// Detect whether this alternative is applicable.
|
||||
if (this.disableIf) {
|
||||
for (const branch of this.disableIf) {
|
||||
let statementMatches = true;
|
||||
for (let [k, v] of Object.entries(branch)) {
|
||||
v = v.trim();
|
||||
if (/^NOT(?=\s)/.test(v)) {
|
||||
v = v.slice(3).trim();
|
||||
if (localState.assignments.get(k) === v) {
|
||||
statementMatches = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (localState.assignments.get(k) !== v) {
|
||||
statementMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (statementMatches) return null;
|
||||
}
|
||||
}
|
||||
// Reject if disable conditions match
|
||||
if (this.shouldReject(localState)) return null;
|
||||
|
||||
// Accept this alternative.
|
||||
const ans = localState.clone();
|
||||
ans.stage = this.next;
|
||||
ans.assignments.set(this.stage, this.key);
|
||||
if (this.keySuffix) ans.key.push(this.keySuffix);
|
||||
if (this.descriptionJoiner && this.descriptionSuffix)
|
||||
ans.addDescription(this.descriptionJoiner, this.descriptionSuffix);
|
||||
if (this.selectorSuffix)
|
||||
for (const [selector, suffix] of Object.entries(this.selectorSuffix))
|
||||
ans.addSelector(selector, suffix);
|
||||
if (this.keyAffix) ans.addKeyAffix(this.mode, this.keyAffix);
|
||||
if (this.descriptionJoiner && this.descriptionAffix)
|
||||
ans.addDescription(this.mode, this.descriptionJoiner, this.descriptionAffix);
|
||||
if (this.selectorAffix)
|
||||
for (const [selector, suffix] of Object.entries(this.selectorAffix))
|
||||
ans.addSelectorAffix(this.mode, selector, suffix);
|
||||
|
||||
if (!this.next) {
|
||||
ans.rank = ++globalState.rank;
|
||||
|
@ -319,6 +300,31 @@ class VbStageAlternative {
|
|||
return ans;
|
||||
}
|
||||
}
|
||||
|
||||
shouldReject(localState) {
|
||||
if (!this.disableIf) return false;
|
||||
|
||||
for (const branch of this.disableIf) {
|
||||
let statementMatches = true;
|
||||
for (let [k, v] of Object.entries(branch)) {
|
||||
v = v.trim();
|
||||
if (/^NOT(?=\s)/.test(v)) {
|
||||
v = v.slice(3).trim();
|
||||
if (localState.assignments.get(k) === v) {
|
||||
statementMatches = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (localState.assignments.get(k) !== v) {
|
||||
statementMatches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (statementMatches) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class VbGlobalState {
|
||||
|
@ -354,13 +360,56 @@ class VbLocalState {
|
|||
return ans;
|
||||
}
|
||||
|
||||
addDescription(joiner, segment) {
|
||||
addKeyAffix(mode, segment) {
|
||||
switch (mode) {
|
||||
case "append":
|
||||
this.key.push(segment);
|
||||
return;
|
||||
case "prepend":
|
||||
this.key.unshift(segment);
|
||||
return;
|
||||
case "replace":
|
||||
this.key = [segment];
|
||||
return;
|
||||
default:
|
||||
throw new Error(`Invalid key affix mode: ${mode}`);
|
||||
}
|
||||
}
|
||||
|
||||
addDescription(mode, joiner, segment) {
|
||||
if (!segment) return;
|
||||
if (!this.descriptions.has(joiner)) this.descriptions.set(joiner, []);
|
||||
this.descriptions.get(joiner).push(segment);
|
||||
|
||||
let descriptionSentence = this.descriptions.get(joiner);
|
||||
switch (mode) {
|
||||
case "append":
|
||||
descriptionSentence.push(segment);
|
||||
return;
|
||||
case "prepend":
|
||||
descriptionSentence.unshift(segment);
|
||||
return;
|
||||
case "replace":
|
||||
descriptionSentence.length = 0;
|
||||
descriptionSentence.push(segment);
|
||||
return;
|
||||
default:
|
||||
throw new Error(`Invalid description affix mode: ${mode}`);
|
||||
}
|
||||
}
|
||||
addSelector(selector, value) {
|
||||
this.selector.set(selector, joinCamel(this.selector.get(selector), value));
|
||||
addSelectorAffix(mode, selector, value) {
|
||||
switch (mode) {
|
||||
case "append":
|
||||
this.selector.set(selector, joinCamel(this.selector.get(selector), value));
|
||||
return;
|
||||
case "prepend":
|
||||
this.selector.set(selector, joinCamel(value, this.selector.get(selector)));
|
||||
return;
|
||||
case "replace":
|
||||
this.selector.set(selector, value);
|
||||
return;
|
||||
default:
|
||||
throw new Error(`Invalid selector affix mode: ${mode}`);
|
||||
}
|
||||
}
|
||||
|
||||
produceKey() {
|
||||
|
@ -388,5 +437,5 @@ class VbLocalState {
|
|||
function arrayToSentence(arr) {
|
||||
if (arr.length == 1) return arr[0];
|
||||
let last = arr.pop();
|
||||
return arr.join(", ") + " and " + last;
|
||||
return arr.join(", ") + ", and " + last;
|
||||
}
|
||||
|
|
2039
params/variants.toml
2039
params/variants.toml
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue