From 0e26c1eac29bb0c368e5f1f7b5e43a0857fdba51 Mon Sep 17 00:00:00 2001 From: AyushCoder9 Date: Sun, 23 Nov 2025 15:23:31 +0530 Subject: [PATCH] Fix px unit page size measurement (#3921) - Make correct px scaling (72/96) the default behavior - Fixes incorrect page size measurements when using px unit with format strings - A4 format now correctly measures as 793.71 x 1122.52 px instead of 446.46 x 631.42 px - Add px_scaling_legacy hotfix for backward compatibility with old (incorrect) behavior - Update documentation to reflect the change --- HOTFIX_README.md | 26 ++++++++++++++++++++------ src/jspdf.js | 15 +++++++++++---- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/HOTFIX_README.md b/HOTFIX_README.md index ddb0fff07..111c5e7d3 100644 --- a/HOTFIX_README.md +++ b/HOTFIX_README.md @@ -16,7 +16,7 @@ new jsPDF({ # Active Hotfixes -## px_scaling +## px_scaling_legacy ### Applies To @@ -24,17 +24,31 @@ jsPDF Core ### Description -When supplying 'px' as the unit for the PDF, the internal scaling factor was being miscalculated making drawn components -larger than they should be. Enabling this hotfix will correct this scaling calculation and items will be drawn to the -correct scale. +For backward compatibility, this hotfix restores the old (incorrect) pixel scaling behavior where scaleFactor = 96/72. +By default, jsPDF now uses the correct pixel scaling (scaleFactor = 72/96) which matches the CSS standard where +1px = 1/96in and 1pt = 1/72in, resulting in 1px = 72/96 pt. ### To Enable -To enable this hotfix, supply a 'hotfixes' array to the options object in the jsPDF constructor function, and add the -string 'px_scaling' to this array. +To enable this hotfix (restore old behavior), supply a 'hotfixes' array to the options object in the jsPDF constructor function, and add the +string 'px_scaling_legacy' to this array. # Accepted Hotfixes +## px_scaling + +### Applies To + +jsPDF Core + +### Description + +When supplying 'px' as the unit for the PDF, the internal scaling factor was being miscalculated making drawn components +larger than they should be. This hotfix corrected the scaling calculation so items are drawn to the correct scale. + +This is now the default behavior as of the fix for issue #3921. The correct scaling (72/96) is used by default. +For backward compatibility with the old incorrect scaling (96/72), use the 'px_scaling_legacy' hotfix. + ## scale_text ### Applies To diff --git a/src/jspdf.js b/src/jspdf.js index e31760609..b92aeafdd 100644 --- a/src/jspdf.js +++ b/src/jspdf.js @@ -179,7 +179,8 @@ function TilingPattern(boundingBox, xStep, yStep, gState, matrix) { * @param {string} [options.orientation=portrait] - Orientation of the first page. Possible values are "portrait" or "landscape" (or shortcuts "p" or "l").
* @param {string} [options.unit=mm] Measurement unit (base unit) to be used when coordinates are specified.
* Possible values are "pt" (points), "mm", "cm", "in", "px", "pc", "em" or "ex". Note that in order to get the correct scaling for "px" - * units, you need to enable the hotfix "px_scaling" by setting options.hotfixes = ["px_scaling"]. + * units, the correct scaling (72/96) is now the default. For backward compatibility with the old incorrect scaling (96/72), + * you can enable the hotfix "px_scaling_legacy" by setting options.hotfixes = ["px_scaling_legacy"]. * @param {string/Array} [options.format=a4] The format of the first page. Can be:
* Default is "a4". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89] * @param {boolean} [options.putOnlyUsedFonts=false] Only put fonts into the PDF, which were used. @@ -2713,12 +2714,15 @@ function jsPDF(options) { if (typeof parmFormat === "string") { dimensions = getPageFormat(parmFormat.toLowerCase()); if (Array.isArray(dimensions)) { + // Dimensions from getPageFormat are in points + // beginPage expects dimensions in points, so we store them as-is width = dimensions[0]; height = dimensions[1]; } } if (Array.isArray(parmFormat)) { + // Array format values are in user units, convert to points for storage width = parmFormat[0] * scaleFactor; height = parmFormat[1] * scaleFactor; } @@ -3221,10 +3225,13 @@ function jsPDF(options) { scaleFactor = 72; break; case "px": - if (hasHotfix("px_scaling") == true) { - scaleFactor = 72 / 96; - } else { + // Default to correct px scaling (72/96 = 0.75) + // This matches CSS standard: 1px = 1/96in, 1pt = 1/72in, so 1px = 72/96 pt + // The old incorrect scaling (96/72) can be enabled via hotfix "px_scaling_legacy" for backward compatibility + if (hasHotfix("px_scaling_legacy") == true) { scaleFactor = 96 / 72; + } else { + scaleFactor = 72 / 96; } break; case "pc":