mirror of
https://github.com/documenso/documenso.git
synced 2026-07-27 02:15:05 +10:00
fix: get accurate pdf page size (#1980)
Handles edge cases with PDF media boxes and crop boxes, deals with certain documents that had been uploaded with weird combos of sizings.
This commit is contained in:
@@ -3,6 +3,7 @@ import type { PDFDocument } from 'pdf-lib';
|
|||||||
import { TextAlignment, rgb, setFontAndSize } from 'pdf-lib';
|
import { TextAlignment, rgb, setFontAndSize } from 'pdf-lib';
|
||||||
|
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
|
||||||
|
import { getPageSize } from './get-page-size';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a rejection stamp to each page of a PDF document.
|
* Adds a rejection stamp to each page of a PDF document.
|
||||||
@@ -27,7 +28,7 @@ export async function addRejectionStampToPdf(
|
|||||||
|
|
||||||
for (let i = 0; i < pages.length; i++) {
|
for (let i = 0; i < pages.length; i++) {
|
||||||
const page = pages[i];
|
const page = pages[i];
|
||||||
const { width, height } = page.getSize();
|
const { width, height } = getPageSize(page);
|
||||||
|
|
||||||
// Draw the "REJECTED" text
|
// Draw the "REJECTED" text
|
||||||
const rejectedTitleText = 'DOCUMENT REJECTED';
|
const rejectedTitleText = 'DOCUMENT REJECTED';
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import type { PDFPage } from 'pdf-lib';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the effective page size for PDF operations.
|
||||||
|
*
|
||||||
|
* Uses CropBox by default to handle rare cases where MediaBox is larger than CropBox.
|
||||||
|
* Falls back to MediaBox when it's smaller than CropBox, following typical PDF reader behavior.
|
||||||
|
*/
|
||||||
|
export const getPageSize = (page: PDFPage) => {
|
||||||
|
const cropBox = page.getCropBox();
|
||||||
|
const mediaBox = page.getMediaBox();
|
||||||
|
|
||||||
|
if (mediaBox.width < cropBox.width || mediaBox.height < cropBox.height) {
|
||||||
|
return mediaBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cropBox;
|
||||||
|
};
|
||||||
@@ -33,6 +33,7 @@ import {
|
|||||||
ZRadioFieldMeta,
|
ZRadioFieldMeta,
|
||||||
ZTextFieldMeta,
|
ZTextFieldMeta,
|
||||||
} from '../../types/field-meta';
|
} from '../../types/field-meta';
|
||||||
|
import { getPageSize } from './get-page-size';
|
||||||
|
|
||||||
export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignature) => {
|
export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignature) => {
|
||||||
const [fontCaveat, fontNoto] = await Promise.all([
|
const [fontCaveat, fontNoto] = await Promise.all([
|
||||||
@@ -77,7 +78,7 @@ export const insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignatu
|
|||||||
|
|
||||||
const isPageRotatedToLandscape = pageRotationInDegrees === 90 || pageRotationInDegrees === 270;
|
const isPageRotatedToLandscape = pageRotationInDegrees === 90 || pageRotationInDegrees === 270;
|
||||||
|
|
||||||
let { width: pageWidth, height: pageHeight } = page.getSize();
|
let { width: pageWidth, height: pageHeight } = getPageSize(page);
|
||||||
|
|
||||||
// PDFs can have pages that are rotated, which are correctly rendered in the frontend.
|
// PDFs can have pages that are rotated, which are correctly rendered in the frontend.
|
||||||
// However when we load the PDF in the backend, the rotation is applied.
|
// However when we load the PDF in the backend, the rotation is applied.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {
|
|||||||
ZRadioFieldMeta,
|
ZRadioFieldMeta,
|
||||||
ZTextFieldMeta,
|
ZTextFieldMeta,
|
||||||
} from '../../types/field-meta';
|
} from '../../types/field-meta';
|
||||||
|
import { getPageSize } from './get-page-size';
|
||||||
|
|
||||||
export const legacy_insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignature) => {
|
export const legacy_insertFieldInPDF = async (pdf: PDFDocument, field: FieldWithSignature) => {
|
||||||
const [fontCaveat, fontNoto] = await Promise.all([
|
const [fontCaveat, fontNoto] = await Promise.all([
|
||||||
@@ -63,7 +64,7 @@ export const legacy_insertFieldInPDF = async (pdf: PDFDocument, field: FieldWith
|
|||||||
|
|
||||||
const isPageRotatedToLandscape = pageRotationInDegrees === 90 || pageRotationInDegrees === 270;
|
const isPageRotatedToLandscape = pageRotationInDegrees === 90 || pageRotationInDegrees === 270;
|
||||||
|
|
||||||
let { width: pageWidth, height: pageHeight } = page.getSize();
|
let { width: pageWidth, height: pageHeight } = getPageSize(page);
|
||||||
|
|
||||||
// PDFs can have pages that are rotated, which are correctly rendered in the frontend.
|
// PDFs can have pages that are rotated, which are correctly rendered in the frontend.
|
||||||
// However when we load the PDF in the backend, the rotation is applied.
|
// However when we load the PDF in the backend, the rotation is applied.
|
||||||
|
|||||||
Reference in New Issue
Block a user