plus d'espace pour les export typo variable, ui css

This commit is contained in:
2026-09-07 16:24:16 +02:00
parent ff8a1d808b
commit c6b3c19d03
4 changed files with 28 additions and 9 deletions
@@ -128,7 +128,12 @@ Comportement Drupal (`Drupal.behaviors.leshedSvgExport`) :
avant de demander le tracé du bon caractère.
- Assemble le SVG (fond transparent, remplissage noir uniquement — décision
volontaire, pas configurable) et déclenche le téléchargement (`Blob` +
`<a download>`).
`<a download>`). Une marge égale à 30 % de la plus grande taille de police
du titre (`ITALIC_OVERFLOW_MARGIN_RATIO`) est ajoutée tout autour du
canevas : les lettres italiques débordent de leur boîte d'avance nominale
(surtout en haut des hampes), et `getBoundingClientRect()` du titre ne
tient pas compte de ce débordement — sans cette marge, un cadrage au plus
juste coupe parfois ces lettres.
- Pour le PNG : rasterise le SVG assemblé via un `<canvas>` à ×4 la taille
affichée (`PNG_SCALE`), puis `canvas.toBlob('image/png')`.
@@ -72,12 +72,21 @@
* positioned glyph path. Nothing here recomputes layout — it only reads
* what the browser already laid out at the moment of the click.
*/
// Fraction of the largest font size on the title, added as padding around
// the whole canvas. Italic glyphs slant past their own nominal advance
// box (most visibly at the top of ascenders), and the title's own
// getBoundingClientRect() doesn't account for that overflow — a tightly
// fitted viewBox clips them. This margin is a generous, font-agnostic
// safety net rather than measuring each glyph's exact ink bounds.
const ITALIC_OVERFLOW_MARGIN_RATIO = 0.3;
async function buildSvg(titleEl, glyphFor, hb) {
const containerRect = titleEl.getBoundingClientRect();
const chars = Array.from(titleEl.querySelectorAll('.char'));
const seenWords = new Set();
const glyphNodes = [];
let maxFontSizePx = 0;
for (const charEl of chars) {
const rawText = charEl.textContent;
if (!rawText || !rawText.trim()) continue;
@@ -86,6 +95,7 @@
const computed = getComputedStyle(charEl);
const fontSizePx = parseFloat(computed.fontSize);
if (!fontSizePx) continue;
maxFontSizePx = Math.max(maxFontSizePx, fontSizePx);
const text = applyTextTransform(rawText, computed.textTransform, charEl, seenWords);
@@ -101,11 +111,12 @@
);
}
const width = containerRect.width;
const height = containerRect.height;
const margin = maxFontSizePx * ITALIC_OVERFLOW_MARGIN_RATIO;
const width = containerRect.width + margin * 2;
const height = containerRect.height + margin * 2;
const svg = [
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width.toFixed(2)} ${height.toFixed(2)}" width="${width.toFixed(2)}" height="${height.toFixed(2)}">`,
'<g fill="#000000">',
`<g fill="#000000" transform="translate(${margin.toFixed(2)}, ${margin.toFixed(2)})">`,
...glyphNodes,
'</g>',
'</svg>',