avm2: Impl `BitmapData.getPixel`.

This also changes the `bitmapdata_constr` test slightly to use a different starting value. Our premultiplied alpha calculations generate slightly different values from Flash Player which trips the test.
This commit is contained in:
David Wendt 2021-09-05 18:47:17 -04:00 committed by Mike Welsh
parent 4c9bd0a6fe
commit 7c5dc568f1
4 changed files with 32 additions and 8 deletions

View File

@ -121,7 +121,7 @@ pub fn class_init<'gc>(
Ok(Value::Undefined) Ok(Value::Undefined)
} }
/// Implements BitmapData.width`'s getter. /// Implements `BitmapData.width`'s getter.
pub fn width<'gc>( pub fn width<'gc>(
_activation: &mut Activation<'_, 'gc, '_>, _activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>, this: Option<Object<'gc>>,
@ -134,7 +134,7 @@ pub fn width<'gc>(
Ok(Value::Undefined) Ok(Value::Undefined)
} }
/// Implements BitmapData.height`'s getter. /// Implements `BitmapData.height`'s getter.
pub fn height<'gc>( pub fn height<'gc>(
_activation: &mut Activation<'_, 'gc, '_>, _activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>, this: Option<Object<'gc>>,
@ -147,7 +147,7 @@ pub fn height<'gc>(
Ok(Value::Undefined) Ok(Value::Undefined)
} }
/// Implements BitmapData.transparent`'s getter. /// Implements `BitmapData.transparent`'s getter.
pub fn transparent<'gc>( pub fn transparent<'gc>(
_activation: &mut Activation<'_, 'gc, '_>, _activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>, this: Option<Object<'gc>>,
@ -160,6 +160,27 @@ pub fn transparent<'gc>(
Ok(Value::Undefined) Ok(Value::Undefined)
} }
/// Implements `BitmapData.getPixel`.
pub fn get_pixel<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
if let Some(bitmap_data) = this.and_then(|t| t.as_bitmap_data()) {
let x = args
.get(0)
.unwrap_or(&Value::Undefined)
.coerce_to_i32(activation)?;
let y = args
.get(1)
.unwrap_or(&Value::Undefined)
.coerce_to_i32(activation)?;
return Ok((bitmap_data.read().get_pixel(x, y) as u32).into());
}
Ok(Value::Undefined)
}
/// Construct `BitmapData`'s class. /// Construct `BitmapData`'s class.
pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> { pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>> {
let class = Class::new( let class = Class::new(
@ -186,5 +207,8 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
]; ];
write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES); write.define_public_builtin_instance_properties(mc, PUBLIC_INSTANCE_PROPERTIES);
const PUBLIC_INSTANCE_METHODS: &[(&str, NativeMethodImpl)] = &[("getPixel", get_pixel)];
write.define_public_builtin_instance_methods(mc, PUBLIC_INSTANCE_METHODS);
class class
} }

View File

@ -1,12 +1,12 @@
package { package {
public class Test { public class Test {
} }
} }
import flash.display.BitmapData; import flash.display.BitmapData;
trace("///var bd = new BitmapData(128, 128, true, 0xCAFEBABE);"); trace("///var bd = new BitmapData(128, 128, true, 0x88FEBABE);");
var bd = new BitmapData(128, 128, true, 0xCAFEBABE); var bd = new BitmapData(128, 128, true, 0x88FEBABE);
trace("///bd.width;"); trace("///bd.width;");
trace(bd.width); trace(bd.width);

View File

@ -1,4 +1,4 @@
///var bd = new BitmapData(128, 128, true, 0xCAFEBABE); ///var bd = new BitmapData(128, 128, true, 0x88FEBABE);
///bd.width; ///bd.width;
128 128
///bd.height; ///bd.height;
@ -6,7 +6,7 @@
///bd.transparent; ///bd.transparent;
true true
///bd.getPixel(0,0); ///bd.getPixel(0,0);
16693695 16628413
///bd = new BitmapData(128, 128, false, 0xCAFEBABE); ///bd = new BitmapData(128, 128, false, 0xCAFEBABE);
///bd.width; ///bd.width;
128 128