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

Fix scaling issues in html module #3203

Merged
merged 5 commits into from
Sep 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 28 additions & 8 deletions src/modules/html.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,16 @@ import { globalObject } from "../libs/globalObject.js";
position: "relative",
display: "inline-block",
width:
Math.max(
this.prop.src.clientWidth,
this.prop.src.scrollWidth,
this.prop.src.offsetWidth
) + "px",
(typeof this.opt.width === "number" &&
!isNaN(this.opt.width) &&
typeof this.opt.windowWidth === "number" &&
!isNaN(this.opt.windowWidth)
? this.opt.windowWidth
: Math.max(
this.prop.src.clientWidth,
this.prop.src.scrollWidth,
this.prop.src.offsetWidth
)) + "px",
left: 0,
right: 0,
top: 0,
Expand Down Expand Up @@ -429,11 +434,20 @@ import { globalObject } from "../libs/globalObject.js";

var pdf = this.opt.jsPDF;
var fontFaces = this.opt.fontFaces;

var scale =
typeof this.opt.width === "number" &&
!isNaN(this.opt.width) &&
typeof this.opt.windowWidth === "number" &&
!isNaN(this.opt.windowWidth)
? this.opt.width / this.opt.windowWidth
: 1;

var options = Object.assign(
{
async: true,
allowTaint: true,
scale: 1,
scale: scale,
scrollX: this.opt.scrollX || 0,
scrollY: this.opt.scrollY || 0,
backgroundColor: "#ffffff",
Expand Down Expand Up @@ -1011,8 +1025,14 @@ import { globalObject } from "../libs/globalObject.js";
* @param {Html2CanvasOptions} [options.html2canvas] html2canvas options
* @param {FontFace[]} [options.fontFaces] A list of font-faces to match when resolving fonts. Fonts will be added to the PDF based on the specified URL. If omitted, the font match algorithm falls back to old algorithm.
* @param {jsPDF} [options.jsPDF] jsPDF instance
* @param {number} [options.x] x position on the PDF document
* @param {number} [options.y] y position on the PDF document
* @param {number=} [options.x] x position on the PDF document in jsPDF units.
* @param {number=} [options.y] y position on the PDF document in jsPDF units.
* @param {number=} [options.width] The target width in the PDF document in jsPDF units. The rendered element will be
* scaled such that it fits into the specified width. Has no effect if either the <code>html2canvas.scale<code> is
* specified or the <code>windowWidth</code> option is NOT specified.
* @param {number=} [options.windowWidth] The window width in CSS pixels. In contrast to the
* <code>html2canvas.windowWidth</code> option, this option affects the actual container size while rendering and
* does NOT affect CSS media queries. This option only has an effect, if the <code>width<code> option is also specified.
*
* @example
* var doc = new jsPDF();
Expand Down
Binary file added test/reference/html-width-100-windowWidth-500.pdf
Binary file not shown.
Binary file not shown.
Binary file added test/reference/html-width-210-windowWidth-250.pdf
Binary file not shown.
Binary file added test/reference/html-width-210-windowWidth-500.pdf
Binary file not shown.
Binary file not shown.
Binary file added test/reference/html-width-300-windowWidth-500.pdf
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion test/specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ If a reference PDF doesn't exist it will be created if you run this command
while the tests run:

```
node tests/utils/reference-server.js
node test/utils/reference-server.js
```

This generates and collects reference PDFs from real browsers. This should be
Expand Down
85 changes: 84 additions & 1 deletion test/specs/html.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function toFontFaceRule(fontFace) {
`;
}

describe("Module: html", function() {
describe("Module: html", () => {
if (
(typeof isNode != "undefined" && isNode) ||
navigator.userAgent.indexOf("Chrome") < 0
Expand All @@ -41,6 +41,89 @@ describe("Module: html", function() {
comparePdf(doc.output(), "html-basic.pdf", "html");
});

it("respects width and windowWidth options", async () => {
const markup =
"<div>" +
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet reprehenderit nihil natus magnam doloremque voluptate ab, laborum officiis corrupti eius voluptatibus quisquam illum esse corporis quod fugit quibusdam minima provident." +
"</div>";

const doc210$250 = await render(markup, { width: 210, windowWidth: 250 });
comparePdf(
doc210$250.output(),
"html-width-210-windowWidth-250.pdf",
"html"
);

const doc210$500 = await render(markup, { width: 210, windowWidth: 500 });
comparePdf(
doc210$500.output(),
"html-width-210-windowWidth-500.pdf",
"html"
);

const doc210$1000 = await render(markup, { width: 210, windowWidth: 1000 });
comparePdf(
doc210$1000.output(),
"html-width-210-windowWidth-1000.pdf",
"html"
);

const doc100$500 = await render(markup, { width: 100, windowWidth: 500 });
comparePdf(
doc100$500.output(),
"html-width-100-windowWidth-500.pdf",
"html"
);

const doc300$500 = await render(markup, { width: 300, windowWidth: 500 });
comparePdf(
doc300$500.output(),
"html-width-300-windowWidth-500.pdf",
"html"
);
});

it("width should not overwrite user-provided html2canvas.scale option", async () => {
const markup =
"<div>" +
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet reprehenderit nihil natus magnam doloremque voluptate ab, laborum officiis corrupti eius voluptatibus quisquam illum esse corporis quod fugit quibusdam minima provident." +
"</div>";
const doc = await render(markup, {
width: 300,
windowWidth: 500,
html2canvas: { scale: 2 }
});
comparePdf(
doc.output(),
"html-width-300-windowWidth-500-scale-2.pdf",
"html"
);
});

it("width and windowWidth should only have an effect if both are supplied", async () => {
const markup =
"<div>" +
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet reprehenderit nihil natus magnam doloremque voluptate ab, laborum officiis corrupti eius voluptatibus quisquam illum esse corporis quod fugit quibusdam minima provident." +
"</div>";
const docWidthOnly = await render(markup, {
width: 300
});
comparePdf(
docWidthOnly.output(),
"html-width-default-windowWidth-default.pdf",
"html"
);

const docWindowWidthOnly = await render(markup, {
windowWidth: 500
});
comparePdf(
docWindowWidthOnly.output(),
"html-width-default-windowWidth-default.pdf",
"html"
);
});

it("renders font-faces", async () => {
const opts = {
fontFaces: [
Expand Down
2 changes: 2 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ declare module "jspdf" {
jsPDF?: jsPDF;
x?: number;
y?: number;
width?: number;
windowWidth?: number;
fontFaces?: HTMLFontFace[];
}

Expand Down