http://git-wip-us.apache.org/repos/asf/flex-asjs/blob/7d529524/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/MatrixUtil.as
----------------------------------------------------------------------
diff --git 
a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/MatrixUtil.as
 
b/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/MatrixUtil.as
deleted file mode 100644
index 04c2c13..0000000
--- 
a/frameworks/projects/Graphics/src/main/flex/org/apache/flex/core/graphics/utils/MatrixUtil.as
+++ /dev/null
@@ -1,1605 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-//  Licensed to the Apache Software Foundation (ASF) under one or more
-//  contributor license agreements.  See the NOTICE file distributed with
-//  this work for additional information regarding copyright ownership.
-//  The ASF licenses this file to You under the Apache License, Version 2.0
-//  (the "License"); you may not use this file except in compliance with
-//  the License.  You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-//  Unless required by applicable law or agreed to in writing, software
-//  distributed under the License is distributed on an "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-//  See the License for the specific language governing permissions and
-//  limitations under the License.
-//
-////////////////////////////////////////////////////////////////////////////////
-
-package org.apache.flex.core.graphics.utils
-{
-       
-       import flash.display.DisplayObject;
-       import flash.geom.Matrix;
-       import flash.geom.Matrix3D;
-       import flash.geom.PerspectiveProjection;
-       import flash.geom.Point;
-       import flash.geom.Rectangle;
-       import flash.geom.Utils3D;
-       import flash.geom.Vector3D;
-       import flash.system.ApplicationDomain;
-       
-       /**
-        *  @private
-        *  The MatrixUtil class is for internal use only.
-        *  Class for matrix and geometric related math routines.
-        */
-       public final class MatrixUtil
-       {
-               
-               private static const RADIANS_PER_DEGREES:Number = Math.PI / 180;
-               private static var SOLUTION_TOLERANCE:Number = 0.1;
-               private static var MIN_MAX_TOLERANCE:Number = 0.1;
-               
-               private static var staticPoint:Point = new Point();
-               
-               // For use in getConcatenatedMatrix function
-               private static var fakeDollarParent:QName;
-               private static var uiComponentClass:Class;
-               private static var uiMovieClipClass:Class;
-               private static var usesMarshalling:Object;
-               private static var lastModuleFactory:Object;
-               private static var computedMatrixProperty:QName;
-               private static var $transformProperty:QName;
-               
-               
//--------------------------------------------------------------------------
-               //
-               //  Class methods
-               //
-               
//--------------------------------------------------------------------------
-               
-               /**
-                *  Returns rotation value clamped between -180 and 180 
degreeds.
-                *  This mimicks the Flash player behavior. 
-                */
-               public static function clampRotation(value:Number):Number
-               {
-                       // Flash player doesn't handle values larger than 2^15 
- 1 (FP-749).
-                       if (value > 180 || value < -180)
-                       {
-                               value = value % 360;
-                               
-                               if (value > 180)
-                                       value = value - 360;
-                               else if (value < -180)
-                                       value = value + 360;
-                       }
-                       return value;
-               }
-               
-               /**
-                *  Returns a static Point object with the result.
-                *  If matrix is null, point is untransformed. 
-                */
-               public static function transformPoint(x:Number, y:Number, 
m:Matrix):Point
-               {
-                       if (!m)
-                       {
-                               staticPoint.x = x;
-                               staticPoint.y = y;
-                               return staticPoint;
-                       }
-                       
-                       staticPoint.x = m.a * x + m.c * y + m.tx;
-                       staticPoint.y = m.b * x + m.d * y + m.ty;
-                       return staticPoint;
-               }
-               
-               public static function composeMatrix(x:Number = 0,
-                                                                               
         y:Number = 0,
-                                                                               
         scaleX:Number = 1,
-                                                                               
         scaleY:Number = 1,
-                                                                               
         rotation:Number = 0,
-                                                                               
         transformX:Number = 0,
-                                                                               
         transformY:Number = 0):Matrix
-               {
-                       var m:Matrix = new Matrix();
-                       m.translate(-transformX, -transformY);
-                       m.scale(scaleX, scaleY);
-                       if (rotation != 0) 
-                               m.rotate(rotation / 180 * Math.PI);
-                       m.translate(transformX + x, transformY + y);
-                       return m;
-               }
-               
-               /**
-                *  Decompose a matrix into its component scale, rotation, and 
translation parts.
-                *  The Vector of Numbers passed in the components parameter 
will be 
-                *  populated by this function with the component parts. 
-                * 
-                *  @param components Vector which holds the component scale, 
rotation 
-                *  and translation values.
-                *  x = components[0]
-                *  y = components[1]
-                *  rotation = components[2]
-                *  scaleX = components[3]
-                *  scaleY = components[4]
-                * 
-                *  @param matrix The matrix to decompose
-                *  @param transformX The x value of the transform center
-                *  @param transformY The y value of the transform center
-                */     
-               public static function 
decomposeMatrix(components:Vector.<Number>,
-                                                                               
           matrix:Matrix,
-                                                                               
           transformX:Number = 0,
-                                                                               
           transformY:Number = 0):void
-               {
-                       // else decompose matrix.  Don't use MatrixDecompose(), 
it can return erronous values
-                       //   when negative scales (and therefore skews) are in 
use.
-                       var Ux:Number;
-                       var Uy:Number;
-                       var Vx:Number;
-                       var Vy:Number;
-                       
-                       Ux = matrix.a;
-                       Uy = matrix.b;
-                       components[3] = Math.sqrt(Ux*Ux + Uy*Uy);
-                       
-                       Vx = matrix.c;
-                       Vy = matrix.d;
-                       components[4] = Math.sqrt(Vx*Vx + Vy*Vy );
-                       
-                       // sign of the matrix determinant will tell us if the 
space is inverted by a 180 degree skew or not.
-                       var determinant:Number = Ux*Vy - Uy*Vx;
-                       if (determinant < 0) // if so, choose y-axis scale as 
the skewed one.  Unfortunately, its impossible to tell if it originally was the 
y or x axis that had the negative scale/skew.
-                       {
-                               components[4] = -(components[4]);
-                               Vx = -Vx;
-                               Vy = -Vy;
-                       }
-                       
-                       components[2] = Math.atan2( Uy, Ux ) / 
RADIANS_PER_DEGREES;
-                       
-                       if (transformX != 0 || transformY != 0)     
-                       {
-                               var postTransformCenter:Point = 
matrix.transformPoint(new Point(transformX,transformY));
-                               components[0] = postTransformCenter.x - 
transformX;
-                               components[1] = postTransformCenter.y - 
transformY;
-                       }
-                       else
-                       {
-                               components[0] = matrix.tx;
-                               components[1] = matrix.ty;
-                       }
-               }
-               
-               /**
-                *  @return Returns the union of <code>rect</code> and
-                *  <code>Rectangle(left, top, right - left, bottom - 
top)</code>.
-                *  Note that if rect is non-null, it will be updated to 
reflect the return value.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function rectUnion(left:Number, top:Number, 
right:Number, bottom:Number,
-                                                                               
 rect:Rectangle):Rectangle
-               {
-                       if (!rect)
-                               return new Rectangle(left, top, right - left, 
bottom - top);
-                       
-                       var minX:Number = Math.min(rect.left,   left);
-                       var minY:Number = Math.min(rect.top,    top);
-                       var maxX:Number = Math.max(rect.right,  right);
-                       var maxY:Number = Math.max(rect.bottom, bottom);
-                       
-                       rect.x      = minX;
-                       rect.y      = minY;
-                       rect.width  = maxX - minX;
-                       rect.height = maxY - minY;
-                       return rect;
-               }
-               
-               /**
-                *  Calculates the bounding box of a post-transformed ellipse.
-                *   
-                *  @param cx The x coordinate of the ellipse's center
-                *  @param cy The y coordinate of the ellipse's center
-                *  @param rx The horizontal radius of the ellipse
-                *  @param ry The vertical radius of the ellipse
-                *  @param matrix The transformation matrix.
-                *  @param rect If non-null, rect will be updated to the union 
of rect and
-                *  the segment bounding box.
-                *  @return Returns the union of the passed in rect with the
-                *  bounding box of the the post-transformed ellipse.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */ 
-               public static function getEllipseBoundingBox(cx:Number, 
cy:Number,
-                                                                               
                         rx:Number, ry:Number,
-                                                                               
                         matrix:Matrix,
-                                                                               
                         rect:Rectangle = null):Rectangle
-               {
-                       var a:Number = matrix.a;
-                       var b:Number = matrix.b;
-                       var c:Number = matrix.c;
-                       var d:Number = matrix.d;
-                       
-                       // Ellipse can be represented by the following 
parametric equations:         
-                       //
-                       // (1) x = cx + rx * cos(t)
-                       // (2) y = cy + ry * sin(t)
-                       //
-                       // After applying transformation with matrix m(a, c, b, 
d) we get:
-                       //
-                       // (3) x = a * cx + a * cos(t) * rx + c * cy + c * 
sin(t) * ry + m.tx
-                       // (4) y = b * cx + b * cos(t) * rx + d * cy + d * 
sin(t) * ry + m.ty
-                       //
-                       // In (3) and (4) x and y are functions of a parameter 
t. To find the extremums we need
-                       // to find where dx/dt and dy/dt reach zero:
-                       //
-                       // (5) dx/dt = - a * sin(t) * rx + c * cos(t) * ry
-                       // (6) dy/dt = - b * sin(t) * rx + d * cos(t) * ry
-                       // (7) dx/dt = 0 <=> sin(t) / cos(t) = (c * ry) / (a * 
rx);   
-                       // (8) dy/dt = 0 <=> sin(t) / cos(t) = (d * ry) / (b * 
rx);
-                       
-                       if (rx == 0 && ry == 0)
-                       {
-                               var pt:Point = new Point(cx, cy);
-                               pt = matrix.transformPoint(pt);
-                               return rectUnion(pt.x, pt.y, pt.x, pt.y, rect);
-                       }
-                       
-                       var t:Number;
-                       var t1:Number;
-                       
-                       if (a * rx == 0)
-                               t = Math.PI / 2;
-                       else
-                               t = Math.atan((c * ry) / (a * rx));
-                       
-                       if (b * rx == 0)
-                               t1 = Math.PI / 2;
-                       else
-                               t1 = Math.atan((d * ry) / (b * rx));            
-                       
-                       var x1:Number = a * Math.cos(t) * rx + c * Math.sin(t) 
* ry;             
-                       var x2:Number = -x1;
-                       x1 += a * cx + c * cy + matrix.tx;
-                       x2 += a * cx + c * cy + matrix.tx;
-                       
-                       var y1:Number = b * Math.cos(t1) * rx + d * 
Math.sin(t1) * ry;             
-                       var y2:Number = -y1;
-                       y1 += b * cx + d * cy + matrix.ty;
-                       y2 += b * cx + d * cy + matrix.ty;
-                       
-                       return rectUnion(Math.min(x1, x2), Math.min(y1, y2), 
Math.max(x1, x2), Math.max(y1, y2), rect); 
-               }
-               
-               /**
-                *  @param x0 x coordinate of the first control point
-                *  @param y0 y coordinate of the first control point
-                *  @param x1 x coordinate of the second control point
-                *  @param y1 y coordinate of the second control point
-                *  @param x2 x coordinate of the third control point
-                *  @param y2 y coordinate of the third control point
-                *  @param sx The pre-transform scale factor for x coordinates.
-                *  @param sy The pre-transform scale factor for y coordinates.
-                *  @param matrix The transformation matrix. Can be null for 
identity transformation.
-                *  @param rect If non-null, rect will be updated to the union 
of rect and
-                *  the segment bounding box.
-                *  @return Returns the union of the post-transformed quadratic
-                *  bezier segment's axis aligned bounding box and the passed 
in rect.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */     
-               static public function getQBezierSegmentBBox(x0:Number, 
y0:Number,
-                                                                               
                         x1:Number, y1:Number,
-                                                                               
                         x2:Number, y2:Number,
-                                                                               
                         sx:Number, sy:Number,
-                                                                               
                         matrix:Matrix,
-                                                                               
                         rect:Rectangle):Rectangle
-               {
-                       var pt:Point;
-                       pt = MatrixUtil.transformPoint(x0 * sx, y0 * sy, 
matrix);
-                       x0 = pt.x;
-                       y0 = pt.y;
-                       
-                       pt = MatrixUtil.transformPoint(x1 * sx, y1 * sy, 
matrix);
-                       x1 = pt.x;
-                       y1 = pt.y;
-                       
-                       pt = MatrixUtil.transformPoint(x2 * sx, y2 * sy, 
matrix);
-                       x2 = pt.x;
-                       y2 = pt.y;
-                       
-                       var minX:Number = Math.min(x0, x2);
-                       var maxX:Number = Math.max(x0, x2);
-                       
-                       var minY:Number = Math.min(y0, y2);
-                       var maxY:Number = Math.max(y0, y2);
-                       
-                       var txDiv:Number = x0 - 2 * x1 + x2;
-                       if (txDiv != 0)
-                       {
-                               var tx:Number = (x0 - x1) / txDiv;
-                               if (0 <= tx && tx <= 1)
-                               {
-                                       var x:Number = (1 - tx) * (1 - tx) * x0 
+ 2 * tx * (1 - tx) * x1 + tx * tx * x2;
-                                       minX = Math.min(x, minX);
-                                       maxX = Math.max(x, maxX);
-                               }  
-                       }
-                       
-                       var tyDiv:Number = y0 - 2 * y1 + y2;
-                       if (tyDiv != 0)
-                       {
-                               var ty:Number = (y0 - y1) / tyDiv;
-                               if (0 <= ty && ty <= 1)
-                               {
-                                       var y:Number = (1 - ty) * (1 - ty) * y0 
+ 2 * ty * (1 - ty) * y1 + ty * ty * y2;
-                                       minY = Math.min(y, minY);
-                                       maxY = Math.max(y, maxY);
-                               }  
-                       }
-                       
-                       return rectUnion(minX, minY, maxX, maxY, rect);
-               }
-               
-               /**
-                *  @param width The width of the bounds to be transformed.
-                *  @param height The height of the bounds to be transformed.
-                *  @param matrix The transfomration matrix. 
-                *  
-                *  @param vec If vec is non-null it will be set to the vector 
from the
-                *  transformed bounds top left to the untransformed bounds top 
left
-                *  in the coordinate space defined by <code>matrix</code>.
-                *  This is useful if you want to align the transformed bounds 
to x,y
-                *  by modifying the object's position. Moving the object by
-                *  <code>x + vec.x</code> and <code>y + vec.y</code> 
respectively
-                *  will offset the transformed bounds top left corner by x,y.
-                *
-                *  @return Returns the transformed bounds. Note that the Point 
object returned will be reused
-                *  by other MatrixUtil methods.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function transformSize(width:Number, 
height:Number, matrix:Matrix):Point
-               {
-                       const a:Number = matrix.a;
-                       const b:Number = matrix.b;
-                       const c:Number = matrix.c;
-                       const d:Number = matrix.d;
-                       
-                       // transform point (0,0)
-                       var x1:Number = 0;
-                       var y1:Number = 0;
-                       
-                       // transform point (width, 0)
-                       var x2:Number = width * a;
-                       var y2:Number = width * b;
-                       
-                       // transform point (0, height)
-                       var x3:Number = height * c;
-                       var y3:Number = height * d;
-                       
-                       // transform point (width, height)
-                       var x4:Number = x2 + x3;
-                       var y4:Number = y2 + y3;
-                       
-                       var minX:Number = Math.min(Math.min(x1, x2), 
Math.min(x3, x4));
-                       var maxX:Number = Math.max(Math.max(x1, x2), 
Math.max(x3, x4));
-                       var minY:Number = Math.min(Math.min(y1, y2), 
Math.min(y3, y4));
-                       var maxY:Number = Math.max(Math.max(y1, y2), 
Math.max(y3, y4));
-                       
-                       staticPoint.x = maxX - minX;
-                       staticPoint.y = maxY - minY;
-                       return staticPoint;
-               }
-               
-               /**
-                *  @param width The width of the bounds to be transformed.
-                *  @param height The height of the bounds to be transformed.
-                *  @param matrix The transfomration matrix.
-                *  
-                *  @param topleft If topLeft is non-null it will be used as 
the origin of the bounds
-                *  rectangle to be transformed.  On return, it will be set to 
the top left of the rectangle
-                *  after transformation.
-                *
-                *  @return Returns the transformed width and height. Note that 
the Point object returned will be reused
-                *  by other MatrixUtil methods.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function transformBounds(width:Number, 
height:Number, matrix:Matrix, topLeft:Point = null):Point
-               {
-                       const a:Number = matrix.a;
-                       const b:Number = matrix.b;
-                       const c:Number = matrix.c;
-                       const d:Number = matrix.d;
-                       
-                       // transform point (0,0)
-                       var x1:Number = 0;
-                       var y1:Number = 0;
-                       
-                       // transform point (width, 0)
-                       var x2:Number = width * a;
-                       var y2:Number = width * b;
-                       
-                       // transform point (0, height)
-                       var x3:Number = height * c;
-                       var y3:Number = height * d;
-                       
-                       // transform point (width, height)
-                       var x4:Number = x2 + x3;
-                       var y4:Number = y2 + y3;
-                       
-                       var minX:Number = Math.min(Math.min(x1, x2), 
Math.min(x3, x4));
-                       var maxX:Number = Math.max(Math.max(x1, x2), 
Math.max(x3, x4));
-                       var minY:Number = Math.min(Math.min(y1, y2), 
Math.min(y3, y4));
-                       var maxY:Number = Math.max(Math.max(y1, y2), 
Math.max(y3, y4));
-                       
-                       staticPoint.x = maxX - minX;
-                       staticPoint.y = maxY - minY;
-                       
-                       if (topLeft)
-                       {
-                               const tx:Number = matrix.tx;
-                               const ty:Number = matrix.ty;
-                               const x:Number = topLeft.x;
-                               const y:Number = topLeft.y;
-                               
-                               topLeft.x = minX + a * x + b * y + tx;
-                               topLeft.y = minY + c * x + d * y + ty;
-                       }
-                       return staticPoint;
-               }
-               
-               /**
-                *  Returns the axis aligned bounding box <code>bounds</code> 
transformed
-                *  with <code>matrix</code> and then projected with 
<code>projection</code>.
-                * 
-                *  @param bounds The bounds, in child coordinates, to be 
transformed and projected.
-                *  @param matrix <p>The transformation matrix. Note that the 
method will clobber the
-                *  original matrix values.</p>
-                *  @param projection The projection.
-                *  @return Returns the <code>bounds</code> parameter that has 
been updated with the
-                *  transformed and projected bounds.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function projectBounds(bounds:Rectangle,
-                                                                               
         matrix:Matrix3D, 
-                                                                               
         projection:PerspectiveProjection):Rectangle
-               {
-                       // Setup the matrix
-                       var centerX:Number = projection.projectionCenter.x;
-                       var centerY:Number = projection.projectionCenter.y;
-                       matrix.appendTranslation(-centerX, -centerY, 
projection.focalLength);
-                       matrix.append(projection.toMatrix3D());
-                       
-                       // Project the corner points
-                       var pt1:Vector3D = new Vector3D(bounds.left, 
bounds.top, 0); 
-                       var pt2:Vector3D = new Vector3D(bounds.right, 
bounds.top, 0) 
-                       var pt3:Vector3D = new Vector3D(bounds.left, 
bounds.bottom, 0);
-                       var pt4:Vector3D = new Vector3D(bounds.right, 
bounds.bottom, 0);
-                       pt1 = Utils3D.projectVector(matrix, pt1);
-                       pt2 = Utils3D.projectVector(matrix, pt2);
-                       pt3 = Utils3D.projectVector(matrix, pt3);
-                       pt4 = Utils3D.projectVector(matrix, pt4);
-                       
-                       // Find the bounding box in 2D
-                       var maxX:Number = Math.max(Math.max(pt1.x, pt2.x), 
Math.max(pt3.x, pt4.x));
-                       var minX:Number = Math.min(Math.min(pt1.x, pt2.x), 
Math.min(pt3.x, pt4.x));
-                       var maxY:Number = Math.max(Math.max(pt1.y, pt2.y), 
Math.max(pt3.y, pt4.y));
-                       var minY:Number = Math.min(Math.min(pt1.y, pt2.y), 
Math.min(pt3.y, pt4.y));
-                       
-                       // Add back the projection center
-                       bounds.x = minX + centerX;
-                       bounds.y = minY + centerY;
-                       bounds.width = maxX - minX;
-                       bounds.height = maxY - minY;
-                       return bounds;
-               }
-               
-               /**
-                *  @param matrix
-                *  @return Returns true when <code>pt == 
matrix.DeltaTransformPoint(pt)</code>
-                *  for any <code>pt:Point</code> (<code>matrix</code> is 
identity matrix,
-                *  when disregarding the translation part).   
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function isDeltaIdentity(matrix:Matrix):Boolean
-               {
-                       return (matrix.a == 1 && matrix.d == 1 &&
-                               matrix.b == 0 && matrix.c == 0);
-               }
-               
-               /**
-                *  <code>fitBounds</code> Calculates a size (x,y) for a 
bounding box (0,0,x,y)
-                *  such that the bounding box transformed with 
<code>matrix</code> will fit
-                *  into (0,0,width,height).
-                *  
-                *  @param width This is the width of the bounding box that 
calculated size
-                *  needs to fit in.
-                * 
-                *  @param height This is the height of the bounding box that 
the calculated
-                *  size needs to fit in.
-                * 
-                *  @param matrix This defines the transformations that the 
function will take
-                *  into account when calculating the size. The bounding box 
(0,0,x,y) of the
-                *  calculated size (x,y) transformed with <code>matrix</code> 
will fit in the
-                *  specified <code>width</code> and <code>height</code>.
-                * 
-                *  @param explicitWidth Explicit width for the calculated 
size. The function
-                *  will first try to find a solution using this width.
-                * 
-                *  @param explicitHeight Preferred height for the calculated 
size. The function
-                *  will first try to find a solution using this height.
-                * 
-                *  @param preferredWidth Preferred width for the calculated 
size. If possible
-                *  the function will set the calculated size width to this 
value.
-                * 
-                *  @param preferredHeight Preferred height for the calculated 
size. If possible
-                *  the function will set the calculated size height to this 
value.
-                * 
-                *  @param minWidth The minimum allowed value for the 
calculated size width.
-                * 
-                *  @param minHeight The minimum allowed value for the 
calculated size height.
-                * 
-                *  @param maxWidth The maximum allowed value for the 
calculated size width.
-                * 
-                *  @param maxHeight The maximum allowed value for the 
calculated size height.
-                * 
-                *  @return Returns the size (x,y) such that the bounding box 
(0,0,x,y) will
-                *  fit into (0,0,width,height) after transformation with 
<code>matrix</code>.
-                *  Returns null if there is no possible solution.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */ 
-               public static function fitBounds(width:Number, height:Number, 
matrix:Matrix,
-                                                                               
 explicitWidth:Number, explicitHeight:Number,
-                                                                               
 preferredWidth:Number, preferredHeight:Number,
-                                                                               
 minWidth:Number, minHeight:Number,
-                                                                               
 maxWidth:Number, maxHeight:Number):Point
-               {
-                       if (isNaN(width) && isNaN(height))
-                               return new Point(preferredWidth, 
preferredHeight);
-                       
-                       // Allow for precision errors by including tolerance 
for certain values.
-                       const newMinWidth:Number = (minWidth < 
MIN_MAX_TOLERANCE) ? 0 : minWidth - MIN_MAX_TOLERANCE;
-                       const newMinHeight:Number = (minHeight < 
MIN_MAX_TOLERANCE) ? 0 : minHeight - MIN_MAX_TOLERANCE;
-                       const newMaxWidth:Number = maxWidth + MIN_MAX_TOLERANCE;
-                       const newMaxHeight:Number = maxHeight + 
MIN_MAX_TOLERANCE;
-                       
-                       var actualSize:Point;
-                       
-                       if (!isNaN(width) && !isNaN(height))
-                       {
-                               actualSize = calcUBoundsToFitTBounds(width, 
height, matrix,
-                                       newMinWidth, newMinHeight, 
-                                       newMaxWidth, newMaxHeight); 
-                               
-                               // If we couldn't fit in both dimensions, try 
to fit only one and
-                               // don't stick out of the other
-                               if (!actualSize)
-                               {
-                                       var actualSize1:Point;
-                                       actualSize1 = fitTBoundsWidth(width, 
matrix,
-                                               explicitWidth, explicitHeight,
-                                               preferredWidth, preferredHeight,
-                                               newMinWidth, newMinHeight, 
-                                               newMaxWidth, newMaxHeight);
-                                       
-                                       // If we fit the width, but not the 
height.
-                                       if (actualSize1)
-                                       {
-                                               var fitHeight:Number = 
transformSize(actualSize1.x, actualSize1.y, matrix).y;
-                                               if (fitHeight - 
SOLUTION_TOLERANCE > height)
-                                                       actualSize1 = null;
-                                       }
-                                       
-                                       var actualSize2:Point
-                                       actualSize2 = fitTBoundsHeight(height, 
matrix,
-                                               explicitWidth, explicitHeight,
-                                               preferredWidth, preferredHeight,
-                                               newMinWidth, newMinHeight, 
-                                               newMaxWidth, newMaxHeight); 
-                                       
-                                       // If we fit the height, but not the 
width
-                                       if (actualSize2)
-                                       {
-                                               var fitWidth:Number = 
transformSize(actualSize2.x, actualSize2.y, matrix).x;
-                                               if (fitWidth - 
SOLUTION_TOLERANCE > width)
-                                                       actualSize2 = null;
-                                       }
-                                       
-                                       if (actualSize1 && actualSize2)
-                                       {
-                                               // Pick a solution
-                                               actualSize = ((actualSize1.x * 
actualSize1.y) > (actualSize2.x * actualSize2.y)) ? actualSize1 : actualSize2;
-                                       }
-                                       else if (actualSize1)
-                                       {
-                                               actualSize = actualSize1;
-                                       }
-                                       else
-                                       {
-                                               actualSize = actualSize2;
-                                       }
-                               }
-                               return actualSize;
-                       }
-                       else if (!isNaN(width))
-                       {
-                               return fitTBoundsWidth(width, matrix,
-                                       explicitWidth, explicitHeight,
-                                       preferredWidth, preferredHeight,
-                                       newMinWidth, newMinHeight, 
-                                       newMaxWidth, newMaxHeight); 
-                       }
-                       else
-                       {
-                               return fitTBoundsHeight(height, matrix,
-                                       explicitWidth, explicitHeight,
-                                       preferredWidth, preferredHeight,
-                                       newMinWidth, newMinHeight, 
-                                       newMaxWidth, newMaxHeight); 
-                       }
-               }
-               
-               /**
-                *  @private
-                * 
-                *  <code>fitTBoundsWidth</code> Calculates a size (x,y) for a 
bounding box (0,0,x,y)
-                *  such that the bounding box transformed with 
<code>matrix</code> will fit
-                *  into the specified width.
-                *  
-                *  @param width This is the width of the bounding box that 
calculated size
-                *  needs to fit in.
-                * 
-                *  @param matrix This defines the transformations that the 
function will take
-                *  into account when calculating the size. The bounding box 
(0,0,x,y) of the
-                *  calculated size (x,y) transformed with <code>matrix</code> 
will fit in the
-                *  specified <code>width</code> and <code>height</code>.
-                * 
-                *  @param explicitWidth Explicit width for the calculated 
size. The function
-                *  will first try to find a solution using this width.
-                * 
-                *  @param explicitHeight Preferred height for the calculated 
size. The function
-                *  will first try to find a solution using this height.
-                * 
-                *  @param preferredWidth Preferred width for the calculated 
size. If possible
-                *  the function will set the calculated size width to this 
value.
-                * 
-                *  @param preferredHeight Preferred height for the calculated 
size. If possible
-                *  the function will set the calculated size height to this 
value.
-                * 
-                *  @param minWidth The minimum allowed value for the 
calculated size width.
-                * 
-                *  @param minHeight The minimum allowed value for the 
calculated size height.
-                * 
-                *  @param maxWidth The maximum allowed value for the 
calculated size width.
-                * 
-                *  @param maxHeight The maximum allowed value for the 
calculated size height.
-                * 
-                *  @return Returns the size (x,y) such that the bounding box 
(0,0,x,y) will
-                *  fit into (0,0,width,height) after transformation with 
<code>matrix</code>.
-                *  Returns null if there is no possible solution.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */    
-               private static function fitTBoundsWidth(width:Number, 
matrix:Matrix,
-                                                                               
                explicitWidth:Number, explicitHeight:Number,
-                                                                               
                preferredWidth:Number, preferredHeight:Number,
-                                                                               
                minWidth:Number, minHeight:Number,
-                                                                               
                maxWidth:Number, maxHeight:Number):Point
-               {
-                       var actualSize:Point;
-                       
-                       // cases 1 and 2: only explicit width or explicit 
height is specified,
-                       // so we try to find a solution with that hard 
constraint.
-                       if (!isNaN(explicitWidth) && isNaN(explicitHeight))
-                       {
-                               actualSize = 
calcUBoundsToFitTBoundsWidth(width, matrix,
-                                       explicitWidth, preferredHeight, 
-                                       explicitWidth, minHeight, 
-                                       explicitWidth, maxHeight);
-                               
-                               if (actualSize)
-                                       return actualSize;
-                       }
-                       else if (isNaN(explicitWidth) && !isNaN(explicitHeight))
-                       {
-                               actualSize = 
calcUBoundsToFitTBoundsWidth(width, matrix,
-                                       preferredWidth, explicitHeight, 
-                                       minWidth, explicitHeight, 
-                                       maxWidth, explicitHeight);
-                               if (actualSize)
-                                       return actualSize;
-                       }
-                       
-                       // case 3: default case. When explicitWidth, 
explicitHeight are both set
-                       // or not set, we use the preferred size since 
calcUBoundsToFitTBoundsWidth
-                       // will just pick one.
-                       actualSize = calcUBoundsToFitTBoundsWidth(width, matrix,
-                               preferredWidth, preferredHeight, 
-                               minWidth, minHeight, 
-                               maxWidth, maxHeight);
-                       
-                       return actualSize;
-               }
-               
-               /**
-                *  @private
-                * 
-                *  <code>fitTBoundsWidth</code> Calculates a size (x,y) for a 
bounding box (0,0,x,y)
-                *  such that the bounding box transformed with 
<code>matrix</code> will fit
-                *  into the specified height.
-                *  
-                *  @param height This is the height of the bounding box that 
the calculated
-                *  size needs to fit in.
-                * 
-                *  @param matrix This defines the transformations that the 
function will take
-                *  into account when calculating the size. The bounding box 
(0,0,x,y) of the
-                *  calculated size (x,y) transformed with <code>matrix</code> 
will fit in the
-                *  specified <code>width</code> and <code>height</code>.
-                * 
-                *  @param explicitWidth Explicit width for the calculated 
size. The function
-                *  will first try to find a solution using this width.
-                * 
-                *  @param explicitHeight Preferred height for the calculated 
size. The function
-                *  will first try to find a solution using this height.
-                * 
-                *  @param preferredWidth Preferred width for the calculated 
size. If possible
-                *  the function will set the calculated size width to this 
value.
-                * 
-                *  @param preferredHeight Preferred height for the calculated 
size. If possible
-                *  the function will set the calculated size height to this 
value.
-                * 
-                *  @param minWidth The minimum allowed value for the 
calculated size width.
-                * 
-                *  @param minHeight The minimum allowed value for the 
calculated size height.
-                * 
-                *  @param maxWidth The maximum allowed value for the 
calculated size width.
-                * 
-                *  @param maxHeight The maximum allowed value for the 
calculated size height.
-                * 
-                *  @return Returns the size (x,y) such that the bounding box 
(0,0,x,y) will
-                *  fit into (0,0,width,height) after transformation with 
<code>matrix</code>.
-                *  Returns null if there is no possible solution.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */    
-               private static function fitTBoundsHeight(height:Number, 
matrix:Matrix,
-                                                                               
                 explicitWidth:Number, explicitHeight:Number,
-                                                                               
                 preferredWidth:Number, preferredHeight:Number,
-                                                                               
                 minWidth:Number, minHeight:Number,
-                                                                               
                 maxWidth:Number, maxHeight:Number):Point
-               {
-                       var actualSize:Point;
-                       
-                       // cases 1 and 2: only explicit width or explicit 
height is specified,
-                       // so we try to find a solution with that hard 
constraint.
-                       if (!isNaN(explicitWidth) && isNaN(explicitHeight))
-                       {
-                               actualSize = 
calcUBoundsToFitTBoundsHeight(height, matrix,
-                                       explicitWidth, preferredHeight, 
-                                       explicitWidth, minHeight, 
-                                       explicitWidth, maxHeight);
-                               
-                               if (actualSize)
-                                       return actualSize;
-                       }
-                       else if (isNaN(explicitWidth) && !isNaN(explicitHeight))
-                       {
-                               actualSize = 
calcUBoundsToFitTBoundsHeight(height, matrix,
-                                       preferredWidth, explicitHeight, 
-                                       minWidth, explicitHeight, 
-                                       maxWidth, explicitHeight);
-                               if (actualSize)
-                                       return actualSize;
-                       }
-                       
-                       // case 3: default case. When explicitWidth, 
explicitHeight are both set
-                       // or not set, we use the preferred size since 
calcUBoundsToFitTBoundsWidth
-                       // will just pick one.
-                       actualSize = calcUBoundsToFitTBoundsHeight(height, 
matrix,
-                               preferredWidth, preferredHeight, 
-                               minWidth, minHeight, 
-                               maxWidth, maxHeight);
-                       
-                       return actualSize;
-               }
-               
-               /**
-                *  Calculates (x,y) such that the bounding box (0,0,x,y) 
transformed
-                *  with <code>matrix</code> will have bounding box with
-                *  height equal to <code>h</code>.
-                *  x and y are restricted by <code>minX</code>, 
<code>maxX</code> and
-                *  <code>minY</code>, <code>maxY</code>.
-                *
-                *  If possible x will be set to <code>preferredX</code> or
-                *  y will be set to <code>preferredY</code>.
-                *  
-                *  When there are multiple solutions, the function picks the 
one that
-                *  minimizes the bounding box area of transformed (0,0,x,y).
-                * 
-                *  The functon assumes <code>minX >= 0</code> and <code>minY 
>= 0</code>
-                *  (solution components x and y are non-negative).
-                *  
-                *  @return Returns Point(x,y) or null if no solution exists. 
-                * 
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */        
-               static public function calcUBoundsToFitTBoundsHeight(h:Number,
-                                                                               
                                         matrix:Matrix,
-                                                                               
                                         preferredX:Number,
-                                                                               
                                         preferredY:Number,
-                                                                               
                                         minX:Number,
-                                                                               
                                         minY:Number,
-                                                                               
                                         maxX:Number, 
-                                                                               
                                         maxY:Number):Point
-               {
-                       // Untransformed bounds size is (x,y). The corners of 
the untransformed
-                       // bounding box are p1(0,0) p2(x,0) p3(0,y) p4(x,y).
-                       // Matrix is | a c tx |
-                       //           | b d ty |
-                       //
-                       // After transfomation with the matrix those four 
points are:
-                       // t1 = (0, 0)              = 
matrix.deltaTransformPoint(p1)
-                       // t2 = (ax, bx)            = 
matrix.deltaTransformPoint(p2)
-                       // t3 = (cy, dy)            = 
matrix.deltaTransformPoint(p3)
-                       // t4 = (ax + cy, cx + dy)  = 
matrix.deltaTransformPoint(p4)
-                       //
-                       // The transformed bounds bounding box dimensions are 
(w,h):
-                       // (1) w = max( t1.x, t2.x, t3.x, t4.x ) - min( t1.x, 
t2.x, t3.x, t4.x)
-                       // (2) h = max( t1.y, t2.y, t3.y, t4.y ) - min( t1.y, 
t2.y, t3.y, t4.y)
-                       //
-                       // Looking at all the possible cases for min and max 
functions above,
-                       // we can construct and solve simple linear systems for 
x and y.
-                       // For example in the case of
-                       // t1.x <= t2.x <= t3.x <= t4.x
-                       // our first equation is
-                       // (1) w = t4.x - t1.x <==> w = ax + cy
-                       //
-                       // To minimize the cases we're looking at we can take 
advantage of
-                       // the limits we have: x >= 0, y >= 0;
-                       // Taking into account these limits we deduce that:
-                       // a*c >= 0  gives us (1) w = abs( t4.x - t1.x ) = abs( 
ax + cy )
-                       // a*c <  0  gives us (1) w = abs( t2.x - t3.x ) = abs( 
ax - cy )
-                       // b*d >= 0  gives us (2) h = abs( t4.y - t1.y ) = abs( 
bx + dy )
-                       // b*d <  0  gives us (2) h = abs( t2.y - t3.y ) = abs( 
bx - dy )
-                       //
-                       // If we do a substitution such that
-                       // c1 = a*c >= 0 ? c : -c
-                       // d1 = b*d >= 0 ? d : -d
-                       // we get the following linear system:
-                       // (1) w = abs( ax + c1y )
-                       // (2) h = abs( bx + d1y )
-                       //
-                       // Since we're matching height we only care about (2) 
-                       
-                       var b:Number = matrix.b;
-                       var d:Number = matrix.d;
-                       
-                       // If components are very close to zero, zero them out 
to handle the special cases
-                       if (-1.0e-9 < b && b < +1.0e-9)
-                               b = 0;
-                       if (-1.0e-9 < d && d < +1.0e-9)
-                               d = 0;
-                       
-                       if (b == 0 && d == 0)
-                               return null; // No solution
-                       
-                       // Handle special cases first
-                       if (b == 0 && d == 0)
-                               return null; // No solution
-                       
-                       if (b == 0)
-                               return new Point( preferredX, h / Math.abs(d) 
);               
-                       else if (d == 0)
-                               return new Point( h / Math.abs(b), preferredY 
);    
-                       
-                       const d1:Number = (b*d >= 0) ? d : -d;
-                       // Now we have the following linear sytesm:
-                       // (1) x = preferredX or y = preferredY
-                       // (2) h = abs( bx + d1y )
-                       
-                       var s:Point;
-                       var x:Number;
-                       var y:Number;
-                       
-                       if (d1 != 0 && preferredX > 0)
-                       {
-                               const invD1:Number = 1 / d1;
-                               preferredX = Math.max(minX, Math.min(maxX, 
preferredX));
-                               x = preferredX;
-                               
-                               // Case1:
-                               // bx + d1y >= 0
-                               // x = preferredX
-                               y = (h - b * x) * invD1;
-                               if (minY <= y && y <= maxY &&
-                                       b * x + d1 * y >= 0 ) // Satisfy Case1
-                               {
-                                       s = new Point(x, y);
-                               }
-                               
-                               // Case2:
-                               // bx + d1y < 0
-                               // x = preferredX
-                               y = (-h - b * x) * invD1;
-                               if (minY <= y && y <= maxY &&
-                                       b * x + d1 * y < 0 ) // Satisfy Case2
-                               {
-                                       // If there is no solution, or the new 
solution yields smaller value, pick the new solution.
-                                       if (!s || transformSize(s.x, s.y, 
matrix).x > transformSize(x, y, matrix).x)
-                                               s = new Point(x, y);
-                               }
-                       }
-                       
-                       if (b != 0 && preferredY > 0)
-                       {
-                               const invB:Number = 1 / b;
-                               preferredY = Math.max(minY, Math.min(maxY, 
preferredY));
-                               y = preferredY;
-                               
-                               // Case3:
-                               // bx + d1y >= 0
-                               // y = preferredY
-                               x = ( h - d1 * y ) * invB;
-                               if (minX <= x && x <= maxX &&
-                                       b * x + d1 * y >= 0) // Satisfy Case3
-                               {
-                                       // If there is no solution, or the new 
solution yields smaller value, pick the new solution.
-                                       if (!s || transformSize(s.x, s.y, 
matrix).x > transformSize(x, y, matrix).x)
-                                               s = new Point(x, y);
-                               }
-                               
-                               // Case4:
-                               // bx + d1y < 0
-                               // y = preferredY
-                               x = ( -h - d1 * y ) * invB;
-                               if (minX <= x && x <= maxX &&
-                                       b * x + d1 * y < 0) // Satisfy Case4
-                               {
-                                       // If there is no solution, or the new 
solution yields smaller value, pick the new solution.
-                                       if (!s || transformSize(s.x, s.y, 
matrix).x > transformSize(x, y, matrix).x)
-                                               s = new Point(x, y);
-                               }
-                       }
-                       
-                       // If there's already a solution that matches preferred 
dimention, return
-                       if (s)
-                               return s;
-                       
-                       // Find a solution that matches the width and minimizes 
the height: 
-                       const a:Number = matrix.a;
-                       const c:Number = matrix.c;
-                       const c1:Number = ( a*c >= 0 ) ? c : -c;
-                       return solveEquation(b, d1, h, minX, minY, maxX, maxY, 
a, c1);
-               }
-               
-               /**
-                *  Calculates (x,y) such that the bounding box (0,0,x,y) 
transformed
-                *  with <code>matrix</code> will have bounding box with
-                *  width equal to <code>w</code>.
-                *  x and y are restricted by <code>minX</code>, 
<code>maxX</code> and
-                *  <code>minY</code>, <code>maxY</code>.
-                *
-                *  If possible x will be set to <code>preferredX</code> or
-                *  y will be set to <code>preferredY</code>.
-                *  
-                *  When there are multiple solutions, the function picks the 
one that
-                *  minimizes the bounding box area of transformed (0,0,x,y).
-                * 
-                *  The functon assumes <code>minX >= 0</code> and <code>minY 
>= 0</code>
-                *  (solution components x and y are non-negative).
-                *  
-                *  @return Returns Point(x,y) or null if no solution exists. 
-                * 
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */        
-               static public function calcUBoundsToFitTBoundsWidth(w:Number,
-                                                                               
                                        matrix:Matrix,
-                                                                               
                                        preferredX:Number,
-                                                                               
                                        preferredY:Number,
-                                                                               
                                        minX:Number,
-                                                                               
                                        minY:Number,
-                                                                               
                                        maxX:Number,
-                                                                               
                                        maxY:Number):Point
-               {
-                       // Untransformed bounds size is (x,y). The corners of 
the untransformed
-                       // bounding box are p1(0,0) p2(x,0) p3(0,y) p4(x,y).
-                       // Matrix is | a c tx |
-                       //           | b d ty |
-                       //
-                       // After transfomation with the matrix those four 
points are:
-                       // t1 = (0, 0)              = 
matrix.deltaTransformPoint(p1)
-                       // t2 = (ax, bx)            = 
matrix.deltaTransformPoint(p2)
-                       // t3 = (cy, dy)            = 
matrix.deltaTransformPoint(p3)
-                       // t4 = (ax + cy, cx + dy)  = 
matrix.deltaTransformPoint(p4)
-                       //
-                       // The transformed bounds bounding box dimensions are 
(w,h):
-                       // (1) w = max( t1.x, t2.x, t3.x, t4.x ) - min( t1.x, 
t2.x, t3.x, t4.x)
-                       // (2) h = max( t1.y, t2.y, t3.y, t4.y ) - min( t1.y, 
t2.y, t3.y, t4.y)
-                       //
-                       // Looking at all the possible cases for min and max 
functions above,
-                       // we can construct and solve simple linear systems for 
x and y.
-                       // For example in the case of
-                       // t1.x <= t2.x <= t3.x <= t4.x
-                       // our first equation is
-                       // (1) w = t4.x - t1.x <==> w = ax + cy
-                       //
-                       // To minimize the cases we're looking at we can take 
advantage of
-                       // the limits we have: x >= 0, y >= 0;
-                       // Taking into account these limits we deduce that:
-                       // a*c >= 0  gives us (1) w = abs( t4.x - t1.x ) = abs( 
ax + cy )
-                       // a*c <  0  gives us (1) w = abs( t2.x - t3.x ) = abs( 
ax - cy )
-                       // b*d >= 0  gives us (2) h = abs( t4.y - t1.y ) = abs( 
bx + dy )
-                       // b*d <  0  gives us (2) h = abs( t2.y - t3.y ) = abs( 
bx - dy )
-                       //
-                       // If we do a substitution such that
-                       // c1 = a*c >= 0 ? c : -c
-                       // d1 = b*d >= 0 ? d : -d
-                       // we get the following linear system:
-                       // (1) w = abs( ax + c1y )
-                       // (2) h = abs( bx + d1y )
-                       //
-                       // Since we're matching width we only care about (1) 
-                       
-                       var a:Number = matrix.a;
-                       var c:Number = matrix.c;
-                       
-                       // If components are very close to zero, zero them out 
to handle the special cases
-                       if (-1.0e-9 < a && a < +1.0e-9)
-                               a = 0;
-                       if (-1.0e-9 < c && c < +1.0e-9)
-                               c = 0;
-                       
-                       // Handle special cases first
-                       if (a == 0 && c == 0)
-                               return null; // No solution
-                       
-                       if (a == 0)
-                               return new Point( preferredX, w / Math.abs(c) 
);               
-                       else if (c == 0)
-                               return new Point( w / Math.abs(a), preferredY 
);    
-                       
-                       const c1:Number = ( a*c >= 0 ) ? c : -c;
-                       // Now we have the following linear sytesm:
-                       // (1) w = abs( ax + c1y )
-                       // (2) x = preferredX or y = preferredY
-                       
-                       var s:Point;
-                       var x:Number;
-                       var y:Number;
-                       
-                       if (c1 != 0 && preferredX > 0)
-                       {
-                               const invC1:Number = 1 / c1;
-                               preferredX = Math.max(minX, Math.min(maxX, 
preferredX));
-                               x = preferredX;
-                               
-                               // Case1:
-                               // a * x + c1 * y >= 0
-                               // x = preferredX
-                               y = (w - a * x) * invC1;
-                               if (minY <= y && y <= maxY &&
-                                       a * x + c1 * y >= 0 ) // Satisfy Case1
-                               {
-                                       s = new Point(x, y);        
-                               }
-                               
-                               // Case2:
-                               // a * x + c1 * y < 0
-                               // x = preferredX
-                               y = (-w - a * x) * invC1;
-                               if (minY <= y && y <= maxY &&
-                                       a * x + c1 * y < 0 ) // Satisfy Case2
-                               {
-                                       // If there is no solution, or the new 
solution yields smaller value, pick the new solution.
-                                       if (!s || transformSize(s.x, s.y, 
matrix).y > transformSize(x, y, matrix).y)
-                                               s = new Point(x, y);
-                               }
-                       }
-                       
-                       if (a != 0 && preferredY > 0)
-                       {
-                               const invA:Number = 1 / a;
-                               preferredY = Math.max(minY, Math.min(maxY, 
preferredY));
-                               y = preferredY;
-                               
-                               // Case3:
-                               // a * x + c1 * y >= 0
-                               // y = preferredY
-                               x = (w - c1 * y ) * invA;
-                               if (minX <= x && x <= maxX &&
-                                       a * x + c1 * y >= 0) // Satisfy Case3
-                               {
-                                       // If there is no solution, or the new 
solution yields smaller value, pick the new solution.
-                                       if (!s || transformSize(s.x, s.y, 
matrix).y > transformSize(x, y, matrix).y)
-                                               s = new Point(x, y);
-                               }
-                               
-                               // Case4:
-                               // a * x + c1 * y < 0
-                               // y = preferredY
-                               x = (-w - c1 * y ) * invA;
-                               if (minX <= x && x <= maxX &&
-                                       a * x + c1 * y < 0) // Satisfy Case4
-                               {
-                                       // If there is no solution, or the new 
solution yields smaller value, pick the new solution.
-                                       if (!s || transformSize(s.x, s.y, 
matrix).y > transformSize(x, y, matrix).y)
-                                               s = new Point(x, y);
-                               }
-                       }
-                       
-                       // If there's already a solution that matches preferred 
dimention, return
-                       if (s)
-                               return s;
-                       
-                       // Find a solution that matches the width and minimizes 
the height: 
-                       const b:Number = matrix.b;
-                       const d:Number = matrix.d;
-                       const d1:Number = (b*d >= 0) ? d : -d;
-                       return solveEquation(a, c1, w, minX, minY, maxX, maxY, 
b, d1);
-               }
-               
-               /**
-                *  Finds a solution (x,y) for the equation abs(a*x + c*y) = w 
such that
-                *  abs(b*x +d*y) is minimized.
-                *  If there is infinite number of solutions, x and y are 
picked to be
-                *  as close as possible.
-                * 
-                *  Doesn't handle cases where <code>a</code> or <code>c</code> 
are zero.
-                * 
-                *  @return Returns Point(x,y)
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */        
-               static private function solveEquation(a:Number,
-                                                                               
          c:Number,
-                                                                               
          w:Number,
-                                                                               
          minX:Number,
-                                                                               
          minY:Number, 
-                                                                               
          maxX:Number, 
-                                                                               
          maxY:Number, 
-                                                                               
          b:Number, 
-                                                                               
          d:Number):Point
-               {
-                       if (a == 0 || c == 0)
-                               return null; // x and y are not co-dependent
-                       
-                       // (1) w = abs( ax + cy )
-                       // Find the range of solutsion for y and pick:
-                       var x:Number;
-                       var y:Number;
-                       var s:Point;
-                       
-                       // Case1: ax + cy >= 0, from (1) above we get:
-                       // (1) x = (w - cy) / a
-                       //
-                       // Lets find the possible range of values for y:
-                       // We know that
-                       // (3) minX <= x <= maxX
-                       //
-                       // Substitute x with (w - cy)/a in (3):
-                       // (3) minX - w/a <= -cy/a <= maxX - w/a
-                       // (3) min( A, B ) <= y <= max( A, B ), where
-                       // A = (minX - w/a) * (-a/c)
-                       // B = (maxX - w/a) * (-a/c)
-                       
-                       var A:Number = (w - minX * a) / c;              
-                       var B:Number = (w - maxX * a) / c;              
-                       var rangeMinY:Number = Math.max(minY, Math.min(A, B));
-                       var rangeMaxY:Number = Math.min(maxY, Math.max(A, B));
-                       const det:Number = (b * c - a * d);
-                       
-                       // We have a possible solution for Case1 if the range 
for y is valid
-                       if (rangeMinY <= rangeMaxY)
-                       {
-                               // Now that we have a valid range for y, we 
need to pick a value within
-                               // that range.
-                               //
-                               // We calculate the value based on a custom 
condition.
-                               //
-                               // The custom condition that we use could be 
anything that defines
-                               // another equation for x and y. Some examples 
are:
-                               // "make x and y as close as possible": y = w / 
( a + c );  
-                               // "minimize abs(bx + dy)": y = b * w / det    
-                               // "preserve aspect ratio": y = w / ( a * 
preferredX / preferredY + c );
-                               if (Math.abs(det) < 1.0e-9)
-                               {
-                                       // There is infinite number of 
solutions, lets pick x == y
-                                       y = w / ( a + c );
-                               }
-                               else
-                               {
-                                       // Minimize abs(bx + dy) - we need to 
solve:
-                                       // abs( b * ( w - c * y ) / a + d * y ) 
= 0
-                                       // which gives us:
-                                       y = b * w / det;
-                               }
-                               
-                               // Now that we have the y value calculated from 
the custom condition,
-                               // we clamp with the range. This gives us a 
solution with
-                               // values as close as possible to satisfy our 
custom condition when
-                               // the condition is a linear function of x and 
y (in our case it is).
-                               y = Math.max(rangeMinY, Math.min(y, rangeMaxY));
-                               
-                               x = (w - c * y) / a;
-                               return new Point(x, y);
-                       }
-                       
-                       // Case2: ax + cy < 0, from (1) above we get:
-                       // (1) x = (-w - cy) / a
-                       //
-                       // Lets find the possible range of values for y:
-                       // We know that
-                       // (3) minX <= x <= maxX
-                       //
-                       // Substitute x with (-w - cy)/a in (3):
-                       // (3) minX + w/a <= -cy/a <= maxX + w/a
-                       // (3) min( A, B ) <= y <= max( A, B ), where
-                       // A = (minX + w/a) * (-a/c)
-                       // B = (maxX + w/a) * (-a/c)
-                       
-                       A = -(minX * a + w) / c;
-                       B = -(maxX * a + w) / c;
-                       rangeMinY = Math.max(minY, Math.min(A, B));
-                       rangeMaxY = Math.min(maxY, Math.max(A, B));
-                       
-                       // We have a possible solution for Case2 if the range 
for y is valid
-                       if (rangeMinY <= rangeMaxY)
-                       {
-                               // Now that we have a valid range for y, we 
need to pick a value within
-                               // that range.
-                               //
-                               // We calculate the value based on a custom 
condition.
-                               //
-                               // The custom condition that we use could be 
anything that defines
-                               // another equation for x and y. Some examples 
are:
-                               // "make x and y as close as possible": y = -w 
/ ( a + c );  
-                               // "minimize abs(bx + dy)": y = -b * w / det    
-                               // "preserve aspect ratio": y = w / ( a * 
preferredX / preferredY + c );
-                               if (Math.abs(det) < 1.0e-9)
-                               {
-                                       // There is infinite number of 
solutions, lets pick x == y
-                                       y = -w / ( a + c );
-                               }
-                               else
-                               {
-                                       // Minimize abs(bx + dy) - we need to 
solve:
-                                       // abs( b * ( -w - c * y ) / a + d * y 
) = 0
-                                       // which gives us:
-                                       y = -b * w / det;
-                               }
-                               
-                               // Now that we have the y value calculated from 
the custom condition,
-                               // we clamp with the range. This gives us a 
solution with
-                               // values as close as possible to satisfy our 
custom condition when
-                               // the condition is a linear function of x and 
y (in our case it is).
-                               y = Math.max(rangeMinY, Math.min(y, rangeMaxY));
-                               x = (-w - c * y) / a;
-                               return new Point(x, y);
-                               
-                       }
-                       return null; // No solution
-               }
-               
-               /**
-                *  Calculates (x,y) such that the bounding box (0,0,x,y) 
transformed
-                *  with <code>matrix</code> will have bounding box (0,0,w,h).
-                *  x and y are restricted by <code>minX</code>, 
<code>maxX</code> and
-                *  <code>minY</code>, <code>maxY</code>.
-                * 
-                *  When there is infinite number of solutions, the function 
will
-                *  calculate x and y to be as close as possible.
-                * 
-                *  The functon assumes <code>minX >= 0</code> and <code>minY 
>= 0</code>
-                *  (solution components x and y are non-negative). 
-                *  
-                *  @return Point(x,y) or null if no solution exists.
-                * 
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               static public function calcUBoundsToFitTBounds(w:Number, 
-                                                                               
                           h:Number,
-                                                                               
                           matrix:Matrix,
-                                                                               
                           minX:Number,
-                                                                               
                           minY:Number, 
-                                                                               
                           maxX:Number, 
-                                                                               
                           maxY:Number):Point
-               {
-                       // Untransformed bounds size is (x,y). The corners of 
the untransformed
-                       // bounding box are p1(0,0) p2(x,0) p3(0,y) p4(x,y).
-                       // Matrix is | a c tx |
-                       //           | b d ty |
-                       //
-                       // After transfomation with the matrix those four 
points are:
-                       // t1 = (0, 0)              = 
matrix.deltaTransformPoint(p1)
-                       // t2 = (ax, bx)            = 
matrix.deltaTransformPoint(p2)
-                       // t3 = (cy, dy)            = 
matrix.deltaTransformPoint(p3)
-                       // t4 = (ax + cy, cx + dy)  = 
matrix.deltaTransformPoint(p4)
-                       //
-                       // The transformed bounds bounding box dimensions are 
(w,h):
-                       // (1) w = max( t1.x, t2.x, t3.x, t4.x ) - min( t1.x, 
t2.x, t3.x, t4.x)
-                       // (2) h = max( t1.y, t2.y, t3.y, t4.y ) - min( t1.y, 
t2.y, t3.y, t4.y)
-                       //
-                       // Looking at all the possible cases for min and max 
functions above,
-                       // we can construct and solve simple linear systems for 
x and y.
-                       // For example in the case of
-                       // t1.x <= t2.x <= t3.x <= t4.x
-                       // our first equation is
-                       // (1) w = t4.x - t1.x <==> w = ax + cy
-                       //
-                       // To minimize the cases we're looking at we can take 
advantage of
-                       // the limits we have: x >= 0, y >= 0;
-                       // Taking into account these limits we deduce that:
-                       // a*c >= 0  gives us (1) w = abs( t4.x - t1.x ) = abs( 
ax + cy )
-                       // a*c <  0  gives us (1) w = abs( t2.x - t3.x ) = abs( 
ax - cy )
-                       // b*d >= 0  gives us (2) h = abs( t4.y - t1.y ) = abs( 
bx + dy )
-                       // b*d <  0  gives us (2) h = abs( t2.y - t3.y ) = abs( 
bx - dy )
-                       //
-                       // If we do a substitution such that
-                       // c1 = a*c >= 0 ? c : -c
-                       // d1 = b*d >= 0 ? d : -d
-                       // we get the following linear system:
-                       // (1) w = abs( ax + c1y )
-                       // (2) h = abs( bx + d1y )
-                       // 
-                       
-                       var a:Number = matrix.a;
-                       var b:Number = matrix.b;
-                       var c:Number = matrix.c;
-                       var d:Number = matrix.d;
-                       
-                       // If components are very close to zero, zero them out 
to handle the special cases
-                       if (-1.0e-9 < a && a < +1.0e-9)
-                               a = 0;
-                       if (-1.0e-9 < b && b < +1.0e-9)
-                               b = 0;
-                       if (-1.0e-9 < c && c < +1.0e-9)
-                               c = 0;
-                       if (-1.0e-9 < d && d < +1.0e-9)
-                               d = 0;
-                       
-                       // Handle special cases.
-                       if (b == 0 && c == 0)
-                       {
-                               // No solution in the following cases since the 
matrix collapses
-                               // all points into a line.
-                               if (a == 0 || d == 0)
-                                       return null;
-                               
-                               // (1) w = abs( ax + cy ) <=> w = abs( ax ) <=> 
w = abs(a)x
-                               // (2) h = abs( bx + dy ) <=> h = abs( dy ) <=> 
h = abs(d)y
-                               return new Point(w / Math.abs(a), h / 
Math.abs(d));
-                       }
-                       
-                       if (a == 0 && d == 0)
-                       {
-                               // No solution in the following cases since the 
matrix collapses
-                               // all points into a line.
-                               if (b == 0 || c == 0)
-                                       return null;
-                               
-                               // (1) w = abs( ax + cy ) <=> w = abs( cy ) <=> 
w = abs(c)y
-                               // (2) h = abs( bx + dy ) <=> h = abs( bx ) <=> 
h = abs(b)x
-                               return new Point(h / Math.abs(b), w / 
Math.abs(c));
-                       }
-                       
-                       // Handle general cases.
-                       const c1:Number = ( a*c >= 0 ) ? c : -c;
-                       const d1:Number = ( b*d >= 0 ) ? d : -d;
-                       // we get the following linear system:
-                       // (1) w = abs( ax + c1y )
-                       // (2) h = abs( bx + d1y )
-                       
-                       // Calculate the determinant of the system
-                       const det:Number = a * d1 - b * c1;
-                       if (Math.abs(det) < 1.0e-9)
-                       {
-                               // No solution in these cases since the matrix
-                               // collapses all points into a line.
-                               if (c1 == 0 || a == 0 || a == -c1)
-                                       return null;
-                               
-                               if (Math.abs(a * h - b * w) > 1.0e-9)
-                                       return null; // No solution in this case
-                               
-                               // Determinant is zero, the equations (1) & (2) 
are equivalent and
-                               // we have only one equation:
-                               // (1) w = abs( ax + c1y )
-                               //
-                               // Solve it finding x and y as close as 
possible:
-                               return solveEquation(a, c1, w, minX, minX, 
maxX, maxY, b, d1);
-                       }
-                       
-                       // Pre-multiply w & h by the inverse dteterminant
-                       const invDet:Number = 1 / det;
-                       w *= invDet;
-                       h *= invDet;
-                       
-                       // Case 1:
-                       // a * x + c1 * y >= 0
-                       // b * x + d1 * y >= 0
-                       var s:Point;
-                       s = solveSystem(a, c1, b, d1, w, h);
-                       if (s &&
-                               minX <= s.x && s.x <= maxX && minY <= s.y && 
s.y <= maxY &&
-                               a * s.x + c1 * s.x >= 0 &&
-                               b * s.x + d1 * s.y >= 0)
-                               return s;
-                       
-                       // Case 2:
-                       // a * x + c1 * y >= 0
-                       // b * x + d1 * y < 0
-                       s = solveSystem( a, c1, b, d1, w, -h);
-                       if (s &&
-                               minX <= s.x && s.x <= maxX && minY <= s.y && 
s.y <= maxY &&
-                               a * s.x + c1 * s.x >= 0 &&
-                               b * s.x + d1 * s.y < 0)
-                               return s;
-                       
-                       // Case 3:
-                       // a * x + c1 * y < 0
-                       // b * x + d1 * y >= 0
-                       s = solveSystem( a, c1, b, d1, -w, h);
-                       if (s &&
-                               minX <= s.x && s.x <= maxX && minY <= s.y && 
s.y <= maxY &&
-                               a * s.x + c1 * s.x < 0 &&
-                               b * s.x + d1 * s.y >= 0)
-                               return s;
-                       
-                       // Case 4:
-                       // a * x + c1 * y < 0
-                       // b * x + d1 * y < 0
-                       s = solveSystem( a, c1, b, d1, -w, -h);
-                       if (s &&
-                               minX <= s.x && s.x <= maxX && minY <= s.y && 
s.y <= maxY &&
-                               a * s.x + c1 * s.x < 0 &&
-                               b * s.x + d1 * s.y < 0)
-                               return s;
-                       
-                       return null; // No solution.
-               }
-               
-               /**
-                *  Determine if two Matrix instances are equal.
-                *  
-                *  @return true if the matrices are equal.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function isEqual(m1:Matrix, m2:Matrix):Boolean
-               {
-                       return ((m1 && m2 && 
-                               m1.a == m2.a &&
-                               m1.b == m2.b &&
-                               m1.c == m2.c &&
-                               m1.d == m2.d &&
-                               m1.tx == m2.tx &&
-                               m1.ty == m2.ty) || 
-                               (!m1 && !m2));
-               }
-               
-               /**
-                *  Determine if two Matrix3D instances are equal.
-                *  
-                *  @return true if the matrices are equal.
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               public static function isEqual3D(m1:Matrix3D, 
m2:Matrix3D):Boolean
-               {
-                       if (m1 && m2 && m1.rawData.length == m2.rawData.length)
-                       {
-                               var r1:Vector.<Number> = m1.rawData;
-                               var r2:Vector.<Number> = m2.rawData;
-                               
-                               return (r1[0] == r2[0] &&
-                                       r1[1] == r2[1] &&
-                                       r1[2] == r2[2] &&
-                                       r1[3] == r2[3] &&
-                                       r1[4] == r2[4] &&
-                                       r1[5] == r2[5] &&
-                                       r1[6] == r2[6] &&
-                                       r1[7] == r2[7] &&
-                                       r1[8] == r2[8] &&
-                                       r1[9] == r2[9] &&
-                                       r1[10] == r2[10] &&
-                                       r1[11] == r2[11] &&
-                                       r1[12] == r2[12] &&
-                                       r1[13] == r2[13] &&
-                                       r1[14] == r2[14] &&
-                                       r1[15] == r2[15]);
-                       }
-                       
-                       return (!m1 && !m2);
-               }
-               
-               /**
-                *  Calculates (x,y) such as to satisfy the linear system:
-                *  | a * x + c * y = m
-                *  | b * x + d * y = n
-                * 
-                *  @param mOverDet <code>mOverDet must be equal to m / (a*d - 
b*c)</code>
-                *  @param nOverDet <code>mOverDet must be equal to n / (a*d - 
b*c)</code>
-                *
-                *  @return returns Point(x,y)
-                *
-                *  
-                *  @langversion 3.0
-                *  @playerversion Flash 9
-                *  @playerversion AIR 1.1
-                *  @productversion Flex 3
-                */
-               static private function solveSystem(a:Number, 
-                                                                               
        c:Number, 
-                                                                               
        b:Number, 
-                                                                               
        d:Number, 
-                                                                               
        mOverDet:Number, 
-                                                                               
        nOverDet:Number):Point
-               {
-                       return new Point(d * mOverDet - c * nOverDet,
-                               a * nOverDet - b * mOverDet);
-               }
-               
-       }
-       
-}
-

Reply via email to