// Meranie šablón cenoviek v prehliadači (dočasný súbor): orezanie na viditeľný obsah a vrstvy z textov. window.measureBadges = async function () { await document.fonts.load('700 20px aptly'); const C = await (await fetch('/__svg/conv.json?' + Date.now())).json(); const NS = 'http://www.w3.org/2000/svg'; const out = []; for (const c of C) { // 1) viditeľný obsah pozadia (alfa kanál) → orezaný viewBox const [vx, vy, vw, vh] = c.vb; const S = 10; const bg = `${c.inner}`; const img = new Image(); img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(bg); await img.decode(); const cv = document.createElement('canvas'); cv.width = Math.ceil(vw * S); cv.height = Math.ceil(vh * S); const ctx = cv.getContext('2d'); ctx.drawImage(img, 0, 0); const a = ctx.getImageData(0, 0, cv.width, cv.height).data; let x0 = 1e9, y0 = 1e9, x1 = -1, y1 = -1; for (let y = 0; y < cv.height; y++) for (let x = 0; x < cv.width; x++) if (a[(y * cv.width + x) * 4 + 3] > 8) { if (x < x0) x0 = x; if (x > x1) x1 = x; if (y < y0) y0 = y; if (y > y1) y1 = y; } const pad = 0.3; const crop = [vx + x0 / S - pad, vy + y0 / S - pad, (x1 + 1 - x0) / S + 2 * pad, (y1 + 1 - y0) / S + 2 * pad].map((v) => Math.round(v * 100) / 100); // 2) texty z pôvodného SVG zmerané s písmom Aptly const host = document.createElement('div'); host.style.cssText = 'position:absolute;left:-5000px;top:0'; host.innerHTML = c.original.replace(/^[\s\S]*?( { const t = els.find((x) => x.getAttribute('transform') === info.transform && x.textContent === info.text); const tr = t.transform.baseVal.consolidate()?.matrix || { e: 0, f: 0 }; const n = t.getNumberOfChars(); const e0 = t.getExtentOfChar(0); return { ...info, start: tr.e + t.getStartPositionOfChar(0).x, end: tr.e + t.getEndPositionOfChar(n - 1).x, top: tr.f + e0.y, h: e0.height, aptly: /aptly/i.test(info.family) }; }); host.remove(); out.push({ ...c, crop, m }); } return out; };