From 022d2cc8cf3ee6e2e7d1625afbdcfd8289347c62 Mon Sep 17 00:00:00 2001 From: Fini Jastrow Date: Tue, 10 Sep 2024 21:30:07 +0200 Subject: [PATCH 1/2] os2: Fill Panose when writing font [why] When an existing font file is read from a buffer and then written back into a buffer all Panose values will be zero. The problem has been most likly been introduced with PR #630 (but I did not check that). There are two disjunct data structures in the font.tables.os2 object that describe the panose values: * An array with the Panose values `.panose = [ 1, 2, ...]` * Dedicated properties for each Panose value e.g. `.bFamilyType` The aforementioned PR seems to address only fonts created from scratch and not parsed from a buffer. Writing out the font into a buffer will always use the dedicated Panose properties and ignore the .panose array. Parsing a font does set the array but not the dedicated properties. They are not even existing then. [how] When an existing font is parsed the `.panose` array is filled (as before). But now the dedicated properties are also created and filled with the individual values. [note] The written font is always using the dedicated values. If a user changes the panose array that will have no effect. There are no checks if the data is consistent. Having the same data in two disjunct structures is not so nice to handle. Signed-off-by: Fini Jastrow --- src/tables/os2.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tables/os2.mjs b/src/tables/os2.mjs index 8392a8df..72d2f9af 100644 --- a/src/tables/os2.mjs +++ b/src/tables/os2.mjs @@ -165,6 +165,16 @@ function parseOS2Table(data, start) { for (let i = 0; i < 10; i++) { os2.panose[i] = p.parseByte(); } + os2.bFamilyType = os2.panose[0]; + os2.bSerifStyle = os2.panose[1]; + os2.bWeight = os2.panose[2]; + os2.bProportion = os2.panose[3]; + os2.bContrast = os2.panose[4]; + os2.bStrokeVariation = os2.panose[5]; + os2.bArmStyle = os2.panose[6]; + os2.bLetterform = os2.panose[7]; + os2.bMidline = os2.panose[8]; + os2.bXHeight = os2.panose[9]; os2.ulUnicodeRange1 = p.parseULong(); os2.ulUnicodeRange2 = p.parseULong(); From a4bf02594c130e7cec491a333e4f6e4358ad9bfa Mon Sep 17 00:00:00 2001 From: Fini Jastrow Date: Wed, 11 Sep 2024 11:28:56 +0200 Subject: [PATCH 2/2] os2: Do some round-trip tests [why] There is no check if the os2 table can be written to a buffer and restored completely. [how] Do some spot checks for values. Signed-off-by: Fini Jastrow --- test/tables/os2.spec.mjs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/tables/os2.spec.mjs diff --git a/test/tables/os2.spec.mjs b/test/tables/os2.spec.mjs new file mode 100644 index 00000000..d763f47a --- /dev/null +++ b/test/tables/os2.spec.mjs @@ -0,0 +1,33 @@ +import assert from 'assert'; +import { parse } from '../../dist/opentype.mjs'; +import { readFileSync } from 'fs'; +const loadSync = (url, opt) => parse(readFileSync(url), opt); + +describe('tables/os2.mjs', function () { + const font = loadSync('./test/fonts/AbrilFatface-Regular.otf'); + const testData = { + achVendID: 'TT\x00\x00', + usWeightClass: 400, + bFamilyType: 2, + bSerifStyle: 0, + bWeight: 5, + bProportion: 3, + bContrast: 0, + bStrokeVariation: 0, + bArmStyle: 0, + bLetterform: 2, + bMidline: 0, + bXHeight: 3, + }; + it('can read some OS2 table entries from file', function () { + for (const k in testData) { + assert.equal(font.tables.os2[k], testData[k]); + } + }); + const font2 = parse(font.toArrayBuffer()); + it('can write some OS2 table entries', function () { + for (const k in testData) { + assert.equal(font2.tables.os2[k], testData[k]); + } + }); +});