Cleanup deps and GC/Quadify code

This commit is contained in:
Belleve Invis 2020-03-21 12:28:32 -07:00
parent fbb977c16f
commit 866dc4daae
19 changed files with 493 additions and 222 deletions

View file

@ -11,7 +11,7 @@
"experimentalObjectRestSpread": true "experimentalObjectRestSpread": true
} }
}, },
"extends": "eslint:recommended", "extends": ["eslint:recommended", "plugin:prettier/recommended"],
"rules": { "rules": {
"indent": ["error", "tab", { "SwitchCase": 1 }], "indent": ["error", "tab", { "SwitchCase": 1 }],
"quotes": ["error", "double", { "allowTemplateLiterals": true }], "quotes": ["error", "double", { "allowTemplateLiterals": true }],

View file

@ -1,3 +1,5 @@
"use strict";
const EmptyFont = require("./empty-font.js"); const EmptyFont = require("./empty-font.js");
const buildGlyphs = require("./build-glyphs.js"); const buildGlyphs = require("./build-glyphs.js");
@ -6,6 +8,7 @@ const { assignFontNames } = require("../meta/naming");
const { setFontMetrics } = require("../meta/aesthetics"); const { setFontMetrics } = require("../meta/aesthetics");
const regulateGlyphs = require("../support/regulate-glyph"); const regulateGlyphs = require("../support/regulate-glyph");
const gcFont = require("./gc");
module.exports = function(para) { module.exports = function(para) {
const font = EmptyFont(); const font = EmptyFont();
@ -39,6 +42,8 @@ module.exports = function(para) {
font.glyf = glyf; font.glyf = glyf;
font.cmap = cmap; font.cmap = cmap;
gcFont(font);
return font; return font;
}; };

View file

@ -1,3 +1,5 @@
"use strict";
module.exports = function() { module.exports = function() {
return { return {
head: { head: {

View file

@ -1,18 +1,83 @@
"use strict"; "use strict";
const { Workflow, introduce, build, gc } = require("megaminx"); module.exports = function gcFont(font) {
const argv = require("yargs").argv; let sink = new Set();
let glyphCount = 0;
async function recipe(ctx, config, argv) { sink.add(".notdef", ".null");
const a = await ctx.run(introduce, "a", { from: argv.i });
await ctx.run(gc, "a"); if (font.cmap) {
await ctx.run(build, "a", { to: argv.o, optimize: true }); for (const k in font.cmap) {
if (font.cmap[k]) sink.add(font.cmap[k]);
}
}
if (font.cmap_uvs) {
for (const k in font.cmap_uvs) {
if (font.cmap_uvs[k]) sink.add(font.cmap_uvs[k]);
}
}
do {
glyphCount = sink.size;
if (font.GSUB) {
for (const l in font.GSUB.lookups) {
const lookup = font.GSUB.lookups[l];
if (!lookup || !lookup.subtables) continue;
if (lookup && lookup.subtables) {
for (let st of lookup.subtables) {
markSubtable(sink, lookup.type, st);
}
}
}
}
if (font.glyf) {
for (const g in font.glyf) {
const glyph = font.glyf[g];
if (!glyph || !glyph.references) continue;
for (const ref of glyph.references) if (ref && ref.glyph) sink.add(ref.glyph);
}
}
let glyphCount1 = sink.size;
if (glyphCount1 === glyphCount) break;
} while (true);
if (font.glyf) {
const filteredGlyf = {};
for (const key in font.glyf) {
if (sink.has(key)) filteredGlyf[key] = font.glyf[key];
}
font.glyf = filteredGlyf;
} else {
font.glyf = {};
}
};
function markSubtable(sink, type, st) {
switch (type) {
case "gsub_single":
case "gsub_multi":
case "gsub_alternate":
for (const k in st) if (sink.has(k) && st[k]) sink.add(st[k]);
break;
case "gsub_ligature":
for (const sub of st.substitutions) {
let check = true;
for (const g of sub.from) if (!sink.has(g)) check = false;
if (check && sub.to) sink.add(sub.to);
}
break;
case "gsub_chaining":
break;
case "gsub_reverse":
if (st.match && st.to) {
const matchCoverage = st.match[st.inputIndex];
for (let j = 0; j < matchCoverage.length; j++) {
if (sink.has(matchCoverage[j]) && st.to[j]) sink.add(st.to[j]);
}
}
break;
}
} }
async function main() {
const config = {};
const flow = new Workflow(config);
await flow.run(recipe, config, argv);
}
main();

View file

@ -4,7 +4,7 @@ import '../support/transform' as : Transform && [object [transformPoint tp]]
import [curveToContour OffsetCurve] from '../support/curve-util' import [curveToContour OffsetCurve] from '../support/curve-util'
import [mix linreg clamp fallback] from '../support/utils' import [mix linreg clamp fallback] from '../support/utils'
import [designParameters] from '../meta/aesthetics' import [designParameters] from '../meta/aesthetics'
import [CubicBezierCurve autoQuadify] from "primitive-quadify-off-curves" import [Curve Quadify] from "typo-geom"
glyph-module glyph-module
@ -209,7 +209,7 @@ glyph-block Overmarks : begin
define z2 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd tildeWaveX] [y : mix tbot ttop tildeWave] define z2 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd tildeWaveX] [y : mix tbot ttop tildeWave]
define z3 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd (1 - tildeWaveX)] [y : mix tbot ttop (1 - tildeWave)] define z3 : tp currentGlyph.gizmo : object [x : mix leftEnd rightEnd (1 - tildeWaveX)] [y : mix tbot ttop (1 - tildeWave)]
define z4 : tp currentGlyph.gizmo : object [x rightEnd] [y ttop] define z4 : tp currentGlyph.gizmo : object [x rightEnd] [y ttop]
define bone : new CubicBezierCurve z1 z2 z3 z4 define bone : new Curve.Bez3 z1 z2 z3 z4
define inner : curveToContour [new OffsetCurve bone (+hs) HVCONTRAST] (1 / 256) define inner : curveToContour [new OffsetCurve bone (+hs) HVCONTRAST] (1 / 256)
define outer : curveToContour [new OffsetCurve bone (-hs) HVCONTRAST] (1 / 256) define outer : curveToContour [new OffsetCurve bone (-hs) HVCONTRAST] (1 / 256)

View file

@ -36,13 +36,13 @@ export : define [buildCCMP sink glyphs markGlyphs] : begin
define lookupCcmp2 : add-lookup sink : object define lookupCcmp2 : add-lookup sink : object
.type 'gsub_ligature' .type 'gsub_ligature'
.subtables : list : object .subtables : list : object : substitutions : list
psilivaria {'commaAbove' 'graveAbove'} object [from {'commaAbove' 'graveAbove'}] [to 'psilivaria']
psilioxia {'commaAbove' 'acuteAbove'} object [from {'commaAbove' 'acuteAbove'}] [to 'psilioxia']
psiliperispomeni {'commaAbove' 'perispomeniAbove'} object [from {'commaAbove' 'perispomeniAbove'}] [to 'psiliperispomeni']
dasiavaria {'revCommaAbove' 'graveAbove'} object [from {'revCommaAbove' 'graveAbove'}] [to 'dasiavaria']
dasiaoxia {'revCommaAbove' 'acuteAbove'} object [from {'revCommaAbove' 'acuteAbove'}] [to 'dasiaoxia']
dasiaperispomeni {'revCommaAbove' 'perispomeniAbove'} object [from {'revCommaAbove' 'perispomeniAbove'}] [to 'dasiaperispomeni']
ccmp.lookups.push lookupCcmp1 lookupCcmp2 ccmp.lookups.push lookupCcmp1 lookupCcmp2
add-common-feature sink ccmp add-common-feature sink ccmp

View file

@ -12,28 +12,27 @@
}, },
"dependencies": { "dependencies": {
"caryll-shapeops": "^0.3.1", "caryll-shapeops": "^0.3.1",
"megaminx": "^0.9.0",
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
"otfcc-ttcize": "^0.9.6", "otfcc-ttcize": "^0.9.6",
"primitive-quadify-off-curves": "^0.6.3", "typo-geom": "0.5.1",
"spiro": "^1.1.0", "spiro": "^1.1.0",
"toml": "^3.0.0", "toml": "^3.0.0",
"topsort": "0.0.2", "topsort": "^0.0.2",
"ttf2woff": "^2.0.1", "ttf2woff": "^2.0.1",
"ttf2woff2": "^3.0.0", "ttf2woff2": "^3.0.0",
"unorm": "^1.6.0", "unorm": "^1.6.0",
"verda": "^1.0.0-12", "verda": "^1.0.0",
"fs-extra": "^8.1.0", "fs-extra": "^9.0.0",
"yargs": "^15.1.0" "yargs": "^15.3.1"
}, },
"devDependencies": { "devDependencies": {
"cldr": "^5.5.4", "cldr": "^5.5.4",
"colors": "^1.3.3", "colors": "^1.4.0",
"ejs": "^3.0.1", "ejs": "^3.0.1",
"eslint": "^5.2.0", "eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.0",
"patel": "^0.33.1", "patel": "^0.33.1",
"patrisika-scopes": "^0.11.1", "semver": "^7.1.3",
"semver": "^7.1.1", "stylus": "^0.54.7"
"stylus": "^0.54.5"
} }
} }

View file

@ -1,6 +1,8 @@
"use strict"; "use strict";
const quadify = require("primitive-quadify-off-curves"); const typoGeom = require("typo-geom");
const Point = require("./point");
const { mix } = require("./utils");
exports.OffsetCurve = class OffsetCurve { exports.OffsetCurve = class OffsetCurve {
constructor(bone, offset, contrast) { constructor(bone, offset, contrast) {
@ -38,7 +40,7 @@ exports.curveToContour = function(curve, err) {
cubic: false, cubic: false,
on: true on: true
}); });
const offPoints = quadify.autoQuadify(curve, err || 1); const offPoints = typoGeom.Quadify.auto(curve, err || 1);
for (let k = 0; k < offPoints.length; k++) { for (let k = 0; k < offPoints.length; k++) {
const z = offPoints[k]; const z = offPoints[k];
if (k > 0) { if (k > 0) {
@ -64,3 +66,211 @@ exports.curveToContour = function(curve, err) {
}); });
return exitPoints; return exitPoints;
}; };
function removeMids(contour) {
for (let rounds = 0; rounds < 255; rounds++) {
const n0 = contour.length;
let last = contour.length - 1;
for (let j = 0; j < contour.length - 1; j++) {
if (
Math.abs(contour[j].x - contour[j + 1].x) < 1 &&
Math.abs(contour[j].y - contour[j + 1].y) < 1
) {
contour[j + 1].rem = true;
contour[j].on = true;
}
}
while (
last > 0 &&
Math.abs(contour[0].x - contour[last].x) < 1 &&
Math.abs(contour[0].y - contour[last].y) < 1
) {
contour[last].rem = true;
contour[0].on = true;
last -= 1;
}
contour = contour.filter(x => !x.rem);
last = contour.length - 1;
for (let j = 1; j < contour.length - 1; j++) {
if (!contour[j - 1].on && contour[j].on && !contour[j + 1].on) {
const mx = contour[j - 1].x + contour[j + 1].x;
const my = contour[j - 1].y + contour[j + 1].y;
const dy = contour[j - 1].y - contour[j + 1].y;
if (
Math.abs(dy) >= 1 &&
Math.abs(contour[j].x * 2 - mx) < 1 &&
Math.abs(contour[j].y * 2 - my) < 1
) {
contour[j].rem = true;
}
}
}
if (!contour[last].rem && !contour[last].on && contour[0].on && !contour[1].on) {
const mx = contour[last].x + contour[1].x;
const my = contour[last].y + contour[1].y;
if (Math.abs(contour[0].x * 2 - mx) < 1 && Math.abs(contour[0].y * 2 - my) < 1) {
contour[0].rem = true;
}
}
contour = contour.filter(x => !x.rem);
const n = contour.length;
if (n >= n0) break;
}
return contour;
}
function extPrior(a, b) {
return a.y < b.y || (a.y === b.y && ((a.on && !b.on) || (a.on === b.on && a.x < b.x)));
}
function canonicalStart(_points) {
const points = _points.reverse().map(z => {
z.x = Math.round(z.x * 1024) / 1024;
z.y = Math.round(z.y * 1024) / 1024;
return z;
});
let jm = 0;
for (var j = 0; j < points.length * 2; j++) {
if (extPrior(points[j % points.length], points[jm])) {
jm = j % points.length;
}
}
return points.slice(jm).concat(points.slice(0, jm));
}
function colinear(x1, y1, x2, y2, x3, y3, err) {
const det = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2);
return det <= err && det >= -err;
}
function inspan(a, b, c) {
if (a > c) return inspan(c, b, a);
return a <= b && b <= c;
}
function handle(z1, z2, z3, z4, err) {
if (
colinear(z1.x, z1.y, z2.x, z2.y, z4.x, z4.y, err) &&
colinear(z1.x, z1.y, z3.x, z3.y, z4.x, z4.y, err) &&
inspan(z1.x, z2.x, z4.x) &&
inspan(z1.y, z2.y, z4.y) &&
inspan(z1.x, z3.x, z4.x) &&
inspan(z1.y, z3.y, z4.y)
) {
return [];
}
const curve = new typoGeom.Curve.Bez3(z1, z2, z3, z4);
const offPoints = typoGeom.Quadify.auto(curve, err);
const ans = [];
for (const z of offPoints) {
ans.push(Point.offFrom(z));
}
return ans;
}
function convertContourToTt(contour, err) {
if (contour.length === 0) return [];
if (contour.length === 1) return [contour[0]];
err = err || 1 / 4;
const newContour = [];
let z0 = contour[0];
newContour.push(Point.cornerFrom(z0));
for (let j = 1; j < contour.length; j++) {
const z = contour[j];
if (z.on) {
newContour.push(Point.cornerFrom(z));
z0 = z;
} else if (z.cubic) {
const z1 = z;
const z2 = contour[j + 1];
const z3 = contour[j + 2];
const quadZs = handle(z0, z1, z2, z3, err);
for (const z of quadZs) newContour.push(z);
newContour.push(Point.cornerFrom(z3));
z0 = z3;
j += 2;
} else {
const zc = z;
let zf = contour[j + 1] ? contour[j + 1] : contour[0];
if (!zf.on) {
zf = Point.cornerFromXY(mix(zc.x, zf.x, 0.5), mix(zc.y, zf.y, 0.5));
}
newContour.push(Point.offFrom(zc));
newContour.push(Point.cornerFrom(zf));
z0 = zf;
j++;
}
}
return newContour;
}
function byFirstPointCoord(a, b) {
if (!a.length) return -1;
if (!b.length) return 1;
let z1 = a[0];
let z2 = b[0];
return z1.y !== z2.y
? z1.y - z2.y
: z1.x !== z2.x
? z1.x - z2.x
: byFirstPointCoord(a.slice(1), b.slice(1));
}
function convertContourListToTt(contours, err) {
err = err || 1 / 4;
let ans = [];
for (let c of contours) {
ans.push(canonicalStart(removeMids(convertContourToTt(c, err))));
}
return ans.sort(byFirstPointCoord);
}
function convertContourToCubic(contour) {
if (!contour || !contour.length) return [];
const newContour = [];
let z0 = contour[0];
newContour.push(Point.cornerFrom(z0));
for (let j = 1; j < contour.length; j++) {
const z = contour[j];
if (z.on) {
newContour.push(Point.cornerFrom(z));
z0 = z;
} else if (z.cubic) {
const z1 = z;
const z2 = contour[j + 1];
const z3 = contour[j + 2];
newContour.push(Point.cubicOffFrom(z1));
newContour.push(Point.cubicOffFrom(z2));
newContour.push(Point.cornerFrom(z3));
z0 = z3;
j += 2;
} else {
const zc = z;
let zf = contour[j + 1] ? contour[j + 1] : contour[0];
if (!zf.on) {
zf = Point.cornerFromXY(mix(zc.x, zf.x, 0.5), mix(zc.y, zf.y, 0.5));
}
const x1 = mix(z0.x, zc.x, 2 / 3);
const y1 = mix(z0.y, zc.y, 2 / 3);
const x2 = mix(zf.x, zc.x, 2 / 3);
const y2 = mix(zf.y, zc.y, 2 / 3);
newContour.push(Point.cubicOffFromXY(x1, y1));
newContour.push(Point.cubicOffFromXY(x2, y2));
newContour.push(Point.cornerFrom(zf));
z0 = zf;
j++;
}
}
return newContour;
}
exports.convertContourToTt = convertContourToTt;
exports.convertContourToCubic = convertContourToCubic;
exports.convertContourListToTt = convertContourListToTt;

View file

@ -1,7 +1,7 @@
"use strict"; "use strict";
const Transform = require("./transform.js"); const Transform = require("./transform.js");
const quadify = require("primitive-quadify-off-curves"); const typoGeom = require("typo-geom");
const SMALL = 1e-4; const SMALL = 1e-4;
@ -197,7 +197,7 @@ class BezierCurveCluster {
z4 = zs[j]; z4 = zs[j];
const z2 = mix(z1, z4, 1 / 3); const z2 = mix(z1, z4, 1 / 3);
const z3 = mix(z1, z4, 2 / 3); const z3 = mix(z1, z4, 2 / 3);
const seg = new quadify.CubicBezierCurve(z1, z2, z3, z4); const seg = new typoGeom.Curve.Bez3(z1, z2, z3, z4);
segments.push(seg); segments.push(seg);
lengths.push(this.measureLength(seg)); lengths.push(this.measureLength(seg));
last = z4; last = z4;
@ -206,7 +206,7 @@ class BezierCurveCluster {
z2 = zs[j], z2 = zs[j],
z3 = zs[j + 1], z3 = zs[j + 1],
z4 = zs[j + 2]; z4 = zs[j + 2];
const seg = new quadify.CubicBezierCurve(z1, z2, z3, z4); const seg = new typoGeom.Curve.Bez3(z1, z2, z3, z4);
segments.push(seg); segments.push(seg);
lengths.push(this.measureLength(seg)); lengths.push(this.measureLength(seg));
last = z4; last = z4;
@ -217,7 +217,7 @@ class BezierCurveCluster {
z4 = zs[j + 1]; z4 = zs[j + 1];
const z2 = mix(zm, z1, 1 / 3); const z2 = mix(zm, z1, 1 / 3);
const z3 = mix(zm, z4, 1 / 3); const z3 = mix(zm, z4, 1 / 3);
const seg = new quadify.CubicBezierCurve(z1, z2, z3, z4); const seg = new typoGeom.Curve.Bez3(z1, z2, z3, z4);
segments.push(seg); segments.push(seg);
lengths.push(this.measureLength(seg)); lengths.push(this.measureLength(seg));
last = z4; last = z4;
@ -307,7 +307,7 @@ function buildCurve(curve) {
if (nPtsOffPoints > 0) { if (nPtsOffPoints > 0) {
const curve = new BezierCurveCluster(pts); const curve = new BezierCurveCluster(pts);
if (curve.isAlmostLinear(1)) continue; if (curve.isAlmostLinear(1)) continue;
const offPoints = quadify.autoQuadify(curve, 1 / 4); const offPoints = typoGeom.Quadify.auto(curve, 1 / 4);
if (!offPoints) continue; if (!offPoints) continue;
for (let k = 0; k < offPoints.length; k++) { for (let k = 0; k < offPoints.length; k++) {
const z = offPoints[k]; const z = offPoints[k];

View file

@ -177,38 +177,3 @@ export all : class Glyph
this.start-from x y this.start-from x y
this.start-from mbx mby this.start-from mbx mby
return this return this
static [contourToStandardCubic contour] : begin
local c {}
if (!contour || !contour.length) : return c
local z0 contour.0
c.push : new Point z0.x z0.y true false false
for [local j 1] (j < contour.length) [inc j] : begin
local point contour.(j)
piecewise
point.on : begin
c.push : new Point point.x point.y true false false
set z0 point
point.cubic : begin
local z1 point
local z2 contour.(j + 1)
local z3 contour.(j + 2)
c.push : new Point z1.x z1.y false true false
c.push : new Point z2.x z2.y false true false
c.push : new Point z3.x z3.y true false false
set z0 z3
set j : j + 2
true : begin
local zc point
local zf : if contour.(j + 1) contour.(j + 1) contour.0
local x1 : mix z0.x zc.x (2 / 3)
local y1 : mix z0.y zc.y (2 / 3)
local x2 : mix zf.x zc.x (2 / 3)
local y2 : mix zf.y zc.y (2 / 3)
c.push : new Point x1 y1 false true false
c.push : new Point x2 y2 false true false
c.push : new Point zf.x zf.y true false false
set z0 zf
inc j
return c

View file

@ -1,3 +1,5 @@
"use strict";
module.exports = function formVariantData(data, para) { module.exports = function formVariantData(data, para) {
const defaultBuildup = {}; const defaultBuildup = {};

View file

@ -1,5 +1,5 @@
function maskBit(x, y) { "use strict";
return x & (1 << y);
}
module.exports = maskBit; module.exports = function maskBit(x, y) {
return x & (1 << y);
};

View file

@ -1,3 +1,5 @@
"use strict";
module.exports = function(xs, ys) { module.exports = function(xs, ys) {
let i, let i,
length = xs.length; length = xs.length;

View file

@ -1,3 +1,5 @@
"use strict";
const blend = require("./monotonic-interpolate"); const blend = require("./monotonic-interpolate");
module.exports = function(aspect, hive, params, sink) { module.exports = function(aspect, hive, params, sink) {

View file

@ -3,8 +3,22 @@ export all : class Point
this.x = x this.x = x
this.y = y this.y = y
this.on = on || false this.on = on || false
this.subdivided = subdivided || false
this.cubic = cubic || false this.cubic = cubic || false
this.subdivided = subdivided || false
static [from z on cubic subdivided] : new Point
* z.x
* z.y
* on
* cubic
* subdivided
static [cornerFrom z] : new Point z.x z.y true false false
static [offFrom z] : new Point z.x z.y false false false
static [cubicOffFrom z] : new Point z.x z.y false true false
static [cornerFromXY x y] : new Point x y true false false
static [offFromXY x y] : new Point x y false false false
static [cubicOffFromXY x y] : new Point x y false true false
static [transformed tfm x y on cubic subdivided] : new Point static [transformed tfm x y on cubic subdivided] : new Point
* x * tfm.xx + y * tfm.yx + tfm.x * x * tfm.xx + y * tfm.yx + tfm.x

View file

@ -1,7 +1,9 @@
"use strict";
const Glyph = require("./glyph"); const Glyph = require("./glyph");
const autoRef = require("./autoref"); const autoRef = require("./autoref");
const caryllShapeOps = require("caryll-shapeops"); const caryllShapeOps = require("caryll-shapeops");
const c2q = require("megaminx").geometry.c2q; const curveUtil = require("./curve-util");
function regulateGlyph(g, skew) { function regulateGlyph(g, skew) {
if (!g.contours) return; if (!g.contours) return;
@ -47,9 +49,11 @@ function regulateGlyph(g, skew) {
function simplifyContours(contours) { function simplifyContours(contours) {
const source = []; const source = [];
for (const contour of contours) { for (const contour of contours) {
if (contour.length > 2) source.push(Glyph.contourToStandardCubic(contour)); if (contour.length > 2) source.push(curveUtil.convertContourToCubic(contour));
} }
const simplified = c2q.contours(caryllShapeOps.removeOverlap(source, 1, 1 << 17, true)); const simplified = curveUtil.convertContourListToTt(
caryllShapeOps.removeOverlap(source, 1, 1 << 17, true)
);
const result = []; const result = [];
for (const contour of simplified) { for (const contour of simplified) {
if (contour.length > 2) result.push(contour); if (contour.length > 2) result.push(contour);

View file

@ -2,6 +2,7 @@ import 'spiro' as SpiroJs
import './spiroexpand' as SpiroExpansionContext import './spiroexpand' as SpiroExpansionContext
import './fairify' as fairify import './fairify' as fairify
import 'caryll-shapeops' as ShapeOps import 'caryll-shapeops' as ShapeOps
import './curve-util' as CurveUtil
import './transform' as Transform import './transform' as Transform
@ -213,14 +214,14 @@ export : define [SetupBuilders args] : begin
if (k.length == 0) : return g if (k.length == 0) : return g
g.include k.0 g.include k.0
set g.contours : g.contours.map Glyph.contourToStandardCubic set g.contours : g.contours.map CurveUtil.convertContourToCubic
foreach [item : items-of : k.slice 1] : begin foreach [item : items-of : k.slice 1] : begin
local g1 : new Glyph local g1 : new Glyph
set g1.gizmo : this.gizmo || globalTransform set g1.gizmo : this.gizmo || globalTransform
g1.include item g1.include item
set g1.contours : g1.contours.map Glyph.contourToStandardCubic set g1.contours : g1.contours.map CurveUtil.convertContourToCubic
local c1 : ShapeOps.boole operator g.contours g1.contours ShapeOps.fillRules.nonzero ShapeOps.fillRules.nonzero 16384 local c1 : ShapeOps.boole operator g.contours g1.contours ShapeOps.fillRules.nonzero ShapeOps.fillRules.nonzero 16384
set g.contours : c1.map : lambda [c] : [Glyph.contourToStandardCubic c].reverse set g.contours : c1.map : lambda [c] : [CurveUtil.convertContourToCubic c].reverse
if [not dontinc] : this.include g if [not dontinc] : this.include g
return g return g

View file

@ -1,3 +1,5 @@
"use strict";
const objectAssign = require("object-assign"); const objectAssign = require("object-assign");
function mergeVSHive(_target, source) { function mergeVSHive(_target, source) {

View file

@ -21,7 +21,6 @@ const OTF2OTC = "otf2otc";
const PATEL_C = ["node", "./node_modules/patel/bin/patel-c"]; const PATEL_C = ["node", "./node_modules/patel/bin/patel-c"];
const TTCIZE = ["node", "./node_modules/otfcc-ttcize/bin/_startup"]; const TTCIZE = ["node", "./node_modules/otfcc-ttcize/bin/_startup"];
const GENERATE = ["node", "gen/generator"]; const GENERATE = ["node", "gen/generator"];
const GC = ["node", "gen/gc"];
const webfontFormats = [ const webfontFormats = [
["woff2", "woff2"], ["woff2", "woff2"],
["woff", "woff"], ["woff", "woff"],
@ -319,8 +318,6 @@ const BuildTTF = file.make(
{ hives, family, shapeWeight, menuWeight, menuStyle, menuWidth }, { hives, family, shapeWeight, menuWeight, menuStyle, menuWidth },
version version
] = await target.need(HivesOf(fn), Version); ] = await target.need(HivesOf(fn), Version);
const otd = output.dir + "/" + output.name + ".otd";
const ttfTmp = output.dir + "/" + output.name + ".tmp.ttf";
const otdTmp = output.dir + "/" + output.name + ".tmp.otd"; const otdTmp = output.dir + "/" + output.name + ".tmp.otd";
const charmap = output.dir + "/" + output.name + ".charmap"; const charmap = output.dir + "/" + output.name + ".charmap";
await target.need(Scripts, fu`parameters.toml`, de`${output.dir}`); await target.need(Scripts, fu`parameters.toml`, de`${output.dir}`);
@ -336,12 +333,13 @@ const BuildTTF = file.make(
["--menu-width", menuWidth], ["--menu-width", menuWidth],
hives hives
); );
await run("otfccbuild", otdTmp, "-o", ttfTmp, "-O3", "--keep-average-char-width"); await run(
await run(GC, ["-i", ttfTmp], ["-o", otd]); "otfccbuild",
await run("otfccbuild", otd, "-o", output.full, "-O3", "--keep-average-char-width", "-q"); otdTmp,
["-o", output.full],
["-O3", "--keep-average-char-width", "-q"]
);
await rm(otdTmp); await rm(otdTmp);
await rm(ttfTmp);
await rm(otd);
} }
); );
const BuildCM = file.make( const BuildCM = file.make(