Move the glyph saving logic to MJS side (#2479)

This commit is contained in:
Belleve 2024-08-21 21:27:21 -10:00 committed by GitHub
parent 499b97e3a1
commit 5ee209c97f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 84 additions and 68 deletions

View file

@ -1,6 +1,6 @@
import [Glyph GlyphProc ForkGlyphProc] from "@iosevka/glyph" import [Glyph GlyphProc ForkGlyphProc] from "@iosevka/glyph"
import [GlyphStore] from "@iosevka/glyph/store" import [GlyphStore] from "@iosevka/glyph/store"
import [GlyphBlock GlyphBuildExecutor] from "@iosevka/glyph/block" import [GlyphBlock GlyphBuildExecutor GlyphSaveSink] from "@iosevka/glyph/block"
import as Gr from "@iosevka/glyph/relation" import as Gr from "@iosevka/glyph/relation"
import as SpiroKit from "@iosevka/font-kits/spiro-kit" import as SpiroKit from "@iosevka/font-kits/spiro-kit"
import as BooleKit from "@iosevka/font-kits/boole-kit" import as BooleKit from "@iosevka/font-kits/boole-kit"
@ -15,7 +15,6 @@ $$include './meta/macros.ptl'
export : define [buildGlyphs para recursive] : begin export : define [buildGlyphs para recursive] : begin
# Execution and dependency management # Execution and dependency management
local $Exec$ : new GlyphBuildExecutor recursive local $Exec$ : new GlyphBuildExecutor recursive
define [glyph-is-needed name] : [not recursive] || [recursive.glyphIsNeeded name]
# Initialize glyph store # Initialize glyph store
local glyphStore : new GlyphStore local glyphStore : new GlyphStore
@ -32,45 +31,8 @@ export : define [buildGlyphs para recursive] : begin
# Anchor parameters # Anchor parameters
define {AS_BASE ALSO_METRICS} {'AS-BASE' 'ALSO-METRICS'} define {AS_BASE ALSO_METRICS} {'AS-BASE' 'ALSO-METRICS'}
# The callback used to create and save glyphs # Glyph saving sink
define [$createAndSaveGlyphImpl$ _1 _2 actions] : begin define $GlyphSaveSink$ : new GlyphSaveSink $Exec$ Metrics glyphStore
local saveGlyphName null
local unicode null
piecewise
([typeof _1] === 'number' && _1) : begin
set saveGlyphName : 'uni' + [_1.toString 16 :.padStart 4 '0' :.toUpperCase]
set unicode _1
([typeof _1] === 'string' && _1) : begin
set saveGlyphName _1
set unicode _2
true : begin
set saveGlyphName null
set unicode null
if (saveGlyphName && [not : glyph-is-needed saveGlyphName]) : return nothing
if para.verbose : console.log saveGlyphName
local glyphObject [new Glyph saveGlyphName]
glyphObject.setWidth Metrics.Width
glyphObject.gizmo = Metrics.GlobalTransform
glyphObject._m_dependencyManager = $Exec$.dependencyManager
glyphObject.include actions true true
$Exec$.setGlyphToBlockDependency glyphObject
if saveGlyphName : begin
if (saveGlyphName.0 != '.' && [glyphStore.queryByName saveGlyphName])
throw : new Error "Glyph \(saveGlyphName) already exists"
glyphStore.addGlyph saveGlyphName glyphObject
if unicode : begin
local u unicode
if ([typeof unicode] === "string") : begin
set u [unicode.codePointAt 0]
glyphStore.encodeGlyph u glyphObject
return glyphObject
# Spiro kit and boole kit # Spiro kit and boole kit
define SpiroFns : SpiroKit.SetupBuilders : object define SpiroFns : SpiroKit.SetupBuilders : object
@ -86,9 +48,9 @@ export : define [buildGlyphs para recursive] : begin
# Setup the capture # Setup the capture
define $$Capture$$ : object define $$Capture$$ : object
$createAndSaveGlyphImpl$
$NamedParameterPair$ $NamedParameterPair$
$Exec$ $Exec$
$GlyphSaveSink$
Metrics : Object.assign {.} Metrics Metrics : Object.assign {.} Metrics
para para
recursive recursive
@ -100,7 +62,6 @@ export : define [buildGlyphs para recursive] : begin
MarkSet MarkSet
AS_BASE AS_BASE
ALSO_METRICS ALSO_METRICS
glyph-is-needed
buildGlyphs buildGlyphs
fontMetrics fontMetrics
GlyphProc GlyphProc
@ -148,8 +109,4 @@ export : define [buildGlyphs para recursive] : begin
$Exec$.executePendingBlocks $Exec$.executePendingBlocks
Gr.linkSuffixPairGr glyphStore 'NWID' 'WWID' Gr.Nwid Gr.Wwid
Gr.linkSuffixPairGr glyphStore 'lnum' 'onum' Gr.Lnum Gr.Onum
Gr.linkSuffixGr glyphStore 'aplForm' Gr.AplForm
return : object glyphStore fontMetrics return : object glyphStore fontMetrics

View file

@ -51,7 +51,7 @@ glyph-block Letter-Latin-Lower-G : begin
set-base-anchor 'overlay' Middle [mix (Descender + O) groundy 0.5] set-base-anchor 'overlay' Middle [mix (Descender + O) groundy 0.5]
set-base-anchor 'strike' Middle (XH / 2) set-base-anchor 'strike' Middle (XH / 2)
create-forked-glyph 'gBar.doubleStorey' : OverlayW obwDoubleStorey derive-composites "gBar.doubleStorey" null "g.doubleStorey" [OverlayW obwDoubleStorey]
create-glyph 'g.openDoubleStorey' : glyph-proc create-glyph 'g.openDoubleStorey' : glyph-proc
include : MarkSet.p include : MarkSet.p
@ -81,7 +81,7 @@ glyph-block Letter-Latin-Lower-G : begin
set-base-anchor 'overlay' Middle [mix (Descender + O) groundy 0.5] set-base-anchor 'overlay' Middle [mix (Descender + O) groundy 0.5]
set-base-anchor 'strike' Middle (XH / 2) set-base-anchor 'strike' Middle (XH / 2)
create-forked-glyph 'gBar.openDoubleStorey' : OverlayW obwDoubleStorey derive-composites "gBar.openDoubleStorey" null "g.openDoubleStorey" [OverlayW obwDoubleStorey]
define SingleStorey : namespace define SingleStorey : namespace
export : define [RoundHookT sink df yTop offset sw] : sink export : define [RoundHookT sink df yTop offset sw] : sink

View file

@ -149,40 +149,35 @@ define-macro eject-contour : syntax-rules
###### Canvas-based mechanism ###### Canvas-based mechanism
define-macro new-glyph : syntax-rules define-macro new-glyph : syntax-rules
`[new-glyph @body] : begin `[new-glyph @body] : begin
dirty `[$createAndSaveGlyphImpl$ null null @[formOf body]] dirty `[$GlyphSaveSink$.save null null @[formOf body]]
define-macro create-glyph : syntax-rules define-macro create-glyph : syntax-rules
`[create-glyph @body] : begin `[create-glyph @body] : begin
if [not externEnv.$nWFGlyphs$] : set externEnv.$nWFGlyphs$ 0 dirty `[$GlyphSaveSink$.save null null @[formOf body]]
inc externEnv.$nWFGlyphs$
local f0 : '.' + [[env.macros.get 'input-path']].1 + '.'
local tcn {".quote" (".WF" + f0 + externEnv.$nWFGlyphs$)}
dirty `[$createAndSaveGlyphImpl$ @tcn null @[formOf body]]
`[create-glyph @name @body] : begin `[create-glyph @name @body] : begin
dirty `[$createAndSaveGlyphImpl$ @[formOf name] null @[formOf body]] dirty `[$GlyphSaveSink$.save @[formOf name] null @[formOf body]]
`[create-glyph @name @code @body] : begin `[create-glyph @name @code @body] : begin
dirty `[$createAndSaveGlyphImpl$ @[formOf name] @[formOf code] @[formOf body]] dirty `[$GlyphSaveSink$.save @[formOf name] @[formOf code] @[formOf body]]
define-macro create-aliased-glyph : syntax-rules define-macro create-aliased-glyph : syntax-rules
`[create-aliased-glyph @name] : begin `[create-aliased-glyph @name] : begin
dirty `[create-aliased-glyph @[formOf name] null] dirty `[create-aliased-glyph @[formOf name] null]
`[create-aliased-glyph @name @code] : begin `[create-aliased-glyph @name @code] : begin
dirty `[$createAndSaveGlyphImpl$ @[formOf name] @[formOf code] dirty `[$GlyphSaveSink$.save @[formOf name] @[formOf code]
[new $Capture$.ForkGlyphProc currentGlyph null] ] [new $Capture$.ForkGlyphProc currentGlyph null] ]
define-macro create-forked-glyph : syntax-rules define-macro create-forked-glyph : syntax-rules
`[create-forked-glyph @body] : begin `[create-forked-glyph @body] : begin
if [not externEnv.$nWFGlyphs$] : set externEnv.$nWFGlyphs$ 0 dirty `[create-forked-glyph null null @[formOf body]]
inc externEnv.$nWFGlyphs$
local f0 : '.' + [[env.macros.get 'input-path']].1 + '.'
local tcn {".quote" (".WF" + f0 + externEnv.$nWFGlyphs$)}
dirty `[create-forked-glyph @tcn null @[formOf body]]
`[create-forked-glyph @name @body] : begin `[create-forked-glyph @name @body] : begin
dirty `[create-forked-glyph @[formOf name] null @[formOf body]] dirty `[create-forked-glyph @[formOf name] null @[formOf body]]
`[create-forked-glyph @name @code @body] : begin `[create-forked-glyph @name @code @body] : begin
dirty `[$createAndSaveGlyphImpl$ @[formOf name] @[formOf code] dirty `[$GlyphSaveSink$.save @[formOf name] @[formOf code]
[new $Capture$.ForkGlyphProc currentGlyph @[formOf body]] ] [new $Capture$.ForkGlyphProc currentGlyph @[formOf body]] ]
define-macro glyph-is-needed : syntax-rules
`[glyph-is-needed @name] : dirty `[$GlyphSaveSink$.glyphIsNeeded @[formOf name]]
###### Glyph modules and Glyph blocks ###### Glyph modules and Glyph blocks
define-macro glyph-module : syntax-rules define-macro glyph-module : syntax-rules
@ -265,13 +260,13 @@ define-macro glyph-block : syntax-rules
([typeof form] === "string") : set variableSet.(form) true ([typeof form] === "string") : set variableSet.(form) true
traceBody body traceBody body
traceBody `[$NamedParameterPair$ $createAndSaveGlyphImpl$ $Exec$] traceBody `[$NamedParameterPair$ $GlyphSaveSink$ $Exec$]
set externEnv.$glyphBlockVariableUsage$ variableSet set externEnv.$glyphBlockVariableUsage$ variableSet
define captureImports `[$createAndSaveGlyphImpl$ $NamedParameterPair$ $Exec$ Metrics para define captureImports `[$GlyphSaveSink$ $NamedParameterPair$ $Exec$ Metrics para recursive
recursive glyphStore glyph-is-needed SpiroFns BooleFns MarkSet AS_BASE ALSO_METRICS glyphStore SpiroFns BooleFns MarkSet AS_BASE ALSO_METRICS buildGlyphs DivFrame
buildGlyphs DivFrame fontMetrics] fontMetrics]
define metricImports `[DesignParameters UPM HalfUPM Width SB CAP XH Ascender Descender define metricImports `[DesignParameters UPM HalfUPM Width SB CAP XH Ascender Descender
Contrast SymbolMid ParenTop ParenBot OperTop OperBot TackTop TackBot PlusTop PlusBot Contrast SymbolMid ParenTop ParenBot OperTop OperBot TackTop TackBot PlusTop PlusBot

View file

@ -108,6 +108,11 @@ define [buildGDEF para glyphStore markGlyphs] : begin
return GDEF return GDEF
export : define [buildOtl para glyphStore] : begin export : define [buildOtl para glyphStore] : begin
# Link glyph pairs by suffix
Gr.linkSuffixPairGr glyphStore 'NWID' 'WWID' Gr.Nwid Gr.Wwid
Gr.linkSuffixPairGr glyphStore 'lnum' 'onum' Gr.Lnum Gr.Onum
Gr.linkSuffixGr glyphStore 'aplForm' Gr.AplForm
local markGlyphs { .all [new Set] .markAttachClassDef [new Map] .markGlyphSets {} } local markGlyphs { .all [new Set] .markAttachClassDef [new Map] .markGlyphSets {} }
local GPOS : buildGPOS para glyphStore markGlyphs local GPOS : buildGPOS para glyphStore markGlyphs
local GDEF : buildGDEF para glyphStore markGlyphs local GDEF : buildGDEF para glyphStore markGlyphs

View file

@ -1,3 +1,5 @@
import { Glyph } from "./glyph.mjs";
export class GlyphBuildExecutor { export class GlyphBuildExecutor {
constructor(recursiveBuildFilter) { constructor(recursiveBuildFilter) {
this.recursiveBuildFilter = recursiveBuildFilter; this.recursiveBuildFilter = recursiveBuildFilter;
@ -174,3 +176,60 @@ export class GlyphBlock {
return this.exports; return this.exports;
} }
} }
/// The class used to handle glyph saving.
export class GlyphSaveSink {
constructor(exec, metrics, store) {
this.exec = exec;
this.metrics = metrics;
this.glyphStore = store;
}
glyphIsNeeded(name) {
return (
!this.exec.recursiveBuildFilter || this.exec.recursiveBuildFilter.glyphIsNeeded(name)
);
}
save($1, $2, contents) {
// Figure out the glyph name and unicode to save
let saveGlyphName = null;
let unicode = null;
if ($1 && typeof $1 === "string") {
saveGlyphName = $1;
unicode = $2 || 0;
} else if ($1 && typeof $1 === "number") {
saveGlyphName = "uni" + $1.toString(16).padStart(4, "0").toUpperCase();
unicode = $1;
}
// If we are in a recursive build run, and the glyph is not needed, skip it
if (saveGlyphName && !this.glyphIsNeeded(saveGlyphName)) return;
// Create the glyph object & include the contents
const glyphObject = new Glyph(saveGlyphName);
glyphObject.setWidth(this.metrics.Width);
glyphObject.gizmo = this.metrics.GlobalTransform;
glyphObject._m_dependencyManager = this.exec.dependencyManager;
glyphObject.include(contents, true, true);
// Set the glyph-to-block dependency
this.exec.setGlyphToBlockDependency(glyphObject);
// Save the glyph if requested
if (saveGlyphName) {
if (this.glyphStore.queryByName(saveGlyphName)) {
throw new Error(`Duplicate glyph: ${saveGlyphName}`);
}
this.glyphStore.addGlyph(saveGlyphName, glyphObject);
if (unicode) {
let u = typeof unicode === "string" ? unicode.codePointAt(0) : unicode;
this.glyphStore.encodeGlyph(u, glyphObject);
}
}
return glyphObject;
}
}