Implement leaning mark mechanism for F, L, P, b, d, h, k, p, q, r to get better mark placement. Now, "narrow" marks will align to these letters' extension parts (#1851).

This commit is contained in:
be5invis 2023-08-12 23:01:10 -07:00
parent 387389919c
commit f7fd09172b
33 changed files with 419 additions and 168 deletions

View file

@ -1,6 +1,7 @@
* Add characters: * Add characters:
- CLOCK FACE ONE OCLOCK (`U+1F550`) ... CLOCK FACE TWELVE-THIRTY (`U+1F567`) (#1850). - CLOCK FACE ONE OCLOCK (`U+1F550`) ... CLOCK FACE TWELVE-THIRTY (`U+1F567`) (#1850).
* Implement leaning mark mechanism for `F`, `L`, `P`, `b`, `d`, `h`, `k`, `p`, `q`, `r` to get better mark placement. Now, "narrow" marks will align to these letters' extension parts (#1851).
* Fix detached cedilla in Hookless asymmetric LATIN SMALL LETTER T WITH CEDILLA (`U+0163`) (#1914). * Fix detached cedilla in Hookless asymmetric LATIN SMALL LETTER T WITH CEDILLA (`U+0163`) (#1914).
* Fix broken hookless/tailless/assymetric t variants in ſt ligature (`U+FB05`) (#1915). * Fix broken hookless/tailless/asymmetric t variants in ſt ligature (`U+FB05`) (#1915).
* Remove unnecessary tailed variants for Cyrillic Shha with Descender (`U+0527`) (#1916). * Remove unnecessary tailed variants for Cyrillic Shha with Descender (`U+0527`) (#1916).
* Remove unnecessary lower-right serif variants for Latin Lower K with Descender (`U+2C6A`) (#1917). * Remove unnecessary lower-right serif variants for Latin Lower K with Descender (`U+2C6A`) (#1917).

View file

@ -21,7 +21,7 @@ function assignSubRank(glyphStore) {
// "Fixed" subfamilies are properly built. // "Fixed" subfamilies are properly built.
function validateMonospace(para, glyphStore) { function validateMonospace(para, glyphStore) {
let awSet = new Set(); let awSet = new Set();
for (const [u, g] of glyphStore.encodedEntries()) { for (const [u, n, g] of glyphStore.encodedEntries()) {
const aw = Math.round(g.advanceWidth || 0); const aw = Math.round(g.advanceWidth || 0);
if (aw > 0) awSet.add(aw); if (aw > 0) awSet.add(aw);
} }

View file

@ -1,4 +1,4 @@
import { Joining, AnyCv, TieMark, Nwid, Wwid } from "../../support/gr.mjs"; import { Joining, AnyCv, TieMark, Nwid, Wwid, VS01 } from "../../support/gr.mjs";
const ApplePostNames = new Map([ const ApplePostNames = new Map([
/* spell-checker: disable */ /* spell-checker: disable */
@ -286,14 +286,18 @@ export function bySpacing(gSrcBase, gOtBase, internalNameMap, conflictSet) {
return n; return n;
} }
const NamingGr = [TieMark, VS01];
export function byGr(gSrcBase, gOtBase, internalNameMap, conflictSet) { export function byGr(gSrcBase, gOtBase, internalNameMap, conflictSet) {
if (!gOtBase.name) return 0; if (!gOtBase.name) return 0;
let n = 0; let n = 0;
for (const cv of AnyCv.query(gSrcBase)) { for (const cv of AnyCv.query(gSrcBase)) {
n += nameByGr(cv, gSrcBase, gOtBase, internalNameMap, conflictSet); n += nameByGr(cv, gSrcBase, gOtBase, internalNameMap, conflictSet);
} }
if (TieMark.get(gSrcBase)) { for (const gr of NamingGr) {
n += nameByGr(TieMark, gSrcBase, gOtBase, internalNameMap, conflictSet); if (gr.get(gSrcBase)) {
n += nameByGr(gr, gSrcBase, gOtBase, internalNameMap, conflictSet);
}
} }
return n; return n;
} }

View file

@ -1,10 +1,13 @@
###### Automatic builds ###### Automatic builds
$$include '../../meta/macros.ptl' $$include '../../meta/macros.ptl'
import [Dotless AnyDerivingCv DotlessOrNot getGrTree CvDecompose] from"../../support/gr.mjs" import [Dotless AnyDerivingCv DotlessOrNot getGrTree CvDecompose LeaningMark LeaningMarkSpacer] from"../../support/gr.mjs"
import [fallback] from"../../support/utils.mjs" import [fallback ArrayUtil MatchUtil constant] from"../../support/utils.mjs"
import as UnicodeKnowledge from"../../meta/unicode-knowledge.mjs" import as UnicodeKnowledge from"../../meta/unicode-knowledge.mjs"
extern Map
extern Set
glyph-module glyph-module
glyph-block AutoBuild-Accents : begin glyph-block AutoBuild-Accents : begin
@ -24,42 +27,150 @@ glyph-block AutoBuild-Accents : begin
set map.(key) amended set map.(key) amended
return amended return amended
# Build accented glyphs # Here, we build a simplified substitution builder that does the mark substitutions
define [isAboveMark mark] : begin define [substParts parts ignore backtrack input loookAhead production] : begin
return : mark && mark.markAnchors && mark.markAnchors.above local igl 0
while (igl < parts.length) : begin
local m : substMatch parts igl ignore backtrack input loookAhead
if [not m]
: then : inc igl
: else : begin
local inputGlyphs : ArrayUtil.mapIndexToItems parts m
local producedGlyphs : production.apply null inputGlyphs
foreach i [range (m.length - 1) downtill 0] : begin
parts.splice m.(i) 1
ArrayUtil.insertSliceAt parts m.0 producedGlyphs
set igl : m.(m.length - 1) + 1 + producedGlyphs.length - m.length
define [MarkSubst lookup] : function [p j parts] : begin return parts
foreach { k v } [Object.entries lookup] : begin
if (p === [query-glyph k]) : set parts.(j) [query-glyph v]
define iotaBelowToLF : MarkSubst UnicodeKnowledge.iotaBelowToLfTf define [substMatch parts igl ignore backtrack input lookAhead] : begin
define ogonekBelowToTR : MarkSubst UnicodeKnowledge.ogonekBelowToTRTf if (igl >= parts.length) : return null
define grekUpperTonos : MarkSubst UnicodeKnowledge.upperGrekMarkToTonosTf if [ignore parts.(igl)] : return null
if [not : input.0 parts.(igl)] : return null
local m { igl }
# Check input
local iglInput : igl + 1
foreach iInput [range 1 input.length] : begin
while (iglInput < parts.length && [ignore parts.(iglInput)]) : inc iglInput
if (iglInput >= parts.length) : return null
if [not : input.(iInput) parts.(iglInput)] : return null
m.push iglInput
inc iglInput
# Check lookahead
local iglLookAhead iglInput
foreach iLookAhead [range 0 lookAhead.length] : begin
while (iglLookAhead < parts.length && [ignore parts.(iglLookAhead)]) : inc iglLookAhead
if (iglLookAhead >= parts.length) : return null
if [not : lookAhead.(iLookAhead) parts.(iglLookAhead)] : return null
inc iglLookAhead
# Check backtrack
local iglBacktrack : igl - 1
foreach iBacktrack [range (backtrack.length - 1) downtill 0] : begin
while (iglBacktrack >= 0 && [ignore parts.(iglBacktrack)]) : dec iglBacktrack
if (iglBacktrack < 0) : return null
if [not : backtrack.(iBacktrack) parts.(iglBacktrack)] : return null
dec iglBacktrack
return m
define [dotless g] : begin
local gDotless : query-glyph : Dotless.get g
if [not gDotless] : return null
return {gDotless}
define [isMark k] : function [g] : begin
return : g && g.markAnchors && g.markAnchors.(k)
define [isMarkExcluding k] : function [g] : begin
return : g && g.markAnchors && [Object.keys g.markAnchors].length && !g.markAnchors.(k)
define [hasBaseAnchor k] : function [g] : begin
return : g && g.baseAnchors && g.baseAnchors.(k)
define [isLeaningMark k] : function [g] : begin
return : g && g.markAnchors && g.markAnchors.(k) && [LeaningMark.get g]
define [leaningMarkSplit g] : begin
local spacer : query-glyph : LeaningMarkSpacer.get g
local alternative : query-glyph : LeaningMark.get g
if (spacer && alternative) : return { spacer alternative }
return { g }
define [markSubst uk] : begin
local fromGlyphs : new Set
local mapping : new Map
foreach { k v } [Object.entries uk] : begin
local gFrom : query-glyph k
local gTo : query-glyph v
if (gFrom && gTo) : begin
fromGlyphs.add gFrom
mapping.set gFrom gTo
define [matcher g] : fromGlyphs.has g
define [ignore g] : g && g.markAnchors && [Object.keys g.markAnchors].length && ![matcher g]
define [production g] : list ([mapping.get g] || g)
return : object matcher ignore production
define [markCombine uk] : begin
local first : new Set
local second : new Set
local mapping : new Map
foreach { k1 m } [Object.entries uk] : begin
foreach { k2 v } [Object.entries m] : begin
local g1 : query-glyph k1
local g2 : query-glyph k2
local g3 : query-glyph v
if (g1 && g2 && g3) : begin
first.add g1
second.add g2
local mm : mapping.get g1
if [not mm] : begin
set mm : new Map
mapping.set g1 mm
mm.set g2 g3
define [matchFirst g] : first.has g
define [matchSecond g] : second.has g
define [production g1 g2] : begin
local mm : mapping.get g1
if [not mm] : return { g1 g2 }
local g3 : mm.get g2
if [not g3] : return { g1 g2 }
return { g3 }
return : object matchFirst matchSecond production
define iotaLF : markSubst UnicodeKnowledge.iotaBelowToLfTf
define ogonek : markSubst UnicodeKnowledge.ogonekBelowToTRTf
define upperTonos : markSubst UnicodeKnowledge.upperGrekMarkToTonosTf
define markComposition : markCombine UnicodeKnowledge.markCompositionTf
define [subParts parts] : begin define [subParts parts] : begin
# Keep the semantics here synchronized with `ccmp` feature ### Keep the semantics here synchronized with `ccmp` feature
# Handle dotless
local hasMarkAbove false
foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true
if (hasMarkAbove && [Dotless.get parts.0]) : begin
local dotless [query-glyph : Dotless.get parts.0]
if dotless : set parts.0 dotless
# replace below marks with trailing marks # Handle dotless form
if parts.0.baseAnchors.lf : parts.forEach iotaBelowToLF substParts parts [isMarkExcluding 'above'] {} {dotless} {[isMark 'above']} dotless
if parts.0.baseAnchors.trailing : parts.forEach ogonekBelowToTR
# composite greek Marks # Handle iota subscript
for [local j 0] (j < parts.length) [inc j] : begin substParts parts iotaLF.ignore {[hasBaseAnchor 'lf']} {iotaLF.matcher} {} iotaLF.production
foreach { gidFirst seconds } [Object.entries UnicodeKnowledge.markCompositionTf]
if (parts.(j) === [query-glyph gidFirst])
foreach { gidSecond gidTo } [Object.entries seconds]
if (parts.(j + 1) === [query-glyph gidSecond]) : begin
set parts.(j) [query-glyph gidTo]; set parts.(j + 1) null
if parts.0.baseAnchors.grekUpperTonos : grekUpperTonos parts.1 1 parts # Handle ogonek
substParts parts ogonek.ignore {[hasBaseAnchor 'trailing']} {ogonek.matcher} {} ogonek.production
return : parts.filter : function [x] [not : not x] # Handle leaning marks
substParts parts [isMarkExcluding 'above'] {[MatchUtil.either [hasBaseAnchor 'leaningAbove'] [isMark 'leaningAbove']]} {[isLeaningMark 'above']} {} leaningMarkSplit
substParts parts [isMarkExcluding 'below'] {[MatchUtil.either [hasBaseAnchor 'leaningBelow'] [isMark 'leaningBelow']]} {[isLeaningMark 'below']} {} leaningMarkSplit
# Handle mark combinations (Greek)
substParts parts MatchUtil.never {} { markComposition.matchFirst markComposition.matchSecond } {} markComposition.production
# Handle upper Greek Tonos marks
substParts parts MatchUtil.never {[hasBaseAnchor 'grekUpperTonos']} {upperTonos.matcher} {} upperTonos.production
define [pad _s n] : begin define [pad _s n] : begin
local s _s local s _s
@ -96,7 +207,7 @@ glyph-block AutoBuild-Accents : begin
if (allFound && parts.length) : begin if (allFound && parts.length) : begin
local glyphName : 'u' + [code.toString 16 :.padStart 4 '0'] local glyphName : 'u' + [code.toString 16 :.padStart 4 '0']
set parts : subParts parts subParts parts
set foundDecompositions.(glyphName) { glyphName code parts } set foundDecompositions.(glyphName) { glyphName code parts }
local s_goalName nothing local s_goalName nothing

View file

@ -3,29 +3,76 @@ $$include '../../meta/macros.ptl'
import [Arcs Quadify ShapeConv] from "typo-geom" import [Arcs Quadify ShapeConv] from "typo-geom"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs" import [TieMark AnyDerivingCv ScheduleLeaningMark LeaningMark LeaningMarkSpacer] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
extern Set
glyph-module glyph-module
glyph-block Mark-Doppelganger : if [not recursive] : begin glyph-block Mark-Doppelganger : if [not recursive] : begin
glyph-block-import CommonShapes glyph-block-import CommonShapes
glyph-block-import Common-Derivatives glyph-block-import Common-Derivatives
define AnchorMap : list define [DeriveMarkChange gr gn akFrom akTo] : begin
list 'above' 'tieAbove' DeriveMeshT {gn} AnyDerivingCv : function [gns] : begin
list 'below' 'tieBelow' local srcGn gns.0
local src : query-glyph srcGn
foreach { gn g } [glyphStore.namedEntries] : begin local toGN : gr.amendName srcGn
local handled false if [not : query-glyph toGN] : begin
foreach { akFrom akTo } [items-of AnchorMap] : begin
if (!handled && g.markAnchors && g.markAnchors.(akFrom)) : begin
set handled true
local toGN : TieMark.amendName gn
create-glyph toGN : glyph-proc create-glyph toGN : glyph-proc
include g AS_BASE ALSO_METRICS include [refer-glyph srcGn] AS_BASE ALSO_METRICS
set currentGlyph.markAnchors.(akTo) currentGlyph.markAnchors.(akFrom) set currentGlyph.markAnchors.(akTo) currentGlyph.markAnchors.(akFrom)
currentGlyph.deleteMarkAnchor akFrom currentGlyph.deleteMarkAnchor akFrom
set currentGlyph.baseAnchors.(akTo) currentGlyph.baseAnchors.(akFrom) set currentGlyph.baseAnchors.(akTo) currentGlyph.baseAnchors.(akFrom)
currentGlyph.deleteBaseAnchor akFrom currentGlyph.deleteBaseAnchor akFrom
TieMark.set g toGN gr.set src toGN
return toGN
local spacerGlyphSet : new Set
define TieAnchorMap : list
list 'above' 'tieAbove'
list 'below' 'tieBelow'
do : foreach { u gn g } [glyphStore.encodedEntries] : DeriveTieMarks gn g
: where : [DeriveTieMarks gn g] : begin
local selection null
foreach { akFrom akTo } [items-of TieAnchorMap] : begin
if (!selection && g.markAnchors.(akFrom)) : begin
set selection { akFrom akTo }
if selection : begin
local { akFrom akTo } selection
DeriveMarkChange TieMark gn akFrom akTo
define LeaningAnchorMap : list
list 'above' 'leaningAbove'
list 'below' 'leaningBelow'
do : foreach { u gn g } [glyphStore.encodedEntries] : DeriveLeaningMark gn g
: where : [DeriveLeaningMark gn g] : begin
local selection null
foreach { akFrom akTo } [items-of LeaningAnchorMap] : begin
if (!selection && g.markAnchors.(akFrom) && [ScheduleLeaningMark.get g]) : begin
set selection { akFrom akTo }
if selection : begin
local { akFrom akTo } selection
# Build the doppelganger
DeriveMarkChange LeaningMark gn akFrom akTo
# build spacer glyph
local deltaX : Math.round : g.baseAnchors.(akFrom).x - g.markAnchors.(akFrom).x
local deltaY : Math.round : g.baseAnchors.(akFrom).y - g.markAnchors.(akFrom).y
local spacerGn "spacerGlyph{\(akTo)}{\(deltaX)}{\(deltaY)}"
LeaningMarkSpacer.set g spacerGn
if [not : spacerGlyphSet.has spacerGn] : begin
spacerGlyphSet.add spacerGn
create-glyph spacerGn : glyph-proc
include g AS_BASE ALSO_METRICS
currentGlyph.clearGeometry

View file

@ -48,7 +48,9 @@ glyph-block Common-Derivatives : begin
alias name unicode (name + '.upright') alias name unicode (name + '.upright')
glyph-block-export query-glyph glyph-block-export query-glyph
define [query-glyph id] : return : glyphStore.queryByName id define [query-glyph id] : begin
if [not id] : return nothing
return : glyphStore.queryByName id
glyph-block-export refer-glyph glyph-block-export refer-glyph
define [refer-glyph id] : lambda [copyAnchors copyWidth] : begin define [refer-glyph id] : lambda [copyAnchors copyWidth] : begin

View file

@ -22,6 +22,7 @@ glyph-block Letter-Cyrillic-Che : begin
define SLAB-TAILED-BGR 6 define SLAB-TAILED-BGR 6
define [CyrCheShape top pyBar bodyType slabType] : glyph-proc define [CyrCheShape top pyBar bodyType slabType] : glyph-proc
set-base-anchor 'leaningBelow' (RightSB - [HSwToV HalfStroke]) 0
local bar : top * [fallback pyBar 0.5] local bar : top * [fallback pyBar 0.5]
include : match bodyType include : match bodyType
[Just BODY-TAILED] : RightwardTailedBar RightSB 0 top [Just BODY-TAILED] : RightwardTailedBar RightSB 0 top

View file

@ -23,6 +23,7 @@ glyph-block Letter-Greek-Upper-Gamma: begin
define GammaBarLeft (SB * 1.5) define GammaBarLeft (SB * 1.5)
define [GammaShape top slabType] : glyph-proc define [GammaShape top slabType] : glyph-proc
set-base-anchor 'leaningBelow' (GammaBarLeft + [HSwToV HalfStroke]) 0
include : VBar.l GammaBarLeft 0 top include : VBar.l GammaBarLeft 0 top
include : HBar.t (GammaBarLeft - O) (RightSB - OX) top include : HBar.t (GammaBarLeft - O) (RightSB - OX) top
match slabType match slabType

View file

@ -503,15 +503,12 @@ glyph-block Letter-Latin-K : begin
if slabLT : include : HSerif.lt (SB + [KBalance slabLT straightBar]) Ascender SideJut if slabLT : include : HSerif.lt (SB + [KBalance slabLT straightBar]) Ascender SideJut
if slabLB : include : tagged 'serifLB' if slabLB : include : tagged 'serifLB'
HSerif.mb (SB + [KBalance slabLT straightBar] + [HSwToV HalfStroke]) 0 Jut HSerif.mb (SB + [KBalance slabLT straightBar] + [HSwToV HalfStroke]) 0 Jut
set-base-anchor 'leaningAbove' (SB + [KBalance slabLT straightBar] + [HSwToV HalfStroke]) Ascender
create-glyph "k.\(suffix)" : glyph-proc create-glyph "k.\(suffix)" : glyph-proc
include : MarkSet.b include : MarkSet.b
include : kBaseShape include : kBaseShape
create-glyph "k/circumflexBase.\(suffix)" : glyph-proc
include [refer-glyph "k.\(suffix)"] AS_BASE ALSO_METRICS
set-base-anchor 'above' (SB + [KBalance slabLT straightBar] + [HSwToV HalfStroke]) Ascender
create-glyph "kDescender.\(suffix)" : glyph-proc create-glyph "kDescender.\(suffix)" : glyph-proc
include : MarkSet.b include : MarkSet.b
include : kBaseShape CyrDescender include : kBaseShape CyrDescender
@ -550,7 +547,6 @@ glyph-block Letter-Latin-K : begin
select-variant 'k' 'k' select-variant 'k' 'k'
select-variant 'k/nonCursive' (shapeFrom -- 'k') select-variant 'k/nonCursive' (shapeFrom -- 'k')
select-variant 'k/circumflexBase' (follow -- 'k')
link-reduced-variant 'k/sansSerif' 'k' MathSansSerif link-reduced-variant 'k/sansSerif' 'k' MathSansSerif
select-variant 'kDescender' 0x2C6A select-variant 'kDescender' 0x2C6A
select-variant 'kPalatalHook' 0x1D84 (follow -- 'kDescender') select-variant 'kPalatalHook' 0x1D84 (follow -- 'kDescender')
@ -578,11 +574,6 @@ glyph-block Letter-Latin-K : begin
derive-composites 'KBarLegStroke' 0xA744 'KBar' 'legSlashOver' derive-composites 'KBarLegStroke' 0xA744 'KBar' 'legSlashOver'
derive-composites 'kBarLegStroke' 0xA745 'kBar' 'legSlashOver' derive-composites 'kBarLegStroke' 0xA745 'kBar' 'legSlashOver'
derive-glyphs 'kCaron' 0x1E9 'k/circumflexBase' : lambda [src gr] : glyph-proc
local shift : Width + SB - Middle + [HSwToV HalfStroke]
include [refer-glyph src] AS_BASE ALSO_METRICS
include [refer-glyph "caronAbove"]
turned 'turnK' 0xA7B0 'K' Middle (CAP / 2) turned 'turnK' 0xA7B0 'K' Middle (CAP / 2)
turned 'turnk' 0x29E 'k' Middle (XH / 2) [MarkSet.p] turned 'turnk' 0x29E 'k' Middle (XH / 2) [MarkSet.p]
turned 'turnSmcpK' 0x1DF10 'smcpK' Middle (XH / 2) turned 'turnSmcpK' 0x1DF10 'smcpK' Middle (XH / 2)

View file

@ -45,6 +45,7 @@ glyph-block Letter-Latin-Lower-B : begin
include : Serifs include : Serifs
set-base-anchor 'overlayOnExtension' (SB + [HSwToV : 0.5 * Stroke]) yOverlay set-base-anchor 'overlayOnExtension' (SB + [HSwToV : 0.5 * Stroke]) yOverlay
set-base-anchor 'overlay' Middle (XH / 2) set-base-anchor 'overlay' Middle (XH / 2)
set-base-anchor 'leaningAbove' (SB + [HSwToV HalfStroke]) Ascender
create-glyph "bBar.\(suffix)" : glyph-proc create-glyph "bBar.\(suffix)" : glyph-proc
include [refer-glyph "b.\(suffix)"] AS_BASE ALSO_METRICS include [refer-glyph "b.\(suffix)"] AS_BASE ALSO_METRICS
@ -86,8 +87,9 @@ glyph-block Letter-Latin-Lower-B : begin
derive-multi-part-glyphs 'bDot' 0x1E03 {'b' 'dotAbove'} : lambda [srcs gr] : glyph-proc derive-multi-part-glyphs 'bDot' 0x1E03 {'b' 'dotAbove'} : lambda [srcs gr] : glyph-proc
local { base mark } srcs local { base mark } srcs
include : refer-glyph mark include : refer-glyph mark
include : Translate (Width + HalfStroke) 0 include : Translate (Width + [HSwToV HalfStroke]) 0
include [refer-glyph base] AS_BASE include [refer-glyph base] AS_BASE
set-base-anchor 'leaningAbove' (Middle + [HSwToV HalfStroke]) Ascender
glyph-block-import Letter-Blackboard : BBS BBD BBBarLeft glyph-block-import Letter-Blackboard : BBS BBD BBBarLeft
create-glyph 'mathbb/b' 0x1D553 : glyph-proc create-glyph 'mathbb/b' 0x1D553 : glyph-proc

View file

@ -96,6 +96,7 @@ glyph-block Letter-Latin-Lower-D : begin
if topSerif : include : topSerif df Ascender if topSerif : include : topSerif df Ascender
if bottomSerif : include : bottomSerif df Ascender if bottomSerif : include : bottomSerif df Ascender
set-base-anchor 'overlayOnExtension' (df.rightSB - [HSwToV : 0.5 * Stroke]) yOverlay set-base-anchor 'overlayOnExtension' (df.rightSB - [HSwToV : 0.5 * Stroke]) yOverlay
set-base-anchor 'leaningAbove' (df.rightSB - [HSwToV HalfStroke]) Ascender
create-glyph "dcroat.\(suffix)" : glyph-proc create-glyph "dcroat.\(suffix)" : glyph-proc
local df : DivFrame 1 local df : DivFrame 1
@ -165,8 +166,9 @@ glyph-block Letter-Latin-Lower-D : begin
derive-multi-part-glyphs 'dDot' 0x1E0B {'d' 'dotAbove'} : lambda [srcs gr] : glyph-proc derive-multi-part-glyphs 'dDot' 0x1E0B {'d' 'dotAbove'} : lambda [srcs gr] : glyph-proc
local { base mark } srcs local { base mark } srcs
include : refer-glyph mark include : refer-glyph mark
include : Translate (Width - HalfStroke) 0 include : Translate (Width - [HSwToV HalfStroke]) 0
include [refer-glyph base] AS_BASE include [refer-glyph base] AS_BASE
set-base-anchor 'leaningAbove' (Middle - [HSwToV HalfStroke]) Ascender
derive-composites 'dBar' 0xA7C8 'd' derive-composites 'dBar' 0xA7C8 'd'
HBar.m (SB - OX) (RightSB + OX) (XH * 0.5) OverlayStroke HBar.m (SB - OX) (RightSB + OX) (XH * 0.5) OverlayStroke

View file

@ -1,7 +1,7 @@
$$include '../../../meta/macros.ptl' $$include '../../../meta/macros.ptl'
import [mix fallback SuffixCfg] from"../../../support/utils.mjs" import [mix fallback SuffixCfg] from"../../../support/utils.mjs"
import [Dotless CvDecompose MathSansSerif] from"../../../support/gr.mjs" import [ScheduleLeaningMark MathSansSerif] from"../../../support/gr.mjs"
glyph-module glyph-module
@ -57,6 +57,7 @@ glyph-block Letter-Latin-Lower-H : begin
foreach { suffix { fTailed {fHasTopSerif Serifs} } } [Object.entries HConfig] : do foreach { suffix { fTailed {fHasTopSerif Serifs} } } [Object.entries HConfig] : do
create-glyph "h.\(suffix)" : glyph-proc create-glyph "h.\(suffix)" : glyph-proc
include : MarkSet.b include : MarkSet.b
set-base-anchor 'leaningAbove' (SB + [HSwToV HalfStroke]) Ascender
include : VBar.l SB 0 Ascender include : VBar.l SB 0 Ascender
include : nShoulder include : nShoulder
left -- (SB + [HSwToV Stroke]) left -- (SB + [HSwToV Stroke])
@ -65,10 +66,6 @@ glyph-block Letter-Latin-Lower-H : begin
if fTailed : include : RightwardTailedBar RightSB 0 (XH - SmallArchDepthB) if fTailed : include : RightwardTailedBar RightSB 0 (XH - SmallArchDepthB)
include : Serifs fTailed false include : Serifs fTailed false
create-glyph "h/circumflexBase.\(suffix)" : glyph-proc
include [refer-glyph "h.\(suffix)"] AS_BASE ALSO_METRICS
set-base-anchor 'above' (SB + [HSwToV HalfStroke]) Ascender
create-glyph "hBar.\(suffix)" : glyph-proc create-glyph "hBar.\(suffix)" : glyph-proc
include [refer-glyph "h.\(suffix)"] AS_BASE ALSO_METRICS include [refer-glyph "h.\(suffix)"] AS_BASE ALSO_METRICS
include : HBar.mOverlay fHasTopSerif include : HBar.mOverlay fHasTopSerif
@ -125,19 +122,9 @@ glyph-block Letter-Latin-Lower-H : begin
select-variant 'h' 'h' select-variant 'h' 'h'
select-variant 'h/tailless' (shapeFrom -- 'h') select-variant 'h/tailless' (shapeFrom -- 'h')
select-variant 'h/circumflexBase' (follow -- 'h')
link-reduced-variant 'h/descBase' 'h' link-reduced-variant 'h/descBase' 'h'
link-reduced-variant 'h/sansSerif' 'h' MathSansSerif link-reduced-variant 'h/sansSerif' 'h' MathSansSerif
derive-glyphs 'hCircumflex' 0x125 'h/circumflexBase' : lambda [src gr] : glyph-proc
include [refer-glyph src] AS_BASE ALSO_METRICS
include [refer-glyph "circumflexAbove"]
derive-glyphs 'hCaron' 0x21F 'h/circumflexBase' : lambda [src gr] : glyph-proc
include [refer-glyph src] AS_BASE ALSO_METRICS
include [refer-glyph "caronAbove"]
select-variant 'hBar' 0x127 (follow -- 'h') select-variant 'hBar' 0x127 (follow -- 'h')
turned 'turnh' 0x265 'h/tailless' Middle (XH / 2) [MarkSet.p] turned 'turnh' 0x265 'h/tailless' Middle (XH / 2) [MarkSet.p]
@ -159,6 +146,7 @@ glyph-block Letter-Latin-Lower-H : begin
local { base mark } srcs local { base mark } srcs
include [refer-glyph base] AS_BASE ALSO_METRICS include [refer-glyph base] AS_BASE ALSO_METRICS
include : with-transform [ApparentTranslate [HSwToV HalfStroke] (XH - Ascender)] [refer-glyph mark] include : with-transform [ApparentTranslate [HSwToV HalfStroke] (XH - Ascender)] [refer-glyph mark]
set-base-anchor 'leaningAbove' (Middle + [HSwToV HalfStroke]) Ascender
derive-glyphs 'hCedilla' 0x1E29 'h' : lambda [src gr] : glyph-proc derive-glyphs 'hCedilla' 0x1E29 'h' : lambda [src gr] : glyph-proc
local shift : Width + SB - Middle + [HSwToV HalfStroke] local shift : Width + SB - Middle + [HSwToV HalfStroke]

View file

@ -51,6 +51,7 @@ glyph-block Letter-Latin-Lower-P : begin
include : Serifs XH include : Serifs XH
set-base-anchor 'overlayOnExtension' (SB + [HSwToV : 0.5 * Stroke]) yOverlay set-base-anchor 'overlayOnExtension' (SB + [HSwToV : 0.5 * Stroke]) yOverlay
set-base-anchor 'strike' Middle (XH / 2) set-base-anchor 'strike' Middle (XH / 2)
set-base-anchor 'leaningBelow' (SB + [HSwToV HalfStroke]) Descender
create-glyph "thorn.\(suffix)" : glyph-proc create-glyph "thorn.\(suffix)" : glyph-proc
include : MarkSet.bp include : MarkSet.bp

View file

@ -77,6 +77,7 @@ glyph-block Letter-Latin-Lower-Q : begin
include : Body terminal XH Descender include : Body terminal XH Descender
if sRT : include : sRT XH if sRT : include : sRT XH
if sRB : include : sRB Descender if sRB : include : sRB Descender
set-base-anchor 'leaningBelow' (RightSB - [HSwToV HalfStroke]) Descender
create-glyph "QRTail.\(suffix)" : glyph-proc create-glyph "QRTail.\(suffix)" : glyph-proc
include : MarkSet.capDesc include : MarkSet.capDesc

View file

@ -72,17 +72,17 @@ glyph-block Letter-Latin-Lower-R : begin
[Just rNarrowSerifed] : mix df.width rHookX df.div [Just rNarrowSerifed] : mix df.width rHookX df.div
[Just rNarrow] : xArchMiddle + 0.1 [Just rNarrow] : xArchMiddle + 0.1
__ rHookX __ rHookX
local [setMarks doTopSerif] : glyph-proc local [setMarks doTopSerif top bottom] : glyph-proc
set-base-anchor 'above' [mix [mix df.leftSB (xBar - [HSwToV Stroke]) : if doTopSerif 0.5 1] df.rightSB 0.5] XH set-base-anchor 'above' [mix [mix df.leftSB (xBar - [HSwToV Stroke]) : if doTopSerif 0.5 1] df.rightSB 0.5] top
set-base-anchor 'overlay' (xBar - Stroke * 0.25) (XH * 0.5) set-base-anchor 'leaningBelow' (xBar - [HSwToV HalfStroke]) bottom
set-base-anchor 'palatalHookAttach' xBar 0 set-base-anchor 'overlay' (xBar - Stroke * 0.25) [mix bottom top 0.5]
set-base-anchor 'palatalHookPos' (xBar + [PalatalHook.adviceGap Stroke]) 0 set-base-anchor 'palatalHookAttach' xBar bottom
set-base-anchor 'palatalHookPos' (xBar + [PalatalHook.adviceGap Stroke]) top
return : object xBar rBottomSerif rTopSerif fine xArchMiddle skew rHookX rHookXN rHookY hookSuperness setMarks return : object xBar rBottomSerif rTopSerif fine xArchMiddle skew rHookX rHookXN rHookY hookSuperness setMarks
define [StandardShape df md doTopSerif doBottomSerif] : glyph-proc define [StandardShape df md doTopSerif doBottomSerif] : glyph-proc
define [object xBar rBottomSerif rTopSerif fine xArchMiddle skew rHookX rHookY hookSuperness setMarks] : RDim df md define [object xBar rBottomSerif rTopSerif fine xArchMiddle skew rHookX rHookY hookSuperness] : RDim df md
include : setMarks doTopSerif
include : dispiro include : dispiro
widths.lhs widths.lhs
g4.up.start rHookX (XH - rHookY - Stroke * 0.5) [heading Upward] g4.up.start rHookX (XH - rHookY - Stroke * 0.5) [heading Upward]
@ -97,8 +97,7 @@ glyph-block Letter-Latin-Lower-R : begin
define [CompactShape df md ts bs] : CompactShapeImpl df md false ts bs define [CompactShape df md ts bs] : CompactShapeImpl df md false ts bs
define [CornerHookShape df md ts bs] : CompactShapeImpl df md true ts bs define [CornerHookShape df md ts bs] : CompactShapeImpl df md true ts bs
define [CompactShapeImpl df md doHookSerif doTopSerif doBottomSerif] : glyph-proc define [CompactShapeImpl df md doHookSerif doTopSerif doBottomSerif] : glyph-proc
define [object xBar rBottomSerif rTopSerif fine xArchMiddle rHookXN setMarks] : RDim df md define [object xBar rBottomSerif rTopSerif fine xArchMiddle rHookXN] : RDim df md
include : setMarks doTopSerif
define xCor : if doHookSerif 0 : CorrectionOMidS * [linreg 72 0.75 108 1 Stroke] define xCor : if doHookSerif 0 : CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]
define arcTopShift : match md define arcTopShift : match md
@ -126,8 +125,7 @@ glyph-block Letter-Latin-Lower-R : begin
if doTopSerif : include : rTopSerif XH if doTopSerif : include : rTopSerif XH
define [EarlessCornerShape df md doTopSerif doBottomSerif] : glyph-proc define [EarlessCornerShape df md doTopSerif doBottomSerif] : glyph-proc
define [object xBar xArchMiddle rHookX rHookY hookSuperness rBottomSerif setMarks] : RDim df md define [object xBar xArchMiddle rHookX rHookY hookSuperness rBottomSerif] : RDim df md
include : setMarks doTopSerif
include : dispiro include : dispiro
widths.lhs widths.lhs
g4.up.start rHookX (XH - rHookY - Stroke * 0.5) [heading Upward] g4.up.start rHookX (XH - rHookY - Stroke * 0.5) [heading Upward]
@ -138,8 +136,7 @@ glyph-block Letter-Latin-Lower-R : begin
if doBottomSerif : include : rBottomSerif 0 if doBottomSerif : include : rBottomSerif 0
define [EarlessRoundedShape df md doTopSerif doBottomSerif] : glyph-proc define [EarlessRoundedShape df md doTopSerif doBottomSerif] : glyph-proc
define [object xBar xArchMiddle rHookX rHookY hookSuperness rBottomSerif setMarks] : RDim df md define [object xBar xArchMiddle rHookX rHookY hookSuperness rBottomSerif] : RDim df md
include : setMarks doTopSerif
local hx : Math.max rHookX (xBar + 1.25 * Stroke) local hx : Math.max rHookX (xBar + 1.25 * Stroke)
include : dispiro include : dispiro
widths.lhs widths.lhs
@ -150,9 +147,8 @@ glyph-block Letter-Latin-Lower-R : begin
if doBottomSerif : include : rBottomSerif 0 if doBottomSerif : include : rBottomSerif 0
define [FlapHooklessShape df md doTopSerif doBottomSerif] : glyph-proc define [FlapHooklessShape df md doTopSerif doBottomSerif] : glyph-proc
define [object xBar rBottomSerif xArchMiddle setMarks] : RDim df md define [object xBar rBottomSerif xArchMiddle] : RDim df md
set-base-anchor 'overlay' (xBar - [HSwToV : 0.5 * Stroke]) (XH / 2) set-base-anchor 'overlay' (xBar - [HSwToV : 0.5 * Stroke]) (XH / 2)
include : setMarks doTopSerif
include : dispiro include : dispiro
widths.lhs widths.lhs
g4.left.start (xArchMiddle - CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]) (XH - O) g4.left.start (xArchMiddle - CorrectionOMidS * [linreg 72 0.75 108 1 Stroke]) (XH - O)
@ -184,12 +180,20 @@ glyph-block Letter-Latin-Lower-R : begin
create-glyph "r.\(suffix)" : glyph-proc create-glyph "r.\(suffix)" : glyph-proc
set-width df.width set-width df.width
include : df.markSet.e include : df.markSet.e
define [object setMarks] : RDim df mode
include : setMarks doTS XH 0
include : F df mode doTS doBS include : F df mode doTS doBS
currentGlyph.copyBaseAnchorIfAbsent 'leaningBelow' 'below'
create-glyph "rLongLeg.\(suffix)" : glyph-proc create-glyph "rLongLeg.\(suffix)" : glyph-proc
set-width df.width set-width df.width
include : df.markSet.p include : df.markSet.p
define [object xBar rBottomSerif] : RDim df mode
define [object xBar rBottomSerif setMarks] : RDim df mode
include : setMarks doTS XH Descender
include : F df mode doTS 0 include : F df mode doTS 0
eject-contour 'serifLB' eject-contour 'serifLB'
include : VBar.r xBar Descender 0 include : VBar.r xBar Descender 0
@ -230,11 +234,10 @@ glyph-block Letter-Latin-Lower-R : begin
include : RetroflexHook.rExt xBar 0 include : RetroflexHook.rExt xBar 0
create-glyph "rTurnRTail.\(suffix)" : glyph-proc create-glyph "rTurnRTail.\(suffix)" : glyph-proc
set-width df.width include [refer-glyph "r.\(suffix)"] AS_BASE ALSO_METRICS
include : df.markSet.e
include : F df mode 0 doBS
eject-contour 'serifLT' eject-contour 'serifLT'
include : FlipAround df.middle (XH / 2) include : FlipAround df.middle (XH / 2)
include : df.markSet.e
define [object xBar] : RDim df mode define [object xBar] : RDim df mode
include : RetroflexHook.lExt (df.rightSB - xBar + df.leftSB) 0 include : RetroflexHook.lExt (df.rightSB - xBar + df.leftSB) 0

View file

@ -67,12 +67,12 @@ glyph-block Letter-Latin-Lower-T : begin
local g : include : HookShapeT dispiro df sym 0 top bot Stroke local g : include : HookShapeT dispiro df sym 0 top bot Stroke
local gEnd g.knots.(g.knots.length - 1) local gEnd g.knots.(g.knots.length - 1)
set-base-anchor 'bottomRight' gEnd.x gEnd.y
local xLeft : BarLeftPos df sym local xLeft : BarLeftPos df sym
set-base-anchor 'above' (xLeft + [HSwToV HalfStroke]) top set-base-anchor 'leaningAbove' (xLeft + [HSwToV HalfStroke]) top
set-base-anchor 'hooktopAttach' (xLeft + [HSwToV HalfStroke]) top set-base-anchor 'hooktopAttach' (xLeft + [HSwToV HalfStroke]) top
set-base-anchor 'below' [mix xLeft gEnd.x : StrokeWidthBlend 0.375 0.5] bot set-base-anchor 'below' [mix xLeft gEnd.x : StrokeWidthBlend 0.375 0.5] bot
set-base-anchor 'bottomRight' gEnd.x gEnd.y
set-base-anchor 'overlay' (g.knots.0.x + [HSwToV : 0.625 * Stroke]) (XH * 0.58) set-base-anchor 'overlay' (g.knots.0.x + [HSwToV : 0.625 * Stroke]) (XH * 0.58)
export : define [Retroflex df sym top bot] : Flat.Retroflex df sym top bot export : define [Retroflex df sym top bot] : Flat.Retroflex df sym top bot
@ -96,9 +96,9 @@ glyph-block Letter-Latin-Lower-T : begin
local gEnd g.rhsKnots.(g.rhsKnots.length - 1) local gEnd g.rhsKnots.(g.rhsKnots.length - 1)
set-base-anchor 'bottomRight' gEnd.x gEnd.y set-base-anchor 'leaningAbove' ([BarLeftPos df sym] + [HSwToV HalfStroke]) top
set-base-anchor 'above' ([BarLeftPos df sym] + [HSwToV HalfStroke]) top
set-base-anchor 'hooktopAttach' ([BarLeftPos df sym] + [HSwToV HalfStroke]) top set-base-anchor 'hooktopAttach' ([BarLeftPos df sym] + [HSwToV HalfStroke]) top
set-base-anchor 'bottomRight' gEnd.x gEnd.y
set-base-anchor 'overlay' (g.knots.0.x + [HSwToV : 0.125 * Stroke]) (XH * 0.58) set-base-anchor 'overlay' (g.knots.0.x + [HSwToV : 0.125 * Stroke]) (XH * 0.58)
export : define [Retroflex df sym top bot] : Flat.Retroflex df sym top bot export : define [Retroflex df sym top bot] : Flat.Retroflex df sym top bot
@ -147,7 +147,7 @@ glyph-block Letter-Latin-Lower-T : begin
flat xBarLeft [if (shape === RETROFLEX) (bot + Hook + HalfStroke) hd.y] flat xBarLeft [if (shape === RETROFLEX) (bot + Hook + HalfStroke) hd.y]
curl xBarLeft top [heading Upward] curl xBarLeft top [heading Upward]
set-base-anchor 'above' (xBarLeft + [HSwToV HalfStroke]) top set-base-anchor 'leaningAbove' (xBarLeft + [HSwToV HalfStroke]) top
set-base-anchor 'hooktopAttach' (xBarLeft + [HSwToV HalfStroke]) top set-base-anchor 'hooktopAttach' (xBarLeft + [HSwToV HalfStroke]) top
set-base-anchor 'topRight' xCrossRight Ascender set-base-anchor 'topRight' xCrossRight Ascender
set-base-anchor 'overlay' (xBarLeft + [HSwToV : 0.625 * Stroke]) (XH * 0.58) set-base-anchor 'overlay' (xBarLeft + [HSwToV : 0.625 * Stroke]) (XH * 0.58)
@ -172,7 +172,8 @@ glyph-block Letter-Latin-Lower-T : begin
include : HCrossBar.top xcl xcr yCrossBar include : HCrossBar.top xcl xcr yCrossBar
set-base-anchor 'overlay' (xLeft + [HSwToV HalfStroke]) (XH * 0.58) set-base-anchor 'overlay' (xLeft + [HSwToV HalfStroke]) (XH * 0.58)
set-base-anchor 'hooktopAttach' (xLeft + [HSwToV HalfStroke]) top set-base-anchor 'hooktopAttach' (xLeft + [HSwToV HalfStroke]) top
set-base-anchor 'below' (xLeft + [HSwToV HalfStroke]) bot set-base-anchor 'leaningAbove' (xLeft + [HSwToV HalfStroke]) top
set-base-anchor 'leaningBelow' (xLeft + [HSwToV HalfStroke]) bot
set-base-anchor 'bottomRight' xEnd (bot + Stroke) set-base-anchor 'bottomRight' xEnd (bot + Stroke)
set-base-anchor 'lTailHookAttach' xEnd (bot + Stroke) set-base-anchor 'lTailHookAttach' xEnd (bot + Stroke)
@ -202,6 +203,8 @@ glyph-block Letter-Latin-Lower-T : begin
set-width df.width set-width df.width
include : df.markSet.b include : df.markSet.b
include : Style.Body df sym top 0 include : Style.Body df sym top 0
currentGlyph.copyBaseAnchorIfAbsent 'leaningAbove' 'above'
currentGlyph.copyBaseAnchorIfAbsent 'leaningBelow' 'below'
create-glyph "t/phoneticLeft2.\(suffix)" : glyph-proc create-glyph "t/phoneticLeft2.\(suffix)" : glyph-proc
set-width df.width set-width df.width

View file

@ -27,6 +27,7 @@ glyph-block Letter-Latin-Upper-F : begin
define xFBarRight : Width - SB * 1.5 define xFBarRight : Width - SB * 1.5
define [FShape] : with-params [top pyBar serifLT serifLB serifV [stroke : AdviceStroke2 2 3 top]] : glyph-proc define [FShape] : with-params [top pyBar serifLT serifLB serifV [stroke : AdviceStroke2 2 3 top]] : glyph-proc
set-base-anchor 'leaningBelow' (xFBarLeft + [HSwToV : 0.5 * stroke]) 0
include : VBar.l (xFBarLeft) 0 top stroke include : VBar.l (xFBarLeft) 0 top stroke
include : HBar.t (xFBarLeft - O) RightSB top stroke include : HBar.t (xFBarLeft - O) RightSB top stroke
include : tagged 'crossBar' include : tagged 'crossBar'

View file

@ -16,6 +16,7 @@ glyph-block Letter-Latin-Upper-L : begin
define [LBarLeftX df] : df.leftSB * 1.5 define [LBarLeftX df] : df.leftSB * 1.5
define [LRightX df] : df.rightSB - 0.75 * OX define [LRightX df] : df.rightSB - 0.75 * OX
define [LShape df top sgr swv] : glyph-proc define [LShape df top sgr swv] : glyph-proc
set-base-anchor 'leaningAbove' ([LBarLeftX df] + [HSwToV : 0.5 * swv]) top
include : VBar.l [LBarLeftX df] 0 top swv include : VBar.l [LBarLeftX df] 0 top swv
include : HBar.b ([LBarLeftX df] - O) [LRightX df] 0 include : HBar.b ([LBarLeftX df] - O) [LRightX df] 0
if (sgr > 1) : begin if (sgr > 1) : begin

View file

@ -71,7 +71,7 @@ glyph-block Letter-Latin-Upper-P : begin
include : spiro-outline include : spiro-outline
PShapeOutlineKnots top mul bp overshoot sw offset PShapeOutlineKnots top mul bp overshoot sw offset
define [PShape] : with-params [top [mul PShape.defaultMul] [bp PShape.BarPos] [overshoot PShape.defaultOvershoot] [sw Stroke] [slab null] [withBar true]] : glyph-proc define [PShape] : with-params [top [mul PShape.defaultMul] [bp PShape.BarPos] [overshoot PShape.defaultOvershoot] [sw Stroke] [slab null] [withBar true] [setMark false]] : glyph-proc
include : dispiro [widths.rhs sw] [PShapeOutlineKnots top mul bp overshoot sw 0] include : dispiro [widths.rhs sw] [PShapeOutlineKnots top mul bp overshoot sw 0]
if withBar : include : tagged 'strokeL' : VBar.l (SB * mul) 0 top sw if withBar : include : tagged 'strokeL' : VBar.l (SB * mul) 0 top sw
if slab : include : slab top sw mul if slab : include : slab top sw mul
@ -141,6 +141,7 @@ glyph-block Letter-Latin-Upper-P : begin
create-glyph "P.\(suffix)" : glyph-proc create-glyph "P.\(suffix)" : glyph-proc
include : MarkSet.capital include : MarkSet.capital
set-base-anchor 'leaningBelow' (SB * PShape.defaultMul + [HSwToV HalfStroke]) 0
include : difference include : difference
PShape CAP (slab -- slabs) PShape CAP (slab -- slabs)
if fGap [PShape.OpenGap (top -- CAP) (bot -- [if fSlabBot Stroke 0])] [glyph-proc] if fGap [PShape.OpenGap (top -- CAP) (bot -- [if fSlabBot Stroke 0])] [glyph-proc]
@ -151,6 +152,7 @@ glyph-block Letter-Latin-Upper-P : begin
create-glyph "smcpP.\(suffix)" : glyph-proc create-glyph "smcpP.\(suffix)" : glyph-proc
include : MarkSet.e include : MarkSet.e
set-base-anchor 'leaningBelow' (SB * PShape.defaultMul + [HSwToV HalfStroke]) 0
include : difference include : difference
PShape XH (slab -- slabs) PShape XH (slab -- slabs)
if fGap [PShape.OpenGap (top -- XH) (bot -- [if fSlabBot Stroke 0])] [glyph-proc] if fGap [PShape.OpenGap (top -- XH) (bot -- [if fSlabBot Stroke 0])] [glyph-proc]

View file

@ -4,7 +4,7 @@ import [Arcs Quadify ShapeConv] from "typo-geom"
import [OffsetCurve BezToContoursSink GEOMETRY_PRECISION] from"../../support/geometry/curve-util.mjs" import [OffsetCurve BezToContoursSink GEOMETRY_PRECISION] from"../../support/geometry/curve-util.mjs"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs" import [ScheduleLeaningMark] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
import [Point] from"../../support/geometry/point.mjs" import [Point] from"../../support/geometry/point.mjs"
@ -30,16 +30,17 @@ glyph-block Mark-Above : begin
define commaAboveRadius : 0.85 * DotRadius * markHalfStroke / HalfStroke define commaAboveRadius : 0.85 * DotRadius * markHalfStroke / HalfStroke
define StdAnchors : namespace define StdAnchors : namespace
export : define [impl mk padding k] : glyph-proc export : define [impl mk padding k fLeaning] : glyph-proc
if (mk === 'above') if (mk === 'above')
: then : set-mark-anchor mk markMiddle (XH - padding * AccentHeight) markMiddle (aboveMarkStack + padding * AccentHeight) : then : set-mark-anchor mk markMiddle (XH - padding * AccentHeight) markMiddle (aboveMarkStack + padding * AccentHeight)
: else : set-mark-anchor mk markMiddle (XH - padding * AccentHeight) : else : set-mark-anchor mk markMiddle (XH - padding * AccentHeight)
set-base-anchor 'aboveBraceL' (markMiddle - k * markExtend) aboveMarkMid set-base-anchor 'aboveBraceL' (markMiddle - k * markExtend) aboveMarkMid
set-base-anchor 'aboveBraceR' (markMiddle + k * markExtend) aboveMarkMid set-base-anchor 'aboveBraceR' (markMiddle + k * markExtend) aboveMarkMid
if fLeaning : ScheduleLeaningMark.set currentGlyph
export : define [narrow] : impl 'above' 0 0 export : define [narrow] : impl 'above' 0 0 true
export : define [mediumNarrow] : impl 'above' 0 0.25 export : define [mediumNarrow] : impl 'above' 0 0.25 true
export : define [medium] : impl 'above' 0 0.5 export : define [medium] : impl 'above' 0 0.5 true
export : define [mediumWide] : impl 'above' 0 0.75 export : define [mediumWide] : impl 'above' 0 0.75
export : define [wide] : impl 'above' 0 1 export : define [wide] : impl 'above' 0 1
export : define [extraWide] : impl 'above' 0 1.5 export : define [extraWide] : impl 'above' 0 1.5
@ -50,6 +51,7 @@ glyph-block Mark-Above : begin
set-width 0 set-width 0
include : StdAnchors.narrow include : StdAnchors.narrow
include : DrawAt markMiddle aboveMarkMid (DotRadius * kdr) include : DrawAt markMiddle aboveMarkMid (DotRadius * kdr)
ScheduleLeaningMark.set currentGlyph
create-glyph "dieresisAbove.\(suffix)" : glyph-proc create-glyph "dieresisAbove.\(suffix)" : glyph-proc
set-width 0 set-width 0
@ -195,7 +197,7 @@ glyph-block Mark-Above : begin
create-glyph 'circumflexAbove' 0x302 : glyph-proc create-glyph 'circumflexAbove' 0x302 : glyph-proc
set-width 0 set-width 0
include : StdAnchors.wide include : StdAnchors.medium
include : CaretShape include : CaretShape
xMiddle -- markMiddle xMiddle -- markMiddle
width -- CaretCaronWidth width -- CaretCaronWidth
@ -206,7 +208,7 @@ glyph-block Mark-Above : begin
create-glyph 'bardownAbove' 0x1DC6 : glyph-proc create-glyph 'bardownAbove' 0x1DC6 : glyph-proc
set-width 0 set-width 0
include : StdAnchors.wide include : StdAnchors.medium
include : CaretRightShape include : CaretRightShape
xMiddle -- markMiddle xMiddle -- markMiddle
width -- CaretCaronWidth width -- CaretCaronWidth
@ -225,7 +227,7 @@ glyph-block Mark-Above : begin
create-glyph 'upbarAbove' 0x1DC7 : glyph-proc create-glyph 'upbarAbove' 0x1DC7 : glyph-proc
set-width 0 set-width 0
include : StdAnchors.wide include : StdAnchors.medium
include : CaretLeftShape include : CaretLeftShape
xMiddle -- markMiddle xMiddle -- markMiddle
width -- CaretCaronWidth width -- CaretCaronWidth
@ -258,7 +260,7 @@ glyph-block Mark-Above : begin
create-glyph 'caronAbove' 0x30c : glyph-proc create-glyph 'caronAbove' 0x30c : glyph-proc
set-width 0 set-width 0
include : StdAnchors.wide include : StdAnchors.medium
include : CaronShape include : CaronShape
xMiddle -- markMiddle xMiddle -- markMiddle
width -- CaretCaronWidth width -- CaretCaronWidth
@ -269,7 +271,7 @@ glyph-block Mark-Above : begin
create-glyph 'barupAbove' 0x1DC4 : glyph-proc create-glyph 'barupAbove' 0x1DC4 : glyph-proc
set-width 0 set-width 0
include : StdAnchors.wide include : StdAnchors.medium
include : CaronRightShape include : CaronRightShape
xMiddle -- markMiddle xMiddle -- markMiddle
width -- CaretCaronWidth width -- CaretCaronWidth
@ -288,7 +290,7 @@ glyph-block Mark-Above : begin
create-glyph 'downbarAbove' 0x1DC5 : glyph-proc create-glyph 'downbarAbove' 0x1DC5 : glyph-proc
set-width 0 set-width 0
include : StdAnchors.wide include : StdAnchors.medium
include : CaronLeftShape include : CaronLeftShape
xMiddle -- markMiddle xMiddle -- markMiddle
width -- CaretCaronWidth width -- CaretCaronWidth

View file

@ -8,9 +8,15 @@ glyph-block Mark-Adjustment : begin
if currentGlyph.baseAnchors.below : begin if currentGlyph.baseAnchors.below : begin
local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.below local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.below
if (a.y > y) : set-base-anchor 'below' a.x y if (a.y > y) : set-base-anchor 'below' a.x y
if currentGlyph.baseAnchors.leaningBelow : begin
local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.leaningBelow
if (a.y > y) : set-base-anchor 'leaningBelow' a.x y
glyph-block-export ExtendAboveBaseAnchors glyph-block-export ExtendAboveBaseAnchors
define [ExtendAboveBaseAnchors y] : glyph-proc define [ExtendAboveBaseAnchors y] : glyph-proc
if currentGlyph.baseAnchors.above : begin if currentGlyph.baseAnchors.above : begin
local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.above local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.above
if (a.y < y) : set-base-anchor 'above' a.x y if (a.y < y) : set-base-anchor 'above' a.x y
if currentGlyph.baseAnchors.leaningAbove : begin
local a : currentGlyph.gizmo.unapply currentGlyph.baseAnchors.leaningAbove
if (a.y < y) : set-base-anchor 'leaningAbove' a.x y

View file

@ -3,7 +3,7 @@ $$include '../../meta/macros.ptl'
import [Arcs Quadify ShapeConv] from "typo-geom" import [Arcs Quadify ShapeConv] from "typo-geom"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs" import [ScheduleLeaningMark] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
glyph-module glyph-module
@ -22,14 +22,15 @@ glyph-block Mark-Below : begin
define belowMarkStack (0 - AccentStackOffset) define belowMarkStack (0 - AccentStackOffset)
define StdAnchors : namespace define StdAnchors : namespace
export : define [impl padding k] : glyph-proc export : define [impl padding k fLeaning] : glyph-proc
set-mark-anchor 'below' markMiddle (0 + padding * AccentHeight) markMiddle (belowMarkStack - padding * AccentHeight) set-mark-anchor 'below' markMiddle (0 + padding * AccentHeight) markMiddle (belowMarkStack - padding * AccentHeight)
set-base-anchor 'belowBraceL' (markMiddle - k * markExtend) belowMarkMid set-base-anchor 'belowBraceL' (markMiddle - k * markExtend) belowMarkMid
set-base-anchor 'belowBraceR' (markMiddle + k * markExtend) belowMarkMid set-base-anchor 'belowBraceR' (markMiddle + k * markExtend) belowMarkMid
if fLeaning : ScheduleLeaningMark.set currentGlyph
export : define [narrow] : impl 0 0 export : define [narrow] : impl 0 0 true
export : define [mediumNarrow] : impl 0 0.25 export : define [mediumNarrow] : impl 0 0.25 true
export : define [medium] : impl 0 0.5 export : define [medium] : impl 0 0.5 true
export : define [mediumWide] : impl 0 0.75 export : define [mediumWide] : impl 0 0.75
export : define [wide] : impl 0 1 export : define [wide] : impl 0 1
@ -174,6 +175,7 @@ glyph-block Mark-Below : begin
mirrorAnchor aboveGlyph currentGlyph 'above' 'below' mirrorAnchor aboveGlyph currentGlyph 'above' 'below'
mirrorAnchor aboveGlyph currentGlyph 'aboveBraceL' 'belowBraceR' mirrorAnchor aboveGlyph currentGlyph 'aboveBraceL' 'belowBraceR'
mirrorAnchor aboveGlyph currentGlyph 'aboveBraceR' 'belowBraceL' mirrorAnchor aboveGlyph currentGlyph 'aboveBraceR' 'belowBraceL'
if [ScheduleLeaningMark.get aboveGlyph] : ScheduleLeaningMark.set currentGlyph
TurnAboveMarkToBelow 'graveBelow' 0x316 'graveAbove' TurnAboveMarkToBelow 'graveBelow' 0x316 'graveAbove'
TurnAboveMarkToBelow 'acuteBelow' 0x317 'acuteAbove' TurnAboveMarkToBelow 'acuteBelow' 0x317 'acuteAbove'

View file

@ -3,7 +3,6 @@ $$include '../../meta/macros.ptl'
import [Arcs Quadify ShapeConv] from "typo-geom" import [Arcs Quadify ShapeConv] from "typo-geom"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
glyph-module glyph-module

View file

@ -3,7 +3,6 @@ $$include '../../meta/macros.ptl'
import [Arcs Quadify ShapeConv] from "typo-geom" import [Arcs Quadify ShapeConv] from "typo-geom"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
glyph-module glyph-module

View file

@ -3,7 +3,6 @@ $$include '../../meta/macros.ptl'
import [Arcs Quadify ShapeConv] from "typo-geom" import [Arcs Quadify ShapeConv] from "typo-geom"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
glyph-module glyph-module

View file

@ -3,7 +3,6 @@ $$include '../../meta/macros.ptl'
import [Arcs Quadify ShapeConv] from "typo-geom" import [Arcs Quadify ShapeConv] from "typo-geom"
import [mix linreg clamp fallback] from"../../support/utils.mjs" import [mix linreg clamp fallback] from"../../support/utils.mjs"
import [DesignParameters] from"../../meta/aesthetics.mjs" import [DesignParameters] from"../../meta/aesthetics.mjs"
import [TieMark TieGlyph] from"../../support/gr.mjs"
import [Box] from"../../support/geometry/box.mjs" import [Box] from"../../support/geometry/box.mjs"
glyph-module glyph-module

View file

@ -300,6 +300,7 @@ class CMarkSet
set this.markAnchors markAnchors set this.markAnchors markAnchors
set this.baseAnchors baseAnchors set this.baseAnchors baseAnchors
public [applyToGlyph g] : begin public [applyToGlyph g] : begin
g.clearAnchors
g.copyAnchors this g.copyAnchors this
export : define [compositeBaseAnchors] : begin export : define [compositeBaseAnchors] : begin

View file

@ -4,8 +4,8 @@ extern Map
extern Set extern Set
define MarkClasses { define MarkClasses {
'above' 'tieAbove' 'topLeft' 'topRight' 'grekUpperTonos' 'aboveBraceL' 'aboveBraceR' 'above' 'tieAbove' 'leaningAbove' 'topLeft' 'topRight' 'grekUpperTonos' 'aboveBraceL' 'aboveBraceR'
'below' 'tieBelow' 'bottomLeft' 'bottomRight' 'trailing' 'lf' 'belowBraceL' 'belowBraceR' 'below' 'tieBelow' 'leaningBelow' 'bottomLeft' 'bottomRight' 'trailing' 'lf' 'belowBraceL' 'belowBraceR'
'overlay' 'slash' 'strike' 'overlay' 'slash' 'strike'
'cvDecompose' 'enclosureInner' 'enclosureInnerFirstHalf' 'enclosureInnerSecondHalf' 'cvDecompose' 'enclosureInner' 'enclosureInnerFirstHalf' 'enclosureInnerSecondHalf'
@ -13,10 +13,10 @@ define MarkClasses {
} }
define MarkInteractions : new Map : list define MarkInteractions : new Map : list
list 'aboveBraceL' {'aboveBraceL' 'above' 'tieAbove' 'topLeft' 'topRight' 'grekUpperTonos'} list 'aboveBraceL' {'aboveBraceL' 'above' 'tieAbove' 'leaningAbove' 'topLeft' 'topRight' 'grekUpperTonos'}
list 'aboveBraceR' {'aboveBraceR' 'above' 'tieAbove' 'topLeft' 'topRight' 'grekUpperTonos'} list 'aboveBraceR' {'aboveBraceR' 'above' 'tieAbove' 'leaningAbove' 'topLeft' 'topRight' 'grekUpperTonos'}
list 'belowBraceL' {'belowBraceL' 'below' 'tieBelow' 'bottomLeft' 'bottomRight' 'trailing' 'lf'} list 'belowBraceL' {'belowBraceL' 'below' 'tieBelow' 'leaningBelow' 'bottomLeft' 'bottomRight' 'trailing' 'lf'}
list 'belowBraceR' {'belowBraceR' 'below' 'tieBelow' 'bottomLeft' 'bottomRight' 'trailing' 'lf'} list 'belowBraceR' {'belowBraceR' 'below' 'tieBelow' 'leaningBelow' 'bottomLeft' 'bottomRight' 'trailing' 'lf'}
define MkmkStackingLimit : new Set { 'above' 'below' } define MkmkStackingLimit : new Set { 'above' 'below' }

View file

@ -1,7 +1,7 @@
$$include '../meta/macros.ptl' $$include '../meta/macros.ptl'
import [AddCommonFeature AddFeature AddLookup AddFeatureLookup ChainRuleBuilder BeginLookupBlock EndLookupBlock UkMapToLookup UkMap2ToLookup] from"./table-util.mjs" 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 [Dotless TieMark TieGlyph OgonekTrY IsSuperscript IsSubscript LeaningMark LeaningMarkSpacer] from"../support/gr.mjs"
import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs" import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs"
extern Set extern Set
@ -40,24 +40,18 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
define groupLF {} define groupLF {}
define dotlessFrom {} define dotlessFrom {}
define dotlessTo {} define dotlessTo {}
define TieMarkFrom {}
define TieMarkTo {}
define TieGlyphs {}
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== "."): begin foreach { gn g } [glyphStore.namedEntries] : if (gn.(0) !== "."): begin
if g.baseAnchors.lf : groupLF.push gid if g.baseAnchors.lf : groupLF.push gn
if g.baseAnchors.grekUpperTonos : groupGrekUpperTonos.push gid if g.baseAnchors.grekUpperTonos : groupGrekUpperTonos.push gn
if [Dotless.get g] : begin if [Dotless.get g] : begin
dotlessFrom.push gid dotlessFrom.push gn
dotlessTo.push [Dotless.get g] dotlessTo.push [Dotless.get g]
if [TieGlyph.get g] : TieGlyphs.push gid
if [TieMark.get g] : begin
TieMarkFrom.push gid
TieMarkTo.push [TieMark.get g]
define [IotaLF] : UkMapToLookup UnicodeKnowledge.iotaBelowToLfTf define [IotaLF] : UkMapToLookup UnicodeKnowledge.iotaBelowToLfTf
define [GrekUpperTonosTf] : UkMapToLookup UnicodeKnowledge.upperGrekMarkToTonosTf define [GrekUpperTonosTf] : UkMapToLookup UnicodeKnowledge.upperGrekMarkToTonosTf
# Dotless transform
export-lookup : AddLookup sink : object export-lookup : AddLookup sink : object
.type 'gsub_chaining' .type 'gsub_chaining'
.ignoreGlyphs [filterMarkByClassNegated markGlyphs 'above'] .ignoreGlyphs [filterMarkByClassNegated markGlyphs 'above']
@ -65,7 +59,7 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
chain-rule (dotlessFrom ~> dotlessTo) (aboveMark ~> null) chain-rule (dotlessFrom ~> dotlessTo) (aboveMark ~> null)
chain-rule groupGrekUpperTonos [GrekUpperTonosTf] chain-rule groupGrekUpperTonos [GrekUpperTonosTf]
# Iota transform (max 6 middle marks are supported) # Iota transform
export-lookup : AddLookup sink : object export-lookup : AddLookup sink : object
.type 'gsub_chaining' .type 'gsub_chaining'
.ignoreGlyphs [filterMarkByClassNegated markGlyphs 'below'] .ignoreGlyphs [filterMarkByClassNegated markGlyphs 'below']
@ -84,7 +78,17 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
'brackAbove' { 'leftBrackAbove' 'rightBrackAbove' } 'brackAbove' { 'leftBrackAbove' 'rightBrackAbove' }
'parenBelow' { 'leftParenBelow' 'rightParenBelow' } 'parenBelow' { 'leftParenBelow' 'rightParenBelow' }
# Tie marks Ccmp-Group "Tie Mark Transform" : begin
define TieMarkFrom {}
define TieMarkTo {}
define TieGlyphs {}
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== ".") : begin
if [TieGlyph.get g] : TieGlyphs.push gid
if [TieMark.get g] : begin
TieMarkFrom.push gid
TieMarkTo.push [TieMark.get g]
define lookupTieMarkLigature : AddLookup sink : object define lookupTieMarkLigature : AddLookup sink : object
.type 'gsub_ligature' .type 'gsub_ligature'
.substitutions : {}.concat .substitutions : {}.concat
@ -99,13 +103,47 @@ export : define [buildCCMP sink glyphStore markGlyphs] : begin
inputEnds 3 inputEnds 3
apply {{.at 1 .lookup lookupTieMarkLigature}} apply {{.at 1 .lookup lookupTieMarkLigature}}
Ccmp-Group "Leaning Mark Trasnform" : begin
define LeaningAnchorMap : list
list 'above' 'leaningAbove'
list 'below' 'leaningBelow'
foreach { mkCenter mkLeaning } [items-of LeaningAnchorMap] : begin
local basesToConsider {}
local markFrom {}
local markTo {}
local markSpacer {}
local splitMapping {}
foreach { gn g } [glyphStore.namedEntries] : if (gn.(0) !== ".") : begin
if (![markGlyphs.all.has gn] && g.baseAnchors.(mkLeaning)) : basesToConsider.push gn
if (g.markAnchors.(mkCenter) && [LeaningMark.get g] && [LeaningMarkSpacer.get g]) : begin
markFrom.push gn
markTo.push [LeaningMark.get g]
markSpacer.push [LeaningMarkSpacer.get g]
splitMapping.push { gn {[LeaningMarkSpacer.get g] [LeaningMark.get g]} }
define lookupTurnMarkIntoLeaningAndSpacer : AddLookup sink : object
.type 'gsub_multiple'
.substitutions : Object.fromEntries splitMapping
export-lookup : AddLookup sink : object
.type 'gsub_chaining'
.ignoreGlyphs [filterMarkByClassNegated markGlyphs mkCenter]
.rules : list
object
.match { [basesToConsider.concat markSpacer] markFrom }
.inputBegins 1
.inputEnds 2
.apply {{.at 1 .lookup lookupTurnMarkIntoLeaningAndSpacer}}
Ccmp-Group "Rhotic Hook Transform" : begin Ccmp-Group "Rhotic Hook Transform" : begin
define superscripts {} define superscripts {}
define subscripts {} define subscripts {}
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== "."): begin foreach { gn g } [glyphStore.namedEntries] : if (gn.(0) !== ".") : begin
if [IsSuperscript.get g] : superscripts.push gid if [IsSuperscript.get g] : superscripts.push gn
if [IsSubscript.get g] : subscripts.push gid if [IsSubscript.get g] : subscripts.push gn
export-lookup : AddLookup sink : object export-lookup : AddLookup sink : object
.type 'gsub_chaining' .type 'gsub_chaining'

View file

@ -14,8 +14,14 @@ export class GlyphStore {
namedEntries() { namedEntries() {
return this.nameForward.entries(); return this.nameForward.entries();
} }
encodedEntries() { glyphNames() {
return this.encodingForward.entries(); return this.nameForward.keys();
}
*encodedEntries() {
for (const [u, g] of this.encodingForward.entries()) {
const name = this.nameBackward.get(g);
if (name) yield [u, name, g];
}
} }
*flattenCodes(g, flatteners) { *flattenCodes(g, flatteners) {
{ {

View file

@ -23,6 +23,10 @@ export class Glyph {
this.ctxTag = null; this.ctxTag = null;
} }
toString() {
return `<Glyph ${this._m_identifier}>`;
}
get identifier() { get identifier() {
return this._m_identifier; return this._m_identifier;
} }
@ -182,6 +186,11 @@ export class Glyph {
this.baseAnchors[id] = new Anchor(mbx, mby).transform(this.gizmo); this.baseAnchors[id] = new Anchor(mbx, mby).transform(this.gizmo);
} }
} }
copyBaseAnchorIfAbsent(to, from) {
if (this.baseAnchors[from] && !this.baseAnchors[to]) {
this.baseAnchors[to] = new Anchor(this.baseAnchors[from].x, this.baseAnchors[from].y);
}
}
clearAnchors() { clearAnchors() {
this.baseAnchors = {}; this.baseAnchors = {};
this.markAnchors = {}; this.markAnchors = {};

View file

@ -20,6 +20,9 @@ export const LowerYDotAtBelow = LinkedGlyphProp("LowerYDotAtBelow");
export const DependentSelector = LinkedGlyphProp("DependentSelector"); export const DependentSelector = LinkedGlyphProp("DependentSelector");
export const MathSansSerif = LinkedGlyphProp("MathSansSerif"); export const MathSansSerif = LinkedGlyphProp("MathSansSerif");
export const VS01 = LinkedGlyphProp("VS01"); export const VS01 = LinkedGlyphProp("VS01");
export const TieMark = LinkedGlyphProp("TieMark");
export const LeaningMark = LinkedGlyphProp("LeaningMark");
export const LeaningMarkSpacer = LinkedGlyphProp("LeaningMarkSpacer");
function LinkedGlyphProp(key) { function LinkedGlyphProp(key) {
return { return {
get(glyph) { get(glyph) {
@ -30,6 +33,12 @@ function LinkedGlyphProp(key) {
if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph"); if (typeof toGid !== "string") throw new Error("Must supply a GID instead of a glyph");
if (!glyph.related) glyph.related = {}; if (!glyph.related) glyph.related = {};
glyph.related[key] = toGid; glyph.related[key] = toGid;
},
amendName(name) {
return `${key}{${name}}`;
},
amendOtName(name) {
return `${name}.${key}`;
} }
}; };
} }
@ -61,25 +70,6 @@ function DecompositionProp(key) {
}; };
} }
export const TieMark = {
tag: "TMRK",
get(glyph) {
if (glyph && glyph.related) return glyph.related.TieMark;
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 = {};
glyph.related.TieMark = toGid;
},
amendName(name) {
return `TieMark{${name}}`;
},
amendOtName(name) {
return name + ".tieMark";
}
};
export const TieGlyph = { export const TieGlyph = {
get(glyph) { get(glyph) {
if (glyph && glyph.related) return glyph.related.TieGlyph; if (glyph && glyph.related) return glyph.related.TieGlyph;
@ -109,6 +99,7 @@ export const NeqLigationSlashDotted = BoolProp("NeqLigationSlashDotted");
export const OgonekTrY = BoolProp("OgonekTrY"); export const OgonekTrY = BoolProp("OgonekTrY");
export const IsSuperscript = BoolProp("IsSuperscript"); export const IsSuperscript = BoolProp("IsSuperscript");
export const IsSubscript = BoolProp("IsSubscript"); export const IsSubscript = BoolProp("IsSubscript");
export const ScheduleLeaningMark = BoolProp("ScheduleLeaningMark");
export const Joining = { export const Joining = {
get(glyph) { get(glyph) {
@ -242,6 +233,7 @@ export function getGrTree(gid, grSetList, fnGidToGlyph) {
getGrTreeImpl(gid, grSetList, fnGidToGlyph, sink); getGrTreeImpl(gid, grSetList, fnGidToGlyph, sink);
return sink; return sink;
} }
function getGrTreeImpl(gid, grSetList, fnGidToGlyph, sink) { function getGrTreeImpl(gid, grSetList, fnGidToGlyph, sink) {
if (!grSetList.length) return; if (!grSetList.length) return;
const g = fnGidToGlyph(gid); const g = fnGidToGlyph(gid);
@ -463,5 +455,6 @@ export const SvInheritableRelations = [
DependentSelector, DependentSelector,
Joining, Joining,
NeqLigationSlashDotted, NeqLigationSlashDotted,
OgonekTrY OgonekTrY,
ScheduleLeaningMark
]; ];

View file

@ -80,3 +80,39 @@ export class $NamedParameterPair$ {
this.right = r; this.right = r;
} }
} }
///////////////////////////////////////////////////////////////////////////////////////////////////
export const MatchUtil = {
never() {
return false;
},
equal(x) {
return y => y === x;
},
negate(f) {
return x => !f(x);
},
both(a, b) {
return x => a(x) && b(x);
},
either(a, b) {
return x => a(x) || b(x);
}
};
export function constant(x) {
return () => x;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
export const ArrayUtil = {
mapIndexToItems(a, indexes) {
let answer = [];
for (const item of indexes) answer.push(a[item]);
return answer;
},
insertSliceAt(a, i, b) {
a.splice(i, 0, ...b);
}
};