////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package mx.graphics
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import mx.events.PropertyChangeEvent;
import mx.geom.CompoundTransform;
import mx.utils.MatrixUtil;
/**
* Defines a set of values used to fill an area on screen
* with a bitmap or other DisplayObject.
*
* @see mx.graphics.IFill
* @see flash.display.Bitmap
* @see flash.display.BitmapData
* @see flash.display.DisplayObject
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class BitmapFill extends EventDispatcher implements IFill
{
include "../core/Version.as";
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function BitmapFill()
{
super();
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
private static const RADIANS_PER_DEGREES:Number = Math.PI / 180;
private static var transformMatrix:Matrix = new Matrix();
private var nonRepeatAlphaSource:BitmapData;
private var _bitmapData:BitmapData;
private var regenerateNonRepeatSource:Boolean = true;
private var lastBoundsWidth:Number = 0;
private var lastBoundsHeight:Number = 0;
private var applyAlphaMultiplier:Boolean = false;
private var nonRepeatSourceCreated:Boolean = false;
private var bitmapDataCreated:Boolean = false;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// alpha
//----------------------------------
private var _alpha:Number = 1;
/**
* The transparency of a fill.
* Possible values are 0.0 (invisible) through 1.0 (opaque).
*
* @default 1.0.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get alpha():Number
{
return _alpha;
}
/**
* @private
*/
public function set alpha(value:Number):void
{
if (_alpha == value)
return;
var oldValue:Number = _alpha;
_alpha = value;
applyAlphaMultiplier = true;
if (_bitmapData && !_bitmapData.transparent && _alpha < 1 && oldValue == 1)
{
// If alpha is not opaque, then reapply the source because we might need
// to clone it.
var s:Object = _source;
_source = null;
source = s;
}
dispatchFillChangedEvent("alpha", oldValue, value);
}
//----------------------------------
// compoundTransform
//----------------------------------
/**
* Holds the matrix and the convenience transform properties (x
, y
, and rotation
).
* The compoundTransform is only created when the matrix
property is set.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected var compoundTransform:CompoundTransform;
//----------------------------------
// matrix
//----------------------------------
[Inspectable(category="General")]
/**
* An array of values used for matrix transformation.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get matrix():Matrix
{
return compoundTransform ? compoundTransform.matrix : null;
}
/**
* @private
*/
public function set matrix(value:Matrix):void
{
var oldValue:Matrix = matrix;
var oldX:Number = x;
var oldY:Number = y;
var oldRotation:Number = rotation;
var oldScaleX:Number = scaleX;
var oldScaleY:Number = scaleY;
if (value == null)
{
compoundTransform = null;
}
else
{
// Create the transform if none exists.
if (compoundTransform == null)
compoundTransform = new CompoundTransform();
compoundTransform.matrix = value; // CompoundTransform will create a clone
dispatchFillChangedEvent("x", oldX, compoundTransform.x);
dispatchFillChangedEvent("y", oldY, compoundTransform.y);
dispatchFillChangedEvent("scaleX", oldScaleX, compoundTransform.scaleX);
dispatchFillChangedEvent("scaleY", oldScaleY, compoundTransform.scaleY);
dispatchFillChangedEvent("rotation", oldRotation, compoundTransform.rotationZ);
}
}
//----------------------------------
// originX
//----------------------------------
private var _originX:Number = 0;
[Bindable("propertyChange")]
[Inspectable(category="General")]
[Deprecated(replacement="transformX", since="4.0")]
/**
* The horizontal origin for the bitmap fill.
* The bitmap fill is offset so that this point appears at the origin.
* Scaling and rotation of the bitmap are performed around this point.
*
* @default 0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get originX():Number
{
return transformX;
}
public function set originX(value:Number):void
{
transformX = value;
}
//----------------------------------
// originY
//----------------------------------
private var _originY:Number = 0;
[Bindable("propertyChange")]
[Inspectable(category="General")]
[Deprecated(replacement="transformY", since="4.0")]
/**
* The vertical origin for the bitmap fill.
* The bitmap fill is offset so that this point appears at the origin.
* Scaling and rotation of the bitmap are performed around this point.
*
* @default 0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get originY():Number
{
return transformY;
}
public function set originY(value:Number):void
{
transformY = value;
}
//----------------------------------
// offsetX
//----------------------------------
[Bindable("propertyChange")]
[Inspectable(category="General")]
[Deprecated(replacement="x", since="4.0")]
/**
* How far the bitmap is horizontally offset from the origin.
* This adjustment is performed after rotation and scaling.
*
* @default 0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get offsetX():Number
{
return isNaN(x) ? 0 : x;
}
public function set offsetX(value:Number):void
{
var oldValue:Number = isNaN(x) ? 0 : x; // Avoid warning since the offsetY getter is deprecated
x = value;
dispatchFillChangedEvent("offsetX", oldValue, value);
}
//----------------------------------
// offsetY
//----------------------------------
[Bindable("propertyChange")]
[Inspectable(category="General")]
[Deprecated(replacement="y", since="4.0")]
/**
* How far the bitmap is vertically offset from the origin.
* This adjustment is performed after rotation and scaling.
*
* @default 0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get offsetY():Number
{
return isNaN(y) ? 0 : y;
}
public function set offsetY(value:Number):void
{
var oldValue:Number = isNaN(y) ? 0 : y; // Avoid warning since the offsetY getter is deprecated
y = value;
dispatchFillChangedEvent("offsetY", oldValue, value);
}
//----------------------------------
// repeat
//----------------------------------
[Bindable("propertyChange")]
[Inspectable(category="General")]
[Deprecated(replacement="fillMode", since="4.0")]
/**
* Whether the bitmap is repeated to fill the area.
* Set to true
to cause the fill to tile outward
* to the edges of the filled region.
* Set to false
to end the fill at the edge of the region.
*
* @default true
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get repeat():Boolean
{
return _fillMode == BitmapFillMode.REPEAT;
}
public function set repeat(value:Boolean):void
{
var oldValue:Boolean = (_fillMode == BitmapFillMode.REPEAT);
if (value != oldValue)
{
//Setting repeat just sets fillMode to repeat
fillMode = value ? BitmapFillMode.REPEAT : BitmapFillMode.SCALE;
dispatchFillChangedEvent("repeat", oldValue, value);
}
}
//----------------------------------
// fillMode
//----------------------------------
/**
* @private
*/
protected var _fillMode:String = BitmapFillMode.SCALE;
[Inspectable(category="General", enumeration="clip,repeat,scale", defaultValue="scale")]
/**
* Determines how the bitmap fills in the dimensions. If you set the value
* of this property in a tag, use the string (such as "repeat"). If you set the value of
* this property in ActionScript, use the constant (such as BitmapFillMode.CLIP
).
*
* When set to BitmapFillMode.CLIP
("clip"), the bitmap
* ends at the edge of the region.
*
* When set to BitmapFillMode.REPEAT
("repeat"), the bitmap
* repeats to fill the region.
*
* When set to BitmapFillMode.SCALE
("scale"), the bitmap
* stretches to fill the region.
*
* @default BitmapFillMode.SCALE
*
* @langversion 3.0
* @playerversion Flash 10
* @playerversion AIR 1.5
* @productversion Flex 4
*/
public function get fillMode():String
{
return _fillMode;
}
/**
* @private
*/
public function set fillMode(value:String):void
{
var oldValue:String = _fillMode;
if (value != _fillMode)
{
_fillMode = value;
dispatchFillChangedEvent("fillMode", oldValue, value);
}
}
//----------------------------------
// rotation
//----------------------------------
private var _rotation:Number = 0;
[Bindable("propertyChange")]
[Inspectable(category="General")]
/**
* The number of degrees to rotate the bitmap.
* Valid values range from 0.0 to 360.0.
*
* @default 0
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get rotation():Number
{
return compoundTransform ? compoundTransform.rotationZ : _rotation;
}
public function set rotation(value:Number):void
{
if (value != rotation)
{
var oldValue:Number = rotation;
if (compoundTransform)
compoundTransform.rotationZ = value;
else
_rotation = value;
dispatchFillChangedEvent("rotation", oldValue, value);
}
}
//----------------------------------
// scaleX
//----------------------------------
private var _scaleX:Number;
[Bindable("propertyChange")]
[Inspectable(category="General")]
/**
* The percent to horizontally scale the bitmap when filling,
* from 0.0 to 1.0.
* If 1.0, the bitmap is filled at its natural size.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get scaleX():Number
{
return compoundTransform ? compoundTransform.scaleX : _scaleX;
}
/**
* @private
*/
public function set scaleX(value:Number):void
{
if (value != scaleX)
{
var oldValue:Number = scaleX;
if (compoundTransform)
{
// If we have a compoundTransform, only non-NaN values are allowed
if (!isNaN(value))
compoundTransform.scaleX = value;
}
else
{
_scaleX = value;
}
dispatchFillChangedEvent("scaleX", oldValue, value);
}
}
//----------------------------------
// scaleY
//----------------------------------
private var _scaleY:Number;
[Bindable("propertyChange")]
[Inspectable(category="General")]
/**
* The percent to vertically scale the bitmap when filling,
* from 0.0 to 1.0.
* If 1.0, the bitmap is filled at its natural size.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get scaleY():Number
{
return compoundTransform ? compoundTransform.scaleY : _scaleY;
}
/**
* @private
*/
public function set scaleY(value:Number):void
{
if (value != scaleY)
{
var oldValue:Number = scaleY;
if (compoundTransform)
{
// If we have a compoundTransform, only non-NaN values are allowed
if (!isNaN(value))
compoundTransform.scaleY = value;
}
else
{
_scaleY = value;
}
dispatchFillChangedEvent("scaleY", oldValue, value);
}
}
//----------------------------------
// source
//----------------------------------
private var _source:Object;
[Inspectable(category="General")]
/**
* The source used for the bitmap fill.
* The fill can render from various graphical sources,
* including the following:
*