Change the mechanism of variants of not-equal ligation (#1400):

- The "dotted" ligation groups (`exeqeq-dotted`, `eqexeq-dotted`, `eqexeq-dl-dotted`, `exeq-dotted`) are removed.
   - A character variant, "lig-neq" (feature tag `VXAF`), is added to control the shape instead.
This commit is contained in:
be5invis 2022-08-15 00:00:03 -07:00
parent e8d2272b28
commit 86e1191854
9 changed files with 148 additions and 131 deletions

View file

@ -1 +0,0 @@
* Ensure that the middle point between Typo Ascender and Descender lies on the middle of symbols/operators (#1398).

4
changes/16.0.0.md Normal file
View file

@ -0,0 +1,4 @@
* \[**Breaking**\] Change the mechanism of variants of not-equal ligation (#1400):
- The "dotted" ligation groups (`exeqeq-dotted`, `eqexeq-dotted`, `eqexeq-dl-dotted`, `exeq-dotted`) are removed.
- A character variant, "lig-neq" (feature tag `VXAF`), is added to control the shape instead.
* Ensure that the middle point between Typo Ascender and Descender lies on the middle of symbols/operators (#1398).

View file

@ -2,7 +2,7 @@
$$include '../../meta/macros.ptl'
import [mix clamp fallback] from"../../support/utils.mjs"
import [Joining] from"../../support/gr.mjs"
import [Joining NeqLigationSlashDotted] from"../../support/gr.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs"
glyph-module
@ -338,76 +338,77 @@ glyph-block Symbol-Ligation : begin
IdentHole (-Width)
IdentHole 0
glyph-block-import NotGlyphFn : notGlyph
### Inequality
define Neq : namespace
export : define Sw OperatorStroke
export : define Dr : Sw / Stroke * DotRadius
export : define DotGap : Math.max ((ParenTop - ParenBot) / 8) [AdviceStroke 5]
export : define PlacementSuffixes : object
"1l" { 0 Joining.Classes.Right }
"2l" { 1 Joining.Classes.Right }
"3l" { 2 Joining.Classes.Right }
"4l" { 3 Joining.Classes.Right }
"1m" { 0 Joining.Classes.Mid }
"2m" { 1 Joining.Classes.Mid }
"3m" { 2 Joining.Classes.Mid }
"4m" { 3 Joining.Classes.Mid }
export : define BarShapeSuffixes : object
vertical { 0 false }
slightlySlanted { 0.375 false }
moreSlanted { 0.75 false }
verticalDotted { 0 true }
slightlySlantedDotted { 0.375 true }
moreSlantedDotted { 0.75 true }
export : define [DependentGlyphBuilder src] : glyph-proc
local { bar dot } src
include [refer-glyph bar] AS_BASE ALSO_METRICS
local dotted : NeqLigationSlashDotted.get [query-glyph bar]
if dotted : include [refer-glyph dot]
foreach { suffix { DrawAt kdr overshoot } } [Object.entries DotVariants] : do
create-glyph "neq/dotPart.\(suffix)" : glyph-proc
set-width 0
set-mark-anchor 'cvDecompose' 0 0
include : DrawAt 0 0 (Neq.Dr - overshoot)
select-variant 'neq/dotPart' (follow -- 'punctuationDot')
foreach { place { shift joinCls } } [Object.entries Neq.PlacementSuffixes] : do
foreach { barSuffix { slope fDotted } } [Object.entries Neq.BarShapeSuffixes] : do
create-glyph "neq.\(place)/barPart.\(barSuffix)" : glyph-proc
define yUp BgOpTop
define yDown : BgOpBot + [if fDotted (2 * Neq.Dr + Neq.DotGap) 0]
define xCenter : Width * (1 / 2 + shift / 2)
define xUp : xCenter + slope * (yUp - SymbolMid)
define xDown : xCenter + slope * (yDown - SymbolMid)
define [slash jk] : function [t b l r sw sh] : glyph-proc
Joining.set currentGlyph jk
include : dispiro
widths.center OperatorStroke
flat (sh + l) b
curl (sh + r) t
widths.center Neq.Sw
corner xUp yUp
corner xDown yDown
define [exSlash2 jk] : function [t b l r sw sh] : glyph-proc
local dr : PeriodRadius / Stroke * OperatorStroke
Joining.set currentGlyph jk
include : union
DotAt (sh + l + dr * (r - l) / (t - b)) (b + dr) dr
intersection
Rect (SymbolMid + t) [Math.min (b + dr * 3.5) (SymbolMid - EqualHalfSpace)] (-Width * 4) (Width * 4)
dispiro
widths.center OperatorStroke
flat (sh + l) b
curl (sh + r) t
if fDotted : begin
NeqLigationSlashDotted.set currentGlyph
define yDotCenter : BgOpBot + Neq.Dr
define xDotCenter : xCenter + slope * (yDotCenter - SymbolMid)
set-base-anchor 'cvDecompose' xDotCenter yDotCenter
notGlyph.generic 'neq.1l' null 'sp1'
shift -- (Width * 0.0)
F -- [slash Joining.Classes.Right]
notGlyph.generic 'neq.2l' null 'sp1'
shift -- (Width * 0.5)
F -- [slash Joining.Classes.Right]
notGlyph.generic 'neq.3l' null 'sp1'
shift -- (Width * 1.0)
F -- [slash Joining.Classes.Right]
notGlyph.generic 'neq.4l' null 'sp1'
shift -- (Width * 1.5)
F -- [slash Joining.Classes.Right]
notGlyph.generic 'neq.1m' null 'sp1'
shift -- (Width * 0.0)
F -- [slash Joining.Classes.Mid]
notGlyph.generic 'neq.2m' null 'sp1'
shift -- (Width * 0.5)
F -- [slash Joining.Classes.Mid]
notGlyph.generic 'neq.3m' null 'sp1'
shift -- (Width * 1.0)
F -- [slash Joining.Classes.Mid]
notGlyph.generic 'neq.4m' null 'sp1'
shift -- (Width * 1.5)
F -- [slash Joining.Classes.Mid]
select-variant "neq.allow-dot.\(place)/barPart"
follow -- "neq.allow-dot"
shapeFrom -- "neq.\(place)/barPart"
select-variant "neq.bar-only.\(place)/barPart"
follow -- "neq.bar-only"
shapeFrom -- "neq.\(place)/barPart"
notGlyph.generic 'neq.1l-dotted' null 'sp1'
shift -- (Width * 0.0)
F -- [exSlash2 Joining.Classes.Right]
notGlyph.generic 'neq.2l-dotted' null 'sp1'
shift -- (Width * 0.5)
F -- [exSlash2 Joining.Classes.Right]
notGlyph.generic 'neq.3l-dotted' null 'sp1'
shift -- (Width * 1.0)
F -- [exSlash2 Joining.Classes.Right]
notGlyph.generic 'neq.4l-dotted' null 'sp1'
shift -- (Width * 1.5)
F -- [exSlash2 Joining.Classes.Right]
notGlyph.generic 'neq.1m-dotted' null 'sp1'
shift -- (Width * 0.0)
F -- [exSlash2 Joining.Classes.Mid]
notGlyph.generic 'neq.2m-dotted' null 'sp1'
shift -- (Width * 0.5)
F -- [exSlash2 Joining.Classes.Mid]
notGlyph.generic 'neq.3m-dotted' null 'sp1'
shift -- (Width * 1.0)
F -- [exSlash2 Joining.Classes.Mid]
notGlyph.generic 'neq.4m-dotted' null 'sp1'
shift -- (Width * 1.5)
F -- [exSlash2 Joining.Classes.Mid]
derive-multi-part-glyphs "neq.allow-dot.\(place)" null { "neq.allow-dot.\(place)/barPart" "neq/dotPart" } Neq.DependentGlyphBuilder
derive-multi-part-glyphs "neq.bar-only.\(place)" null { "neq.bar-only.\(place)/barPart" "neq/dotPart" } Neq.DependentGlyphBuilder
do "<| , |> and <>"
glyph-block-import Symbol-Math-Relation-Inequality : LessShape GreaterShape

View file

@ -743,34 +743,21 @@ define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] :
{'equal.cf' 'equal.jf'} ~> look-around
equal ~> {'equal.jf'}
piecewise
[hasLG 'eqexeq-dotted'] : chain-rule
equal ~> {'ident.fc'}
exclam ~> {'neq.1m-dotted'}
equal ~> {'ident.cc+cf'}
[hasLG 'eqexeq'] : chain-rule
equal ~> {'ident.fc'}
exclam ~> {'neq.1m'}
exclam ~> {'neq.allow-dot.1m'}
equal ~> {'ident.cc+cf'}
[hasLG 'eqexeq-dl-dotted'] : chain-rule
equal ~> {'equal.fc'}
exclam ~> {'neq.1m-dotted'}
equal ~> {'equal.cc+cf'}
[hasLG 'eqexeq-dl'] : chain-rule
equal ~> {'equal.fc'}
exclam ~> {'neq.1m'}
exclam ~> {'neq.allow-dot.1m'}
equal ~> {'equal.cc+cf'}
true : chain-rule
AnyEqualEnding ~> look-around
exclam ~> advance
equal ~> look-around
piecewise
[hasLG 'exeq-dotted'] : chain-rule
exclam ~> {'neq.4l-dotted'}
equal ~> {'equal.fc+cc'}
equal ~> {'equal.cc'}
equal ~> {'equal.cf'}
[hasLG 'exeq'] : chain-rule
exclam ~> {'neq.4l'}
exclam ~> {'neq.allow-dot.4l'}
equal ~> {'equal.fc+cc'}
equal ~> {'equal.cc'}
equal ~> {'equal.cf'}
@ -781,30 +768,22 @@ define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] :
equal ~> {'equal.cc'}
equal ~> {'equal.cf'}
piecewise
[hasLG 'exeqeq-dotted'] : chain-rule
exclam ~> {'neq.3l-dotted'}
equal ~> {'ident.fc+cc'}
equal ~> {'ident.cf'}
[hasLG 'exeqeq'] : chain-rule
exclam ~> {'neq.3l'}
exclam ~> {'neq.allow-dot.3l'}
equal ~> {'ident.fc+cc'}
equal ~> {'ident.cf'}
[hasLG 'exeq-dotted'] : chain-rule
exclam ~> {'neq.3l-dotted'}
equal ~> {'equal.fc+cc'}
equal ~> {'equal.cf'}
[hasLG 'exeq'] : chain-rule
exclam ~> {'neq.3l'}
exclam ~> {'neq.allow-dot.3l'}
equal ~> {'equal.fc+cc'}
equal ~> {'equal.cf'}
piecewise
[hasLG 'eqslasheq'] : chain-rule
equal ~> {'ident.fc'}
slash ~> {'neq.1m'}
slash ~> {'neq.bar-only.1m'}
equal ~> {'ident.cc+cf'}
[hasLG 'slasheq'] : chain-rule
equal ~> {'equal.fc'}
slash ~> {'neq.1m'}
slash ~> {'neq.bar-only.1m'}
equal ~> {'equal.cc+cf'}
piecewise
[hasLG 'eqeqeq'] : chain-rule
@ -813,25 +792,22 @@ define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] :
equal ~> {'ident.cf'}
piecewise
[hasLG 'tildeeq'] : chain-rule
anyWave ~> [just 'neq.2l']
anyWave ~> [just 'neq.bar-only.2l']
equal ~> {'equal.fc+cf'}
piecewise
[hasLG 'slasheq'] : chain-rule
slash ~> {'neq.2l'}
slash ~> {'neq.bar-only.2l'}
equal ~> {'equal.fc+cf'}
piecewise
[hasLG 'exeq-dotted'] : chain-rule
exclam ~> {'neq.2l-dotted'}
equal ~> {'equal.fc+cf'}
[hasLG 'exeq'] : chain-rule
exclam ~> {'neq.2l'}
exclam ~> {'neq.allow-dot.2l'}
equal ~> {'equal.fc+cf'}
piecewise
[hasLG 'ltgt-diamond'] : chain-rule
lessAndEquiv ~> [just 'less.lig.diamond']
greaterAndEquiv ~> [just 'greater.lig.diamond']
[hasLG 'ltgt-ne'] : chain-rule
lessAndEquiv ~> [just 'neq.2l']
lessAndEquiv ~> [just 'neq.bar-only.2l']
greaterAndEquiv ~> [just 'equal.fc+cf']
piecewise
[hasLG 'eqeq'] : chain-rule

View file

@ -168,6 +168,17 @@ export const Joining = {
}
};
export const NeqLigationSlashDotted = {
get(glyph) {
if (glyph && glyph.related) return !!glyph.related.neqLigationSlashDotted;
else return false;
},
set(glyph) {
if (!glyph.related) glyph.related = {};
glyph.related.neqLigationSlashDotted = true;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////
const CvTagCache = new Map();
@ -452,4 +463,9 @@ export function hashCv(g) {
///////////////////////////////////////////////////////////////////////////////////////////////////
export const SvInheritableRelations = [RightDependentLink, RightDependentTrigger, Joining];
export const SvInheritableRelations = [
RightDependentLink,
RightDependentTrigger,
Joining,
NeqLigationSlashDotted
];

View file

@ -75,7 +75,7 @@ class Prime {
this.description = cfg.description || null;
this.ligatureSampler = / /.test(cfg.sampler || "");
this.descSampleText = this.ligatureSampler
? cfg.sampler.split(" ")
? cfg.sampler.split(" ").filter(x => !!x.trim())
: [...(cfg.sampler || "")];
this.tag = cfg.tag;
this.slopeDependent = !!cfg.slopeDependent;

View file

@ -40,45 +40,21 @@ samples = ["!=="]
sampleRank = 3
desc = 'Enable special ligation for `!==` with triple lines'
[simple.exeqeq-dotted]
ligGroup = "exeqeq-dotted"
samples = ["!=="]
sampleRank = 4
desc = 'Enable special ligation for `!==` with triple lines, and a dot at below for distinction'
[simple.eqexeq]
ligGroup = "eqexeq"
samples = ["=!="]
desc = 'Enable special ligation for `=!=` with triple lines'
[simple.eqexeq-dotted]
ligGroup = "eqexeq-dotted"
samples = ["=!="]
sampleRank = 2
desc = 'Enable special ligation for `=!=` with triple lines and a dot at below for distinction'
[simple.eqexeq-dl]
ligGroup = "eqexeq-dl"
samples = ["=!="]
desc = 'Enable special ligation for `=!=` with double lines'
[simple.eqexeq-dl-dotted]
ligGroup = "eqexeq-dl-dotted"
samples = ["=!="]
sampleRank = 2
desc = 'Enable special ligation for `=!=` with double lines, and a dot at below for distinction'
[simple.exeq]
ligGroup = "exeq"
samples = ["!=", "!=="]
desc = 'Enable ligation for `!=` and `!==`'
[simple.exeq-dotted]
ligGroup = "exeq-dotted"
samples = ["!=", "!=="]
rank = 2
desc = 'Enable ligation for `!=` and `!==` with a dot at below for distinction'
[simple.tildeeq]
ligGroup = "tildeeq"
samples = ["~="]

View file

@ -6523,6 +6523,7 @@ selector."bar.slanted" = "forceUpright"
[prime.lig-ltgteq]
sampler = "<= >="
samplerExplain = "Less-equal and Greater-equal ligations"
tag = "cv95"
[prime.lig-ltgteq.variants.flat]
@ -6633,6 +6634,49 @@ selector.diacriticDot = "square"
[prime.lig-neq]
sampler = "!= "
samplerExplain = "Not-equal ligations"
tag = "VXAF"
[prime.lig-neq.variants.vertical]
rank = 1
description = "The bar in inequality (`!=`, etc.) ligation is vertical"
selector."neq.allow-dot" = "vertical"
selector."neq.bar-only" = "vertical"
[prime.lig-neq.variants.slightly-slanted]
rank = 2
description = "The bar in inequality (`!=`, etc.) ligation is slightly slanted"
selector."neq.allow-dot" = "slightlySlanted"
selector."neq.bar-only" = "slightlySlanted"
[prime.lig-neq.variants.more-slanted]
rank = 3
description = "The bar in inequality (`!=`, etc.) ligation is more slanted"
selector."neq.allow-dot" = "moreSlanted"
selector."neq.bar-only" = "moreSlanted"
[prime.lig-neq.variants.vertical-dotted]
rank = 4
description = "The bar in inequality (`!=`, etc.) ligation is vertical, and with a dot at bottom for ligations built from exclamation sign (`!`)"
selector."neq.allow-dot" = "verticalDotted"
selector."neq.bar-only" = "vertical"
[prime.lig-neq.variants.slightly-slanted-dotted]
rank = 5
description = "The bar in inequality (`!=`, etc.) ligation is slightly slanted, and with a dot at bottom for ligations built from exclamation sign (`!`)"
selector."neq.allow-dot" = "slightlySlantedDotted"
selector."neq.bar-only" = "slightlySlanted"
[prime.lig-neq.variants.more-slanted-dotted]
rank = 6
description = "The bar in inequality (`!=`, etc.) ligation is more slanted, and with a dot at bottom for ligations built from exclamation sign (`!`)"
selector."neq.allow-dot" = "moreSlantedDotted"
selector."neq.bar-only" = "moreSlanted"
# This is a special variant selector that controls digit form
[prime.digit-form]
isSpecial = true
@ -6766,6 +6810,7 @@ ascii-grave = "straight"
question = "smooth"
punctuation-dot = "round"
diacritic-dot = "round"
lig-neq = "slightly-slanted"
# m, n, h has tailed variant, but not very ideal
# Do not make them default