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:
* - No stretching, rotation, or skewing can be applied to the Bitmap object.
* - No color transform can be applied to the Bitmap object.
* - No blend mode can be applied to the Bitmap object.
* - No clipping can be done through mask layers or
* setMask() methods.
* - The image itself cannot be a mask.
* - The destination coordinates must be on a whole pixel boundary.
*
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;
}
}