tenta fix pdfservice.js
This commit is contained in:
1 parent
5705978424
commit
bf277416ff
1 file changed
+43
-61
@@ -347,46 +347,6 @@ export class PdfService {
|
|||||||
const fontItalic = await pdfDoc.embedFont(StandardFonts.TimesItalic);
|
const fontItalic = await pdfDoc.embedFont(StandardFonts.TimesItalic);
|
||||||
const fontBoldItalic = fontBold; // pdf-lib não tem TimesBoldItalic, usa bold
|
const fontBoldItalic = fontBold; // pdf-lib não tem TimesBoldItalic, usa bold
|
||||||
|
|
||||||
// Função para quebrar texto em linhas respeitando largura máxima e manter quebras de linha simples
|
|
||||||
function wrapTextStyled(text: string, font: any, fontBold: any, fontItalic: any, fontBoldItalic: any, fontSize: number, maxWidth: number, indent: boolean, align: string, bold: boolean, italic: boolean): { text: string, font: any, indent: boolean, align: string, bold: boolean, italic: boolean }[] {
|
|
||||||
// Mantém quebras de linha simples para espaçamento
|
|
||||||
const rawLines = text.split('\n');
|
|
||||||
const lines: { text: string, font: any, indent: boolean, align: string, bold: boolean, italic: boolean }[] = [];
|
|
||||||
for (const rawLine of rawLines) {
|
|
||||||
let line = rawLine;
|
|
||||||
// Detecta negrito e itálico inline
|
|
||||||
let isBold = bold, isItalic = italic;
|
|
||||||
if (/^<b>|^<strong>/.test(line)) { isBold = true; line = line.replace(/^<b>|^<strong>/, ''); }
|
|
||||||
if (/^<i>|^<em>/.test(line)) { isItalic = true; line = line.replace(/^<i>|^<em>/, ''); }
|
|
||||||
if (/<\/b>$|<\/strong>$/.test(line)) { isBold = true; line = line.replace(/<\/b>$|<\/strong>$/, ''); }
|
|
||||||
if (/<\/i>$|<\/em>$/.test(line)) { isItalic = true; line = line.replace(/<\/i>$|<\/em>$/, ''); }
|
|
||||||
line = line.replace(/<\/?(b|strong|i|em)>/gi, '');
|
|
||||||
|
|
||||||
// Seleciona fonte correta
|
|
||||||
let usedFont = font;
|
|
||||||
if (isBold && isItalic && fontBoldItalic) usedFont = fontBoldItalic;
|
|
||||||
else if (isBold && fontBold) usedFont = fontBold;
|
|
||||||
else if (isItalic && fontItalic) usedFont = fontItalic;
|
|
||||||
|
|
||||||
// Quebra em palavras para justificar
|
|
||||||
const words = line.split(' ');
|
|
||||||
let currentLine = '';
|
|
||||||
for (let i = 0; i < words.length; i++) {
|
|
||||||
const word = words[i];
|
|
||||||
const testLine = currentLine ? currentLine + ' ' + word : word;
|
|
||||||
const width = usedFont.widthOfTextAtSize(testLine, fontSize);
|
|
||||||
if (width > maxWidth && currentLine) {
|
|
||||||
lines.push({ text: currentLine, font: usedFont, indent, align, bold: isBold, italic: isItalic });
|
|
||||||
currentLine = word;
|
|
||||||
} else {
|
|
||||||
currentLine = testLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (currentLine) lines.push({ text: currentLine, font: usedFont, indent, align, bold: isBold, italic: isItalic });
|
|
||||||
}
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Quebrar o texto em páginas
|
// Quebrar o texto em páginas
|
||||||
let currentPar = 0;
|
let currentPar = 0;
|
||||||
let currentLine = 0;
|
let currentLine = 0;
|
||||||
@@ -406,7 +366,6 @@ export class PdfService {
|
|||||||
let y = PAGE_HEIGHT - margens.top;
|
let y = PAGE_HEIGHT - margens.top;
|
||||||
let firstLine = true;
|
let firstLine = true;
|
||||||
while (currentPar < paragrafos.length) {
|
while (currentPar < paragrafos.length) {
|
||||||
// Detecta recuo e alinhamento por marcação
|
|
||||||
let indent = paragrafos[currentPar].startsWith('§§INDENT§§');
|
let indent = paragrafos[currentPar].startsWith('§§INDENT§§');
|
||||||
let center = paragrafos[currentPar].startsWith('§§CENTER§§');
|
let center = paragrafos[currentPar].startsWith('§§CENTER§§');
|
||||||
let align = center ? 'center' : 'justify';
|
let align = center ? 'center' : 'justify';
|
||||||
@@ -416,22 +375,45 @@ export class PdfService {
|
|||||||
let bold = /^<b>|^<strong>/.test(text);
|
let bold = /^<b>|^<strong>/.test(text);
|
||||||
let italic = /^<i>|^<em>/.test(text);
|
let italic = /^<i>|^<em>/.test(text);
|
||||||
|
|
||||||
const styledLines = wrapTextStyled(text, font, fontBold, fontItalic, fontBoldItalic, FONT_SIZE, MAX_WIDTH - (indent ? FONT_SIZE * 2 : 0), indent, align, bold, italic);
|
// Remove tags de formatação para o texto puro
|
||||||
let lineIdx = 0;
|
let cleanText = text.replace(/<\/?(b|strong|i|em)>/gi, '');
|
||||||
if (currentLine > 0) lineIdx = currentLine;
|
|
||||||
for (; lineIdx < styledLines.length; lineIdx++) {
|
// Seleciona fonte correta
|
||||||
|
let usedFont = font;
|
||||||
|
if (bold && italic) usedFont = fontBoldItalic;
|
||||||
|
else if (bold) usedFont = fontBold;
|
||||||
|
else if (italic) usedFont = fontItalic;
|
||||||
|
|
||||||
|
// Quebra em linhas respeitando largura máxima
|
||||||
|
const words = cleanText.split(' ');
|
||||||
|
let lines: string[] = [];
|
||||||
|
let current = '';
|
||||||
|
for (let i = 0; i < words.length; i++) {
|
||||||
|
const word = words[i];
|
||||||
|
const testLine = current ? current + ' ' + word : word;
|
||||||
|
const width = usedFont.widthOfTextAtSize(testLine, FONT_SIZE);
|
||||||
|
if (width > MAX_WIDTH - (indent ? FONT_SIZE * 2 : 0) && current) {
|
||||||
|
lines.push(current);
|
||||||
|
current = word;
|
||||||
|
} else {
|
||||||
|
current = testLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current) lines.push(current);
|
||||||
|
|
||||||
|
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
||||||
if (y < margens.bottom + LINE_HEIGHT) {
|
if (y < margens.bottom + LINE_HEIGHT) {
|
||||||
currentLine = lineIdx;
|
currentLine = lineIdx;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let { text, font: usedFont, indent, align, bold, italic } = styledLines[lineIdx];
|
let line = lines[lineIdx];
|
||||||
let x = margens.left + (indent ? FONT_SIZE * 2 : 0);
|
let x = margens.left + (indent ? FONT_SIZE * 2 : 0);
|
||||||
|
|
||||||
// Centralizado
|
// Centralizado
|
||||||
if (align === 'center') {
|
if (align === 'center') {
|
||||||
const textWidth = usedFont.widthOfTextAtSize(text, FONT_SIZE);
|
const textWidth = usedFont.widthOfTextAtSize(line, FONT_SIZE);
|
||||||
x = margens.left + ((MAX_WIDTH - (indent ? FONT_SIZE * 2 : 0) - textWidth) / 2) + (indent ? FONT_SIZE * 2 : 0);
|
x = margens.left + ((MAX_WIDTH - (indent ? FONT_SIZE * 2 : 0) - textWidth) / 2) + (indent ? FONT_SIZE * 2 : 0);
|
||||||
page.drawText(text, {
|
page.drawText(line, {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
size: FONT_SIZE,
|
size: FONT_SIZE,
|
||||||
@@ -440,39 +422,39 @@ export class PdfService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Justificado (exceto última linha do parágrafo e centralizado)
|
// Justificado (exceto última linha do parágrafo e centralizado)
|
||||||
else if (text.trim().length > 0 && lineIdx < styledLines.length - 1 && align === 'justify') {
|
else if (line.trim().length > 0 && lineIdx < lines.length - 1 && align === 'justify') {
|
||||||
const words = text.split(' ');
|
const lineWords = line.split(' ');
|
||||||
if (words.length > 1) {
|
if (lineWords.length > 1) {
|
||||||
const textWidth = usedFont.widthOfTextAtSize(text, FONT_SIZE);
|
const textWidth = usedFont.widthOfTextAtSize(line, FONT_SIZE);
|
||||||
const spaceWidth = usedFont.widthOfTextAtSize(' ', FONT_SIZE);
|
const spaceWidth = usedFont.widthOfTextAtSize(' ', FONT_SIZE);
|
||||||
const totalSpaces = words.length - 1;
|
const totalSpaces = lineWords.length - 1;
|
||||||
const extraSpace = (MAX_WIDTH - (indent ? FONT_SIZE * 2 : 0) - textWidth) / totalSpaces;
|
const extraSpace = (MAX_WIDTH - (indent ? FONT_SIZE * 2 : 0) - textWidth) / totalSpaces;
|
||||||
let cursor = x;
|
let cursor = x;
|
||||||
for (let w = 0; w < words.length; w++) {
|
for (let w = 0; w < lineWords.length; w++) {
|
||||||
page.drawText(words[w], {
|
page.drawText(lineWords[w], {
|
||||||
x: cursor,
|
x: cursor,
|
||||||
y,
|
y,
|
||||||
size: FONT_SIZE,
|
size: FONT_SIZE,
|
||||||
font: usedFont
|
font: usedFont
|
||||||
});
|
});
|
||||||
if (w < words.length - 1) {
|
if (w < lineWords.length - 1) {
|
||||||
cursor += usedFont.widthOfTextAtSize(words[w], FONT_SIZE) + spaceWidth + extraSpace;
|
cursor += usedFont.widthOfTextAtSize(lineWords[w], FONT_SIZE) + spaceWidth + extraSpace;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
page.drawText(text, { x, y, size: FONT_SIZE, font: usedFont });
|
page.drawText(line, { x, y, size: FONT_SIZE, font: usedFont });
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
page.drawText(text, { x, y, size: FONT_SIZE, font: usedFont });
|
page.drawText(line, { x, y, size: FONT_SIZE, font: usedFont });
|
||||||
}
|
}
|
||||||
y -= FONT_SIZE * 1.25; // espaçamento entre linhas 1,25
|
y -= FONT_SIZE * 1.25; // espaçamento entre linhas 1,25
|
||||||
currentLine = 0;
|
currentLine = 0;
|
||||||
firstLine = false;
|
firstLine = false;
|
||||||
}
|
}
|
||||||
if (lineIdx >= styledLines.length) {
|
if (lines.length > 0) {
|
||||||
y -= FONT_SIZE * 0.5;
|
y -= FONT_SIZE * 0.5;
|
||||||
}
|
}
|
||||||
if (lineIdx < styledLines.length) {
|
if (currentLine > 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
currentPar++;
|
currentPar++;
|
||||||
|
|||||||
Reference in new issue
Block a user