import type { TextElementLike } from './text-types.js'; /** * Lay a curved text element out and return the SVG that draws it. * * Why not a native ``, which is what svg/html-export used to emit: * `` hands vertical placement to the SVG renderer's own * interpretation of `dominant-baseline`, and that does NOT agree with * render-tag. Measured against render-tag's ink on an identical arc, native * `dominant-baseline="central"` sat high by * 28px Arial -14px (-0.500 em) * 28px Times New Roman -10px (-0.357 em) * 56px Arial -25px (-0.446 em) * — font-dependent, and not even proportional to the font size. So no constant * and no fontSize-derived formula can reconcile the two; it needs the font's * own metrics, which is exactly what render-tag already computed. An earlier * attempt to bolt a render-tag-derived offset onto a native textPath made * fidelity worse (curved-text-align svg 0.3443 -> 0.1141), because it mixed one * engine's bounds with another engine's baseline. Emitting render-tag's own * geometry took the same fixture to 1.0000. * * The mapping is one-to-one with `drawTextOnPathLayout`, which per glyph does * `translate(x, y); rotate(rotation); textBaseline='alphabetic'; * fillText(char, 0, baselineLocalY(tb, ascent, descent))`. SVG's default * dominant-baseline IS alphabetic, so every number below is render-tag's own and * nothing is left to the renderer to interpret. * * `groupAttrs` is the pin transform plus the paint every glyph shares; the * caller puts it on the wrapping . `bounds` is render-tag's LINE BOX * (verified: after pinning by -bounds.y the ink starts ~3px lower at 28px * Arial), and the canvas pins that same line box, so using it keeps the spokes * aligned with the canvas rather than with the ink. * * THROWS without a canvas backend, like `resolveCurveBoxHeight` — render-tag has * to measure glyphs. Callers that must survive plain Node guard the call and * report it with `warnCurveFallbackOnce`. */ export declare function curveTextToSvg(opts: { /** The text element. Its styled html is derived here, not by the caller. */ element: TextElementLike & { fill?: string; }; /** The element's already-normalized rich text (normalizeRichTextHtml). */ normalizedText: string; /** The arc, from getCurvePath. */ path: string; /** Overrides every glyph's colour (a gradient `url(#id)` reference). */ fillOverride?: string; /** Overrides the stroke paint (a gradient `url(#id)` reference). */ strokeOverride?: string; }): { markup: string; /** Pin transform + shared paint, for the wrapping . */ groupAttrs: Record; /** The same, serialized and escaped, for string-building callers. */ groupAttrsString: string; /** Curve bounds in the glyphs' own space — for a userSpaceOnUse gradient. */ bounds: { x: number; y: number; width: number; height: number; }; }; /** Report that a curve degraded to the legacy `` geometry. Shared so * both exporters say the same thing. Only reached when `canMeasureText()` * said yes and the layout failed anyway — i.e. a real problem, never the * supported no-canvas mode. Keyed on the message, not a single flag, so a * DIFFERENT failure later is not swallowed by the first. */ export declare function warnCurveFallbackOnce(err: unknown): void;