Skip to content

Commit 31ea96b

Browse files
committed
WIP: make fontDict
1 parent 328368d commit 31ea96b

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

src/tables/cff.js

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ const PRIVATE_DICT_META_CFF2 = [
422422

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

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

1938-
function makePrivateDict(attrs, strings, version) {
1941+
function makeFontDictIndex(fontDicts) {
1942+
let dicts = [];
1943+
for(let i = 0; i < fontDicts.length; i++) {
1944+
dicts.push({name: `fontDict_${i}`, type: 'TABLE', value: fontDicts[i]});
1945+
}
1946+
const t = new table.Record('Font DICT INDEX', [
1947+
{name: 'fontDicts', type: 'INDEX32', value: fontDicts}
1948+
]);
1949+
return t;
1950+
}
1951+
1952+
function makeFontDict(attrs) {
1953+
const t = new table.Record('Font DICT', [
1954+
{name: 'dict', type: 'DICT', value: {}}
1955+
]);
1956+
t.dict = makeDict(FONT_DICT_META, attrs);
1957+
return t;
1958+
}
1959+
1960+
function makePrivateDict(attrs, strings) {
19391961
const t = new table.Record('Private DICT', [
19401962
{name: 'dict', type: 'DICT', value: {}}
19411963
]);
1942-
t.dict = makeDict(version > 1 ? PRIVATE_DICT_META_CFF2 : PRIVATE_DICT_META, attrs, strings);
1964+
t.dict = makeDict(FONT_DICT_META, attrs, strings);
19431965
return t;
19441966
}
19451967

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

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

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

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

2092+
// @TODO: if there's more than one fontDict
20702093
// {name: 'FDSelect', type: 'RECORD'}
20712094
// t.FDSelect =
2072-
// {name: 'FontDICTIndex', type: 'RECORD'}
2073-
// t.FontDICTIndex =
2095+
2096+
t.fields.push({name: 'fontDictIndex', type: 'RECORD'});
2097+
let fontDicts = cffTable && cffTable.topDict._fdArray;
2098+
if (!fontDicts) {
2099+
fontDicts = [makeFontDict([0, 0])];
2100+
} else {
2101+
fontDicts = fontDicts.map(d => {
2102+
return makeFontDict([0, 0]);
2103+
});
2104+
}
2105+
t.fontDictIndex = makeFontDictIndex(fontDicts);
2106+
2107+
console.log('#########################################')
2108+
console.log(t.fontDictIndex)
2109+
20742110
// {name: 'fdArray', type: 'RECORD'}
20752111
// t.fdArray =
20762112
// {name: 'privateDict', type: 'RECORD'}

src/types.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,7 @@ encode.OPERAND = function(v, type) {
858858
} else if (type === 'offset') {
859859
// We make it easy for ourselves and always encode offsets as
860860
// 4 bytes. This makes offset calculation for the top dict easier.
861-
// for CFF2 an in order to save space, we use the 'varoffset' type
861+
// For CFF2 an in order to save space, we use the 'varoffset' type
862862
const enc1 = encode.NUMBER32(v);
863863
for (let j = 0; j < enc1.length; j++) {
864864
d.push(enc1[j]);

0 commit comments

Comments
 (0)