import * as THREE from 'three/webgpu'; import type { MSDFFont } from './MSDFFont.cjs'; import { type MSDFTextAlign } from './MSDFTextLayout.cjs'; /** Horizontal origin used when positioning a self-laid-out text block. */ export type MSDFTextAnchorX = 'left' | 'center' | 'right' | number; /** Vertical origin used when positioning a self-laid-out text block. */ export type MSDFTextAnchorY = 'baseline' | 'top' | 'middle' | 'bottom'; /** One pre-broken line supplied by an external layout system. */ export interface MSDFTextLineInput { /** Text content for this line. */ text: string; /** Horizontal line origin in text units. */ x: number; /** Baseline position in text units, with positive Y pointing up. */ y: number; /** Optional target width fitted with bounded letter spacing. */ width?: number | undefined; } /** Construction options for {@link MSDFText}. */ export interface MSDFTextOptions { /** Parsed metrics for the atlas texture. */ font?: MSDFFont | null | undefined; /** MSDF atlas texture. The caller retains ownership and disposes it. */ map?: THREE.Texture | null | undefined; /** Content for self-layout mode. Newlines are supported. */ text?: string | undefined; /** Pre-broken lines that override self-layout while non-null. */ lines?: readonly MSDFTextLineInput[] | null | undefined; /** World units per em, or CSS pixels per em in screen-space mode. */ fontSize?: number | undefined; /** Additional spacing between adjacent glyphs. */ letterSpacing?: number | undefined; /** Line-box height, or zero to use the font's default. */ lineHeight?: number | undefined; /** Maximum line width used by self-layout. */ maxWidth?: number | undefined; /** Horizontal alignment within the maximum width. */ align?: MSDFTextAlign | undefined; /** Horizontal origin for the laid-out block. */ anchorX?: MSDFTextAnchorX | undefined; /** Vertical origin for the laid-out block. */ anchorY?: MSDFTextAnchorY | undefined; /** Initial text color. */ color?: THREE.ColorRepresentation | undefined; /** Initial text opacity. */ opacity?: number | undefined; /** Whether positions and sizes use CSS-pixel viewport coordinates. */ screenSpace?: boolean | undefined; /** screenSpace only: snap glyph origins to physical pixels (default true). Disable for smoothly animated text. */ pixelSnap?: boolean | undefined; } /** Read-only layout statistics from the most recent update. */ export interface MSDFTextLayoutInfo { /** Laid-out width in text units. */ width: number; /** Laid-out height in text units. */ height: number; /** Number of drawable glyph instances. */ glyphCount: number; } /** * A text block rendered from a pre-generated MSDF atlas — one instanced quad per glyph, * one draw call per text. Layout is synchronous and CPU-cheap (advances + kerning from the * font JSON); no runtime SDF generation, no async glyph pipeline. * * Two layout modes: * - `text`: the block wraps/aligns itself ({@link layoutMSDFText}), for standalone 3D text. * - `lines`: pre-broken lines with explicit per-line offsets (and optional target widths), * for mirroring layout decisions made elsewhere — e.g. the browser's own line boxes when * syncing DOM text to the canvas. * * With `screenSpace: true` the mesh ignores the camera and positions glyphs in CSS pixels: * set `setViewport(w, h)` and `setScreenOffset(x, y)` (top-left origin, y-down). * * @class MSDFText * @augments THREE.Mesh * @short Instanced MSDF text mesh: build-time atlas, minimal TSL, world or screen space. * @category Text * @tags WebGPU, WebGL * * @example * const font = parseMSDFFont( await ( await fetch( 'font.msdf.json' ) ).json() ); * const map = await ktx2Loader.loadAsync( 'font.msdf.ktx2' ); * const text = new MSDFText( { font, map, text: 'Hello\nMSDF', fontSize: 1, align: 'center' } ); * scene.add( text ); */ export declare class MSDFText extends THREE.Mesh { /** Runtime type guard for MSDF text meshes. */ readonly isMSDFText: boolean; private _font; private _text; private _lines; private _fontSize; private _letterSpacing; private _lineHeight; private _maxWidth; private _align; private _anchorX; private _anchorY; private _capacity; private _dirty; private _layoutInfo; private get _textMaterial(); /** * Creates one renderable text mesh and takes ownership of its generated geometry and material. * The supplied font metrics and atlas texture remain caller-owned. * * @param {Object} [options] * @param {import('./MSDFFont.js').MSDFFont|null} [options.font=null] - Parsed atlas metrics. * @param {THREE.Texture|null} [options.map=null] - The matching MSDF atlas texture. * @param {string} [options.text=''] - Content for self-layout mode (`\n` supported). * @param {Array<{text: string, x: number, y: number, width?: number}>|null} [options.lines=null] * Pre-broken lines: `x` = line start, `y` = baseline (y-up, negative below the origin), * optional `width` = target width to fit via tracking. Overrides `text` when set. * @param {number} [options.fontSize=1] - Units per em (CSS px per em in screen space). * @param {number} [options.letterSpacing=0] * @param {number} [options.lineHeight=0] - Line box height in units; 0 → font default. * @param {number} [options.maxWidth=Infinity] - Wrap width (text mode). * @param {('left'|'center'|'right')} [options.align='left'] - Alignment (text mode). * @param {('left'|'center'|'right'|number)} [options.anchorX='left'] - Origin along x (text mode). * @param {('baseline'|'top'|'middle'|'bottom')} [options.anchorY='baseline'] - Origin along y (text mode). * @param {THREE.Color|number|string} [options.color=0xffffff] * @param {number} [options.opacity=1] * @param {boolean} [options.screenSpace=false] * @param {boolean} [options.pixelSnap=true] - screenSpace only: snap glyph origins to * physical pixels for uniformly crisp stems at any DPR. Disable for smoothly animated text. */ constructor(options?: MSDFTextOptions); /** Parsed atlas metrics used for subsequent layouts. The caller retains ownership. */ get font(): MSDFFont | null; set font(value: MSDFFont | null); /** Text content for self-layout mode; assigning it leaves pre-broken-lines mode. */ get text(): string; set text(value: unknown); /** World units per em, or CSS pixels per em in screen-space mode. */ get fontSize(): number; set fontSize(value: number); /** Additional spacing between adjacent glyphs. */ get letterSpacing(): number; set letterSpacing(value: number); /** Line-box height, or zero to use the font's default line height. */ get lineHeight(): number; set lineHeight(value: number); /** Maximum line width used by self-layout before wrapping. */ get maxWidth(): number; set maxWidth(value: number); /** Horizontal alignment of lines within the self-layout width. */ get align(): MSDFTextAlign; set align(value: MSDFTextAlign); /** Horizontal origin of the self-laid-out block. */ get anchorX(): MSDFTextAnchorX; set anchorX(value: MSDFTextAnchorX); /** Vertical origin of the self-laid-out block. */ get anchorY(): MSDFTextAnchorY; set anchorY(value: MSDFTextAnchorY); /** Text color. Mutating the returned Three.js color updates rendering immediately. */ get color(): THREE.Color; set color(value: THREE.ColorRepresentation); /** Text opacity in the inclusive range normally used by Three.js materials. */ get opacity(): number; set opacity(value: number); /** Signed fake-weight bias; positive values make glyph strokes appear bolder. */ get weightBias(): number; set weightBias(value: number); /** * Binds the atlas texture (normalizing its sampler state for MSDF). * @param {THREE.Texture|null} map */ setMap(map: THREE.Texture | null): void; /** * Pre-broken lines mode — mirrors externally computed line boxes (e.g. DOM Range rects). * Passing null returns to self-layout of `.text`. * * @param {Array<{text: string, x: number, y: number, width?: number}>|null} lines */ setLines(lines: readonly MSDFTextLineInput[] | null): void; /** screenSpace: places the mesh origin in the viewport (CSS px, y-down top-left origin). */ setScreenOffset(x: number, y: number): void; /** screenSpace: the canvas CSS pixel size (share the same values across all texts). */ setViewport(width: number, height: number): void; /** Coalesces pending layout changes immediately before Three.js renders the mesh. */ onBeforeRender(): void; private _allocate; private _collectPlacements; /** * Relayouts the text and rewrites the instance buffers. Runs automatically before * rendering when a property changed; call directly to force a synchronous rebuild. */ update(): void; /** Read-only dimensions and glyph count from the most recent synchronous layout. */ get layoutInfo(): Readonly; /** Frees the owned GPU geometry and material. The caller-owned atlas texture is not disposed. */ dispose(): void; }