Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize CFF DICT's _defaultWidthX and _nominalWidthX #445

Merged
merged 1 commit into from
Nov 7, 2020

Conversation

ZeroUltimax
Copy link
Contributor

@ZeroUltimax ZeroUltimax commented Aug 25, 2020

As specified by CFF specification (see page 24), the defaultWidthX and nominalWidthX operators should have a default value of 0.

Description

gatherCFFTopDicts parses the CFF table's DICT data. It is in charge of assigning correct defaults for the private DICT operator subrs. I assumed we would like to also initialize the default values for _defaultWidthX and _nominalWidthX here, since other calculations rely on there always being a value for the topDict's _defaultWidthX and _nominalWidthX.

Motivation and Context

This solves the problem of OTF fonts that don't have a private DICT having all glyphs end up with a width of NaN, since the width calculation expects values for _defaultWidthX and _nominalWidthX.

How Has This Been Tested?

The following test used to fail their assertion. They now pass.

const fs = require('fs');
const opentype = require('./dist/opentype.js');
const assert = require('assert');

function makeSubFont(font, content) {
  return new opentype.Font({
    familyName: font.names.fontFamily.en,
    styleName: font.names.fontSubfamily.en,
    unitsPerEm: font.unitsPerEm,
    ascender: font.ascender,
    descender: font.descender,
    glyphs: font.stringToGlyphs(Array.from(new Set(content.split(''))).join('')),
  })
}

let font = opentype.loadSync('./SourceHanSans-Regular.otf');
const char = '上';
const advanceWidthChar = font.charToGlyph(char).advanceWidth;

assert.strictEqual(font.charToGlyph(char).advanceWidth, advanceWidthChar, "advanceWidth before getBoundingBox");
font.charToGlyph(char).getBoundingBox();
// works
assert.strictEqual(font.charToGlyph(char).advanceWidth, advanceWidthChar, "advanceWidth after getBoundingBox");

const subFont = makeSubFont(font, "上与乡互他伊作全公制前包单司客工布带开括旅晓朗机村棒游环球的相着离程管糖网罕联至蕾视足踏迹遍频颗高︐︒﹁﹂");

const fileName = 'test.woff';
fs.writeFileSync(fileName, Buffer.from(subFont.toArrayBuffer()));
let newFont = opentype.loadSync(fileName, {});

assert.strictEqual(newFont.charToGlyph(char).advanceWidth, advanceWidthChar, "advanceWidth before getBoundingBox");
newFont.charToGlyph(char).getBoundingBox();
// does not work
assert.strictEqual(newFont.charToGlyph(char).advanceWidth, advanceWidthChar, "advanceWidth after getBoundingBox");

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I did npm run test and all tests passed green (including code styling checks).
  • I have added tests to cover my changes.
  • My change requires a change to the documentation.
  • I have updated the README accordingly.
  • I have read the CONTRIBUTING document.

@Jolg42
Copy link
Member

Jolg42 commented Nov 7, 2020

Amazing PR description ❤️

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants