core: Add flash.filters.GradientGlowFilter
This commit is contained in:
parent
0cab167e4c
commit
01557fba5a
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
|
@ -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),
|
||||
|
|
|
@ -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.
Loading…
Reference in New Issue