diff --git a/gen/generator.js b/gen/generator.js index 35a6ff6c7..184c9d30f 100644 --- a/gen/generator.js +++ b/gen/generator.js @@ -12,7 +12,7 @@ const formLigationData = require("../support/ligation-data"); const regulateGlyphs = require("../support/regulate-glyph"); const toml = require("toml"); -main().catch(e => { +main().catch((e) => { console.error(e); process.exit(1); }); @@ -57,7 +57,7 @@ async function getParameters(argv) { version: argv.ver, weight: argv["menu-weight"] - 0, width: argv["menu-width"] - 0, - slant: argv["menu-slant"] + slant: argv["menu-slant"], }; return para; @@ -94,11 +94,21 @@ async function saveCharMap(font) { for (const gid in font.glyf) { const glyph = font.glyf[gid]; if (!glyph) continue; - const isSpace = glyph.contours && glyph.contours.length; + + const glyphIsHidden = /^\./.test(gid); + const typographicFeatures = []; + if (!glyphIsHidden) { + if (/\.hwid$/.test(gid) || /\.fwid$/.test(gid)) + typographicFeatures.push("hwid", "fwid"); + if (/\.lnum$/.test(gid) || /\.onum$/.test(gid)) + typographicFeatures.push("lnum", "onum"); + } + charMap.push([ glyph.name, glyph.unicode, - glyph.advanceWidth === 0 ? (objHashNonEmpty(glyph.anchors) ? 1 : isSpace ? 2 : 0) : 0 + typographicFeatures, + glyph.featureSelector ? Object.keys(glyph.featureSelector) : [], ]); } await fs.writeFile(argv.charmap, JSON.stringify(charMap), "utf8"); diff --git a/glyphs/autobuild-transformed.ptl b/glyphs/autobuild-transformed.ptl index 7e2be9496..c79f6dacb 100644 --- a/glyphs/autobuild-transformed.ptl +++ b/glyphs/autobuild-transformed.ptl @@ -26,7 +26,7 @@ glyph-block Autobuild-Transformed : begin scale -- 0.7 mono -- true sbscale -- 1 - foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : 'sup' + glyphid] : glyph-construction + foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : glyphid + '+sup'] : glyph-construction if unicode : assign-unicode unicode local middle : miniatureFont.(glyphid).advanceWidth / 2 include miniatureFont.(glyphid) AS_BASE ALSO_METRICS @@ -45,7 +45,7 @@ glyph-block Autobuild-Transformed : begin scale -- 0.7 mono -- true sbscale -- 1 - foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : 'sub' + glyphid] : glyph-construction + foreach {unicode glyphid pri} [items-of records] : create-glyph [suggestName : glyphid + '+sub'] : glyph-construction if unicode : assign-unicode unicode local middle : miniatureFont.(glyphid).advanceWidth / 2 include miniatureFont.(glyphid) AS_BASE ALSO_METRICS @@ -372,23 +372,23 @@ glyph-block Autobuild-Transformed : begin apply-transform : Italify sketch # tradeMark - include : DoubleSuperscript [refer-glyph 'supT'] [refer-glyph 'supM'] + include : DoubleSuperscript [refer-glyph 'T+sup'] [refer-glyph 'M+sup'] save 'tradeMark' 0x2122 sketch # serviceMark - include : DoubleSuperscript [refer-glyph 'supS'] [refer-glyph 'supM'] + include : DoubleSuperscript [refer-glyph 'S+sup'] [refer-glyph 'M+sup'] save 'serviceMark' 0x2120 sketch # raisedMC - include : DoubleSuperscript [refer-glyph 'supM'] [refer-glyph 'supC'] + include : DoubleSuperscript [refer-glyph 'M+sup'] [refer-glyph 'C+sup'] save 'raisedMC' 0x1F16A sketch # raisedMD - include : DoubleSuperscript [refer-glyph 'supM'] [refer-glyph 'supD'] + include : DoubleSuperscript [refer-glyph 'M+sup'] [refer-glyph 'D+sup'] save 'raisedMD' 0x1F16B sketch # raisedMR - include : DoubleSuperscript [refer-glyph 'supM'] [refer-glyph 'supR'] + include : DoubleSuperscript [refer-glyph 'M+sup'] [refer-glyph 'R+sup'] save 'raisedMR' 0x1F16C define [createFracImpl suffix records fine scaleFactor closing] : begin @@ -420,7 +420,7 @@ glyph-block Autobuild-Transformed : begin apply-transform : Italify foreach {unicode numid denid height} [items-of records] : do - save-glyph [suggestName : numid + 'over' + denid] unicode : glyph-construction + save-glyph [suggestName : numid + '.over.' + denid + suffix] unicode : glyph-construction include : refer-glyph (numid + suffix + ".numpart") include : refer-glyph (denid + suffix + ".denpart") if fine : include : HBar SB RIGHTSB symbolMid (fine * 0.75) diff --git a/glyphs/common-shapes.ptl b/glyphs/common-shapes.ptl index 665ca1d0f..ffbc05bdb 100644 --- a/glyphs/common-shapes.ptl +++ b/glyphs/common-shapes.ptl @@ -8,19 +8,20 @@ import [designParameters] from '../meta/aesthetics' glyph-module glyph-block CommonShapes : begin - define [queryFeatureSelector follow para name transform] : begin + define [queryFeatureSelector follow para name transform omit] : begin local fs {.} local introduced false foreach [{k h} : pairs-of para.variants] : begin local suffix h.(follow) - if (suffix && transform && transform.(suffix)) : set suffix transform.(suffix) - if (suffix && h.__cvmap && h.__cvmap.(follow)) : begin - local tag h.__cvmap.(follow) - set fs.(tag) ([fallback name follow] + '.' + suffix) - set introduced true + if (suffix && !(omit && omit.(k))) : begin + if (suffix && transform && transform.(suffix)) : set suffix transform.(suffix) + if (suffix && h.__cvmap && h.__cvmap.(follow)) : begin + local tag h.__cvmap.(follow) + set fs.(tag) ([fallback name follow] + '.' + suffix) + set introduced true return : if introduced fs null - define [select-variant] : params [name unicode [to-name name] transform [follow name]] : begin + define [select-variant] : params [name unicode [to-name name] transform omit [follow name]] : begin if (pickHash && [not pickHash.(name)]) : return nothing local variant : variantSelector.(follow) || para.defaultVariant.(follow) @@ -28,14 +29,13 @@ glyph-block CommonShapes : begin throw : new Error "Variant for \(name) is not assigned." if (transform && transform.(variant)) : set variant transform.(variant) - local chosenGlyph glyphMap.(name + '.' + variant) create-glyph [fallback to-name name] : glyph-construction - include chosenGlyph AS_BASE ALSO_METRICS + include [refer-glyph (name + '.' + variant)] AS_BASE ALSO_METRICS if unicode : assign-unicode unicode - set currentGlyph.featureSelector : queryFeatureSelector follow para name transform + set currentGlyph.featureSelector : queryFeatureSelector follow para name transform omit if (follow !== name) : set currentGlyph.featureSelectorFollows follow - set this.cmpPriority chosenGlyph.cmpPriority + set this.cmpPriority [query-glyph (name + '.' + variant)].cmpPriority define [italic-variant name unicode] : create-glyph name : glyph-construction define base : if para.isItalic glyphMap.(name + '.italic') glyphMap.(name + '.upright') diff --git a/glyphs/letters-unified-basic.ptl b/glyphs/letters-unified-basic.ptl index a25e8731a..3747db745 100644 --- a/glyphs/letters-unified-basic.ptl +++ b/glyphs/letters-unified-basic.ptl @@ -1523,6 +1523,25 @@ glyph-block LetterUnified-Basic : begin set-anchor "overlay" BASE MIDDLE (XH / 2) save 'yhooktop.curly' + sketch # y.cursive + include MarkSet.p + include : nShoulder + left -- (SB + STROKE * HVCONTRAST) + right -- RIGHTSB + fine -- SHOULDERFINE + include : FlipAround MIDDLE (XH / 2) + include : dispiro + widths.rhs + flat RIGHTSB (XH - HOOK - HALFSTROKE) [heading DOWNWARD] + curl RIGHTSB (DESCENDER + SMALLSMOOTHA) + hookend (DESCENDER + O) + g4 SB (DESCENDER + SHOOK) + include : VerticalHook (RIGHTSB - HALFSTROKE * HVCONTRAST) (XH - HOOK - HALFSTROKE) HOOKX (-HOOK) + if SLAB : begin + include : LeftwardTopSerif SB XH SIDEJUT + set-anchor "overlay" BASE MIDDLE (XH / 2) + save 'yhooktop.cursive' + sketch # cyrU include MarkSet.capital branch @@ -1534,12 +1553,10 @@ glyph-block LetterUnified-Basic : begin set-anchor "overlay" BASE MIDDLE (XH / 2 - DESCENDER) save 'cyrU.curly' - select-variant 'yhooktop' 0x1B4 - select-variant 'cyrU' 0x423 (follow -- 'yhooktop') + select-variant 'yhooktop' 0x1B4 (follow -- 'y') + select-variant 'cyrU' 0x423 (omit -- {.v-y-cursive true .cv49 true}) - turned 'turny.straight' nothing 'y.straight' MIDDLE (XH / 2) MarkSet.b - turned 'turny.curly' nothing 'y.curly' MIDDLE (XH / 2) MarkSet.b - select-variant 'turny' 0x28E (follow -- 'yhooktop') + turned 'turny' 0x28E 'y' MIDDLE (XH / 2) MarkSet.b define [LambdaBarOverlayShape] : FlatSlashShape [mix SB RIGHTSB 0.45] [mix 0 CAP 0.8] (OVERLAYSTROKE / 2) diff --git a/glyphs/symbol-punctuation.ptl b/glyphs/symbol-punctuation.ptl index b7b9a239f..1fcd54e79 100644 --- a/glyphs/symbol-punctuation.ptl +++ b/glyphs/symbol-punctuation.ptl @@ -870,12 +870,6 @@ glyph-block Symbol-Punctuation : begin set-width WIDTH include : HBarTop SB RIGHTSB 0 save 'underscore.belowBaseline' - branch - include : HBarTop SB RIGHTSB (-openBoxGap) - save 'doubleUnderscore.belowBaseline' - branch - include : OpenBoxSide (-STROKE) - save 'openBox.belowBaseline' sketch # underscore.low set-width WIDTH diff --git a/utility/export-data/coverage-export/gather-coverage-data.js b/utility/export-data/coverage-export/gather-coverage-data.js index 6e3f15145..c9dd87adf 100644 --- a/utility/export-data/coverage-export/gather-coverage-data.js +++ b/utility/export-data/coverage-export/gather-coverage-data.js @@ -2,17 +2,17 @@ const blockData = require("./block-data"); const ucdNames = require("unicode-13.0.0/Names"); const ugc = require("unicode-13.0.0/General_Category"); -module.exports = function(rawCov) { +module.exports = function (rawCov) { const result = []; const glyphNameMap = new Map(); - for (const [lchFont, [gn, ck]] of rawCov) { - glyphNameMap.set(lchFont, gn); + for (const [lchFont, [gn, tv, cv]] of rawCov) { + glyphNameMap.set(lchFont, [gn, tv, cv]); } for (const [[lchBlockStart, lchBlockEnd], block] of blockData) { let blockResults = []; let processed = new Set(); - for (const [lchFont, [_gn, ck]] of rawCov) { + for (const [lchFont] of rawCov) { if (lchFont < 0x20 || lchFont < lchBlockStart || lchFont > lchBlockEnd) continue; const lchStart = (lchFont >>> 4) << 4; const lchEnd = lchStart + 0x10; @@ -20,12 +20,15 @@ module.exports = function(rawCov) { if (processed.has(lch)) continue; const chName = ucdNames.get(lch); const gc = ugc.get(lch); + const inFont = glyphNameMap.get(lch); blockResults.push({ lch, gc, charName: chName, - glyphName: glyphNameMap.get(lch), - inFont: glyphNameMap.has(lch) + glyphName: inFont ? inFont[0] : undefined, + inFont: !!inFont, + typographicVariants: inFont && inFont[1].length ? inFont[1] : undefined, + charVariants: inFont && inFont[2].length ? inFont[2] : undefined, }); processed.add(lch); } @@ -33,7 +36,7 @@ module.exports = function(rawCov) { if (blockResults.length) { result.push({ name: block, - characters: blockResults.sort((a, b) => a.lch - b.lch) + characters: blockResults.sort((a, b) => a.lch - b.lch), }); } } diff --git a/utility/export-data/supported-languages.js b/utility/export-data/supported-languages.js index bc96692d6..aa7ed9f9b 100644 --- a/utility/export-data/supported-languages.js +++ b/utility/export-data/supported-languages.js @@ -2,7 +2,7 @@ const cldr = require("cldr"); const fs = require("fs-extra"); const gatherCov = require("./coverage-export/gather-coverage-data"); -module.exports = async function(charMapPath) { +module.exports = async function (charMapPath) { const charMap = await fs.readJson(charMapPath); const supportLocaleSet = new Set(); @@ -18,7 +18,7 @@ module.exports = async function(charMapPath) { ...(exemplar.auxiliary || []), ...(exemplar.index || []), ...(exemplar.numbers || []), - ...(exemplar.punctuation || []) + ...(exemplar.punctuation || []), ].join(""); let fullSupport = true; @@ -58,14 +58,15 @@ module.exports = async function(charMapPath) { } const rawCoverage = new Map(); - for (const [gn, codes, cl] of charMap) for (const u of codes) rawCoverage.set(u, [gn, cl]); + for (const [gn, codes, tv, cv] of charMap) + for (const u of codes) rawCoverage.set(u, [gn, tv, cv]); return { stats: { glyphCount: charMap.length, - codePointCount: rawCoverage.size + codePointCount: rawCoverage.size, }, unicodeCoverage: gatherCov(rawCoverage), - languages: Array.from(supportLangSet).sort() + languages: Array.from(supportLangSet).sort(), }; }; diff --git a/variants.toml b/variants.toml index ed31e7aca..04be1e773 100644 --- a/variants.toml +++ b/variants.toml @@ -323,21 +323,21 @@ tag = "cv48" sampler = 'y' description = 'More-straight letter `y`' y = "straight" -yhooktop = "straight" +cyrU = "straight" [simple.v-y-curly] tag = "cv79" sampler = 'y' description = 'More curly letter `y`, like Iosevka 2.x' y = "curly" -yhooktop = "curly" +cyrU = "curly" [simple.v-y-cursive] tag = "cv49" sampler = 'y' description = 'Cursive-like `y`' y = "cursive" -yhooktop = "straight" +cyrU = "straight" [simple.v-eszet-traditional] tag = 'cv34'