/** * Funciones auxiliares para dibujar elementos en el PDF */ import type { jsPDF } from 'jspdf' import { PDF_CONFIG } from './pdfLayout' /** * Dibuja un checkbox (marcado o sin marcar) */ export function dibujarCheckbox( doc: jsPDF, x: number, y: number, checked: boolean = false, size: number = PDF_CONFIG.checkboxSize ): void { doc.setDrawColor(0) doc.setLineWidth(PDF_CONFIG.lineWidth.normal) doc.rect(x, y, size, size) if (checked) { // Dibujar X dentro del checkbox const padding = 0.4 doc.line(x + padding, y + padding, x + size - padding, y + size - padding) doc.line(x + size - padding, y + padding, x + padding, y + size - padding) } } /** * Dibuja un checkbox con label */ export function dibujarCheckboxConLabel( doc: jsPDF, x: number, y: number, label: string, checked: boolean = false, indent: boolean = false ): number { const checkboxSize = PDF_CONFIG.checkboxSize const xOffset = indent ? 2 : 0 dibujarCheckbox(doc, x + xOffset, y, checked, checkboxSize) doc.setFontSize(PDF_CONFIG.fontSize.tiny) doc.setFont('helvetica', 'normal') doc.text(label, x + xOffset + checkboxSize + 1, y + checkboxSize - 0.5) // Retorna el ancho total usado return xOffset + checkboxSize + 1 + doc.getTextWidth(label) } /** * Dibuja las 5 casillas de tazas con números */ export function dibujarCasillasTazas( doc: jsPDF, x: number, y: number, tazasSeleccionadas: number[], label: string ): void { const checkboxSize = PDF_CONFIG.checkboxSize const spacing = checkboxSize + 1.5 // Label doc.setFontSize(PDF_CONFIG.fontSize.small) doc.setFont('helvetica', 'bold') doc.text(label, x, y) // Casillas 1-5 const startX = x const startY = y + 2 for (let i = 1; i <= 5; i++) { const checkX = startX + (i - 1) * spacing const isSelected = tazasSeleccionadas.includes(i) dibujarCheckbox(doc, checkX, startY, isSelected, checkboxSize) // Número debajo de la casilla doc.setFontSize(PDF_CONFIG.fontSize.tiny) doc.setFont('helvetica', 'normal') doc.text(String(i), checkX + checkboxSize / 2 - 0.5, startY + checkboxSize + 2) } } /** * Dibuja un rectángulo con texto centrado */ export function dibujarCeldaTexto( doc: jsPDF, x: number, y: number, width: number, height: number, texto: string, opciones: { fontSize?: number fontStyle?: 'normal' | 'bold' align?: 'left' | 'center' | 'right' border?: boolean backgroundColor?: string } = {} ): void { const { fontSize = PDF_CONFIG.fontSize.body, fontStyle = 'normal', align = 'center', border = true, backgroundColor, } = opciones // Fondo si se especifica if (backgroundColor) { doc.setFillColor(backgroundColor) doc.rect(x, y, width, height, 'F') } // Borde if (border) { doc.setDrawColor(0) doc.setLineWidth(PDF_CONFIG.lineWidth.thin) doc.rect(x, y, width, height) } // Texto doc.setFontSize(fontSize) doc.setFont('helvetica', fontStyle) let textX = x + 1 if (align === 'center') { textX = x + width / 2 } else if (align === 'right') { textX = x + width - 1 } doc.text(texto, textX, y + height / 2 + fontSize / 4, { align, }) } /** * Dibuja una línea horizontal */ export function dibujarLineaHorizontal( doc: jsPDF, x1: number, y: number, x2: number, grosor: number = PDF_CONFIG.lineWidth.normal ): void { doc.setDrawColor(0) doc.setLineWidth(grosor) doc.line(x1, y, x2, y) } /** * Dibuja una línea vertical */ export function dibujarLineaVertical( doc: jsPDF, x: number, y1: number, y2: number, grosor: number = PDF_CONFIG.lineWidth.normal ): void { doc.setDrawColor(0) doc.setLineWidth(grosor) doc.line(x, y1, x, y2) } /** * Dibuja un campo de texto con label y línea para escribir */ export function dibujarCampoTexto( doc: jsPDF, x: number, y: number, label: string, valor: string | null, anchoLinea: number = 30 ): void { doc.setFontSize(PDF_CONFIG.fontSize.small) doc.setFont('helvetica', 'bold') doc.text(label, x, y) const labelWidth = doc.getTextWidth(label) // Línea para escribir dibujarLineaHorizontal(doc, x + labelWidth + 1, y + 0.5, x + labelWidth + 1 + anchoLinea) // Valor si existe if (valor) { doc.setFont('helvetica', 'normal') doc.text(valor, x + labelWidth + 2, y) } } /** * Dibuja texto multilínea con word wrap */ export function dibujarTextoMultilinea( doc: jsPDF, x: number, y: number, texto: string, maxWidth: number, lineHeight: number = 3 ): number { doc.setFontSize(PDF_CONFIG.fontSize.small) doc.setFont('helvetica', 'normal') const lines = doc.splitTextToSize(texto, maxWidth) let currentY = y for (const line of lines) { doc.text(line, x, currentY) currentY += lineHeight } return currentY - y // Retorna la altura total usada } /** * Dibuja un rectángulo con bordes */ export function dibujarRectangulo( doc: jsPDF, x: number, y: number, width: number, height: number, grosor: number = PDF_CONFIG.lineWidth.normal ): void { doc.setDrawColor(0) doc.setLineWidth(grosor) doc.rect(x, y, width, height) } /** * Trunca texto si excede el ancho máximo */ export function truncarTexto( doc: jsPDF, texto: string, maxWidth: number, fontSize: number ): string { doc.setFontSize(fontSize) if (doc.getTextWidth(texto) <= maxWidth) { return texto } let truncado = texto while (doc.getTextWidth(truncado + '...') > maxWidth && truncado.length > 0) { truncado = truncado.slice(0, -1) } return truncado + '...' }