Skip to content

Commit 84004b8

Browse files
committed
cff: Humanify user facing way "delta"s are handled
[why] At the moment the delta values are not de- or encoded. The delta format is a packed format to have the smallest possible values in the array of numbers (i.e. relative to the previous number). But usually users do not face this but are shown absolute values; in all other font specific applications. For example BlueValues [ 500, 550 ] // User sees the BlueZone is from 500 to 550 Encoded as [ 500, 50 ] opentype.js at the moment does not translate these deltas in any way and users must know this and use the inconvenient 'packed' encoding format. [how] Convert the read relative delta values to absolute coordinates in the blueValues (and other) properties, that users can interact with. On font encoding time the absolute coordinates are converted back to relative ones and encoded in the font file. [note] https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf The second and subsequent numbers in a delta are encoded as the difference between successive values. For example, an array a0, a1, ..., an would be encoded as: a0 (a1–a0) (a2–a1) ..., (an–a(n–1)) This is done because small numbers can be encoded with fewer bytes and the total aim is to reduce the size. Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
1 parent aea28e5 commit 84004b8

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/tables/cff.mjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,17 @@ function interpretDict(dict, meta, strings) {
308308
if (m.type === 'SID') {
309309
value = getCFFString(strings, value);
310310
}
311+
if (m.type === 'delta' && value !== null) {
312+
if (!Array.isArray(value) || value.length % 2 != 0) {
313+
throw new Error(`Read delta data invalid`);
314+
}
315+
// Convert delta array to human readable version
316+
let current = 0;
317+
for(let i = 0; i < value.length; i++) {
318+
value[i] = value[i] + current;
319+
current = value[i]
320+
}
321+
}
311322
newDict[m.name] = value;
312323
}
313324
}
@@ -1416,6 +1427,21 @@ function makeDict(meta, attrs, strings) {
14161427
if (entry.type === 'SID') {
14171428
value = encodeString(value, strings);
14181429
}
1430+
if (entry.type === 'delta' && value !== null) {
1431+
if (!Array.isArray(value) || value.length % 2 != 0) {
1432+
throw new Error(`Provided delta data invalid`);
1433+
}
1434+
// Convert human readable delta array to DICT version
1435+
// See https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
1436+
// Private DICT data > Table 6 Operand Types > delta
1437+
let current = 0;
1438+
for(let i = 0; i < value.length; i++) {
1439+
let nextcurrent = value[i];
1440+
value[i] = value[i] - current;
1441+
current = nextcurrent;
1442+
}
1443+
console.log("OUTCOMING", value);
1444+
}
14191445

14201446
m[entry.op] = {name: entry.name, type: entry.type, value: value};
14211447
}

test/tables/cff.spec.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ describe('tables/cff.mjs', function () {
9393
assert.equal(topDict.vstore, 16);
9494
assert.equal(topDict.fdSelect, null);
9595

96-
assert.deepEqual(privateDict1.blueValues, [-20, 20, 472, 18, 35, 15, 105, 15, 10, 20, 40, 20]);
97-
assert.deepEqual(privateDict1.otherBlues, [-250, 10]);
98-
assert.deepEqual(privateDict1.familyBlues, [-20, 20, 473, 18, 34, 15, 104, 15, 10, 20, 40, 20]);
99-
assert.deepEqual(privateDict1.familyOtherBlues, [ -249, 10 ]);
96+
assert.deepEqual(privateDict1.blueValues, [-20, 0, 472, 490, 525, 540, 645, 660, 670, 690, 730, 750]);
97+
assert.deepEqual(privateDict1.otherBlues, [-250, -240]);
98+
assert.deepEqual(privateDict1.familyBlues, [-20, 0, 473, 491, 525, 540, 644, 659, 669, 689, 729, 749]);
99+
assert.deepEqual(privateDict1.familyOtherBlues, [ -249, -239 ]);
100100
assert.equal(privateDict1.blueScale, 0.0375);
101101
assert.equal(privateDict1.blueShift, 7);
102102
assert.equal(privateDict1.blueFuzz, 0);

0 commit comments

Comments
 (0)