Take the userUnit into account in the PageViewport class (issue 19176)

This commit is contained in:
Jonas Jenwald 2024-12-08 14:45:54 +01:00
parent 3f1d07a35e
commit c6e3fc4fe6
6 changed files with 84 additions and 6 deletions

View File

@ -1408,6 +1408,7 @@ class PDFPageProxy {
} = {}) { } = {}) {
return new PageViewport({ return new PageViewport({
viewBox: this.view, viewBox: this.view,
userUnit: this.userUnit,
scale, scale,
rotation, rotation,
offsetX, offsetX,

View File

@ -83,6 +83,7 @@ async function fetchData(url, type = "text") {
* @typedef {Object} PageViewportParameters * @typedef {Object} PageViewportParameters
* @property {Array<number>} viewBox - The xMin, yMin, xMax and * @property {Array<number>} viewBox - The xMin, yMin, xMax and
* yMax coordinates. * yMax coordinates.
* @property {number} userUnit - The size of units.
* @property {number} scale - The scale of the viewport. * @property {number} scale - The scale of the viewport.
* @property {number} rotation - The rotation, in degrees, of the viewport. * @property {number} rotation - The rotation, in degrees, of the viewport.
* @property {number} [offsetX] - The horizontal, i.e. x-axis, offset. The * @property {number} [offsetX] - The horizontal, i.e. x-axis, offset. The
@ -116,6 +117,7 @@ class PageViewport {
*/ */
constructor({ constructor({
viewBox, viewBox,
userUnit,
scale, scale,
rotation, rotation,
offsetX = 0, offsetX = 0,
@ -123,11 +125,14 @@ class PageViewport {
dontFlip = false, dontFlip = false,
}) { }) {
this.viewBox = viewBox; this.viewBox = viewBox;
this.userUnit = userUnit;
this.scale = scale; this.scale = scale;
this.rotation = rotation; this.rotation = rotation;
this.offsetX = offsetX; this.offsetX = offsetX;
this.offsetY = offsetY; this.offsetY = offsetY;
scale *= userUnit; // Take the userUnit into account.
// creating transform to convert pdf coordinate system to the normal // creating transform to convert pdf coordinate system to the normal
// canvas like coordinates taking in account scale and rotation // canvas like coordinates taking in account scale and rotation
const centerX = (viewBox[2] + viewBox[0]) / 2; const centerX = (viewBox[2] + viewBox[0]) / 2;
@ -208,12 +213,14 @@ class PageViewport {
* @type {Object} * @type {Object}
*/ */
get rawDims() { get rawDims() {
const { viewBox } = this; const { userUnit, viewBox } = this;
const dims = viewBox.map(x => x * userUnit);
return shadow(this, "rawDims", { return shadow(this, "rawDims", {
pageWidth: viewBox[2] - viewBox[0], pageWidth: dims[2] - dims[0],
pageHeight: viewBox[3] - viewBox[1], pageHeight: dims[3] - dims[1],
pageX: viewBox[0], pageX: dims[0],
pageY: viewBox[1], pageY: dims[1],
}); });
} }
@ -231,6 +238,7 @@ class PageViewport {
} = {}) { } = {}) {
return new PageViewport({ return new PageViewport({
viewBox: this.viewBox.slice(), viewBox: this.viewBox.slice(),
userUnit: this.userUnit,
scale, scale,
rotation, rotation,
offsetX, offsetX,
@ -514,6 +522,7 @@ function getXfaPageViewport(xfaPage, { scale = 1, rotation = 0 }) {
return new PageViewport({ return new PageViewport({
viewBox, viewBox,
userUnit: 1,
scale, scale,
rotation, rotation,
}); });

View File

@ -553,6 +553,7 @@
!poppler-67295-0.pdf !poppler-67295-0.pdf
!poppler-85140-0.pdf !poppler-85140-0.pdf
!issue15012.pdf !issue15012.pdf
!issue19176.pdf
!issue15150.pdf !issue15150.pdf
!poppler-395-0-fuzzed.pdf !poppler-395-0-fuzzed.pdf
!issue14165.pdf !issue14165.pdf

28
test/pdfs/issue19176.pdf Normal file
View File

@ -0,0 +1,28 @@
%PDF-2.0
%¿÷¢þ
1 0 obj
<< /Pages 2 0 R /Type /Catalog >>
endobj
2 0 obj
<< /Count 1 /Kids [ 3 0 R ] /Type /Pages >>
endobj
3 0 obj
<< /Type /Page /Parent 2 0 R /Resources << >> /MediaBox [0 0 8.5 11] /UserUnit 72 /Contents 4 0 R >>
endobj
4 0 obj
<< /Length 15 >>
stream
1 1 6.5 9 re f
endstream
endobj
xref
0 5
0000000000 65535 f
0000000015 00000 n
0000000064 00000 n
0000000123 00000 n
0000000239 00000 n
trailer << /Root 1 0 R /Size 5 >>
startxref
303
%%EOF

View File

@ -2734,6 +2734,13 @@
"type": "eq", "type": "eq",
"about": "TrueType font with (0, 1) cmap." "about": "TrueType font with (0, 1) cmap."
}, },
{
"id": "issue19176",
"file": "pdfs/issue19176.pdf",
"md5": "c307418412a72997671518fa978439e0",
"rounds": 1,
"type": "eq"
},
{ {
"id": "issue4801", "id": "issue4801",
"file": "pdfs/issue4801.pdf", "file": "pdfs/issue4801.pdf",

View File

@ -3081,10 +3081,21 @@ describe("api", function () {
expect(page.ref).toEqual({ num: 15, gen: 0 }); expect(page.ref).toEqual({ num: 15, gen: 0 });
}); });
it("gets userUnit", function () { it("gets default userUnit", function () {
expect(page.userUnit).toEqual(1.0); expect(page.userUnit).toEqual(1.0);
}); });
it("gets non-default userUnit", async function () {
const loadingTask = getDocument(buildGetDocumentParams("issue19176.pdf"));
const pdfDoc = await loadingTask.promise;
const pdfPage = await pdfDoc.getPage(1);
expect(pdfPage.userUnit).toEqual(72);
await loadingTask.destroy();
});
it("gets view", function () { it("gets view", function () {
expect(page.view).toEqual([0, 0, 595.28, 841.89]); expect(page.view).toEqual([0, 0, 595.28, 841.89]);
}); });
@ -3116,6 +3127,7 @@ describe("api", function () {
expect(viewport instanceof PageViewport).toEqual(true); expect(viewport instanceof PageViewport).toEqual(true);
expect(viewport.viewBox).toEqual(page.view); expect(viewport.viewBox).toEqual(page.view);
expect(viewport.userUnit).toEqual(page.userUnit);
expect(viewport.scale).toEqual(1.5); expect(viewport.scale).toEqual(1.5);
expect(viewport.rotation).toEqual(90); expect(viewport.rotation).toEqual(90);
expect(viewport.transform).toEqual([0, 1.5, 1.5, 0, 0, 0]); expect(viewport.transform).toEqual([0, 1.5, 1.5, 0, 0, 0]);
@ -3123,6 +3135,26 @@ describe("api", function () {
expect(viewport.height).toEqual(892.92); expect(viewport.height).toEqual(892.92);
}); });
it("gets viewport with non-default userUnit", async function () {
const loadingTask = getDocument(buildGetDocumentParams("issue19176.pdf"));
const pdfDoc = await loadingTask.promise;
const pdfPage = await pdfDoc.getPage(1);
const viewport = pdfPage.getViewport({ scale: 1 });
expect(viewport instanceof PageViewport).toEqual(true);
expect(viewport.viewBox).toEqual(pdfPage.view);
expect(viewport.userUnit).toEqual(pdfPage.userUnit);
expect(viewport.scale).toEqual(1);
expect(viewport.rotation).toEqual(0);
expect(viewport.transform).toEqual([72, 0, 0, -72, 0, 792]);
expect(viewport.width).toEqual(612);
expect(viewport.height).toEqual(792);
await loadingTask.destroy();
});
it('gets viewport with "offsetX/offsetY" arguments', function () { it('gets viewport with "offsetX/offsetY" arguments', function () {
const viewport = page.getViewport({ const viewport = page.getViewport({
scale: 1, scale: 1,