BitmapData.draw bug?

I have some strange behaviour with the BitmapData.draw() function

Consider the following code:

var canvas:BitmapData =  new BitmapData(400, 400, true, 0xFF000000); 
		 
var rwidth:Int = 250;
var rheight:Int = 50; 
var redcolor:Int = 0xFFFF0000;
var ribbon:BitmapData =  new BitmapData(rwidth, rheight, true, 0x00000000); 
var hs:Shape = new Shape();
var g:Graphics = hs.graphics;
g.lineStyle(1, redcolor);
g.beginFill(redcolor);
g.drawRect(0, 0, rwidth, rheight);
g.endFill();
ribbon.draw(hs);
		
var cliprect:Rectangle = new Rectangle(0, 0, 50, 50);

if I do

canvas.copyPixels(ribbon, cliprect, new Point(50, 50), null, null, true);

That’s OK, I have a red square that appear over my black canvas (at position (50,50))

But now, if instead of using the copyPixel() function, I use the draw function, with the following code:

var mat:Matrix = new Matrix();
mat.translate(50, 50);
canvas.draw(ribbon, mat, null, null, cliprect);

I have nothing but my black canvas (no red square at all). Whereas I would be expecting the same result as with the copyPixel() function (a red square at position 50,50 ).
So is there something I misunderstood or is it a bug in the bitmapdata.draw() function?

Tested with openfl 3.3.3 and lime 2.6.2 on flash target

Hi,

The cliprect starts at the origin of the bitmaps.
So you tell the canvas to draw only on the top left 50, 50 rectangle.
And you start drawing at 50, 50 ( because of the translate ).

So set your rectangle to ( 50, 50, rwidth, rheight ), or try not setting the clip rect parameter, it’s an optional parameter.

Yes the cliprect start at the origin of the bitmap. But it is the origin of the source bitmap (ribbon), not the destination one (canvas). So I don’t understand your remark.

No, no, that’s the thing.

The rectangle are different paraments in copyPixels and draw.
In copyPixels, it clips the source, what you copy from.
In draw, it clips the area where you draw in the destination.

PS: At least, I am pretty sure, I didn’t run the code.
Just try changing the rectangle to 50, 50, widthyouwant, heightyouwant and see if it works.

Well. According to the openfl api cliprect refer to the source for both functions:

http://www.openfl.org/documentation/api/openfl/display/BitmapData.html

function draw(source:IBitmapDrawable, matrix:Matrix, colorTransform:ColorTransform, blendMode:BlendMode, clipRect:Rectangle, smoothing:Bool):Void

@param clipRect A Rectangle object that defines the area of the source object to draw. If you do not supply this value, no clipping occurs and the entire source object is drawn.

Hum, I remembered something else…
My bad then, hope you find a solution.

OpenFL does nothing when targeting Flash, it just changes the calls from openfl.* to flash.* so if it doesn’t work on Flash is a Flash thing. Also, the documentation is the same as the one in Flash http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html#draw()

In your code you are saying:

  • Move the ribbon shape to (50, 50) but clip the draw() call to the canvas bitmap to (0, 0, 50, 50)

In your code you are saying:

  • Move the ribbon shape to (50, 50) but clip the draw() call to the canvas bitmap to (0, 0, 50, 50)

No. In my code I am saying:

  • clip a 50x50 square with left corner at position (0,0) from the ribbon bitmapdata and start drawing it (translate it) at position (50,50) on the canvas bitmapdata

Believe me, I wrote the BitmapData.draw() implementation for non-flash targets. AS3 documentation has a lot of errors :sweat: It applies the transformation before clipping.

Well OK. Applying the transform before the clipping is a complete nonsense for me but if this is how it works, guess we have to deal with it :wink: