avm1: Added BitmapData::compare
This commit is contained in:
parent
3760e0e275
commit
687069ba7d
|
@ -40,6 +40,7 @@ const PROTO_DECLS: &[Declaration] = declare_properties! {
|
|||
"pixelDissolve" => method(pixel_dissolve);
|
||||
"scroll" => method(scroll);
|
||||
"threshold" => method(threshold);
|
||||
"compare" => method(compare);
|
||||
};
|
||||
|
||||
const OBJECT_DECLS: &[Declaration] = declare_properties! {
|
||||
|
@ -1063,6 +1064,69 @@ pub fn threshold<'gc>(
|
|||
Ok((-1).into())
|
||||
}
|
||||
|
||||
pub fn compare<'gc>(
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(bitmap_data) = this.as_bitmap_data_object() {
|
||||
if bitmap_data.disposed() {
|
||||
return Ok((-2).into());
|
||||
}
|
||||
|
||||
let other_bitmap = args
|
||||
.get(0)
|
||||
.unwrap_or(&Value::Undefined)
|
||||
.coerce_to_object(activation);
|
||||
|
||||
if let Some(other_bitmap_data) = other_bitmap.as_bitmap_data_object() {
|
||||
if other_bitmap_data.disposed() {
|
||||
return Ok((-2).into());
|
||||
}
|
||||
|
||||
if bitmap_data.bitmap_data().read().width()
|
||||
!= other_bitmap_data.bitmap_data().read().width()
|
||||
{
|
||||
return Ok((-3).into());
|
||||
}
|
||||
if bitmap_data.bitmap_data().read().height()
|
||||
!= other_bitmap_data.bitmap_data().read().height()
|
||||
{
|
||||
return Ok((-4).into());
|
||||
}
|
||||
if bitmap_data
|
||||
.bitmap_data()
|
||||
.read()
|
||||
.pixels()
|
||||
.eq(other_bitmap_data.bitmap_data().read().pixels())
|
||||
{
|
||||
return Ok((0).into());
|
||||
}
|
||||
|
||||
let new_bitmap_data = BitmapDataObject::empty_object(
|
||||
activation.context.gc_context,
|
||||
Some(activation.context.avm1.prototypes.bitmap_data),
|
||||
);
|
||||
|
||||
new_bitmap_data
|
||||
.as_bitmap_data_object()
|
||||
.unwrap()
|
||||
.bitmap_data()
|
||||
.write(activation.context.gc_context)
|
||||
.compare(
|
||||
&bitmap_data.bitmap_data().read(),
|
||||
&other_bitmap_data.bitmap_data().read(),
|
||||
);
|
||||
|
||||
return Ok(new_bitmap_data.into());
|
||||
}
|
||||
|
||||
return Ok(Value::Undefined);
|
||||
}
|
||||
|
||||
Ok((-1).into())
|
||||
}
|
||||
|
||||
pub fn create_proto<'gc>(
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
proto: Object<'gc>,
|
||||
|
|
|
@ -854,6 +854,35 @@ impl<'gc> BitmapData<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn compare(&mut self, bitmap: &Self, other: &Self) {
|
||||
// Should be replaced with i32::abs_diff once stabilized (https://github.com/rust-lang/rust/issues/89492)
|
||||
fn abs_diff(a: i32, b: i32) -> i32 {
|
||||
if a > b {
|
||||
a.wrapping_sub(b)
|
||||
} else {
|
||||
b.wrapping_sub(a)
|
||||
}
|
||||
}
|
||||
|
||||
for i in 0..self.pixels().len() {
|
||||
let bitmap_pixel = bitmap.pixels()[i];
|
||||
let other_pixel = other.pixels()[i];
|
||||
self.pixels[i] = Color(
|
||||
if bitmap_pixel.with_alpha(0xffu8) != other_pixel.with_alpha(0xffu8) {
|
||||
(0xff << 24)
|
||||
+ (abs_diff(bitmap_pixel.red() as i32, other_pixel.red() as i32) << 16)
|
||||
+ (abs_diff(bitmap_pixel.green() as i32, other_pixel.green() as i32) << 8)
|
||||
+ abs_diff(bitmap_pixel.blue() as i32, other_pixel.blue() as i32)
|
||||
} else if bitmap_pixel.alpha() != other_pixel.alpha() {
|
||||
(abs_diff(bitmap_pixel.alpha() as i32, other_pixel.alpha() as i32) << 24)
|
||||
+ 0xffffff
|
||||
} else {
|
||||
0
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object2(&self) -> Avm2Value<'gc> {
|
||||
self.avm2_object
|
||||
.map(|o| o.into())
|
||||
|
|
Loading…
Reference in New Issue