import { Color } from '../../common/colors' ; import { Rect } from '../../geoms/types' ; import { ClippedRanges } from '../../utils/geometry' ; internal export type CanvasRenderer = ( ctx : CanvasRenderingContext2D ) => void ; internal export function isCanvasRenderer ( thing ) { return thing instanceof Function ; } param ctx param fun internal export function withContext ( ctx , fun ) { ctx . save ( ) ; fun ( ctx ) ; ctx . restore ( ) ; } internal export function clearCanvas ( ctx , bgColor ) { withContext ( ctx , ( ) => { ctx . setTransform ( 1 , 0 , 0 , 1 , 0 , 0 ) ; ctx . clearRect ( 0 , 0 , ctx . canvas . width , ctx . canvas . height ) ; ctx . fillStyle = bgColor ; ctx . fillRect ( 0 , 0 , ctx . canvas . width , ctx . canvas . height ) ; } ) ; } internal export function renderLayers ( ctx , layers ) { layers . forEach ( ( renderLayer ) => renderLayer ( ctx ) ) ; } internal export function withClip ( ctx , clippings , fun , shouldClip = true ) { withContext ( ctx , ( ) => { if ( shouldClip ) { const { x , y , width , height } = clippings ; ctx . beginPath ( ) ; ctx . rect ( x , y , width , height ) ; ctx . clip ( ) ; } withContext ( ctx , ( ) => fun ( ctx ) ) ; } ) ; } internal export function withClipRanges ( ctx , clippedRanges , { width , height , y } , negate , fun ) { withContext ( ctx , ( ) => { if ( clippedRanges . length > 0 ) { ctx . beginPath ( ) ; if ( negate ) { clippedRanges . forEach ( ( [ x0 , x1 ] ) => ctx . rect ( x0 , y , x1 - x0 , height ) ) ; } else { const firstX = clippedRanges [ 0 ] [ 0 ] ; const lastX = clippedRanges [ clippedRanges . length - 1 ] [ 1 ] ; ctx . rect ( 0 , - 0.5 , firstX , height ) ; ctx . rect ( lastX , y , width - lastX , height ) ; clippedRanges . forEach ( ( [ , x0 ] , i ) => { if ( i < clippedRanges . length - 1 ) ctx . rect ( x0 , y , clippedRanges [ i + 1 ] [ 0 ] - x0 , height ) ; } ) ; } ctx . clip ( ) ; } fun ( ctx ) ; } ) ; }