core: Always check mergeAlpha in BitmapData.copyPixels
Previously, we would only use mergeAlpha if alphaBitmapData and alphaPoint. However, mergeAlpha can be used even when those parameters are null. Some of the AVM1 argument handling was also incorrect - I've fixed it, and extended the existing test with the output-based test added for AVM2.
|
@ -789,6 +789,16 @@ pub fn copy_pixels<'gc>(
|
|||
|
||||
if let Some(src_bitmap) = source_bitmap.as_bitmap_data_object() {
|
||||
if !src_bitmap.disposed() {
|
||||
let merge_alpha = if args.len() >= 6 {
|
||||
Some(
|
||||
args.get(5)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.as_bool(activation.swf_version()),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// dealing with object aliasing...
|
||||
let src_bitmap_clone: BitmapData; // only initialized if source is the same object as self
|
||||
let src_bitmap_data_cell = src_bitmap.bitmap_data();
|
||||
|
@ -802,62 +812,53 @@ pub fn copy_pixels<'gc>(
|
|||
&src_bitmap_gc_ref
|
||||
};
|
||||
|
||||
if args.len() >= 5 {
|
||||
let alpha_point = args
|
||||
.get(4)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation);
|
||||
let alpha_bitmap = args
|
||||
.get(3)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation);
|
||||
|
||||
let alpha_x = alpha_point
|
||||
.get("x", activation)?
|
||||
.coerce_to_f64(activation)?
|
||||
as i32;
|
||||
if let Some(alpha_bitmap) = alpha_bitmap.as_bitmap_data_object() {
|
||||
if !alpha_bitmap.disposed() {
|
||||
let alpha_point = args
|
||||
.get(4)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation);
|
||||
|
||||
let alpha_y = alpha_point
|
||||
.get("y", activation)?
|
||||
.coerce_to_f64(activation)?
|
||||
as i32;
|
||||
let alpha_x = alpha_point
|
||||
.get("x", activation)?
|
||||
.coerce_to_f64(activation)?
|
||||
as i32;
|
||||
|
||||
let alpha_bitmap = args
|
||||
.get(3)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation);
|
||||
let alpha_y = alpha_point
|
||||
.get("y", activation)?
|
||||
.coerce_to_f64(activation)?
|
||||
as i32;
|
||||
|
||||
if let Some(alpha_bitmap) = alpha_bitmap.as_bitmap_data_object() {
|
||||
if !alpha_bitmap.disposed() {
|
||||
// dealing with aliasing the same way as for the source
|
||||
let alpha_bitmap_clone: BitmapData;
|
||||
let alpha_bitmap_data_cell = alpha_bitmap.bitmap_data();
|
||||
let alpha_bitmap_gc_ref;
|
||||
let alpha_bitmap_ref = if GcCell::ptr_eq(
|
||||
alpha_bitmap.bitmap_data(),
|
||||
bitmap_data.bitmap_data(),
|
||||
) {
|
||||
alpha_bitmap_clone = alpha_bitmap_data_cell.read().clone();
|
||||
&alpha_bitmap_clone
|
||||
} else {
|
||||
alpha_bitmap_gc_ref = alpha_bitmap_data_cell.read();
|
||||
&alpha_bitmap_gc_ref
|
||||
};
|
||||
// dealing with aliasing the same way as for the source
|
||||
let alpha_bitmap_clone: BitmapData;
|
||||
let alpha_bitmap_data_cell = alpha_bitmap.bitmap_data();
|
||||
let alpha_bitmap_gc_ref;
|
||||
let alpha_bitmap_ref = if GcCell::ptr_eq(
|
||||
alpha_bitmap.bitmap_data(),
|
||||
bitmap_data.bitmap_data(),
|
||||
) {
|
||||
alpha_bitmap_clone = alpha_bitmap_data_cell.read().clone();
|
||||
&alpha_bitmap_clone
|
||||
} else {
|
||||
alpha_bitmap_gc_ref = alpha_bitmap_data_cell.read();
|
||||
&alpha_bitmap_gc_ref
|
||||
};
|
||||
|
||||
let merge_alpha = if args.len() >= 6 {
|
||||
args.get(5)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.as_bool(activation.swf_version())
|
||||
} else {
|
||||
true
|
||||
};
|
||||
|
||||
bitmap_data
|
||||
.bitmap_data()
|
||||
.write(activation.context.gc_context)
|
||||
.copy_pixels(
|
||||
source_bitmap_ref,
|
||||
(src_min_x, src_min_y, src_width, src_height),
|
||||
(dest_x, dest_y),
|
||||
Some((alpha_bitmap_ref, (alpha_x, alpha_y), merge_alpha)),
|
||||
);
|
||||
}
|
||||
bitmap_data
|
||||
.bitmap_data()
|
||||
.write(activation.context.gc_context)
|
||||
.copy_pixels(
|
||||
source_bitmap_ref,
|
||||
(src_min_x, src_min_y, src_width, src_height),
|
||||
(dest_x, dest_y),
|
||||
Some((alpha_bitmap_ref, (alpha_x, alpha_y))),
|
||||
merge_alpha.unwrap_or(true),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
bitmap_data
|
||||
|
@ -868,6 +869,9 @@ pub fn copy_pixels<'gc>(
|
|||
(src_min_x, src_min_y, src_width, src_height),
|
||||
(dest_x, dest_y),
|
||||
None,
|
||||
// Despite what the docs claim, mergeAlpa appears to be treated as 'false'
|
||||
// when no 'alphaBitmap' is specified (e.g. only 3 args are passed)
|
||||
merge_alpha.unwrap_or(false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -254,18 +254,62 @@ pub fn copy_pixels<'gc>(
|
|||
&src_bitmap_gc_ref
|
||||
};
|
||||
|
||||
let mut alpha_source = None;
|
||||
|
||||
if args.len() >= 4 {
|
||||
log::warn!("BitmapData.copyPixels - alpha not implemented");
|
||||
if let Some(alpha_bitmap) = args
|
||||
.get(3)
|
||||
.and_then(|o| o.as_object())
|
||||
.and_then(|o| o.as_bitmap_data())
|
||||
{
|
||||
// Testing shows that a null/undefined 'alphaPoint' parameter is treated
|
||||
// as 'new Point(0, 0)'
|
||||
let mut x = 0;
|
||||
let mut y = 0;
|
||||
|
||||
if let Ok(alpha_point) = args
|
||||
.get(4)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation)
|
||||
{
|
||||
x = alpha_point
|
||||
.get_property(&Multiname::public("x"), activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
y = alpha_point
|
||||
.get_property(&Multiname::public("y"), activation)?
|
||||
.coerce_to_i32(activation)?;
|
||||
}
|
||||
|
||||
alpha_source = Some((alpha_bitmap, (x, y)));
|
||||
}
|
||||
}
|
||||
|
||||
bitmap_data
|
||||
.write(activation.context.gc_context)
|
||||
.copy_pixels(
|
||||
source_bitmap_ref,
|
||||
(src_min_x, src_min_y, src_width, src_height),
|
||||
(dest_x, dest_y),
|
||||
None,
|
||||
);
|
||||
let merge_alpha = args
|
||||
.get(5)
|
||||
.unwrap_or(&Value::Bool(false))
|
||||
.coerce_to_boolean();
|
||||
|
||||
if let Some((alpha_bitmap, alpha_point)) = alpha_source {
|
||||
bitmap_data
|
||||
.write(activation.context.gc_context)
|
||||
.copy_pixels(
|
||||
source_bitmap_ref,
|
||||
(src_min_x, src_min_y, src_width, src_height),
|
||||
(dest_x, dest_y),
|
||||
Some((&*alpha_bitmap.read(), alpha_point)),
|
||||
merge_alpha,
|
||||
);
|
||||
} else {
|
||||
bitmap_data
|
||||
.write(activation.context.gc_context)
|
||||
.copy_pixels(
|
||||
source_bitmap_ref,
|
||||
(src_min_x, src_min_y, src_width, src_height),
|
||||
(dest_x, dest_y),
|
||||
None,
|
||||
merge_alpha,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -559,7 +559,8 @@ impl<'gc> BitmapData<'gc> {
|
|||
source_bitmap: &Self,
|
||||
src_rect: (i32, i32, i32, i32),
|
||||
dest_point: (i32, i32),
|
||||
alpha_source: Option<(&Self, (i32, i32), bool)>,
|
||||
alpha_source: Option<(&Self, (i32, i32))>,
|
||||
merge_alpha: bool,
|
||||
) {
|
||||
let (src_min_x, src_min_y, src_width, src_height) = src_rect;
|
||||
let (dest_min_x, dest_min_y) = dest_point;
|
||||
|
@ -581,8 +582,7 @@ impl<'gc> BitmapData<'gc> {
|
|||
|
||||
let mut dest_color = self.get_pixel_raw(dest_x as u32, dest_y as u32).unwrap();
|
||||
|
||||
if let Some((alpha_bitmap, (alpha_min_x, alpha_min_y), merge_alpha)) = alpha_source
|
||||
{
|
||||
if let Some((alpha_bitmap, (alpha_min_x, alpha_min_y))) = alpha_source {
|
||||
let alpha_x = src_x - src_min_x + alpha_min_x;
|
||||
let alpha_y = src_y - src_min_y + alpha_min_y;
|
||||
|
||||
|
@ -627,11 +627,16 @@ impl<'gc> BitmapData<'gc> {
|
|||
intermediate_color
|
||||
};
|
||||
} else {
|
||||
dest_color = if source_bitmap.transparency && !self.transparency {
|
||||
dest_color.blend_over(&source_color)
|
||||
} else {
|
||||
source_color
|
||||
};
|
||||
dest_color =
|
||||
if (source_bitmap.transparency && !self.transparency) || merge_alpha {
|
||||
dest_color.blend_over(&source_color)
|
||||
} else {
|
||||
source_color
|
||||
};
|
||||
|
||||
if !self.transparency {
|
||||
dest_color = dest_color.with_alpha(0xFF)
|
||||
}
|
||||
}
|
||||
|
||||
self.set_pixel32_raw(dest_x as u32, dest_y as u32, dest_color);
|
||||
|
|
|
@ -189,6 +189,7 @@ swf_tests! {
|
|||
(as3_astypelate, "avm2/astypelate", 1),
|
||||
(as3_bitand, "avm2/bitand", 1),
|
||||
(as3_bitmap_constr, "avm2/bitmap_constr", 1),
|
||||
(as3_bitmapdata_copypixels, "avm2/bitmapdata_copypixels", 2, img = true),
|
||||
#[ignore] (as3_bitmap_properties, "avm2/bitmap_properties", 1),
|
||||
(as3_bitmap_timeline, "avm2/bitmap_timeline", 1),
|
||||
(as3_bitmapdata_constr, "avm2/bitmapdata_constr", 1),
|
||||
|
@ -1328,6 +1329,7 @@ fn test_swf_approx(
|
|||
expected_captures.len(),
|
||||
"Differing numbers of regex captures"
|
||||
);
|
||||
|
||||
// Each capture group (other than group 0, which is always the entire regex
|
||||
// match) represents a floating-point value
|
||||
for (actual_val, expected_val) in actual_captures
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import flash.display.BitmapData;
|
||||
import flash.display.BitmapData;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.geom.Point;
|
||||
|
||||
|
||||
class BitmapCopyPixels {
|
||||
|
||||
static function plop(mc : MovieClip, sx : Number, sy : Number,
|
||||
|
@ -27,7 +28,7 @@ class BitmapCopyPixels {
|
|||
src_img._x = sx + 110;
|
||||
src_img._y = sy + 20;
|
||||
|
||||
dest.copyPixels(src, new Rectangle(0,0,80,20), new Point(10, 10));
|
||||
dest.copyPixels(src, new Rectangle(0,0,80,20), new Point(10, 10));
|
||||
|
||||
|
||||
var alpha:BitmapData = new BitmapData(40, 20, transp_alpha, 0x66884422);
|
||||
|
@ -41,7 +42,71 @@ class BitmapCopyPixels {
|
|||
dest.copyPixels(src, new Rectangle(0,0,80,20), new Point(10, 50), alpha, new Point(0,0), merge);
|
||||
}
|
||||
|
||||
static function main(mc) {
|
||||
public static function test(mc) {
|
||||
// These values are straight alpha.
|
||||
// BitmapData internally converts to premultiplied alpha,
|
||||
// and converts back to straight alpha in 'getPixel'. This results
|
||||
// in rounding, which Ruffle currently doesn't match. These values
|
||||
// were chosen to produce the same rounded result in Flash and Ruffle.
|
||||
// FIXME - determine the correct roudning behavior to use for Ruffle,
|
||||
// and test that a 'getPixel/setPixel' round-trip always agrees between
|
||||
// Flash and Ruffle.
|
||||
var target = new BitmapData(5, 5, true, 0x45112233);
|
||||
var source = new BitmapData(5, 5, true, 0x22445566);
|
||||
var otherSource = new BitmapData(5, 5, true, 0x80aabbcc);
|
||||
|
||||
target.copyPixels(source, new Rectangle(0, 0, 2, 2), new Point(0, 0), null, null, true);
|
||||
target.copyPixels(otherSource, new Rectangle(0, 0, 1, 1), new Point(4, 4), null, null, false);
|
||||
for (var py = 0; py < target.height; py++) {
|
||||
var line = "";
|
||||
for (var px = 0; px < target.height; px++) {
|
||||
line += target.getPixel32(px, py).toString(16) + " ";
|
||||
}
|
||||
trace(line);
|
||||
}
|
||||
|
||||
|
||||
var transparent = new BitmapData(1, 1, false, 0x80FFFFFF);
|
||||
var nonTransparent = new BitmapData(1, 1, false, 0x0);
|
||||
var transparentSource = new BitmapData(1, 1, true, 0xF00E0E0E);
|
||||
|
||||
trace("transparentSource: " + transparentSource.getPixel32(0, 0).toString(16));
|
||||
|
||||
trace("Non-transparent testing");
|
||||
|
||||
var nonTransparentSource = new BitmapData(1, 1, false, 0x80020406);
|
||||
trace("Original pixel: " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
trace("transparent source mergeAlpha=false " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
trace("transparent source mergeAlpha=true " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
trace("nontransparent source mergeAlpha=false " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
trace("nontransparent source mergeAlpha=true " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
trace("");
|
||||
trace("Transparent testing");
|
||||
trace("Original pixel: " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
// FIXME - enable these when Ruffle rounding is correct
|
||||
|
||||
//transparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
//trace("transparent source mergeAlpha=false " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
//transparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
//trace("transparent source mergeAlpha=true " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
transparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
trace("nontransparent source mergeAlpha=false " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
transparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
trace("nontransparent source mergeAlpha=true " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
BitmapCopyPixels.plop(mc, 10, 20, true, true, true , false);
|
||||
BitmapCopyPixels.plop(mc, 210, 20, true, true, false , false);
|
||||
BitmapCopyPixels.plop(mc, 410, 20, true, false, true , false);
|
||||
|
@ -63,4 +128,4 @@ class BitmapCopyPixels {
|
|||
BitmapCopyPixels.plop(mc, 410, 720, false, false, true , true);
|
||||
BitmapCopyPixels.plop(mc, 610, 720, false, false, false , true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -0,0 +1,17 @@
|
|||
5d243147 5d243147 45122134 45122134 45122134
|
||||
5d243147 5d243147 45122134 45122134 45122134
|
||||
45122134 45122134 45122134 45122134 45122134
|
||||
45122134 45122134 45122134 45122134 45122134
|
||||
45122134 45122134 45122134 45122134 -7f564435
|
||||
transparentSource: -ff1f1f2
|
||||
Non-transparent testing
|
||||
Original pixel: -1000000
|
||||
transparent source mergeAlpha=false -f2f2f3
|
||||
transparent source mergeAlpha=true -f2f2f3
|
||||
nontransparent source mergeAlpha=false -fdfbfa
|
||||
nontransparent source mergeAlpha=true -fdfbfa
|
||||
|
||||
Transparent testing
|
||||
Original pixel: -1
|
||||
nontransparent source mergeAlpha=false -fdfbfa
|
||||
nontransparent source mergeAlpha=true -fdfbfa
|
|
@ -0,0 +1,150 @@
|
|||
package {
|
||||
import flash.display.BitmapData;
|
||||
import flash.geom.Rectangle;
|
||||
import flash.geom.Point;
|
||||
import flash.display.Bitmap;
|
||||
import flash.display.Stage;
|
||||
|
||||
public class Test {
|
||||
public function Test(stage: Stage) {
|
||||
// These values are straight alpha.
|
||||
// BitmapData internally converts to premultiplied alpha,
|
||||
// and converts back to straight alpha in 'getPixel'. This results
|
||||
// in rounding, which Ruffle currently doesn't match. These values
|
||||
// were chosen to produce the same rounded result in Flash and Ruffle.
|
||||
// FIXME - determine the correct roudning behavior to use for Ruffle,
|
||||
// and test that a 'getPixel/setPixel' round-trip always agrees between
|
||||
// Flash and Ruffle.
|
||||
var target = new BitmapData(5, 5, true, 0x45112233);
|
||||
var source = new BitmapData(5, 5, true, 0x22445566);
|
||||
var otherSource = new BitmapData(5, 5, true, 0x80aabbcc);
|
||||
|
||||
target.copyPixels(source, new Rectangle(0, 0, 2, 2), new Point(0, 0), null, null, true);
|
||||
target.copyPixels(otherSource, new Rectangle(0, 0, 1, 1), new Point(4, 4), null, null, false);
|
||||
|
||||
printImage(target);
|
||||
|
||||
|
||||
var transparent = new BitmapData(1, 1, false, 0x80FFFFFF);
|
||||
var nonTransparent = new BitmapData(1, 1, false, 0x0);
|
||||
var transparentSource = new BitmapData(1, 1, true, 0xF00E0E0E);
|
||||
|
||||
trace("transparentSource: " + transparentSource.getPixel32(0, 0).toString(16));
|
||||
|
||||
trace("Non-transparent testing");
|
||||
|
||||
var nonTransparentSource = new BitmapData(1, 1, false, 0x80020406);
|
||||
trace("Original pixel: " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
trace("transparent source mergeAlpha=false " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
trace("transparent source mergeAlpha=true " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
trace("nontransparent source mergeAlpha=false " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
nonTransparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
trace("nontransparent source mergeAlpha=true " + nonTransparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
trace();
|
||||
trace("Transparent testing");
|
||||
trace("Original pixel: " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
// FIXME - enable these when Ruffle rounding is correct
|
||||
|
||||
//transparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
//trace("transparent source mergeAlpha=false " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
//transparent.copyPixels(transparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
//trace("transparent source mergeAlpha=true " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
transparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, false);
|
||||
trace("nontransparent source mergeAlpha=false " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
transparent.copyPixels(nonTransparentSource, new Rectangle(0, 0, 1, 1), new Point(0, 0), null, null, true);
|
||||
trace("nontransparent source mergeAlpha=true " + transparent.getPixel32(0, 0).toString(16));
|
||||
|
||||
plop(stage, 10, 20, true, true, true , false);
|
||||
plop(stage, 210, 20, true, true, false , false);
|
||||
plop(stage, 410, 20, true, false, true , false);
|
||||
plop(stage, 610, 20, true, false, false , false);
|
||||
|
||||
plop(stage, 10, 220, false, true, true , false);
|
||||
plop(stage, 210, 220, false, true, false , false);
|
||||
plop(stage, 410, 220, false, false, true , false);
|
||||
plop(stage, 610, 220, false, false, false , false);
|
||||
|
||||
|
||||
plop(stage, 10, 520, true, true, true , true);
|
||||
plop(stage, 210, 520, true, true, false , true);
|
||||
plop(stage, 410, 520, true, false, true , true);
|
||||
plop(stage, 610, 520, true, false, false , true);
|
||||
|
||||
plop(stage, 10, 720, false, true, true , true);
|
||||
plop(stage, 210, 720, false, true, false , true);
|
||||
plop(stage, 410, 720, false, false, true , true);
|
||||
plop(stage, 610, 720, false, false, false , true);
|
||||
|
||||
var weirdDest = new BitmapData(5, 5, true, 0);
|
||||
var weirdSource = new BitmapData(5, 5, false, 0x800000);
|
||||
var weirdAlphaSource = new BitmapData(5, 5, true, 0xff112233);
|
||||
weirdAlphaSource.fillRect(new Rectangle(3, 3, 2, 2), 0xaabbccdd);
|
||||
|
||||
trace("Copy with alphaPoint=undefined:");
|
||||
|
||||
// Specifying an alphaPoint of 'undefined' should use 'new Point(0, 0)''
|
||||
weirdDest.copyPixels(weirdSource, new Rectangle(0, 0, 2, 2), new Point(0, 0), weirdAlphaSource, undefined, true);
|
||||
printImage(weirdDest);
|
||||
}
|
||||
|
||||
static function printImage(target:BitmapData) {
|
||||
for (var py = 0; py < target.height; py++) {
|
||||
var line = "";
|
||||
for (var px = 0; px < target.height; px++) {
|
||||
line += target.getPixel32(px, py).toString(16) + " ";
|
||||
}
|
||||
trace(line);
|
||||
}
|
||||
}
|
||||
|
||||
static function plop(stage: Stage, sx : Number, sy : Number,
|
||||
transp_src : Boolean, transp_dest : Boolean, transp_alpha : Boolean,
|
||||
merge: Boolean) {
|
||||
|
||||
var dest:BitmapData = new BitmapData(100, 100, transp_dest, 0xBBFF0000);
|
||||
dest.fillRect(new Rectangle(20,10, 20, 80), 0x8888FF00);
|
||||
dest.fillRect(new Rectangle(50,10, 20, 80), 0x220088FF);
|
||||
|
||||
var dest_img = new Bitmap(dest);
|
||||
|
||||
dest_img.x = sx;
|
||||
dest_img.y = sy;
|
||||
|
||||
|
||||
var src:BitmapData = new BitmapData(80, 20, transp_src, 0x44888888);
|
||||
var src_img = new Bitmap(src);
|
||||
src.fillRect(new Rectangle(5, 5, 10, 10), 0xAA2288DD);
|
||||
|
||||
src_img.x = sx + 110;
|
||||
src_img.y = sy + 20;
|
||||
|
||||
dest.copyPixels(src, new Rectangle(0,0,80,20), new Point(10, 10));
|
||||
|
||||
|
||||
var alpha:BitmapData = new BitmapData(40, 20, transp_alpha, 0x66884422);
|
||||
var alpha_img = new Bitmap(alpha);
|
||||
alpha.fillRect(new Rectangle(4, 8, 12, 30), 0xEE8844DD);
|
||||
|
||||
alpha_img.x = sx + 110;
|
||||
alpha_img.y = sy + 60;
|
||||
|
||||
dest.copyPixels(src, new Rectangle(0,0,80,20), new Point(10, 50), alpha, new Point(0,0), merge);
|
||||
|
||||
stage.addChild(dest_img);
|
||||
stage.addChild(src_img);
|
||||
stage.addChild(alpha_img);
|
||||
}
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 22 KiB |
|
@ -0,0 +1,23 @@
|
|||
5d243147 5d243147 45122134 45122134 45122134
|
||||
5d243147 5d243147 45122134 45122134 45122134
|
||||
45122134 45122134 45122134 45122134 45122134
|
||||
45122134 45122134 45122134 45122134 45122134
|
||||
45122134 45122134 45122134 45122134 80a9bbcb
|
||||
transparentSource: f00e0e0e
|
||||
Non-transparent testing
|
||||
Original pixel: ff000000
|
||||
transparent source mergeAlpha=false ff0d0d0d
|
||||
transparent source mergeAlpha=true ff0d0d0d
|
||||
nontransparent source mergeAlpha=false ff020406
|
||||
nontransparent source mergeAlpha=true ff020406
|
||||
|
||||
Transparent testing
|
||||
Original pixel: ffffffff
|
||||
nontransparent source mergeAlpha=false ff020406
|
||||
nontransparent source mergeAlpha=true ff020406
|
||||
Copy with alphaPoint=undefined:
|
||||
ff800000 ff800000 0 0 0
|
||||
ff800000 ff800000 0 0 0
|
||||
0 0 0 0 0
|
||||
0 0 0 0 0
|
||||
0 0 0 0 0
|