Skip to content

Bounding box of form objects is incorrect for units other than 'pt' #3627

@HackbrettXXX

Description

@HackbrettXXX

Steps to reproduce

const doc = new jsPDF({ unit: 'mm', format: [200, 200], orientation: 'p' }) // with unit: 'pt' it works as expected

doc.advancedAPI()

doc.beginFormObject(-50, -50, 100, 100, doc.unitMatrix)
doc.rect(-50, -50, 100, 100).fill()
doc.endFormObject('0')

doc.doFormObject('0', new doc.Matrix(1, 0, 0, 1, 100, 100))

doc.setDrawColor(255, 0, 0)
doc.rect(50, 50, 100, 100).stroke()

doc.compatAPI()

Expected output

image

Actual output

image
actual.pdf
Form object:

24 0 obj
<<
/Type /XObject
/Subtype /Form
/BBox [-50. -50. -14.7222222222222285 -14.7222222222222285]
/Matrix [1. 0. 0. 1. 0. 0.]
/Length 24
>>
stream
-50. -50. 100. 100. re
f
endstream
endobj

Issue

The width and height of the bbox are scaled with the inverse scaling factor:

jsPDF/src/jspdf.js

Lines 5957 to 5964 in 5d09af9

var getPageWidth = (API.getPageWidth = function(pageNumber) {
pageNumber = pageNumber || currentPage;
return (
(pagesContext[pageNumber].mediaBox.topRightX -
pagesContext[pageNumber].mediaBox.bottomLeftX) /
scaleFactor
);
});

called by

jsPDF/src/jspdf.js

Lines 5707 to 5721 in 5d09af9

var RenderTarget = function() {
this.page = page;
this.currentPage = currentPage;
this.pages = pages.slice(0);
this.pagesContext = pagesContext.slice(0);
this.x = pageX;
this.y = pageY;
this.matrix = pageMatrix;
this.width = getPageWidth(currentPage);
this.height = getPageHeight(currentPage);
this.outputDestination = outputDestination;
this.id = ""; // set by endFormObject()
this.objectNumber = -1; // will be set by putXObject()
};

called by

jsPDF/src/jspdf.js

Lines 5751 to 5771 in 5d09af9

var endFormObject = function(key) {
// only add it if it is not already present (the keys provided by the user must be unique!)
if (renderTargetMap[key]) {
renderTargetStack.pop().restore();
return;
}
// save the created xObject
var newXObject = new RenderTarget();
var xObjectId = "Xo" + (Object.keys(renderTargets).length + 1).toString(10);
newXObject.id = xObjectId;
renderTargetMap[key] = xObjectId;
renderTargets[xObjectId] = newXObject;
events.publish("addFormObject", newXObject);
// restore state from stack
renderTargetStack.pop().restore();
};

x and y are not scaled.

The expected behavior is that x, y, with, height are all scaled by the normal (not inverse) scaling factor. This way the values passed to beginFormObject are actually interpreted with the correct unit.

This issue came up in yWorks/svg2pdf.js#244.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions