import { Billboard, DisplayObject as AwayDisplayObject, SceneImage2D } from '@awayjs/scene'; import { DisplayObject } from './DisplayObject'; import { BitmapData } from './BitmapData'; import { ImageTexture2D } from '@awayjs/renderer'; import { IBitmapDataOwner } from './IBitmapDataOwner'; import { BitmapImage2D } from '@awayjs/stage'; import { Debug } from '@awayjs/core'; import { MaterialManager } from '@awayjs/graphics'; /** * The Bitmap class represents display objects that represent bitmap images. These can be images * that you load with the flash.display.Loader class, or they can be images that you create with * the Bitmap() constructor. * *

The * Bitmap() constructor allows you to create a Bitmap object that * contains a reference to a BitmapData object. After you create a Bitmap object, use the * addChild() or * addChildAt() method of the parent DisplayObjectContainer * instance to place the bitmap on the display list.

* A Bitmap object can share its BitmapData reference among several Bitmap objects, * independent of translation or rotation properties. Because you can create multiple Bitmap * objects that reference the same BitmapData object, multiple display objects can use the * same complex BitmapData object without incurring the memory overhead of a BitmapData * object for each display object instance.

* A BitmapData object can be drawn to the screen by a Bitmap object in one of two ways: * by using the vector renderer as a fill-bitmap shape, or by using a faster pixel-copying routine. * The pixel-copying routine is substantially faster than the vector renderer, but the Bitmap object * must meet certain conditions to use it:

If you load a Bitmap object from a domain other than that of the Loader object used to * load the image, and there is no URL policy file that permits access to the domain of * the Loader object, then a script in that domain cannot access the Bitmap * object or its properties and methods. For more information, see the Flash Player Developer Center Topic: * * Security.

Note: * The Bitmap class is not a subclass of the InteractiveObject class, so * it cannot dispatch mouse events. However, you can use the * addEventListener() method * of the display object container that contains the Bitmap object.

*/ export class Bitmap extends DisplayObject implements IBitmapDataOwner { private _texture: ImageTexture2D; private _bitmapData: BitmapData; private _bitmapMappedFromAsset: boolean; private static _bitmaps: Array = new Array(); public static getNewBitmap( bitmapData: BitmapData = null, pixelSnapping: string = 'auto', smoothing: boolean = false): Bitmap { if (Bitmap._bitmaps.length) { const bitmap: Bitmap = Bitmap._bitmaps.pop(); bitmap.adaptee = Billboard.getNewBillboard(MaterialManager.getMaterialForBitmap(), pixelSnapping, smoothing); bitmap.adaptee.style.image = bitmapData.adaptee; return bitmap; } return new Bitmap(bitmapData, pixelSnapping, smoothing); } /** * Initializes a Bitmap object to refer to the specified BitmapData object. * @param bitmapData The BitmapData object being referenced. * @param pixelSnapping Whether or not the Bitmap object is snapped to the nearest pixel. * @param smoothing Whether or not the bitmap is smoothed when scaled. For example, the * following examples show the same bitmap scaled by a factor of 3, with * smoothing set to false (left) and true (right): */ constructor(bitmapData: BitmapData = null, pixelSnapping: string = 'auto', smoothing: boolean = false) { super(); if (!this._bitmapData && bitmapData) this.bitmapData = bitmapData; this.pixelSnapping = pixelSnapping; this.smoothing = smoothing; } protected mapAdaptee(adaptee: AwayDisplayObject) { let mappedAdapt = adaptee; if (adaptee instanceof BitmapImage2D || adaptee instanceof SceneImage2D) { this._adaptee = mappedAdapt = Billboard.getNewBillboard(MaterialManager.getMaterialForBitmap(), 'auto', false); this._adaptee.style.image = adaptee; const bitmap = new ( this.sec).flash.display.BitmapData(adaptee); this.bitmapData = bitmap; this._bitmapMappedFromAsset = true; } return super.mapAdaptee(mappedAdapt); } protected createAdaptee(): AwayDisplayObject { const newAdaptee = Billboard.getNewBillboard(MaterialManager.getMaterialForBitmap()); return newAdaptee; } public clone(): Bitmap { const newInstance: Bitmap = Bitmap.getNewBitmap(this._bitmapData); this._adaptee.copyTo(newInstance.adaptee); return newInstance; } /** * @inheritDoc */ public dispose(): void { this.disposeValues(); Bitmap._bitmaps.push(this); } public disposeValues(): void { this.bitmapData = null; super.disposeValues(); } /** * The BitmapData object being referenced. */ public get bitmapData (): BitmapData { return this._bitmapData; } public set bitmapData (value: BitmapData) { if (this._bitmapData == value && this._bitmapData && this._bitmapData.adaptee === value.adaptee) return; if (this._bitmapData) this._bitmapData._removeOwner(this); this._bitmapData = value; if (this._bitmapData) this._bitmapData._addOwner(this); this.adaptee.style.image = this._bitmapData ? this._bitmapData.adaptee : null; } /** * Controls whether or not the Bitmap object is snapped to the nearest pixel. The PixelSnapping * class includes possible values: * * PixelSnapping.NEVER—No pixel snapping occurs.PixelSnapping.ALWAYS—The image is always snapped to the nearest * pixel, independent of transformation.PixelSnapping.AUTO—The image is snapped * to the nearest pixel if it is drawn with no rotation * or skew and it is drawn at a scale factor of 99.9% to 100.1%. If these conditions are satisfied, * the bitmap image is drawn at 100% scale, snapped to the nearest pixel. Internally, this value allows the image * to be drawn as fast as possible using the vector renderer. */ public get pixelSnapping (): string { return ''; } public set pixelSnapping (value: string) { // @todo Debug.throwPIR('playerglobals/display/Bitmap', 'set pixelSnapping', ''); } /** * Controls whether or not the bitmap is smoothed when scaled. If true, the bitmap is * smoothed when scaled. If false, the bitmap is not smoothed when scaled. */ public get smoothing (): boolean { return this.adaptee.style.sampler.smooth; } public set smoothing (value: boolean) { this.adaptee.style.sampler.smooth = value; } }