import { assert } from "@here/harp-utils" ; import { parseCSSColor } from "csscolorparser" ; import { ColorUtils } from "./ColorUtils" ; internal export enum StringEncodedNumeralType { Meters , Pixels , Hex } internal export interface StringEncodedNumeralFormat { readonly type : StringEncodedNumeralType ; readonly size : number ; readonly regExp : RegExp ; mask ? : number ; decoder : ( encodedValue : string , target : number [ ] ) => boolean ; } const StringEncodedMeters = { type : StringEncodedNumeralType . Meters , size : 1 , regExp : /^((?=\.\d|\d)(?:\d+)?(?:\.?\d*))m$/ , decoder : ( encodedValue , target ) => { const match = StringEncodedMeters . regExp . exec ( encodedValue ) ; return match ? ( target [ 0 ] = Number ( match [ 1 ] ) ) !== undefined : false ; } } ; const StringEncodedPixels = { type : StringEncodedNumeralType . Pixels , size : 1 , mask : 1.0 , regExp : /^((?=\.\d|\d)(?:\d+)?(?:\.?\d*))px$/ , decoder : ( encodedValue , target ) => { const match = StringEncodedPixels . regExp . exec ( encodedValue ) ; if ( match === null ) { return false ; } target [ 0 ] = Number ( match [ 1 ] ) ; return true ; } } ; const StringEncodedHex = { type : StringEncodedNumeralType . Hex , size : 4 , regExp : /^\#((?:[0-9A-Fa-f][0-9A-Fa-f]){4}|[0-9A-Fa-f]{4})$/ , decoder : ( encodedValue , target ) => { const match = StringEncodedHex . regExp . exec ( encodedValue ) ; if ( match === null ) { return false ; } const hex = match [ 1 ] ; const size = hex . length ; assert ( size === 4 || size === 8 , `Matched incorrect hex color format` ) ; if ( size === 4 ) { target [ 0 ] = parseInt ( hex . charAt ( 0 ) + hex . charAt ( 0 ) , 16 ) / 255 ; target [ 1 ] = parseInt ( hex . charAt ( 1 ) + hex . charAt ( 1 ) , 16 ) / 255 ; target [ 2 ] = parseInt ( hex . charAt ( 2 ) + hex . charAt ( 2 ) , 16 ) / 255 ; target [ 3 ] = size === 4 ? parseInt ( hex . charAt ( 3 ) + hex . charAt ( 3 ) , 16 ) / 255 : 1 ; } else if ( size === 8 ) { target [ 0 ] = parseInt ( hex . charAt ( 0 ) + hex . charAt ( 1 ) , 16 ) / 255 ; target [ 1 ] = parseInt ( hex . charAt ( 2 ) + hex . charAt ( 3 ) , 16 ) / 255 ; target [ 2 ] = parseInt ( hex . charAt ( 4 ) + hex . charAt ( 5 ) , 16 ) / 255 ; target [ 3 ] = size === 8 ? parseInt ( hex . charAt ( 6 ) + hex . charAt ( 7 ) , 16 ) / 255 : 1 ; } return true ; } } ; internal export const StringEncodedMetricFormats = [ StringEncodedMeters , StringEncodedPixels ] ; const StringEncodedMetricFormatMaxSize = StringEncodedMetricFormats . reduce ( ( a , b ) => Math . max ( a , b . size ) , 0 ) ; internal export const StringEncodedColorFormats = [ StringEncodedHex ] ; const StringEncodedColorFormatMaxSize = StringEncodedColorFormats . reduce ( ( a , b ) => Math . max ( a , b . size ) , 0 ) ; internal export const StringEncodedNumeralFormats = [ ... StringEncodedMetricFormats , ... StringEncodedColorFormats ] ; internal export const StringEncodedNumeralFormatMaxSize = Math . max ( StringEncodedColorFormatMaxSize , StringEncodedMetricFormatMaxSize ) ; const tmpBuffer = new Array ( StringEncodedNumeralFormatMaxSize ) ; param numeral param pixelToMeters returns export function parseStringEncodedNumeral ( numeral , pixelToMeters = 1.0 ) { return parseStringLiteral ( numeral , StringEncodedNumeralFormats , pixelToMeters ) ; } param color returns export function parseStringEncodedColor ( color ) { return parseStringLiteral ( color , StringEncodedColorFormats ) ; } function parseStringLiteral ( text , formats , pixelToMeters = 1.0 ) { const matchedFormat = formats . find ( format => { return format . decoder ( text , tmpBuffer ) ? true : false ; } ) ; if ( matchedFormat === undefined ) { const components = parseCSSColor ( text ) ; return Array . isArray ( components ) && ! components . some ( c => isNaN ( c ) ) ? ColorUtils . getHexFromRgba ( components [ 0 ] / 255 , components [ 1 ] / 255 , components [ 2 ] / 255 , components [ 3 ] ) : undefined ; } switch ( matchedFormat ?. type ) { case StringEncodedNumeralType . Pixels : return tmpBuffer [ 0 ] * pixelToMeters ; case StringEncodedNumeralType . Hex : return ColorUtils . getHexFromRgba ( tmpBuffer [ 0 ] , tmpBuffer [ 1 ] , tmpBuffer [ 2 ] , tmpBuffer [ 3 ] ) ; default : return tmpBuffer [ 0 ] ; } }