import { Line, LineSegment, Run } from '../../../../contracts/src/index.js'; type UnderlinePaintRun = { underline?: { style?: string; color?: string; } | null; fontSize?: number; color?: string; }; type UnderlineSource = Run | UnderlinePaintRun; export declare const underlineStyleForRun: (run: UnderlineSource) => string | undefined; export declare const canPaintUnderlineAsBorder: (run: UnderlineSource) => boolean; /** * Whether the line-level underline overlay may own this run's underline (SD-3330). * * Scoped to the styles a single CSS `border-top` reproduces faithfully: `single`, `double`, * `dotted`, `dashed`. Everything else stays on its existing path on purpose, so the overlay * never silently flattens a distinct style into solid inside a "continuous" line: * - `none` paints nothing (rejected by canPaintUnderlineAsBorder); * - `wave`, `thick`, and the OOXML heavy/compound spellings (`dotDash`, `dashLongHeavy`, ...) a * border-top cannot draw - they keep their current (degraded) per-run rendering. * * `words` is NOT solved end-to-end here. canPaintUnderlineAsBorder rejects a literal `words`, but * the v1 adapter's normalizeUnderlineStyle collapses OOXML `words` to `single` BEFORE paint, so a * `words` underline reaches this layer as `single` and gets overlaid - it does not reproduce Word's * "underline the words, not the tab whitespace". Fixing that needs an importer/adapter change and is * out of scope for the seam fix; the guard here is only defensive for a producer that passes `words` raw. * * Color is a separate axis: this gate is style-only, and underlineBorderForRun does not resolve * theme/`auto` underline colors (it uses the literal color string, as the prior border path did), * so theme-color fidelity is out of scope here too. * * Mixed lines stay per-run: a single-underlined tab can be overlaid while an adjacent wavy run * keeps its native text-decoration. */ export declare const canPaintUnderlineOverlay: (run: UnderlineSource) => boolean; export declare const underlineBorderForRun: (run: UnderlineSource) => string | undefined; export declare const renderInlineTabRun: (run: Extract, line: Line, doc: Document, layoutEpoch: number, styleId?: string, paintUnderline?: boolean) => HTMLElement; export declare const renderPositionedTabRun: (run: Extract, line: Line, doc: Document, layoutEpoch: number, tabStartX: number, indentOffset: number, immediateNextSegment?: LineSegment, styleId?: string, paintUnderline?: boolean) => { element: HTMLElement; tabEndX: number; actualTabWidth: number; }; /** * Distance, in pixels from the top of the line box, at which a tab's underline * (border-bottom) should be drawn so it lines up with the `text-decoration` * underline of adjacent text runs. * * The line box places the baseline at `half-leading + ascent` from its top * (the remaining `half-leading + descent` sits below). `text-decoration` * underlines render slightly below the baseline, so we add a small gap that * scales with font size (capped by the descent). This is geometry derived from * the resolved line metrics. The painter never measures the DOM (SD-2957). */ export declare const underlineOffsetFromLineTop: (line: Line) => number; export {}; //# sourceMappingURL=tab-run.d.ts.map