tenta fix pdfservice.js
This commit is contained in:
1 parent
287ed34abf
commit
eeeae75919
1 file changed
+70
-23
@@ -329,38 +329,56 @@ export class PdfService {
|
||||
.replace(/<!--[\s\S]*?-->/g, '');
|
||||
}
|
||||
|
||||
// Função para renderizar texto com formatação inline (negrito, itálico, ambos) e controle de quebra de linha
|
||||
function renderInlineFormattedParagraph(page, text: string, x: number, y: number, font, fontBold, fontItalic, fontBoldItalic, fontSize: number, color, align: string, maxWidth: number) {
|
||||
// Divide o texto em tokens de formatação (<b>, <i>, etc)
|
||||
let regex = /(<\/?(b|strong|i|em)>)/gi;
|
||||
let tokens: { text: string, bold: boolean, italic: boolean }[] = [];
|
||||
// Função para renderizar texto com formatação inline (negrito, itálico, sublinhado) e controle de quebra de linha e recuo
|
||||
function renderInlineFormattedParagraph(
|
||||
page,
|
||||
text: string,
|
||||
x: number,
|
||||
y: number,
|
||||
font,
|
||||
fontBold,
|
||||
fontItalic,
|
||||
fontBoldItalic,
|
||||
fontSize: number,
|
||||
color,
|
||||
align: string,
|
||||
maxWidth: number,
|
||||
indent: boolean
|
||||
) {
|
||||
// Divide o texto em tokens de formatação (<b>, <i>, <u>, etc)
|
||||
let regex = /(<\/?(b|strong|i|em|u)>)/gi;
|
||||
let tokens: { text: string, bold: boolean, italic: boolean, underline: boolean }[] = [];
|
||||
let lastIndex = 0;
|
||||
let match;
|
||||
let currentStyle = { bold: false, italic: false };
|
||||
let currentStyle = { bold: false, italic: false, underline: false };
|
||||
while ((match = regex.exec(text)) !== null) {
|
||||
if (match.index > lastIndex) {
|
||||
tokens.push({
|
||||
text: text.substring(lastIndex, match.index),
|
||||
bold: currentStyle.bold,
|
||||
italic: currentStyle.italic
|
||||
italic: currentStyle.italic,
|
||||
underline: currentStyle.underline
|
||||
});
|
||||
}
|
||||
if (/^<(b|strong)>$/i.test(match[0])) currentStyle.bold = true;
|
||||
if (/^<\/(b|strong)>$/i.test(match[0])) currentStyle.bold = false;
|
||||
if (/^<(i|em)>$/i.test(match[0])) currentStyle.italic = true;
|
||||
if (/^<\/(i|em)>$/i.test(match[0])) currentStyle.italic = false;
|
||||
if (/^<u>$/i.test(match[0])) currentStyle.underline = true;
|
||||
if (/^<\/u>$/i.test(match[0])) currentStyle.underline = false;
|
||||
lastIndex = regex.lastIndex;
|
||||
}
|
||||
if (lastIndex < text.length) {
|
||||
tokens.push({
|
||||
text: text.substring(lastIndex),
|
||||
bold: currentStyle.bold,
|
||||
italic: currentStyle.italic
|
||||
italic: currentStyle.italic,
|
||||
underline: currentStyle.underline
|
||||
});
|
||||
}
|
||||
|
||||
// Junta todos os tokens em uma lista de palavras com formatação
|
||||
let words: { text: string, font: any }[] = [];
|
||||
let words: { text: string, font: any, underline: boolean }[] = [];
|
||||
for (const token of tokens) {
|
||||
let usedFont = font;
|
||||
if (token.bold && token.italic) usedFont = fontBoldItalic;
|
||||
@@ -370,19 +388,24 @@ export class PdfService {
|
||||
const split = token.text.split(/(\s+)/);
|
||||
for (const part of split) {
|
||||
if (part.length > 0) {
|
||||
words.push({ text: part, font: usedFont });
|
||||
words.push({ text: part, font: usedFont, underline: token.underline });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Monta linhas respeitando largura máxima
|
||||
let lines: { text: string, tokens: { text: string, font: any }[] }[] = [];
|
||||
let lines: { text: string, tokens: { text: string, font: any, underline: boolean }[] }[] = [];
|
||||
let currentLine = '';
|
||||
let currentTokens: { text: string, font: any }[] = [];
|
||||
let currentTokens: { text: string, font: any, underline: boolean }[] = [];
|
||||
let currentWidth = 0;
|
||||
for (const word of words) {
|
||||
for (const [i, word] of words.entries()) {
|
||||
// Aplica recuo de parágrafo na primeira linha
|
||||
let recuo = 0;
|
||||
if (indent && lines.length === 0 && currentLine === '') {
|
||||
recuo = fontSize * 2;
|
||||
}
|
||||
const wordWidth = word.font.widthOfTextAtSize(word.text, fontSize);
|
||||
if (currentWidth + wordWidth > maxWidth && currentLine.trim() !== '') {
|
||||
if (currentWidth + wordWidth + recuo > maxWidth && currentLine.trim() !== '') {
|
||||
lines.push({ text: currentLine, tokens: currentTokens });
|
||||
currentLine = word.text;
|
||||
currentTokens = [word];
|
||||
@@ -403,6 +426,13 @@ 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
|
||||
let recuo = 0;
|
||||
if (indent && i === 0) {
|
||||
recuo = fontSize * 2;
|
||||
drawX += recuo;
|
||||
}
|
||||
|
||||
// Centralizado
|
||||
if (align === 'center') {
|
||||
drawX = x + (maxWidth - totalWidth) / 2;
|
||||
@@ -420,13 +450,23 @@ export class PdfService {
|
||||
font: t.font,
|
||||
color
|
||||
});
|
||||
// Sublinhado
|
||||
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
|
||||
});
|
||||
}
|
||||
if (/^\s+$/.test(t.text)) {
|
||||
drawX += t.font.widthOfTextAtSize(t.text, fontSize) + extraSpace;
|
||||
} else {
|
||||
drawX += t.font.widthOfTextAtSize(t.text, fontSize);
|
||||
}
|
||||
}
|
||||
y -= fontSize * 1.25;
|
||||
y -= fontSize * 1.5;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -439,9 +479,19 @@ export class PdfService {
|
||||
font: t.font,
|
||||
color
|
||||
});
|
||||
// Sublinhado
|
||||
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.25;
|
||||
y -= fontSize * 1.5;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
@@ -512,12 +562,8 @@ export class PdfService {
|
||||
// Renderiza o parágrafo inteiro com recuo (não só a primeira linha)
|
||||
let x = margens.left;
|
||||
let parWidth = MAX_WIDTH;
|
||||
if (indent) {
|
||||
x += FONT_SIZE * 2;
|
||||
parWidth -= FONT_SIZE * 2;
|
||||
}
|
||||
|
||||
// Renderiza texto com formatação inline (negrito, itálico, ambos) e controle de linhas
|
||||
// Renderiza texto com formatação inline (negrito, itálico, sublinhado, ambos) e controle de linhas
|
||||
let yAfter = renderInlineFormattedParagraph(
|
||||
page,
|
||||
text,
|
||||
@@ -530,12 +576,13 @@ export class PdfService {
|
||||
FONT_SIZE,
|
||||
rgb(0, 0, 0),
|
||||
align,
|
||||
parWidth
|
||||
parWidth,
|
||||
indent
|
||||
);
|
||||
y = yAfter - FONT_SIZE * 0.5;
|
||||
|
||||
currentPar++;
|
||||
if (y < margens.bottom + FONT_SIZE * 1.25) break;
|
||||
if (y < margens.bottom + FONT_SIZE * 1.5) break;
|
||||
}
|
||||
pageIndex++;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user