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

Add fonts with different font-weights #2920

Closed
whjvenyl opened this issue Sep 21, 2020 · 9 comments
Closed

Add fonts with different font-weights #2920

whjvenyl opened this issue Sep 21, 2020 · 9 comments

Comments

@whjvenyl
Copy link

whjvenyl commented Sep 21, 2020

Cross-Link to original issue #199.

Request to extend the 'addFont' with an additional parameter for font-weights. (or even better, replace the 'font-style' definition):

Why:
As of now, there's a missmatch between the possibility to define font-weights and font-styles in css and what's possible in jsPDF. Several popular font-families consist out of several individual fonts, which define their style primarly on the font-weight, not the font-style.

For example, the popular Roboto font defines for 'bold' either the Roboto-Medium (with 500 weight) and Roboto-Bold (with 700 weight). With the current implementation and the font-matching done purely on font-style, it is not possible to have both of those fonts defined in the same pdf-report. (since font weight maps to ['normal', 'italic', 'bold', ... ])

font-face declaration of roboto medium:

@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 500;
  src: local('Roboto Medium'), local('Roboto-Medium'),
    font('Roboto-Medium.woff2') format('woff2'),
    font('Roboto-Medium.woff') format('woff');
  font-display: swap;
}

currently possible to be render it in jspdf with:

doc.addFileToVFS('Roboto-Medium.ttf', robotoMedium);
doc.addFont('Roboto-Medium.ttf', 'Roboto', 'normal');

desired call with font-weight:
doc.addFont('Roboto-Medium.ttf', 'Roboto', 'normal', '500');

@azozello
Copy link

azozello commented Oct 6, 2020

Hi, I would like to help with this issue, could you please assign it to me?

@HackbrettXXX
Copy link
Collaborator

Sure, thanks :) Make sure to make the new API backwards compatible.

@vbinithyanandamv
Copy link
Contributor

I can take this, if no one is proceeding with it. @HackbrettXXX Can you provide me some direction on this one.

@HackbrettXXX
Copy link
Collaborator

@vbinithyanandamv font style and font weight are currently stored in the fontStyle field of a font object. Possible values currently are "normal", "italic", "bold", and "bolditalic".

In an optimal solution, we would probably completely separate font style and font weight. This would add another parameter to methods like addFont or setFont. Also, from a plugin perspective, it would be a breaking change to replace the current fontStyle property with two properties (changing the semantics of the fontStyle property and adding a fontWeight property). This makes it hard to implement it backwards compatible. So we probably can't really do this. Maybe behind a hotfix flag.

The second approach would be to extend the current encoding in a single string by the numeric values, e.g. fontStyle: '500italic'. Since font style does not have numeric values, this would still be unambiguous. Since fonts are stored/identified by a combination of font name and font style, there is probably not much we need to do to implement this. We could, however, add additional parameters to the public API methods, that make the usage less ugly. Making this backwards compatible should be possible, I think.

@vbinithyanandamv
Copy link
Contributor

vbinithyanandamv commented Dec 10, 2020

@HackbrettXXX So should i just provide an API like below

doc.addFont('Roboto-Medium.ttf', 'Roboto', 'normal', null , null , '500');

since we already have two more param in between, will make the last one as optional.

and when adding will combine it out

fonstyle: 'normal500'

will that be a good way to go about it? It will also be backwards compatible too.

@HackbrettXXX
Copy link
Collaborator

HackbrettXXX commented Dec 11, 2020

The public API method currently has only 4 parameters:

API.addFont = function(postScriptName, fontName, fontStyle, encoding) {

Since the encoding parameter is optional and has only 4 valid values ("StandardEncoding", "MacRomanEncoding", "Identity-H", "WinAnsiEncoding"), I think we can put the new fontWeight parameter in between:

API.addFont = function(postScriptName, fontName, fontStyle, fontWeight, encoding) {

Make sure that passing an encoding without fontWeight will still work. Also, I think we should allow numbers and strings as fontWeight values.

Regarding the "normal" value:

  • if the user passes "normal, normal", I think we should normalize this to just "normal". Same goes for "normal, 400".
  • if the user passes "italic, normal" or "italic, 400", normalize this to "normal"
  • "bold, normal" is invalid

@vbinithyanandamv
Copy link
Contributor

vbinithyanandamv commented Dec 11, 2020

@HackbrettXXX Makes sense. How do u think we should handle the invalid case? Throwing error or any standard we already follow on invalid cases?

@HackbrettXXX
Copy link
Collaborator

I think throwing an error is good :)

@HackbrettXXX
Copy link
Collaborator

Resolved in #3036.

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

No branches or pull requests

4 participants