tenta fix pdfservice.js
This commit is contained in:
1 parent
19f0187227
commit
db0c011b8b
1 file changed
+187
@@ -348,6 +348,193 @@ export class PdfService {
|
||||
.replace(/>/g, '>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderiza um parágrafo com formatação inline (negrito, itálico)
|
||||
* @returns A posição Y após renderizar ou null se não coube na página
|
||||
*/
|
||||
function renderInlineFormattedParagraph(
|
||||
page: any,
|
||||
text: string,
|
||||
x: number,
|
||||
startY: number,
|
||||
normalFont: any,
|
||||
boldFont: any,
|
||||
italicFont: any,
|
||||
boldItalicFont: any,
|
||||
fontSize: number,
|
||||
color: any,
|
||||
align: 'left' | 'center' | 'right' | 'justify',
|
||||
maxWidth: number,
|
||||
debug: boolean = false,
|
||||
marginTop: number,
|
||||
marginBottom: number,
|
||||
pageHeight: number
|
||||
): number | null {
|
||||
const lineHeight = fontSize * 1.5;
|
||||
let y = startY;
|
||||
let currentX = x;
|
||||
let words: Array<{text: string, font: any, width: number}> = [];
|
||||
let currentLine: Array<{text: string, font: any, width: number}> = [];
|
||||
let currentLineWidth = 0;
|
||||
let textParts = [];
|
||||
|
||||
// Detectar formatação inline
|
||||
let remainingText = text;
|
||||
let currentFont = normalFont;
|
||||
let boldActive = false;
|
||||
let italicActive = false;
|
||||
|
||||
// Processa texto com formatação
|
||||
while (remainingText.length > 0) {
|
||||
if (remainingText.startsWith('<b>')) {
|
||||
// Começa negrito
|
||||
boldActive = true;
|
||||
remainingText = remainingText.substring(3);
|
||||
currentFont = italicActive ? boldItalicFont : boldFont;
|
||||
} else if (remainingText.startsWith('</b>')) {
|
||||
// Termina negrito
|
||||
boldActive = false;
|
||||
remainingText = remainingText.substring(4);
|
||||
currentFont = italicActive ? italicFont : normalFont;
|
||||
} else if (remainingText.startsWith('<i>')) {
|
||||
// Começa itálico
|
||||
italicActive = true;
|
||||
remainingText = remainingText.substring(3);
|
||||
currentFont = boldActive ? boldItalicFont : italicFont;
|
||||
} else if (remainingText.startsWith('</i>')) {
|
||||
// Termina itálico
|
||||
italicActive = false;
|
||||
remainingText = remainingText.substring(4);
|
||||
currentFont = boldActive ? boldFont : normalFont;
|
||||
} else {
|
||||
// Texto normal - procura pela próxima tag de formatação
|
||||
let nextTag = remainingText.search(/<\/?[bi]>/);
|
||||
if (nextTag === -1) {
|
||||
// Não há mais tags, adiciona todo o texto restante
|
||||
textParts.push({
|
||||
text: remainingText,
|
||||
font: currentFont
|
||||
});
|
||||
remainingText = '';
|
||||
} else {
|
||||
// Adiciona texto até a próxima tag
|
||||
textParts.push({
|
||||
text: remainingText.substring(0, nextTag),
|
||||
font: currentFont
|
||||
});
|
||||
remainingText = remainingText.substring(nextTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Processa partes de texto em palavras para quebra de linha
|
||||
for (const part of textParts) {
|
||||
const partWords = part.text.split(/\s+/);
|
||||
|
||||
for (let i = 0; i < partWords.length; i++) {
|
||||
if (partWords[i].length === 0) continue;
|
||||
|
||||
const wordText = i < partWords.length - 1 ? partWords[i] + ' ' : partWords[i];
|
||||
const wordWidth = part.font.widthOfTextAtSize(wordText, fontSize);
|
||||
|
||||
words.push({
|
||||
text: wordText,
|
||||
font: part.font,
|
||||
width: wordWidth
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Processa palavras em linhas
|
||||
for (let i = 0; i < words.length; i++) {
|
||||
const word = words[i];
|
||||
|
||||
if (currentLineWidth + word.width <= maxWidth) {
|
||||
// A palavra cabe na linha atual
|
||||
currentLine.push(word);
|
||||
currentLineWidth += word.width;
|
||||
} else {
|
||||
// A palavra não cabe, desenha a linha atual e começa nova linha
|
||||
// Primeiro verifica se há espaço vertical suficiente
|
||||
if (y - lineHeight < marginBottom) {
|
||||
return null; // Não há espaço suficiente na página
|
||||
}
|
||||
|
||||
// Desenha a linha com o alinhamento apropriado
|
||||
y = drawFormattedLine(page, currentLine, x, y, maxWidth, align, fontSize, color);
|
||||
|
||||
// Começa uma nova linha com a palavra atual
|
||||
currentLine = [word];
|
||||
currentLineWidth = word.width;
|
||||
}
|
||||
}
|
||||
|
||||
// Desenha a última linha se houver palavras restantes
|
||||
if (currentLine.length > 0) {
|
||||
if (y - lineHeight < marginBottom) {
|
||||
return null; // Não há espaço suficiente na página
|
||||
}
|
||||
|
||||
y = drawFormattedLine(page, currentLine, x, y, maxWidth, align, fontSize, color);
|
||||
}
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Desenha uma linha formatada com alinhamento específico
|
||||
*/
|
||||
function drawFormattedLine(
|
||||
page: any,
|
||||
line: Array<{text: string, font: any, width: number}>,
|
||||
x: number,
|
||||
y: number,
|
||||
maxWidth: number,
|
||||
align: 'left' | 'center' | 'right' | 'justify',
|
||||
fontSize: number,
|
||||
color: any
|
||||
): number {
|
||||
const lineHeight = fontSize * 1.5;
|
||||
let currentX = x;
|
||||
let totalWidth = line.reduce((sum, word) => sum + word.width, 0);
|
||||
|
||||
// Calcula o espaço adicional entre palavras para justificação
|
||||
let extraSpacing = 0;
|
||||
if (align === 'justify' && line.length > 1 && totalWidth < maxWidth * 0.8) {
|
||||
extraSpacing = (maxWidth - totalWidth) / (line.length - 1);
|
||||
}
|
||||
|
||||
// Ajusta a posição x inicial baseada no alinhamento
|
||||
if (align === 'center') {
|
||||
currentX = x + (maxWidth - totalWidth) / 2;
|
||||
} else if (align === 'right') {
|
||||
currentX = x + maxWidth - totalWidth;
|
||||
}
|
||||
|
||||
// Desenha cada palavra
|
||||
for (let i = 0; i < line.length; i++) {
|
||||
const word = line[i];
|
||||
page.drawText(word.text, {
|
||||
x: currentX,
|
||||
y: y,
|
||||
font: word.font,
|
||||
size: fontSize,
|
||||
color: color
|
||||
});
|
||||
|
||||
// Avança X para a próxima palavra
|
||||
currentX += word.width;
|
||||
|
||||
// Adiciona espaço extra para justificação, exceto na última palavra
|
||||
if (align === 'justify' && i < line.length - 1) {
|
||||
currentX += extraSpacing;
|
||||
}
|
||||
}
|
||||
|
||||
// Retorna a nova posição Y após desenhar a linha
|
||||
return y - lineHeight;
|
||||
}
|
||||
|
||||
// Processe o texto com as novas funções melhoradas
|
||||
const textoLimpo = stripUnsupportedTags(
|
||||
this.processarTemplate(conteudo, escritorio)
|
||||
|
||||
Reference in new issue
Block a user