You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
src and family do not survive that treatment, because they are not
independent settings: family names a subfamily/variation inside the given src. When a row style supplies both and a cell overrides only src, the
row's family is carried over and doc.font(src, family) is handed a pair that
was never configured.
Two ways that goes wrong, both from the issue:
doc.table({rowStyles: [{font: {src: SOME_TTC_FONT,family: FONT_FAMILY}}]}).row([{text: 'Hello World',font: {src: SOME_TTF_FONT}}]);// Error: Variations require a font with the fvar, gvar and glyf, or CFF2 tables
doc.table({rowStyles: [{font: {src: SOME_TTC_FONT,family: FONT_FAMILY}}]}).row([{text: 'foo'},{text: 'bar',font: {src: SOME_TTF_FONT}}]);// no error, but SOME_TTF_FONT is silently ignored - FONT_FAMILY is already// cached against the first font, so the cell renders in the wrong typeface
Setting a font for a row and overriding it on one cell is ordinary use, and the
silent variant is the worse of the two: the document renders, just with the
wrong font.
The fix
Resolve the font by walking the levels from least to most specific and treating src and family as one unit:
a level that sets src also resetsfamily, so a stale family cannot
outlive the font it belonged to;
a level that sets only family still refines the inherited src, so
selecting a variation from a row or column font keeps working;
size is genuinely independent and continues to merge on its own.
Testing
Two tests added to tests/unit/table.spec.js, using the fonts already in the
repo. The first fails without the change with the exact error from the issue:
expected [Function] to not throw an error but
'Error: Variations require a font with the fvar, gvar and glyf, or CFF2 tables.' was thrown
The second covers the case that must keep working - a cell that overrides only family still refines the row's src.
Full unit suite passes: 387/387. eslint and prettier clean.
Yes - I tested it both ways rather than assume, and it does.
#1743 is the same line. deepMerge deep-clones every source, so a Buffer or Uint8Array src came out the other side as a plain object of numeric keys,
which is why it stopped looking like a font. It is also why that merge was slow:
it was walking the whole font file byte by byte.
Same document, tests/fonts/Roboto-Regular.ttf read into a Buffer:
on master Buffer src -> Error: Not a supported font format or standard PDF font.
Uint8Array src -> Error: Not a supported font format or standard PDF font.
on this branch Buffer src -> ok
Uint8Array src -> ok
Replacing the merge with direct assignment means the src is never cloned, so it
arrives at doc.font() as the same object it went in as.
I have pushed a test covering it, which asserts identity (src === buffer) so a
future reintroduction of cloning fails loudly rather than silently. With lib/table/normalize.js reverted to master both tests in that block fail:
a cell overriding only src does not inherit the row family
-> Error: Variations require a font with the fvar, gvar and glyf, or CFF2 tables.
a binary font src is passed through untouched
-> Error: Not a supported font format or standard PDF font.
Full unit suite passes: 388/388.
Happy to add Fixes #1743 to the description if you would like both closed by
this PR.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1746.
The bug
A table resolves each cell's font by merging the column, row and cell styles key
by key:
srcandfamilydo not survive that treatment, because they are notindependent settings:
familynames a subfamily/variation inside the givensrc. When a row style supplies both and a cell overrides onlysrc, therow's
familyis carried over anddoc.font(src, family)is handed a pair thatwas never configured.
Two ways that goes wrong, both from the issue:
Setting a font for a row and overriding it on one cell is ordinary use, and the
silent variant is the worse of the two: the document renders, just with the
wrong font.
The fix
Resolve the font by walking the levels from least to most specific and treating
srcandfamilyas one unit:srcalso resetsfamily, so a stale family cannotoutlive the font it belonged to;
familystill refines the inheritedsrc, soselecting a variation from a row or column font keeps working;
sizeis genuinely independent and continues to merge on its own.Testing
Two tests added to
tests/unit/table.spec.js, using the fonts already in therepo. The first fails without the change with the exact error from the issue:
The second covers the case that must keep working - a cell that overrides only
familystill refines the row'ssrc.Full unit suite passes: 387/387. eslint and prettier clean.