import { TNSCanvasRenderingContext2DBase } from './canvas-plugin.common' ; import { CanvasGradient } from './CanvasGradient' ; import { ColorHandler } from './ColorHelper' ; import { TNSPath2D } from './TNSPath2D' ; import { ImageSource } from '@nativescript/core/image-source' ; import { ImageData } from './ImageData' ; import { TextMetrics } from './TextMetrics' ; import { Color } from '@nativescript/core/color' ; import { TNSImageAsset } from './TNSImageAsset' ; import { CanvasPattern } from './CanvasPattern' ; import { TNSCanvas } from './TNSCanvas' ; declare var com ; export class TNSCanvasRenderingContext2D extends TNSCanvasRenderingContext2DBase { public static isDebug = false ; static colorCache = { } ; private context ; constructor ( context ) { super ( ) ; this . context = context ; } get native ( ) { return this . context ; } get canvas ( ) { return this . _canvas ; } private _shadowColor : string = 'transparent' ; get shadowColor ( ) { this . log ( 'shadowColor' ) ; return this . _shadowColor ; } set shadowColor ( color ) { this . log ( 'shadowColor value:' , color ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { if ( typeof color === 'string' && ! isNaN ( parseInt ( color ) ) ) { this . context . setShadowColor ( new Color ( parseInt ( color ) ) . argb ) ; } else { this . context . setShadowColor ( new Color ( color ) . argb ) ; } } } get font ( ) : string { this . log ( 'get font' ) ; return this . context . getFont ( ) ; } set font ( value ) { this . log ( 'set font value:' , value ) ; if ( this . context ) { this . context . setFont ( value ) ; } } get direction ( ) : string { this . log ( 'direction' ) ; return this . context . getDirection ( ) ; } set direction ( value ) { this . log ( 'direction value:' , value ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setDirection ( value ) ; } } get globalAlpha ( ) : number { this . log ( 'globalAlpha' ) ; return this . context . getGlobalAlpha ( ) ; } set globalAlpha ( alpha ) { this . log ( 'globalAlpha value:' , alpha ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setGlobalAlpha ( alpha ) ; } } get imageSmoothingEnabled ( ) { this . log ( 'imageSmoothingEnabled' ) ; return this . context . getImageSmoothingEnabled ( ) ; } set imageSmoothingEnabled ( enabled ) { this . log ( 'imageSmoothingEnabled value:' , enabled ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setImageSmoothingEnabled ( enabled ) ; } } get imageSmoothingQuality ( ) { this . log ( 'imageSmoothingQuality' ) ; return this . context . getImageSmoothingQuality ( ) . toString ( ) ; } set imageSmoothingQuality ( quality ) { this . log ( 'imageSmoothingQuality value:' , quality ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { switch ( quality ) { case 'high' : this . context . setImageSmoothingQuality ( com . github . triniwiz . canvas . CanvasRenderingContext2D . ImageSmoothingQuality . High ) ; break ; case 'medium' : this . context . setImageSmoothingQuality ( com . github . triniwiz . canvas . CanvasRenderingContext2D . ImageSmoothingQuality . Medium ) ; break ; default : this . context . setImageSmoothingQuality ( com . github . triniwiz . canvas . CanvasRenderingContext2D . ImageSmoothingQuality . Low ) ; break ; } } } get lineDashOffset ( ) { this . log ( 'lineDashOffset' ) ; return this . context . getLineDashOffset ( ) ; } set lineDashOffset ( offset ) { this . log ( 'lineDashOffset value:' , offset ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setLineDashOffset ( offset ) ; } } get lineJoin ( ) { this . log ( 'lineJoin' ) ; return this . context . getLineJoin ( ) . toString ( ) ; } set lineJoin ( join ) { this . log ( 'lineJoin value:' , join ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { switch ( join ) { case 'bevel' : this . context . setLineJoin ( com . github . triniwiz . canvas . CanvasRenderingContext2D . LineJoin . Bevel ) ; break ; case 'round' : this . context . setLineJoin ( com . github . triniwiz . canvas . CanvasRenderingContext2D . LineJoin . Round ) ; break ; default : this . context . setLineJoin ( com . github . triniwiz . canvas . CanvasRenderingContext2D . LineJoin . Miter ) ; break ; } } } get lineCap ( ) { this . log ( 'lineCap' ) ; return this . context . getLineCap ( ) . toString ( ) ; } set lineCap ( cap ) { this . log ( 'lineCap value:' , cap ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { switch ( cap ) { case 'round' : this . context . setLineCap ( com . github . triniwiz . canvas . CanvasRenderingContext2D . LineCap . Round ) ; break ; case 'square' : this . context . setLineCap ( com . github . triniwiz . canvas . CanvasRenderingContext2D . LineCap . Square ) ; break ; default : this . context . setLineCap ( com . github . triniwiz . canvas . CanvasRenderingContext2D . LineCap . Butt ) ; } } } get miterLimit ( ) { this . log ( 'miterLimit value:' ) ; return this . context . getMiterLimit ( ) ; } set miterLimit ( limit ) { this . log ( 'miterLimit value:' , limit ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setMiterLimit ( limit ) ; } } get shadowBlur ( ) { this . log ( 'shadowBlur' ) ; return this . context . getShadowBlur ( ) ; } set shadowBlur ( blur ) { this . log ( 'shadowBlur value:' , blur ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setShadowBlur ( blur ) ; } } get shadowOffsetX ( ) { this . log ( 'shadowOffsetX' ) ; return this . context . getShadowOffsetX ( ) ; } set shadowOffsetX ( x ) { this . log ( 'shadowOffsetX value:' , x ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setShadowOffsetX ( x ) ; } } get shadowOffsetY ( ) { this . log ( 'shadowOffsetY' ) ; return this . context . getShadowOffsetY ( ) ; } set shadowOffsetY ( y ) { this . log ( 'shadowOffsetY value:' , y ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setShadowOffsetY ( y ) ; } } get textAlign ( ) { this . log ( 'textAlign' ) ; return this . context . getTextAlign ( ) . toString ( ) ; } set textAlign ( alignment ) { this . log ( 'textAlign value:' , alignment ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { switch ( alignment ) { case 'start' : this . context . setTextAlign ( com . github . triniwiz . canvas . CanvasTextAlignment . Start ) ; break ; case 'center' : this . context . setTextAlign ( com . github . triniwiz . canvas . CanvasTextAlignment . Center ) ; break ; case 'end' : this . context . setTextAlign ( com . github . triniwiz . canvas . CanvasTextAlignment . End ) ; break ; case 'right' : this . context . setTextAlign ( com . github . triniwiz . canvas . CanvasTextAlignment . Right ) ; break ; default : this . context . setTextAlign ( com . github . triniwiz . canvas . CanvasTextAlignment . Left ) ; break ; } } } get globalCompositeOperation ( ) { this . log ( 'globalCompositeOperation' ) ; return this . context . getGlobalCompositeOperation ( ) . toString ( ) ; } set globalCompositeOperation ( composite ) { this . log ( 'globalCompositeOperation value:' , composite ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { let operation ; switch ( composite . toLowerCase ( ) ) { case 'source-over' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . SourceOver ; break ; case 'source-in' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . SourceIn ; break ; case 'source-out' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . SourceoOut ; break ; case 'source-atop' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . SourceAtop ; break ; case 'destination-over' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . DestinationOver ; break ; case 'destination-in' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . DestinationIn ; break ; case 'destination-out' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . DestinationOut ; break ; case 'destination-atop' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . DestinationAtop ; break ; case 'lighter' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Lighter ; break ; case 'copy' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Copy ; break ; case 'xor' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Xor ; break ; case 'multiply' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Multiply ; break ; case 'screen' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Screen ; break ; case 'overlay' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Overlay ; break ; case 'darken' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Darken ; break ; case 'lighten' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Lighten ; break ; case 'color-dodge' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . ColorDodge ; break ; case 'color-burn' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . ColorBurn ; break ; case 'hard-light' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . HardLight ; break ; case 'soft-light' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . SoftLight ; break ; case 'difference' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Difference ; break ; case 'exclusion' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Exclusion ; break ; case 'hue' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Hue ; break ; case 'saturation' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Saturation ; break ; case 'color' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Color ; break ; case 'luminosity' : operation = com . github . triniwiz . canvas . CanvasCompositeOperationType . Luminosity ; break ; } this . context . setGlobalCompositeOperation ( operation ) ; } } private _fillStyle : string | CanvasGradient | CanvasPattern = 'black' ; get fillStyle ( ) { this . log ( 'fillStyle' ) ; return this . _fillStyle ; } set fillStyle ( color ) { this . log ( 'fillStyle:' , color ) ; this . _ensureLayoutBeforeDraw ( ) ; let nativeStyle ; if ( this . _fillStyle === color ) { return ; } if ( ! ( color instanceof CanvasGradient || color instanceof CanvasPattern ) && TNSCanvasRenderingContext2D . colorCache [ color ] ) { const cache = TNSCanvasRenderingContext2D . colorCache [ color ] ; this . _fillStyle = cache ; this . context . setFillStyle ( cache ) ; return ; } if ( color instanceof CanvasGradient ) { nativeStyle = color . native ; this . _fillStyle = color ; } else if ( color instanceof CanvasPattern ) { nativeStyle = color . native ; this . _fillStyle = color ; } else { if ( typeof color === 'string' && color . startsWith ( 'hsla' ) ) { color = ColorHandler . HSLAToRGBA ( color , false ) ; } else if ( typeof color === 'string' && color . startsWith ( 'hsl' ) ) { color = ColorHandler . HSLToRGB ( color , false ) ; } if ( typeof color === 'string' && color . indexOf ( 'Invalid input color' ) > - 1 ) { color = 'black' ; } if ( color === undefined || color === null ) { color = 'black' ; } this . _fillStyle = color ; nativeStyle = new Color ( color ) . argb ; TNSCanvasRenderingContext2D . colorCache [ color ] = nativeStyle ; } this . context . setFillStyle ( nativeStyle ) ; } private _strokeStyle : string | CanvasGradient | CanvasPattern = 'black' ; get strokeStyle ( ) { this . log ( 'strokeStyle' ) ; return this . _strokeStyle ; } set strokeStyle ( color ) { this . log ( 'strokeStyle value:' , color ) ; this . _ensureLayoutBeforeDraw ( ) ; let nativeStyle ; if ( this . _strokeStyle === color ) { return ; } if ( ! ( color instanceof CanvasGradient || color instanceof CanvasPattern ) && TNSCanvasRenderingContext2D . colorCache [ color ] ) { const cache = TNSCanvasRenderingContext2D . colorCache [ color ] ; this . _strokeStyle = cache ; this . context . setStrokeStyle ( cache ) ; return ; } if ( color instanceof CanvasGradient ) { nativeStyle = color . native ; this . _strokeStyle = color ; } else if ( color instanceof CanvasPattern ) { nativeStyle = color . native ; this . _strokeStyle = color ; } else { if ( typeof color === 'string' && color . startsWith ( 'hsla' ) ) { color = ColorHandler . HSLAToRGBA ( color , false ) ; } else if ( typeof color === 'string' && color . startsWith ( 'hsl' ) ) { color = ColorHandler . HSLToRGB ( color , false ) ; } if ( typeof color === 'string' && color . indexOf ( 'Invalid input color' ) > - 1 ) { color = 'black' ; } this . _strokeStyle = color ; nativeStyle = new Color ( color ) . argb ; TNSCanvasRenderingContext2D . colorCache [ color ] = nativeStyle ; } this . context . setStrokeStyle ( nativeStyle ) ; } get lineWidth ( ) { this . log ( 'lineWidth' ) ; return this . context . getLineWidth ( ) ; } set lineWidth ( width ) { this . log ( 'lineWidth value:' , width ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( this . context ) { this . context . setLineWidth ( width ) ; } } addHitRegion ( region ) { } arc ( x , y , radius , startAngle , endAngle , anticlockwise = false ) { this . log ( 'arc value:' , x , y , radius , startAngle , endAngle , anticlockwise ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . arc ( x , y , radius , startAngle , endAngle , anticlockwise ) ; } arcTo ( x1 , y1 , x2 , y2 , radius ) { this . log ( 'arcTo value:' , x1 , y1 , x2 , y2 , radius ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . arcTo ( x1 , y1 , x2 , y2 , radius ) ; } beginPath ( ) { this . log ( 'beginPath' ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . beginPath ( ) ; } bezierCurveTo ( cp1x , cp1y , cp2x , cp2y , x , y ) { this . log ( 'bezierCurveTo value:' , cp1x , cp1y , cp2x , cp2y , x , y ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . bezierCurveTo ( cp1x , cp1y , cp2x , cp2y , x , y ) ; } clearHitRegions ( ) { } clearRect ( x , y , width , height ) { this . log ( 'clearRect value:' , x , y , width , height ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . clearRect ( x , y , width , height ) ; } clip ( ) ; clip ( fillRule ) ; clip ( path , fillRule ) ; clip ( ... args ) { this . log ( 'clip value:' , ... args ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( typeof args [ 0 ] === 'string' ) { this . context . clip ( args [ 0 ] ) ; } else if ( args [ 0 ] instanceof TNSPath2D && typeof args [ 1 ] === 'string' ) { this . context . clip ( args [ 0 ] . native , args [ 1 ] ) ; } else if ( args [ 0 ] instanceof TNSPath2D ) { this . context . clip ( args [ 0 ] . native ) ; } else { this . context . clip ( ) ; } } closePath ( ) { this . log ( 'closePath' ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . closePath ( ) ; } createImageData ( width , height ) ; createImageData ( data ) ; createImageData ( width , height ? ) { this . log ( 'createImageData value:' , arguments ) ; if ( width instanceof ImageData ) { return ImageData . from ( width ) ; } else { return ImageData . fromNative ( this . context . createImageData ( width as any , height ) ) ; } } createLinearGradient ( x0 , y0 , x1 , y1 ) { this . log ( 'createLinearGradient value:' , x0 , y0 , x1 , y1 ) ; this . _ensureLayoutBeforeDraw ( ) ; return CanvasGradient . fromNative ( this . context . createLinearGradient ( x0 , y0 , x1 , y1 ) ) ; } createPattern ( image , repetition ) { this . log ( 'createPattern value:' , image , repetition ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( repetition === undefined || typeof repetition !== 'string' ) { const e = new Error ( 'The string did not match the expected pattern.' ) ; e . name = 'SyntaxError' ; throw e ; } let img ; if ( image instanceof ImageSource ) { img = image . android ; } else if ( image instanceof android . graphics . Bitmap ) { img = image ; } else if ( image instanceof TNSImageAsset ) { img = image . native ; } else if ( image instanceof TNSCanvas ) { img = image . android ; } else if ( image && typeof image . tagName === 'string' && image . tagName === 'IMG' ) { if ( image . _imageSource instanceof ImageSource ) { img = image . _imageSource . android ; } else if ( image . _image instanceof android . graphics . Bitmap ) { img = image . _image ; } else if ( image . _asset instanceof TNSImageAsset ) { img = image . _asset . native ; } else if ( typeof image . src === 'string' ) { img = ImageSource . fromFileSync ( image . src ) . android ; } } else if ( image && typeof image . tagName === 'string' && image . tagName === 'CANVAS' && image . _canvas instanceof TNSCanvas ) { img = image . _canvas . android ; } if ( ! img ) { return null ; } let rep ; switch ( repetition ) { case 'no-repeat' : rep = com . github . triniwiz . canvas . Pattern . PatternRepetition . NoRepeat ; break ; case 'repeat-x' : rep = com . github . triniwiz . canvas . Pattern . PatternRepetition . RepeatX ; break ; case 'repeat-y' : rep = com . github . triniwiz . canvas . Pattern . PatternRepetition . RepeatY ; break ; default : rep = com . github . triniwiz . canvas . Pattern . PatternRepetition . Repeat ; break ; } return new CanvasPattern ( this . context . createPattern ( img , rep ) ) ; } createRadialGradient ( x0 , y0 , r0 , x1 , y1 , r1 ) { this . log ( 'createRadialGradient value:' , x0 , y0 , r0 , x1 , y1 , r1 ) ; this . _ensureLayoutBeforeDraw ( ) ; return CanvasGradient . fromNative ( this . context . createRadialGradient ( x0 , y0 , r0 , x1 , y1 , r1 ) ) ; } drawFocusIfNeeded ( element ) ; drawFocusIfNeeded ( path , element ) ; drawFocusIfNeeded ( ... args ) { } drawImage ( image , dx , dy ) ; drawImage ( image , dx , dy , dWidth , dHeight ) ; drawImage ( image , sx , sy , sWidth , sHeight , dx , dy , dWidth , dHeight ) ; drawImage ( ... args ) { this . log ( 'drawImage value:' , ... args ) ; this . _ensureLayoutBeforeDraw ( ) ; let image = args [ 0 ] ; if ( image instanceof TNSImageAsset ) { image = image . native ; } else if ( image instanceof ImageSource ) { image = image . android ; } else if ( image instanceof android . graphics . Bitmap ) { image = image ; } else if ( image instanceof TNSCanvas ) { image = image . android ; } else if ( image && typeof image . tagName === 'string' && image . tagName === 'IMG' ) { if ( image . _imageSource instanceof ImageSource ) { image = image . _imageSource . android ; } else if ( image . _image instanceof android . graphics . Bitmap ) { image = image . _image ; } else if ( image . _asset instanceof TNSImageAsset ) { image = image . _asset . native ; } else if ( typeof image . src === 'string' ) { image = ImageSource . fromFileSync ( image . src ) . android ; } } else if ( image && typeof image . tagName === 'string' && image . tagName === 'CANVAS' && image . _canvas instanceof TNSCanvas ) { image = image . _canvas . android ; } if ( args . length === 3 ) { this . context . drawImage ( image , args [ 1 ] , args [ 2 ] ) ; } else if ( args . length === 5 ) { this . context . drawImage ( image , args [ 1 ] , args [ 2 ] , args [ 3 ] , args [ 4 ] ) ; } else if ( args . length === 9 ) { this . context . drawImage ( image , args [ 1 ] , args [ 2 ] , args [ 3 ] , args [ 4 ] , args [ 5 ] , args [ 6 ] , args [ 7 ] , args [ 8 ] ) ; } } ellipse ( x , y , radiusX , radiusY , rotation , startAngle , endAngle , anticlockwise = false ) { this . log ( 'ellipse value:' , x , y , radiusX , radiusY , rotation , startAngle , endAngle , anticlockwise ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . ellipse ( x , y , radiusX , radiusY , rotation , startAngle , endAngle , anticlockwise ) ; } fill ( ) ; fill ( fillRule ) ; fill ( path , fillRule ) ; fill ( ... args ) { this . log ( 'fill value:' , ... args ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( typeof args [ 0 ] === 'string' ) { this . context . fill ( args [ 0 ] ) ; } else if ( args [ 0 ] instanceof TNSPath2D && typeof args [ 1 ] === 'string' ) { this . context . fill ( args [ 0 ] . native , args [ 1 ] ) ; } else if ( args [ 0 ] instanceof TNSPath2D ) { this . context . fill ( args [ 0 ] . native ) ; } else { this . context . fill ( ) ; } } fillRect ( x , y , width , height ) { this . log ( 'fillRect value:' , x , y , width , height ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . fillRect ( x , y , width , height ) ; } fillText ( text , x , y , maxWidth ) { this . log ( 'fillText value:' , text , x , y , maxWidth ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( typeof maxWidth === 'number' ) { this . context . fillText ( text , x , y , maxWidth ) ; } else { this . context . fillText ( text , x , y ) ; } } getImageData ( sx , sy , sw , sh ) { this . log ( 'getImageData value:' , sx , sy , sw , sh ) ; this . _ensureLayoutBeforeDraw ( ) ; return ImageData . fromNative ( this . context . getImageData ( sx , sy , sw , sh ) ) ; } getLineDash ( ) { this . log ( 'getLineDash' ) ; this . _ensureLayoutBeforeDraw ( ) ; return this . context . getLineDash ( ) as any ; } isPointInPath ( x , y , fillRule ) ; isPointInPath ( path , x , y , fillRule ) ; isPointInPath ( ... args ) { this . log ( 'isPointInPath value:' , ... args ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( args . length === 2 ) { return this . context . isPointInPath ( args [ 0 ] , args [ 1 ] ) ; } else if ( args . length === 3 ) { return this . context . isPointInPath ( args [ 0 ] , args [ 1 ] , args [ 2 ] ) ; } else if ( args . length === 4 && args [ 0 ] instanceof TNSPath2D ) { return this . context . isPointInPath ( args [ 0 ] . native , args [ 1 ] , args [ 2 ] , args [ 3 ] ) ; } return false ; } isPointInStroke ( x , y ) ; isPointInStroke ( path , x , y ) ; isPointInStroke ( ... args ) { this . log ( 'isPointInStroke value:' , ... args ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( args . length === 2 ) { return this . context . isPointInStroke ( args [ 0 ] , args [ 1 ] ) ; } else if ( args . length === 3 && args [ 0 ] instanceof TNSPath2D ) { return this . context . isPointInStroke ( args [ 0 ] . native , args [ 1 ] , args [ 2 ] ) ; } return false ; } lineTo ( x , y ) { this . log ( 'lineTo value:' , x , y ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . lineTo ( x , y ) ; } measureText ( text ) { this . log ( 'measureText value:' , text ) ; this . _ensureLayoutBeforeDraw ( ) ; return new TextMetrics ( this . context . measureText ( text ) ) ; } moveTo ( x , y ) { this . log ( 'moveTo value:' , x , y ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . moveTo ( x , y ) ; } putImageData ( imageData , dx , dy ) ; putImageData ( imageData , dx , dy , dirtyX , dirtyY , dirtyWidth , dirtyHeight ) ; putImageData ( imageData , dx , dy , dirtyX ? , dirtyY ? , dirtyWidth ? , dirtyHeight ? ) ; putImageData ( ... args ) { this . log ( 'putImageData value:' , ... args ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( ! args ) { return ; } let data = args [ 0 ] as any ; if ( args . length === 1 ) { data . native . updateData ( Array . from ( data . data ) ) ; this . context . putImageData ( data . native ) ; } else if ( args . length === 3 ) { data . native . updateData ( Array . from ( data . data ) ) ; this . context . putImageData ( data . native , args [ 1 ] , args [ 2 ] ) ; } else if ( args . length === 7 ) { data . native . updateData ( Array . from ( data . data ) ) ; this . context . putImageData ( data . native , args [ 1 ] , args [ 2 ] , args [ 3 ] , args [ 4 ] , args [ 5 ] , args [ 6 ] ) ; } } quadraticCurveTo ( cpx , cpy , x , y ) { this . log ( 'quadraticCurveTo value:' , cpx , cpy , x , y ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . quadraticCurveTo ( cpx , cpy , x , y ) ; } rect ( x , y , width , height ) { this . log ( 'rect value:' , x , y , width , height ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . rect ( x , y , width , height ) ; } removeHitRegion ( id ) { } resetTransform ( ) { this . log ( 'resetTransform value:' ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . resetTransform ( ) ; } restore ( ) { this . log ( 'restore' ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . restore ( ) ; } rotate ( angle ) { this . log ( 'rotate value:' , angle ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . rotate ( angle ) ; } save ( ) { this . log ( 'save' ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . save ( ) ; } scale ( x , y ) { this . log ( 'scale value:' , x , y ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . scale ( x , y ) ; } scrollPathIntoView ( ) ; scrollPathIntoView ( path ) ; scrollPathIntoView ( path ? ) { } setLineDash ( segments ) { this . log ( 'setLineDash value:' , segments ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . setLineDash ( segments ) ; } setTransform ( a , b , c , d , e , f ) { this . log ( 'setTransform value:' , a , b , c , d , e , f ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . setTransform ( a , b , c , d , e , f ) ; } stroke ( ) ; stroke ( path ? ) { this . log ( 'stroke value:' , path ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( path ) { this . context . stroke ( path . native ) ; } else { this . context . stroke ( ) ; } } strokeRect ( x , y , width , height ) { this . log ( 'strokeRect value:' , x , y , width , height ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . strokeRect ( x , y , width , height ) ; } strokeText ( text , x , y , maxWidth ? ) { this . log ( 'strokeText value:' , text , x , y , maxWidth ) ; this . _ensureLayoutBeforeDraw ( ) ; if ( typeof maxWidth === 'number' ) { this . context . strokeText ( text , x , y , maxWidth ) ; } else { this . context . strokeText ( text , x , y ) ; } } transform ( a , b , c , d , e , f ) { this . log ( 'transform value:' , a , b , c , d , e , f ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . transform ( a , b , c , d , e , f ) ; } translate ( x , y ) { this . log ( 'translate value:' , x , y ) ; this . _ensureLayoutBeforeDraw ( ) ; this . context . translate ( x , y ) ; } private _ensureLayoutBeforeDraw ( ) { if ( this . canvas ) { this . canvas . _layoutNative ( ) ; } } private log ( message , ... args ) { if ( ! TNSCanvasRenderingContext2D . isDebug ) { return ; } console . log ( message , args ) ; } }