import { NormalizedStyle, NormalizedFill, NormalizedOutline, FullStyle, TextObject, ReactivableEvents, Reactivable, NormalizedText } from 'modern-idoc';
import { BoundingBox, Path2D, Vector2, VectorLike, Path2DSet, Path2DDrawStyle, Path2DStyle } from 'modern-path2d';
import { Fonts, SFNT } from 'modern-font';

declare class Fragment {
    content: string;
    style: NormalizedStyle;
    index: number;
    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, index: number, parent: Paragraph);
    updateComputedStyle(): this;
    initCharacters(): this;
}

declare class Character {
    content: string;
    index: number;
    parent: Fragment;
    path: Path2D<Character>;
    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;
}

interface Plugin {
    name: string;
    pathSet?: Path2DSet;
    getBoundingBox?: (text: Text$1) => BoundingBox | undefined;
    update?: (text: Text$1) => void;
    updateOrder?: number;
    render?: (renderer: Canvas2DRenderer) => void;
    renderOrder?: number;
    load?: (text: Text$1) => Promise<void>;
    context?: Record<string, any>;
}
interface Options extends TextObject {
    debug?: boolean;
    measureDom?: HTMLElement;
    fonts?: Fonts;
    plugins?: Plugin[];
}

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 RenderOptions {
    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 TextEvents extends ReactivableEvents {
    update: [ctx: {
        text: Text$1;
    }];
    measure: [ctx: {
        text: Text$1;
        result: MeasureResult;
    }];
    render: [ctx: {
        text: Text$1;
        view: HTMLCanvasElement;
        pixelRatio: number;
    }];
}
interface Text$1 {
    on: <K extends keyof TextEvents & string>(event: K, listener: (...args: TextEvents[K]) => void) => this;
    once: <K extends keyof TextEvents & string>(event: K, listener: (...args: TextEvents[K]) => void) => this;
    off: <K extends keyof TextEvents & string>(event: K, listener: (...args: TextEvents[K]) => void) => this;
    emit: <K extends keyof TextEvents & string>(event: K, ...args: TextEvents[K]) => this;
}
declare class Text$1 extends Reactivable {
    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;
    computedEffects: NormalizedStyle[];
    paragraphs: Paragraph[];
    inlineBox: BoundingBox;
    lineBox: BoundingBox;
    rawGlyphBox: BoundingBox;
    glyphBox: BoundingBox;
    pathBox: BoundingBox;
    boundingBox: BoundingBox;
    measurer: Measurer;
    plugins: Map<string, Plugin>;
    pathSets: Path2DSet[];
    get fontSize(): number;
    get isVertical(): boolean;
    get characters(): Character[];
    constructor(options?: Options);
    set(options?: Options): void;
    use(plugin: Plugin): this;
    forEachCharacter(handle: (character: Character, ctx: {
        paragraphIndex: number;
        fragmentIndex: number;
        characterIndex: number;
    }) => void): this;
    load(): Promise<void>;
    protected _update(): this;
    createDom(): HTMLElement;
    measure(dom?: HTMLElement | undefined): MeasureResult;
    getGlyphBox(): BoundingBox;
    protected _updateInlineBox(): this;
    protected _updatePathBox(): this;
    protected _updateBoundingBox(): this;
    requestUpdate(): this;
    update(dom?: HTMLElement | undefined): this;
    render(options: RenderOptions): void;
    toString(): string;
}

declare class Paragraph {
    style: NormalizedStyle;
    index: number;
    parent: Text$1;
    lineBox: BoundingBox;
    fragments: Fragment[];
    fill?: NormalizedFill;
    outline?: NormalizedOutline;
    computedStyle: FullStyle;
    get computedFill(): NormalizedFill | undefined;
    get computedOutline(): NormalizedOutline | undefined;
    constructor(style: NormalizedStyle, index: number, parent: Text$1);
    updateComputedStyle(): this;
}

interface DrawShapePathsOptions extends NormalizedStyle, Omit<Partial<Path2DDrawStyle>, 'fill' | 'outline'> {
    fontSize?: number;
    clipRect?: BoundingBox;
}
declare class Canvas2DRenderer {
    text: Text$1;
    context: CanvasRenderingContext2D;
    pixelRatio: number;
    constructor(text: Text$1, context: CanvasRenderingContext2D);
    protected _setupView: () => void;
    protected _setupColors: () => void;
    setup: () => this;
    protected _parseColor: (source: string | CanvasGradient | CanvasPattern, box: BoundingBox) => string | CanvasGradient | CanvasPattern;
    protected _uploadedStyles: string[];
    uploadColor: (style: NormalizedStyle, box: BoundingBox) => void;
    drawPath: (path: Path2D, options?: DrawShapePathsOptions) => void;
    protected _mergePathStyle(path: Path2D, style: Partial<Path2DStyle>): Partial<Path2DStyle>;
    drawCharacter: (character: Character, userStyle?: NormalizedStyle) => void;
}

export { Canvas2DRenderer as C, Fragment as F, Text$1 as T, Character as a, Paragraph as b, Measurer as g, textDefaultStyle as t };
export type { DrawShapePathsOptions as D, MeasureResult as M, Options as O, Plugin as P, RenderOptions as R, MeasuredParagraph as c, MeasuredFragment as d, MeasuredCharacter as e, MeasureDomResult as f, TextEvents as h };
