Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25ffb3727b | ||
|
|
d42a09ab81 |
@@ -25,20 +25,39 @@ const SIG_CANVAS_H = 160;
|
|||||||
function buildSignatureElement(svgString, x, y, scale) {
|
function buildSignatureElement(svgString, x, y, scale) {
|
||||||
if (!svgString || typeof svgString !== 'string') return '';
|
if (!svgString || typeof svgString !== 'string') return '';
|
||||||
|
|
||||||
// Nur <path>-Elemente extrahieren (unsere Signatur-SVGs enthalten ausschließlich Paths)
|
// viewBox der Signatur lesen, damit beliebige Quell-SVGs (z.B. Illustrator-
|
||||||
const pathRegex = /<path\b([^/]*)\/>/gi;
|
// Export mit eigener viewBox) korrekt normiert werden statt fix auf den
|
||||||
|
// 600×160-Zeichen-Canvas. Ohne viewBox: Fallback auf den Canvas (Alt-Signaturen).
|
||||||
|
let minx = 0;
|
||||||
|
let miny = 0;
|
||||||
|
let vh = SIG_CANVAS_H;
|
||||||
|
const vbM = svgString.match(/viewBox\s*=\s*"([^"]+)"/i);
|
||||||
|
if (vbM) {
|
||||||
|
const p = vbM[1].trim().split(/[\s,]+/).map(Number);
|
||||||
|
if (p.length === 4 && p[2] > 0 && p[3] > 0) { minx = p[0]; miny = p[1]; vh = p[3]; }
|
||||||
|
}
|
||||||
|
// Skala auf die Eigen-Höhe beziehen: Canvas-Signaturen (vh=160) unverändert,
|
||||||
|
// hochgeladene SVGs werden auf dieselbe Zielhöhe eingepasst.
|
||||||
|
const s = scale * (SIG_CANVAS_H / vh);
|
||||||
|
|
||||||
|
// Alle Zeichen-Elemente extrahieren und IMMER als Single-Stroke ausgeben:
|
||||||
|
// fill:none + schwarzer Stroke inline; Klasse/Style/fill/stroke/width/height
|
||||||
|
// entfernen. So gehen per <style>-Klasse (z.B. .cls-1) gesetzte Linien nicht
|
||||||
|
// verloren (sonst fällt der Pfad auf fill:black zurück und rendert gefüllt).
|
||||||
|
const elemRe = /<(path|polyline|line|circle|ellipse|polygon)\b([^>]*?)\/?>/gi;
|
||||||
const elements = [];
|
const elements = [];
|
||||||
let m;
|
let m;
|
||||||
while ((m = pathRegex.exec(svgString)) !== null) {
|
while ((m = elemRe.exec(svgString)) !== null) {
|
||||||
// Stroke-Farbe auf Druckfarbe setzen, stroke-width relativ zur Skalierung anpassen
|
const attrs = m[2].replace(/\s(?:class|style|fill|stroke|stroke-width|width|height)\s*=\s*"[^"]*"/gi, '');
|
||||||
const attrs = m[1]
|
elements.push(`<${m[1]}${attrs} fill="none" stroke="#000000"/>`);
|
||||||
.replace(/stroke="[^"]*"/i, 'stroke="#000000"')
|
|
||||||
.replace(/stroke-width="[^"]*"/i, `stroke-width="${(2.5 / scale).toFixed(2)}"`);
|
|
||||||
elements.push(`<path${attrs}/>`);
|
|
||||||
}
|
}
|
||||||
if (!elements.length) return '';
|
if (!elements.length) return '';
|
||||||
|
|
||||||
return `<g transform="translate(${x.toFixed(1)}, ${y.toFixed(1)}) scale(${scale.toFixed(4)})">
|
// stroke-width auf der Gruppe (in Quell-Einheiten), damit nach scale ~2.5px herauskommt.
|
||||||
|
const sw = (2.5 / s).toFixed(2);
|
||||||
|
const tx = (x - minx * s).toFixed(1);
|
||||||
|
const ty = (y - miny * s).toFixed(1);
|
||||||
|
return `<g transform="translate(${tx}, ${ty}) scale(${s.toFixed(4)})" stroke-width="${sw}" stroke-linecap="round" stroke-linejoin="round">
|
||||||
${elements.join('\n ')}
|
${elements.join('\n ')}
|
||||||
</g>`;
|
</g>`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,29 +141,49 @@ async function scriptalizeBatch(texts, font = "tilda", errFrequency = 10) {
|
|||||||
config.scriptalizer.fontMap[font.toLowerCase()] ||
|
config.scriptalizer.fontMap[font.toLowerCase()] ||
|
||||||
config.scriptalizer.fontMap.tilda;
|
config.scriptalizer.fontMap.tilda;
|
||||||
const separator = config.scriptalizer.separator;
|
const separator = config.scriptalizer.separator;
|
||||||
const BATCH_SIZE = 18; // 18 Texte pro Scriptalizer API Call (Scriptalizer-API-Limit: 32000 Zeichen pro Call → ca. 1700 Zeichen pro Brief sicher)
|
const BATCH_SIZE = 18; // Zusätzlicher Deckel: max. 18 Texte pro Call (unabhängig von der Länge).
|
||||||
|
// Primäre Grenze ist die ZEICHENLÄNGE: die Scriptalizer-API begrenzt den
|
||||||
|
// InputText auf 32000 Zeichen pro Call ("Input length limit 32000 exceeded").
|
||||||
|
// Fixe 18er-Batches sprengen das bei langen (mehrseitigen) Texten – daher nach
|
||||||
|
// kumulativer Länge batchen, mit Sicherheitsabstand.
|
||||||
|
const MAX_BATCH_CHARS = 28000;
|
||||||
|
const sepLen = separator.length;
|
||||||
|
|
||||||
|
// Batches nach Länge (und max. Anzahl) bilden.
|
||||||
|
const batches = [];
|
||||||
|
{
|
||||||
|
let cur = [];
|
||||||
|
let curLen = 0;
|
||||||
|
for (const t of texts) {
|
||||||
|
const tLen = String(t || "").length;
|
||||||
|
const projected = curLen + (cur.length ? sepLen : 0) + tLen;
|
||||||
|
if (cur.length && (projected > MAX_BATCH_CHARS || cur.length >= BATCH_SIZE)) {
|
||||||
|
batches.push(cur);
|
||||||
|
cur = [];
|
||||||
|
curLen = 0;
|
||||||
|
}
|
||||||
|
cur.push(t);
|
||||||
|
curLen += (cur.length > 1 ? sepLen : 0) + tLen;
|
||||||
|
}
|
||||||
|
if (cur.length) batches.push(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
const totalBatches = batches.length;
|
||||||
console.log(
|
console.log(
|
||||||
`[Scriptalizer] Processing ${texts.length} texts in batches of ${BATCH_SIZE}`
|
`[Scriptalizer] Processing ${texts.length} texts in ${totalBatches} batch(es) (max ${BATCH_SIZE} texts / ${MAX_BATCH_CHARS} chars each)`
|
||||||
);
|
);
|
||||||
|
|
||||||
const allScriptalized = [];
|
const allScriptalized = [];
|
||||||
|
|
||||||
// Teile in 25er Batches auf
|
for (let b = 0; b < batches.length; b += 1) {
|
||||||
for (let i = 0; i < texts.length; i += BATCH_SIZE) {
|
const batch = batches[b];
|
||||||
const batch = texts.slice(i, i + BATCH_SIZE);
|
const batchNumber = b + 1;
|
||||||
const batchNumber = Math.floor(i / BATCH_SIZE) + 1;
|
const combinedText = batch.join(separator);
|
||||||
const totalBatches = Math.ceil(texts.length / BATCH_SIZE);
|
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`[Scriptalizer] Processing batch ${batchNumber}/${totalBatches} (${
|
`[Scriptalizer] Processing batch ${batchNumber}/${totalBatches} (${batch.length} texts, ${combinedText.length} chars)`
|
||||||
batch.length
|
|
||||||
} texts, indices ${i}-${i + batch.length - 1})`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Kombiniere Texte mit Separator
|
|
||||||
const combinedText = batch.join(separator);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await callScriptalizer(
|
const result = await callScriptalizer(
|
||||||
combinedText,
|
combinedText,
|
||||||
|
|||||||
Reference in New Issue
Block a user