mirror of
https://github.com/scratchfoundation/scratch-flash.git
synced 2024-12-13 01:21:28 -05:00
151 lines
4.7 KiB
ActionScript
151 lines
4.7 KiB
ActionScript
|
/*
|
||
|
* Scratch Project Editor and Player
|
||
|
* Copyright (C) 2014 Massachusetts Institute of Technology
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
package {
|
||
|
import flash.display.BitmapData;
|
||
|
import flash.display.DisplayObject;
|
||
|
import flash.geom.Point;
|
||
|
import flash.geom.Rectangle;
|
||
|
|
||
|
public class ChildRender extends BitmapData {
|
||
|
private const allowPartial:Boolean = true;
|
||
|
private const maxSize:uint = 1022;
|
||
|
private const halfSize:uint = maxSize >> 1;
|
||
|
private var orig_width:Number;
|
||
|
private var orig_height:Number;
|
||
|
private var orig_bounds:Rectangle;
|
||
|
public var inner_x:Number;
|
||
|
public var inner_y:Number;
|
||
|
public var inner_w:Number;
|
||
|
public var inner_h:Number;
|
||
|
public var scale:Number;
|
||
|
public function ChildRender(w:Number, h:Number, dispObj:DisplayObject, penLayer:DisplayObject, b:Rectangle) {
|
||
|
orig_width = w;
|
||
|
orig_height = h;
|
||
|
orig_bounds = b;
|
||
|
scale = 1;
|
||
|
|
||
|
reset(dispObj, penLayer);
|
||
|
|
||
|
super(Math.ceil(Math.min(w, maxSize)), Math.ceil(Math.min(h, maxSize)), true, 0);
|
||
|
}
|
||
|
|
||
|
public function reset(dispObj:DisplayObject, penLayer:DisplayObject):void {
|
||
|
inner_x = inner_y = 0;
|
||
|
inner_w = inner_h = 1;
|
||
|
|
||
|
if(!allowPartial) {
|
||
|
if(orig_width > maxSize || orig_height > maxSize)
|
||
|
scale = maxSize / Math.max(orig_width, orig_height);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Is it too large and needs to be partially rendered?
|
||
|
var bounds:Rectangle;
|
||
|
if(orig_width > maxSize || orig_height > maxSize) {
|
||
|
bounds = getVisibleBounds(dispObj, penLayer);
|
||
|
bounds.inflate(halfSize - bounds.width / 2, 0);
|
||
|
if(bounds.x < 0) {
|
||
|
bounds.width += bounds.x;
|
||
|
bounds.x = 0;
|
||
|
}
|
||
|
if(bounds.right > orig_width)
|
||
|
bounds.width += orig_width - bounds.right;
|
||
|
|
||
|
inner_x = bounds.x / orig_width;
|
||
|
inner_w = maxSize / orig_width;
|
||
|
}
|
||
|
|
||
|
if(orig_height > maxSize) {
|
||
|
if(!bounds) bounds = getVisibleBounds(dispObj, penLayer);
|
||
|
bounds.inflate(0, halfSize - bounds.height / 2);
|
||
|
if(bounds.y < 0) {
|
||
|
bounds.height += bounds.y;
|
||
|
bounds.y = 0;
|
||
|
}
|
||
|
if(bounds.bottom > orig_height)
|
||
|
bounds.height += orig_height - bounds.bottom;
|
||
|
|
||
|
inner_y = bounds.y / orig_height;
|
||
|
inner_h = maxSize / orig_height;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function isPartial():Boolean {
|
||
|
return allowPartial && (width < orig_width || height < orig_height);
|
||
|
}
|
||
|
|
||
|
public function get renderWidth():Number {
|
||
|
return (width > orig_width ? orig_width : width);
|
||
|
}
|
||
|
|
||
|
public function get renderHeight():Number {
|
||
|
return (height > orig_height ? orig_height : height);
|
||
|
}
|
||
|
|
||
|
public function needsResize(w:Number, h:Number):Boolean {
|
||
|
if(width > orig_width && Math.ceil(w) > width) {
|
||
|
return true;
|
||
|
}
|
||
|
if(height > orig_height && Math.ceil(h) > height) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public function needsRender(dispObj:DisplayObject, w:Number, h:Number, penLayer:DisplayObject):Boolean {
|
||
|
if(inner_x == 0 && inner_y == 0 && inner_w == 1 && inner_h == 1) return false;
|
||
|
|
||
|
var renderRect:Rectangle = new Rectangle(inner_x*w, inner_y*h, inner_w*w, inner_h*h);
|
||
|
renderRect.width += 0.001;
|
||
|
renderRect.height += 0.001;
|
||
|
var stageRect:Rectangle = getVisibleBounds(dispObj, penLayer);
|
||
|
var containsStage:Boolean = renderRect.containsRect(stageRect);
|
||
|
return !containsStage;
|
||
|
}
|
||
|
|
||
|
private function getVisibleBounds(dispObj:DisplayObject, penLayer:DisplayObject):Rectangle {
|
||
|
var visibleBounds:Rectangle = penLayer.getBounds(dispObj);
|
||
|
var tl:Point = orig_bounds.topLeft;
|
||
|
visibleBounds.offset(-tl.x, -tl.y);
|
||
|
if(visibleBounds.x < 0) {
|
||
|
visibleBounds.width += visibleBounds.x;
|
||
|
visibleBounds.x = 0;
|
||
|
}
|
||
|
if(visibleBounds.y < 0) {
|
||
|
visibleBounds.height += visibleBounds.y;
|
||
|
visibleBounds.y = 0;
|
||
|
}
|
||
|
if(visibleBounds.right > orig_width) {
|
||
|
visibleBounds.width += orig_width - visibleBounds.right;
|
||
|
}
|
||
|
if(visibleBounds.bottom > orig_height) {
|
||
|
visibleBounds.height += orig_height - visibleBounds.bottom;
|
||
|
}
|
||
|
visibleBounds.x *= dispObj.scaleX;
|
||
|
visibleBounds.y *= dispObj.scaleY;
|
||
|
visibleBounds.width *= dispObj.scaleX;
|
||
|
visibleBounds.height *= dispObj.scaleY;
|
||
|
|
||
|
return visibleBounds;
|
||
|
}
|
||
|
}
|
||
|
}
|