Skip to content

Instantly share code, notes, and snippets.

@jgranick
Created April 25, 2018 14:23
Show Gist options
  • Save jgranick/b5b3b5ee066322d21cd2fd084ef8987b to your computer and use it in GitHub Desktop.
Save jgranick/b5b3b5ee066322d21cd2fd084ef8987b to your computer and use it in GitHub Desktop.
package openfl.display;
import lime.graphics.cairo.Cairo;
import lime.graphics.utils.ImageCanvasUtil;
import lime.ui.MouseCursor;
import lime.utils.ObjectPool;
import openfl._internal.renderer.cairo.CairoBitmap;
import openfl._internal.renderer.cairo.CairoDisplayObject;
import openfl._internal.renderer.cairo.CairoGraphics;
import openfl._internal.renderer.canvas.CanvasBitmap;
import openfl._internal.renderer.canvas.CanvasDisplayObject;
import openfl._internal.renderer.canvas.CanvasGraphics;
import openfl._internal.renderer.dom.DOMBitmap;
import openfl._internal.renderer.dom.DOMDisplayObject;
import openfl._internal.renderer.opengl.GLBitmap;
import openfl._internal.renderer.opengl.GLDisplayObject;
import openfl._internal.renderer.opengl.GLGraphics;
import openfl._internal.Lib;
import openfl.display.Stage;
import openfl.errors.TypeError;
import openfl.events.Event;
import openfl.events.EventPhase;
import openfl.events.EventDispatcher;
import openfl.events.MouseEvent;
import openfl.events.RenderEvent;
import openfl.events.TouchEvent;
import openfl.filters.BitmapFilter;
import openfl.geom.ColorTransform;
import openfl.geom.Matrix;
import openfl.geom.Point;
import openfl.geom.Rectangle;
import openfl.geom.Transform;
import openfl.Vector;
#if (js && html5)
import js.html.CanvasElement;
import js.html.CanvasRenderingContext2D;
import js.html.CSSStyleDeclaration;
import js.html.Element;
#end
#if !openfl_debug
@:fileXml('tags="haxe,release"')
@:noDebug
#end
@:access(lime.graphics.Image)
@:access(lime.graphics.ImageBuffer)
@:access(openfl._internal.renderer.opengl.GLGraphics)
@:access(openfl.events.Event)
@:access(openfl.display.Bitmap)
@:access(openfl.display.BitmapData)
@:access(openfl.display.DisplayObjectContainer)
@:access(openfl.display.Graphics)
@:access(openfl.display.Shader)
@:access(openfl.display.Stage)
@:access(openfl.filters.BitmapFilter)
@:access(openfl.geom.ColorTransform)
@:access(openfl.geom.Matrix)
@:access(openfl.geom.Rectangle)
/**
* The DisplayObject class is the base class for all objects that can be
* placed on the display list. The display list manages all objects displayed
* in openfl. Use the DisplayObjectContainer class to arrange the
* display objects in the display list. DisplayObjectContainer objects can
* have child display objects, while other display objects, such as Shape and
* TextField objects, are "leaf" nodes that have only parents and siblings, no
* children.
*
* The DisplayObject class supports basic functionality like the _x_
* and _y_ position of an object, as well as more advanced properties of
* the object such as its transformation matrix.
*
* DisplayObject is an abstract base class; therefore, you cannot call
* DisplayObject directly. Invoking `new DisplayObject()` throws an
* `ArgumentError` exception.
*
* All display objects inherit from the DisplayObject class.
*
* The DisplayObject class itself does not include any APIs for rendering
* content onscreen. For that reason, if you want create a custom subclass of
* the DisplayObject class, you will want to extend one of its subclasses that
* do have APIs for rendering content onscreen, such as the Shape, Sprite,
* Bitmap, SimpleButton, TextField, or MovieClip class.
*
* The DisplayObject class contains several broadcast events. Normally, the
* target of any particular event is a specific DisplayObject instance. For
* example, the target of an `added` event is the specific
* DisplayObject instance that was added to the display list. Having a single
* target restricts the placement of event listeners to that target and in
* some cases the target's ancestors on the display list. With broadcast
* events, however, the target is not a specific DisplayObject instance, but
* rather all DisplayObject instances, including those that are not on the
* display list. This means that you can add a listener to any DisplayObject
* instance to listen for broadcast events. In addition to the broadcast
* events listed in the DisplayObject class's Events table, the DisplayObject
* class also inherits two broadcast events from the EventDispatcher class:
* `activate` and `deactivate`.
*
* Some properties previously used in the ActionScript 1.0 and 2.0
* MovieClip, TextField, and Button classes(such as `_alpha`,
* `_height`, `_name`, `_width`,
* `_x`, `_y`, and others) have equivalents in the
* ActionScript 3.0 DisplayObject class that are renamed so that they no
* longer begin with the underscore(_) character.
*
* For more information, see the "Display Programming" chapter of the
* _ActionScript 3.0 Developer's Guide_.
*
* @event added Dispatched when a display object is added to the
* display list. The following methods trigger this
* event:
* `DisplayObjectContainer.addChild()`,
* `DisplayObjectContainer.addChildAt()`.
* @event addedToStage Dispatched when a display object is added to the on
* stage display list, either directly or through the
* addition of a sub tree in which the display object
* is contained. The following methods trigger this
* event:
* `DisplayObjectContainer.addChild()`,
* `DisplayObjectContainer.addChildAt()`.
* @event enterFrame [broadcast event] Dispatched when the playhead is
* entering a new frame. If the playhead is not
* moving, or if there is only one frame, this event
* is dispatched continuously in conjunction with the
* frame rate. This event is a broadcast event, which
* means that it is dispatched by all display objects
* with a listener registered for this event.
* @event exitFrame [broadcast event] Dispatched when the playhead is
* exiting the current frame. All frame scripts have
* been run. If the playhead is not moving, or if
* there is only one frame, this event is dispatched
* continuously in conjunction with the frame rate.
* This event is a broadcast event, which means that
* it is dispatched by all display objects with a
* listener registered for this event.
* @event frameConstructed [broadcast event] Dispatched after the constructors
* of frame display objects have run but before frame
* scripts have run. If the playhead is not moving, or
* if there is only one frame, this event is
* dispatched continuously in conjunction with the
* frame rate. This event is a broadcast event, which
* means that it is dispatched by all display objects
* with a listener registered for this event.
* @event removed Dispatched when a display object is about to be
* removed from the display list. Two methods of the
* DisplayObjectContainer class generate this event:
* `removeChild()` and
* `removeChildAt()`.
*
* The following methods of a
* DisplayObjectContainer object also generate this
* event if an object must be removed to make room for
* the new object: `addChild()`,
* `addChildAt()`, and
* `setChildIndex()`.
* @event removedFromStage Dispatched when a display object is about to be
* removed from the display list, either directly or
* through the removal of a sub tree in which the
* display object is contained. Two methods of the
* DisplayObjectContainer class generate this event:
* `removeChild()` and
* `removeChildAt()`.
*
* The following methods of a
* DisplayObjectContainer object also generate this
* event if an object must be removed to make room for
* the new object: `addChild()`,
* `addChildAt()`, and
* `setChildIndex()`.
* @event render [broadcast event] Dispatched when the display list
* is about to be updated and rendered. This event
* provides the last opportunity for objects listening
* for this event to make changes before the display
* list is rendered. You must call the
* `invalidate()` method of the Stage
* object each time you want a `render`
* event to be dispatched. `Render` events
* are dispatched to an object only if there is mutual
* trust between it and the object that called
* `Stage.invalidate()`. This event is a
* broadcast event, which means that it is dispatched
* by all display objects with a listener registered
* for this event.
*
* **Note: **This event is not dispatched if the
* display is not rendering. This is the case when the
* content is either minimized or obscured.
*/
extern class DisplayObject extends EventDispatcher implements IBitmapDrawable #if openfl_dynamic implements Dynamic<DisplayObject> #end {
private static var __broadcastEvents = new Map<String, Array<DisplayObject>> ();
private static var __initStage:Stage;
private static var __instanceCount = 0;
private static #if !js inline #end var __supportDOM:Bool #if !js = false #end;
private static var __tempColorTransform = new ColorTransform ();
private static var __tempStack = new ObjectPool<Vector<DisplayObject>> (function () { return new Vector<DisplayObject> (); }, function (stack) { stack.length = 0; });
/**
* Indicates the alpha transparency value of the object specified. Valid
* values are 0(fully transparent) to 1(fully opaque). The default value is
* 1. Display objects with `alpha` set to 0 _are_ active,
* even though they are invisible.
*/
public var alpha (get, set):Float;
/**
* A value from the BlendMode class that specifies which blend mode to use. A
* bitmap can be drawn internally in two ways. If you have a blend mode
* enabled or an external clipping mask, the bitmap is drawn by adding a
* bitmap-filled square shape to the vector render. If you attempt to set
* this property to an invalid value, Flash runtimes set the value to
* `BlendMode.NORMAL`.
*
* The `blendMode` property affects each pixel of the display
* object. Each pixel is composed of three constituent colors(red, green,
* and blue), and each constituent color has a value between 0x00 and 0xFF.
* Flash Player or Adobe AIR compares each constituent color of one pixel in
* the movie clip with the corresponding color of the pixel in the
* background. For example, if `blendMode` is set to
* `BlendMode.LIGHTEN`, Flash Player or Adobe AIR compares the red
* value of the display object with the red value of the background, and uses
* the lighter of the two as the value for the red component of the displayed
* color.
*
* The following table describes the `blendMode` settings. The
* BlendMode class defines string values you can use. The illustrations in
* the table show `blendMode` values applied to a circular display
* object(2) superimposed on another display object(1).
*/
public var blendMode (get, set):BlendMode;
/**
* All vector data for a display object that has a cached bitmap is drawn
* to the bitmap instead of the main display. If
* `cacheAsBitmapMatrix` is null or unsupported, the bitmap is
* then copied to the main display as unstretched, unrotated pixels snapped
* to the nearest pixel boundaries. Pixels are mapped 1 to 1 with the parent
* object. If the bounds of the bitmap change, the bitmap is recreated
* instead of being stretched.
*
* If `cacheAsBitmapMatrix` is non-null and supported, the
* object is drawn to the off-screen bitmap using that matrix and the
* stretched and/or rotated results of that rendering are used to draw the
* object to the main display.
*
* No internal bitmap is created unless the `cacheAsBitmap`
* property is set to `true`.
*
* After you set the `cacheAsBitmap` property to
* `true`, the rendering does not change, however the display
* object performs pixel snapping automatically. The animation speed can be
* significantly faster depending on the complexity of the vector content.
*
*
* The `cacheAsBitmap` property is automatically set to
* `true` whenever you apply a filter to a display object(when
* its `filter` array is not empty), and if a display object has a
* filter applied to it, `cacheAsBitmap` is reported as
* `true` for that display object, even if you set the property to
* `false`. If you clear all filters for a display object, the
* `cacheAsBitmap` setting changes to what it was last set to.
*
* A display object does not use a bitmap even if the
* `cacheAsBitmap` property is set to `true` and
* instead renders from vector data in the following cases:
*
*
* * The bitmap is too large. In AIR 1.5 and Flash Player 10, the maximum
* size for a bitmap image is 8,191 pixels in width or height, and the total
* number of pixels cannot exceed 16,777,215 pixels.(So, if a bitmap image
* is 8,191 pixels wide, it can only be 2,048 pixels high.) In Flash Player 9
* and earlier, the limitation is is 2880 pixels in height and 2,880 pixels
* in width.
* * The bitmap fails to allocate(out of memory error).
*
*
* The `cacheAsBitmap` property is best used with movie clips
* that have mostly static content and that do not scale and rotate
* frequently. With such movie clips, `cacheAsBitmap` can lead to
* performance increases when the movie clip is translated(when its _x_
* and _y_ position is changed).
*/
public var cacheAsBitmap (get, set):Bool;
public var cacheAsBitmapMatrix (get, set):Matrix;
/**
* An indexed array that contains each filter object currently associated
* with the display object. The openfl.filters package contains several
* classes that define specific filters you can use.
*
* Filters can be applied in Flash Professional at design time, or at run
* time by using ActionScript code. To apply a filter by using ActionScript,
* you must make a temporary copy of the entire `filters` array,
* modify the temporary array, then assign the value of the temporary array
* back to the `filters` array. You cannot directly add a new
* filter object to the `filters` array.
*
* To add a filter by using ActionScript, perform the following steps
* (assume that the target display object is named
* `myDisplayObject`):
*
* 1. Create a new filter object by using the constructor method of your
* chosen filter class.
* 2. Assign the value of the `myDisplayObject.filters` array
* to a temporary array, such as one named `myFilters`.
* 3. Add the new filter object to the `myFilters` temporary
* array.
* 4. Assign the value of the temporary array to the
* `myDisplayObject.filters` array.
*
* If the `filters` array is undefined, you do not need to use
* a temporary array. Instead, you can directly assign an array literal that
* contains one or more filter objects that you create. The first example in
* the Examples section adds a drop shadow filter by using code that handles
* both defined and undefined `filters` arrays.
*
* To modify an existing filter object, you must use the technique of
* modifying a copy of the `filters` array:
*
* 1. Assign the value of the `filters` array to a temporary
* array, such as one named `myFilters`.
* 2. Modify the property by using the temporary array,
* `myFilters`. For example, to set the quality property of the
* first filter in the array, you could use the following code:
* `myFilters[0].quality = 1;`
* 3. Assign the value of the temporary array to the `filters`
* array.
*
* At load time, if a display object has an associated filter, it is
* marked to cache itself as a transparent bitmap. From this point forward,
* as long as the display object has a valid filter list, the player caches
* the display object as a bitmap. This source bitmap is used as a source
* image for the filter effects. Each display object usually has two bitmaps:
* one with the original unfiltered source display object and another for the
* final image after filtering. The final image is used when rendering. As
* long as the display object does not change, the final image does not need
* updating.
*
* The openfl.filters package includes classes for filters. For example, to
* create a DropShadow filter, you would write:
*
* @throws ArgumentError When `filters` includes a ShaderFilter
* and the shader output type is not compatible with
* this operation(the shader must specify a
* `pixel4` output).
* @throws ArgumentError When `filters` includes a ShaderFilter
* and the shader doesn't specify any image input or
* the first input is not an `image4` input.
* @throws ArgumentError When `filters` includes a ShaderFilter
* and the shader specifies an image input that isn't
* provided.
* @throws ArgumentError When `filters` includes a ShaderFilter, a
* ByteArray or Vector.<Number> instance as a shader
* input, and the `width` and
* `height` properties aren't specified for
* the ShaderInput object, or the specified values
* don't match the amount of data in the input data.
* See the `ShaderInput.input` property for
* more information.
*/
public var filters (get, set):Array<BitmapFilter>;
/**
* Indicates the height of the display object, in pixels. The height is
* calculated based on the bounds of the content of the display object. When
* you set the `height` property, the `scaleY` property
* is adjusted accordingly, as shown in the following code:
*
* Except for TextField and Video objects, a display object with no
* content(such as an empty sprite) has a height of 0, even if you try to
* set `height` to a different value.
*/
public var height (get, set):Float;
/**
* Returns a LoaderInfo object containing information about loading the file
* to which this display object belongs. The `loaderInfo` property
* is defined only for the root display object of a SWF file or for a loaded
* Bitmap(not for a Bitmap that is drawn with ActionScript). To find the
* `loaderInfo` object associated with the SWF file that contains
* a display object named `myDisplayObject`, use
* `myDisplayObject.root.loaderInfo`.
*
* A large SWF file can monitor its download by calling
* `this.root.loaderInfo.addEventListener(Event.COMPLETE,
* func)`.
*/
public var loaderInfo (get, never):LoaderInfo;
/**
* The calling display object is masked by the specified `mask`
* object. To ensure that masking works when the Stage is scaled, the
* `mask` display object must be in an active part of the display
* list. The `mask` object itself is not drawn. Set
* `mask` to `null` to remove the mask.
*
* To be able to scale a mask object, it must be on the display list. To
* be able to drag a mask Sprite object(by calling its
* `startDrag()` method), it must be on the display list. To call
* the `startDrag()` method for a mask sprite based on a
* `mouseDown` event being dispatched by the sprite, set the
* sprite's `buttonMode` property to `true`.
*
* When display objects are cached by setting the
* `cacheAsBitmap` property to `true` an the
* `cacheAsBitmapMatrix` property to a Matrix object, both the
* mask and the display object being masked must be part of the same cached
* bitmap. Thus, if the display object is cached, then the mask must be a
* child of the display object. If an ancestor of the display object on the
* display list is cached, then the mask must be a child of that ancestor or
* one of its descendents. If more than one ancestor of the masked object is
* cached, then the mask must be a descendent of the cached container closest
* to the masked object in the display list.
*
* **Note:** A single `mask` object cannot be used to mask
* more than one calling display object. When the `mask` is
* assigned to a second display object, it is removed as the mask of the
* first object, and that object's `mask` property becomes
* `null`.
*/
public var mask (get, set):DisplayObject;
/**
* Indicates the x coordinate of the mouse or user input device position, in
* pixels.
*
* **Note**: For a DisplayObject that has been rotated, the returned x
* coordinate will reflect the non-rotated object.
*/
public var mouseX (get, never):Float;
/**
* Indicates the y coordinate of the mouse or user input device position, in
* pixels.
*
* **Note**: For a DisplayObject that has been rotated, the returned y
* coordinate will reflect the non-rotated object.
*/
public var mouseY (get, never):Float;
/**
* Indicates the instance name of the DisplayObject. The object can be
* identified in the child list of its parent display object container by
* calling the `getChildByName()` method of the display object
* container.
*
* @throws IllegalOperationError If you are attempting to set this property
* on an object that was placed on the timeline
* in the Flash authoring tool.
*/
public var name (get, set):String;
/**
* Specifies whether the display object is opaque with a certain background
* color. A transparent bitmap contains alpha channel data and is drawn
* transparently. An opaque bitmap has no alpha channel(and renders faster
* than a transparent bitmap). If the bitmap is opaque, you specify its own
* background color to use.
*
* If set to a number value, the surface is opaque(not transparent) with
* the RGB background color that the number specifies. If set to
* `null`(the default value), the display object has a
* transparent background.
*
* The `opaqueBackground` property is intended mainly for use
* with the `cacheAsBitmap` property, for rendering optimization.
* For display objects in which the `cacheAsBitmap` property is
* set to true, setting `opaqueBackground` can improve rendering
* performance.
*
* The opaque background region is _not_ matched when calling the
* `hitTestPoint()` method with the `shapeFlag`
* parameter set to `true`.
*
* The opaque background region does not respond to mouse events.
*/
public var opaqueBackground:Null<UInt>;
/**
* Indicates the DisplayObjectContainer object that contains this display
* object. Use the `parent` property to specify a relative path to
* display objects that are above the current display object in the display
* list hierarchy.
*
* You can use `parent` to move up multiple levels in the
* display list as in the following:
*
* @throws SecurityError The parent display object belongs to a security
* sandbox to which you do not have access. You can
* avoid this situation by having the parent movie call
* the `Security.allowDomain()` method.
*/
public var parent (default, null):DisplayObjectContainer;
/**
* For a display object in a loaded SWF file, the `root` property
* is the top-most display object in the portion of the display list's tree
* structure represented by that SWF file. For a Bitmap object representing a
* loaded image file, the `root` property is the Bitmap object
* itself. For the instance of the main class of the first SWF file loaded,
* the `root` property is the display object itself. The
* `root` property of the Stage object is the Stage object itself.
* The `root` property is set to `null` for any display
* object that has not been added to the display list, unless it has been
* added to a display object container that is off the display list but that
* is a child of the top-most display object in a loaded SWF file.
*
* For example, if you create a new Sprite object by calling the
* `Sprite()` constructor method, its `root` property
* is `null` until you add it to the display list(or to a display
* object container that is off the display list but that is a child of the
* top-most display object in a SWF file).
*
* For a loaded SWF file, even though the Loader object used to load the
* file may not be on the display list, the top-most display object in the
* SWF file has its `root` property set to itself. The Loader
* object does not have its `root` property set until it is added
* as a child of a display object for which the `root` property is
* set.
*/
public var root (get, never):DisplayObject;
/**
* Indicates the rotation of the DisplayObject instance, in degrees, from its
* original orientation. Values from 0 to 180 represent clockwise rotation;
* values from 0 to -180 represent counterclockwise rotation. Values outside
* this range are added to or subtracted from 360 to obtain a value within
* the range. For example, the statement `my_video.rotation = 450`
* is the same as ` my_video.rotation = 90`.
*/
public var rotation (get, set):Float;
/**
* The current scaling grid that is in effect. If set to `null`,
* the entire display object is scaled normally when any scale transformation
* is applied.
*
* When you define the `scale9Grid` property, the display
* object is divided into a grid with nine regions based on the
* `scale9Grid` rectangle, which defines the center region of the
* grid. The eight other regions of the grid are the following areas:
*
*
* * The upper-left corner outside of the rectangle
* * The area above the rectangle
* * The upper-right corner outside of the rectangle
* * The area to the left of the rectangle
* * The area to the right of the rectangle
* * The lower-left corner outside of the rectangle
* * The area below the rectangle
* * The lower-right corner outside of the rectangle
*
*
* You can think of the eight regions outside of the center(defined by
* the rectangle) as being like a picture frame that has special rules
* applied to it when scaled.
*
* When the `scale9Grid` property is set and a display object
* is scaled, all text and gradients are scaled normally; however, for other
* types of objects the following rules apply:
*
*
* * Content in the center region is scaled normally.
* * Content in the corners is not scaled.
* * Content in the top and bottom regions is scaled horizontally only.
* Content in the left and right regions is scaled vertically only.
* * All fills(including bitmaps, video, and gradients) are stretched to
* fit their shapes.
*
*
* If a display object is rotated, all subsequent scaling is normal(and
* the `scale9Grid` property is ignored).
*
* For example, consider the following display object and a rectangle that
* is applied as the display object's `scale9Grid`:
*
* A common use for setting `scale9Grid` is to set up a display
* object to be used as a component, in which edge regions retain the same
* width when the component is scaled.
*
* @throws ArgumentError If you pass an invalid argument to the method.
*/
public var scale9Grid:Rectangle;
/**
* Indicates the horizontal scale(percentage) of the object as applied from
* the registration point. The default registration point is(0,0). 1.0
* equals 100% scale.
*
* Scaling the local coordinate system changes the `x` and
* `y` property values, which are defined in whole pixels.
*/
public var scaleX (get, set):Float;
/**
* Indicates the vertical scale(percentage) of an object as applied from the
* registration point of the object. The default registration point is(0,0).
* 1.0 is 100% scale.
*
* Scaling the local coordinate system changes the `x` and
* `y` property values, which are defined in whole pixels.
*/
public var scaleY (get, set):Float;
/**
* The scroll rectangle bounds of the display object. The display object is
* cropped to the size defined by the rectangle, and it scrolls within the
* rectangle when you change the `x` and `y` properties
* of the `scrollRect` object.
*
* The properties of the `scrollRect` Rectangle object use the
* display object's coordinate space and are scaled just like the overall
* display object. The corner bounds of the cropped window on the scrolling
* display object are the origin of the display object(0,0) and the point
* defined by the width and height of the rectangle. They are not centered
* around the origin, but use the origin to define the upper-left corner of
* the area. A scrolled display object always scrolls in whole pixel
* increments.
*
* You can scroll an object left and right by setting the `x`
* property of the `scrollRect` Rectangle object. You can scroll
* an object up and down by setting the `y` property of the
* `scrollRect` Rectangle object. If the display object is rotated
* 90° and you scroll it left and right, the display object actually scrolls
* up and down.
*/
public var scrollRect (get, set):Rectangle;
@:beta public var shader (get, set):Shader;
/**
* The Stage of the display object. A Flash runtime application has only one
* Stage object. For example, you can create and load multiple display
* objects into the display list, and the `stage` property of each
* display object refers to the same Stage object(even if the display object
* belongs to a loaded SWF file).
*
* If a display object is not added to the display list, its
* `stage` property is set to `null`.
*/
public var stage (default, null):Stage;
/**
* An object with properties pertaining to a display object's matrix, color
* transform, and pixel bounds. The specific properties - matrix,
* colorTransform, and three read-only properties
* (`concatenatedMatrix`, `concatenatedColorTransform`,
* and `pixelBounds`) - are described in the entry for the
* Transform class.
*
* Each of the transform object's properties is itself an object. This
* concept is important because the only way to set new values for the matrix
* or colorTransform objects is to create a new object and copy that object
* into the transform.matrix or transform.colorTransform property.
*
* For example, to increase the `tx` value of a display
* object's matrix, you must make a copy of the entire matrix object, then
* copy the new object into the matrix property of the transform object:
* ` var myMatrix:Matrix =
* myDisplayObject.transform.matrix; myMatrix.tx += 10;
* myDisplayObject.transform.matrix = myMatrix; `
*
* You cannot directly set the `tx` property. The following
* code has no effect on `myDisplayObject`:
* ` myDisplayObject.transform.matrix.tx +=
* 10; `
*
* You can also copy an entire transform object and assign it to another
* display object's transform property. For example, the following code
* copies the entire transform object from `myOldDisplayObj` to
* `myNewDisplayObj`:
* `myNewDisplayObj.transform = myOldDisplayObj.transform;`
*
* The resulting display object, `myNewDisplayObj`, now has the
* same values for its matrix, color transform, and pixel bounds as the old
* display object, `myOldDisplayObj`.
*
* Note that AIR for TV devices use hardware acceleration, if it is
* available, for color transforms.
*/
public var transform (get, set):Transform;
/**
* Whether or not the display object is visible. Display objects that are not
* visible are disabled. For example, if `visible=false` for an
* InteractiveObject instance, it cannot be clicked.
*/
public var visible (get, set):Bool;
/**
* Indicates the width of the display object, in pixels. The width is
* calculated based on the bounds of the content of the display object. When
* you set the `width` property, the `scaleX` property
* is adjusted accordingly, as shown in the following code:
*
* Except for TextField and Video objects, a display object with no
* content(such as an empty sprite) has a width of 0, even if you try to set
* `width` to a different value.
*/
public var width (get, set):Float;
/**
* Indicates the _x_ coordinate of the DisplayObject instance relative
* to the local coordinates of the parent DisplayObjectContainer. If the
* object is inside a DisplayObjectContainer that has transformations, it is
* in the local coordinate system of the enclosing DisplayObjectContainer.
* Thus, for a DisplayObjectContainer rotated 90° counterclockwise, the
* DisplayObjectContainer's children inherit a coordinate system that is
* rotated 90° counterclockwise. The object's coordinates refer to the
* registration point position.
*/
public var x (get, set):Float;
/**
* Indicates the _y_ coordinate of the DisplayObject instance relative
* to the local coordinates of the parent DisplayObjectContainer. If the
* object is inside a DisplayObjectContainer that has transformations, it is
* in the local coordinate system of the enclosing DisplayObjectContainer.
* Thus, for a DisplayObjectContainer rotated 90° counterclockwise, the
* DisplayObjectContainer's children inherit a coordinate system that is
* rotated 90° counterclockwise. The object's coordinates refer to the
* registration point position.
*/
public var y (get, set):Float;
#if openfljs
private static function __init__ () {
untyped Object.defineProperties (DisplayObject.prototype, {
"alpha": { get: untyped __js__ ("function () { return this.get_alpha (); }"), set: untyped __js__ ("function (v) { return this.set_alpha (v); }") },
"blendMode": { get: untyped __js__ ("function () { return this.get_blendMode (); }"), set: untyped __js__ ("function (v) { return this.set_blendMode (v); }") },
"cacheAsBitmap": { get: untyped __js__ ("function () { return this.get_cacheAsBitmap (); }"), set: untyped __js__ ("function (v) { return this.set_cacheAsBitmap (v); }") },
"cacheAsBitmapMatrix": { get: untyped __js__ ("function () { return this.get_cacheAsBitmapMatrix (); }"), set: untyped __js__ ("function (v) { return this.set_cacheAsBitmapMatrix (v); }") },
"filters": { get: untyped __js__ ("function () { return this.get_filters (); }"), set: untyped __js__ ("function (v) { return this.set_filters (v); }") },
"height": { get: untyped __js__ ("function () { return this.get_height (); }"), set: untyped __js__ ("function (v) { return this.set_height (v); }") },
"loaderInfo": { get: untyped __js__ ("function () { return this.get_loaderInfo (); }") },
"mask": { get: untyped __js__ ("function () { return this.get_mask (); }"), set: untyped __js__ ("function (v) { return this.set_mask (v); }") },
"mouseX": { get: untyped __js__ ("function () { return this.get_mouseX (); }") },
"mouseY": { get: untyped __js__ ("function () { return this.get_mouseY (); }") },
"name": { get: untyped __js__ ("function () { return this.get_name (); }"), set: untyped __js__ ("function (v) { return this.set_name (v); }") },
"root": { get: untyped __js__ ("function () { return this.get_root (); }") },
"rotation": { get: untyped __js__ ("function () { return this.get_rotation (); }"), set: untyped __js__ ("function (v) { return this.set_rotation (v); }") },
"scaleX": { get: untyped __js__ ("function () { return this.get_scaleX (); }"), set: untyped __js__ ("function (v) { return this.set_scaleX (v); }") },
"scaleY": { get: untyped __js__ ("function () { return this.get_scaleY (); }"), set: untyped __js__ ("function (v) { return this.set_scaleY (v); }") },
"scrollRect": { get: untyped __js__ ("function () { return this.get_scrollRect (); }"), set: untyped __js__ ("function (v) { return this.set_scrollRect (v); }") },
"shader": { get: untyped __js__ ("function () { return this.get_shader (); }"), set: untyped __js__ ("function (v) { return this.set_shader (v); }") },
"transform": { get: untyped __js__ ("function () { return this.get_transform (); }"), set: untyped __js__ ("function (v) { return this.set_transform (v); }") },
"visible": { get: untyped __js__ ("function () { return this.get_visible (); }"), set: untyped __js__ ("function (v) { return this.set_visible (v); }") },
"width": { get: untyped __js__ ("function () { return this.get_width (); }"), set: untyped __js__ ("function (v) { return this.set_width (v); }") },
"x": { get: untyped __js__ ("function () { return this.get_x (); }"), set: untyped __js__ ("function (v) { return this.set_x (v); }") },
"y": { get: untyped __js__ ("function () { return this.get_y (); }"), set: untyped __js__ ("function (v) { return this.set_y (v); }") },
});
}
#end
private function new () {
super ();
if (__initStage != null) {
this.stage = __initStage;
__initStage = null;
}
__alpha = 1;
__blendMode = NORMAL;
__cacheAsBitmap = false;
__transform = new Matrix ();
__visible = true;
__rotation = 0;
__rotationSine = 0;
__rotationCosine = 1;
__scaleX = 1;
__scaleY = 1;
__worldAlpha = 1;
__worldBlendMode = NORMAL;
__worldTransform = new Matrix ();
__worldColorTransform = new ColorTransform ();
__renderTransform = new Matrix ();
__worldVisible = true;
name = "instance" + (++__instanceCount);
}
public override function addEventListener (type:String, listener:Dynamic->Void, useCapture:Bool = false, priority:Int = 0, useWeakReference:Bool = false):Void {
switch (type) {
case Event.ACTIVATE, Event.DEACTIVATE, Event.ENTER_FRAME, Event.EXIT_FRAME, Event.FRAME_CONSTRUCTED, Event.RENDER:
if (!__broadcastEvents.exists (type)) {
__broadcastEvents.set (type, []);
}
var dispatchers = __broadcastEvents.get (type);
if (dispatchers.indexOf (this) == -1) {
dispatchers.push (this);
}
case RenderEvent.CLEAR_DOM, RenderEvent.RENDER_CAIRO, RenderEvent.RENDER_CANVAS, RenderEvent.RENDER_DOM, RenderEvent.RENDER_OPENGL:
if (__customRenderEvent == null) {
__customRenderEvent = new RenderEvent (null);
__customRenderEvent.objectColorTransform = new ColorTransform ();
__customRenderEvent.objectMatrix = new Matrix ();
__customRenderClear = true;
}
default:
}
super.addEventListener (type, listener, useCapture, priority, useWeakReference);
}
public override function dispatchEvent (event:Event):Bool {
if (Std.is (event, MouseEvent)) {
var mouseEvent:MouseEvent = cast event;
mouseEvent.stageX = __getRenderTransform ().__transformX (mouseEvent.localX, mouseEvent.localY);
mouseEvent.stageY = __getRenderTransform ().__transformY (mouseEvent.localX, mouseEvent.localY);
} else if (Std.is (event, TouchEvent)) {
var touchEvent:TouchEvent = cast event;
touchEvent.stageX = __getRenderTransform ().__transformX (touchEvent.localX, touchEvent.localY);
touchEvent.stageY = __getRenderTransform ().__transformY (touchEvent.localX, touchEvent.localY);
}
return __dispatchWithCapture (event);
}
/**
* Returns a rectangle that defines the area of the display object relative
* to the coordinate system of the `targetCoordinateSpace` object.
* Consider the following code, which shows how the rectangle returned can
* vary depending on the `targetCoordinateSpace` parameter that
* you pass to the method:
*
* **Note:** Use the `localToGlobal()` and
* `globalToLocal()` methods to convert the display object's local
* coordinates to display coordinates, or display coordinates to local
* coordinates, respectively.
*
* The `getBounds()` method is similar to the
* `getRect()` method; however, the Rectangle returned by the
* `getBounds()` method includes any strokes on shapes, whereas
* the Rectangle returned by the `getRect()` method does not. For
* an example, see the description of the `getRect()` method.
*
* @param targetCoordinateSpace The display object that defines the
* coordinate system to use.
* @return The rectangle that defines the area of the display object relative
* to the `targetCoordinateSpace` object's coordinate
* system.
*/
public function getBounds (targetCoordinateSpace:DisplayObject):Rectangle {
var matrix = Matrix.__pool.get ();
if (targetCoordinateSpace != null && targetCoordinateSpace != this) {
matrix.copyFrom (__getWorldTransform ());
var targetMatrix = Matrix.__pool.get ();
targetMatrix.copyFrom (targetCoordinateSpace.__getWorldTransform ());
targetMatrix.invert ();
matrix.concat (targetMatrix);
Matrix.__pool.release (targetMatrix);
} else {
matrix.identity ();
}
var bounds = new Rectangle ();
__getBounds (bounds, matrix);
Matrix.__pool.release (matrix);
return bounds;
}
/**
* Returns a rectangle that defines the boundary of the display object, based
* on the coordinate system defined by the `targetCoordinateSpace`
* parameter, excluding any strokes on shapes. The values that the
* `getRect()` method returns are the same or smaller than those
* returned by the `getBounds()` method.
*
* **Note:** Use `localToGlobal()` and
* `globalToLocal()` methods to convert the display object's local
* coordinates to Stage coordinates, or Stage coordinates to local
* coordinates, respectively.
*
* @param targetCoordinateSpace The display object that defines the
* coordinate system to use.
* @return The rectangle that defines the area of the display object relative
* to the `targetCoordinateSpace` object's coordinate
* system.
*/
public function getRect (targetCoordinateSpace:DisplayObject):Rectangle {
// should not account for stroke widths, but is that possible?
return getBounds (targetCoordinateSpace);
}
/**
* Converts the `point` object from the Stage(global) coordinates
* to the display object's(local) coordinates.
*
* To use this method, first create an instance of the Point class. The
* _x_ and _y_ values that you assign represent global coordinates
* because they relate to the origin(0,0) of the main display area. Then
* pass the Point instance as the parameter to the
* `globalToLocal()` method. The method returns a new Point object
* with _x_ and _y_ values that relate to the origin of the display
* object instead of the origin of the Stage.
*
* @param point An object created with the Point class. The Point object
* specifies the _x_ and _y_ coordinates as
* properties.
* @return A Point object with coordinates relative to the display object.
*/
public function globalToLocal (pos:Point):Point {
return __globalToLocal (pos, new Point ());
}
/**
* Evaluates the bounding box of the display object to see if it overlaps or
* intersects with the bounding box of the `obj` display object.
*
* @param obj The display object to test against.
* @return `true` if the bounding boxes of the display objects
* intersect; `false` if not.
*/
public function hitTestObject (obj:DisplayObject):Bool {
if (obj != null && obj.parent != null && parent != null) {
var currentBounds = getBounds (this);
var targetBounds = obj.getBounds (this);
return currentBounds.intersects (targetBounds);
}
return false;
}
/**
* Evaluates the display object to see if it overlaps or intersects with the
* point specified by the `x` and `y` parameters. The
* `x` and `y` parameters specify a point in the
* coordinate space of the Stage, not the display object container that
* contains the display object(unless that display object container is the
* Stage).
*
* @param x The _x_ coordinate to test against this object.
* @param y The _y_ coordinate to test against this object.
* @param shapeFlag Whether to check against the actual pixels of the object
* (`true`) or the bounding box
* (`false`).
* @return `true` if the display object overlaps or intersects
* with the specified point; `false` otherwise.
*/
public function hitTestPoint (x:Float, y:Float, shapeFlag:Bool = false):Bool {
if (stage != null) {
return __hitTest (x, y, shapeFlag, null, true, this);
} else {
return false;
}
}
/**
* Calling the `invalidate()` method signals to have the current object
* redrawn the next time the object is eligible to be rendered.
**/
public function invalidate ():Void {
__setRenderDirty ();
}
/**
* Converts the `point` object from the display object's(local)
* coordinates to the Stage(global) coordinates.
*
* This method allows you to convert any given _x_ and _y_
* coordinates from values that are relative to the origin(0,0) of a
* specific display object(local coordinates) to values that are relative to
* the origin of the Stage(global coordinates).
*
* To use this method, first create an instance of the Point class. The
* _x_ and _y_ values that you assign represent local coordinates
* because they relate to the origin of the display object.
*
* You then pass the Point instance that you created as the parameter to
* the `localToGlobal()` method. The method returns a new Point
* object with _x_ and _y_ values that relate to the origin of the
* Stage instead of the origin of the display object.
*
* @param point The name or identifier of a point created with the Point
* class, specifying the _x_ and _y_ coordinates as
* properties.
* @return A Point object with coordinates relative to the Stage.
*/
public function localToGlobal (point:Point):Point {
return __getRenderTransform ().transformPoint (point);
}
public override function removeEventListener (type:String, listener:Dynamic->Void, useCapture:Bool = false):Void {
super.removeEventListener (type, listener, useCapture);
switch (type) {
case Event.ACTIVATE, Event.DEACTIVATE, Event.ENTER_FRAME, Event.EXIT_FRAME, Event.FRAME_CONSTRUCTED, Event.RENDER:
if (!hasEventListener (type)) {
if (__broadcastEvents.exists (type)) {
__broadcastEvents.get (type).remove (this);
}
}
case RenderEvent.CLEAR_DOM, RenderEvent.RENDER_CAIRO, RenderEvent.RENDER_CANVAS, RenderEvent.RENDER_DOM, RenderEvent.RENDER_OPENGL:
if (!hasEventListener (RenderEvent.CLEAR_DOM) && !hasEventListener (RenderEvent.RENDER_CAIRO) && !hasEventListener (RenderEvent.RENDER_CANVAS) && !hasEventListener (RenderEvent.RENDER_DOM) && !hasEventListener (RenderEvent.RENDER_OPENGL)) {
__customRenderEvent = null;
}
default:
}
}
private static inline function __calculateAbsoluteTransform (local:Matrix, parentTransform:Matrix, target:Matrix):Void {
target.a = local.a * parentTransform.a + local.b * parentTransform.c;
target.b = local.a * parentTransform.b + local.b * parentTransform.d;
target.c = local.c * parentTransform.a + local.d * parentTransform.c;
target.d = local.c * parentTransform.b + local.d * parentTransform.d;
target.tx = local.tx * parentTransform.a + local.ty * parentTransform.c + parentTransform.tx;
target.ty = local.tx * parentTransform.b + local.ty * parentTransform.d + parentTransform.ty;
}
private function __cleanup ():Void {
__cairo = null;
#if (js && html5)
__canvas = null;
__context = null;
#end
if (__graphics != null) {
__graphics.__cleanup ();
}
}
private function __dispatch (event:Event):Bool {
if (__eventMap != null && hasEventListener (event.type)) {
var result = super.__dispatchEvent (event);
if (event.__isCanceled) {
return true;
}
return result;
}
return true;
}
private function __dispatchChildren (event:Event):Void {
}
private override function __dispatchEvent (event:Event):Bool {
var parent = event.bubbles ? this.parent : null;
var result = super.__dispatchEvent (event);
if (event.__isCanceled) {
return true;
}
if (parent != null && parent != this) {
event.eventPhase = EventPhase.BUBBLING_PHASE;
if (event.target == null) {
event.target = this;
}
parent.__dispatchEvent (event);
}
return result;
}
private function __dispatchWithCapture (event:Event):Bool {
if (event.target == null) {
event.target = this;
}
if (parent != null) {
event.eventPhase = CAPTURING_PHASE;
if (parent == stage) {
parent.__dispatch (event);
} else {
var stack = __tempStack.get ();
var parent = parent;
var i = 0;
while (parent != null) {
stack[i] = parent;
parent = parent.parent;
i++;
}
for (j in 0...i) {
stack[i - j - 1].__dispatch (event);
}
__tempStack.release (stack);
}
}
event.eventPhase = AT_TARGET;
return __dispatchEvent (event);
}
private function __enterFrame (deltaTime:Int):Void {
}
private function __getBounds (rect:Rectangle, matrix:Matrix):Void {
if (__graphics != null) {
__graphics.__getBounds (rect, matrix);
}
}
private function __getCursor ():MouseCursor {
return null;
}
private function __getFilterBounds (rect:Rectangle, matrix:Matrix):Void {
// TODO: Should this be __getRenderBounds, to account for scrollRect?
__getBounds (rect, matrix);
if (__filters != null) {
var extension = Rectangle.__pool.get ();
for (filter in __filters) {
extension.__expand (-filter.__leftExtension, -filter.__topExtension, filter.__leftExtension + filter.__rightExtension, filter.__topExtension + filter.__bottomExtension);
}
rect.width += extension.width;
rect.height += extension.height;
rect.x += extension.x;
rect.y += extension.y;
Rectangle.__pool.release (extension);
}
}
private function __getInteractive (stack:Array<DisplayObject>):Bool {
return false;
}
private function __getLocalBounds (rect:Rectangle):Void {
//var cacheX = __transform.tx;
//var cacheY = __transform.ty;
//__transform.tx = __transform.ty = 0;
__getBounds (rect, __transform);
//__transform.tx = cacheX;
//__transform.ty = cacheY;
rect.x -= __transform.tx;
rect.y -= __transform.ty;
}
private function __getRenderBounds (rect:Rectangle, matrix:Matrix):Void {
if (__scrollRect == null) {
__getBounds (rect, matrix);
} else {
var r = Rectangle.__pool.get ();
r.copyFrom (__scrollRect);
r.__transform (r, matrix);
rect.__expand (matrix.tx, matrix.ty, r.width, r.height);
Rectangle.__pool.release (r);
}
}
private function __getRenderTransform ():Matrix {
__getWorldTransform ();
return __renderTransform;
}
private function __getWorldTransform ():Matrix {
var transformDirty = __transformDirty || __worldTransformInvalid;
if (transformDirty) {
var list = [];
var current = this;
if (parent == null) {
__update (true, false);
} else {
while (current != stage) {
list.push (current);
current = current.parent;
if (current == null) break;
}
}
var i = list.length;
while (--i >= 0) {
current = list[i];
current.__update (true, false);
}
}
return __worldTransform;
}
private function __globalToLocal (global:Point, local:Point):Point {
__getRenderTransform ();
if (global == local) {
__renderTransform.__transformInversePoint (global);
} else {
local.x = __renderTransform.__transformInverseX (global.x, global.y);
local.y = __renderTransform.__transformInverseY (global.x, global.y);
}
return local;
}
private function __hitTest (x:Float, y:Float, shapeFlag:Bool, stack:Array<DisplayObject>, interactiveOnly:Bool, hitObject:DisplayObject):Bool {
if (__graphics != null) {
if (!hitObject.visible || __isMask) return false;
if (mask != null && !mask.__hitTestMask (x, y)) return false;
if (__graphics.__hitTest (x, y, shapeFlag, __getRenderTransform ())) {
if (stack != null && !interactiveOnly) {
stack.push (hitObject);
}
return true;
}
}
return false;
}
private function __hitTestMask (x:Float, y:Float):Bool {
if (__graphics != null) {
if (__graphics.__hitTest (x, y, true, __getRenderTransform ())) {
return true;
}
}
return false;
}
private function __readGraphicsData (graphicsData:Vector<IGraphicsData>, recurse:Bool):Void {
if (__graphics != null) {
__graphics.__readGraphicsData (graphicsData);
}
}
private function __renderCairo (renderer:CairoRenderer):Void {
#if lime_cairo
__updateCacheBitmap (renderer, !__worldColorTransform.__isDefault ());
if (__cacheBitmap != null && !__isCacheBitmapRender) {
CairoBitmap.render (__cacheBitmap, renderer);
} else {
CairoDisplayObject.render (this, renderer);
}
__renderEvent (renderer);
#end
}
private function __renderCairoMask (renderer:CairoRenderer):Void {
#if lime_cairo
if (__graphics != null) {
CairoGraphics.renderMask (__graphics, renderer);
}
#end
}
private function __renderCanvas (renderer:CanvasRenderer):Void {
if (mask == null || (mask.width > 0 && mask.height > 0)) {
__updateCacheBitmap (renderer, !__worldColorTransform.__isDefault ());
if (__cacheBitmap != null && !__isCacheBitmapRender) {
CanvasBitmap.render (__cacheBitmap, renderer);
} else {
CanvasDisplayObject.render (this, renderer);
}
}
__renderEvent (renderer);
}
private function __renderCanvasMask (renderer:CanvasRenderer):Void {
if (__graphics != null) {
CanvasGraphics.renderMask (__graphics, renderer);
}
}
private function __renderDOM (renderer:DOMRenderer):Void {
__updateCacheBitmap (renderer, !__worldColorTransform.__isDefault ());
if (__cacheBitmap != null && !__isCacheBitmapRender) {
__renderDOMClear (renderer);
__cacheBitmap.stage = stage;
DOMBitmap.render (__cacheBitmap, renderer);
} else {
DOMDisplayObject.render (this, renderer);
}
__renderEvent (renderer);
}
private function __renderDOMClear (renderer:DOMRenderer):Void {
DOMDisplayObject.clear (this, renderer);
}
private function __renderEvent (renderer:DisplayObjectRenderer):Void {
if (__customRenderEvent != null && __renderable) {
__customRenderEvent.allowSmoothing = renderer.__allowSmoothing;
__customRenderEvent.objectMatrix.copyFrom (__renderTransform);
__customRenderEvent.objectColorTransform.__copyFrom (__worldColorTransform);
__customRenderEvent.renderer = renderer;
switch (renderer.__type) {
case OPENGL:
var renderer:OpenGLRenderer = cast renderer;
renderer.setShader (__worldShader);
__customRenderEvent.type = RenderEvent.RENDER_OPENGL;
case CAIRO:
__customRenderEvent.type = RenderEvent.RENDER_CAIRO;
case DOM:
if (stage != null && __worldVisible) {
__customRenderEvent.type = RenderEvent.RENDER_DOM;
} else {
__customRenderEvent.type = RenderEvent.CLEAR_DOM;
}
case CANVAS:
__customRenderEvent.type = RenderEvent.RENDER_CANVAS;
default:
return;
}
renderer.__setBlendMode (__worldBlendMode);
renderer.__pushMaskObject (this);
dispatchEvent (__customRenderEvent);
renderer.__popMaskObject (this);
if (renderer.__type == OPENGL) {
var renderer:OpenGLRenderer = cast renderer;
renderer.setViewport ();
}
}
}
private function __renderGL (renderer:OpenGLRenderer):Void {
__updateCacheBitmap (renderer, false);
if (__cacheBitmap != null && !__isCacheBitmapRender) {
GLBitmap.render (__cacheBitmap, renderer);
} else {
GLDisplayObject.render (this, renderer);
}
__renderEvent (renderer);
}
private function __renderGLMask (renderer:OpenGLRenderer):Void {
if (__graphics != null) {
GLGraphics.renderMask (__graphics, renderer);
}
}
private function __setParentRenderDirty ():Void {
var renderParent = __renderParent != null ? __renderParent : parent;
if (renderParent != null && !renderParent.__renderDirty) {
renderParent.__renderDirty = true;
renderParent.__setParentRenderDirty ();
}
}
private inline function __setRenderDirty ():Void {
if (!__renderDirty) {
__renderDirty = true;
__setParentRenderDirty ();
}
}
private function __setStageReference (stage:Stage):Void {
this.stage = stage;
}
private function __setTransformDirty ():Void {
if (!__transformDirty) {
__transformDirty = true;
__setWorldTransformInvalid ();
__setParentRenderDirty ();
}
}
private function __setWorldTransformInvalid ():Void {
__worldTransformInvalid = true;
}
private function __shouldCacheHardware (value:Null<Bool>):Null<Bool> {
if (value == true || __filters != null) return true;
if (value == false || (__graphics != null && !GLGraphics.isCompatible (__graphics))) {
return false;
}
return null;
}
private function __stopAllMovieClips ():Void {
}
private function __update (transformOnly:Bool, updateChildren:Bool):Void {
var renderParent = __renderParent != null ? __renderParent : parent;
if (__isMask && renderParent == null) renderParent = __maskTarget;
__renderable = (visible && __scaleX != 0 && __scaleY != 0 && !__isMask && (renderParent == null || !renderParent.__isMask));
__updateTransforms ();
//if (updateChildren && __transformDirty) {
__transformDirty = false;
//}
__worldTransformInvalid = false;
if (!transformOnly) {
if (__supportDOM) {
__renderTransformChanged = !__renderTransform.equals (__renderTransformCache);
if (__renderTransformCache == null) {
__renderTransformCache = __renderTransform.clone ();
} else {
__renderTransformCache.copyFrom (__renderTransform);
}
}
if (__objectTransform != null) {
__worldColorTransform.__copyFrom (__objectTransform.colorTransform);
}
if (renderParent != null) {
if (__supportDOM) {
var worldVisible = (renderParent.__worldVisible && visible);
__worldVisibleChanged = (__worldVisible != worldVisible);
__worldVisible = worldVisible;
var worldAlpha = alpha * renderParent.__worldAlpha;
__worldAlphaChanged = (__worldAlpha != worldAlpha);
__worldAlpha = worldAlpha;
} else {
__worldAlpha = alpha * renderParent.__worldAlpha;
}
__worldColorTransform.__combine (renderParent.__worldColorTransform);
if (__blendMode == null || __blendMode == NORMAL) {
// TODO: Handle multiple blend modes better
__worldBlendMode = renderParent.__blendMode;
} else {
__worldBlendMode = __blendMode;
}
if (__shader == null) {
__worldShader = renderParent.__shader;
} else {
__worldShader = __shader;
}
} else {
__worldAlpha = alpha;
if (__supportDOM) {
__worldVisibleChanged = (__worldVisible != visible);
__worldVisible = visible;
__worldAlphaChanged = (__worldAlpha != alpha);
}
}
//if (updateChildren && __renderDirty) {
//__renderDirty = false;
//}
}
if (updateChildren && mask != null) {
mask.__update (transformOnly, true);
}
}
private function __updateCacheBitmap (renderer:DisplayObjectRenderer, force:Bool):Bool {
if (__isCacheBitmapRender) return false;
if (cacheAsBitmap || (renderer.__type != OPENGL && !__worldColorTransform.__isDefault ())) {
var matrix = null, rect = null;
__update (false, true);
var needRender = (__cacheBitmap == null || (__renderDirty && (force || (__children != null && __children.length > 0) || (__graphics != null && __graphics.__dirty))) || opaqueBackground != __cacheBitmapBackground || !__cacheBitmapColorTransform.__equals (__worldColorTransform));
var updateTransform = (needRender || (!__cacheBitmap.__worldTransform.equals (__worldTransform)));
var hasFilters = __filters != null;
if (hasFilters && !needRender) {
for (filter in __filters) {
if (filter.__renderDirty) {
needRender = true;
break;
}
}
}
if (__cacheBitmapMatrix == null) {
__cacheBitmapMatrix = new Matrix ();
}
var bitmapMatrix = (__cacheAsBitmapMatrix != null ? __cacheAsBitmapMatrix : __renderTransform);
if (!needRender && (bitmapMatrix.a != __cacheBitmapMatrix.a || bitmapMatrix.b != __cacheBitmapMatrix.b || bitmapMatrix.c != __cacheBitmapMatrix.c || bitmapMatrix.d != __cacheBitmapMatrix.d)) {
needRender = true;
}
__cacheBitmapMatrix.copyFrom (bitmapMatrix);
__cacheBitmapMatrix.tx = 0;
__cacheBitmapMatrix.ty = 0;
// TODO: Handle dimensions better if object has a scrollRect?
var bitmapWidth = 0, bitmapHeight = 0;
var filterWidth = 0, filterHeight = 0;
var offsetX = 0., offsetY = 0.;
if (updateTransform || needRender) {
rect = Rectangle.__pool.get ();
__getFilterBounds (rect, __cacheBitmapMatrix);
filterWidth = Math.ceil (rect.width);
filterHeight = Math.ceil (rect.height);
offsetX = rect.x > 0 ? Math.ceil (rect.x) : Math.floor (rect.x);
offsetY = rect.y > 0 ? Math.ceil (rect.y) : Math.floor (rect.y);
if (__cacheBitmapData != null) {
if (filterWidth > __cacheBitmapData.width || filterHeight > __cacheBitmapData.height) {
bitmapWidth = Math.ceil (Math.max (filterWidth * 1.25, __cacheBitmapData.width));
bitmapHeight = Math.ceil (Math.max (filterHeight * 1.25, __cacheBitmapData.height));
needRender = true;
} else {
bitmapWidth = __cacheBitmapData.width;
bitmapHeight = __cacheBitmapData.height;
}
} else {
bitmapWidth = filterWidth;
bitmapHeight = filterHeight;
}
}
if (needRender) {
updateTransform = true;
__cacheBitmapBackground = opaqueBackground;
var color = opaqueBackground != null ? (0xFF << 24) | opaqueBackground : 0;
if (filterWidth >= 0.5 && filterHeight >= 0.5) {
if (__cacheBitmapData == null || bitmapWidth > __cacheBitmapData.width || bitmapHeight > __cacheBitmapData.height) {
__cacheBitmapData = new BitmapData (bitmapWidth, bitmapHeight, true, color);
if (__cacheBitmap == null) __cacheBitmap = new Bitmap ();
__cacheBitmap.__bitmapData = __cacheBitmapData;
__cacheBitmapRenderer = null;
} else {
__cacheBitmapData.fillRect (__cacheBitmapData.rect, color);
}
} else {
__cacheBitmap = null;
__cacheBitmapData = null;
__cacheBitmapData2 = null;
__cacheBitmapData3 = null;
__cacheBitmapRenderer = null;
return true;
}
} else {
// Should we retain these longer?
__cacheBitmapData = __cacheBitmap.bitmapData;
__cacheBitmapData2 = null;
__cacheBitmapData3 = null;
}
if (updateTransform || needRender) {
__cacheBitmap.__worldTransform.copyFrom (__worldTransform);
if (bitmapMatrix == __renderTransform) {
__cacheBitmap.__renderTransform.identity ();
__cacheBitmap.__renderTransform.tx = __renderTransform.tx + offsetX;
__cacheBitmap.__renderTransform.ty = __renderTransform.ty + offsetY;
} else {
__cacheBitmap.__renderTransform.copyFrom (__cacheBitmapMatrix);
__cacheBitmap.__renderTransform.invert ();
__cacheBitmap.__renderTransform.concat (__renderTransform);
__cacheBitmap.__renderTransform.tx += offsetX;
__cacheBitmap.__renderTransform.ty += offsetY;
}
}
__cacheBitmap.smoothing = renderer.__allowSmoothing;
__cacheBitmap.__renderable = __renderable;
__cacheBitmap.__worldAlpha = __worldAlpha;
__cacheBitmap.__worldBlendMode = __worldBlendMode;
__cacheBitmap.__worldShader = __worldShader;
__cacheBitmap.__scrollRect = __scrollRect;
//__cacheBitmap.filters = filters;
__cacheBitmap.mask = __mask;
if (needRender) {
var renderType = renderer.__type;
if (renderType == OPENGL) {
if (#if !openfl_disable_gl_cacheasbitmap __shouldCacheHardware (null) == false #else true #end) {
#if (js && html5)
renderType = CANVAS;
#else
renderType = CAIRO;
#end
}
}
if (__cacheBitmapRenderer == null || renderType != __cacheBitmapRenderer.__type) {
if (renderType == OPENGL) {
__cacheBitmapRenderer = new OpenGLRenderer (cast (renderer, OpenGLRenderer).__gl, __cacheBitmapData);
} else {
if (__cacheBitmapData.image == null) {
var color = opaqueBackground != null ? (0xFF << 24) | opaqueBackground : 0;
__cacheBitmapData = new BitmapData (bitmapWidth, bitmapHeight, true, color);
}
#if (js && html5)
ImageCanvasUtil.convertToCanvas (__cacheBitmapData.image);
__cacheBitmapRenderer = new CanvasRenderer (__cacheBitmapData.image.buffer.__srcContext);
#else
__cacheBitmapRenderer = new CairoRenderer (new Cairo (__cacheBitmapData.getSurface ()));
#end
}
__cacheBitmapRenderer.__worldTransform = new Matrix ();
__cacheBitmapRenderer.__worldColorTransform = new ColorTransform ();
}
__cacheBitmapRenderer.__stage = stage;
__cacheBitmapRenderer.__allowSmoothing = renderer.__allowSmoothing;
__cacheBitmapRenderer.__setBlendMode (NORMAL);
__cacheBitmapRenderer.__worldAlpha = 1 / __worldAlpha;
__cacheBitmapRenderer.__worldTransform.copyFrom (__renderTransform);
__cacheBitmapRenderer.__worldTransform.invert ();
__cacheBitmapRenderer.__worldTransform.concat (__cacheBitmapMatrix);
__cacheBitmapRenderer.__worldTransform.tx -= offsetX;
__cacheBitmapRenderer.__worldTransform.ty -= offsetY;
__cacheBitmapRenderer.__worldColorTransform.__copyFrom (__worldColorTransform);
__cacheBitmapRenderer.__worldColorTransform.__invert ();
__isCacheBitmapRender = true;
if (__cacheBitmapRenderer.__type == OPENGL) {
var parentRenderer:OpenGLRenderer = cast renderer;
var childRenderer:OpenGLRenderer = cast __cacheBitmapRenderer;
var cacheBlendMode = parentRenderer.__blendMode;
parentRenderer.__suspendClipAndMask ();
childRenderer.__copyShader (parentRenderer);
__cacheBitmapData.__setUVRect (childRenderer.__gl, 0, 0, filterWidth, filterHeight);
childRenderer.__setRenderTarget (__cacheBitmapData);
if (__cacheBitmapData.image != null) __cacheBitmapData.__textureVersion = __cacheBitmapData.image.version;
__cacheBitmapData.__drawGL (this, childRenderer);
if (hasFilters) {
var needSecondBitmapData = true;
var needCopyOfOriginal = false;
for (filter in __filters) {
// if (filter.__needSecondBitmapData) {
// needSecondBitmapData = true;
// }
if (filter.__preserveObject) {
needCopyOfOriginal = true;
}
}
var bitmap = __cacheBitmapData;
var bitmap2 = null;
var bitmap3 = null;
// if (needSecondBitmapData) {
if (__cacheBitmapData2 == null || bitmapWidth > __cacheBitmapData2.width || bitmapHeight > __cacheBitmapData2.height) {
__cacheBitmapData2 = new BitmapData (bitmapWidth, bitmapHeight, true, 0);
} else {
//__cacheBitmapData2.fillRect (__cacheBitmapData2.rect, 0);
if (__cacheBitmapData2.image != null) {
__cacheBitmapData2.__textureVersion = __cacheBitmapData2.image.version;
}
}
__cacheBitmapData2.__setUVRect (childRenderer.__gl, 0, 0, filterWidth, filterHeight);
bitmap2 = __cacheBitmapData2;
// } else {
// bitmap2 = bitmapData;
// }
if (needCopyOfOriginal) {
if (__cacheBitmapData3 == null || bitmapWidth > __cacheBitmapData3.width || bitmapHeight > __cacheBitmapData3.height) {
__cacheBitmapData3 = new BitmapData (bitmapWidth, bitmapHeight, true, 0);
} else {
//__cacheBitmapData3.fillRect (__cacheBitmapData3.rect, 0);
if (__cacheBitmapData3.image != null) {
__cacheBitmapData3.__textureVersion = __cacheBitmapData3.image.version;
}
}
__cacheBitmapData3.__setUVRect (childRenderer.__gl, 0, 0, filterWidth, filterHeight);
bitmap3 = __cacheBitmapData3;
}
childRenderer.__setBlendMode (NORMAL);
childRenderer.__worldAlpha = 1;
childRenderer.__worldTransform.identity ();
childRenderer.__worldColorTransform.__identity ();
// var sourceRect = bitmap.rect;
// if (__tempPoint == null) __tempPoint = new Point ();
// var destPoint = __tempPoint;
var shader, cacheBitmap;
for (filter in __filters) {
if (filter.__preserveObject) {
childRenderer.__setRenderTarget (bitmap3);
childRenderer.__renderFilterPass (bitmap, childRenderer.__defaultDisplayShader);
}
for (i in 0...filter.__numShaderPasses) {
shader = filter.__initShader (childRenderer, i);
childRenderer.__setBlendMode (filter.__shaderBlendMode);
childRenderer.__setRenderTarget (bitmap2);
childRenderer.__renderFilterPass (bitmap, shader);
cacheBitmap = bitmap;
bitmap = bitmap2;
bitmap2 = cacheBitmap;
}
if (filter.__preserveObject) {
childRenderer.__setBlendMode (NORMAL);
childRenderer.__setRenderTarget (bitmap);
childRenderer.__renderFilterPass (bitmap3, childRenderer.__defaultDisplayShader, false);
}
filter.__renderDirty = false;
}
__cacheBitmap.__bitmapData = bitmap;
}
parentRenderer.__blendMode = NORMAL;
parentRenderer.__setBlendMode (cacheBlendMode);
parentRenderer.__copyShader (childRenderer);
parentRenderer.__resumeClipAndMask ();
parentRenderer.setViewport ();
} else {
#if (js && html5)
__cacheBitmapData.__drawCanvas (this, cast __cacheBitmapRenderer);
#else
__cacheBitmapData.__drawCairo (this, cast __cacheBitmapRenderer);
#end
if (hasFilters) {
var needSecondBitmapData = false;
var needCopyOfOriginal = false;
for (filter in __filters) {
if (filter.__needSecondBitmapData) {
needSecondBitmapData = true;
}
if (filter.__preserveObject) {
needCopyOfOriginal = true;
}
}
var bitmap = __cacheBitmapData;
var bitmap2 = null;
var bitmap3 = null;
if (needSecondBitmapData) {
if (__cacheBitmapData2 == null || __cacheBitmapData2.image == null || bitmapWidth > __cacheBitmapData2.width || bitmapHeight > __cacheBitmapData2.height) {
__cacheBitmapData2 = new BitmapData (bitmapWidth, bitmapHeight, true, 0);
} else {
__cacheBitmapData2.fillRect (__cacheBitmapData2.rect, 0);
}
bitmap2 = __cacheBitmapData2;
} else {
bitmap2 = bitmap;
}
if (needCopyOfOriginal) {
if (__cacheBitmapData3 == null || __cacheBitmapData3.image == null || bitmapWidth > __cacheBitmapData3.width || bitmapHeight > __cacheBitmapData3.height) {
__cacheBitmapData3 = new BitmapData (bitmapWidth, bitmapHeight, true, 0);
} else {
__cacheBitmapData3.fillRect (__cacheBitmapData3.rect, 0);
}
bitmap3 = __cacheBitmapData3;
}
var sourceRect = Rectangle.__pool.get ();
sourceRect.setTo (0, 0, filterWidth, filterHeight);
if (__tempPoint == null) __tempPoint = new Point ();
var destPoint = __tempPoint;
var cacheBitmap, lastBitmap;
for (filter in __filters) {
if (filter.__preserveObject) {
bitmap3.copyPixels (bitmap, bitmap.rect, destPoint);
}
lastBitmap = filter.__applyFilter (bitmap2, bitmap, sourceRect, destPoint);
if (filter.__preserveObject) {
lastBitmap.draw (bitmap3, null, __objectTransform != null ? __objectTransform.colorTransform : null);
}
filter.__renderDirty = false;
if (needSecondBitmapData && lastBitmap == bitmap2) {
cacheBitmap = bitmap;
bitmap = bitmap2;
bitmap2 = cacheBitmap;
}
}
Rectangle.__pool.release (sourceRect);
__cacheBitmap.__bitmapData = bitmap;
__cacheBitmap.__imageVersion = bitmap.__textureVersion;
}
}
__isCacheBitmapRender = false;
if (__cacheBitmapColorTransform == null) __cacheBitmapColorTransform = new ColorTransform ();
__cacheBitmapColorTransform.__copyFrom (__worldColorTransform);
if (!__cacheBitmapColorTransform.__isDefault ()) {
__cacheBitmapData.colorTransform (__cacheBitmapData.rect, __cacheBitmapColorTransform);
}
}
if (updateTransform) {
__update (false, true);
Rectangle.__pool.release (rect);
return true;
} else {
return false;
}
} else if (__cacheBitmap != null) {
if (renderer.__type == DOM) {
__cacheBitmap.__renderDOMClear (cast renderer);
}
__cacheBitmap = null;
__cacheBitmapData = null;
__cacheBitmapData2 = null;
__cacheBitmapData3 = null;
__cacheBitmapColorTransform = null;
__cacheBitmapRenderer = null;
return true;
}
return false;
}
private function __updateChildren (transformOnly:Bool):Void {
var renderParent = __renderParent != null ? __renderParent : parent;
__renderable = (visible && __scaleX != 0 && __scaleY != 0 && !__isMask && (renderParent == null || !renderParent.__isMask));
__worldAlpha = __alpha;
__worldBlendMode = __blendMode;
__worldShader = __shader;
if (__transformDirty) {
__transformDirty = false;
}
}
private function __updateMask (maskGraphics:Graphics):Void {
if (__graphics != null) {
maskGraphics.__commands.overrideMatrix (this.__worldTransform);
maskGraphics.__commands.append (__graphics.__commands);
maskGraphics.__dirty = true;
maskGraphics.__visible = true;
if (maskGraphics.__bounds == null) {
maskGraphics.__bounds = new Rectangle();
}
__graphics.__getBounds (maskGraphics.__bounds, @:privateAccess Matrix.__identity);
}
}
private function __updateTransforms (overrideTransform:Matrix = null):Void {
var overrided = overrideTransform != null;
var local = overrided ? overrideTransform : __transform;
if (__worldTransform == null) {
__worldTransform = new Matrix ();
}
if (__renderTransform == null) {
__renderTransform = new Matrix ();
}
var renderParent = __renderParent != null ? __renderParent : parent;
if (!overrided && parent != null) {
__calculateAbsoluteTransform (local, parent.__worldTransform, __worldTransform);
} else {
__worldTransform.copyFrom (local);
}
if (!overrided && renderParent != null) {
__calculateAbsoluteTransform (local, renderParent.__renderTransform, __renderTransform);
} else {
__renderTransform.copyFrom (local);
}
if (__scrollRect != null) {
__renderTransform.__translateTransformed (-__scrollRect.x, -__scrollRect.y);
}
}
// Get & Set Methods
private function get_alpha ():Float {
return __alpha;
}
private function set_alpha (value:Float):Float {
if (value > 1.0) value = 1.0;
if (value != __alpha) __setRenderDirty ();
return __alpha = value;
}
private function get_blendMode ():BlendMode {
return __blendMode;
}
private function set_blendMode (value:BlendMode):BlendMode {
if (value == null) value = NORMAL;
if (value != __blendMode) __setRenderDirty ();
return __blendMode = value;
}
private function get_cacheAsBitmap ():Bool {
return (__filters == null ? __cacheAsBitmap : true);
}
private function set_cacheAsBitmap (value:Bool):Bool {
__setRenderDirty ();
return __cacheAsBitmap = value;
}
private function get_cacheAsBitmapMatrix ():Matrix {
return __cacheAsBitmapMatrix;
}
private function set_cacheAsBitmapMatrix (value:Matrix):Matrix {
__setRenderDirty ();
return __cacheAsBitmapMatrix = (value != null ? value.clone () : value);
}
private function get_filters ():Array<BitmapFilter> {
if (__filters == null) {
return new Array ();
} else {
return __filters.copy ();
}
}
private function set_filters (value:Array<BitmapFilter>):Array<BitmapFilter> {
if (value != null && value.length > 0) {
__filters = value;
//__updateFilters = true;
} else {
__filters = null;
//__updateFilters = false;
}
__setRenderDirty ();
return value;
}
private function get_height ():Float {
var rect = Rectangle.__pool.get ();
__getLocalBounds (rect);
var height = rect.height;
Rectangle.__pool.release (rect);
return height;
}
private function set_height (value:Float):Float {
var rect = Rectangle.__pool.get ();
var matrix = Matrix.__pool.get ();
matrix.identity ();
__getBounds (rect, matrix);
if (value != rect.height) {
scaleY = value / rect.height;
} else {
scaleY = 1;
}
Rectangle.__pool.release (rect);
Matrix.__pool.release (matrix);
return value;
}
private function get_loaderInfo ():LoaderInfo {
if (stage != null) {
return Lib.current.__loaderInfo;
}
return null;
}
private function get_mask ():DisplayObject {
return __mask;
}
private function set_mask (value:DisplayObject):DisplayObject {
if (value == __mask) {
return value;
}
if (value != __mask) {
__setTransformDirty ();
__setRenderDirty ();
}
if (__mask != null) {
__mask.__isMask = false;
__mask.__maskTarget = null;
__mask.__setTransformDirty ();
__mask.__setRenderDirty ();
}
if (value != null) {
value.__isMask = true;
value.__maskTarget = this;
value.__setWorldTransformInvalid ();
}
if (__cacheBitmap != null && __cacheBitmap.mask != value) {
__cacheBitmap.mask = value;
}
return __mask = value;
}
private function get_mouseX ():Float {
var mouseX = (stage != null ? stage.__mouseX : Lib.current.stage.__mouseX);
var mouseY = (stage != null ? stage.__mouseY : Lib.current.stage.__mouseY);
return __getRenderTransform ().__transformInverseX (mouseX, mouseY);
}
private function get_mouseY ():Float {
var mouseX = (stage != null ? stage.__mouseX : Lib.current.stage.__mouseX);
var mouseY = (stage != null ? stage.__mouseY : Lib.current.stage.__mouseY);
return __getRenderTransform ().__transformInverseY (mouseX, mouseY);
}
private function get_name ():String {
return __name;
}
private function set_name (value:String):String {
return __name = value;
}
private function get_root ():DisplayObject {
if (stage != null) {
return Lib.current;
}
return null;
}
private function get_rotation ():Float {
return __rotation;
}
private function set_rotation (value:Float):Float {
if (value != __rotation) {
__rotation = value;
var radians = __rotation * (Math.PI / 180);
__rotationSine = Math.sin (radians);
__rotationCosine = Math.cos (radians);
__transform.a = __rotationCosine * __scaleX;
__transform.b = __rotationSine * __scaleX;
__transform.c = -__rotationSine * __scaleY;
__transform.d = __rotationCosine * __scaleY;
__setTransformDirty ();
}
return value;
}
@:keep private function get_scaleX ():Float {
return __scaleX;
}
@:keep private function set_scaleX (value:Float):Float {
if (value != __scaleX) {
__scaleX = value;
if (__transform.b == 0) {
if (value != __transform.a) __setTransformDirty ();
__transform.a = value;
} else {
var a = __rotationCosine * value;
var b = __rotationSine * value;
if (__transform.a != a || __transform.b != b) {
__setTransformDirty ();
}
__transform.a = a;
__transform.b = b;
}
}
return value;
}
@:keep private function get_scaleY ():Float {
return __scaleY;
}
@:keep private function set_scaleY (value:Float):Float {
if (value != __scaleY) {
__scaleY = value;
if (__transform.c == 0) {
if (value != __transform.d) __setTransformDirty ();
__transform.d = value;
} else {
var c = -__rotationSine * value;
var d = __rotationCosine * value;
if (__transform.d != d || __transform.c != c) {
__setTransformDirty ();
}
__transform.c = c;
__transform.d = d;
}
}
return value;
}
private function get_scrollRect ():Rectangle {
if (__scrollRect == null) {
return null;
}
return __scrollRect.clone();
}
private function set_scrollRect (value:Rectangle):Rectangle {
if (value != __scrollRect) {
__setTransformDirty ();
if (__supportDOM) {
__setRenderDirty ();
}
}
return __scrollRect = value;
}
private function get_shader ():Shader {
return __shader;
}
private function set_shader (value:Shader):Shader {
__shader = value;
__setRenderDirty ();
return value;
}
private function get_transform ():Transform {
if (__objectTransform == null) {
__objectTransform = new Transform (this);
}
return __objectTransform;
}
private function set_transform (value:Transform):Transform {
if (value == null) {
throw new TypeError ("Parameter transform must be non-null.");
}
if (__objectTransform == null) {
__objectTransform = new Transform (this);
}
__setTransformDirty ();
__objectTransform.matrix = value.matrix;
__objectTransform.colorTransform = value.colorTransform.__clone();
return __objectTransform;
}
private function get_visible ():Bool {
return __visible;
}
private function set_visible (value:Bool):Bool {
if (value != __visible) __setRenderDirty ();
return __visible = value;
}
private function get_width ():Float {
var rect = Rectangle.__pool.get ();
__getLocalBounds (rect);
var width = rect.width;
Rectangle.__pool.release (rect);
return width;
}
private function set_width (value:Float):Float {
var rect = Rectangle.__pool.get ();
var matrix = Matrix.__pool.get ();
matrix.identity ();
__getBounds (rect, matrix);
if (value != rect.width) {
scaleX = value / rect.width;
} else {
scaleX = 1;
}
Rectangle.__pool.release (rect);
Matrix.__pool.release (matrix);
return value;
}
private function get_x ():Float {
return __transform.tx;
}
private function set_x (value:Float):Float {
if (value != __transform.tx) __setTransformDirty ();
return __transform.tx = value;
}
private function get_y ():Float {
return __transform.ty;
}
private function set_y (value:Float):Float {
if (value != __transform.ty) __setTransformDirty ();
return __transform.ty = value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment