Cleanup deps and GC/Quadify code
This commit is contained in:
parent
fbb977c16f
commit
866dc4daae
19 changed files with 493 additions and 222 deletions
|
@ -11,7 +11,7 @@
|
|||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
|
||||
"rules": {
|
||||
"indent": ["error", "tab", { "SwitchCase": 1 }],
|
||||
"quotes": ["error", "double", { "allowTemplateLiterals": true }],
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
const EmptyFont = require("./empty-font.js");
|
||||
const buildGlyphs = require("./build-glyphs.js");
|
||||
|
||||
|
@ -6,6 +8,7 @@ const { assignFontNames } = require("../meta/naming");
|
|||
const { setFontMetrics } = require("../meta/aesthetics");
|
||||
|
||||
const regulateGlyphs = require("../support/regulate-glyph");
|
||||
const gcFont = require("./gc");
|
||||
|
||||
module.exports = function(para) {
|
||||
const font = EmptyFont();
|
||||
|
@ -39,6 +42,8 @@ module.exports = function(para) {
|
|||
font.glyf = glyf;
|
||||
font.cmap = cmap;
|
||||
|
||||
gcFont(font);
|
||||
|
||||
return font;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = function() {
|
||||
return {
|
||||
head: {
|
||||
|
|
87
gen/gc.js
87
gen/gc.js
|
@ -1,18 +1,83 @@
|
|||
"use strict";
|
||||
|
||||
const { Workflow, introduce, build, gc } = require("megaminx");
|
||||
const argv = require("yargs").argv;
|
||||
module.exports = function gcFont(font) {
|
||||
let sink = new Set();
|
||||
let glyphCount = 0;
|
||||
|
||||
async function recipe(ctx, config, argv) {
|
||||
const a = await ctx.run(introduce, "a", { from: argv.i });
|
||||
await ctx.run(gc, "a");
|
||||
await ctx.run(build, "a", { to: argv.o, optimize: true });
|
||||
sink.add(".notdef", ".null");
|
||||
|
||||
if (font.cmap) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const config = {};
|
||||
const flow = new Workflow(config);
|
||||
await flow.run(recipe, config, argv);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import '../support/transform' as : Transform && [object [transformPoint tp]]
|
|||
import [curveToContour OffsetCurve] from '../support/curve-util'
|
||||
import [mix linreg clamp fallback] from '../support/utils'
|
||||
import [designParameters] from '../meta/aesthetics'
|
||||
import [CubicBezierCurve autoQuadify] from "primitive-quadify-off-curves"
|
||||
import [Curve Quadify] from "typo-geom"
|
||||
|
||||
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 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 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 outer : curveToContour [new OffsetCurve bone (-hs) HVCONTRAST] (1 / 256)
|
||||
|
|
|
@ -36,13 +36,13 @@ export : define [buildCCMP sink glyphs markGlyphs] : begin
|
|||
|
||||
define lookupCcmp2 : add-lookup sink : object
|
||||
.type 'gsub_ligature'
|
||||
.subtables : list : object
|
||||
psilivaria {'commaAbove' 'graveAbove'}
|
||||
psilioxia {'commaAbove' 'acuteAbove'}
|
||||
psiliperispomeni {'commaAbove' 'perispomeniAbove'}
|
||||
dasiavaria {'revCommaAbove' 'graveAbove'}
|
||||
dasiaoxia {'revCommaAbove' 'acuteAbove'}
|
||||
dasiaperispomeni {'revCommaAbove' 'perispomeniAbove'}
|
||||
.subtables : list : object : substitutions : list
|
||||
object [from {'commaAbove' 'graveAbove'}] [to 'psilivaria']
|
||||
object [from {'commaAbove' 'acuteAbove'}] [to 'psilioxia']
|
||||
object [from {'commaAbove' 'perispomeniAbove'}] [to 'psiliperispomeni']
|
||||
object [from {'revCommaAbove' 'graveAbove'}] [to 'dasiavaria']
|
||||
object [from {'revCommaAbove' 'acuteAbove'}] [to 'dasiaoxia']
|
||||
object [from {'revCommaAbove' 'perispomeniAbove'}] [to 'dasiaperispomeni']
|
||||
|
||||
ccmp.lookups.push lookupCcmp1 lookupCcmp2
|
||||
add-common-feature sink ccmp
|
||||
|
|
21
package.json
21
package.json
|
@ -12,28 +12,27 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"caryll-shapeops": "^0.3.1",
|
||||
"megaminx": "^0.9.0",
|
||||
"object-assign": "^4.1.1",
|
||||
"otfcc-ttcize": "^0.9.6",
|
||||
"primitive-quadify-off-curves": "^0.6.3",
|
||||
"typo-geom": "0.5.1",
|
||||
"spiro": "^1.1.0",
|
||||
"toml": "^3.0.0",
|
||||
"topsort": "0.0.2",
|
||||
"topsort": "^0.0.2",
|
||||
"ttf2woff": "^2.0.1",
|
||||
"ttf2woff2": "^3.0.0",
|
||||
"unorm": "^1.6.0",
|
||||
"verda": "^1.0.0-12",
|
||||
"fs-extra": "^8.1.0",
|
||||
"yargs": "^15.1.0"
|
||||
"verda": "^1.0.0",
|
||||
"fs-extra": "^9.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"cldr": "^5.5.4",
|
||||
"colors": "^1.3.3",
|
||||
"colors": "^1.4.0",
|
||||
"ejs": "^3.0.1",
|
||||
"eslint": "^5.2.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.0",
|
||||
"patel": "^0.33.1",
|
||||
"patrisika-scopes": "^0.11.1",
|
||||
"semver": "^7.1.1",
|
||||
"stylus": "^0.54.5"
|
||||
"semver": "^7.1.3",
|
||||
"stylus": "^0.54.7"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"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 {
|
||||
constructor(bone, offset, contrast) {
|
||||
|
@ -38,7 +40,7 @@ exports.curveToContour = function(curve, err) {
|
|||
cubic: false,
|
||||
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++) {
|
||||
const z = offPoints[k];
|
||||
if (k > 0) {
|
||||
|
@ -64,3 +66,211 @@ exports.curveToContour = function(curve, err) {
|
|||
});
|
||||
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;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const Transform = require("./transform.js");
|
||||
const quadify = require("primitive-quadify-off-curves");
|
||||
const typoGeom = require("typo-geom");
|
||||
|
||||
const SMALL = 1e-4;
|
||||
|
||||
|
@ -197,7 +197,7 @@ class BezierCurveCluster {
|
|||
z4 = zs[j];
|
||||
const z2 = mix(z1, z4, 1 / 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);
|
||||
lengths.push(this.measureLength(seg));
|
||||
last = z4;
|
||||
|
@ -206,7 +206,7 @@ class BezierCurveCluster {
|
|||
z2 = zs[j],
|
||||
z3 = zs[j + 1],
|
||||
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);
|
||||
lengths.push(this.measureLength(seg));
|
||||
last = z4;
|
||||
|
@ -217,7 +217,7 @@ class BezierCurveCluster {
|
|||
z4 = zs[j + 1];
|
||||
const z2 = mix(zm, z1, 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);
|
||||
lengths.push(this.measureLength(seg));
|
||||
last = z4;
|
||||
|
@ -307,7 +307,7 @@ function buildCurve(curve) {
|
|||
if (nPtsOffPoints > 0) {
|
||||
const curve = new BezierCurveCluster(pts);
|
||||
if (curve.isAlmostLinear(1)) continue;
|
||||
const offPoints = quadify.autoQuadify(curve, 1 / 4);
|
||||
const offPoints = typoGeom.Quadify.auto(curve, 1 / 4);
|
||||
if (!offPoints) continue;
|
||||
for (let k = 0; k < offPoints.length; k++) {
|
||||
const z = offPoints[k];
|
||||
|
|
|
@ -177,38 +177,3 @@ export all : class Glyph
|
|||
this.start-from x y
|
||||
this.start-from mbx mby
|
||||
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
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = function formVariantData(data, para) {
|
||||
const defaultBuildup = {};
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
function maskBit(x, y) {
|
||||
return x & (1 << y);
|
||||
}
|
||||
"use strict";
|
||||
|
||||
module.exports = maskBit;
|
||||
module.exports = function maskBit(x, y) {
|
||||
return x & (1 << y);
|
||||
};
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = function(xs, ys) {
|
||||
let i,
|
||||
length = xs.length;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
const blend = require("./monotonic-interpolate");
|
||||
|
||||
module.exports = function(aspect, hive, params, sink) {
|
||||
|
|
|
@ -3,8 +3,22 @@ export all : class Point
|
|||
this.x = x
|
||||
this.y = y
|
||||
this.on = on || false
|
||||
this.subdivided = subdivided || 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
|
||||
* x * tfm.xx + y * tfm.yx + tfm.x
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
const Glyph = require("./glyph");
|
||||
const autoRef = require("./autoref");
|
||||
const caryllShapeOps = require("caryll-shapeops");
|
||||
const c2q = require("megaminx").geometry.c2q;
|
||||
const curveUtil = require("./curve-util");
|
||||
|
||||
function regulateGlyph(g, skew) {
|
||||
if (!g.contours) return;
|
||||
|
@ -47,9 +49,11 @@ function regulateGlyph(g, skew) {
|
|||
function simplifyContours(contours) {
|
||||
const source = [];
|
||||
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 = [];
|
||||
for (const contour of simplified) {
|
||||
if (contour.length > 2) result.push(contour);
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'spiro' as SpiroJs
|
|||
import './spiroexpand' as SpiroExpansionContext
|
||||
import './fairify' as fairify
|
||||
import 'caryll-shapeops' as ShapeOps
|
||||
import './curve-util' as CurveUtil
|
||||
|
||||
import './transform' as Transform
|
||||
|
||||
|
@ -213,14 +214,14 @@ export : define [SetupBuilders args] : begin
|
|||
if (k.length == 0) : return g
|
||||
|
||||
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
|
||||
local g1 : new Glyph
|
||||
set g1.gizmo : this.gizmo || globalTransform
|
||||
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
|
||||
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
|
||||
return g
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
"use strict";
|
||||
|
||||
const objectAssign = require("object-assign");
|
||||
|
||||
function mergeVSHive(_target, source) {
|
||||
|
|
14
verdafile.js
14
verdafile.js
|
@ -21,7 +21,6 @@ const OTF2OTC = "otf2otc";
|
|||
const PATEL_C = ["node", "./node_modules/patel/bin/patel-c"];
|
||||
const TTCIZE = ["node", "./node_modules/otfcc-ttcize/bin/_startup"];
|
||||
const GENERATE = ["node", "gen/generator"];
|
||||
const GC = ["node", "gen/gc"];
|
||||
const webfontFormats = [
|
||||
["woff2", "woff2"],
|
||||
["woff", "woff"],
|
||||
|
@ -319,8 +318,6 @@ const BuildTTF = file.make(
|
|||
{ hives, family, shapeWeight, menuWeight, menuStyle, menuWidth },
|
||||
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 charmap = output.dir + "/" + output.name + ".charmap";
|
||||
await target.need(Scripts, fu`parameters.toml`, de`${output.dir}`);
|
||||
|
@ -336,12 +333,13 @@ const BuildTTF = file.make(
|
|||
["--menu-width", menuWidth],
|
||||
hives
|
||||
);
|
||||
await run("otfccbuild", otdTmp, "-o", ttfTmp, "-O3", "--keep-average-char-width");
|
||||
await run(GC, ["-i", ttfTmp], ["-o", otd]);
|
||||
await run("otfccbuild", otd, "-o", output.full, "-O3", "--keep-average-char-width", "-q");
|
||||
await run(
|
||||
"otfccbuild",
|
||||
otdTmp,
|
||||
["-o", output.full],
|
||||
["-O3", "--keep-average-char-width", "-q"]
|
||||
);
|
||||
await rm(otdTmp);
|
||||
await rm(ttfTmp);
|
||||
await rm(otd);
|
||||
}
|
||||
);
|
||||
const BuildCM = file.make(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue