add variant for 1

This commit is contained in:
belleve 2018-03-31 16:52:31 +08:00
parent bf2aecee9d
commit 6f344b626d
4 changed files with 126 additions and 119 deletions

View file

@ -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));
}
}

View file

@ -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

View file

@ -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]}

View file

@ -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]