Skip to content

Commit 87118db

Browse files
'DisplayObject.drawToBitmapData' now supports sizes bigger than the stage / back buffer
1 parent 007062a commit 87118db

File tree

1 file changed

+48
-14
lines changed

1 file changed

+48
-14
lines changed

starling/src/starling/display/DisplayObject.as

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ package starling.display
3636
import starling.utils.Color;
3737
import starling.utils.MathUtil;
3838
import starling.utils.MatrixUtil;
39+
import starling.utils.Pool;
3940
import starling.utils.SystemUtil;
41+
import starling.utils.execute;
4042

4143
use namespace starling_internal;
4244

@@ -392,8 +394,8 @@ package starling.display
392394
/** Draws the object into a BitmapData object.
393395
*
394396
* <p>This is achieved by drawing the object into the back buffer and then copying the
395-
* pixels of the back buffer into a texture. This also means that the returned bitmap
396-
* data cannot be bigger than the current viewPort.</p>
397+
* pixels of the back buffer into a texture. Beware: image sizes bigger than the back
398+
* buffer are only supported in AIR version 25 or higher and NOT in Flash Player.</p>
397399
*
398400
* @param out If you pass null, the object will be created for you.
399401
* If you pass a BitmapData object, it should have the size of the
@@ -412,6 +414,8 @@ package starling.display
412414
var scaleX:Number = viewPort.width / stageWidth;
413415
var scaleY:Number = viewPort.height / stageHeight;
414416
var backBufferScale:Number = painter.backBufferScaleFactor;
417+
var totalScaleX:Number = scaleX * backBufferScale;
418+
var totalScaleY:Number = scaleY * backBufferScale;
415419
var projectionX:Number, projectionY:Number;
416420
var bounds:Rectangle;
417421

@@ -429,33 +433,63 @@ package starling.display
429433
projectionX = bounds.x;
430434
projectionY = bounds.y;
431435

432-
out ||= new BitmapData(Math.ceil(bounds.width * scaleX * backBufferScale),
433-
Math.ceil(bounds.height * scaleY * backBufferScale));
436+
out ||= new BitmapData(Math.ceil(bounds.width * totalScaleX),
437+
Math.ceil(bounds.height * totalScaleY));
434438
}
435439

436440
color = Color.multiply(color, alpha); // premultiply alpha
437441

438-
painter.clear(color, alpha);
439442
painter.pushState();
440443
painter.setupContextDefaults();
441444
painter.state.renderTarget = null;
442445
painter.state.setModelviewMatricesToIdentity();
443446
painter.setStateTo(transformationMatrix);
444-
painter.state.setProjectionMatrix(projectionX, projectionY,
445-
painter.backBufferWidth / scaleX, painter.backBufferHeight / scaleY,
446-
stageWidth, stageHeight, stage.cameraPosition);
447447

448-
if (_mask) painter.drawMask(mask, this);
448+
// Images that are bigger than the current back buffer are drawn in multiple steps.
449449

450-
if (_filter) _filter.render(painter);
451-
else render(painter);
450+
var stepX:Number;
451+
var stepY:Number = projectionY;
452+
var stepWidth:Number = painter.backBufferWidth / scaleX;
453+
var stepHeight:Number = painter.backBufferHeight / scaleY;
454+
var positionInBitmap:Point = Pool.getPoint(0, 0);
455+
var boundsInBuffer:Rectangle = Pool.getRectangle(0, 0,
456+
painter.backBufferWidth * backBufferScale,
457+
painter.backBufferHeight * backBufferScale);
452458

453-
if (_mask) painter.eraseMask(mask, this);
459+
while (positionInBitmap.y < out.height)
460+
{
461+
stepX = projectionX;
462+
positionInBitmap.x = 0;
463+
464+
while (positionInBitmap.x < out.width)
465+
{
466+
painter.clear(color, alpha);
467+
painter.state.setProjectionMatrix(stepX, stepY, stepWidth, stepHeight,
468+
stageWidth, stageHeight, stage.cameraPosition);
469+
470+
if (_mask) painter.drawMask(mask, this);
471+
472+
if (_filter) _filter.render(painter);
473+
else render(painter);
474+
475+
if (_mask) painter.eraseMask(mask, this);
476+
477+
painter.finishMeshBatch();
478+
execute(painter.context.drawToBitmapData, out, boundsInBuffer, positionInBitmap);
479+
480+
stepX += stepWidth;
481+
positionInBitmap.x += stepWidth * totalScaleX;
482+
}
483+
484+
stepY += stepHeight;
485+
positionInBitmap.y += stepHeight * totalScaleY;
486+
}
454487

455-
painter.finishMeshBatch();
456-
painter.context.drawToBitmapData(out);
457488
painter.popState();
458489

490+
Pool.putRectangle(boundsInBuffer);
491+
Pool.putPoint(positionInBitmap);
492+
459493
return out;
460494
}
461495

0 commit comments

Comments
 (0)