core: Add flash.filters.GradientGlowFilter

This commit is contained in:
CUB3D 2021-01-06 20:28:31 +00:00 committed by Mike Welsh
parent 0cab167e4c
commit 01557fba5a
12 changed files with 1074 additions and 23 deletions

View File

@ -34,6 +34,7 @@ mod external_interface;
mod function;
mod glow_filter;
pub mod gradient_bevel_filter;
pub mod gradient_glow_filter;
mod key;
mod load_vars;
mod math;
@ -503,6 +504,8 @@ pub struct SystemPrototypes<'gc> {
pub convolution_filter_constructor: Object<'gc>,
pub gradient_bevel_filter: Object<'gc>,
pub gradient_bevel_filter_constructor: Object<'gc>,
pub gradient_glow_filter: Object<'gc>,
pub gradient_glow_filter_constructor: Object<'gc>,
pub date: Object<'gc>,
pub bitmap_data: Object<'gc>,
pub bitmap_data_constructor: Object<'gc>,
@ -780,6 +783,16 @@ pub fn create_globals<'gc>(
gradient_bevel_filter_proto,
);
//TODO: are there any differnces
let gradient_glow_filter_proto =
gradient_glow_filter::create_proto(gc_context, bitmap_filter_proto, function_proto);
let gradient_glow_filter = FunctionObject::constructor(
gc_context,
Executable::Native(gradient_glow_filter::constructor),
Some(function_proto),
gradient_glow_filter_proto,
);
filters.define_value(
gc_context,
"BitmapFilter",
@ -835,6 +848,12 @@ pub fn create_globals<'gc>(
gradient_bevel_filter.into(),
EnumSet::empty(),
);
filters.define_value(
gc_context,
"GradientGlowFilter",
gradient_glow_filter.into(),
EnumSet::empty(),
);
let bitmap_data_proto = bitmap_data::create_proto(gc_context, object_proto, function_proto);
let bitmap_data =
@ -1157,6 +1176,8 @@ pub fn create_globals<'gc>(
convolution_filter_constructor: convolution_filter,
gradient_bevel_filter: gradient_bevel_filter_proto,
gradient_bevel_filter_constructor: gradient_bevel_filter,
gradient_glow_filter: gradient_glow_filter_proto,
gradient_glow_filter_constructor: gradient_glow_filter,
date: date_proto,
bitmap_data: bitmap_data_proto,
bitmap_data_constructor: bitmap_data,

View File

@ -234,6 +234,36 @@ pub fn clone<'gc>(
return Ok(cloned.into());
}
if let Some(this) = this.as_gradient_glow_filter_object() {
let proto = activation
.context
.avm1
.prototypes
.gradient_glow_filter_constructor;
let distance = this.get("distance", activation)?;
let angle = this.get("angle", activation)?;
let colors = this.get("colors", activation)?;
let alphas = this.get("alphas", activation)?;
let ratios = this.get("ratios", activation)?;
let blur_x = this.get("blurX", activation)?;
let blur_y = this.get("blurY", activation)?;
let strength = this.get("strength", activation)?;
let quality = this.get("quality", activation)?;
let type_ = this.get("type", activation)?;
let knockout = this.get("knockout", activation)?;
let cloned = proto.construct(
activation,
&[
distance, angle, colors, alphas, ratios, blur_x, blur_y, strength, quality, type_,
knockout,
],
)?;
return Ok(cloned.into());
}
Ok(Value::Undefined)
}

View File

@ -26,7 +26,7 @@ pub fn blur_x<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_blur_filter_object() {
return Ok(filter.blur_x().into())
return Ok(filter.blur_x().into());
}
Ok(Value::Undefined)
@ -56,7 +56,7 @@ pub fn get_blur_y<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_blur_filter_object() {
return Ok(filter.blur_y().into())
return Ok(filter.blur_y().into());
}
Ok(Value::Undefined)
@ -86,7 +86,7 @@ pub fn get_quality<'gc>(
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_blur_filter_object() {
return Ok(filter.quality().into())
return Ok(filter.quality().into());
}
Ok(Value::Undefined)

View File

@ -29,8 +29,6 @@ pub fn constructor<'gc>(
Ok(Value::Undefined)
}
// todo: check floats / types etcss
pub fn distance<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
@ -195,7 +193,12 @@ pub fn set_alphas<'gc>(
let mut arr = Vec::with_capacity(arr_len);
for index in 0..arr_len {
arr.push(obj.array_element(index).coerce_to_f64(activation)?.max(0.0).min(1.0));
arr.push(
obj.array_element(index)
.coerce_to_f64(activation)?
.max(0.0)
.min(1.0),
);
}
let colors = filter.colors().into_iter().take(arr_len).collect();
@ -247,10 +250,14 @@ pub fn set_ratios<'gc>(
let mut arr = Vec::with_capacity(arr_len);
for index in 0..arr_len {
arr.push(obj.array_element(index).coerce_to_i32(activation)?.max(0).min(255) as u8);
arr.push(
obj.array_element(index)
.coerce_to_i32(activation)?
.max(0)
.min(255) as u8,
);
}
let colors = filter.colors().into_iter().take(arr_len).collect();
filter.set_colors(activation.context.gc_context, colors);
@ -384,13 +391,13 @@ pub fn set_quality<'gc>(
Ok(Value::Undefined)
}
pub fn type_<'gc>(
pub fn get_type<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_gradient_bevel_filter_object() {
let type_: &str = filter.type_().into();
let type_: &str = filter.get_type().into();
return Ok(AvmString::new(activation.context.gc_context, type_.to_string()).into());
}
@ -622,7 +629,7 @@ pub fn create_proto<'gc>(
"type",
FunctionObject::function(
gc_context,
Executable::Native(type_),
Executable::Native(get_type),
Some(fn_proto),
fn_proto,
),

View File

@ -0,0 +1,664 @@
//! flash.filter.GradientGlowFilter object
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::function::{Executable, FunctionObject};
use crate::avm1::object::bevel_filter::BevelFilterType;
use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject;
use crate::avm1::{AvmString, Object, ScriptObject, TObject, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
set_distance(activation, this, args.get(0..1).unwrap_or_default())?;
set_angle(activation, this, args.get(1..2).unwrap_or_default())?;
set_colors(activation, this, args.get(2..3).unwrap_or_default())?;
set_alphas(activation, this, args.get(3..4).unwrap_or_default())?;
set_ratios(activation, this, args.get(4..5).unwrap_or_default())?;
set_blur_x(activation, this, args.get(5..6).unwrap_or_default())?;
set_blur_y(activation, this, args.get(6..7).unwrap_or_default())?;
set_strength(activation, this, args.get(7..8).unwrap_or_default())?;
set_quality(activation, this, args.get(8..9).unwrap_or_default())?;
set_type(activation, this, args.get(9..10).unwrap_or_default())?;
set_knockout(activation, this, args.get(10..11).unwrap_or_default())?;
Ok(Value::Undefined)
}
pub fn distance<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.distance().into());
}
Ok(Value::Undefined)
}
pub fn set_distance<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let distance = args
.get(0)
.unwrap_or(&4.0.into())
.coerce_to_f64(activation)?;
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_distance(activation.context.gc_context, distance);
}
Ok(Value::Undefined)
}
pub fn angle<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.angle().into());
}
Ok(Value::Undefined)
}
pub fn set_angle<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let angle = args
.get(0)
.unwrap_or(&44.9999999772279.into())
.coerce_to_f64(activation)?;
let clamped_angle = if angle.is_sign_negative() {
-(angle.abs() % 360.0)
} else {
angle % 360.0
};
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_angle(activation.context.gc_context, clamped_angle);
}
Ok(Value::Undefined)
}
pub fn colors<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let array = ScriptObject::array(
activation.context.gc_context,
Some(activation.context.avm1.prototypes.array),
);
let arr = filter.colors();
for (index, item) in arr.iter().copied().enumerate() {
array.set_array_element(index, item.into(), activation.context.gc_context);
}
return Ok(array.into());
}
Ok(Value::Undefined)
}
pub fn set_colors<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let colors = args.get(0).unwrap_or(&Value::Undefined);
if let Value::Object(obj) = colors {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let arr_len = obj.length();
let mut colors_arr = Vec::with_capacity(arr_len);
let old_alphas = filter.alphas();
let mut alphas_arr = Vec::with_capacity(arr_len);
for index in 0..arr_len {
let col = obj.array_element(index).coerce_to_u32(activation)?;
let alpha = if let Some(alpha) = old_alphas.get(index) {
*alpha
} else if col >> 24 == 0 {
0.0
} else {
255.0 / (col >> 24) as f64
};
colors_arr.push(col & 0xFFFFFF);
alphas_arr.push(alpha);
}
filter.set_colors(activation.context.gc_context, colors_arr);
filter.set_alphas(activation.context.gc_context, alphas_arr);
let ratios = filter.ratios().into_iter().take(arr_len).collect();
filter.set_ratios(activation.context.gc_context, ratios);
}
}
Ok(Value::Undefined)
}
pub fn alphas<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let array = ScriptObject::array(
activation.context.gc_context,
Some(activation.context.avm1.prototypes.array),
);
let arr = filter.alphas();
for (index, item) in arr.iter().copied().enumerate() {
array.set_array_element(index, item.into(), activation.context.gc_context);
}
return Ok(array.into());
}
Ok(Value::Undefined)
}
pub fn set_alphas<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let alphas = args.get(0).unwrap_or(&Value::Undefined);
if let Value::Object(obj) = alphas {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let arr_len = obj.length().min(filter.colors().len());
let mut arr = Vec::with_capacity(arr_len);
for index in 0..arr_len {
arr.push(
obj.array_element(index)
.coerce_to_f64(activation)?
.max(0.0)
.min(1.0),
);
}
let colors = filter.colors().into_iter().take(arr_len).collect();
filter.set_colors(activation.context.gc_context, colors);
let ratios = filter.ratios().into_iter().take(arr_len).collect();
filter.set_ratios(activation.context.gc_context, ratios);
filter.set_alphas(activation.context.gc_context, arr);
}
}
Ok(Value::Undefined)
}
pub fn ratios<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let array = ScriptObject::array(
activation.context.gc_context,
Some(activation.context.avm1.prototypes.array),
);
let arr = filter.ratios();
for (index, item) in arr.iter().copied().enumerate() {
array.set_array_element(index, item.into(), activation.context.gc_context);
}
return Ok(array.into());
}
Ok(Value::Undefined)
}
pub fn set_ratios<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let ratios = args.get(0).unwrap_or(&Value::Undefined);
if let Value::Object(obj) = ratios {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let arr_len = obj.length().min(filter.colors().len());
let mut arr = Vec::with_capacity(arr_len);
for index in 0..arr_len {
arr.push(
obj.array_element(index)
.coerce_to_i32(activation)?
.max(0)
.min(255) as u8,
);
}
let colors = filter.colors().into_iter().take(arr_len).collect();
filter.set_colors(activation.context.gc_context, colors);
let alphas = filter.alphas().into_iter().take(arr_len).collect();
filter.set_alphas(activation.context.gc_context, alphas);
filter.set_ratios(activation.context.gc_context, arr);
}
}
Ok(Value::Undefined)
}
pub fn blur_x<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.blur_x().into());
}
Ok(Value::Undefined)
}
pub fn set_blur_x<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let blur_x = args
.get(0)
.unwrap_or(&4.0.into())
.coerce_to_f64(activation)
.map(|x| x.max(0.0).min(255.0))?;
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_blur_x(activation.context.gc_context, blur_x);
}
Ok(Value::Undefined)
}
pub fn blur_y<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.blur_y().into());
}
Ok(Value::Undefined)
}
pub fn set_blur_y<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let blur_y = args
.get(0)
.unwrap_or(&4.0.into())
.coerce_to_f64(activation)
.map(|x| x.max(0.0).min(255.0))?;
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_blur_y(activation.context.gc_context, blur_y);
}
Ok(Value::Undefined)
}
pub fn strength<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.strength().into());
}
Ok(Value::Undefined)
}
pub fn set_strength<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let strength = args
.get(0)
.unwrap_or(&1.0.into())
.coerce_to_f64(activation)
.map(|x| x.max(0.0).min(255.0))?;
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_strength(activation.context.gc_context, strength);
}
Ok(Value::Undefined)
}
pub fn quality<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.quality().into());
}
Ok(Value::Undefined)
}
pub fn set_quality<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let quality = args
.get(0)
.unwrap_or(&1.0.into())
.coerce_to_i32(activation)
.map(|x| x.max(0).min(15))?;
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_quality(activation.context.gc_context, quality);
}
Ok(Value::Undefined)
}
pub fn get_type<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(filter) = this.as_gradient_glow_filter_object() {
let type_: &str = filter.get_type().into();
return Ok(AvmString::new(activation.context.gc_context, type_.to_string()).into());
}
Ok(Value::Undefined)
}
pub fn set_type<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let type_: BevelFilterType = args
.get(0)
.unwrap_or(&Value::String(AvmString::new(
activation.context.gc_context,
"inner".to_string(),
)))
.coerce_to_string(activation)
.map(|s| s.as_str().into())?;
if let Some(filter) = this.as_gradient_glow_filter_object() {
filter.set_type(activation.context.gc_context, type_);
}
Ok(Value::Undefined)
}
pub fn knockout<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(object) = this.as_gradient_glow_filter_object() {
return Ok(object.knockout().into());
}
Ok(Value::Undefined)
}
pub fn set_knockout<'gc>(
activation: &mut Activation<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let knockout = args
.get(0)
.unwrap_or(&false.into())
.as_bool(activation.current_swf_version());
if let Some(object) = this.as_gradient_glow_filter_object() {
object.set_knockout(activation.context.gc_context, knockout);
}
Ok(Value::Undefined)
}
pub fn create_proto<'gc>(
gc_context: MutationContext<'gc, '_>,
proto: Object<'gc>,
fn_proto: Object<'gc>,
) -> Object<'gc> {
let color_matrix_filter = GradientGlowFilterObject::empty_object(gc_context, Some(proto));
let object = color_matrix_filter.as_script_object().unwrap();
object.add_property(
gc_context,
"distance",
FunctionObject::function(
gc_context,
Executable::Native(distance),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_distance),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"angle",
FunctionObject::function(
gc_context,
Executable::Native(angle),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_angle),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"colors",
FunctionObject::function(
gc_context,
Executable::Native(colors),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_colors),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"alphas",
FunctionObject::function(
gc_context,
Executable::Native(alphas),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_alphas),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"ratios",
FunctionObject::function(
gc_context,
Executable::Native(ratios),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_ratios),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"blurX",
FunctionObject::function(
gc_context,
Executable::Native(blur_x),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_blur_x),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"blurY",
FunctionObject::function(
gc_context,
Executable::Native(blur_y),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_blur_y),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"strength",
FunctionObject::function(
gc_context,
Executable::Native(strength),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_strength),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"quality",
FunctionObject::function(
gc_context,
Executable::Native(quality),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_quality),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"type",
FunctionObject::function(
gc_context,
Executable::Native(get_type),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_type),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
object.add_property(
gc_context,
"knockout",
FunctionObject::function(
gc_context,
Executable::Native(knockout),
Some(fn_proto),
fn_proto,
),
Some(FunctionObject::function(
gc_context,
Executable::Native(set_knockout),
Some(fn_proto),
fn_proto,
)),
EnumSet::empty(),
);
color_matrix_filter.into()
}

View File

@ -19,6 +19,7 @@ use crate::avm1::object::displacement_map_filter::DisplacementMapFilterObject;
use crate::avm1::object::drop_shadow_filter::DropShadowFilterObject;
use crate::avm1::object::glow_filter::GlowFilterObject;
use crate::avm1::object::gradient_bevel_filter::GradientBevelFilterObject;
use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject;
use crate::avm1::object::transform_object::TransformObject;
use crate::avm1::object::xml_attributes_object::XMLAttributesObject;
use crate::avm1::object::xml_idmap_object::XMLIDMapObject;
@ -45,6 +46,7 @@ pub mod displacement_map_filter;
pub mod drop_shadow_filter;
pub mod glow_filter;
pub mod gradient_bevel_filter;
pub mod gradient_glow_filter;
pub mod script_object;
pub mod shared_object;
pub mod sound_object;
@ -82,6 +84,7 @@ pub mod xml_object;
DisplacementMapFilterObject(DisplacementMapFilterObject<'gc>),
ConvolutionFilterObject(ConvolutionFilterObject<'gc>),
GradientBevelFilterObject(GradientBevelFilterObject<'gc>),
GradientGlowFilterObject(GradientGlowFilterObject<'gc>),
DateObject(DateObject<'gc>),
BitmapData(BitmapDataObject<'gc>),
}
@ -500,6 +503,11 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
None
}
/// Get the underlying `GradientGlowFilterObject`, if it exists
fn as_gradient_glow_filter_object(&self) -> Option<GradientGlowFilterObject<'gc>> {
None
}
/// Get the underlying `BitmapDataObject`, if it exists
fn as_bitmap_data_object(&self) -> Option<BitmapDataObject<'gc>> {
None

View File

@ -53,18 +53,14 @@ impl fmt::Debug for GradientBevelFilterObject<'_> {
impl<'gc> GradientBevelFilterObject<'gc> {
add_field_accessors!(
[set_angle, angle, angle, f64],
[set_blur_x, blur_x, blur_x, f64],
[set_blur_y, blur_y, blur_y, f64],
[set_distance, distance, distance, f64],
[set_knockout, knockout, knockout, bool],
[set_quality, quality, quality, i32],
[set_strength, strength, strength, f64],
[set_type, type_, type_, BevelFilterType],
);
//TODO: combine with above
add_field_accessors!(
[angle, f64, set => set_angle, get => angle],
[blur_x, f64, set => set_blur_x, get => blur_x],
[blur_y, f64, set => set_blur_y, get => blur_y],
[distance, f64, set => set_distance, get => distance],
[knockout, bool, set => set_knockout, get => knockout],
[quality, i32, set => set_quality, get => quality],
[strength, f64, set => set_strength, get => strength],
[type_, BevelFilterType, set => set_type, get => get_type],
[alphas, Vec<f64>, set => set_alphas],
[colors, Vec<u32>, set => set_colors],
[ratios, Vec<u8>, set => set_ratios],

View File

@ -0,0 +1,136 @@
use crate::add_field_accessors;
use crate::avm1::error::Error;
use crate::avm1::{Object, ScriptObject, TObject, Value};
use crate::impl_custom_object_without_set;
use gc_arena::{Collect, GcCell, MutationContext};
use crate::avm1::activation::Activation;
use crate::avm1::object::bevel_filter::BevelFilterType;
use std::fmt;
/// A GradientGlowFilter
#[derive(Clone, Copy, Collect)]
#[collect(no_drop)]
pub struct GradientGlowFilterObject<'gc>(GcCell<'gc, GradientGlowFilterData<'gc>>);
#[derive(Clone, Collect)]
#[collect(no_drop)]
pub struct GradientGlowFilterData<'gc> {
/// The underlying script object.
base: ScriptObject<'gc>,
alphas: Vec<f64>,
angle: f64,
blur_x: f64,
blur_y: f64,
colors: Vec<u32>,
distance: f64,
knockout: bool,
quality: i32,
ratios: Vec<u8>,
strength: f64,
type_: BevelFilterType,
}
impl fmt::Debug for GradientGlowFilterObject<'_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let this = self.0.read();
f.debug_struct("GradientGlowFilter")
.field("alphas", &this.alphas)
.field("angle", &this.angle)
.field("blurX", &this.blur_x)
.field("blurY", &this.blur_y)
.field("colors", &this.colors)
.field("distance", &this.distance)
.field("knockout", &this.knockout)
.field("quality", &this.quality)
.field("ratios", &this.ratios)
.field("strength", &this.strength)
.field("type_", &this.type_)
.finish()
}
}
impl<'gc> GradientGlowFilterObject<'gc> {
add_field_accessors!(
[angle, f64, set => set_angle, get => angle],
[blur_x, f64, set => set_blur_x, get => blur_x],
[blur_y, f64, set => set_blur_y, get => blur_y],
[distance, f64, set => set_distance, get => distance],
[knockout, bool, set => set_knockout, get => knockout],
[quality, i32, set => set_quality, get => quality],
[strength, f64, set => set_strength, get => strength],
[type_, BevelFilterType, set => set_type, get => get_type],
[alphas, Vec<f64>, set => set_alphas],
[colors, Vec<u32>, set => set_colors],
[ratios, Vec<u8>, set => set_ratios],
);
pub fn alphas(&self) -> Vec<f64> {
self.0.read().alphas.clone()
}
pub fn colors(&self) -> Vec<u32> {
self.0.read().colors.clone()
}
pub fn ratios(&self) -> Vec<u8> {
self.0.read().ratios.clone()
}
pub fn empty_object(gc_context: MutationContext<'gc, '_>, proto: Option<Object<'gc>>) -> Self {
GradientGlowFilterObject(GcCell::allocate(
gc_context,
GradientGlowFilterData {
base: ScriptObject::object(gc_context, proto),
alphas: vec![],
angle: 0.0,
blur_x: 0.0,
blur_y: 0.0,
colors: vec![],
distance: 0.0,
knockout: false,
quality: 0,
ratios: vec![],
strength: 0.0,
type_: BevelFilterType::Inner,
},
))
}
}
impl<'gc> TObject<'gc> for GradientGlowFilterObject<'gc> {
impl_custom_object_without_set!(base);
fn set(
&self,
name: &str,
value: Value<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
) -> Result<(), Error<'gc>> {
let base = self.0.read().base;
base.internal_set(
name,
value,
activation,
(*self).into(),
Some(activation.context.avm1.prototypes.gradient_glow_filter),
)
}
fn as_gradient_glow_filter_object(&self) -> Option<GradientGlowFilterObject<'gc>> {
Some(*self)
}
fn create_bare_object(
&self,
activation: &mut Activation<'_, 'gc, '_>,
_this: Object<'gc>,
) -> Result<Object<'gc>, Error<'gc>> {
Ok(GradientGlowFilterObject::empty_object(
activation.context.gc_context,
Some(activation.context.avm1.prototypes.gradient_glow_filter),
)
.into())
}
}

View File

@ -304,6 +304,7 @@ swf_tests! {
(displacement_map_filter, "avm1/displacement_map_filter", 1),
(convolution_filter, "avm1/convolution_filter", 1),
(gradient_bevel_filter, "avm1/gradient_bevel_filter", 1),
(gradient_glow_filter, "avm1/gradient_glow_filter", 1),
(bitmap_data, "avm1/bitmap_data", 1),
(array_call_method, "avm1/array_call_method", 1),
(as3_hello_world, "avm2/hello_world", 1),

View File

@ -0,0 +1,188 @@
// new GradientGlowFilter
[object Object]
// x.clone()
[object Object]
// x.clone() == x
false
// x.alphas
// x.angle
44.9999999772279
// x.blurX
4
// x.blurY
4
// x.colors
// x.distance
4
// x.knockout
false
// x.quality
1
// x.ratios
// x.strength
1
// x.type
inner
// x.alphas
// x.colors
// x.ratios
// x.alphas
0
// x.colors
0
// x.ratios
0
// x.alphas
1
// x.colors
1
// x.ratios
0
// x.alphas
1
// x.colors
1
// x.ratios
0
// x.alphas
// x.colors
// x.ratios
// x.alphas
1
// x.colors
65535
// x.ratios
1
// x.alphas
0.4
// x.colors
65535
// x.ratios
1
// x.alphas
0
// x.colors
65535
// x.ratios
1
// x.alphas
0.4
// x.colors
65535
// x.ratios
1
// x.alphas
0.4
// x.colors
65535
// x.ratios
1
// x.alphas
1
// x.colors
16777215
// x.ratios
255
// x.alphas
0
// x.colors
1
// x.ratios
0
// x.alphas (after set to null)
0.4
// x.colors (after set to null)
65535
// x.ratios (after set to null)
1
// x.angle (after set to 1000)
280
// x.blurX (after set to 1000)
255
// x.blurY (after set to 1000)
4
// x.distance (after set to 1000)
1000
// x.quality (after set to 1000)
15
// x.strength (after set to 1000)
255
// x.type (after set to null)
full
// x.angle (after set to -1000)
-280
// x.blurX (after set to -1000)
0
// x.blurY (after set to -1000)
4
// x.distance (after set to -1000)
-1000
// x.quality (after set to -1000)
0
// x.strength (after set to -1000)
0
// x.angle (after set to 1.5)
1.5
// x.blurX (after set to 1.5)
1.5
// x.blurY (after set to 1.5)
4
// x.distance (after set to 1.5)
1.5
// x.quality (after set to 1.5)
1
// x.strength (after set to 1.5)
0
// oob_over.alphas
// oob_over.angle
280
// oob_over.blurX
255
// oob_over.blurY
255
// oob_over.colors
// oob_over.distance
1000
// oob_over.knockout
false
// oob_over.quality
15
// oob_over.ratios
// oob_over.strength
255
// oob_over.type
full
// oob_under.alphas
// oob_under.angle
-280
// oob_under.blurX
0
// oob_under.blurY
0
// oob_under.colors
// oob_under.distance
-1000
// oob_under.knockout
false
// oob_under.quality
0
// oob_under.ratios
// oob_under.strength
0
// oob_under.type
full

Binary file not shown.

Binary file not shown.