Optimize
This commit is contained in:
parent
4139b9b142
commit
ce4212a639
4 changed files with 79 additions and 42 deletions
|
@ -3,15 +3,16 @@ import path from "path";
|
||||||
import url from "url";
|
import url from "url";
|
||||||
|
|
||||||
import * as Toml from "@iarna/toml";
|
import * as Toml from "@iarna/toml";
|
||||||
import { FontIo, Ot, CliProc } from "ot-builder";
|
import { CliProc, Ot } from "ot-builder";
|
||||||
|
|
||||||
import { assignFontNames, createNamingDictFromArgv } from "./gen/meta/naming.mjs";
|
import { assignFontNames, createNamingDictFromArgv } from "./gen/meta/naming.mjs";
|
||||||
|
import { readTTF, saveTTF } from "./support/font-io/font-io.mjs";
|
||||||
|
|
||||||
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
||||||
|
|
||||||
export default main;
|
export default main;
|
||||||
async function main(argv) {
|
async function main(argv) {
|
||||||
const font = await readTTF(argv);
|
const font = await readTTF(argv.i);
|
||||||
|
|
||||||
const naming = createNamingDictFromArgv(argv);
|
const naming = createNamingDictFromArgv(argv);
|
||||||
assignFontNames(font, naming, false);
|
assignFontNames(font, naming, false);
|
||||||
|
@ -24,17 +25,26 @@ async function main(argv) {
|
||||||
await deriveTerm(font);
|
await deriveTerm(font);
|
||||||
await deriveFixed_DropWideChars(font);
|
await deriveFixed_DropWideChars(font);
|
||||||
await deriveFixed_DropFeatures(font, false);
|
await deriveFixed_DropFeatures(font, false);
|
||||||
CliProc.gcFont(font, Ot.ListGlyphStoreFactory);
|
|
||||||
break;
|
break;
|
||||||
case "fixed":
|
case "fixed":
|
||||||
await deriveTerm(font);
|
await deriveTerm(font);
|
||||||
await deriveFixed_DropWideChars(font);
|
await deriveFixed_DropWideChars(font);
|
||||||
await deriveFixed_DropFeatures(font, true);
|
await deriveFixed_DropFeatures(font, true);
|
||||||
CliProc.gcFont(font, Ot.ListGlyphStoreFactory);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
await saveTTF(argv, font);
|
await saveTTF(argv.oNoGc, font);
|
||||||
|
|
||||||
|
switch (argv.shape.spacing) {
|
||||||
|
case "fontconfig-mono":
|
||||||
|
case "fixed":
|
||||||
|
CliProc.gcFont(font, Ot.ListGlyphStoreFactory);
|
||||||
|
await saveTTF(argv.o, font);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
await fs.promises.copyFile(argv.oNoGc, argv.o);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// To derive -Term variants, simply apply NWID
|
// To derive -Term variants, simply apply NWID
|
||||||
|
@ -98,18 +108,3 @@ async function deriveFixed_DropFeatures(font, fFixed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function readTTF(argv) {
|
|
||||||
const buf = await fs.promises.readFile(argv.i);
|
|
||||||
const sfnt = FontIo.readSfntOtf(buf);
|
|
||||||
const font = FontIo.readFont(sfnt, Ot.ListGlyphStoreFactory);
|
|
||||||
return font;
|
|
||||||
}
|
|
||||||
async function saveTTF(argv, font) {
|
|
||||||
const sfnt = FontIo.writeFont(font, {
|
|
||||||
glyphStore: { statOs2XAvgCharWidth: false },
|
|
||||||
generateDummyDigitalSignature: true
|
|
||||||
});
|
|
||||||
const buf = FontIo.writeSfntOtf(sfnt);
|
|
||||||
await fs.promises.writeFile(argv.o, buf);
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,10 +5,10 @@ import zlib from "zlib";
|
||||||
|
|
||||||
import * as Toml from "@iarna/toml";
|
import * as Toml from "@iarna/toml";
|
||||||
import { encode } from "@msgpack/msgpack";
|
import { encode } from "@msgpack/msgpack";
|
||||||
import { FontIo } from "ot-builder";
|
|
||||||
|
|
||||||
import { buildFont } from "./gen/build-font.mjs";
|
import { buildFont } from "./gen/build-font.mjs";
|
||||||
import { createNamingDictFromArgv } from "./gen/meta/naming.mjs";
|
import { createNamingDictFromArgv } from "./gen/meta/naming.mjs";
|
||||||
|
import { saveTTF } from "./support/font-io/font-io.mjs";
|
||||||
import { createGrDisplaySheet } from "./support/gr.mjs";
|
import { createGrDisplaySheet } from "./support/gr.mjs";
|
||||||
import { applyLigationData } from "./support/ligation-data.mjs";
|
import { applyLigationData } from "./support/ligation-data.mjs";
|
||||||
import { applyMetricOverride } from "./support/metric-override.mjs";
|
import { applyMetricOverride } from "./support/metric-override.mjs";
|
||||||
|
@ -17,6 +17,17 @@ import * as VariantData from "./support/variant-data.mjs";
|
||||||
|
|
||||||
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
|
||||||
|
|
||||||
|
export default main;
|
||||||
|
async function main(argv) {
|
||||||
|
const paraT = await getParameters();
|
||||||
|
const { font, glyphStore, cacheUpdated } = await buildFont(argv, paraT(argv));
|
||||||
|
if (argv.oCharMap) await saveCharMap(argv, glyphStore);
|
||||||
|
if (argv.o) await saveTTF(argv.o, font);
|
||||||
|
return { cacheUpdated };
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Parameter preparation
|
// Parameter preparation
|
||||||
async function getParameters() {
|
async function getParameters() {
|
||||||
const PARAMETERS_TOML = path.resolve(__dirname, "../params/parameters.toml");
|
const PARAMETERS_TOML = path.resolve(__dirname, "../params/parameters.toml");
|
||||||
|
@ -72,15 +83,7 @@ async function tryParseToml(str) {
|
||||||
function deepClone(pod) {
|
function deepClone(pod) {
|
||||||
return JSON.parse(JSON.stringify(pod));
|
return JSON.parse(JSON.stringify(pod));
|
||||||
}
|
}
|
||||||
// Save TTF
|
|
||||||
async function saveTTF(argv, font) {
|
|
||||||
const sfnt = FontIo.writeFont(font, {
|
|
||||||
glyphStore: { statOs2XAvgCharWidth: false },
|
|
||||||
generateDummyDigitalSignature: true
|
|
||||||
});
|
|
||||||
const buf = FontIo.writeSfntOtf(sfnt);
|
|
||||||
await fs.promises.writeFile(argv.o, buf);
|
|
||||||
}
|
|
||||||
// Save character map file
|
// Save character map file
|
||||||
async function saveCharMap(argv, glyphStore) {
|
async function saveCharMap(argv, glyphStore) {
|
||||||
let charMap = [];
|
let charMap = [];
|
||||||
|
@ -93,10 +96,3 @@ async function saveCharMap(argv, glyphStore) {
|
||||||
}
|
}
|
||||||
await fs.promises.writeFile(argv.oCharMap, zlib.gzipSync(encode(charMap)));
|
await fs.promises.writeFile(argv.oCharMap, zlib.gzipSync(encode(charMap)));
|
||||||
}
|
}
|
||||||
export default (async function main(argv) {
|
|
||||||
const paraT = await getParameters();
|
|
||||||
const { font, glyphStore, cacheUpdated } = await buildFont(argv, paraT(argv));
|
|
||||||
if (argv.oCharMap) await saveCharMap(argv, glyphStore);
|
|
||||||
if (argv.o) await saveTTF(argv, font);
|
|
||||||
return { cacheUpdated };
|
|
||||||
});
|
|
||||||
|
|
19
font-src/support/font-io/font-io.mjs
Normal file
19
font-src/support/font-io/font-io.mjs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
import { FontIo, Ot } from "ot-builder";
|
||||||
|
|
||||||
|
export async function readTTF(input) {
|
||||||
|
const buf = await fs.promises.readFile(input);
|
||||||
|
const sfnt = FontIo.readSfntOtf(buf);
|
||||||
|
const font = FontIo.readFont(sfnt, Ot.ListGlyphStoreFactory);
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveTTF(output, font) {
|
||||||
|
const sfnt = FontIo.writeFont(font, {
|
||||||
|
glyphStore: { statOs2XAvgCharWidth: false },
|
||||||
|
generateDummyDigitalSignature: true
|
||||||
|
});
|
||||||
|
const buf = FontIo.writeSfntOtf(sfnt);
|
||||||
|
await fs.promises.writeFile(output, buf);
|
||||||
|
}
|
|
@ -373,23 +373,28 @@ const DistUnhintedTTF = file.make(
|
||||||
await target.need(Scripts, Parameters, Dependencies, de(out.dir));
|
await target.need(Scripts, Parameters, Dependencies, de(out.dir));
|
||||||
const [fi] = await target.need(FontInfoOf(fn));
|
const [fi] = await target.need(FontInfoOf(fn));
|
||||||
|
|
||||||
|
const charMapDir = `${BUILD}/ttf/${gr}`;
|
||||||
|
const charMapPath = `${charMapDir}/${fn}.charmap.mpz`;
|
||||||
|
const noGcTtfPath = `${charMapDir}/${fn}.no-gc.ttf`;
|
||||||
|
|
||||||
if (fi.spacingDerive) {
|
if (fi.spacingDerive) {
|
||||||
// The font is a spacing variant, and is derivable form an existing
|
// The font is a spacing variant, and is derivable form an existing
|
||||||
// normally-spaced variant.
|
// normally-spaced variant.
|
||||||
const spD = fi.spacingDerive;
|
const spD = fi.spacingDerive;
|
||||||
const [deriveFrom] = await target.need(DistUnhintedTTF(spD.prefix, spD.fileName));
|
const [deriveFrom] = await target.need(
|
||||||
|
DistUnhintedTTF(spD.prefix, spD.fileName),
|
||||||
|
de(charMapDir)
|
||||||
|
);
|
||||||
|
|
||||||
echo.action(echo.hl.command(`Create TTF`), out.full);
|
echo.action(echo.hl.command(`Create TTF`), out.full);
|
||||||
await silently.node(`font-src/derive-spacing.mjs`, {
|
await silently.node(`font-src/derive-spacing.mjs`, {
|
||||||
i: deriveFrom.full,
|
i: deriveFrom.full,
|
||||||
|
oNoGc: noGcTtfPath,
|
||||||
o: out.full,
|
o: out.full,
|
||||||
...fi
|
...fi
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Ab-initio build
|
// Ab-initio build
|
||||||
const charMapDir = `${BUILD}/ttf/${gr}`;
|
|
||||||
const charMapPath = `${charMapDir}/${fn}.charmap.mpz`;
|
|
||||||
|
|
||||||
const cacheFileName =
|
const cacheFileName =
|
||||||
`${Math.round(1000 * fi.shape.weight)}-${Math.round(1000 * fi.shape.width)}-` +
|
`${Math.round(1000 * fi.shape.weight)}-${Math.round(1000 * fi.shape.width)}-` +
|
||||||
`${Math.round(3600 * fi.shape.slopeAngle)}-${fi.shape.slope}`;
|
`${Math.round(3600 * fi.shape.slopeAngle)}-${fi.shape.slope}`;
|
||||||
|
@ -428,6 +433,27 @@ const DistUnhintedTTF = file.make(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const BuildNoGcTtfImpl = file.make(
|
||||||
|
(gr, f) => `${BUILD}/ttf/${gr}/${f}.no-gc.ttf`,
|
||||||
|
async (target, output, gr, f) => {
|
||||||
|
await target.need(DistUnhintedTTF(gr, f));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const BuildNoGcTtf = task.make(
|
||||||
|
(gr, fn) => `BuildNoGcTtf::${gr}/${fn}`,
|
||||||
|
async (target, gr, fn) => {
|
||||||
|
const [fi] = await target.need(FontInfoOf(fn));
|
||||||
|
if (fi.spacingDerive) {
|
||||||
|
const [noGc] = await target.need(BuildNoGcTtfImpl(gr, fn));
|
||||||
|
return noGc;
|
||||||
|
} else {
|
||||||
|
const [distUnhinted] = await target.need(DistUnhintedTTF(gr, fn));
|
||||||
|
return distUnhinted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const BuildCM = file.make(
|
const BuildCM = file.make(
|
||||||
(gr, f) => `${BUILD}/ttf/${gr}/${f}.charmap.mpz`,
|
(gr, f) => `${BUILD}/ttf/${gr}/${f}.charmap.mpz`,
|
||||||
async (target, output, gr, f) => {
|
async (target, output, gr, f) => {
|
||||||
|
@ -678,9 +704,10 @@ async function buildCompositeTtc(out, inputs) {
|
||||||
echo.action(echo.hl.command(`Create TTC`), out.full, echo.hl.operator("<-"), inputPaths);
|
echo.action(echo.hl.command(`Create TTC`), out.full, echo.hl.operator("<-"), inputPaths);
|
||||||
await absolutelySilently.run(TTCIZE, ["-o", out.full], inputPaths);
|
await absolutelySilently.run(TTCIZE, ["-o", out.full], inputPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function buildGlyphSharingTtc(target, parts, out) {
|
async function buildGlyphSharingTtc(target, parts, out) {
|
||||||
await target.need(de`${out.dir}`);
|
await target.need(de`${out.dir}`);
|
||||||
const [ttfInputs] = await target.need(parts.map(part => DistUnhintedTTF(part.dir, part.file)));
|
const [ttfInputs] = await target.need(parts.map(part => BuildNoGcTtf(part.dir, part.file)));
|
||||||
const tmpTtc = `${out.dir}/${out.name}.unhinted.ttc`;
|
const tmpTtc = `${out.dir}/${out.name}.unhinted.ttc`;
|
||||||
const ttfInputPaths = ttfInputs.map(p => p.full);
|
const ttfInputPaths = ttfInputs.map(p => p.full);
|
||||||
echo.action(echo.hl.command(`Create TTC`), out.full, echo.hl.operator("<-"), ttfInputPaths);
|
echo.action(echo.hl.command(`Create TTC`), out.full, echo.hl.operator("<-"), ttfInputPaths);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue