tenta fix pdfservice.js

This commit is contained in:
rodrigo committed 2025-04-21 23:11:33 -03:00
1 parent 8abf8791be
commit defd9b33f5
1 file changed
+17 -21
+17 -21
View File
@@ -392,22 +392,22 @@ export class PdfService {
} }
} }
// NOVA ABORDAGEM: calcula o recuo apenas na PRIMEIRA linha do parágrafo, nunca nas demais
let lines: { tokens: { text: string, font: any, underline: boolean, bold: boolean, italic: boolean }[] }[] = []; let lines: { tokens: { text: string, font: any, underline: boolean, bold: boolean, italic: boolean }[] }[] = [];
let currentTokens: { text: string, font: any, underline: boolean, bold: boolean, italic: boolean }[] = []; let currentTokens: { text: string, font: any, underline: boolean, bold: boolean, italic: boolean }[] = [];
let currentWidth = 0; let currentWidth = 0;
// Defina recuo antes do loop const recuo = indent ? fontSize * 2 : 0;
let recuo = indent ? fontSize * 2 : 0;
for (const [i, word] of words.entries()) { for (const [i, word] of words.entries()) {
const wordWidth = word.font.widthOfTextAtSize(word.text, fontSize); const wordWidth = word.font.widthOfTextAtSize(word.text, fontSize);
// Corrige o cálculo de recuo apenas na primeira palavra da primeira linha // Só aplica recuo na primeira linha do parágrafo
if (lines.length === 0 && currentTokens.length === 0 && recuo > 0) { if (lines.length === 0 && currentTokens.length === 0 && recuo > 0) {
if (wordWidth + recuo > maxWidth) { if (wordWidth + recuo + currentWidth > maxWidth) {
lines.push({ tokens: currentTokens }); lines.push({ tokens: currentTokens });
currentTokens = [word]; currentTokens = [word];
currentWidth = wordWidth; currentWidth = wordWidth;
} else { } else {
currentTokens.push(word); currentTokens.push(word);
currentWidth += wordWidth + recuo; currentWidth += wordWidth;
} }
} else { } else {
if (currentWidth + wordWidth > maxWidth && currentTokens.length > 0) { if (currentWidth + wordWidth > maxWidth && currentTokens.length > 0) {
@@ -432,34 +432,30 @@ export class PdfService {
let drawX = x; let drawX = x;
let totalWidth = line.tokens.reduce((acc, t) => acc + t.font.widthOfTextAtSize(t.text, fontSize), 0); 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) // Aplica recuo de parágrafo SOMENTE na primeira linha
let recuo = 0; let lineRecuo = (indent && i === 0) ? recuo : 0;
// Detecta se é uma linha de lista (ex: "1. ", "a) ", "1) ") e NÃO aplica recuo drawX += lineRecuo;
const isListaLinha = i === 0 && line.tokens.length > 0 && /^\s*((\d+\.|[a-zA-Z]\)|\d+\)))\s+/.test(line.tokens[0].text);
if (indent && i === 0 && (align === 'justify' || align === 'left') && !isListaLinha) {
recuo = fontSize * 2;
drawX += recuo;
}
// Alinhamento // Alinhamento
if (align === 'center') { if (align === 'center') {
drawX = x + (maxWidth - totalWidth) / 2; drawX = x + (maxWidth - totalWidth) / 2 + lineRecuo;
} else if (align === 'right') { } else if (align === 'right') {
drawX = x + (maxWidth - totalWidth); drawX = x + (maxWidth - totalWidth) + lineRecuo;
} else if (align === 'justify' && i !== lines.length - 1 && line.tokens.length > 1) { } else if (align === 'justify' && i !== lines.length - 1 && line.tokens.length > 1) {
// Justify: distribui espaço entre palavras (menos na última linha) // Justify: distribui espaço entre palavras (menos na última linha)
const wordsOnly = line.tokens.filter(t => t.text.trim() !== ''); const wordsOnly = line.tokens.filter(t => t.text.trim() !== '');
const spaces = line.tokens.filter(t => /^\s+$/.test(t.text)); const spaces = line.tokens.filter(t => /^\s+$/.test(t.text));
const numSpaces = spaces.length; const numSpaces = spaces.length;
const lineTextWidth = line.tokens.reduce((acc, t) => acc + t.font.widthOfTextAtSize(t.text, fontSize), 0); const lineTextWidth = line.tokens.reduce((acc, t) => acc + t.font.widthOfTextAtSize(t.text, fontSize), 0);
const extraSpace = maxWidth - lineTextWidth; const extraSpace = maxWidth - lineTextWidth - lineRecuo;
let spaceWidth = 0; let spaceWidth = 0;
if (numSpaces > 0) { if (numSpaces > 0) {
spaceWidth = extraSpace / numSpaces; spaceWidth = extraSpace / numSpaces;
} }
let localDrawX = drawX;
for (const t of line.tokens) { for (const t of line.tokens) {
page.drawText(t.text, { page.drawText(t.text, {
x: drawX, x: localDrawX,
y, y,
size: fontSize, size: fontSize,
font: t.font, font: t.font,
@@ -468,16 +464,16 @@ export class PdfService {
if (t.underline && t.text.trim() !== '') { if (t.underline && t.text.trim() !== '') {
const underlineY = y - 1.5; const underlineY = y - 1.5;
page.drawLine({ page.drawLine({
start: { x: drawX, y: underlineY }, start: { x: localDrawX, y: underlineY },
end: { x: drawX + t.font.widthOfTextAtSize(t.text, fontSize), y: underlineY }, end: { x: localDrawX + t.font.widthOfTextAtSize(t.text, fontSize), y: underlineY },
thickness: 0.75, thickness: 0.75,
color color
}); });
} }
if (/^\s+$/.test(t.text) && spaceWidth > 0) { if (/^\s+$/.test(t.text) && spaceWidth > 0) {
drawX += t.font.widthOfTextAtSize(t.text, fontSize) + spaceWidth; localDrawX += t.font.widthOfTextAtSize(t.text, fontSize) + spaceWidth;
} else { } else {
drawX += t.font.widthOfTextAtSize(t.text, fontSize); localDrawX += t.font.widthOfTextAtSize(t.text, fontSize);
} }
} }
y -= fontSize * 1.5; y -= fontSize * 1.5;