Skip to content

Commit

Permalink
WIP: make fontDict
Browse files Browse the repository at this point in the history
  • Loading branch information
Connum committed Apr 20, 2024
1 parent 328368d commit 31ea96b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
50 changes: 43 additions & 7 deletions src/tables/cff.js
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ const PRIVATE_DICT_META_CFF2 = [

// https://learn.microsoft.com/en-us/typography/opentype/spec/cff2#table-10-font-dict-operator-entries
const FONT_DICT_META = [
{name: 'private', op: 18, type: ['number', 'offset'], value: [0, 0]}
{name: 'private', op: 18, type: ['number', 'varoffset'], value: [0, 0]}
];

// Parse the CFF top dictionary. A CFF table can contain multiple fonts, each with their own top dictionary.
Expand Down Expand Up @@ -659,6 +659,8 @@ function parseCFFCharstring(font, glyph, code, version, coords) {
if(glyph.blendDeltas && glyph.blendDeltas.length) {
glyph.blendDeltas = [];
}
// @TODO: instead of re-parsing the path each time (which will not take into account any possible changes to the path),
// apply the stored (and possible modified) blend data
return parseCFFCharstring(font, glyph, code, version, variationCoords);
};
}
Expand Down Expand Up @@ -1806,6 +1808,7 @@ function glyphToOps(glyph, version, font) {
// candidates for sub routines and extracts them from the glyphs, replacing the actual commands
if(glyph.subrs && glyph.gsubrs && glyph.subrs.length === glyph.gsubrs.length) {
const cffTable = font.tables[version < 2 ? 'cff' : 'cff2'];
if(!cffTable) return;
const fdIndex = cffTable.topDict._fdSelect ? cffTable.topDict._fdSelect[glyph.index] : 0;
const fdDict = cffTable.topDict._fdArray[fdIndex];
for(let i = 0; i < glyph.subrs.length; i++) {
Expand Down Expand Up @@ -1935,18 +1938,36 @@ function makeCharStringsIndex(glyphs, version) {
return t;
}

function makePrivateDict(attrs, strings, version) {
function makeFontDictIndex(fontDicts) {
let dicts = [];
for(let i = 0; i < fontDicts.length; i++) {
dicts.push({name: `fontDict_${i}`, type: 'TABLE', value: fontDicts[i]});
}
const t = new table.Record('Font DICT INDEX', [
{name: 'fontDicts', type: 'INDEX32', value: fontDicts}
]);
return t;
}

function makeFontDict(attrs) {
const t = new table.Record('Font DICT', [
{name: 'dict', type: 'DICT', value: {}}
]);
t.dict = makeDict(FONT_DICT_META, attrs);
return t;
}

function makePrivateDict(attrs, strings) {
const t = new table.Record('Private DICT', [
{name: 'dict', type: 'DICT', value: {}}
]);
t.dict = makeDict(version > 1 ? PRIVATE_DICT_META_CFF2 : PRIVATE_DICT_META, attrs, strings);
t.dict = makeDict(FONT_DICT_META, attrs, strings);
return t;
}

function makeCFFTable(glyphs, options, version) {
const font = glyphs.font;
const cffVersion = version || 1;
console.log(font);
const cffTable = font.tables[cffVersion > 1 ? 'cff2' : 'cff'];

const tableFields = cffVersion < 2 ? [
Expand Down Expand Up @@ -2009,7 +2030,8 @@ function makeCFFTable(glyphs, options, version) {
}

const strings = [];
const vstore = cffTable.topDict._vstore;
const vstore = cffTable && cffTable.topDict._vstore;
// @TODO: If we have a gvar table, make a vstore for the output font

t.header = makeHeader(cffVersion);
if(cffVersion < 2) {
Expand Down Expand Up @@ -2067,10 +2089,24 @@ function makeCFFTable(glyphs, options, version) {
t.fields.push({name: 'charStringsIndex', type: 'RECORD'});
}

// @TODO: if there's more than one fontDict
// {name: 'FDSelect', type: 'RECORD'}
// t.FDSelect =
// {name: 'FontDICTIndex', type: 'RECORD'}
// t.FontDICTIndex =

t.fields.push({name: 'fontDictIndex', type: 'RECORD'});
let fontDicts = cffTable && cffTable.topDict._fdArray;
if (!fontDicts) {
fontDicts = [makeFontDict([0, 0])];
} else {
fontDicts = fontDicts.map(d => {
return makeFontDict([0, 0]);
});
}
t.fontDictIndex = makeFontDictIndex(fontDicts);

console.log('#########################################')
console.log(t.fontDictIndex)

// {name: 'fdArray', type: 'RECORD'}
// t.fdArray =
// {name: 'privateDict', type: 'RECORD'}
Expand Down
2 changes: 1 addition & 1 deletion src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ encode.OPERAND = function(v, type) {
} else if (type === 'offset') {
// We make it easy for ourselves and always encode offsets as
// 4 bytes. This makes offset calculation for the top dict easier.
// for CFF2 an in order to save space, we use the 'varoffset' type
// For CFF2 an in order to save space, we use the 'varoffset' type
const enc1 = encode.NUMBER32(v);
for (let j = 0; j < enc1.length; j++) {
d.push(enc1[j]);
Expand Down

0 comments on commit 31ea96b

Please sign in to comment.