http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/7d529524/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/AdvancedLayoutFeatures.as
----------------------------------------------------------------------
diff --git 
a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/AdvancedLayoutFeatures.as
 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/AdvancedLayoutFeatures.as
new file mode 100644
index 0000000..1b8bee6
--- /dev/null
+++ 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/AdvancedLayoutFeatures.as
@@ -0,0 +1,1140 @@
+/**
+ * Licensed 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 org.apache.flex.graphics.utils
+{
+       import flash.events.Event;
+       import flash.geom.Matrix;
+       import flash.geom.Matrix3D;
+       import flash.geom.Point;
+       import flash.geom.Vector3D;
+       import flash.system.Capabilities;
+       
+       import org.apache.flex.graphics.utils.IAssetLayoutFeatures;
+       
+       
+       /**
+        *  @private
+        *  Transform Offsets can be assigned to any Component or 
GraphicElement to modify the transform
+        *  of the object beyond where its parent layout places it.
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       public class AdvancedLayoutFeatures implements IAssetLayoutFeatures
+       {
+               
//--------------------------------------------------------------------------
+               //
+               //  Constructor
+               //
+               
//--------------------------------------------------------------------------
+               /**
+                *  Constructor.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function AdvancedLayoutFeatures()
+               {
+                       layout = new CompoundTransform();
+               }
+               
+               
+               
+               /**
+                * @private
+                * a flag for use by the owning object indicating whether the 
owning object has a pending update
+                * to the computed matrix.  it is the owner's responsibility to 
set this flag.
+                */
+               public var updatePending:Boolean = false;
+               
+               /**
+                * storage for the depth value. Layering is considered 
'advanced' layout behavior, and not something
+                * that gets used by the majority of the components out there.  
So if a component has a non-zero depth,
+                * it will allocate a AdvancedLayoutFeatures object and store 
the value here.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public var depth:Number = 0;
+               
+               /**
+                * @private
+                * slots for the various 2D and 3D matrices for layout, offset, 
and computed transforms.  Note that 
+                * these are only allocated and computed on demand -- many 
component instances will never use a 3D
+                * matrix, for example. 
+                */
+               protected var _computedMatrix:Matrix;
+               protected var _computedMatrix3D:Matrix3D;
+               
+               /**
+                * @private
+                * the layout visible transform as defined by the user and 
parent layout.
+                */
+               protected var layout:CompoundTransform;
+               
+               /**
+                * @private
+                * offset values applied by the user
+                */
+               private var _postLayoutTransformOffsets:TransformOffsets;
+               
+               /**
+                * @private
+                * bit field flags for indicating which transforms are valid -- 
the layout properties, the matrices,
+                * and the 3D matrices.  Since developers can set any of the 
three programmatically, the last one set
+                * will always be valid, and the others will be invalid until 
validated on demand.
+                */
+               private static const COMPUTED_MATRIX_VALID:uint     = 0x1;
+               private static const COMPUTED_MATRIX3D_VALID:uint   = 0x2;
+               
+               /**
+                * @private
+                * general storage for all of our flags.  
+                */
+               private var _flags:uint = 0;
+               
+               /**
+                * @private
+                * static data used by utility methods below
+                */
+               private static var reVT:Vector3D = new Vector3D(0,0,0);
+               private static var reVR:Vector3D = new Vector3D(0,0,0);
+               private static var reVS:Vector3D = new Vector3D(1,1,1);
+               
+               private static var reV:Vector.<Vector3D> = new 
Vector.<Vector3D>();
+               reV.push(reVT);
+               reV.push(reVR);
+               reV.push(reVS);
+               
+               
+               private static const RADIANS_PER_DEGREES:Number = Math.PI / 180;
+               
+               private static const ZERO_REPLACEMENT_IN_3D:Number = 
.00000000000001;
+               
+               private static var tempLocalPosition:Vector3D;
+               
+               /**
+                * @private
+                * a pointer to the function we use to transform vectors, to 
work around a bug
+                * in early versions of the flash player.
+                */
+               private static var transformVector:Function = 
initTransformVectorFunction;
+               
+               /**
+                * @private
+                * an actionscript implementation to transform a vector by a 
matrix. Bugs in early versions of 
+                * flash 10's implementation of Matrix.transformVector force us 
to do it ourselves in actionscript. 
+                */
+               private static function 
pre10_0_22_87_transformVector(m:Matrix3D,v:Vector3D):Vector3D
+               {
+                       var r:Vector.<Number> = m.rawData;
+                       return new Vector3D(
+                               r[0] * v.x + r[4] * v.y + r[8] * v.z + r[12], 
+                               r[1] * v.x + r[5] * v.y + r[9] * v.z + r[13], 
+                               r[2] * v.x + r[6] * v.y + r[10] * v.z + r[14],
+                               1); 
+               }
+               
+               /**
+                * @private
+                * a  function to transform vectors using the built in player 
API, if we're in a late enough player version
+                * that we won't run into bugs.s
+                */
+               private static function 
nativeTransformVector(m:Matrix3D,v:Vector3D):Vector3D
+               {
+                       return m.transformVector(v);
+               }
+               
+               /**
+                * @private
+                * the first time someone calls transformVector, they'll get 
this function.  It checks the player version,
+                * and if decides which implementation to use based on whether 
a bug is present or not.
+                */
+               private static function 
initTransformVectorFunction(m:Matrix3D,v:Vector3D):Vector3D
+               {
+                       var canUseNative:Boolean = false;
+                       var version:Array = Capabilities.version.split(' 
')[1].split(',');
+                       if (parseFloat(version[0]) > 10)
+                               canUseNative  = true;
+                       else if (parseFloat(version[1]) > 0)
+                               canUseNative  = true;
+                       else if (parseFloat(version[2]) > 22)
+                               canUseNative  = true;
+                       else if (parseFloat(version[3]) >= 87)
+                               canUseNative  = true;
+                       if (canUseNative)
+                               transformVector = nativeTransformVector;
+                       else
+                               transformVector = pre10_0_22_87_transformVector;
+                       
+                       return transformVector(m,v);
+               }
+               
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                * layout transform convenience property.  Represents the x 
value of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutX(value:Number):void
+               {
+                       layout.x = value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutX():Number
+               {
+                       return layout.x;
+               }
+               /**
+                * layout transform convenience property.  Represents the y 
value of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutY(value:Number):void
+               {
+                       layout.y = value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutY():Number
+               {
+                       return layout.y;
+               }
+               
+               /**
+                * layout transform convenience property.  Represents the z 
value of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutZ(value:Number):void
+               {
+                       layout.z = value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutZ():Number
+               {
+                       return layout.z;
+               }
+               
+               //----------------------------------
+               //  layoutWidth
+               //----------------------------------
+               
+               private var _layoutWidth:Number = 0;
+               
+               /**
+                *  Used by the mirroring transform.   See the mirror property.
+                *  @default 0
+                */
+               public function get layoutWidth():Number
+               {
+                       return _layoutWidth;
+               }
+               
+               /**
+                *  @private
+                */
+               public function set layoutWidth(value:Number):void
+               {
+                       if (value == _layoutWidth)
+                               return;
+                       _layoutWidth = value;
+                       invalidate();
+               }
+               
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                * @private
+                * the x value of the point around which any rotation and scale 
is performed in both the layout and computed matrix.
+                */
+               public function set transformX(value:Number):void
+               {
+                       layout.transformX = value;
+                       invalidate();
+               }
+               /**
+                * @private
+                */
+               public function get transformX():Number
+               {
+                       return layout.transformX;
+               }
+               
+               /**
+                * @private
+                * the y value of the point around which any rotation and scale 
is performed in both the layout and computed matrix.
+                */
+               public function set transformY(value:Number):void
+               {
+                       layout.transformY = value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get transformY():Number
+               {
+                       return layout.transformY;
+               }
+               
+               /**
+                * @private
+                * the z value of the point around which any rotation and scale 
is performed in both the layout and computed matrix.
+                */
+               public function set transformZ(value:Number):void
+               {
+                       layout.transformZ = value;  
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get transformZ():Number
+               {
+                       return layout.transformZ;
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               
+               /**
+                * layout transform convenience property.  Represents the 
rotation around the X axis of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutRotationX(value:Number):void
+               {
+                       layout.rotationX= value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutRotationX():Number
+               {
+                       return layout.rotationX;
+               }
+               
+               /**
+                * layout transform convenience property.  Represents the 
rotation around the Y axis of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutRotationY(value:Number):void
+               {
+                       layout.rotationY= value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutRotationY():Number
+               {
+                       return layout.rotationY;
+               }
+               
+               /**
+                * layout transform convenience property.  Represents the 
rotation around the Z axis of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutRotationZ(value:Number):void
+               {
+                       layout.rotationZ= value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutRotationZ():Number
+               {
+                       return layout.rotationZ;
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               
+               /**
+                * layout transform convenience property.  Represents the scale 
along the X axis of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutScaleX(value:Number):void
+               {
+                       layout.scaleX = value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutScaleX():Number
+               {
+                       return layout.scaleX;
+               }
+               
+               /**
+                * layout transform convenience property.  Represents the scale 
along the Y axis of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutScaleY(value:Number):void
+               {
+                       layout.scaleY= value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutScaleY():Number
+               {
+                       return layout.scaleY;
+               }
+               
+               
+               /**
+                * layout transform convenience property.  Represents the scale 
along the Z axis of the layout matrix used in layout and in 
+                * the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set layoutScaleZ(value:Number):void
+               {
+                       layout.scaleZ= value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutScaleZ():Number
+               {
+                       return layout.scaleZ;
+               }
+               
+               /**
+                * @private
+                * The 2D matrix used during layout calculations to determine 
the layout and size of the component and its parent and siblings.
+                * If the convenience properties are set, this matrix is built 
from those properties.  
+                * If the matrix is set directly, the convenience properties 
will be updated to values derived from this matrix.
+                * This matrix is used in the calculation of the computed 
transform if possible. Under certain circumstances, such as when 
+                * offsets are provided, the decomposed layout properties will 
be used instead.
+                */
+               public function set layoutMatrix(value:Matrix):void
+               {
+                       layout.matrix = value;
+                       invalidate();
+               }
+               
+               
+               /**
+                * @private
+                */
+               public function get layoutMatrix():Matrix
+               {
+                       return layout.matrix;
+                       
+               }
+               
+               
+               /**
+                * @private
+                * The 3D matrix used during layout calculations to determine 
the layout and size of the component and its parent and siblings.
+                * This matrix is only used by parents that respect 3D layoyut.
+                * If the convenience properties are set, this matrix is built 
from those properties.  
+                * If the matrix is set directly, the convenience properties 
will be updated to values derived from this matrix.
+                * This matrix is used in the calculation of the computed 
transform if possible. Under certain circumstances, such as when 
+                * offsets are provided, the decomposed layout properties will 
be used instead.
+                */
+               public function set layoutMatrix3D(value:Matrix3D):void
+               {
+                       layout.matrix3D = value;
+                       invalidate();
+               }
+               
+               /**
+                * @private
+                */
+               public function get layoutMatrix3D():Matrix3D
+               {
+                       return layout.matrix3D;
+               }
+               
+               /**
+                * true if the computed transform has 3D values.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function get is3D():Boolean
+               {
+                       return (layout.is3D || (postLayoutTransformOffsets != 
null && postLayoutTransformOffsets.is3D));
+               }
+               
+               /**
+                * true if the layout transform has 3D values.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function get layoutIs3D():Boolean
+               {
+                       return layout.is3D;
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               /** offsets to the transform convenience properties that are 
applied when a component is rendered. If this 
+                * property is set, its values will be added to the layout 
transform properties to determine the true matrix used to render
+                * the component
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set 
postLayoutTransformOffsets(value:TransformOffsets):void
+               {
+                       if (_postLayoutTransformOffsets != null)
+                       {
+                               
_postLayoutTransformOffsets.removeEventListener(Event.CHANGE,postLayoutTransformOffsetsChangedHandler);
+                               _postLayoutTransformOffsets.owner = null;
+                       }
+                       _postLayoutTransformOffsets = value;
+                       if (_postLayoutTransformOffsets != null)
+                       {
+                               
_postLayoutTransformOffsets.addEventListener(Event.CHANGE,postLayoutTransformOffsetsChangedHandler);
+                               _postLayoutTransformOffsets.owner = this;
+                       }
+                       invalidate();       
+               }
+               
+               public function get 
postLayoutTransformOffsets():TransformOffsets
+               {
+                       return _postLayoutTransformOffsets;
+               }
+               
+               private function 
postLayoutTransformOffsetsChangedHandler(e:Event):void
+               {
+                       invalidate();       
+               }
+               
+               //----------------------------------
+               //  mirror
+               //----------------------------------
+               
+               private var _mirror:Boolean = false;
+               
+               /**
+                *  If true the X axis is scaled by -1 and the x coordinate of 
the origin
+                *  is translated by the component's width.  
+                * 
+                *  The net effect of this "mirror" transform is to flip the 
direction 
+                *  that the X axis increases in without changing the layout 
element's 
+                *  location relative to the parent's origin.
+                * 
+                *  @default false
+                */
+               public function get mirror():Boolean
+               {
+                       return _mirror;
+               }
+               
+               /**
+                *  @private
+                */
+               public function set mirror(value:Boolean):void
+               {
+                       _mirror = value;
+                       invalidate();
+               }
+               
+               
+               //----------------------------------
+               //  stretchX
+               //----------------------------------
+               
+               private var _stretchX:Number = 1;
+               
+               /**
+                *  The stretchY is the horizontal component of the stretch 
scale factor which
+                *  is applied before any other transformation property.
+                *  @default 1
+                */
+               public function get stretchX():Number
+               {
+                       return _stretchX;
+               }
+               
+               /**
+                *  @private
+                */
+               public function set stretchX(value:Number):void
+               {
+                       if (value == _stretchX)
+                               return;         
+                       _stretchX = value;
+                       invalidate();
+               }
+               
+               //----------------------------------
+               //  stretchY
+               //----------------------------------
+               
+               private var _stretchY:Number = 1;
+               
+               /**
+                *  The stretchY is the vertical component of the stretch scale 
factor which
+                *  is applied before any other transformation property.
+                *  @default 1
+                */
+               public function get stretchY():Number
+               {
+                       return _stretchY;
+               }
+               
+               /**
+                *  @private
+                */
+               public function set stretchY(value:Number):void
+               {
+                       if (value == _stretchY)
+                               return;         
+                       _stretchY = value;
+                       invalidate();
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                * @private
+                * invalidates our various cached values.  Any change to the 
AdvancedLayoutFeatures object that affects
+                * the various transforms should call this function.    
+                * @param reason - the code indicating what changes to cause 
the invalidation.
+                * @param affects3D - a flag indicating whether the change 
affects the 2D/3D nature of the various transforms.
+                * @param dispatchChangeEvent - if true, the 
AdvancedLayoutFeatures will dispatch a change indicating that its underlying 
transforms
+                * have been modified. 
+                */
+               private function invalidate():void
+               {                       
+                       _flags &= ~COMPUTED_MATRIX_VALID;
+                       _flags &= ~COMPUTED_MATRIX3D_VALID;
+               }
+               
+               
+               /**
+                * the computed matrix, calculated by combining the layout 
matrix and  and any offsets provided..
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function get computedMatrix():Matrix
+               {
+                       if (_flags & COMPUTED_MATRIX_VALID)
+                               return _computedMatrix;
+                       
+                       if (!postLayoutTransformOffsets && !mirror && stretchX 
== 1 && stretchY == 1)
+                       {
+                               return layout.matrix;
+                       }           
+                       
+                       var m:Matrix = _computedMatrix;
+                       if (m == null)
+                               m = _computedMatrix = new Matrix();
+                       else
+                               m.identity();
+                       
+                       var tx:Number = layout.transformX;
+                       var ty:Number = layout.transformY;
+                       var sx:Number = layout.scaleX;
+                       var sy:Number = layout.scaleY;
+                       var rz:Number = layout.rotationZ;
+                       var x:Number = layout.x;
+                       var y:Number = layout.y;
+                       
+                       if (mirror)
+                       {
+                               sx *= -1;
+                               x += layoutWidth;
+                       }
+                       
+                       if (postLayoutTransformOffsets)
+                       {
+                               sx *= postLayoutTransformOffsets.scaleX;
+                               sy *= postLayoutTransformOffsets.scaleY;
+                               rz += postLayoutTransformOffsets.rotationZ;
+                               x += postLayoutTransformOffsets.x;
+                               y += postLayoutTransformOffsets.y;
+                       }
+                       
+                       if (stretchX != 1 || stretchY != 1)
+                               m.scale(stretchX, stretchY);
+                       build2DMatrix(m, tx, ty, sx, sy, rz, x, y);
+                       
+                       _flags |= COMPUTED_MATRIX_VALID;
+                       return m;
+               }
+               
+               /**
+                * the computed 3D matrix, calculated by combining the 3D 
layout matrix and  and any offsets provided..
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function get computedMatrix3D():Matrix3D
+               {
+                       if (_flags & COMPUTED_MATRIX3D_VALID)
+                               return _computedMatrix3D;
+                       
+                       
+                       if (!postLayoutTransformOffsets && !mirror && stretchX 
== 1 && stretchY == 1)
+                       {
+                               return layout.matrix3D;
+                       }
+                       
+                       var m:Matrix3D = _computedMatrix3D;
+                       if (m == null)
+                               m = _computedMatrix3D = new Matrix3D();
+                       else
+                               m.identity();
+                       
+                       var tx:Number = layout.transformX;
+                       var ty:Number = layout.transformY;
+                       var tz:Number = layout.transformZ;
+                       var sx:Number = layout.scaleX;
+                       var sy:Number = layout.scaleY;
+                       var sz:Number = layout.scaleZ;
+                       var rx:Number = layout.rotationX;
+                       var ry:Number = layout.rotationY;
+                       var rz:Number = layout.rotationZ;
+                       var x:Number = layout.x;
+                       var y:Number = layout.y;
+                       var z:Number = layout.z;
+                       
+                       if (mirror)
+                       {
+                               sx *= -1;
+                               x += layoutWidth;
+                       }
+                       
+                       if (postLayoutTransformOffsets)
+                       {
+                               sx *= postLayoutTransformOffsets.scaleX;
+                               sy *= postLayoutTransformOffsets.scaleY;
+                               sz *= postLayoutTransformOffsets.scaleZ;
+                               rx += postLayoutTransformOffsets.rotationX;
+                               ry += postLayoutTransformOffsets.rotationY;
+                               rz += postLayoutTransformOffsets.rotationZ;
+                               x += postLayoutTransformOffsets.x;
+                               y += postLayoutTransformOffsets.y;
+                               z += postLayoutTransformOffsets.z;
+                       }
+                       
+                       build3DMatrix(m, tx, ty, tz, sx, sy, sz, rx, ry, rz, x, 
y, z);
+                       // Always prepend last
+                       if (stretchX != 1 || stretchY != 1)
+                               m.prependScale(stretchX, stretchY, 1);  
+                       
+                       _flags |= COMPUTED_MATRIX3D_VALID;
+                       return m;           
+               }
+               
+               
+               /**
+                * @private
+                * convenience function for building a 2D matrix from the 
convenience properties 
+                */
+               public static function build2DMatrix(m:Matrix,
+                                                                               
         tx:Number,ty:Number,
+                                                                               
         sx:Number,sy:Number,
+                                                                               
         rz:Number,
+                                                                               
         x:Number,y:Number):void
+               {
+                       m.translate(-tx,-ty);
+                       m.scale(sx,sy);
+                       m.rotate(rz* RADIANS_PER_DEGREES);
+                       m.translate(x+tx,y+ty);         
+               }
+               
+               
+               /**
+                * @private
+                * convenience function for building a 3D matrix from the 
convenience properties 
+                */
+               public static function build3DMatrix(m:Matrix3D,
+                                                                               
         tx:Number,ty:Number,tz:Number,
+                                                                               
         sx:Number,sy:Number,sz:Number,
+                                                                               
         rx:Number,ry:Number,rz:Number,
+                                                                               
         x:Number,y:Number,z:Number):void
+               {
+                       reVR.x = rx * RADIANS_PER_DEGREES;
+                       reVR.y = ry * RADIANS_PER_DEGREES;
+                       reVR.z = rz * RADIANS_PER_DEGREES;
+                       m.recompose(reV);
+                       if (sx == 0)
+                               sx = ZERO_REPLACEMENT_IN_3D;
+                       if (sy == 0)
+                               sy = ZERO_REPLACEMENT_IN_3D;
+                       if (sz == 0)
+                               sz = ZERO_REPLACEMENT_IN_3D;
+                       m.prependScale(sx,sy,sz);
+                       m.prependTranslation(-tx,-ty,-tz);
+                       m.appendTranslation(tx+x,ty+y,tz+z);
+               }                                   
+               
+               
+               /**
+                * A utility method to transform a point specified in the local
+                * coordinates of this object to its location in the object's 
parent's 
+                * coordinates. The pre-layout and post-layout result will be 
set on 
+                * the <code>position</code> and <code>postLayoutPosition</code>
+                * parameters, if they are non-null.
+                * 
+                * @param propertyIs3D A boolean reflecting whether the 
calculation needs
+                * to take into account the 3D matrix of the object.
+                * @param localPoint The point to be transformed, specified in 
the
+                * local coordinates of the object.
+                * @position A Vector3D point that will hold the pre-layout
+                * result. If null, the parameter is ignored.
+                * @postLayoutPosition A Vector3D point that will hold the 
post-layout
+                * result. If null, the parameter is ignored.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4
+                */
+               public function transformPointToParent(propertyIs3D:Boolean,
+                                                                               
           localPosition:Vector3D, position:Vector3D,
+                                                                               
           postLayoutPosition:Vector3D):void
+               {
+                       var transformedV:Vector3D;
+                       var transformedP:Point;
+                       tempLocalPosition = 
+                               localPosition ?
+                               localPosition.clone() :
+                               new Vector3D();
+                       
+                       if (is3D || propertyIs3D) 
+                       {
+                               if (position != null)
+                               {
+                                       transformedV = 
transformVector(layoutMatrix3D, tempLocalPosition); 
+                                       position.x = transformedV.x;
+                                       position.y = transformedV.y;
+                                       position.z = transformedV.z;
+                               } 
+                               
+                               if (postLayoutPosition != null)
+                               {           
+                                       // computedMatrix factor in stretchXY, 
so divide it out of position first
+                                       tempLocalPosition.x /= stretchX;
+                                       tempLocalPosition.y /= stretchY;
+                                       transformedV = 
transformVector(computedMatrix3D, tempLocalPosition);
+                                       postLayoutPosition.x = transformedV.x;
+                                       postLayoutPosition.y = transformedV.y;
+                                       postLayoutPosition.z = transformedV.z;
+                               }
+                       }
+                       else
+                       {
+                               var localP:Point = new 
Point(tempLocalPosition.x, 
+                                       tempLocalPosition.y);
+                               if (position != null)
+                               {
+                                       transformedP = 
layoutMatrix.transformPoint(localP);
+                                       position.x = transformedP.x;
+                                       position.y = transformedP.y;
+                                       position.z = 0;
+                               }
+                               
+                               if (postLayoutPosition != null)
+                               {
+                                       // computedMatrix factor in stretchXY, 
so divide it out of position first
+                                       localP.x /= stretchX;
+                                       localP.y /= stretchY;
+                                       transformedP = 
computedMatrix.transformPoint(localP);
+                                       postLayoutPosition.x = transformedP.x;
+                                       postLayoutPosition.y = transformedP.y;
+                                       postLayoutPosition.z = 0;
+                               }
+                       }
+               }
+               
+               /**
+                * @private
+                * call when you've changed the inputs to the computed 
transform to make 
+                * any adjustments to keep a particular point fixed in parent 
coordinates.
+                */
+               private function 
completeTransformCenterAdjustment(changeIs3D:Boolean, 
+                                                                               
                                   transformCenter:Vector3D, 
targetPosition:Vector3D,
+                                                                               
                                   targetPostLayoutPosition:Vector3D):void
+               {
+                       // TODO (chaase): optimize for transformCenter == 
(0,0,0)
+                       if (is3D || changeIs3D)
+                       {
+                               if (targetPosition != null)
+                               {
+                                       var adjustedLayoutCenterV:Vector3D = 
transformVector(layoutMatrix3D, transformCenter); 
+                                       if 
(adjustedLayoutCenterV.equals(targetPosition) == false)
+                                       {
+                                               
layout.translateBy(targetPosition.x - adjustedLayoutCenterV.x,
+                                                       targetPosition.y - 
adjustedLayoutCenterV.y, 
+                                                       targetPosition.z - 
adjustedLayoutCenterV.z);
+                                               invalidate(); 
+                                       }       
+                               }
+                               if (targetPostLayoutPosition != null && 
_postLayoutTransformOffsets != null)
+                               {
+                                       // computedMatrix factor in stretchXY, 
so divide it out of transform center first
+                                       var tmpPos:Vector3D = new 
Vector3D(transformCenter.x, transformCenter.y, transformCenter.z);
+                                       tmpPos.x /= stretchX;
+                                       tmpPos.y /= stretchY;
+                                       var adjustedComputedCenterV:Vector3D = 
transformVector(computedMatrix3D, tmpPos);
+                                       if 
(adjustedComputedCenterV.equals(targetPostLayoutPosition) == false)
+                                       {
+                                               postLayoutTransformOffsets.x 
+=targetPostLayoutPosition.x - adjustedComputedCenterV.x;
+                                               postLayoutTransformOffsets.y += 
targetPostLayoutPosition.y - adjustedComputedCenterV.y;
+                                               postLayoutTransformOffsets.z += 
targetPostLayoutPosition.z - adjustedComputedCenterV.z;
+                                               invalidate(); 
+                                       }       
+                               }
+                       }
+                       else
+                       {
+                               var transformCenterP:Point = new 
Point(transformCenter.x,transformCenter.y);
+                               if (targetPosition != null)
+                               {
+                                       var currentPositionP:Point = 
layoutMatrix.transformPoint(transformCenterP);
+                                       if (currentPositionP.x != 
targetPosition.x || 
+                                               currentPositionP.y != 
targetPosition.y)
+                                       {
+                                               
layout.translateBy(targetPosition.x - currentPositionP.x,
+                                                       targetPosition.y - 
currentPositionP.y, 0);
+                                               invalidate(); 
+                                       }       
+                               }
+                               
+                               if (targetPostLayoutPosition != null && 
_postLayoutTransformOffsets != null)
+                               {           
+                                       // computedMatrix factor in stretchXY, 
so divide it out of transform center first
+                                       transformCenterP.x /= stretchX;
+                                       transformCenterP.y /= stretchY;
+                                       var currentPostLayoutPosition:Point = 
+                                               
computedMatrix.transformPoint(transformCenterP);
+                                       if (currentPostLayoutPosition.x != 
targetPostLayoutPosition.x || 
+                                               currentPostLayoutPosition.y != 
targetPostLayoutPosition.y)
+                                       {
+                                               _postLayoutTransformOffsets.x 
+= targetPostLayoutPosition.x - currentPostLayoutPosition.x;
+                                               _postLayoutTransformOffsets.y 
+= targetPostLayoutPosition.y - currentPostLayoutPosition.y;
+                                               invalidate(); 
+                                       }       
+                               }
+                       }
+               }   
+               
+               private static var staticTranslation:Vector3D = new Vector3D();
+               private static var staticOffsetTranslation:Vector3D = new 
Vector3D();
+               
+               /**
+                * A utility method to update the rotation and scale of the 
transform 
+                * while keeping a particular point, specified in the 
component's own 
+                * coordinate space, fixed in the parent's coordinate space.  
This 
+                * function will assign the rotation and scale values provided, 
then 
+                * update the x/y/z properties as necessary to keep tx/ty/tz 
fixed.
+                * @param transformCenter the point, in the component's own 
coordinates, 
+                * to keep fixed relative to its parent.
+                * @param rotation the new values for the rotation of the 
transform
+                * @param scale the new values for the scale of the transform
+                * @param translation the new values for the translation of the 
transform
+                */
+               public function transformAround(transformCenter:Vector3D,
+                                                                               
scale:Vector3D,
+                                                                               
rotation:Vector3D,
+                                                                               
transformCenterPosition:Vector3D,
+                                                                               
postLayoutScale:Vector3D = null,
+                                                                               
postLayoutRotation:Vector3D = null,
+                                                                               
postLayoutTransformCenterPosition:Vector3D = null):void
+               {
+                       var is3D:Boolean = (scale != null && scale.z != 1) ||
+                               (rotation != null && ((rotation.x != 0 ) || 
(rotation.y != 0))) || 
+                               (transformCenterPosition != null && 
transformCenterPosition.z != 0) ||
+                               (postLayoutScale != null && postLayoutScale.z 
!= 1) ||
+                               (postLayoutRotation != null && 
+                                       (postLayoutRotation.x != 0 || 
postLayoutRotation.y != 0)) || 
+                               (postLayoutTransformCenterPosition != null && 
postLayoutTransformCenterPosition.z != 0);
+                       
+                       var needOffsets:Boolean = _postLayoutTransformOffsets 
== null && 
+                               (postLayoutScale != null || postLayoutRotation 
!= null || 
+                                       postLayoutTransformCenterPosition != 
null);
+                       if (needOffsets)
+                               _postLayoutTransformOffsets = new 
TransformOffsets();                                               
+                       
+                       // now if they gave us a non-trivial transform center, 
and didn't tell us where they want it, 
+                       // we need to calculate where it is so that we can make 
sure we keep it there.             
+                       if (transformCenter != null && 
+                               (transformCenterPosition == null || 
postLayoutTransformCenterPosition == null))
+                       {           
+                               transformPointToParent(is3D, transformCenter, 
staticTranslation,
+                                       staticOffsetTranslation);
+                               if (postLayoutTransformCenterPosition == null 
&& transformCenterPosition != null)
+                               {
+                                       staticOffsetTranslation.x = 
transformCenterPosition.x + staticOffsetTranslation.x - staticTranslation.x;
+                                       staticOffsetTranslation.y = 
transformCenterPosition.y + staticOffsetTranslation.y - staticTranslation.y;
+                                       staticOffsetTranslation.z = 
transformCenterPosition.z + staticOffsetTranslation.z - staticTranslation.z;
+                               }
+                               
+                       }
+                       // if targetPosition/postLayoutTargetPosition is null 
here, it might be because the caller passed in
+                       // requested values, so we haven't calculated it yet.  
So that means our target position is the values
+                       // they passed in.        
+                       var targetPosition:Vector3D = (transformCenterPosition 
== null)? staticTranslation:transformCenterPosition;
+                       var postLayoutTargetPosition:Vector3D = 
(postLayoutTransformCenterPosition == null)? 
staticOffsetTranslation:postLayoutTransformCenterPosition;
+                       
+                       // now update our transform values.     
+                       if (rotation != null)
+                       {
+                               if (!isNaN(rotation.x))
+                                       layout.rotationX = rotation.x;
+                               if (!isNaN(rotation.y))
+                                       layout.rotationY = rotation.y;
+                               if (!isNaN(rotation.z))
+                                       layout.rotationZ = rotation.z;
+                       }
+                       if (scale != null)
+                       {           
+                               if (!isNaN(scale.x))
+                                       layout.scaleX = scale.x;
+                               if (!isNaN(scale.y))
+                                       layout.scaleY = scale.y;
+                               if (!isNaN(scale.z))
+                                       layout.scaleZ = scale.z;
+                       }
+                       
+                       if (postLayoutRotation != null)
+                       {           
+                               _postLayoutTransformOffsets.rotationX = 
postLayoutRotation.x;
+                               _postLayoutTransformOffsets.rotationY = 
postLayoutRotation.y;
+                               _postLayoutTransformOffsets.rotationZ = 
postLayoutRotation.z;
+                       }
+                       if (postLayoutScale != null)
+                       {           
+                               _postLayoutTransformOffsets.scaleX = 
postLayoutScale.x;
+                               _postLayoutTransformOffsets.scaleY = 
postLayoutScale.y;
+                               _postLayoutTransformOffsets.scaleZ = 
postLayoutScale.z;
+                       }
+                       
+                       // if they didn't pass us a transform center, 
+                       // then we assume it's the origin. In that case, it's 
trivially easy
+                       // to make sure the origin is at a particular 
point...we simply set 
+                       // the transformCenterPosition portion of our 
transforms to that point. 
+                       if (transformCenter == null)
+                       {
+                               if (transformCenterPosition != null)
+                               {
+                                       layout.x = transformCenterPosition.x;
+                                       layout.y = transformCenterPosition.y;
+                                       layout.z = transformCenterPosition.z;
+                               }
+                               if (postLayoutTransformCenterPosition != null)
+                               {
+                                       _postLayoutTransformOffsets.x = 
postLayoutTransformCenterPosition.x - layout.x;
+                                       _postLayoutTransformOffsets.y = 
postLayoutTransformCenterPosition.y - layout.y;
+                                       _postLayoutTransformOffsets.z = 
postLayoutTransformCenterPosition.z - layout.z;
+                               }
+                       }
+                       invalidate();
+                       
+                       // if they did pass in a transform center, go do the 
adjustments necessary to keep it fixed in place.
+                       if (transformCenter != null)
+                               completeTransformCenterAdjustment(is3D, 
transformCenter, 
+                                       targetPosition, 
postLayoutTargetPosition);
+                       
+                       
+               }
+               
+       }
+}
+

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/7d529524/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/CompoundTransform.as
----------------------------------------------------------------------
diff --git 
a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/CompoundTransform.as
 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/CompoundTransform.as
new file mode 100644
index 0000000..6259bd6
--- /dev/null
+++ 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/CompoundTransform.as
@@ -0,0 +1,777 @@
+/**
+ * Licensed 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 org.apache.flex.graphics.utils
+{
+       import flash.geom.Matrix;
+       import flash.geom.Matrix3D;
+       import flash.geom.Vector3D;
+       
+       import __AS3__.vec.Vector;
+       
+       /**
+        *  A CompoundTransform represents a 2D or 3D matrix transform.  A 
compound transform represents a matrix that can be queried or set either as a 
2D matrix,
+        *  a 3D matrix, or as individual convenience transform properties such 
as x, y, scaleX, rotationZ, etc. 
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 9
+        *  @playerversion AIR 1.1
+        *  @productversion Flex 3
+        */
+       public class CompoundTransform
+       {
+               
//--------------------------------------------------------------------------
+               //
+               //  Constructor
+               //
+               
//--------------------------------------------------------------------------
+               /**
+                *  Constructor.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function CompoundTransform()
+               {
+               }
+               
+               
+               
+               /**
+                * @private
+                * storage for transform properties. These values are 
concatenated together with the layout properties to
+                * form the actual computed matrix used to render the object.
+                */
+               private var _rotationX:Number = 0;
+               private var _rotationY:Number = 0;
+               private var _rotationZ:Number = 0;
+               private var _scaleX:Number = 1;
+               private var _scaleY:Number = 1;
+               private var _scaleZ:Number = 1;     
+               private var _x:Number = 0;
+               private var _y:Number = 0;
+               private var _z:Number = 0;
+               
+               private var _transformX:Number = 0;
+               private var _transformY:Number = 0;
+               private var _transformZ:Number = 0;
+               
+               
+               /**
+                * @private
+                * slots for the 2D and 3D matrix transforms.  Note that 
+                * these are only allocated and computed on demand -- many 
component instances will never use a 3D
+                * matrix, for example. 
+                */
+               private var _matrix:Matrix;
+               private var _matrix3D:Matrix3D;
+               
+               
+               /**
+                * @private
+                * bit field flags for indicating which transforms are valid -- 
the layout properties, the matrices,
+                * and the 3D matrices.  Since developers can set any of the 
three programmatically, the last one set
+                * will always be valid, and the others will be invalid until 
validated on demand.
+                */
+               private static const MATRIX_VALID:uint      = 0x20;
+               private static const MATRIX3D_VALID:uint        = 0x40;
+               private static const PROPERTIES_VALID:uint  = 0x80;
+               
+               
+               /**
+                * @private
+                * flags for tracking whether the  transform is 3D. A transform 
is 3D if any of the 3D properties -- rotationX/Y, scaleZ, or z -- are set.
+                */
+               private static const IS_3D:uint                 = 0x200;
+               private static const M3D_FLAGS_VALID:uint           = 0x400;
+               
+               /**
+                * @private
+                * constants to indicate which form of a transform -- the 
properties, matrix, or matrix3D -- is
+                *  'the source of truth.'   
+                */
+               public static const SOURCE_PROPERTIES:uint          = 1;
+               /**
+                * @private
+                * constants to indicate which form of a transform -- the 
properties, matrix, or matrix3D -- is
+                *  'the source of truth.'   
+                */
+               public static const SOURCE_MATRIX:uint          = 2;
+               /**
+                * @private
+                * constants to indicate which form of a transform -- the 
properties, matrix, or matrix3D -- is
+                *  'the source of truth.'   
+                */
+               public static const SOURCE_MATRIX3D:uint            = 3;
+               
+               /**
+                * @private
+                * indicates the 'source of truth' for the transform.  
+                */
+               public var sourceOfTruth:uint = SOURCE_PROPERTIES;
+               
+               /**
+                * @private
+                * general storage for all of ur flags.  
+                */
+               private var _flags:uint =  PROPERTIES_VALID;
+               
+               /**
+                * @private
+                * flags that get passed to the invalidate method indicating 
why the invalidation is happening.
+                */
+               private static const INVALIDATE_FROM_NONE:uint =            0;  
                    
+               private static const INVALIDATE_FROM_PROPERTY:uint =        4;  
                    
+               private static const INVALIDATE_FROM_MATRIX:uint =          5;  
                    
+               private static const INVALIDATE_FROM_MATRIX3D:uint =        6;  
                    
+               
+               /**
+                * @private
+                * static data used by utility methods below
+                */
+               private static var decomposition:Vector.<Number> = new 
Vector.<Number>();
+               decomposition.push(0);
+               decomposition.push(0);
+               decomposition.push(0);
+               decomposition.push(0);
+               decomposition.push(0);
+               
+               private static const RADIANS_PER_DEGREES:Number = Math.PI / 180;
+               
+               
//----------------------------------------------------------------------------
+               
+               /**
+                *  The x value of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set x(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _x)
+                               return;
+                       translateBy(value-_x,0,0);
+                       invalidate(INVALIDATE_FROM_PROPERTY, false 
/*affects3D*/);
+               }
+               /**
+                * @private
+                */
+               public function get x():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _x;
+               }
+               
+               /**
+                *  The y value of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set y(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _y)
+                               return;
+                       translateBy(0,value-_y,0);
+                       invalidate(INVALIDATE_FROM_PROPERTY, false 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get y():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _y;
+               }
+               
+               /**
+                *  The z value of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set z(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _z)
+                               return;
+                       translateBy(0,0,value-_z);
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get z():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _z;
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               
+               /**
+                *  The rotationX, in degrees, of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set rotationX(value:Number):void
+               {
+                       // clamp the rotation value between -180 and 180.  This 
is what 
+                       // the Flash player does, so let's mimic it here too.
+                       value = MatrixUtil.clampRotation(value);
+                       
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _rotationX)
+                               return;
+                       _rotationX = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get rotationX():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _rotationX;
+               }
+               
+               /**
+                *  The rotationY, in degrees, of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set rotationY(value:Number):void
+               {
+                       // clamp the rotation value between -180 and 180.  This 
is what 
+                       // the Flash player does, so let's mimic it here too.
+                       value = MatrixUtil.clampRotation(value);
+                       
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _rotationY)
+                               return;
+                       _rotationY = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get rotationY():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _rotationY;
+               }
+               
+               /**
+                *  The rotationZ, in degrees, of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set rotationZ(value:Number):void
+               {
+                       // clamp the rotation value between -180 and 180.  This 
is what 
+                       // the Flash player does, so let's mimic it here too.
+                       value = MatrixUtil.clampRotation(value);
+                       
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _rotationZ)
+                               return;
+                       _rotationZ = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, false 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get rotationZ():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _rotationZ;
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               
+               /**
+                *  The scaleX of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set scaleX(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _scaleX)
+                               return;
+                       _scaleX = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, false 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get scaleX():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _scaleX;
+               }
+               
+               /**
+                *  The scaleY of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set scaleY(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _scaleY)
+                               return;
+                       _scaleY = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, false 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get scaleY():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _scaleY;
+               }
+               
+               
+               /**
+                *  The scaleZ of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set scaleZ(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _scaleZ)
+                               return;
+                       _scaleZ = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get scaleZ():Number
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       return _scaleZ;
+               }
+               
+               
+               /**
+                * @private
+                * returns true if the transform has 3D values.
+                */
+               public function get is3D():Boolean
+               {
+                       if ((_flags & M3D_FLAGS_VALID) == 0)
+                               update3DFlags();
+                       return ((_flags & IS_3D) != 0);
+               }
+               
+               
//------------------------------------------------------------------------------
+               /**
+                *  The x value of the transform center. The transform center 
is kept fixed as rotation and scale are applied. 
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set transformX(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _transformX)
+                               return;
+                       _transformX = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get transformX():Number
+               {
+                       return _transformX;
+               }
+               
+               
//------------------------------------------------------------------------------
+               /**
+                *  The y value of the tansform center. The transform center is 
kept fixed as rotation and scale are applied. 
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set transformY(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _transformY)
+                               return;
+                       _transformY = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get transformY():Number
+               {
+                       return _transformY;
+               }
+               
//------------------------------------------------------------------------------
+               /**
+                *  The z value of the tansform center. The transform center is 
kept fixed as rotation and scale are applied. 
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function set transformZ(value:Number):void
+               {
+                       if ((_flags & PROPERTIES_VALID) == false) 
validatePropertiesFromMatrix();
+                       if (value == _transformZ)
+                               return;
+                       _transformZ = value;
+                       invalidate(INVALIDATE_FROM_PROPERTY, true 
/*affects3D*/);
+               }
+               
+               /**
+                * @private
+                */
+               public function get transformZ():Number
+               {
+                       return _transformZ;
+               }
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                * @private
+                * invalidates our various cached values.  Any change to the 
CompoundTransform object that affects
+                * the various transforms should call this function. 
+                * @param reason - the code indicating what changes to cause 
the invalidation.
+                * @param affects3D - a flag indicating whether the change 
affects the 2D/3D nature of the various transforms.
+                * @param dispatchChangeEvent - if true, the CompoundTransform 
will dispatch a change indicating that its underlying transforms
+                * have been modified. 
+                */
+               private function invalidate(reason:uint, affects3D:Boolean):void
+               {
+                       //race("invalidating: " + reason);
+                       switch(reason)
+                       {
+                               case INVALIDATE_FROM_PROPERTY:
+                                       sourceOfTruth = SOURCE_PROPERTIES;
+                                       _flags |= PROPERTIES_VALID;
+                                       _flags &= ~MATRIX_VALID;
+                                       _flags &= ~MATRIX3D_VALID;
+                                       break;
+                               case INVALIDATE_FROM_MATRIX:
+                                       sourceOfTruth = SOURCE_MATRIX;
+                                       _flags |= MATRIX_VALID;
+                                       _flags &= ~PROPERTIES_VALID;
+                                       _flags &= ~MATRIX3D_VALID;
+                                       break;
+                               case INVALIDATE_FROM_MATRIX3D:
+                                       sourceOfTruth = SOURCE_MATRIX3D;
+                                       _flags |= MATRIX3D_VALID;
+                                       _flags &= ~PROPERTIES_VALID;
+                                       _flags &= ~MATRIX_VALID;
+                                       break;
+                       }                       
+                       if (affects3D)
+                               _flags &= ~M3D_FLAGS_VALID;
+                       
+               }
+               
+               private static const EPSILON:Number = .001;
+               /**
+                * @private
+                * updates the flags that indicate whether the layout, offset, 
and/or computed transforms are 3D in nature.  
+                * Since the user can set either the individual transform 
properties or the matrices directly, we compute these 
+                * flags based on what the current 'source of truth' is for 
each of these values.
+                */
+               private function update3DFlags():void
+               {           
+                       if ((_flags & M3D_FLAGS_VALID) == 0)
+                       {
+                               var matrixIs3D:Boolean = false;
+                               
+                               switch(sourceOfTruth)
+                               {
+                                       case SOURCE_PROPERTIES:
+                                               matrixIs3D = ( // note that 
rotationZ is the same as rotation, and not a 3D affecting                       
    
+                                                       (Math.abs(_scaleZ-1) > 
EPSILON) ||  // property.
+                                                       
((Math.abs(_rotationX)+EPSILON)%360) > 2*EPSILON ||
+                                                       
((Math.abs(_rotationY)+EPSILON)%360) > 2*EPSILON ||
+                                                       Math.abs(_z) > EPSILON
+                                               );
+                                               break;
+                                       case SOURCE_MATRIX:
+                                               matrixIs3D = false;
+                                               break;
+                                       case SOURCE_MATRIX3D:
+                                               var rawData:Vector.<Number> = 
_matrix3D.rawData;                    
+                                               matrixIs3D = (rawData[2] != 0 
||        // rotation y 
+                                                       rawData[6] != 0 ||      
// rotation x
+                                                       rawData[8] !=0 ||       
// rotation y
+                                                       rawData[10] != 1 ||     
// scalez / rotation x / rotation y
+                                                       rawData[14] != 0);      
// translation z
+                                               break;                          
    
+                               }
+                               
+                               if (matrixIs3D)
+                                       _flags |= IS_3D;
+                               else
+                                       _flags &= ~IS_3D;
+                               
+                               _flags |= M3D_FLAGS_VALID;
+                       }
+               }
+               
+               
+               /** 
+                *  Applies the delta to the transform's translation component. 
Unlike setting the x, y, or z properties directly,
+                *  this method can be safely called without changing the 
transform's concept of 'the source of truth'.
+                * 
+                *  @param x The x value of the transform.
+                *  
+                *  @param y The y value of the transform.
+                *  
+                *  @param z The z value of the transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function translateBy(x:Number,y:Number,z:Number = 0):void
+               {
+                       if (_flags & MATRIX_VALID)
+                       {
+                               _matrix.tx += x;
+                               _matrix.ty += y;
+                       }
+                       if (_flags & PROPERTIES_VALID)
+                       {
+                               _x += x;
+                               _y += y;
+                               _z += z;
+                       }
+                       if (_flags & MATRIX3D_VALID)
+                       {
+                               var data:Vector.<Number> = _matrix3D.rawData;
+                               data[12] += x;
+                               data[13] += y;
+                               data[14] += z;
+                               _matrix3D.rawData = data;           
+                       }   
+                       invalidate(INVALIDATE_FROM_NONE, z != 0 /*affects3D*/);
+               }
+               
+               
+               /**
+                *  The 2D matrix either set directly by the user, or composed 
by combining the transform center, scale, rotation
+                *  and translation, in that order.  
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function get matrix():Matrix
+               {
+                       
+                       if (_flags & MATRIX_VALID)
+                               return _matrix;
+                       
+                       if ((_flags & PROPERTIES_VALID) == false)
+                               validatePropertiesFromMatrix();
+                       
+                       var m:Matrix = _matrix;
+                       if (m == null)
+                               m = _matrix = new Matrix();
+                       else
+                               m.identity();
+                       
+                       
AdvancedLayoutFeatures.build2DMatrix(m,_transformX,_transformY,
+                               _scaleX,_scaleY,
+                               _rotationZ,
+                               _x,_y);   
+                       _flags |= MATRIX_VALID;
+                       return m;       
+               }
+               
+               /**
+                * @private
+                */ 
+               public function set matrix(v:Matrix):void
+               {
+                       if (_matrix== null)
+                       {
+                               _matrix = v.clone();
+                       }
+                       else
+                       {
+                               _matrix.identity(); 
+                               _matrix.concat(v);          
+                       }
+                       
+                       // affects3D is true since setting matrix changes the 
transform to 2D
+                       invalidate(INVALIDATE_FROM_MATRIX, true /*affects3D*/);
+               }
+               
+               /**
+                * @private
+                * decomposes the offset transform matrices down into the 
convenience offset properties. Note that this is not
+                * a bi-directional transformation -- it is possible to create 
a matrix that can't be fully represented in the
+                * convenience properties. This function will pull from the 
matrix or matrix3D values, depending on which was most
+                * recently set
+                */
+               private function validatePropertiesFromMatrix():void
+               {       
+                       if (sourceOfTruth == SOURCE_MATRIX3D)
+                       {
+                               var result:Vector.<Vector3D> = 
_matrix3D.decompose();
+                               _rotationX = result[1].x / RADIANS_PER_DEGREES;
+                               _rotationY = result[1].y / RADIANS_PER_DEGREES;
+                               _rotationZ = result[1].z / RADIANS_PER_DEGREES;
+                               _scaleX = result[2].x;
+                               _scaleY = result[2].y;
+                               _scaleZ = result[2].z;
+                               
+                               if (_transformX != 0 || _transformY != 0 || 
_transformZ != 0)
+                               {
+                                       var postTransformTCenter:Vector3D = 
_matrix3D.transformVector(new Vector3D(_transformX,_transformY,_transformZ));
+                                       _x = postTransformTCenter.x - 
_transformX;
+                                       _y = postTransformTCenter.y - 
_transformY;
+                                       _z = postTransformTCenter.z - 
_transformZ;
+                               }
+                               else
+                               {
+                                       _x = result[0].x;
+                                       _y = result[0].y;
+                                       _z = result[0].z;
+                               }
+                       }                        
+                       else if (sourceOfTruth == SOURCE_MATRIX)
+                       {
+                               
MatrixUtil.decomposeMatrix(decomposition,_matrix,_transformX,_transformY);
+                               _x = decomposition[0];
+                               _y = decomposition[1];
+                               _z = 0;
+                               _rotationX = 0;
+                               _rotationY = 0;
+                               _rotationZ = decomposition[2];
+                               _scaleX = decomposition[3];
+                               _scaleY = decomposition[4];
+                               _scaleZ = 1;
+                       }
+                       _flags |= PROPERTIES_VALID;
+                       
+               }
+               
+               
+               
+               /**
+                *  The 3D matrix either set directly by the user, or composed 
by combining the transform center, scale, rotation
+                *  and translation, in that order. 
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 9
+                *  @playerversion AIR 1.1
+                *  @productversion Flex 3
+                */
+               public function get matrix3D():Matrix3D
+               {
+                       if (_flags & MATRIX3D_VALID)
+                               return _matrix3D;
+                       
+                       if ((_flags & PROPERTIES_VALID) == false)
+                               validatePropertiesFromMatrix();
+                       
+                       var m:Matrix3D = _matrix3D;
+                       if (m == null)
+                               m =  _matrix3D = new Matrix3D();
+                       else
+                               m.identity();
+                       
+                       
AdvancedLayoutFeatures.build3DMatrix(m,transformX,transformY,transformZ,
+                               _scaleX,_scaleY,_scaleZ,
+                               _rotationX,_rotationY,_rotationZ,               
        
+                               _x,_y,_z);
+                       _flags |= MATRIX3D_VALID;
+                       return m;
+                       
+               }
+               
+               /**
+                * @private
+                */
+               public function set matrix3D(v:Matrix3D):void
+               {
+                       if (_matrix3D == null)
+                       {
+                               _matrix3D = v.clone();
+                       }
+                       else
+                       {
+                               _matrix3D.identity();
+                               if (v)
+                                       _matrix3D.append(v);            
+                       }
+                       invalidate(INVALIDATE_FROM_MATRIX3D, true 
/*affects3D*/);
+               }
+               
+       }
+}

http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/7d529524/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/IAssetLayoutFeatures.as
----------------------------------------------------------------------
diff --git 
a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/IAssetLayoutFeatures.as
 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/IAssetLayoutFeatures.as
new file mode 100644
index 0000000..97f2f79
--- /dev/null
+++ 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/graphics/utils/IAssetLayoutFeatures.as
@@ -0,0 +1,371 @@
+/**
+ * Licensed 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 org.apache.flex.graphics.utils
+{
+       import flash.geom.Matrix;
+       import flash.geom.Matrix3D;
+       
+       
+       /**
+        *  The IAssetLayoutFeatures interface defines the minimum properties 
and methods 
+        *  required for an Object to support advanced transforms in embedded 
assets.
+        *  
+        *  @see mx.core.AdvancedLayoutFeatures
+        *  
+        *  @langversion 3.0
+        *  @playerversion Flash 10
+        *  @playerversion AIR 1.5
+        *  @productversion Flex 4.1
+        */
+       public interface IAssetLayoutFeatures
+       {
+               
+               /**
+                *  Layout transform convenience property.  Represents the x 
value of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutX(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutX():Number;
+               
+               /**
+                *  Layout transform convenience property.  Represents the y 
value of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutY(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutY():Number;
+               
+               /**
+                *  Layout transform convenience property.  Represents the z 
value of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutZ(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutZ():Number;
+               
+               /**
+                *  Used by the mirroring transform. See the mirror property.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get layoutWidth():Number;
+               
+               /**
+                *  @private
+                */
+               function set layoutWidth(value:Number):void;
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                *  The x value of the point around which any rotation and 
scale is performed in both the layout and computed matrix.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set transformX(value:Number):void;
+               /**
+                * @private
+                */
+               function get transformX():Number;
+               
+               /**
+                *  The y value of the point around which any rotation and 
scale is performed in both the layout and computed matrix.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set transformY(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get transformY():Number;
+               
+               /**
+                *  The z value of the point around which any rotation and 
scale is performed in both the layout and computed matrix.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set transformZ(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get transformZ():Number;
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                *  Layout transform convenience property.  Represents the 
rotation around the X axis of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutRotationX(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutRotationX():Number;
+               
+               /**
+                *  Layout transform convenience property.  Represents the 
rotation around the Y axis of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutRotationY(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutRotationY():Number;
+               
+               /**
+                *  Layout transform convenience property.  Represents the 
rotation around the Z axis of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutRotationZ(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutRotationZ():Number;
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                *  Layout transform convenience property.  Represents the 
scale along the X axis of the layout matrix used in layout and in 
+                *  the computed transform.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutScaleX(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutScaleX():Number;
+               
+               /**
+                *  Layout transform convenience property.  Represents the 
scale along the Y axis of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutScaleY(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutScaleY():Number;
+               
+               /**
+                *  Layout transform convenience property.  Represents the 
scale along the Z axis of the layout matrix used in layout and in 
+                *  the computed transform.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutScaleZ(value:Number):void;
+               
+               /**
+                * @private
+                */
+               function get layoutScaleZ():Number;
+               
+               /**
+                *  The 2D matrix used during layout calculations to determine 
the layout and size of the component and its parent and siblings.
+                *  
+                *   @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutMatrix(value:Matrix):void;
+               
+               /**
+                * @private
+                */
+               function get layoutMatrix():Matrix;
+               
+               /**
+                *  The 3D matrix used during layout calculations to determine 
the layout and size of the component and its parent and siblings.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function set layoutMatrix3D(value:Matrix3D):void;
+               
+               /**
+                * @private
+                */
+               function get layoutMatrix3D():Matrix3D;
+               
+               /**
+                *  True if the computed transform has 3D values.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get is3D():Boolean;
+               
+               /**
+                *  True if the layout transform has 3D values.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get layoutIs3D():Boolean;
+               
+               /**
+                *  If true the X axis is scaled by -1 and the x coordinate of 
the origin
+                *  is translated by the component's width.  
+                * 
+                *  The net effect of this "mirror" transform is to flip the 
direction 
+                *  that the X axis increases in without changing the layout 
element's 
+                *  location relative to the parent's origin.
+                * 
+                *  @default false
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get mirror():Boolean;
+               
+               /**
+                *  @private
+                */
+               function set mirror(value:Boolean):void;
+               
+               
+               /**
+                *  The stretchY is the horizontal component of the stretch 
scale factor which
+                *  is applied before any other transformation property.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get stretchX():Number;
+               
+               /**
+                *  @private
+                */
+               function set stretchX(value:Number):void;
+               
+               /**
+                *  The stretchY is the vertical component of the stretch scale 
factor which
+                *  is applied before any other transformation property.
+                * 
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get stretchY():Number;
+               
+               /**
+                *  @private
+                */
+               function set stretchY(value:Number):void;
+               
+               
//------------------------------------------------------------------------------
+               
+               /**
+                *  The computed matrix, calculated by combining the layout 
matrix and any offsets provided.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get computedMatrix():Matrix;
+               
+               /**
+                *  The computed 3D matrix, calculated by combining the 3D 
layout matrix and any offsets provided.
+                *  
+                *  @langversion 3.0
+                *  @playerversion Flash 10
+                *  @playerversion AIR 1.5
+                *  @productversion Flex 4.1
+                */
+               function get computedMatrix3D():Matrix3D;
+       }
+}

Reply via email to