Website: add multiple-dimensional variation export
This commit is contained in:
parent
6b853b520b
commit
1130f0bee6
3 changed files with 69 additions and 63 deletions
|
@ -7,7 +7,7 @@ const BuildFont = require("./gen/build-font.js");
|
|||
const Parameters = require("./support/parameters");
|
||||
const FormVariantData = require("./support/variant-data");
|
||||
const FormLigationData = require("./support/ligation-data");
|
||||
const { AnyCv, CvDecompose } = require("./support/gr");
|
||||
const { createGrDisplaySheet } = require("./support/gr");
|
||||
const Toml = require("@iarna/toml");
|
||||
|
||||
module.exports = async function main(argv) {
|
||||
|
@ -101,33 +101,7 @@ async function saveCharMap(argv, font) {
|
|||
for (const gid in font.glyf) {
|
||||
const glyph = font.glyf[gid];
|
||||
if (!glyph) continue;
|
||||
|
||||
const glyphIsHidden = /^\./.test(gid);
|
||||
const typographicFeatures = [];
|
||||
if (!glyphIsHidden) {
|
||||
if (/\.NWID$/.test(gid) || /\.WWID$/.test(gid))
|
||||
typographicFeatures.push("NWID", "WWID");
|
||||
if (/\.lnum$/.test(gid) || /\.onum$/.test(gid))
|
||||
typographicFeatures.push("lnum", "onum");
|
||||
}
|
||||
|
||||
let variantFeatures;
|
||||
if (CvDecompose.get(glyph)) {
|
||||
const variantFeatureSet = new Set();
|
||||
const decomposition = CvDecompose.get(glyph);
|
||||
for (const gn of decomposition) {
|
||||
const component = font.glyf[gn];
|
||||
if (!component) continue;
|
||||
for (const cv of AnyCv.query(component)) variantFeatureSet.add(cv.tag);
|
||||
}
|
||||
variantFeatures = Array.from(variantFeatureSet).sort();
|
||||
} else {
|
||||
variantFeatures = AnyCv.query(glyph)
|
||||
.map(gr => gr.tag)
|
||||
.sort();
|
||||
}
|
||||
|
||||
charMap.push([glyph.name, glyph.unicode, typographicFeatures, variantFeatures]);
|
||||
charMap.push([glyph.name, glyph.unicode, ...createGrDisplaySheet(font, gid)]);
|
||||
}
|
||||
await fs.writeFile(argv.oCharMap, JSON.stringify(charMap), "utf8");
|
||||
}
|
||||
|
|
|
@ -224,6 +224,68 @@ function getGrMesh(gidList, grq, fnGidToGlyph) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
function createGrDisplaySheet(font, gid) {
|
||||
const glyph = font.glyf[gid];
|
||||
if (!glyph) return [];
|
||||
|
||||
// Query selected typographic features -- mostly NWID and WWID
|
||||
let typographicFeatures = [];
|
||||
queryPairFeatureTags(gid, "NWID", "WWID", typographicFeatures);
|
||||
queryPairFeatureTags(gid, "lnum", "onum", typographicFeatures);
|
||||
|
||||
let charVariantFeatures = [];
|
||||
const decomposition = CvDecompose.get(glyph);
|
||||
if (decomposition) {
|
||||
const variantFeatureSet = new Set();
|
||||
for (const componentGn of decomposition) {
|
||||
const component = font.glyf[componentGn];
|
||||
if (!component) continue;
|
||||
const cvRow = queryCvFeatureTagsOf(componentGn, component, variantFeatureSet);
|
||||
if (cvRow.length) charVariantFeatures.push(cvRow);
|
||||
}
|
||||
} else {
|
||||
const cvRow = queryCvFeatureTagsOf(gid, glyph, null);
|
||||
if (cvRow.length) charVariantFeatures.push(cvRow);
|
||||
}
|
||||
|
||||
return [typographicFeatures, charVariantFeatures];
|
||||
}
|
||||
function queryPairFeatureTags(gid, f1, f2, sink) {
|
||||
const glyphIsHidden = /^\./.test(gid);
|
||||
if (!glyphIsHidden) {
|
||||
const re1 = new RegExp(`\\.${f1}$`),
|
||||
re2 = new RegExp(`\\.${f2}$`);
|
||||
if (re1.test(gid) || re2.test(gid)) {
|
||||
sink.push(f1, f2);
|
||||
}
|
||||
}
|
||||
}
|
||||
function byTagPreference(a, b) {
|
||||
const ua = a.tag.toUpperCase(),
|
||||
ub = b.tag.toUpperCase();
|
||||
if (ua < ub) return -1;
|
||||
if (ua > ub) return 1;
|
||||
return 0;
|
||||
}
|
||||
function queryCvFeatureTagsOf(gid, glyph, vfs) {
|
||||
const cvs = AnyCv.query(glyph).sort(byTagPreference);
|
||||
let results = [];
|
||||
let existingGlyphs = new Set();
|
||||
for (const gr of cvs) {
|
||||
const tag = gr.tag;
|
||||
const target = gr.get(glyph);
|
||||
if (target === gid) continue;
|
||||
if (existingGlyphs.has(target)) continue;
|
||||
existingGlyphs.add(target);
|
||||
if (!vfs) results.push(tag);
|
||||
else if (!vfs.has(tag)) {
|
||||
results.push(tag);
|
||||
vfs.add(tag);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
exports.Dotless = Dotless;
|
||||
exports.Cv = Cv;
|
||||
exports.AnyCv = AnyCv;
|
||||
|
@ -236,3 +298,4 @@ exports.DoNotDeriveVariants = DoNotDeriveVariants;
|
|||
exports.AnyDerivingCv = AnyDerivingCv;
|
||||
exports.CcmpDecompose = CcmpDecompose;
|
||||
exports.CvDecompose = CvDecompose;
|
||||
exports.createGrDisplaySheet = createGrDisplaySheet;
|
||||
|
|
|
@ -23,11 +23,6 @@ module.exports = function (covUpright, covItalic, covOblique) {
|
|||
const [glyphName, typographicVariants, charVariantsUpright] = cdUpright;
|
||||
const [, , charVariantsItalic] = cdItalic;
|
||||
const [, , charVariantsOblique] = cdOblique;
|
||||
const interleaved = interleaveCharacterVariants(
|
||||
new Set(charVariantsUpright),
|
||||
new Set(charVariantsItalic),
|
||||
new Set(charVariantsOblique)
|
||||
);
|
||||
blockResults.push({
|
||||
lch,
|
||||
gc,
|
||||
|
@ -35,10 +30,9 @@ module.exports = function (covUpright, covItalic, covOblique) {
|
|||
inFont: true,
|
||||
glyphName: glyphName,
|
||||
typographicVariants: typographicVariants,
|
||||
charVariants: interleaved.common,
|
||||
charVariantsUpright: interleaved.uprightSpecific,
|
||||
charVariantsItalic: interleaved.italicSpecific,
|
||||
charVariantsOblique: interleaved.obliqueSpecific
|
||||
charVariantsUpright,
|
||||
charVariantsItalic,
|
||||
charVariantsOblique
|
||||
});
|
||||
} else {
|
||||
blockResults.push({
|
||||
|
@ -46,12 +40,7 @@ module.exports = function (covUpright, covItalic, covOblique) {
|
|||
gc,
|
||||
charName: chName,
|
||||
inFont: false,
|
||||
glyphName: undefined,
|
||||
typographicVariants: undefined,
|
||||
charVariants: undefined,
|
||||
charVariantsUpright: undefined,
|
||||
charVariantsItalic: undefined,
|
||||
charVariantsOblique: undefined
|
||||
glyphName: undefined
|
||||
});
|
||||
}
|
||||
processed.add(lch);
|
||||
|
@ -66,23 +55,3 @@ module.exports = function (covUpright, covItalic, covOblique) {
|
|||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
function interleaveCharacterVariants(up, it, ob) {
|
||||
const common = new Set();
|
||||
for (const cv of up) {
|
||||
if (it.has(cv) && ob.has(cv)) common.add(cv);
|
||||
}
|
||||
const upS = new Set(),
|
||||
itS = new Set(),
|
||||
obS = new Set();
|
||||
for (const cv of up) if (!common.has(cv)) upS.add(cv);
|
||||
for (const cv of it) if (!common.has(cv)) itS.add(cv);
|
||||
for (const cv of ob) if (!common.has(cv)) obS.add(cv);
|
||||
|
||||
return {
|
||||
common: [...common],
|
||||
uprightSpecific: [...upS],
|
||||
italicSpecific: [...itS],
|
||||
obliqueSpecific: [...obS]
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue