eclipsesource / eclipsesource/pdf-maker
Fonts with more than four styles are registered under the wrong family
- Dominant language
- TypeScript
- Stars
- 22
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
`registerFont()` derives the font family from the *legacy* family name (name ID 1) of the font, by
way of `PDFEmbeddedFont.familyName` in `@ralfstx/pdf-core`. That name is constrained by the
four-styles-per-family model of legacy systems, so a family that ships more than regular, italic,
bold, and bold italic has to spread the remaining styles over families of their own. The real
family is in the typographic family name (name ID 16), which is present exactly when it deviates
from name ID 1.
Inter is a typical example. Of its 18 static faces, only the four legacy styles report the family
`Inter`:
| file | family (ID 1) | typographic family (ID 16) | weight | style |
| --- | --- | --- | --- | --- |
| `Inter-Thin.ttf` | `Inter Thin` | `Inter` | 100 | normal |
| `Inter-ExtraLight.ttf` | `Inter Extra Light` | `Inter` | 200 | normal |
| `Inter-Light.ttf` | `Inter Light` | `Inter` | 300 | normal |
| `Inter-Regular.ttf` | `Inter` | – | 400 | normal |
| `Inter-Medium.ttf` | `Inter Medium` | `Inter` | 500 | normal |
| `Inter-SemiBold.ttf` | `Inter Semi Bold` | `Inter` | 600 | normal |
| `Inter-Bold.ttf` | `Inter` | – | 700 | normal |
| `Inter-ExtraBold.ttf` | `Inter Extra Bold` | `Inter` | 800 | normal |
| `Inter-Black.ttf` | `Inter Black` | `Inter` | 900 | normal |
The italic face of each weight behaves the same way. Weight and style are extracted correctly for
all of them, from `usWeightClass` and `fsSelection`; the family is the only thing that goes wrong.
## Steps to reproduce
```js
const pdfMaker = new PdfMaker();
pdfMaker.registerFont(await readFile('Inter-Regular.ttf'));
pdfMaker.registerFont(await readFile('Inter-SemiBold.ttf'));
pdfMaker.registerFont(await readFile('Inter-Bold.ttf'));
await pdfMaker.makePdf({
content: [{ text: 'Semi Bold', fontFamily: 'Inter', fontWeight: 600 }],
});
```
Expected: the text is rendered in Inter Semi Bold.
Actual: the text is rendered in Inter Bold. The semi-bold face is registered under the family
`Inter Semi Bold`, so `selectFontDef()` never considers it for the family `Inter`, and
`selectFontForWeight()` resolves weight 600 to the next higher weight it does find, 700.
Working around this requires overriding the family per face:
```js
pdfMaker.registerFont(await readFile('Inter-SemiBold.ttf'), { family: 'Inter', weight: 600 });
```
## Related: the fallback is silent
Whether or not the family is resolved correctly, `selectFontForWeight()` substituting a different
weight is invisible from the outside. A warning when the selected weight deviates from the
requested one would turn this class of problem into a quick diagnosis instead of a font table dig.
Happy to split that out into its own issue.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.