diff --git a/src/server/services/PdfService.ts b/src/server/services/PdfService.ts index d9eb71c..018c1e8 100644 --- a/src/server/services/PdfService.ts +++ b/src/server/services/PdfService.ts @@ -397,8 +397,9 @@ export class PdfService { let currentTokens: { text: string, font: any, underline: boolean, bold: boolean, italic: boolean }[] = []; let currentWidth = 0; for (const [i, word] of words.entries()) { + // Aplica recuo de parágrafo na primeira linha (apenas se alinhamento for justify ou left) let recuo = 0; - if (indent && lines.length === 0 && currentTokens.length === 0) { + if (indent && lines.length === 0 && currentTokens.length === 0 && (align === 'justify' || align === 'left')) { recuo = fontSize * 2; } const wordWidth = word.font.widthOfTextAtSize(word.text, fontSize); @@ -423,15 +424,40 @@ export class PdfService { let drawX = x; let totalWidth = line.tokens.reduce((acc, t) => acc + t.font.widthOfTextAtSize(t.text, fontSize), 0); + // Aplica recuo de parágrafo na primeira linha (apenas se alinhamento for justify ou left) let recuo = 0; - if (indent && i === 0) { + if (indent && i === 0 && (align === 'justify' || align === 'left')) { recuo = fontSize * 2; drawX += recuo; } + // Centralizado if (align === 'center') { drawX = x + (maxWidth - totalWidth) / 2; - } else if (align === 'justify' && i < lines.length - 1) { + for (const t of line.tokens) { + page.drawText(t.text, { + x: drawX, + y, + size: fontSize, + font: t.font, + color + }); + if (t.underline && t.text.trim() !== '') { + const underlineY = y - 1.5; + page.drawLine({ + start: { x: drawX, y: underlineY }, + end: { x: drawX + t.font.widthOfTextAtSize(t.text, fontSize), y: underlineY }, + thickness: 0.75, + color + }); + } + drawX += t.font.widthOfTextAtSize(t.text, fontSize); + } + y -= fontSize * 1.5; + continue; + } + // Justificado (exceto última linha) + else if (align === 'justify' && i < lines.length - 1) { const spaceCount = line.tokens.filter(t => /^\s+$/.test(t.text)).length; const extraSpace = spaceCount > 0 ? (maxWidth - totalWidth) / spaceCount : 0; for (const t of line.tokens) { @@ -460,6 +486,7 @@ export class PdfService { continue; } + // Alinhamento à esquerda (ou última linha justificada) for (const t of line.tokens) { page.drawText(t.text, { x: drawX, @@ -533,9 +560,15 @@ export class PdfService { while (currentPar < paragrafos.length) { let indent = paragrafos[currentPar].startsWith('§§INDENT§§'); let center = paragrafos[currentPar].startsWith('§§CENTER§§'); - let align = center ? 'center' : 'justify'; + let align: 'center' | 'justify' | 'left' = center ? 'center' : 'justify'; let text = paragrafos[currentPar].replace(/^§§INDENT§§/, '').replace(/^§§CENTER§§/, '').trim(); + // Se o parágrafo for centralizado, força alinhamento center e ignora recuo + if (center) { + indent = false; + align = 'center'; + } + text = decodeHtmlEntities(text); let x = margens.left;