Flash getBounds bug

about 2 years ago malczak actionscript comments

Recently, as I worked on a new version of komixo maker, I came across this, really irritating, bug. As it is written in title, it is related with getBounds method of DisplayObject class. Following the documentation, this method should return rectangle that defines the boundary of the display object, including all strokes. Method works fine, unless You decide, to draw shapes with line scaling mode set to LineScaleMode.NONE. This scaling mode ensures that line thickness will never be scaled, if shape will be scaled.

In this situation getBounds, does not return correct rectangle. Method will always return rectangle, as if object was drawn with line scale set to LineScaleMode.NORMAL. In this mode, line thickness is scaled when object is scaled. And rectangle returned by getBounds, will always be larger than object itself (for scaled shapes).

To test this, we can create Shape object and draw a circle on it, with line scaling mode set to LineScaleMode.NONE. Then lets scale our shape, and call getBounds method. What we will see, is that rectangle is larger than the object itself.

Example code (copy pasted from fla project)

 1 addChild( createShape(LineScaleMode.NORMAL) ).alpha = 0.4;
 2 var shp:Shape = addChild( createShape( LineScaleMode.NONE ) ) as Shape;
 3 addChild( createShape(LineScaleMode.NONE, NaN ) ).alpha = 0.4;
 4 
 5 var rr:Rectangle = shp.getRect(this);
 6 var rb:Rectangle = shp.getBounds(this);
 7 
 8 var ms:Shape = new Shape();
 9 addChild( ms );
10 ms.graphics.lineStyle( 1, 0xff0000, 1, false, LineScaleMode.NONE );
11 ms.graphics.drawRect( rr.x, rr.y, rr.width, rr.height );
12 
13 ms.graphics.lineStyle( 1, 0x0000ff, 1, false, LineScaleMode.NONE );
14 ms.graphics.drawRect( rb.x, rb.y, rb.width, rb.height );                    
15 
16 trace("rect ", rr );
17 trace("bounds ", rb );
18 
19 
20 
21 function createShape( lineScaleMode:String, lineThickness:Number=8 ):Shape
22 {
23     var shp:Shape = new Shape();
24     shp.graphics.beginFill( 0x00ff00, 0.8 );
25     shp.graphics.lineStyle( lineThickness, 0x0, 0.7, false, lineScaleMode );
26     shp.graphics.drawEllipse( 0,0, 150, 150 );
27     shp.graphics.endFill(); 
28     
29     
30     shp.transform.matrix = new Matrix( 2, 0, 0, 2 );
31 
32     return shp; 
33 };

and the resulting image for that code
- red rectangle is returned by getRect method
- blue rectangle is returned by getBounds method
... and as we can see the blue one includes scaled stroke

To get a correct boundary box rectangle, we can draw object into BitmapData or traverse all children, to manually create boundary box rectangle. First solution is described here while the second one is described here by David Barlia.

Moreover this is well known bug, and was already reported as a flashplayer bug. Unfortunately, it seems to be not very important for Adobe, to fix known and already reported bugs.

Related bugs and feature requests are : #FP-452, #FP-595, #FP-741, #FP-3948.

Comments

No comments as yet. Be first to comment.

New comment

  1. (with http or https prefix)

  2. (use [code][/code] tags to post a code snippet)

  3. (javascript is required)

Website content premeditately commited by malczak & sobstel.
Layout by mlando. Icons by dryicons.com. All rights reserved.