UNPKG

modern-text

Version:

Measure and render text in a way that describes the DOM.

245 lines (237 loc) 7.62 kB
import { Fonts, SFNT } from 'modern-font'; import { NormalizedStyle, NormalizedFill, NormalizedOutline, FullStyle, TextObject, EventEmitter, PropertyDeclaration, ReactiveObject, NormalizedText } from 'modern-idoc'; import { BoundingBox, Path2D, Vector2, VectorLike, Path2DSet } from 'modern-path2d'; declare class Fragment { content: string; style: NormalizedStyle; parent: Paragraph; inlineBox: BoundingBox; fill?: NormalizedFill; outline?: NormalizedOutline; characters: Character[]; computedStyle: FullStyle; get computedFill(): NormalizedFill | undefined; get computedOutline(): NormalizedOutline | undefined; get computedContent(): string; constructor(content: string, style: NormalizedStyle | undefined, parent: Paragraph); updateComputedStyle(): this; initCharacters(): this; } declare class Character { content: string; index: number; parent: Fragment; path: Path2D; lineBox: BoundingBox; inlineBox: BoundingBox; glyphBox?: BoundingBox; advanceWidth: number; advanceHeight: number; underlinePosition: number; underlineThickness: number; strikeoutPosition: number; strikeoutSize: number; ascender: number; descender: number; typoAscender: number; typoDescender: number; typoLineGap: number; winAscent: number; winDescent: number; xHeight: number; capHeight: number; baseline: number; centerDiviation: number; fontStyle?: 'bold' | 'italic'; get compatibleGlyphBox(): BoundingBox; get center(): Vector2; get computedFill(): NormalizedFill | undefined; get computedOutline(): NormalizedOutline | undefined; get computedStyle(): FullStyle; get isVertical(): boolean; get fontSize(): number; get fontHeight(): number; constructor(content: string, index: number, parent: Fragment); protected _getFontSFNT(fonts?: Fonts): SFNT | undefined; updateGlyph(sfnt?: SFNT | undefined): this; update(fonts?: Fonts): this; protected _italic(path: Path2D, startPoint?: VectorLike): void; getGlyphMinMax(min?: Vector2, max?: Vector2, withStyle?: boolean): { min: Vector2; max: Vector2; } | undefined; getGlyphBoundingBox(withStyle?: boolean): BoundingBox | undefined; drawTo(ctx: CanvasRenderingContext2D, config?: NormalizedStyle): void; } declare class Paragraph { style: NormalizedStyle; parent: Text$1; lineBox: BoundingBox; fragments: Fragment[]; fill?: NormalizedFill; outline?: NormalizedOutline; computedStyle: FullStyle; get computedFill(): NormalizedFill | undefined; get computedOutline(): NormalizedOutline | undefined; constructor(style: NormalizedStyle, parent: Text$1); updateComputedStyle(): this; addFragment(content: string, style?: NormalizedStyle): Fragment; } interface TextPlugin { name: string; pathSet?: Path2DSet; getBoundingBox?: (text: Text$1) => BoundingBox | undefined; update?: (text: Text$1) => void; updateOrder?: number; render?: (ctx: CanvasRenderingContext2D, text: Text$1) => void; renderOrder?: number; load?: (text: Text$1) => Promise<void>; } interface TextOptions extends TextObject { debug?: boolean; measureDom?: HTMLElement; fonts?: Fonts; plugins?: TextPlugin[]; } interface MeasuredParagraph { paragraphIndex: number; left: number; top: number; width: number; height: number; } interface MeasuredFragment { paragraphIndex: number; fragmentIndex: number; left: number; top: number; width: number; height: number; } interface MeasuredCharacter { paragraphIndex: number; fragmentIndex: number; characterIndex: number; newParagraphIndex: number; content: string; left: number; top: number; width: number; height: number; textHeight: number; textWidth: number; } interface measureDOMResult { paragraphs: Paragraph[]; boundingBox: BoundingBox; } declare class Measurer { static notZeroStyles: Set<string>; static pxStyles: Set<string>; protected _toDomStyle(style: Record<string, any>): Record<string, any>; /** * <section style="..."> * <ul> * <li style="..."> * <span style="...">...</span> * <span>...</span> * </li> * </ul> * </section> */ createDom(paragraphs: Paragraph[], rootStyle: FullStyle): HTMLElement; measureDOMText(text: Text): { content: string; top: number; left: number; width: number; height: number; }[]; measureDOM(dom: HTMLElement): { paragraphs: MeasuredParagraph[]; fragments: MeasuredFragment[]; characters: MeasuredCharacter[]; }; measureParagraphDOM(paragraphs: Paragraph[], dom: HTMLElement): measureDOMResult; measure(paragraphs: Paragraph[], rootStyle: FullStyle, dom?: HTMLElement): measureDOMResult; } interface TextRenderOptions { view: HTMLCanvasElement; pixelRatio?: number; onContext?: (context: CanvasRenderingContext2D) => void; } interface MeasureResult { paragraphs: Paragraph[]; lineBox: BoundingBox; rawGlyphBox: BoundingBox; glyphBox: BoundingBox; pathBox: BoundingBox; boundingBox: BoundingBox; } declare const textDefaultStyle: FullStyle; interface TextEventMap { updateProperty: [ key: string, newValue: unknown, oldValue: unknown, declaration: PropertyDeclaration ]; update: [{ text: Text$1; }]; measure: [{ text: Text$1; result: MeasureResult; }]; render: [{ text: Text$1; view: HTMLCanvasElement; pixelRatio: number; }]; } declare class Text$1 extends EventEmitter<TextEventMap> implements ReactiveObject { debug: boolean; content: NormalizedText['content']; style?: NormalizedText['style']; effects?: NormalizedText['effects']; fill?: NormalizedText['fill']; outline?: NormalizedText['outline']; measureDom?: HTMLElement; fonts?: Fonts; needsUpdate: boolean; computedStyle: FullStyle; paragraphs: Paragraph[]; lineBox: BoundingBox; rawGlyphBox: BoundingBox; glyphBox: BoundingBox; pathBox: BoundingBox; boundingBox: BoundingBox; measurer: Measurer; plugins: Map<string, TextPlugin>; pathSets: Path2DSet[]; get fontSize(): number; get isVertical(): boolean; get characters(): Character[]; constructor(options?: TextOptions); set(options?: TextOptions): void; onUpdateProperty(key: string, newValue: unknown, oldValue: unknown, declaration: PropertyDeclaration): void; use(plugin: TextPlugin): this; forEachCharacter(handle: (character: Character, ctx: { paragraphIndex: number; fragmentIndex: number; characterIndex: number; }) => void): this; load(): Promise<void>; updateParagraphs(): this; createDom(): HTMLElement; measure(dom?: HTMLElement | undefined): MeasureResult; getGlyphBox(): BoundingBox; updatePathBox(): this; updateBoundingBox(): this; requestUpdate(): this; update(dom?: HTMLElement | undefined): this; render(options: TextRenderOptions): void; toString(): string; } export { Character as C, Fragment as F, Paragraph as P, Text$1 as T, Measurer as g, textDefaultStyle as t }; export type { MeasureResult as M, TextPlugin as a, TextOptions as b, TextRenderOptions as c, MeasuredParagraph as d, MeasuredFragment as e, MeasuredCharacter as f, TextEventMap as h, measureDOMResult as m };