@lightningtv/renderer
Version:
Lightning 3 Renderer
371 lines (370 loc) • 11.2 kB
TypeScript
import type { EventEmitter } from '../../../common/EventEmitter.js';
import type { CoreTextNode } from '../../CoreTextNode.js';
import type { Stage } from '../../Stage.js';
import type { TrFontFace, TrFontFaceDescriptors } from '../font-face-types/TrFontFace.js';
import type { TextBaseline, TextVerticalAlign } from './LightningTextTextureRenderer.js';
/**
* Augmentable map of text renderer type IDs to text renderer types.
*
* @example
* ```ts
* declare module './TextRenderer' {
* interface TextRendererMap {
* canvas: CanvasTextRenderer;
* }
* }
* ```
*/
export interface TextRendererMap {
}
export interface TextRendererState {
props: TrProps;
/**
* Whether or not the text renderer state is scheduled to be updated
* via queueMicrotask.
*/
updateScheduled: boolean;
status: 'initialState' | 'loading' | 'loaded' | 'failed' | 'destroyed';
/**
* Event emitter for the text renderer
*/
emitter: EventEmitter;
/**
* Force a full layout pass for the calculation of the
* total dimensions of the text
*/
forceFullLayoutCalc: boolean;
textW: number | undefined;
textH: number | undefined;
isRenderable: boolean;
debugData: {
updateCount: number;
layoutCount: number;
drawCount: number;
lastLayoutNumCharacters: number;
layoutSum: number;
drawSum: number;
bufferSize: number;
};
}
export interface TextRendererDebugProps {
showRenderWindow: boolean;
showVisibleRect: boolean;
showElementRect: boolean;
disableScissor: boolean;
printLayoutTime: boolean;
}
/**
* Text renderer properties that are used in resolving appropriate font faces
*
* @remarks
* Extended by {@link TrProps}
*/
export interface TrFontProps {
/**
* Font Family
*
* @internalRemarks
* `fontFamily` is defined currently as single string, but in the future we may want to
* support multiple font family fallbacks, as this is supported by CSS / Canvas2d. We can
* do this in a backwards compatible way by unioning an array of strings to the
* `fontFamily` property.
*/
fontFamily: string;
/**
* Font Weight
*
* @remarks
* The font weight to use when looking up the font face. This can be a numeric
* value between 1 and 1000, or one of the following strings:
* - `'normal'` - same as 400
* - `'bold'` - same as 700
* - `'bolder'` - (Not yet properly supported)
*/
fontWeight: TrFontFaceDescriptors['weight'] | 'bolder' | 'lighter';
/**
* Font Style
*
* @remarks
* The font style to use when looking up the font face. This can be one of the
* following strings:
* - `'normal'`
* - `'italic'`
* - `'oblique'`
*/
fontStyle: TrFontFaceDescriptors['style'];
/**
* Font Stretch
*
* @remarks
* The font stretch to use when looking up the font face. This can be one of the
* following strings:
* - `'normal'`
* - `'ultra-condensed'`
* - `'extra-condensed'`
* - `'condensed'`
* - `'semi-condensed'`
* - `'semi-expanded'`
* - `'expanded'`
* - `'extra-expanded'`
* - `'ultra-expanded'`
*
* @default 'normal'
*/
fontStretch: TrFontFaceDescriptors['stretch'];
/**
* Font Size
*
* @remarks
* The font size to use when looking up the font face.
*
* The font size is specified in pixels and is the height of the font's
* em-square. The em-square is essentially the height of the capital letters
* for the font. The actual height of the text can be larger than the
* specified font size, as the font may have ascenders and descenders that
* extend beyond the em-square.
*
* @default 16
*/
fontSize: number;
}
export interface TrProps extends TrFontProps {
/**
* Text to display
*
* @default ''
*/
text: string;
/**
* Text alignment
*
* @remarks
* Alignment of the text relative to it's contained bounds. For best results,
* use {@link contain} mode `'width'` or `'both'` and a set an explicit
* {@link width} for the text to be aligned within.
*
* @default 'left'
*/
textAlign: 'left' | 'center' | 'right';
/**
* Color of text
*
* @remarks
* The color value is a number in the format 0xRRGGBBAA, where RR is the red
* component, GG is the green component, BB is the blue component, and AA is
* the alpha component.
*
* @default 0xffffffff (opaque white)
*/
color: number;
x: number;
y: number;
/**
* Contain mode for text
*
* @remarks
* The contain mode determines how the text is contained within the bounds
* of the Text Node. The default value is `'none'`, which means that the
* Text Renderer will not constrain the text in any way. `'width'` mode will
* constrain the text to the set width wrapping lines as necessary, and
* `'both'` mode will constrain the text to both the set width and height
* wrapping lines and truncating text as necessary.
*
* ## Text Auto-size Behavior
* Depending on the set contain mode, after the text 'loaded' event is emitted,
* the text node may have either its {@link width} and {@link height} updated
* to match the rendered size of the text.
*
* When contain mode is 'none', both the {@link width} and {@link height}
* properties are updated.
*
* When contain mode is 'width', only the {@link height} property is updated.
*
* When contain mode is 'both', neither property is updated.
*
* @default 'none'
*/
contain: 'none' | 'width' | 'both';
width: number;
height: number;
/**
* Whether or not the text is scrollable
*
* @remarks
* If `scrollable` is `true`, the text can be scrolled vertically within the
* bounds of the Text Node. You can set the scroll position using the
* {@link scrollY} property.
*
* @default false
*/
scrollable: boolean;
/**
* Vertical scroll position for text
*
* @remarks
* The vertical scroll position of the text. This property is only used if
* {@link scrollable} is `true`.
*
* @default 0
*/
scrollY: number;
/**
* Vertical offset for text
*
* @remarks
* The vertical offset of the text. This property is only used if
* {@link scrollable} is `true`.
*
* @default 0
*/
offsetY: number;
/**
* Letter spacing for text (in pixels)
*
* @remarks
* This property sets additional (or reduced, if value is negative) spacing
* between characters in the text.
*
* @default 0
*/
letterSpacing: number;
/**
* Line height for text (in pixels)
*
* @remarks
* This property sets the height of each line. If set to `undefined`, the
* line height will be calculated based on the font and font size to be the
* minimal height required to completely contain a line of text.
*
* See: https://github.com/lightning-js/renderer/issues/170
*
* @default `undefined`
*/
lineHeight: number | undefined;
/**
* Max lines for text
*
* @remarks
* This property sets max number of lines of a text paragraph.
* Not yet implemented in the SDF renderer.
*
* @default 0
*/
maxLines: number;
/**
* Baseline for text
*
* @remarks
* This property sets the text baseline used when drawing text.
* Not yet implemented in the SDF renderer.
*
* @default alphabetic
*/
textBaseline: TextBaseline;
/**
* Vertical Align for text when lineHeight > fontSize
*
* @remarks
* This property sets the vertical align of the text.
* Not yet implemented in the SDF renderer.
*
* @default middle
*/
verticalAlign: TextVerticalAlign;
/**
* Overflow Suffix for text
*
* @remarks
* The suffix to be added when text is cropped due to overflow.
* Not yet implemented in the SDF renderer.
*
* @default "..."
*/
overflowSuffix: string;
zIndex: number;
debug: Partial<TextRendererDebugProps>;
}
export type TrPropSetters<StateT = TextRendererState> = {
[key in keyof TrProps]: (state: StateT, value: TrProps[key]) => void;
};
/**
* Event handler for when text is loaded
*
* @remarks
* Emitted by state.emitter
*/
export type TrLoadedEventHandler = (target: any) => void;
/**
* Event handler for when text failed to load
*
* @remarks
* Emitted by state.emitter
*/
export type TrFailedEventHandler = (target: any, error: Error) => void;
export declare abstract class TextRenderer<StateT extends TextRendererState = TextRendererState> {
protected stage: Stage;
readonly set: Readonly<TrPropSetters<StateT>>;
abstract type: 'canvas' | 'sdf';
constructor(stage: Stage);
setStatus(state: StateT, status: StateT['status'], error?: Error): void;
/**
* Allows the CoreTextNode to communicate changes to the isRenderable state of
* the itself.
*
* @param state
* @param renderable
*/
setIsRenderable(state: StateT, renderable: boolean): void;
/**
* Called by constructor to get a map of property setter functions for this renderer.
*/
abstract getPropertySetters(): Partial<TrPropSetters<StateT>>;
/**
* Given text renderer properties (particularly the specific properties related to font selection)
* returns whether or not the renderer can render it.
*
* @param props
*/
abstract canRenderFont(props: TrFontProps): boolean;
/**
* Called by the TrFontManager to find out if a newly added font face is supported
* by this renderer.
*
* @param fontFace
*/
abstract isFontFaceSupported(fontFace: TrFontFace): boolean;
/**
* Called by the TrFontManager to add a font face to the renderer's font registry.
*
* @remarks
* This method MUST ONLY be called for a fontFace that previously passed the
* {@link isFontFaceSupported} check.
*
* @param fontFace
*/
abstract addFontFace(fontFace: TrFontFace): void;
abstract createState(props: TrProps, node: CoreTextNode): StateT;
/**
* Destroy/Clean up the state object
*
* @remarks
* Opposite of createState(). Frees any event listeners / resources held by
* the state that may not reliably get garbage collected.
*
* @param state
*/
destroyState(state: StateT): void;
/**
* Schedule a state update via queueMicrotask
*
* @remarks
* This method is used to schedule a state update via queueMicrotask. This
* method should be called whenever a state update is needed, and it will
* ensure that the state is only updated once per microtask.
* @param state
* @returns
*/
scheduleUpdateState(state: StateT): void;
abstract updateState(state: StateT): void;
renderQuads?(node: CoreTextNode): void;
}