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

Fix saving loca index format/version when subsetting #191

Merged
merged 1 commit into from
Mar 11, 2019

Conversation

blikblum
Copy link
Member

@blikblum blikblum commented Mar 5, 2019

Fixes saving the loca index format when subsetting.

Fonts with version 1 (long format) were being saved with version 0. This was mangling the odd offsets (they were being saved divided by two and read multiplied by two creating a off by one error)

Probably fixes bpampuch/pdfmake#1659 and foliojs/pdfkit#914

@ValeSauer
Copy link

@blikblum Thanks for this PR: As far as I see, this does not change the API. However, after having updated fontkit I still get the same results as described here bpampuch/pdfmake#1659. Not sure if I did everything the right way. Does this require further changes in the downstream modules?

@blikblum
Copy link
Member Author

blikblum commented Mar 5, 2019

Did you rebuild font kit?

@ValeSauer
Copy link

Check, I built and it worked! Great!

@@ -57,7 +57,8 @@ export default class TTFSubset extends Subset {
this.glyf = [];
this.offset = 0;
this.loca = {
offsets: []
offsets: [],
version: this.font.loca.version
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will cause us to switch to the large format sometimes when not needed. For example, if the original font contained a lot of glyphs, but the subset only contains a few, then we shouldn't need to use the large format.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be a issue because the subset size would still be proportional to the original font. Say we have a font with 1000 glyphs with same size, a subset with 100 glyphs of such font would have the expected 10% size of the original.

Also is not doable to convert from large to short format because would require to make all offsets even numbers, needing to add some sort of data padding complicating things at write and read time. This could even work with fontkit but would not work for, e.g, pdf readers

In a font i was testing (NanumGothic) the .notdef (id 0) glyph has a size of 87 bytes = the offset of the first glyph in the subset. Since the short format requires the offset to be stored divided by 2, it saves as 43. When reading the subset, the offset is multiplied by 2 getting 86 -> the glyph data is read incorrectly.

To convert to short format it would need pad the id 0 glyph (or any odd sized glyph) to have one more byte or store a lookup somewhere the glyphs that need to have the offset corrected at read time. This should work in fontkit only and the complexity (and size increase) is not worth.

@devongovett devongovett merged commit 436bd5e into foliojs:master Mar 11, 2019
@@ -56,6 +56,23 @@ describe('font subsetting', function() {
done();
}));
});

it('should handle fonts with long index to location format (indexToLocFormat = 1)', function(done) {
let font = fontkit.openSync(__dirname + '/data/FiraSans/FiraSans-Regular.ttf');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this font wasn't committed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for committing it for me

@mbutterick
Copy link

would require to make all offsets even numbers, needing to add some sort of data padding complicating things at write and read time

FWIW I work on a Racket port of fontkit. I discovered this problem independently. AFAICT padding glyf data buffer to a 2-byte boundary is established practice (in ancient times, these buffers were even padded to 4-byte boundaries). It can be done in one line right about here. It works fine. I agree with @devongovett’s original logic about deriving the loca version rather than copying it, because the short version is intended as a kind of compression.

@blikblum
Copy link
Member Author

I agree with @devongovett’s original logic about deriving the loca version rather than copying it, because the short version is intended as a kind of compression.

Nice, please create a PR so we can review.

@mbutterick
Copy link

I work on a Racket port of fontkit. Unfortunately I don’t know how to fix it in JS.

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.

Server side pdfmake embeds fonts incompletely
4 participants