prototypo-library
Version:
This is prototypo parametric font library
161 lines (137 loc) • 3.67 kB
JavaScript
import _mapValues from 'lodash/mapValues';
import _forOwn from 'lodash/forOwn';
import {constantOrFormula} from '../utils/generic';
import Glyph from './Glyph';
const keyToTransform = [
'familyName',
'version',
'description',
'ascender',
'descender',
'cap-height',
'descendent-height',
];
export default class FontPrecursor {
constructor(fontSrc, {resolveOp} = {resolveOp: true}) {
const {fontinfo, lib} = fontSrc;
keyToTransform.forEach((key) => {
this[key] = constantOrFormula(fontinfo[key]);
});
this.parameters = _mapValues(lib.parameters, param =>
constantOrFormula(param),
);
this.paramBase = {
manualChanges: {},
postDepManualChanges: {},
altList: {},
glyphComponentChoice: {},
};
this.unicodeToGlyphName = {};
this.glyphs = _mapValues(fontSrc.glyphs, (glyph) => {
if (glyph.name.indexOf('alt') === -1) {
this.unicodeToGlyphName[glyph.unicode] = glyph.name;
}
return new Glyph(glyph, this.paramBase, {resolveOp});
});
// this.analyzeDependency();
}
analyzeDependency() {
_forOwn(this.glyphs, (glyph) => {
glyph.analyzeDependency();
});
}
constructFont(params, subset) {
let localParams = {
...params,
..._mapValues(this.parameters, param => param.getResult(params)),
manualChanges: {
...this.paramBase.manualChanges,
...params.manualChanges,
},
postDepManualChanges: {
...this.paramBase.postDepManualChanges,
...params.postDepManualChanges,
},
glyphComponentChoice: {
...this.paramBase.glyphComponentChoice,
...params.glyphComponentChoice,
},
altList: {
...this.paramBase.altList,
...params.altList,
},
};
const transformedThis = {};
const glyphNames = [];
const glyphs = [];
for (let i = 0; i < keyToTransform.length; i++) {
const key = keyToTransform[i];
const prop = this[key];
transformedThis[key] = prop.getResult(localParams);
}
for (let i = 0; i < subset.length; i++) {
const char = subset[i];
const altOrDefault
= localParams.altList[char] || this.unicodeToGlyphName[char];
glyphNames.push(altOrDefault);
}
for (let i = 0; i < glyphNames.length; i++) {
const name = glyphNames[i];
const indivParam = {...params};
if (name !== undefined) {
if (localParams.indiv_glyphs) {
const group
= localParams.indiv_glyphs[this.glyphs[name].unicode.value];
if (group) {
const indivModifs = localParams.indiv_group_param[group];
const keys = Object.keys(indivModifs);
for (let j = 0; j < keys.length; j++) {
const param = keys[j].substr(0, keys[j].length - 4);
const mod = indivModifs[keys[j]];
indivParam[param]
= mod.state === 'relative'
? params[param] * mod.value
: params[param] + mod.value;
}
}
localParams = {
...localParams,
...indivParam,
..._mapValues(this.parameters, param =>
param.getResult(indivParam),
),
manualChanges: {
...this.paramBase.manualChanges,
...localParams.manualChanges,
},
postDepManualChanges: {
...this.paramBase.postDepManualChanges,
...params.postDepManualChanges,
},
glyphComponentChoice: {
...this.paramBase.glyphComponentChoice,
...localParams.glyphComponentChoice,
},
altList: {
...this.paramBase.altList,
...localParams.altList,
},
};
}
if (this.glyphs[name]) {
glyphs.push(
this.glyphs[name].constructGlyph(
{...localParams},
undefined,
this.glyphs,
),
);
}
}
}
return {
...transformedThis,
glyphs,
};
}
}