/** * Text Clip Renderer * * Implements `background-clip: text` — paints the element's background * (color + images) to an offscreen canvas and clips it to the text glyph * shapes with destination-in compositing, then composites the result back * onto the main canvas. * * Extracted from CanvasRenderer to keep paint orchestration separate from * this self-contained compositing algorithm. * * The offscreen and mask canvases are backed at device-pixel resolution * (bounds × scale) with their contexts scaled to CSS pixels, so the * composite back onto the main canvas maps 1:1 onto the backing store and * stays sharp at devicePixelRatio > 1. * * Matching browser paint order for clipped text: * - text shadows render *beneath* the clipped background (silhouettes in * the shadow colour), they are not part of the clip region; * - -webkit-text-stroke is part of the clip region (fill ∪ stroke band). */ import { ElementPaint } from '../stacking-context'; import { CSSParsedDeclaration } from '../../css'; import { Context } from '../../core/context'; export interface TextClipRendererDependencies { /** Main canvas context the clipped background is composited onto. */ ctx: CanvasRenderingContext2D; context: Context; /** Device-pixel ratio shared with the main renderer. */ scale: number; /** Font builder shared with the text renderer so both use identical fonts. */ createFontStyle: (styles: CSSParsedDeclaration) => string[]; } export declare class TextClipRenderer { private readonly ctx; private readonly context; private readonly scale; private readonly createFontStyle; constructor(deps: TextClipRendererDependencies); render(paint: ElementPaint): Promise; private createLayer; private createGlyphLayer; /** * Draw one text bound onto a glyph layer, splitting into per-glyph draws * when letter-spacing is in effect so the layout matches the main text * renderer. Vertical writing modes fall back to a single draw call. */ private drawGlyphs; /** * Paint the text-shadow silhouettes for every glyph, one canvas per * shadow, returned front-to-back (the last shadow sits deepest). Returns * null when the element has no text shadows. */ private renderShadowSilhouettes; }