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

Text scaleFactor incorrect depending on the unit? #2781

Closed
cswkim opened this issue Jun 21, 2020 · 4 comments
Closed

Text scaleFactor incorrect depending on the unit? #2781

cswkim opened this issue Jun 21, 2020 · 4 comments

Comments

@cswkim
Copy link

cswkim commented Jun 21, 2020

I'm using the master branch of jsPDF in an iOS browser. My initialization is:

const doc = new jsPDF({
    unit: 'in',
    format: [5.5, 8.5],
    precision: 10,
    putOnlyUsedFonts: true
})

doc.setFontSize(20)

I want the PDF to mimic the text elements in my HTML which use px units. setFontSize() accepts parameters as pt values right? So if my HTML text element is 20px in css, what do I send to setFontSize()? 1px = 0.75pt? If so, shouldn't I be sending 15? Is the original global unit setting in the constructor have anything to do with the setFontSize() method? I find that multiplying my css px value by ~1.6-1.7 gets the generated PDF to better match font sizing in my HTML. So if my html text element has font-size: 20px, I call doc.setFontSize(34) But that was just me constantly changing the multiply factor and eyeing the result. I'm trying to find an exact method. Also, letter-spacing in css is normal by default, but I guess what normal means is defined by the browser. Not setting the charSpace option and leaving it as the default value of 0 also does not exactly match what gets generated in the PDF.

Does the device PPI/DPI factor in? The dimensions of my HTML container element? The dimensions of the PDF page?

@HackbrettXXX
Copy link
Collaborator

HackbrettXXX commented Jun 23, 2020

As you can see here, the scaleFactor is set to a fixed value of 1pt = 96/72 px. It does not factor in the device PPI/DPI. This behavior is "correct", since we can argue that PDF is a print medium and CSS sets the pixel ratio for print media to 1px = 1/96in (see e.g. here).

Regarding the letter-spacing: could you attach screenshots and the output PDF?

EDIT: This comment is incorrect! #2927 (comment)

@github-actions
Copy link

This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.

@cswkim
Copy link
Author

cswkim commented Mar 24, 2021

As you can see here, the scaleFactor is set to a fixed value of 1pt = 96/72 px. It does not factor in the device PPI/DPI. This behavior is "correct", since we can argue that PDF is a print medium and CSS sets the pixel ratio for print media to 1px = 1/96in (see e.g. here).

Regarding the letter-spacing: could you attach screenshots and the output PDF?

EDIT: This comment is incorrect! #2927 (comment)

Sorry to bring up this old issue, but I'm wondering how to properly scale font. I can't seem to get the text sizes correct in the generated PDF. All of my html elements (images and text) are absolutely positioned and have px units for dimensions and size. But I want my PDF to be 5.5in by 8.5in, so initially I had:

const doc = new jsPDF({
    unit: 'in',
    format: [5.5, 8.5],
    putOnlyUsedFonts: true
})

but based on your comment and looking at the linked issue, I decided to use px like so:

const doc = new jsPDF({
    unit: 'px',
    format: [5.5 * 96, 8.5 * 96],
    putOnlyUsedFonts: true,
    hotfixes: ['px_scaling']
})

and then I re-calculated every elements left, top (and for images width and height) to scale from my container dimensions to the PDF dimensions:

const newLeft = (elementLeft / containerWidth) * (5.5 * 96)
const newTop = (elementTop / containerHeight) * (8.5 * 96)
.etc

This is so that my html container is let's say 209px by 323px but the PDF is 528px (5.5*96) by 816px (8.5*96) and all the elements are scaled and positioned properly in the PDF. This seems to work fine, but I don't know what to do about setFontSize(). My text elements all use px for font-size. If I just use the px value for setFontSize() I get something like:

HTML
Screen Shot 2021-03-24 at 10 07 52 AM

PDF
Screen Shot 2021-03-24 at 10 08 47 AM

Obviously the text needs to scale up, but I don't know by how much. Is there a way to grab the in to px scale factor of 96 from the API so I don't have to hard-code? Is there a better way to do this?

@HackbrettXXX
Copy link
Collaborator

@cswkim font sizes are always given in pt for historic reasons. So you need to scale the font size yourself. You can retrieve the current scale factor with doc.internal.scaleFactor.

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

2 participants