Files
card-forge/src/lib/pdfLayout.ts
2025-07-30 16:36:06 +02:00

104 lines
2.6 KiB
TypeScript

// PDF Layout Configuration Module
// Centralized configuration for PDF generation layouts, using millimeters.
import {
PHOTO_DIMENSIONS,
TEXT_FIELD_LAYOUT,
PHOTO_FIELD_LAYOUT
} from './pdfSettings';
import { get } from 'idb-keyval';
// Conversion factor from millimeters to points (1 inch = 72 points, 1 inch = 25.4 mm)
export const MM_TO_PT = 72 / 25.4;
export interface GridLayout {
cols: number;
rows: number;
cellWidth: number; // mm
cellHeight: number; // mm
}
// Function to retrieve a blob from IndexedDB
export async function getImageBlob(url: string): Promise<Blob | undefined> {
return await get(url);
}
// Calculate how many cards can fit on a page.
export function calculateGrid(
pageWidth: number,
pageHeight: number,
margin: number,
cardWidth: number,
cardHeight: number
): GridLayout {
const printableWidth = pageWidth - 2 * margin;
const printableHeight = pageHeight - 2 * margin;
const cols = Math.floor(printableWidth / cardWidth);
const rows = Math.floor(printableHeight / cardHeight);
return {
cols,
rows,
cellWidth: cardWidth,
cellHeight: cardHeight
};
}
// Helper function to get absolute position in points for pdf-lib
export function getAbsolutePositionPt(
cellX_mm: number,
cellY_mm: number,
pageHeight_mm: number,
relativePos_mm: any
): { x: number; y: number; size: number } {
const absoluteX_mm = cellX_mm + relativePos_mm.x;
// pdf-lib Y-coordinate is from bottom, so we invert
const absoluteY_mm = pageHeight_mm - (cellY_mm + relativePos_mm.y);
return {
x: absoluteX_mm * MM_TO_PT,
y: absoluteY_mm * MM_TO_PT,
size: relativePos_mm.size // size is already in points
};
}
// Helper function to get absolute photo dimensions in points for pdf-lib
export function getAbsolutePhotoDimensionsPt(
cellX_mm: number,
cellY_mm: number,
pageHeight_mm: number,
relativePhoto_mm: any
): { x: number; y: number; width: number; height: number } {
const absoluteX_mm = cellX_mm + relativePhoto_mm.x;
// pdf-lib Y-coordinate is from bottom, so we invert and account for height
const absoluteY_mm = pageHeight_mm - (cellY_mm + relativePhoto_mm.y + relativePhoto_mm.height);
return {
x: absoluteX_mm * MM_TO_PT,
y: absoluteY_mm * MM_TO_PT,
width: relativePhoto_mm.width * MM_TO_PT,
height: relativePhoto_mm.height * MM_TO_PT
};
}
// Border configuration
export const BORDER_CONFIG = {
color: { r: 0.8, g: 0.8, b: 0.8 },
width: 1 // in points
};
// Text configuration
export const TEXT_CONFIG = {
color: { r: 0, g: 0, b: 0 },
lineHeight: 14 // in points
};
// Placeholder text configuration
export const PLACEHOLDER_CONFIG = {
text: 'Photo placeholder',
color: { r: 0.5, g: 0.5, b: 0.5 },
size: 8 // in points
};