// Handle rotated/landscape pages in PDFs // Procedural implementation (no OOP) interface PDFRotationState { rotations: Map; } function createPDFRotation(): PDFRotationState { return { rotations: new Map(), }; } async function loadPDFPageRotations( state: PDFRotationState, doc: any, ): Promise { const rotations = new Map(); for (let pageNum = 1; pageNum <= doc.numPages; pageNum++) { const page = await doc.getPage(pageNum); const viewport = page.getViewport({ scale: 1 }); const rotation = viewport.rotation; if (rotation !== 0) { rotations.set(pageNum, rotation); } } return { ...state, rotations }; } function getPDFPageRotation( state: PDFRotationState, pageNumber: number, ): number { return state.rotations.get(pageNumber) || 0; } function hasPDFPageRotation( state: PDFRotationState, pageNumber: number, ): boolean { return state.rotations.has(pageNumber); } function applyPDFRotation( state: PDFRotationState, canvas: HTMLCanvasElement, pageNumber: number, ): void { const rotation = getPDFPageRotation(state, pageNumber); if (rotation === 0) return; const ctx = canvas.getContext("2d"); if (!ctx) return; ctx.save(); ctx.translate(canvas.width / 2, canvas.height / 2); ctx.rotate((rotation * Math.PI) / 180); ctx.translate(-canvas.width / 2, -canvas.height / 2); ctx.restore(); } function getPDFAdjustedViewport( state: PDFRotationState, pageNumber: number, viewport: any, ): any { const rotation = getPDFPageRotation(state, pageNumber); if (rotation === 0 || rotation === 180) { return viewport; } return { ...viewport, width: viewport.height, height: viewport.width, }; }