alafr / SVG-to-PDFKit

Insert SVG into a PDF document created with PDFKit
MIT License
397 stars 111 forks source link

SVG size does not match PDF document size #139

Closed vitto closed 2 years ago

vitto commented 3 years ago

For some reason, when I create the insert the SVG in the PDF file it build the document with margins to the left and bottom:

function exportPDF(item) {
  const sourceFile = path.join(__dirname, `resources/${item}.svg`)
  fs.readFile(sourceFile, 'utf8', function(err, data) {
    if (err) throw err

    svgDim.get(sourceFile, function(err, dimensions) {
        if (err) console.log(err)

        const width = dimensions.width
        const height = dimensions.height
        const doc = new PDFDocument({
          size: [ width , height ]
        })

        SVGtoPDF(doc, data, 0, 0, { width: width, height: height })

        const stream = fs.createWriteStream(`dist/${item}.pdf`)
        stream.on('finish', function() {
          console.log(`Generating PDF document: ${item}.pdf ${width}x${height}px`)
        })
        doc.pipe(stream)
        doc.end()
    })

  })
}

I've solved the problem just by adding an hardcoded margin by my hand with widthScaled but I'm pretty sure there is something I'm missing, because it doesn't seems to be the right way to fix my problem:

function exportPDF(item) {
  const sourceFile = path.join(__dirname, `resources/${item}.svg`)
  fs.readFile(sourceFile, 'utf8', function(err, data) {
    if (err) throw err

    svgDim.get(sourceFile, function(err, dimensions) {
        if (err) console.log(err)

        const width = dimensions.width
        const height = dimensions.height
        const scale = 0.25
        const widthScaled = width - (width * scale)
        const heightScaled = height - (height * scale)
        const doc = new PDFDocument({
          size: [ widthScaled , heightScaled ]
        })

        SVGtoPDF(doc, data, 0, 0, { width: width, height: height })

        const stream = fs.createWriteStream(`dist/${item}.pdf`)
        stream.on('finish', function() {
          console.log(`Generating PDF document: ${item}.pdf ${width}x${height}px`)
        })
        doc.pipe(stream)
        doc.end()
    })

  })
}

It works, but I don't know why I have to do it.

thomasmattheussen commented 3 years ago

Just stumbled upon this. I'm doing the exact same thing for quite some time now. No clue as to why I've had to do it though 😅

thomasmattheussen commented 3 years ago

Well, this just bit me. What we were doing with widthScaled isn't actually correct. I've found the solution here: https://github.com/alafr/SVG-to-PDFKit/issues/102

The problem is that PDF's are in points and SVG's are in pixels. 24px equals 18pt (18/24 = 0.75).

What I had to do in my case is keep the width as is and add the option { assumePt: true }.

const doc = new PDFDocument({
    size: [24, 24],
});
SVGtoPDF(doc, svg, 0, 0, { assumePt: true });
vitto commented 2 years ago

It worked! Thank you, I didn't found this option before. Solved.