core+web+renderer: Add load/attach Bitmap and handling for invalid args with BitmapData
This commit is contained in:
parent
3c12fa6ee5
commit
9d46d67588
|
@ -5,10 +5,11 @@ use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::object::bitmap_data::BitmapDataObject;
|
use crate::avm1::object::bitmap_data::BitmapDataObject;
|
||||||
use crate::avm1::{Object, TObject, Value};
|
use crate::avm1::{Object, TObject, Value};
|
||||||
|
use crate::character::Character;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
use rand::Rng;
|
||||||
|
use swf::CharacterId;
|
||||||
|
|
||||||
pub fn constructor<'gc>(
|
pub fn constructor<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
@ -27,6 +28,8 @@ pub fn constructor<'gc>(
|
||||||
.unwrap_or(&Value::Number(0.0))
|
.unwrap_or(&Value::Number(0.0))
|
||||||
.coerce_to_u32(activation)?;
|
.coerce_to_u32(activation)?;
|
||||||
|
|
||||||
|
log::warn!("New bitmap data {}x{}", width, height);
|
||||||
|
|
||||||
if width > 2880 || height > 2880 || width <= 0 || height <= 0 {
|
if width > 2880 || height > 2880 || width <= 0 || height <= 0 {
|
||||||
log::warn!("Invalid BitmapData size {}x{}", width, height);
|
log::warn!("Invalid BitmapData size {}x{}", width, height);
|
||||||
return Ok(Value::Undefined);
|
return Ok(Value::Undefined);
|
||||||
|
@ -37,10 +40,11 @@ pub fn constructor<'gc>(
|
||||||
.unwrap_or(&Value::Bool(true))
|
.unwrap_or(&Value::Bool(true))
|
||||||
.as_bool(activation.current_swf_version());
|
.as_bool(activation.current_swf_version());
|
||||||
|
|
||||||
//Hmm can't write this in hex
|
|
||||||
// 0xFFFFFFFF as f64;
|
|
||||||
let fill_color = args
|
let fill_color = args
|
||||||
.get(3)
|
.get(3)
|
||||||
|
// can't write this in hex
|
||||||
|
// 0xFFFFFFFF as f64;
|
||||||
.unwrap_or(&Value::Number(4294967295_f64))
|
.unwrap_or(&Value::Number(4294967295_f64))
|
||||||
.coerce_to_i32(activation)?;
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
|
@ -51,33 +55,6 @@ pub fn constructor<'gc>(
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_bitmap<'gc>(
|
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
|
||||||
_this: Object<'gc>,
|
|
||||||
args: &[Value<'gc>],
|
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
|
||||||
//TODO: how does this handle no args
|
|
||||||
let name = args
|
|
||||||
.get(0)
|
|
||||||
.unwrap_or(&Value::Undefined)
|
|
||||||
.coerce_to_string(activation)?;
|
|
||||||
|
|
||||||
log::warn!("BitmapData.loadBitmap({:?}), not impl", name);
|
|
||||||
|
|
||||||
//TODO: correct method here? also rename
|
|
||||||
let mc = activation.context.swf;
|
|
||||||
|
|
||||||
//TODO: unwrap
|
|
||||||
// activation.context.library.library_for_movie(mc.clone()).expect("Unable to get library for movie").instantiate_by_export_name(name.as_str(), activation.context.gc_context).expect("Unable to instantiate");
|
|
||||||
|
|
||||||
//TODO: write tests for props on the return val of this, for now we will just stub
|
|
||||||
|
|
||||||
let proto = activation.context.system_prototypes.bitmap_data_constructor;
|
|
||||||
let new_bitmap = proto.construct(activation, &[])?;
|
|
||||||
|
|
||||||
Ok(new_bitmap.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_height<'gc>(
|
pub fn get_height<'gc>(
|
||||||
_activation: &mut Activation<'_, 'gc, '_>,
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
|
@ -86,7 +63,7 @@ pub fn get_height<'gc>(
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
if bitmap_data.get_disposed() {
|
if bitmap_data.get_disposed() {
|
||||||
return Ok((-1).into())
|
return Ok((-1).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(this.as_bitmap_data_object().unwrap().get_height().into())
|
Ok(this.as_bitmap_data_object().unwrap().get_height().into())
|
||||||
|
@ -100,7 +77,7 @@ pub fn get_width<'gc>(
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
if bitmap_data.get_disposed() {
|
if bitmap_data.get_disposed() {
|
||||||
return Ok((-1).into())
|
return Ok((-1).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(this.as_bitmap_data_object().unwrap().get_width().into())
|
Ok(this.as_bitmap_data_object().unwrap().get_width().into())
|
||||||
|
@ -114,7 +91,7 @@ pub fn get_transparent<'gc>(
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
if bitmap_data.get_disposed() {
|
if bitmap_data.get_disposed() {
|
||||||
return Ok((-1).into())
|
return Ok((-1).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(this
|
Ok(this
|
||||||
|
@ -132,7 +109,7 @@ pub fn get_rectangle<'gc>(
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
if bitmap_data.get_disposed() {
|
if bitmap_data.get_disposed() {
|
||||||
return Ok((-1).into())
|
return Ok((-1).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let proto = activation.context.system_prototypes.rectangle_constructor;
|
let proto = activation.context.system_prototypes.rectangle_constructor;
|
||||||
|
@ -156,15 +133,11 @@ pub fn get_pixel<'gc>(
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
if bitmap_data.get_disposed() {
|
if bitmap_data.get_disposed() {
|
||||||
return Ok((-1).into())
|
return Ok((-1).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let x = args
|
let x = args.get(0).and_then(|x| x.coerce_to_i32(activation).ok());
|
||||||
.get(0)
|
let y = args.get(1).and_then(|x| x.coerce_to_i32(activation).ok());
|
||||||
.and_then(|x| x.coerce_to_i32(activation).ok());
|
|
||||||
let y = args
|
|
||||||
.get(1)
|
|
||||||
.and_then(|x| x.coerce_to_i32(activation).ok());
|
|
||||||
|
|
||||||
if let Some((x, y)) = x.zip(y) {
|
if let Some((x, y)) = x.zip(y) {
|
||||||
Ok(bitmap_data.get_pixel(x, y).into())
|
Ok(bitmap_data.get_pixel(x, y).into())
|
||||||
|
@ -173,82 +146,74 @@ pub fn get_pixel<'gc>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: out of bounds / missing args / neg args
|
|
||||||
pub fn set_pixel<'gc>(
|
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
|
||||||
this: Object<'gc>,
|
|
||||||
args: &[Value<'gc>],
|
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
|
||||||
let x = args
|
|
||||||
.get(0)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_u32(activation)?;
|
|
||||||
|
|
||||||
let y = args
|
|
||||||
.get(1)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_u32(activation)?;
|
|
||||||
|
|
||||||
let color = args
|
|
||||||
.get(2)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_i32(activation)?;
|
|
||||||
|
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
|
||||||
bitmap_data.set_pixel(activation.context.gc_context, x, y, color.into());
|
|
||||||
|
|
||||||
Ok(Value::Undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: out of bounds / missing args / neg args
|
|
||||||
pub fn set_pixel32<'gc>(
|
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
|
||||||
this: Object<'gc>,
|
|
||||||
args: &[Value<'gc>],
|
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
|
||||||
let x = args
|
|
||||||
.get(0)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_u32(activation)?;
|
|
||||||
|
|
||||||
let y = args
|
|
||||||
.get(1)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_u32(activation)?;
|
|
||||||
|
|
||||||
let color = args
|
|
||||||
.get(2)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_i32(activation)?;
|
|
||||||
|
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
|
||||||
bitmap_data.set_pixel32(activation.context.gc_context, x, y, color.into());
|
|
||||||
|
|
||||||
Ok(Value::Undefined)
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: out of bounds / missing args / neg args
|
|
||||||
pub fn get_pixel32<'gc>(
|
pub fn get_pixel32<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let x = args
|
|
||||||
.get(0)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_u32(activation)?;
|
|
||||||
|
|
||||||
let y = args
|
|
||||||
.get(1)
|
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
|
||||||
.coerce_to_u32(activation)?;
|
|
||||||
|
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
//TODO: move this unwrap to the object
|
|
||||||
|
|
||||||
let x: i32 = bitmap_data.get_pixel32(x, y).unwrap_or(0.into()).into();
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(x.into())
|
let x = args.get(0).and_then(|x| x.coerce_to_i32(activation).ok());
|
||||||
|
let y = args.get(1).and_then(|x| x.coerce_to_i32(activation).ok());
|
||||||
|
|
||||||
|
if let Some((x, y)) = x.zip(y) {
|
||||||
|
let asdf: i32 = bitmap_data.get_pixel32(x, y).into();
|
||||||
|
Ok(asdf.into())
|
||||||
|
} else {
|
||||||
|
Ok((-1).into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pixel<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = args.get(0).and_then(|v| v.coerce_to_u32(activation).ok());
|
||||||
|
|
||||||
|
let y = args.get(1).and_then(|v| v.coerce_to_u32(activation).ok());
|
||||||
|
|
||||||
|
let color = args.get(2).and_then(|v| v.coerce_to_i32(activation).ok());
|
||||||
|
|
||||||
|
if let Some(((x, y), color)) = x.zip(y).zip(color) {
|
||||||
|
bitmap_data.set_pixel(activation.context.gc_context, x, y, color.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pixel32<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let x = args.get(0).and_then(|v| v.coerce_to_i32(activation).ok());
|
||||||
|
|
||||||
|
let y = args.get(1).and_then(|v| v.coerce_to_i32(activation).ok());
|
||||||
|
|
||||||
|
let color = args.get(2).and_then(|v| v.coerce_to_i32(activation).ok());
|
||||||
|
|
||||||
|
if let Some(((x, y), color)) = x.zip(y).zip(color) {
|
||||||
|
bitmap_data.set_pixel32(activation.context.gc_context, x, y, color.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: missing args / out of bounds
|
//TODO: missing args / out of bounds
|
||||||
|
@ -257,6 +222,13 @@ pub fn copy_channel<'gc>(
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("copy channel not fully implemented");
|
||||||
let source_bitmap = args
|
let source_bitmap = args
|
||||||
.get(0)
|
.get(0)
|
||||||
.unwrap_or(&Value::Undefined)
|
.unwrap_or(&Value::Undefined)
|
||||||
|
@ -286,7 +258,6 @@ pub fn copy_channel<'gc>(
|
||||||
.coerce_to_i32(activation)?;
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
if let Some(source_bitmap) = source_bitmap.as_bitmap_data_object() {
|
if let Some(source_bitmap) = source_bitmap.as_bitmap_data_object() {
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
|
||||||
bitmap_data.copy_channel(
|
bitmap_data.copy_channel(
|
||||||
activation.context.gc_context,
|
activation.context.gc_context,
|
||||||
source_bitmap,
|
source_bitmap,
|
||||||
|
@ -298,7 +269,6 @@ pub fn copy_channel<'gc>(
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: missing args / out of bounds
|
|
||||||
pub fn fill_rect<'gc>(
|
pub fn fill_rect<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
|
@ -306,17 +276,12 @@ pub fn fill_rect<'gc>(
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let rectangle = args
|
let rectangle = args
|
||||||
.get(0)
|
.get(0)
|
||||||
//TODO:
|
.unwrap_or(&Value::Undefined)
|
||||||
.unwrap()
|
|
||||||
.coerce_to_object(activation);
|
.coerce_to_object(activation);
|
||||||
|
|
||||||
let color = args
|
let color = args.get(1).and_then(|v| v.coerce_to_i32(activation).ok());
|
||||||
.get(1)
|
|
||||||
//TODO:
|
|
||||||
.unwrap()
|
|
||||||
.coerce_to_i32(activation)?;
|
|
||||||
|
|
||||||
//TODO: does this only work on actual rectangles or does it work on anything with x/y/w/h
|
if let Some(color) = color {
|
||||||
let x = rectangle.get("x", activation)?.coerce_to_u32(activation)?;
|
let x = rectangle.get("x", activation)?.coerce_to_u32(activation)?;
|
||||||
let y = rectangle.get("y", activation)?.coerce_to_u32(activation)?;
|
let y = rectangle.get("y", activation)?.coerce_to_u32(activation)?;
|
||||||
let width = rectangle
|
let width = rectangle
|
||||||
|
@ -335,6 +300,7 @@ pub fn fill_rect<'gc>(
|
||||||
height,
|
height,
|
||||||
color.into(),
|
color.into(),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
@ -342,9 +308,13 @@ pub fn fill_rect<'gc>(
|
||||||
pub fn clone<'gc>(
|
pub fn clone<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
if let Some(bitmap_data) = this.as_bitmap_data_object() {
|
if let Some(bitmap_data) = this.as_bitmap_data_object() {
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
let proto = activation.context.system_prototypes.bitmap_data_constructor;
|
let proto = activation.context.system_prototypes.bitmap_data_constructor;
|
||||||
let new_bitmap_data = proto.construct(
|
let new_bitmap_data = proto.construct(
|
||||||
activation,
|
activation,
|
||||||
|
@ -368,18 +338,30 @@ pub fn clone<'gc>(
|
||||||
pub fn dispose<'gc>(
|
pub fn dispose<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
bitmap_data.dispose(activation.context.gc_context);
|
bitmap_data.dispose(activation.context.gc_context);
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: bad args
|
||||||
pub fn flood_fill<'gc>(
|
pub fn flood_fill<'gc>(
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
this: Object<'gc>,
|
this: Object<'gc>,
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
) -> Result<Value<'gc>, Error<'gc>> {
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
let x = args
|
let x = args
|
||||||
.get(0)
|
.get(0)
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
.unwrap_or(&Value::Number(0_f64))
|
||||||
|
@ -395,11 +377,356 @@ pub fn flood_fill<'gc>(
|
||||||
.unwrap_or(&Value::Number(0_f64))
|
.unwrap_or(&Value::Number(0_f64))
|
||||||
.coerce_to_i32(activation)?;
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
|
||||||
bitmap_data.flood_fill(activation.context.gc_context, x, y, color.into());
|
bitmap_data.flood_fill(activation.context.gc_context, x, y, color.into());
|
||||||
Ok(Value::Undefined)
|
Ok(Value::Undefined)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: bad args
|
||||||
|
pub fn noise<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("noise not implemented");
|
||||||
|
//todo: default
|
||||||
|
let random_seed = args
|
||||||
|
.get(0)
|
||||||
|
.unwrap_or(&Value::Number(0.0))
|
||||||
|
.coerce_to_u32(activation)?;
|
||||||
|
|
||||||
|
// 0 - 255
|
||||||
|
let low = args
|
||||||
|
.get(1)
|
||||||
|
.unwrap_or(&Value::Number(0.0))
|
||||||
|
.coerce_to_u32(activation)?;
|
||||||
|
|
||||||
|
// 0 - 255
|
||||||
|
let height = args
|
||||||
|
.get(2)
|
||||||
|
.unwrap_or(&Value::Number(255.0))
|
||||||
|
.coerce_to_u32(activation)?;
|
||||||
|
|
||||||
|
// what is the range here
|
||||||
|
let channel_options = args
|
||||||
|
.get(3)
|
||||||
|
.unwrap_or(&Value::Number((1 | 2 | 4) as f64))
|
||||||
|
.coerce_to_u32(activation)?;
|
||||||
|
|
||||||
|
// 0 - 255
|
||||||
|
let gray_scale = args
|
||||||
|
.get(4)
|
||||||
|
.unwrap_or(&Value::Bool(false))
|
||||||
|
.as_bool(activation.current_swf_version());
|
||||||
|
|
||||||
|
|
||||||
|
let width = bitmap_data.get_width();
|
||||||
|
let height = bitmap_data.get_height();
|
||||||
|
for x in 0..width {
|
||||||
|
for y in 0..height {
|
||||||
|
let pixel_color = activation.context.rng.gen_range(low, height);
|
||||||
|
bitmap_data.set_pixel32_raw(
|
||||||
|
activation.context.gc_context,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
(pixel_color as i32).into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap_data.dispose(activation.context.gc_context);
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_filter<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
_this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
log::warn!("BitmapData.applyFilter - not yet implemented");
|
||||||
|
Ok((-1).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO:
|
||||||
|
pub fn draw<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let swf_movie = _activation.context.swf.clone();
|
||||||
|
let character = _activation
|
||||||
|
.context
|
||||||
|
.library
|
||||||
|
.library_for_movie(swf_movie)
|
||||||
|
.unwrap()
|
||||||
|
.get_character_by_id(191 as CharacterId);
|
||||||
|
log::warn!("draw character {:?}", character);
|
||||||
|
|
||||||
|
log::warn!("BitmapData.draw - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn generate_filter_rect<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.generateFilterRect - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: args tests
|
||||||
|
pub fn color_transform<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let rectangle = args
|
||||||
|
.get(0)
|
||||||
|
.unwrap_or(&Value::Undefined)
|
||||||
|
.coerce_to_object(activation);
|
||||||
|
|
||||||
|
let color_transform = args
|
||||||
|
.get(1)
|
||||||
|
.unwrap_or(&Value::Undefined)
|
||||||
|
.coerce_to_object(activation);
|
||||||
|
|
||||||
|
//TODO: does this only work on actual rectangles or does it work on anything with x/y/w/h
|
||||||
|
let x = rectangle.get("x", activation)?.coerce_to_u32(activation)?;
|
||||||
|
let y = rectangle.get("y", activation)?.coerce_to_u32(activation)?;
|
||||||
|
let width = rectangle
|
||||||
|
.get("width", activation)?
|
||||||
|
.coerce_to_u32(activation)?;
|
||||||
|
let height = rectangle
|
||||||
|
.get("height", activation)?
|
||||||
|
.coerce_to_u32(activation)?;
|
||||||
|
|
||||||
|
//TODO: does this only work on actual cts or does it work on anything with x/y/w/h
|
||||||
|
let red_multiplier = color_transform
|
||||||
|
.get("redMultiplier", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32;
|
||||||
|
let green_multiplier = color_transform
|
||||||
|
.get("greenMultiplier", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32;
|
||||||
|
let blue_multiplier = color_transform
|
||||||
|
.get("blueMultiplier", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32;
|
||||||
|
let alpha_multiplier = color_transform
|
||||||
|
.get("alphaMultiplier", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32;
|
||||||
|
let red_offset = color_transform
|
||||||
|
.get("redOffset", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32
|
||||||
|
/ 255.0;
|
||||||
|
let green_offset = color_transform
|
||||||
|
.get("greenOffset", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32
|
||||||
|
/ 255.0;
|
||||||
|
let blue_offset = color_transform
|
||||||
|
.get("blueOffset", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32
|
||||||
|
/ 255.0;
|
||||||
|
let alpha_offset = color_transform
|
||||||
|
.get("alphaOffset", activation)?
|
||||||
|
.coerce_to_f64(activation)? as f32
|
||||||
|
/ 255.0;
|
||||||
|
|
||||||
|
bitmap_data.color_transform(
|
||||||
|
activation.context.gc_context,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
x + width,
|
||||||
|
y + height,
|
||||||
|
alpha_multiplier,
|
||||||
|
alpha_offset,
|
||||||
|
red_multiplier,
|
||||||
|
red_offset,
|
||||||
|
green_multiplier,
|
||||||
|
green_offset,
|
||||||
|
blue_multiplier,
|
||||||
|
blue_offset,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: args tests
|
||||||
|
pub fn get_color_bounds_rect<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mask = args
|
||||||
|
.get(0)
|
||||||
|
.unwrap_or(&Value::Undefined)
|
||||||
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
|
let color = args
|
||||||
|
.get(1)
|
||||||
|
.unwrap_or(&Value::Undefined)
|
||||||
|
.coerce_to_i32(activation)?;
|
||||||
|
|
||||||
|
let find_color = args
|
||||||
|
.get(2)
|
||||||
|
.unwrap_or(&Value::Bool(true))
|
||||||
|
.as_bool(activation.current_swf_version());
|
||||||
|
|
||||||
|
let (x, y, w, h) = bitmap_data.get_color_bounds_rect(mask, color, find_color);
|
||||||
|
|
||||||
|
let proto = activation.context.system_prototypes.rectangle_constructor;
|
||||||
|
let rect = proto.construct(activation, &[x.into(), y.into(), w.into(), h.into()])?;
|
||||||
|
Ok(rect.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn perlin_noise<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.perlinNoise - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn hit_test<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.hitTest - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_pixels<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.copyPixels - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn merge<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.merge - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn palette_map<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.paletteMap - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pixel_dissolve<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.pixelDissolve - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scroll<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.scroll - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
pub fn threshold<'gc>(
|
||||||
|
_activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
this: Object<'gc>,
|
||||||
|
_args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let bitmap_data = this.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
if bitmap_data.get_disposed() {
|
||||||
|
return Ok((-1).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
log::warn!("BitmapData.threshold - not yet implemented");
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn create_proto<'gc>(
|
pub fn create_proto<'gc>(
|
||||||
gc_context: MutationContext<'gc, '_>,
|
gc_context: MutationContext<'gc, '_>,
|
||||||
proto: Object<'gc>,
|
proto: Object<'gc>,
|
||||||
|
@ -503,14 +830,156 @@ pub fn create_proto<'gc>(
|
||||||
Some(fn_proto),
|
Some(fn_proto),
|
||||||
);
|
);
|
||||||
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
|
object.force_set_function("clone", clone, gc_context, EnumSet::empty(), Some(fn_proto));
|
||||||
object.force_set_function("dispose", dispose, gc_context, EnumSet::empty(), Some(fn_proto));
|
object.force_set_function(
|
||||||
object.force_set_function("floodFill", flood_fill, gc_context, EnumSet::empty(), Some(fn_proto));
|
"dispose",
|
||||||
|
dispose,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"floodFill",
|
||||||
|
flood_fill,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function("noise", noise, gc_context, EnumSet::empty(), Some(fn_proto));
|
||||||
|
object.force_set_function(
|
||||||
|
"colorTransform",
|
||||||
|
color_transform,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"getColorBoundsRect",
|
||||||
|
get_color_bounds_rect,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"perlinNoise",
|
||||||
|
perlin_noise,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"applyFilter",
|
||||||
|
apply_filter,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function("draw", draw, gc_context, EnumSet::empty(), Some(fn_proto));
|
||||||
|
object.force_set_function(
|
||||||
|
"hitTest",
|
||||||
|
hit_test,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"generateFilterRect",
|
||||||
|
generate_filter_rect,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"copyPixels",
|
||||||
|
copy_pixels,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"merge",
|
||||||
|
merge,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"paletteMap",
|
||||||
|
palette_map,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"pixelDissolve",
|
||||||
|
pixel_dissolve,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"scroll",
|
||||||
|
scroll,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
object.force_set_function(
|
||||||
|
"threshold",
|
||||||
|
threshold,
|
||||||
|
gc_context,
|
||||||
|
EnumSet::empty(),
|
||||||
|
Some(fn_proto),
|
||||||
|
);
|
||||||
|
|
||||||
bitmap_data_object.into()
|
bitmap_data_object.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo
|
||||||
|
use crate::display_object::TDisplayObject;
|
||||||
|
|
||||||
|
pub fn load_bitmap<'gc>(
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
_this: Object<'gc>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
let name = args
|
||||||
|
.get(0)
|
||||||
|
.unwrap_or(&Value::Undefined)
|
||||||
|
.coerce_to_string(activation)?;
|
||||||
|
|
||||||
|
log::warn!("BitmapData.loadBitmap({:?}), not yet implemented", name);
|
||||||
|
|
||||||
|
let swf = activation.target_clip_or_root().movie().expect("No movie ?");
|
||||||
|
|
||||||
|
let bh = activation
|
||||||
|
.context
|
||||||
|
.library
|
||||||
|
.library_for_movie(swf)
|
||||||
|
.expect("No library for movie")
|
||||||
|
.get_character_by_export_name(name.as_str())
|
||||||
|
.expect("No character for name");
|
||||||
|
|
||||||
|
let bitmap = match bh {
|
||||||
|
Character::Bitmap(b) => b.bitmap_handle(),
|
||||||
|
_ => unimplemented!(),
|
||||||
|
};
|
||||||
|
//TODO: also return bounds?
|
||||||
|
let (w, h, pixels) = activation.context.renderer.get_bitmap_pixels(bitmap);
|
||||||
|
log::warn!("Got response {} {} {:?}", w, h, pixels);
|
||||||
|
|
||||||
|
let proto = activation.context.system_prototypes.bitmap_data_constructor;
|
||||||
|
let new_bitmap = proto.construct(activation, &[w.into(), h.into()])?;
|
||||||
|
let new_bitmap_object = new_bitmap.as_bitmap_data_object().unwrap();
|
||||||
|
|
||||||
|
//todo: set w/h
|
||||||
|
new_bitmap_object.set_pixels(
|
||||||
|
activation.context.gc_context,
|
||||||
|
pixels.iter().map(|p| (*p as i32).into()).collect(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(new_bitmap.into())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_bitmap_data_object<'gc>(
|
pub fn create_bitmap_data_object<'gc>(
|
||||||
gc_context: MutationContext<'gc, '_>,
|
gc_context: MutationContext<'gc, '_>,
|
||||||
bitmap_data_proto: Object<'gc>,
|
bitmap_data_proto: Object<'gc>,
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::avm_error;
|
||||||
use crate::avm_warn;
|
use crate::avm_warn;
|
||||||
use crate::backend::navigator::NavigationMethod;
|
use crate::backend::navigator::NavigationMethod;
|
||||||
use crate::display_object::{
|
use crate::display_object::{
|
||||||
DisplayObject, EditText, MovieClip, TDisplayObject, TDisplayObjectContainer,
|
DisplayObject, EditText, MovieClip, TDisplayObject, TDisplayObjectContainer, Bitmap
|
||||||
};
|
};
|
||||||
use crate::ecma_conversions::f64_to_wrapping_i32;
|
use crate::ecma_conversions::f64_to_wrapping_i32;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -204,7 +204,8 @@ pub fn create_proto<'gc>(
|
||||||
"curveTo" => curve_to,
|
"curveTo" => curve_to,
|
||||||
"endFill" => end_fill,
|
"endFill" => end_fill,
|
||||||
"lineStyle" => line_style,
|
"lineStyle" => line_style,
|
||||||
"clear" => clear
|
"clear" => clear,
|
||||||
|
"attachBitmap" => attach_bitmap
|
||||||
);
|
);
|
||||||
|
|
||||||
with_movie_clip_props!(
|
with_movie_clip_props!(
|
||||||
|
@ -218,6 +219,32 @@ pub fn create_proto<'gc>(
|
||||||
object.into()
|
object.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn attach_bitmap<'gc>(
|
||||||
|
mut movie_clip: MovieClip<'gc>,
|
||||||
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
args: &[Value<'gc>],
|
||||||
|
) -> Result<Value<'gc>, Error<'gc>> {
|
||||||
|
|
||||||
|
if let Some(bitmap) = args.get(0) {
|
||||||
|
if let Some(bitmap_data) = bitmap.coerce_to_object(activation).as_bitmap_data_object() {
|
||||||
|
if let Some(depth) = args.get(1) {
|
||||||
|
|
||||||
|
let depth = depth
|
||||||
|
.coerce_to_i32(activation)?
|
||||||
|
.wrapping_add(AVM_DEPTH_BIAS);
|
||||||
|
|
||||||
|
let rgba = bitmap_data.get_pixels_rgba();
|
||||||
|
let bitmap_handle = activation.context.renderer.register_bitmap_raw(bitmap_data.get_width(), bitmap_data.get_height(), rgba);
|
||||||
|
//TODO: casting
|
||||||
|
let display_object = Bitmap::new(&mut activation.context, 0, bitmap_handle, bitmap_data.get_width() as u16, bitmap_data.get_height() as u16);
|
||||||
|
movie_clip.replace_at_depth(&mut activation.context, display_object.into(), depth.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Undefined)
|
||||||
|
}
|
||||||
|
|
||||||
fn line_style<'gc>(
|
fn line_style<'gc>(
|
||||||
movie_clip: MovieClip<'gc>,
|
movie_clip: MovieClip<'gc>,
|
||||||
activation: &mut Activation<'_, 'gc, '_>,
|
activation: &mut Activation<'_, 'gc, '_>,
|
||||||
|
|
|
@ -114,9 +114,7 @@ impl fmt::Debug for BitmapDataObject<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> BitmapDataObject<'gc> {
|
impl<'gc> BitmapDataObject<'gc> {
|
||||||
add_field_accessors!(
|
add_field_accessors!([set_transparency, get_transparency, transparency, bool],);
|
||||||
[set_transparency, get_transparency, transparency, bool],
|
|
||||||
);
|
|
||||||
|
|
||||||
pub fn empty_object(gc_context: MutationContext<'gc, '_>, proto: Option<Object<'gc>>) -> Self {
|
pub fn empty_object(gc_context: MutationContext<'gc, '_>, proto: Option<Object<'gc>>) -> Self {
|
||||||
BitmapDataObject(GcCell::allocate(
|
BitmapDataObject(GcCell::allocate(
|
||||||
|
@ -132,6 +130,12 @@ impl<'gc> BitmapDataObject<'gc> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_pixels_rgba(&self) -> Vec<u8> {
|
||||||
|
self.0.read().pixels.iter().flat_map(|p| {
|
||||||
|
vec![p.get_red(), p.get_green(), p.get_blue(), p.get_alpha()]
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_disposed(&self) -> bool {
|
pub fn get_disposed(&self) -> bool {
|
||||||
self.0.read().disposed
|
self.0.read().disposed
|
||||||
}
|
}
|
||||||
|
@ -176,43 +180,57 @@ impl<'gc> BitmapDataObject<'gc> {
|
||||||
.copied()
|
.copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pixel32(&self, x: u32, y: u32) -> Option<Color> {
|
pub fn get_pixel32(&self, x: i32, y: i32) -> Color {
|
||||||
self.get_pixel_raw(x, y).map(|f| f.to_un_multiplied_alpha())
|
self.get_pixel_raw(x as u32, y as u32)
|
||||||
|
.map(|f| f.to_un_multiplied_alpha())
|
||||||
|
.unwrap_or(0.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pixel(&self, x: i32, y: i32) -> i32 {
|
pub fn get_pixel(&self, x: i32, y: i32) -> i32 {
|
||||||
if !self.is_point_in_bounds(x, y) {
|
if !self.is_point_in_bounds(x, y) {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
self.get_pixel32(x as u32, y as u32).map(|p| p.with_alpha(0x0)).unwrap_or(0.into()).into()
|
self.get_pixel32(x, y).with_alpha(0x0).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_pixel32_raw(&self, gc_context: MutationContext<'gc, '_>, x: u32, y: u32, color: Color) {
|
//TODO: private?
|
||||||
|
pub fn set_pixel32_raw(
|
||||||
|
&self,
|
||||||
|
gc_context: MutationContext<'gc, '_>,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
color: Color,
|
||||||
|
) {
|
||||||
let width = self.get_width();
|
let width = self.get_width();
|
||||||
//TODO: bounds check
|
//TODO: bounds check
|
||||||
self.0.write(gc_context).pixels[(x + y * width) as usize] = color;
|
self.0.write(gc_context).pixels[(x + y * width) as usize] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_pixel32(&self, gc_context: MutationContext<'gc, '_>, x: u32, y: u32, color: Color) {
|
pub fn set_pixel32(&self, gc_context: MutationContext<'gc, '_>, x: i32, y: i32, color: Color) {
|
||||||
|
//TODO: what does flash do on set out of bounds
|
||||||
|
if self.is_point_in_bounds(x, y) {
|
||||||
self.set_pixel32_raw(
|
self.set_pixel32_raw(
|
||||||
gc_context,
|
gc_context,
|
||||||
x,
|
x as u32,
|
||||||
y,
|
y as u32,
|
||||||
color.to_premultiplied_alpha(self.get_transparency()),
|
color.to_premultiplied_alpha(self.get_transparency()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_pixel(&self, gc_context: MutationContext<'gc, '_>, x: u32, y: u32, color: Color) {
|
pub fn set_pixel(&self, gc_context: MutationContext<'gc, '_>, x: u32, y: u32, color: Color) {
|
||||||
let current_alpha = self.get_pixel_raw(x, y).map(|p| p.get_alpha()).unwrap_or(0);
|
let current_alpha = self.get_pixel_raw(x, y).map(|p| p.get_alpha()).unwrap_or(0);
|
||||||
self.set_pixel32_raw(
|
self.set_pixel32(gc_context, x as i32, y as i32, color.with_alpha(current_alpha))
|
||||||
gc_context,
|
|
||||||
x,
|
// self.set_pixel32_raw(
|
||||||
y,
|
// gc_context,
|
||||||
color
|
// x,
|
||||||
.with_alpha(current_alpha)
|
// y,
|
||||||
.to_premultiplied_alpha(self.get_transparency()),
|
// color
|
||||||
)
|
// .with_alpha(current_alpha)
|
||||||
|
// .to_premultiplied_alpha(self.get_transparency()),
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dispose(&self, gc_context: MutationContext<'gc, '_>) {
|
pub fn dispose(&self, gc_context: MutationContext<'gc, '_>) {
|
||||||
|
@ -273,10 +291,11 @@ impl<'gc> BitmapDataObject<'gc> {
|
||||||
// TODO: if rect.contains((x, y)) and offset by pnt
|
// TODO: if rect.contains((x, y)) and offset by pnt
|
||||||
|
|
||||||
//TODO: how does this handle out of bounds
|
//TODO: how does this handle out of bounds
|
||||||
let original_color = self.get_pixel32(x as u32, y as u32).unwrap_or(0.into()).0 as u32;
|
let original_color =
|
||||||
|
self.get_pixel_raw(x as u32, y as u32).unwrap_or(0.into()).0 as u32;
|
||||||
|
|
||||||
//TODO: does this calculation work if they are different sizes (might be fixed now)
|
//TODO: does this calculation work if they are different sizes (might be fixed now)
|
||||||
let source_color = source.get_pixel32(x, y).unwrap_or(0.into()).0 as u32;
|
let source_color = source.get_pixel_raw(x, y).unwrap_or(0.into()).0 as u32;
|
||||||
|
|
||||||
//TODO: should this channel be an enum?
|
//TODO: should this channel be an enum?
|
||||||
//TODO: need to support multiple (how does this work if you copy red -> blue and green or any other multi copy)
|
//TODO: need to support multiple (how does this work if you copy red -> blue and green or any other multi copy)
|
||||||
|
@ -363,6 +382,87 @@ impl<'gc> BitmapDataObject<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn color_transform(
|
||||||
|
&self,
|
||||||
|
gc_context: MutationContext<'gc, '_>,
|
||||||
|
min_x: u32,
|
||||||
|
min_y: u32,
|
||||||
|
max_x: u32,
|
||||||
|
max_y: u32,
|
||||||
|
a_mult: f32,
|
||||||
|
a_add: f32,
|
||||||
|
r_mult: f32,
|
||||||
|
r_add: f32,
|
||||||
|
g_mult: f32,
|
||||||
|
g_add: f32,
|
||||||
|
b_mult: f32,
|
||||||
|
b_add: f32,
|
||||||
|
) {
|
||||||
|
for x in min_x..max_x {
|
||||||
|
for y in min_y..max_y {
|
||||||
|
let color = self.get_pixel_raw(x, y).unwrap_or(0.into());
|
||||||
|
let a = ((color.get_alpha() as f32 * a_mult) + a_add) as u8;
|
||||||
|
let r = ((color.get_red() as f32 * r_mult) + r_add) as u8;
|
||||||
|
let g = ((color.get_green() as f32 * g_mult) + g_add) as u8;
|
||||||
|
let b = ((color.get_blue() as f32 * b_mult) + b_add) as u8;
|
||||||
|
|
||||||
|
self.set_pixel32_raw(gc_context, x, y, Color::argb(a, r, g, b))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_color_bounds_rect(
|
||||||
|
&self,
|
||||||
|
mask: i32,
|
||||||
|
color: i32,
|
||||||
|
find_color: bool,
|
||||||
|
) -> (u32, u32, u32, u32) {
|
||||||
|
//TODO: option, if none take image bounds
|
||||||
|
let mut min_x = Option::<i32>::None;
|
||||||
|
let mut max_x = Option::<i32>::None;
|
||||||
|
let mut min_y = Option::<i32>::None;
|
||||||
|
let mut max_y = Option::<i32>::None;
|
||||||
|
|
||||||
|
for x in 0..self.get_width() {
|
||||||
|
for y in 0..self.get_height() {
|
||||||
|
//TODO: does this check for premultiplied colours or not
|
||||||
|
let pixel_raw = self.get_pixel_raw(x, y).unwrap_or(0.into()).0;
|
||||||
|
let color_matches = if find_color {
|
||||||
|
(pixel_raw & mask) == color
|
||||||
|
} else {
|
||||||
|
(pixel_raw & mask) != color
|
||||||
|
};
|
||||||
|
|
||||||
|
if color_matches {
|
||||||
|
if (x as i32) < min_x.unwrap_or(self.get_width() as i32) {
|
||||||
|
min_x = Some(x as i32)
|
||||||
|
}
|
||||||
|
if (x as i32) > max_x.unwrap_or(-1) {
|
||||||
|
max_x = Some(x as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y as i32) < min_y.unwrap_or(self.get_height() as i32) {
|
||||||
|
min_y = Some(y as i32)
|
||||||
|
}
|
||||||
|
if (y as i32) > max_y.unwrap_or(-1) {
|
||||||
|
max_y = Some(y as i32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let min_x = min_x.unwrap_or(0);
|
||||||
|
let min_y = min_y.unwrap_or(0);
|
||||||
|
let max_x = max_x.unwrap_or(self.get_width() as i32);
|
||||||
|
let max_y = max_y.unwrap_or(self.get_height() as i32);
|
||||||
|
|
||||||
|
(
|
||||||
|
min_x as u32,
|
||||||
|
min_y as u32,
|
||||||
|
(min_x + max_x) as u32,
|
||||||
|
(min_y + max_y) as u32,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_width(&self) -> u32 {
|
pub fn get_width(&self) -> u32 {
|
||||||
self.0.read().width
|
self.0.read().width
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,9 @@ pub trait RenderBackend: Downcast {
|
||||||
fn activate_mask(&mut self);
|
fn activate_mask(&mut self);
|
||||||
fn deactivate_mask(&mut self);
|
fn deactivate_mask(&mut self);
|
||||||
fn pop_mask(&mut self);
|
fn pop_mask(&mut self);
|
||||||
|
|
||||||
|
fn get_bitmap_pixels(&mut self, bitmap: BitmapHandle) -> (u32, u32, Vec<u32>);
|
||||||
|
fn register_bitmap_raw(&mut self, width: u32, height: u32, rgba: Vec<u8>) -> BitmapHandle;
|
||||||
}
|
}
|
||||||
impl_downcast!(RenderBackend);
|
impl_downcast!(RenderBackend);
|
||||||
|
|
||||||
|
@ -146,6 +149,14 @@ impl RenderBackend for NullRenderer {
|
||||||
fn activate_mask(&mut self) {}
|
fn activate_mask(&mut self) {}
|
||||||
fn deactivate_mask(&mut self) {}
|
fn deactivate_mask(&mut self) {}
|
||||||
fn pop_mask(&mut self) {}
|
fn pop_mask(&mut self) {}
|
||||||
|
|
||||||
|
fn get_bitmap_pixels(&mut self, bitmap: BitmapHandle) -> (u32, u32, Vec<u32>) {
|
||||||
|
(0, 0, vec![])
|
||||||
|
}
|
||||||
|
fn register_bitmap_raw(&mut self, width: u32, height: u32, rgba: Vec<u8>) -> BitmapHandle
|
||||||
|
{
|
||||||
|
BitmapHandle(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The format of image data in a DefineBitsJpeg2/3 tag.
|
/// The format of image data in a DefineBitsJpeg2/3 tag.
|
||||||
|
@ -160,7 +171,7 @@ pub enum JpegTagFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decoded bitmap data from an SWF tag.
|
/// Decoded bitmap data from an SWF tag.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Bitmap {
|
pub struct Bitmap {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
|
@ -169,7 +180,7 @@ pub struct Bitmap {
|
||||||
|
|
||||||
/// Decoded bitmap data from an SWF tag.
|
/// Decoded bitmap data from an SWF tag.
|
||||||
/// The image data will have pre-multiplied alpha.
|
/// The image data will have pre-multiplied alpha.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum BitmapFormat {
|
pub enum BitmapFormat {
|
||||||
Rgb(Vec<u8>),
|
Rgb(Vec<u8>),
|
||||||
Rgba(Vec<u8>),
|
Rgba(Vec<u8>),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::backend::audio::SoundHandle;
|
||||||
use crate::display_object::{Bitmap, Button, EditText, Graphic, MorphShape, MovieClip, Text};
|
use crate::display_object::{Bitmap, Button, EditText, Graphic, MorphShape, MovieClip, Text};
|
||||||
use crate::font::Font;
|
use crate::font::Font;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Character<'gc> {
|
pub enum Character<'gc> {
|
||||||
EditText(EditText<'gc>),
|
EditText(EditText<'gc>),
|
||||||
Graphic(Graphic<'gc>),
|
Graphic(Graphic<'gc>),
|
||||||
|
|
|
@ -127,7 +127,8 @@ impl SwfMovie {
|
||||||
|
|
||||||
/// Get the URL this SWF was fetched from.
|
/// Get the URL this SWF was fetched from.
|
||||||
pub fn url(&self) -> Option<&str> {
|
pub fn url(&self) -> Option<&str> {
|
||||||
self.url.as_deref()
|
// self.url.as_deref()
|
||||||
|
Some("ww.king.com")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parameters(&self) -> &PropertyMap<String> {
|
pub fn parameters(&self) -> &PropertyMap<String> {
|
||||||
|
|
|
@ -66,13 +66,76 @@ undefined
|
||||||
-f10001
|
-f10001
|
||||||
// fillRect(src.rectangle, 0xFF121212
|
// fillRect(src.rectangle, 0xFF121212
|
||||||
// src.getPixel32(0, 0)
|
// src.getPixel32(0, 0)
|
||||||
-ededee
|
-15592942
|
||||||
// src.getPixel32(1, 0)
|
|
||||||
-ededee
|
|
||||||
// src.getPixel32(0, 1)
|
// src.getPixel32(0, 1)
|
||||||
-ededee
|
-15592942
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-15592942
|
||||||
// src.getPixel32(1, 1)
|
// src.getPixel32(1, 1)
|
||||||
-ededee
|
-15592942
|
||||||
|
// fillRect(src.rectangle, 0xFF121212
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-15592942
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-15592942
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-15592942
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-15592942
|
||||||
|
// fillRect({x: 1, y: 1, width: 1, height: 1}, 0xFF242424
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-14408668
|
||||||
|
// fillRect(src.rectangle
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-14408668
|
||||||
|
// fillRect()
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-14408668
|
||||||
|
// fillRect(undefined, 0xFF121212
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-14408668
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-14408668
|
||||||
|
// fillRect({x: -10, y: 1, width: 1, height: 1}, 0xF3243434
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-215731148
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-215731148
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-215731148
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-215731148
|
||||||
|
// fillRect({x: 0, y: 1, width: 100, height: 100}, 0xFF424242
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-12434878
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
-12434878
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
-12434878
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
-12434878
|
||||||
// src.getPixel32(0, 0) alpha = 0
|
// src.getPixel32(0, 0) alpha = 0
|
||||||
0
|
0
|
||||||
// src.getPixel32(0, 0) alpha = 1
|
// src.getPixel32(0, 0) alpha = 1
|
||||||
|
@ -145,8 +208,54 @@ fffffff
|
||||||
-1
|
-1
|
||||||
// disposed.rectangle
|
// disposed.rectangle
|
||||||
-1
|
-1
|
||||||
|
// disposed.applyFilter()
|
||||||
|
-1
|
||||||
|
// disposed.clone()
|
||||||
|
-1
|
||||||
|
// disposed.colorTransform()
|
||||||
|
-1
|
||||||
|
// disposed.copyChannel()
|
||||||
|
-1
|
||||||
|
// disposed.copyPixels()
|
||||||
|
-1
|
||||||
|
// disposed.dispose()
|
||||||
|
-1
|
||||||
|
// disposed.draw()
|
||||||
|
-1
|
||||||
|
// disposed.fillRect()
|
||||||
|
undefined
|
||||||
|
// disposed.floodFill()
|
||||||
|
-1
|
||||||
|
// disposed.generateFilterRect()
|
||||||
|
-1
|
||||||
|
// disposed.getColorBoundsRect()
|
||||||
|
-1
|
||||||
// disposed.getPixel(0, 0)
|
// disposed.getPixel(0, 0)
|
||||||
-1
|
-1
|
||||||
|
// disposed.getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// disposed.hitTest()
|
||||||
|
-1
|
||||||
|
// disposed.loadBitmap()
|
||||||
|
undefined
|
||||||
|
// disposed.merge()
|
||||||
|
-1
|
||||||
|
// disposed.noise()
|
||||||
|
-1
|
||||||
|
// disposed.paletteMap()
|
||||||
|
-1
|
||||||
|
// disposed.perlinNoise()
|
||||||
|
-1
|
||||||
|
// disposed.pixelDissolve()
|
||||||
|
-1
|
||||||
|
// disposed.scroll()
|
||||||
|
-1
|
||||||
|
// disposed.setPixel(0, 0, 0)
|
||||||
|
-1
|
||||||
|
// disposed.setPixel32(0, 0, 0)
|
||||||
|
-1
|
||||||
|
// disposed.threshold()
|
||||||
|
-1
|
||||||
// flood_filled.getPixel32(0, 0)
|
// flood_filled.getPixel32(0, 0)
|
||||||
-545455
|
-545455
|
||||||
// flood_filled.getPixel32(1, 0)
|
// flood_filled.getPixel32(1, 0)
|
||||||
|
@ -163,3 +272,527 @@ fffffff
|
||||||
0
|
0
|
||||||
// getPixel (10, 10)
|
// getPixel (10, 10)
|
||||||
0
|
0
|
||||||
|
// setPixel32 (noargs)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// setPixel32 (0)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// setPixel32 (0, 0)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// setPixel32 (0, 0, 0xFF00FF00)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// setPixel (noargs)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// setPixel (0)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// setPixel (0, 0)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-1
|
||||||
|
// setPixel (0, 0, 0xFF00FF00)
|
||||||
|
// getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 0)
|
||||||
|
-16711936
|
||||||
|
// src.getPixel32(0, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(0, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(1, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(2, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(3, 4)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 0)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 1)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 2)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 3)
|
||||||
|
0
|
||||||
|
// src.getPixel32(4, 4)
|
||||||
|
0
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -32,6 +32,7 @@ pub struct WebCanvasRenderBackend {
|
||||||
use_color_transform_hack: bool,
|
use_color_transform_hack: bool,
|
||||||
pixelated_property_value: &'static str,
|
pixelated_property_value: &'static str,
|
||||||
deactivating_mask: bool,
|
deactivating_mask: bool,
|
||||||
|
bitmap_registry: HashMap<CharacterId, Bitmap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Canvas-drawable shape data extracted from an SWF file.
|
/// Canvas-drawable shape data extracted from an SWF file.
|
||||||
|
@ -223,6 +224,7 @@ impl WebCanvasRenderBackend {
|
||||||
} else {
|
} else {
|
||||||
"pixelated"
|
"pixelated"
|
||||||
},
|
},
|
||||||
|
bitmap_registry: HashMap::new(),
|
||||||
};
|
};
|
||||||
Ok(renderer)
|
Ok(renderer)
|
||||||
}
|
}
|
||||||
|
@ -374,6 +376,13 @@ impl WebCanvasRenderBackend {
|
||||||
id: CharacterId,
|
id: CharacterId,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
) -> Result<BitmapInfo, Error> {
|
) -> Result<BitmapInfo, Error> {
|
||||||
|
//TODO:
|
||||||
|
self.bitmap_registry.insert(id, Bitmap {
|
||||||
|
width: 123,
|
||||||
|
height: 123,
|
||||||
|
data: BitmapFormat::Rgb(vec![])
|
||||||
|
});
|
||||||
|
|
||||||
let data = ruffle_core::backend::render::remove_invalid_jpeg_data(data);
|
let data = ruffle_core::backend::render::remove_invalid_jpeg_data(data);
|
||||||
let mut decoder = jpeg_decoder::Decoder::new(&data[..]);
|
let mut decoder = jpeg_decoder::Decoder::new(&data[..]);
|
||||||
decoder.read_info()?;
|
decoder.read_info()?;
|
||||||
|
@ -403,6 +412,8 @@ impl WebCanvasRenderBackend {
|
||||||
id: CharacterId,
|
id: CharacterId,
|
||||||
bitmap: Bitmap,
|
bitmap: Bitmap,
|
||||||
) -> Result<BitmapInfo, Error> {
|
) -> Result<BitmapInfo, Error> {
|
||||||
|
self.bitmap_registry.insert(id, bitmap.clone());
|
||||||
|
|
||||||
let (width, height) = (bitmap.width, bitmap.height);
|
let (width, height) = (bitmap.width, bitmap.height);
|
||||||
let png = Self::bitmap_to_png_data_uri(bitmap)?;
|
let png = Self::bitmap_to_png_data_uri(bitmap)?;
|
||||||
|
|
||||||
|
@ -522,6 +533,9 @@ impl RenderBackend for WebCanvasRenderBackend {
|
||||||
) -> Result<BitmapInfo, Error> {
|
) -> Result<BitmapInfo, Error> {
|
||||||
let bitmap = ruffle_core::backend::render::decode_define_bits_lossless(swf_tag)?;
|
let bitmap = ruffle_core::backend::render::decode_define_bits_lossless(swf_tag)?;
|
||||||
|
|
||||||
|
self.bitmap_registry.insert(swf_tag.id, bitmap.clone());
|
||||||
|
|
||||||
|
|
||||||
let png = Self::bitmap_to_png_data_uri(bitmap)?;
|
let png = Self::bitmap_to_png_data_uri(bitmap)?;
|
||||||
|
|
||||||
let image = HtmlImageElement::new().unwrap();
|
let image = HtmlImageElement::new().unwrap();
|
||||||
|
@ -746,6 +760,51 @@ impl RenderBackend for WebCanvasRenderBackend {
|
||||||
.draw_image_with_html_canvas_element(&maskee_canvas, 0.0, 0.0)
|
.draw_image_with_html_canvas_element(&maskee_canvas, 0.0, 0.0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_bitmap_pixels(&mut self, bitmap: BitmapHandle) -> (u32, u32, Vec<u32>) {
|
||||||
|
log::error!("Get bitmap pixels canvas {:?}", bitmap);
|
||||||
|
|
||||||
|
if let Some((id, _texture)) = self.id_to_bitmap.iter().find(|(_k, v)| v.0 == bitmap.0) {
|
||||||
|
if let Some(bitmap) = self.bitmap_registry.get(id) {
|
||||||
|
log::error!("Found bitmap = {:?}", bitmap);
|
||||||
|
let data = match &bitmap.data {
|
||||||
|
BitmapFormat::Rgb(x) => {
|
||||||
|
x.chunks_exact(3).map(|chunk| {
|
||||||
|
let r = chunk[0];
|
||||||
|
let g = chunk[1];
|
||||||
|
let b = chunk[2];
|
||||||
|
(0xFF << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
BitmapFormat::Rgba(x) => {
|
||||||
|
x.chunks_exact(4).map(|chunk| {
|
||||||
|
let r = chunk[0];
|
||||||
|
let g = chunk[1];
|
||||||
|
let b = chunk[2];
|
||||||
|
//TODO: check this order, assuming because rgb_a
|
||||||
|
let a = chunk[3];
|
||||||
|
((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(bitmap.width, bitmap.height, data)
|
||||||
|
} else {
|
||||||
|
log::error!("Failed to find bitmap {} in registry", id);
|
||||||
|
(0, 0, vec![0])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::error!("Failed to find bitmap {:?} in id_to_bitmap", bitmap);
|
||||||
|
(0, 0, vec![1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_bitmap_raw(&mut self, width: u32, height: u32, rgba: Vec<u8>) -> BitmapHandle {
|
||||||
|
self.register_bitmap_raw(0 as CharacterId, Bitmap {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
data: BitmapFormat::Rgba(rgba)
|
||||||
|
}).unwrap().handle
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
#[allow(clippy::cognitive_complexity)]
|
||||||
|
|
|
@ -13,6 +13,7 @@ use web_sys::{
|
||||||
WebGlFramebuffer, WebGlProgram, WebGlRenderbuffer, WebGlRenderingContext as Gl, WebGlShader,
|
WebGlFramebuffer, WebGlProgram, WebGlRenderbuffer, WebGlRenderingContext as Gl, WebGlShader,
|
||||||
WebGlTexture, WebGlUniformLocation, WebGlVertexArrayObject, WebglDebugRendererInfo,
|
WebGlTexture, WebGlUniformLocation, WebGlVertexArrayObject, WebglDebugRendererInfo,
|
||||||
};
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
type Error = Box<dyn std::error::Error>;
|
type Error = Box<dyn std::error::Error>;
|
||||||
|
|
||||||
|
@ -70,6 +71,8 @@ pub struct WebGlRenderBackend {
|
||||||
view_width: i32,
|
view_width: i32,
|
||||||
view_height: i32,
|
view_height: i32,
|
||||||
view_matrix: [[f32; 4]; 4],
|
view_matrix: [[f32; 4]; 4],
|
||||||
|
|
||||||
|
bitmap_registry: HashMap<swf::CharacterId, Bitmap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_GRADIENT_COLORS: usize = 15;
|
const MAX_GRADIENT_COLORS: usize = 15;
|
||||||
|
@ -208,6 +211,7 @@ impl WebGlRenderBackend {
|
||||||
blend_func: (Gl::SRC_ALPHA, Gl::ONE_MINUS_SRC_ALPHA),
|
blend_func: (Gl::SRC_ALPHA, Gl::ONE_MINUS_SRC_ALPHA),
|
||||||
mult_color: None,
|
mult_color: None,
|
||||||
add_color: None,
|
add_color: None,
|
||||||
|
bitmap_registry: HashMap::new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let quad_mesh = renderer.build_quad_mesh()?;
|
let quad_mesh = renderer.build_quad_mesh()?;
|
||||||
|
@ -675,6 +679,8 @@ impl WebGlRenderBackend {
|
||||||
id: swf::CharacterId,
|
id: swf::CharacterId,
|
||||||
bitmap: Bitmap,
|
bitmap: Bitmap,
|
||||||
) -> Result<BitmapInfo, Error> {
|
) -> Result<BitmapInfo, Error> {
|
||||||
|
self.bitmap_registry.insert(id, bitmap.clone());
|
||||||
|
|
||||||
let texture = self.gl.create_texture().unwrap();
|
let texture = self.gl.create_texture().unwrap();
|
||||||
self.gl.bind_texture(Gl::TEXTURE_2D, Some(&texture));
|
self.gl.bind_texture(Gl::TEXTURE_2D, Some(&texture));
|
||||||
match bitmap.data {
|
match bitmap.data {
|
||||||
|
@ -1266,6 +1272,46 @@ impl RenderBackend for WebGlRenderBackend {
|
||||||
};
|
};
|
||||||
self.mask_state_dirty = true;
|
self.mask_state_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_bitmap_pixels(&mut self, bitmap: BitmapHandle) -> (u32, u32, Vec<u32>) {
|
||||||
|
println!("Get bitmap pixels webgl {:?}", bitmap);
|
||||||
|
if let Some((id, _texture)) = self.textures.get(bitmap.0) {
|
||||||
|
if let Some(bitmap) = self.bitmap_registry.get(id) {
|
||||||
|
let data = match &bitmap.data {
|
||||||
|
BitmapFormat::Rgb(x) => {
|
||||||
|
x.chunks_exact(3).map(|chunk| {
|
||||||
|
let r = chunk[0];
|
||||||
|
let g = chunk[1];
|
||||||
|
let b = chunk[2];
|
||||||
|
(0xFF << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
BitmapFormat::Rgba(x) => {
|
||||||
|
x.chunks_exact(4).map(|chunk| {
|
||||||
|
let r = chunk[0];
|
||||||
|
let g = chunk[1];
|
||||||
|
let b = chunk[2];
|
||||||
|
//TODO: check this order, assuming because rgb_a
|
||||||
|
let a = chunk[3];
|
||||||
|
((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(bitmap.width, bitmap.height, data)
|
||||||
|
} else {
|
||||||
|
println!("Failed 1");
|
||||||
|
(0, 0, vec![])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Failed 2");
|
||||||
|
(0, 0, vec![])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn register_bitmap_raw(&mut self, width: u32, height: u32, rgba: Vec<u8>) -> BitmapHandle {
|
||||||
|
//TODO:
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Texture {
|
struct Texture {
|
||||||
|
|
|
@ -45,6 +45,7 @@ use crate::globals::Globals;
|
||||||
use ruffle_core::swf::{Matrix, Twips};
|
use ruffle_core::swf::{Matrix, Twips};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
pub use wgpu;
|
pub use wgpu;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
pub struct Descriptors {
|
pub struct Descriptors {
|
||||||
pub device: wgpu::Device,
|
pub device: wgpu::Device,
|
||||||
|
@ -95,6 +96,7 @@ pub struct WgpuRenderBackend<T: RenderTarget> {
|
||||||
quad_vbo: wgpu::Buffer,
|
quad_vbo: wgpu::Buffer,
|
||||||
quad_ibo: wgpu::Buffer,
|
quad_ibo: wgpu::Buffer,
|
||||||
quad_tex_transforms: wgpu::Buffer,
|
quad_tex_transforms: wgpu::Buffer,
|
||||||
|
bitmap_registry: HashMap<CharacterId, Bitmap>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Enum)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Enum)]
|
||||||
|
@ -269,6 +271,7 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
quad_vbo,
|
quad_vbo,
|
||||||
quad_ibo,
|
quad_ibo,
|
||||||
quad_tex_transforms,
|
quad_tex_transforms,
|
||||||
|
bitmap_registry: HashMap::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,6 +687,8 @@ impl<T: RenderTarget> WgpuRenderBackend<T> {
|
||||||
bitmap: Bitmap,
|
bitmap: Bitmap,
|
||||||
debug_str: &str,
|
debug_str: &str,
|
||||||
) -> BitmapInfo {
|
) -> BitmapInfo {
|
||||||
|
self.bitmap_registry.insert(id, bitmap.clone());
|
||||||
|
|
||||||
let extent = wgpu::Extent3d {
|
let extent = wgpu::Extent3d {
|
||||||
width: bitmap.width,
|
width: bitmap.width,
|
||||||
height: bitmap.height,
|
height: bitmap.height,
|
||||||
|
@ -1489,6 +1494,38 @@ impl<T: RenderTarget + 'static> RenderBackend for WgpuRenderBackend<T> {
|
||||||
MaskState::DrawMaskedContent
|
MaskState::DrawMaskedContent
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_bitmap_pixels(&mut self, bitmap: BitmapHandle) -> (u32, u32, Vec<u32>) {
|
||||||
|
if let Some((id, _texture)) = self.textures.get(bitmap.0) {
|
||||||
|
if let Some(bitmap) = self.bitmap_registry.get(id) {
|
||||||
|
let data = match &bitmap.data {
|
||||||
|
BitmapFormat::Rgb(x) => {
|
||||||
|
x.chunks_exact(3).map(|chunk| {
|
||||||
|
let r = chunk[0];
|
||||||
|
let g = chunk[1];
|
||||||
|
let b = chunk[2];
|
||||||
|
(0xFF << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
BitmapFormat::Rgba(x) => {
|
||||||
|
x.chunks_exact(4).map(|chunk| {
|
||||||
|
let r = chunk[0];
|
||||||
|
let g = chunk[1];
|
||||||
|
let b = chunk[2];
|
||||||
|
//TODO: check this order, assuming because rgb_a
|
||||||
|
let a = chunk[3];
|
||||||
|
((a as u32) << 24) | ((r as u32) << 16) | ((g as u32) << 8) | (b as u32)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(bitmap.width, bitmap.height, data)
|
||||||
|
} else {
|
||||||
|
(0, 0, vec![])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(0, 0, vec![])
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_quad_buffers(device: &wgpu::Device) -> (wgpu::Buffer, wgpu::Buffer, wgpu::Buffer) {
|
fn create_quad_buffers(device: &wgpu::Device) -> (wgpu::Buffer, wgpu::Buffer, wgpu::Buffer) {
|
||||||
|
|
Loading…
Reference in New Issue