add variant for 1
This commit is contained in:
parent
bf2aecee9d
commit
6f344b626d
4 changed files with 126 additions and 119 deletions
210
generator.js
210
generator.js
|
@ -1,22 +1,22 @@
|
|||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
let fs = require("fs");
|
||||
let path = require("path");
|
||||
|
||||
// var TTFWriter = require('node-sfnt').TTFWriter;
|
||||
var argv = require("yargs").argv;
|
||||
var buildGlyphs = require("./buildglyphs.js");
|
||||
var parameters = require("./support/parameters");
|
||||
var toml = require("toml");
|
||||
// let TTFWriter = require('node-sfnt').TTFWriter;
|
||||
let argv = require("yargs").argv;
|
||||
let buildGlyphs = require("./buildglyphs.js");
|
||||
let parameters = require("./support/parameters");
|
||||
let toml = require("toml");
|
||||
|
||||
var Glyph = require("./support/glyph");
|
||||
var autoref = require("./support/autoref");
|
||||
let Glyph = require("./support/glyph");
|
||||
let autoref = require("./support/autoref");
|
||||
const objectAssign = require("object-assign");
|
||||
|
||||
var caryllShapeOps = require("caryll-shapeops");
|
||||
var c2q = require("megaminx").geometry.c2q;
|
||||
let caryllShapeOps = require("caryll-shapeops");
|
||||
let c2q = require("megaminx").geometry.c2q;
|
||||
|
||||
function hasv(obj) {
|
||||
if (!obj) return false;
|
||||
for (var k in obj) if (obj[k]) return true;
|
||||
for (let k in obj) if (obj[k]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -70,8 +70,25 @@ function formVariantData(data, para) {
|
|||
return vs;
|
||||
}
|
||||
|
||||
// Font building
|
||||
const font = (function() {
|
||||
function byGlyphPriority(a, b) {
|
||||
const pri1 = a.cmpPriority || 0;
|
||||
const pri2 = b.cmpPriority || 0;
|
||||
if (pri1 > pri2) return -1;
|
||||
if (pri1 < pri2) return 1;
|
||||
if (a.contours && b.contours && a.contours.length < b.contours.length) return 1;
|
||||
if (a.contours && b.contours && a.contours.length > b.contours.length) return -1;
|
||||
if (a.advanceWidth < b.advanceWidth) return -1;
|
||||
if (a.advanceWidth > b.advanceWidth) return 1;
|
||||
if ((a.unicode && a.unicode[0] && !b.unicode) || !b.unicode[0]) return -1;
|
||||
if ((b.unicode && b.unicode[0] && !a.unicode) || !a.unicode[0]) return +1;
|
||||
if (a.unicode && a.unicode[0] && b.unicode && b.unicode[0] && a.unicode[0] < b.unicode[0])
|
||||
return -1;
|
||||
if (a.unicode && a.unicode[0] && b.unicode && b.unicode[0] && a.unicode[0] > b.unicode[0])
|
||||
return +1;
|
||||
return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
|
||||
}
|
||||
|
||||
function getParameters(argv) {
|
||||
const parametersData = Object.assign(
|
||||
{},
|
||||
toml.parse(fs.readFileSync(path.join(__dirname, "parameters.toml"), "utf-8")),
|
||||
|
@ -80,7 +97,6 @@ const font = (function() {
|
|||
: []
|
||||
);
|
||||
const variantData = toml.parse(fs.readFileSync(path.join(__dirname, "variants.toml"), "utf-8"));
|
||||
const emptyFont = toml.parse(fs.readFileSync(path.join(__dirname, "emptyfont.toml"), "utf-8"));
|
||||
|
||||
const para = parameters.build(parametersData, argv._);
|
||||
const vsdata = formVariantData(variantData, para);
|
||||
|
@ -88,9 +104,13 @@ const font = (function() {
|
|||
para.variantSelector = parameters.build(vsdata, argv._);
|
||||
para.defaultVariant = vsdata.default;
|
||||
if (argv.family) para.family = argv.family;
|
||||
const fontUniqueName =
|
||||
para.family + " " + para.style + " " + para.version + " (" + para.codename + ")";
|
||||
return para;
|
||||
}
|
||||
|
||||
// Font building
|
||||
const font = (function() {
|
||||
const emptyFont = toml.parse(fs.readFileSync(path.join(__dirname, "emptyfont.toml"), "utf-8"));
|
||||
const para = getParameters(argv);
|
||||
const font = buildGlyphs.build.call(emptyFont, para);
|
||||
|
||||
font.parameters = para;
|
||||
|
@ -99,83 +119,46 @@ const font = (function() {
|
|||
g.gord = j;
|
||||
return g;
|
||||
})
|
||||
.sort(function(a, b) {
|
||||
const pri1 = a.cmpPriority || 0;
|
||||
const pri2 = b.cmpPriority || 0;
|
||||
if (pri1 > pri2) return -1;
|
||||
if (pri1 < pri2) return 1;
|
||||
if (a.contours && b.contours && a.contours.length < b.contours.length) return 1;
|
||||
if (a.contours && b.contours && a.contours.length > b.contours.length) return -1;
|
||||
if (a.advanceWidth < b.advanceWidth) return -1;
|
||||
if (a.advanceWidth > b.advanceWidth) return 1;
|
||||
if ((a.unicode && a.unicode[0] && !b.unicode) || !b.unicode[0]) return -1;
|
||||
if ((b.unicode && b.unicode[0] && !a.unicode) || !a.unicode[0]) return +1;
|
||||
if (
|
||||
a.unicode &&
|
||||
a.unicode[0] &&
|
||||
b.unicode &&
|
||||
b.unicode[0] &&
|
||||
a.unicode[0] < b.unicode[0]
|
||||
)
|
||||
return -1;
|
||||
if (
|
||||
a.unicode &&
|
||||
a.unicode[0] &&
|
||||
b.unicode &&
|
||||
b.unicode[0] &&
|
||||
a.unicode[0] > b.unicode[0]
|
||||
)
|
||||
return +1;
|
||||
return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
|
||||
});
|
||||
.sort(byGlyphPriority);
|
||||
return font;
|
||||
})();
|
||||
|
||||
if (argv.charmap) {
|
||||
fs.writeFileSync(
|
||||
argv.charmap,
|
||||
JSON.stringify(
|
||||
font.glyf.map(function(glyph) {
|
||||
return [
|
||||
glyph.name,
|
||||
glyph.unicode,
|
||||
glyph.advanceWidth === 0
|
||||
? hasv(glyph.anchors) ? 1 : glyph.contours && glyph.contours.length ? 2 : 0
|
||||
: 0
|
||||
];
|
||||
})
|
||||
),
|
||||
"utf8"
|
||||
);
|
||||
const charmap = font.glyf.map(function(glyph) {
|
||||
return [
|
||||
glyph.name,
|
||||
glyph.unicode,
|
||||
glyph.advanceWidth === 0
|
||||
? hasv(glyph.anchors) ? 1 : glyph.contours && glyph.contours.length ? 2 : 0
|
||||
: 0
|
||||
];
|
||||
});
|
||||
fs.writeFileSync(argv.charmap, JSON.stringify(charmap), "utf8");
|
||||
}
|
||||
|
||||
if (argv.o) {
|
||||
var o_glyf = {};
|
||||
var cmap = {};
|
||||
var skew = (argv.uprightify ? 1 : 0) * Math.tan((font.post.italicAngle || 0) / 180 * Math.PI);
|
||||
// autoref
|
||||
autoref(font.glyf);
|
||||
// regulate
|
||||
font.glyf.forEach(g => {
|
||||
function regulateGlyph(g, skew) {
|
||||
if (!g.contours) return;
|
||||
for (var k = 0; k < g.contours.length; k++) {
|
||||
var contour = g.contours[k];
|
||||
for (var p = 0; p < contour.length; p++) {
|
||||
|
||||
// Regulate
|
||||
for (let k = 0; k < g.contours.length; k++) {
|
||||
const contour = g.contours[k];
|
||||
for (let p = 0; p < contour.length; p++) {
|
||||
contour[p].x += contour[p].y * skew;
|
||||
if (!contour[p].on) continue;
|
||||
contour[p].x = Math.round(contour[p].x);
|
||||
}
|
||||
var offJ = null,
|
||||
let offJ = null,
|
||||
mx = null;
|
||||
for (var p = 0; p < contour.length; p++) {
|
||||
for (let p = 0; p < contour.length; p++) {
|
||||
if (!contour[p].on) continue;
|
||||
if (offJ) {
|
||||
var origx = contour[p].x;
|
||||
var rx = Math.round(contour[p].x * 4) / 4;
|
||||
var origx0 = mx;
|
||||
var rx0 = contour[offJ - 1].x;
|
||||
const origx = contour[p].x;
|
||||
const rx = Math.round(contour[p].x * 4) / 4;
|
||||
const origx0 = mx;
|
||||
const rx0 = contour[offJ - 1].x;
|
||||
if (origx === origx0) continue;
|
||||
for (var poff = offJ; poff < p; poff++) {
|
||||
for (let poff = offJ; poff < p; poff++) {
|
||||
contour[poff].x =
|
||||
(contour[poff].x - origx0) / (origx - origx0) * (rx - rx0) + rx0;
|
||||
}
|
||||
|
@ -185,44 +168,51 @@ if (argv.o) {
|
|||
offJ = p + 1;
|
||||
}
|
||||
}
|
||||
var c1 = [];
|
||||
for (var k = 0; k < g.contours.length; k++) {
|
||||
const c1 = [];
|
||||
for (let k = 0; k < g.contours.length; k++) {
|
||||
c1.push(Glyph.contourToStandardCubic(g.contours[k]));
|
||||
}
|
||||
g.contours = c1;
|
||||
});
|
||||
// overlap removal
|
||||
font.glyf.forEach(g => {
|
||||
if (g.contours) {
|
||||
g.contours = caryllShapeOps.removeOverlap(g.contours, 1, 256, true);
|
||||
}
|
||||
});
|
||||
// reorder
|
||||
font.glyf = font.glyf.sort((a, b) => a.gord - b.gord);
|
||||
// finalize
|
||||
font.glyf.forEach(g => {
|
||||
if (g.contours) {
|
||||
Glyph.prototype.cleanup.call(g, 0.1);
|
||||
g.contours = c2q.contours(g.contours);
|
||||
for (var k = 0; k < g.contours.length; k++) {
|
||||
var contour = g.contours[k];
|
||||
for (var p = 0; p < contour.length; p++) {
|
||||
contour[p].x -= contour[p].y * skew;
|
||||
}
|
||||
|
||||
// De-overlap
|
||||
g.contours = caryllShapeOps.removeOverlap(c1, 1, 256, true);
|
||||
|
||||
// Finalize
|
||||
Glyph.prototype.cleanup.call(g, 0.1);
|
||||
g.contours = c2q.contours(g.contours);
|
||||
for (let k = 0; k < g.contours.length; k++) {
|
||||
const contour = g.contours[k];
|
||||
for (let p = 0; p < contour.length; p++) {
|
||||
contour[p].x -= contour[p].y * skew;
|
||||
}
|
||||
}
|
||||
o_glyf[g.name] = g;
|
||||
if (g.unicode && g.unicode.length) {
|
||||
cmap[g.unicode[0]] = g.name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
font.glyf = o_glyf;
|
||||
font.cmap = cmap;
|
||||
font.glyfMap = null;
|
||||
const skew = (argv.uprightify ? 1 : 0) * Math.tan((font.post.italicAngle || 0) / 180 * Math.PI);
|
||||
// autoref
|
||||
autoref(font.glyf);
|
||||
// regulate
|
||||
for (let g of font.glyf) regulateGlyph(g, skew);
|
||||
|
||||
// reorder
|
||||
font.glyf = font.glyf.sort((a, b) => a.gord - b.gord);
|
||||
|
||||
// finalize
|
||||
const o_glyf = {};
|
||||
const o_cmap = {};
|
||||
for (let g of font.glyf) {
|
||||
o_glyf[g.name] = g;
|
||||
if (!g.unicode) continue;
|
||||
for (let u of g.unicode) o_cmap[u] = g.name;
|
||||
}
|
||||
|
||||
// Prepare OTD
|
||||
const otd = Object.assign({}, font);
|
||||
otd.glyf = o_glyf;
|
||||
otd.cmap = o_cmap;
|
||||
otd.glyfMap = null;
|
||||
if (argv.o === "|") {
|
||||
process.stdout.write(JSON.stringify(font));
|
||||
process.stdout.write(JSON.stringify(otd));
|
||||
} else {
|
||||
fs.writeFileSync(argv.o, JSON.stringify(font));
|
||||
fs.writeFileSync(argv.o, JSON.stringify(otd));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,16 +30,20 @@ export : define [apply] : begin
|
|||
|
||||
select-variant 'zero' '0'
|
||||
|
||||
sketch # one
|
||||
sketch # one.hooky
|
||||
include markset.capital
|
||||
include : VBar (MIDDLE + ONEBALANCE) 0 CAP
|
||||
include : dispiro
|
||||
flat (MIDDLE - HALFSTROKE * HVCONTRAST + ONEBALANCE) CAP [widths STROKE 0]
|
||||
curl (MIDDLE - HOOKX * 1.25 + ONEBALANCE) (CAP - HOOK * 0.75)
|
||||
save 'one.hooky'
|
||||
|
||||
if SLAB : begin
|
||||
include : CenterBottomSerif (MIDDLE + ONEBALANCE) 0 LONGJUT
|
||||
save 'one' '1'
|
||||
sketch # one.serifed
|
||||
include glyphs.'one.hooky' AS_BASE
|
||||
include : CenterBottomSerif (MIDDLE + ONEBALANCE) 0 LONGJUT
|
||||
save 'one.serifed'
|
||||
|
||||
select-variant 'one' '1'
|
||||
|
||||
sketch # two
|
||||
include markset.capital
|
||||
|
|
|
@ -118,11 +118,12 @@ define [buildGSUB para glyphList markGlyphs] : begin
|
|||
commonList.push feature
|
||||
set lookups.(feature).subtables.0.(glyph.name) fs.(feature)
|
||||
# ssxx
|
||||
foreach [{name composition} : pairs-of para.variants] : if (name.length === 4 && composition.__isComposite) : begin
|
||||
commonList.push name
|
||||
local tags {.}
|
||||
foreach [{ch tag} : pairs-of composition.__cvmap] : set tags.(tag) true
|
||||
set features.(name) : [Object.keys tags].filter (tag => tags.(tag))
|
||||
foreach [{name composition} : pairs-of para.variants] : begin
|
||||
if (name.length === 4 && composition.__isComposite && [name.slice 0 2] === 'ss') : begin
|
||||
commonList.push name
|
||||
local tags {.}
|
||||
foreach [{ch tag} : pairs-of composition.__cvmap] : set tags.(tag) true
|
||||
set features.(name) : [Object.keys tags].filter (tag => tags.(tag))
|
||||
|
||||
set languages.'cyrl_SRB ' {.features [{'locl_srb'}.concat commonList]}
|
||||
set languages.'cyrl_MKD ' {.features [{'locl_srb'}.concat commonList]}
|
||||
|
|
|
@ -199,6 +199,14 @@ tag = "cv48"
|
|||
y = "curly"
|
||||
tag = "cv49"
|
||||
|
||||
[simple.v-one-hooky]
|
||||
one = "hooky"
|
||||
tag = "cv50"
|
||||
|
||||
[simple.v-one-serifed]
|
||||
one = "serifed"
|
||||
tag = "cv51"
|
||||
|
||||
[simple.others]
|
||||
I = 'serifed'
|
||||
J = 'serifed'
|
||||
|
@ -221,6 +229,7 @@ design = [
|
|||
'v-dollar-through',
|
||||
'v-numbersign-upright',
|
||||
'v-three-twoarcs',
|
||||
'v-one-hooky',
|
||||
'others'
|
||||
]
|
||||
upright = [
|
||||
|
@ -238,6 +247,9 @@ italic = [
|
|||
'v-y-curly'
|
||||
]
|
||||
|
||||
[composite.slab]
|
||||
design = ['v-one-serifed']
|
||||
|
||||
# Composite character options, overrides default settings above.
|
||||
# Andale Mono Style
|
||||
[composite.ss01]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue