feat: increase font scaling and add inline product name rendering for improved thermal printer legibility
This commit is contained in:
parent
71b7461f41
commit
e667ef3bac
@ -41,7 +41,7 @@ export class HtmlToImageConverter {
|
||||
clone.style.backgroundColor = 'white';
|
||||
clone.style.color = 'black';
|
||||
clone.style.fontFamily = 'monospace, Courier, "Courier New"';
|
||||
clone.style.fontSize = '12px';
|
||||
clone.style.fontSize = '15px';
|
||||
clone.style.lineHeight = '1.4';
|
||||
|
||||
// Create a temporary container to measure height
|
||||
@ -113,15 +113,15 @@ export class HtmlToImageConverter {
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.textBaseline = 'top';
|
||||
ctx.font = '12px monospace';
|
||||
ctx.font = '16px monospace';
|
||||
|
||||
const padding = 10;
|
||||
const lineHeight = 16;
|
||||
const maxWidth = width - (padding * 2);
|
||||
let y = padding;
|
||||
|
||||
// Helper function to wrap text
|
||||
const wrapText = (text, maxWidth) => {
|
||||
const wrapText = (text, maxWidth, fontSize) => {
|
||||
ctx.font = `${ctx.font.includes('bold') ? 'bold' : 'normal'} ${fontSize}px monospace`;
|
||||
const words = text.split(' ');
|
||||
const lines = [];
|
||||
let currentLine = '';
|
||||
@ -146,11 +146,12 @@ export class HtmlToImageConverter {
|
||||
};
|
||||
|
||||
// Helper to draw text with alignment
|
||||
const drawText = (text, align = 'left', bold = false) => {
|
||||
const drawText = (text, align = 'left', bold = false, fontSize = 16) => {
|
||||
if (!text || !text.trim()) return;
|
||||
|
||||
ctx.font = `${bold ? 'bold' : 'normal'} 12px monospace`;
|
||||
const lines = wrapText(text, maxWidth);
|
||||
ctx.font = `${bold ? 'bold' : 'normal'} ${fontSize}px monospace`;
|
||||
const localLineHeight = Math.round(fontSize * 1.3);
|
||||
const lines = wrapText(text, maxWidth, fontSize);
|
||||
|
||||
for (const line of lines) {
|
||||
let x = padding;
|
||||
@ -163,7 +164,7 @@ export class HtmlToImageConverter {
|
||||
}
|
||||
|
||||
ctx.fillText(line, x, y);
|
||||
y += lineHeight;
|
||||
y += localLineHeight;
|
||||
}
|
||||
};
|
||||
|
||||
@ -175,7 +176,7 @@ export class HtmlToImageConverter {
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.stroke();
|
||||
y += lineHeight;
|
||||
y += 8;
|
||||
};
|
||||
|
||||
// Extract and render content recursively
|
||||
@ -195,9 +196,20 @@ export class HtmlToImageConverter {
|
||||
const fontWeight = style.fontWeight;
|
||||
const isBold = fontWeight === 'bold' || parseInt(fontWeight) >= 600;
|
||||
|
||||
// Get font size and scale it up for high legibility on thermal printer
|
||||
let fontSize = 16;
|
||||
const fontSizeStr = style.fontSize;
|
||||
if (fontSizeStr) {
|
||||
const parsed = parseFloat(fontSizeStr);
|
||||
if (!isNaN(parsed) && parsed > 0) {
|
||||
fontSize = Math.max(12, Math.round(parsed * 1.35));
|
||||
}
|
||||
}
|
||||
const localLineHeight = Math.round(fontSize * 1.3);
|
||||
|
||||
// Handle special elements
|
||||
if (tagName === 'BR') {
|
||||
y += lineHeight;
|
||||
y += localLineHeight;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -206,6 +218,22 @@ export class HtmlToImageConverter {
|
||||
return;
|
||||
}
|
||||
|
||||
// Special optimization: If the element is a product-name, print quantity and name inline
|
||||
if (el.classList && el.classList.contains('product-name')) {
|
||||
const qtyEl = el.querySelector('.qty') || el.querySelector('span:first-child');
|
||||
const nameEl = el.querySelector('.text-wrap') || el.querySelector('span:nth-child(2)') || el.querySelector('span:last-child');
|
||||
const qtyText = qtyEl ? qtyEl.textContent.trim() : '';
|
||||
let nameText = nameEl ? nameEl.textContent.trim() : '';
|
||||
if (!nameText && !qtyEl && el.textContent) {
|
||||
nameText = el.textContent.trim();
|
||||
}
|
||||
if (qtyText || nameText) {
|
||||
const combined = qtyText ? `${qtyText} ${nameText}` : nameText;
|
||||
drawText(combined, textAlign, isBold, fontSize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if element has only text content (no child elements)
|
||||
const hasOnlyText = Array.from(el.childNodes).every(
|
||||
node => node.nodeType === Node.TEXT_NODE
|
||||
@ -214,7 +242,7 @@ export class HtmlToImageConverter {
|
||||
if (hasOnlyText) {
|
||||
const text = el.textContent.trim();
|
||||
if (text) {
|
||||
drawText(text, textAlign, isBold);
|
||||
drawText(text, textAlign, isBold, fontSize);
|
||||
}
|
||||
} else {
|
||||
// Process children
|
||||
@ -222,7 +250,7 @@ export class HtmlToImageConverter {
|
||||
if (child.nodeType === Node.TEXT_NODE) {
|
||||
const text = child.textContent.trim();
|
||||
if (text) {
|
||||
drawText(text, textAlign, isBold);
|
||||
drawText(text, textAlign, isBold, fontSize);
|
||||
}
|
||||
} else if (child.nodeType === Node.ELEMENT_NODE) {
|
||||
processElement(child);
|
||||
@ -232,7 +260,7 @@ export class HtmlToImageConverter {
|
||||
|
||||
// Add spacing after block elements
|
||||
if (display === 'block' || tagName === 'DIV' || tagName === 'P' || tagName === 'TABLE') {
|
||||
y += lineHeight / 2;
|
||||
y += localLineHeight / 2;
|
||||
}
|
||||
};
|
||||
|
||||
@ -247,7 +275,7 @@ export class HtmlToImageConverter {
|
||||
const lines = allText.split('\n').filter(l => l.trim());
|
||||
y = padding;
|
||||
for (const line of lines) {
|
||||
drawText(line.trim());
|
||||
drawText(line.trim(), 'left', false, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user