import { hAlignFromPlacement , hPlacementFromAlignment , TextPlacement , vAlignFromPlacement , vPlacementFromAlignment } from "@here/harp-text-canvas" ; import { assert } from "@here/harp-utils" ; import { LayoutState } from "./LayoutState" ; import { RenderState } from "./RenderState" ; import { TextElement } from "./TextElement" ; import { TextElementType } from "./TextElementType" ; /**
 * `TextElementState` keeps the current state of a text element while it's being rendered.
 */ export class TextElementState { hidden private m_viewDistance : number | undefined ; hidden private m_iconRenderState ? : RenderState ; hidden private m_textRenderState ? : RenderState ; hidden private m_textLayoutState ? : LayoutState ; hidden private readonly m_lineMarkerIndex ? : number ; param element param positionIndex constructor ( readonly element , positionIndex ? ) { this . m_lineMarkerIndex = positionIndex ; } get initialized ( ) : boolean { return this . m_textRenderState !== undefined || this . m_iconRenderState !== undefined ; } returns get visible ( ) : boolean { if ( this . m_textRenderState !== undefined && this . m_textRenderState . isVisible ( ) ) { return true ; } const iconRenderState = this . iconRenderState ; if ( iconRenderState !== undefined && iconRenderState . isVisible ( ) ) { return true ; } return false ; } returns get textPlacement ( ) : TextPlacement { const themeLayout = this . element . layoutStyle ! ; const stateLayout = this . m_textLayoutState ; const lastPlacement = stateLayout !== undefined ? stateLayout . textPlacement : { h : hPlacementFromAlignment ( themeLayout . horizontalAlignment ) , v : vPlacementFromAlignment ( themeLayout . verticalAlignment ) } ; return lastPlacement ; } param placement set textPlacement ( placement ) { if ( this . m_textLayoutState === undefined && this . isBaseTextPlacement ( placement ) === true ) { return ; } if ( this . m_textLayoutState === undefined ) { this . m_textLayoutState = new LayoutState ( placement ) ; } else { this . m_textLayoutState . textPlacement = placement ; } } param placement returns isBaseTextPlacement ( placement ) { const themeLayout = this . element . layoutStyle ; if ( themeLayout !== undefined ) { return ( hAlignFromPlacement ( placement . h ) === themeLayout . horizontalAlignment && vAlignFromPlacement ( placement . v ) === themeLayout . verticalAlignment ) ; } return undefined ; } /**
     * Resets the element to an initialized state.
     */ reset ( ) { if ( this . m_textRenderState !== undefined ) { this . m_textRenderState . reset ( ) ; } if ( this . m_textLayoutState !== undefined ) { if ( this . element . layoutStyle !== undefined ) { this . m_textLayoutState . reset ( this . element . layoutStyle ) ; } else { this . m_textLayoutState = undefined ; } } if ( this . iconRenderState ) { ( this . m_iconRenderState as RenderState ) . reset ( ) ; } this . m_viewDistance = undefined ; this . element . textBufferObject = undefined ; this . element . bounds = undefined ; } param predecessor replace ( predecessor ) { this . m_textRenderState = predecessor . m_textRenderState ; this . m_textLayoutState = predecessor . m_textLayoutState ; this . m_iconRenderState = predecessor . m_iconRenderState ; predecessor . m_textRenderState = undefined ; predecessor . m_textLayoutState = undefined ; predecessor . m_iconRenderState = undefined ; if ( this . element . glyphs === undefined ) { this . element . glyphs = predecessor . element . glyphs ; this . element . glyphCaseArray = predecessor . element . glyphCaseArray ; } this . element . bounds = undefined ; this . element . textBufferObject = undefined ; } returns get viewDistance ( ) : number | undefined { return this . m_viewDistance ; } param viewDistance update ( viewDistance ) { if ( ! this . initialized && viewDistance !== undefined ) { this . initializeRenderStates ( ) ; } this . setViewDistance ( viewDistance ) ; } param viewDistance setViewDistance ( viewDistance ) { this . m_viewDistance = viewDistance ; } returns get renderDistance ( ) : number { return this . element . alwaysOnTop === true ? 0 : this . m_viewDistance !== undefined ? - this . m_viewDistance : 0 ; } returns get textRenderState ( ) : RenderState | undefined { return this . m_textRenderState ; } returns get iconRenderState ( ) : RenderState | undefined { return this . m_iconRenderState ; } /**
     * Returns the index into the path of the TextElement if the TextElement is of type LineMarker,
     * `undefined` otherwise.
     */ public get lineMarkerIndex ( ) : number | undefined { return this . m_lineMarkerIndex ; } /**
     * Returns the position of the TextElement. If this TextElementState belongs to a TextElement
     * of type LineMarker, it returns the position of the marker at the references index in the
     * path of the TextElement.
     */ public get position ( ) : THREE . Vector3 { return this . element . path !== undefined && this . m_lineMarkerIndex !== undefined ? this . element . path [ this . m_lineMarkerIndex ] : this . element . position ; } param time param disableFading updateFading ( time , disableFading ) { if ( this . m_textRenderState !== undefined ) { this . m_textRenderState . updateFading ( time , disableFading ) ; } if ( this . iconRenderState !== undefined ) { this . iconRenderState . updateFading ( time , disableFading ) ; } } /**
     * Initialize text and icon render states
     */ private initializeRenderStates ( ) { assert ( this . m_textRenderState === undefined ) ; assert ( this . m_textLayoutState === undefined ) ; assert ( this . m_iconRenderState === undefined ) ; const { textFadeTime } = this . element ; this . m_textRenderState = new RenderState ( textFadeTime ) ; if ( this . element . type === TextElementType . PoiLabel || this . element . type === TextElementType . LineMarker ) { const techniqueIconFadeTime = this . element . poiInfo ?. technique . iconFadeTime ; const iconFadeTime = techniqueIconFadeTime !== undefined ? techniqueIconFadeTime * 1000 : textFadeTime ; this . m_iconRenderState = new RenderState ( iconFadeTime ) ; } } } /**
 * Test if the TextElement this  TextElementState refers to is of type LineMarker.
 *  param state export function isLineMarkerElementState ( state ) { return ( state as any ) . m_lineMarkerIndex !== undefined ; }