avm1: Migrate `DropShadowFilter` to `NativeObject`
This commit is contained in:
parent
814cb00821
commit
3dcf246870
|
@ -27,7 +27,7 @@ pub(crate) mod context_menu_item;
|
|||
pub mod convolution_filter;
|
||||
pub(crate) mod date;
|
||||
pub mod displacement_map_filter;
|
||||
pub mod drop_shadow_filter;
|
||||
pub(crate) mod drop_shadow_filter;
|
||||
pub(crate) mod error;
|
||||
mod external_interface;
|
||||
mod function;
|
||||
|
@ -499,8 +499,6 @@ pub struct SystemPrototypes<'gc> {
|
|||
pub context_menu_item_constructor: Object<'gc>,
|
||||
pub bitmap_filter: Object<'gc>,
|
||||
pub bitmap_filter_constructor: Object<'gc>,
|
||||
pub drop_shadow_filter: Object<'gc>,
|
||||
pub drop_shadow_filter_constructor: Object<'gc>,
|
||||
pub color_matrix_filter: Object<'gc>,
|
||||
pub color_matrix_filter_constructor: Object<'gc>,
|
||||
pub displacement_map_filter: Object<'gc>,
|
||||
|
@ -759,15 +757,8 @@ pub fn create_globals<'gc>(
|
|||
let glow_filter =
|
||||
glow_filter::create_constructor(gc_context, bitmap_filter_proto, function_proto);
|
||||
|
||||
let drop_shadow_filter_proto =
|
||||
drop_shadow_filter::create_proto(gc_context, bitmap_filter_proto, function_proto);
|
||||
let drop_shadow_filter = FunctionObject::constructor(
|
||||
gc_context,
|
||||
Executable::Native(drop_shadow_filter::constructor),
|
||||
constructor_to_fn!(drop_shadow_filter::constructor),
|
||||
function_proto,
|
||||
drop_shadow_filter_proto,
|
||||
);
|
||||
let drop_shadow_filter =
|
||||
drop_shadow_filter::create_constructor(gc_context, bitmap_filter_proto, function_proto);
|
||||
|
||||
let color_matrix_filter_proto =
|
||||
color_matrix_filter::create_proto(gc_context, bitmap_filter_proto, function_proto);
|
||||
|
@ -1139,8 +1130,6 @@ pub fn create_globals<'gc>(
|
|||
context_menu_item_constructor: context_menu_item,
|
||||
bitmap_filter: bitmap_filter_proto,
|
||||
bitmap_filter_constructor: bitmap_filter,
|
||||
drop_shadow_filter: drop_shadow_filter_proto,
|
||||
drop_shadow_filter_constructor: drop_shadow_filter,
|
||||
color_matrix_filter: color_matrix_filter_proto,
|
||||
color_matrix_filter_constructor: color_matrix_filter,
|
||||
displacement_map_filter: displacement_map_filter_proto,
|
||||
|
|
|
@ -34,6 +34,9 @@ pub fn clone<'gc>(
|
|||
NativeObject::GlowFilter(glow_filter) => {
|
||||
NativeObject::GlowFilter(glow_filter.duplicate(activation.context.gc_context))
|
||||
}
|
||||
NativeObject::DropShadowFilter(drop_shadow_filter) => NativeObject::DropShadowFilter(
|
||||
drop_shadow_filter.duplicate(activation.context.gc_context),
|
||||
),
|
||||
_ => NativeObject::None,
|
||||
};
|
||||
if !matches!(native, NativeObject::None) {
|
||||
|
@ -53,44 +56,6 @@ pub fn clone<'gc>(
|
|||
return Ok(cloned.into());
|
||||
}
|
||||
|
||||
if let Some(this) = this.as_drop_shadow_filter_object() {
|
||||
let proto = activation
|
||||
.context
|
||||
.avm1
|
||||
.prototypes()
|
||||
.drop_shadow_filter_constructor;
|
||||
|
||||
let distance = this.get("distance", activation)?;
|
||||
let angle = this.get("angle", activation)?;
|
||||
let color = this.get("color", activation)?;
|
||||
let alpha = this.get("alpha", 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 inner = this.get("inner", activation)?;
|
||||
let knockout = this.get("knockout", activation)?;
|
||||
let hide_object = this.get("hide_object", activation)?;
|
||||
|
||||
let cloned = proto.construct(
|
||||
activation,
|
||||
&[
|
||||
distance,
|
||||
angle,
|
||||
color,
|
||||
alpha,
|
||||
blur_x,
|
||||
blur_y,
|
||||
strength,
|
||||
quality,
|
||||
inner,
|
||||
knockout,
|
||||
hide_object,
|
||||
],
|
||||
)?;
|
||||
return Ok(cloned);
|
||||
}
|
||||
|
||||
if let Some(this) = this.as_color_matrix_filter_object() {
|
||||
let proto = activation
|
||||
.context
|
||||
|
|
|
@ -1,381 +1,389 @@
|
|||
//! flash.filters.DropShadowFilter object
|
||||
|
||||
use crate::avm1::activation::Activation;
|
||||
use crate::avm1::clamp::Clamp;
|
||||
use crate::avm1::error::Error;
|
||||
use crate::avm1::object::drop_shadow_filter::DropShadowFilterObject;
|
||||
use crate::avm1::function::{Executable, FunctionObject};
|
||||
use crate::avm1::object::NativeObject;
|
||||
use crate::avm1::property_decl::{define_properties_on, Declaration};
|
||||
use crate::avm1::{Object, TObject, Value};
|
||||
use gc_arena::MutationContext;
|
||||
use crate::avm1::{Activation, Error, Object, ScriptObject, TObject, Value};
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
use swf::Color;
|
||||
|
||||
#[derive(Clone, Debug, Collect)]
|
||||
#[collect(require_static)]
|
||||
struct DropShadowFilterData {
|
||||
distance: f64,
|
||||
// TODO: Introduce `Angle<Radians>` struct.
|
||||
angle: f64,
|
||||
color: Color,
|
||||
quality: i32,
|
||||
inner: bool,
|
||||
knockout: bool,
|
||||
blur_x: f64,
|
||||
blur_y: f64,
|
||||
// TODO: Introduce unsigned `Fixed8`?
|
||||
strength: u16,
|
||||
hide_object: bool,
|
||||
}
|
||||
|
||||
impl Default for DropShadowFilterData {
|
||||
#[allow(clippy::approx_constant)]
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
distance: 4.0,
|
||||
angle: 0.785398163, // ~45 degrees
|
||||
color: Color::BLACK,
|
||||
quality: 1,
|
||||
inner: false,
|
||||
knockout: false,
|
||||
blur_x: 4.0,
|
||||
blur_y: 4.0,
|
||||
strength: 1 << 8,
|
||||
hide_object: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Collect)]
|
||||
#[collect(no_drop)]
|
||||
#[repr(transparent)]
|
||||
pub struct DropShadowFilter<'gc>(GcCell<'gc, DropShadowFilterData>);
|
||||
|
||||
impl<'gc> DropShadowFilter<'gc> {
|
||||
fn new(activation: &mut Activation<'_, 'gc>, args: &[Value<'gc>]) -> Result<Self, Error<'gc>> {
|
||||
let drop_shadow_filter = Self(GcCell::allocate(
|
||||
activation.context.gc_context,
|
||||
Default::default(),
|
||||
));
|
||||
drop_shadow_filter.set_distance(activation, args.get(0))?;
|
||||
drop_shadow_filter.set_angle(activation, args.get(1))?;
|
||||
drop_shadow_filter.set_color(activation, args.get(2))?;
|
||||
drop_shadow_filter.set_alpha(activation, args.get(3))?;
|
||||
drop_shadow_filter.set_blur_x(activation, args.get(4))?;
|
||||
drop_shadow_filter.set_blur_y(activation, args.get(5))?;
|
||||
drop_shadow_filter.set_strength(activation, args.get(6))?;
|
||||
drop_shadow_filter.set_quality(activation, args.get(7))?;
|
||||
drop_shadow_filter.set_inner(activation, args.get(8))?;
|
||||
drop_shadow_filter.set_knockout(activation, args.get(9))?;
|
||||
drop_shadow_filter.set_hide_object(activation, args.get(10))?;
|
||||
Ok(drop_shadow_filter)
|
||||
}
|
||||
|
||||
pub(crate) fn duplicate(&self, gc_context: MutationContext<'gc, '_>) -> Self {
|
||||
Self(GcCell::allocate(gc_context, self.0.read().clone()))
|
||||
}
|
||||
|
||||
fn distance(&self) -> f64 {
|
||||
self.0.read().distance
|
||||
}
|
||||
|
||||
fn set_distance(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let distance = value.coerce_to_f64(activation)?;
|
||||
self.0.write(activation.context.gc_context).distance = distance;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn angle(&self) -> f64 {
|
||||
self.0.read().angle.to_degrees()
|
||||
}
|
||||
|
||||
fn set_angle(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let angle = (value.coerce_to_f64(activation)? % 360.0).to_radians();
|
||||
self.0.write(activation.context.gc_context).angle = angle;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn color(&self) -> i32 {
|
||||
self.0.read().color.to_rgb() as i32
|
||||
}
|
||||
|
||||
fn set_color(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let color = Color::from_rgb(value.coerce_to_u32(activation)?, 0);
|
||||
self.0.write(activation.context.gc_context).color = color;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn alpha(&self) -> f64 {
|
||||
f64::from(self.0.read().color.a) / 255.0
|
||||
}
|
||||
|
||||
fn set_alpha(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let alpha = (value.coerce_to_f64(activation)? * 255.0) as u8;
|
||||
self.0.write(activation.context.gc_context).color.a = alpha;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn quality(&self) -> i32 {
|
||||
self.0.read().quality
|
||||
}
|
||||
|
||||
fn set_quality(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let quality = value.coerce_to_i32(activation)?.clamp(0, 15);
|
||||
self.0.write(activation.context.gc_context).quality = quality;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inner(&self) -> bool {
|
||||
self.0.read().inner
|
||||
}
|
||||
|
||||
fn set_inner(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let inner = value.as_bool(activation.swf_version());
|
||||
self.0.write(activation.context.gc_context).inner = inner;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn knockout(&self) -> bool {
|
||||
self.0.read().knockout
|
||||
}
|
||||
|
||||
fn set_knockout(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let knockout = value.as_bool(activation.swf_version());
|
||||
self.0.write(activation.context.gc_context).knockout = knockout;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn blur_x(&self) -> f64 {
|
||||
self.0.read().blur_x
|
||||
}
|
||||
|
||||
fn set_blur_x(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let blur_x = value.coerce_to_f64(activation)?.clamp(0.0, 255.0);
|
||||
self.0.write(activation.context.gc_context).blur_x = blur_x;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn blur_y(&self) -> f64 {
|
||||
self.0.read().blur_y
|
||||
}
|
||||
|
||||
fn set_blur_y(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let blur_y = value.coerce_to_f64(activation)?.clamp(0.0, 255.0);
|
||||
self.0.write(activation.context.gc_context).blur_y = blur_y;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn strength(&self) -> f64 {
|
||||
f64::from(self.0.read().strength) / 256.0
|
||||
}
|
||||
|
||||
fn set_strength(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let strength = ((value.coerce_to_f64(activation)? * 256.0) as u16).clamp(0, 0xFF00);
|
||||
self.0.write(activation.context.gc_context).strength = strength;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn hide_object(&self) -> bool {
|
||||
self.0.read().hide_object
|
||||
}
|
||||
|
||||
fn set_hide_object(
|
||||
&self,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
value: Option<&Value<'gc>>,
|
||||
) -> Result<(), Error<'gc>> {
|
||||
if let Some(value) = value {
|
||||
let hide_object = value.as_bool(activation.swf_version());
|
||||
self.0.write(activation.context.gc_context).hide_object = hide_object;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! drop_shadow_filter_method {
|
||||
($index:literal) => {
|
||||
|activation, this, args| method(activation, this, args, $index)
|
||||
};
|
||||
}
|
||||
|
||||
const PROTO_DECLS: &[Declaration] = declare_properties! {
|
||||
"alpha" => property(alpha, set_alpha);
|
||||
"angle" => property(angle, set_angle);
|
||||
"blurX" => property(blur_x, set_blur_x);
|
||||
"blurY" => property(blur_y, set_blur_y);
|
||||
"color" => property(color, set_color);
|
||||
"distance" => property(distance, set_distance);
|
||||
"hideObject" => property(hide_object, set_hide_object);
|
||||
"inner" => property(inner, set_inner);
|
||||
"knockout" => property(knockout, set_knockout);
|
||||
"quality" => property(quality, set_quality);
|
||||
"strength" => property(strength, set_strength);
|
||||
"distance" => property(drop_shadow_filter_method!(1), drop_shadow_filter_method!(2); VERSION_8);
|
||||
"angle" => property(drop_shadow_filter_method!(3), drop_shadow_filter_method!(4); VERSION_8);
|
||||
"color" => property(drop_shadow_filter_method!(5), drop_shadow_filter_method!(6); VERSION_8);
|
||||
"alpha" => property(drop_shadow_filter_method!(7), drop_shadow_filter_method!(8); VERSION_8);
|
||||
"quality" => property(drop_shadow_filter_method!(9), drop_shadow_filter_method!(10); VERSION_8);
|
||||
"inner" => property(drop_shadow_filter_method!(11), drop_shadow_filter_method!(12); VERSION_8);
|
||||
"knockout" => property(drop_shadow_filter_method!(13), drop_shadow_filter_method!(14); VERSION_8);
|
||||
"blurX" => property(drop_shadow_filter_method!(15), drop_shadow_filter_method!(16); VERSION_8);
|
||||
"blurY" => property(drop_shadow_filter_method!(17), drop_shadow_filter_method!(18); VERSION_8);
|
||||
"strength" => property(drop_shadow_filter_method!(19), drop_shadow_filter_method!(20); VERSION_8);
|
||||
"hideObject" => property(drop_shadow_filter_method!(21), drop_shadow_filter_method!(22); VERSION_8);
|
||||
};
|
||||
|
||||
pub fn constructor<'gc>(
|
||||
fn method<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
index: u8,
|
||||
) -> 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_color(activation, this, args.get(2..3).unwrap_or_default())?;
|
||||
set_alpha(activation, this, args.get(3..4).unwrap_or_default())?;
|
||||
set_blur_x(activation, this, args.get(4..5).unwrap_or_default())?;
|
||||
set_blur_y(activation, this, args.get(5..6).unwrap_or_default())?;
|
||||
set_strength(activation, this, args.get(6..7).unwrap_or_default())?;
|
||||
set_quality(activation, this, args.get(7..8).unwrap_or_default())?;
|
||||
set_inner(activation, this, args.get(8..9).unwrap_or_default())?;
|
||||
set_knockout(activation, this, args.get(9..10).unwrap_or_default())?;
|
||||
set_hide_object(activation, this, args.get(10..11).unwrap_or_default())?;
|
||||
const CONSTRUCTOR: u8 = 0;
|
||||
const GET_DISTANCE: u8 = 1;
|
||||
const SET_DISTANCE: u8 = 2;
|
||||
const GET_ANGLE: u8 = 3;
|
||||
const SET_ANGLE: u8 = 4;
|
||||
const GET_COLOR: u8 = 5;
|
||||
const SET_COLOR: u8 = 6;
|
||||
const GET_ALPHA: u8 = 7;
|
||||
const SET_ALPHA: u8 = 8;
|
||||
const GET_QUALITY: u8 = 9;
|
||||
const SET_QUALITY: u8 = 10;
|
||||
const GET_INNER: u8 = 11;
|
||||
const SET_INNER: u8 = 12;
|
||||
const GET_KNOCKOUT: u8 = 13;
|
||||
const SET_KNOCKOUT: u8 = 14;
|
||||
const GET_BLUR_X: u8 = 15;
|
||||
const SET_BLUR_X: u8 = 16;
|
||||
const GET_BLUR_Y: u8 = 17;
|
||||
const SET_BLUR_Y: u8 = 18;
|
||||
const GET_STRENGTH: u8 = 19;
|
||||
const SET_STRENGTH: u8 = 20;
|
||||
const GET_HIDE_OBJECT: u8 = 21;
|
||||
const SET_HIDE_OBJECT: u8 = 22;
|
||||
|
||||
Ok(this.into())
|
||||
}
|
||||
|
||||
pub fn alpha<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
return Ok(object.alpha().into());
|
||||
if index == CONSTRUCTOR {
|
||||
let drop_shadow_filter = DropShadowFilter::new(activation, args)?;
|
||||
this.set_native(
|
||||
activation.context.gc_context,
|
||||
NativeObject::DropShadowFilter(drop_shadow_filter),
|
||||
);
|
||||
return Ok(this.into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn set_alpha<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let alpha = args
|
||||
.get(0)
|
||||
.unwrap_or(&1.into())
|
||||
.coerce_to_f64(activation)
|
||||
.map(|x| x.clamp_also_nan(0.0, 1.0))?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_alpha(activation.context.gc_context, alpha);
|
||||
}
|
||||
|
||||
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_drop_shadow_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.into()).coerce_to_f64(activation)?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_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_drop_shadow_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
|
||||
let this = match this.native() {
|
||||
NativeObject::DropShadowFilter(drop_shadow_filter) => drop_shadow_filter,
|
||||
_ => return Ok(Value::Undefined),
|
||||
};
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_angle(activation.context.gc_context, clamped_angle);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
Ok(match index {
|
||||
GET_DISTANCE => this.distance().into(),
|
||||
SET_DISTANCE => {
|
||||
this.set_distance(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_ANGLE => this.angle().into(),
|
||||
SET_ANGLE => {
|
||||
this.set_angle(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_COLOR => this.color().into(),
|
||||
SET_COLOR => {
|
||||
this.set_color(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_ALPHA => this.alpha().into(),
|
||||
SET_ALPHA => {
|
||||
this.set_alpha(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_QUALITY => this.quality().into(),
|
||||
SET_QUALITY => {
|
||||
this.set_quality(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_INNER => this.inner().into(),
|
||||
SET_INNER => {
|
||||
this.set_inner(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_KNOCKOUT => this.knockout().into(),
|
||||
SET_KNOCKOUT => {
|
||||
this.set_knockout(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_BLUR_X => this.blur_x().into(),
|
||||
SET_BLUR_X => {
|
||||
this.set_blur_x(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_BLUR_Y => this.blur_y().into(),
|
||||
SET_BLUR_Y => {
|
||||
this.set_blur_y(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_STRENGTH => this.strength().into(),
|
||||
SET_STRENGTH => {
|
||||
this.set_strength(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
GET_HIDE_OBJECT => this.hide_object().into(),
|
||||
SET_HIDE_OBJECT => {
|
||||
this.set_hide_object(activation, args.get(0))?;
|
||||
Value::Undefined
|
||||
}
|
||||
_ => 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_drop_shadow_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.into())
|
||||
.coerce_to_f64(activation)
|
||||
.map(|x| x.clamp(0.0, 255.0))?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_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_drop_shadow_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.into())
|
||||
.coerce_to_f64(activation)
|
||||
.map(|x| x.clamp(0.0, 255.0))?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_blur_y(activation.context.gc_context, blur_y);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn color<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
return Ok(object.color().into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn set_color<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let color = args
|
||||
.get(0)
|
||||
.unwrap_or(&0x000000.into())
|
||||
.coerce_to_u32(activation)?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_color(activation.context.gc_context, color & 0xFFFFFF);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn hide_object<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
return Ok(object.hide_object().into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn set_hide_object<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let hide_object = args
|
||||
.get(0)
|
||||
.unwrap_or(&false.into())
|
||||
.as_bool(activation.swf_version());
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_hide_object(activation.context.gc_context, hide_object);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn inner<'gc>(
|
||||
_activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
_args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
return Ok(object.inner().into());
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn set_inner<'gc>(
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
this: Object<'gc>,
|
||||
args: &[Value<'gc>],
|
||||
) -> Result<Value<'gc>, Error<'gc>> {
|
||||
let inner = args
|
||||
.get(0)
|
||||
.unwrap_or(&false.into())
|
||||
.as_bool(activation.swf_version());
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_inner(activation.context.gc_context, inner);
|
||||
}
|
||||
|
||||
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_drop_shadow_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.swf_version());
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_knockout(activation.context.gc_context, knockout);
|
||||
}
|
||||
|
||||
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_drop_shadow_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.into())
|
||||
.coerce_to_i32(activation)
|
||||
.map(|x| x.clamp(0, 15))?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_quality(activation.context.gc_context, quality);
|
||||
}
|
||||
|
||||
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_drop_shadow_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.into())
|
||||
.coerce_to_f64(activation)
|
||||
.map(|x| x.clamp_also_nan(0.0, 255.0))?;
|
||||
|
||||
if let Some(object) = this.as_drop_shadow_filter_object() {
|
||||
object.set_strength(activation.context.gc_context, strength);
|
||||
}
|
||||
|
||||
Ok(Value::Undefined)
|
||||
}
|
||||
|
||||
pub fn create_proto<'gc>(
|
||||
pub fn create_constructor<'gc>(
|
||||
gc_context: MutationContext<'gc, '_>,
|
||||
proto: Object<'gc>,
|
||||
fn_proto: Object<'gc>,
|
||||
) -> Object<'gc> {
|
||||
let drop_shadow_filter = DropShadowFilterObject::empty_object(gc_context, proto);
|
||||
let object = drop_shadow_filter.raw_script_object();
|
||||
define_properties_on(PROTO_DECLS, gc_context, object, fn_proto);
|
||||
drop_shadow_filter.into()
|
||||
let drop_shadow_filter_proto = ScriptObject::new(gc_context, Some(proto));
|
||||
define_properties_on(PROTO_DECLS, gc_context, drop_shadow_filter_proto, fn_proto);
|
||||
FunctionObject::constructor(
|
||||
gc_context,
|
||||
Executable::Native(drop_shadow_filter_method!(0)),
|
||||
constructor_to_fn!(drop_shadow_filter_method!(0)),
|
||||
fn_proto,
|
||||
drop_shadow_filter_proto.into(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@ use crate::avm1::globals::bevel_filter::BevelFilter;
|
|||
use crate::avm1::globals::blur_filter::BlurFilter;
|
||||
use crate::avm1::globals::color_transform::ColorTransformObject;
|
||||
use crate::avm1::globals::date::Date;
|
||||
use crate::avm1::globals::drop_shadow_filter::DropShadowFilter;
|
||||
use crate::avm1::globals::glow_filter::GlowFilter;
|
||||
use crate::avm1::object::array_object::ArrayObject;
|
||||
use crate::avm1::object::bitmap_data::BitmapDataObject;
|
||||
use crate::avm1::object::color_matrix_filter::ColorMatrixFilterObject;
|
||||
use crate::avm1::object::convolution_filter::ConvolutionFilterObject;
|
||||
use crate::avm1::object::displacement_map_filter::DisplacementMapFilterObject;
|
||||
use crate::avm1::object::drop_shadow_filter::DropShadowFilterObject;
|
||||
use crate::avm1::object::gradient_bevel_filter::GradientBevelFilterObject;
|
||||
use crate::avm1::object::gradient_glow_filter::GradientGlowFilterObject;
|
||||
use crate::avm1::object::shared_object::SharedObject;
|
||||
|
@ -37,7 +37,6 @@ pub mod color_matrix_filter;
|
|||
pub mod convolution_filter;
|
||||
mod custom_object;
|
||||
pub mod displacement_map_filter;
|
||||
pub mod drop_shadow_filter;
|
||||
pub mod gradient_bevel_filter;
|
||||
pub mod gradient_glow_filter;
|
||||
pub mod script_object;
|
||||
|
@ -58,6 +57,7 @@ pub enum NativeObject<'gc> {
|
|||
BlurFilter(BlurFilter<'gc>),
|
||||
BevelFilter(BevelFilter<'gc>),
|
||||
GlowFilter(GlowFilter<'gc>),
|
||||
DropShadowFilter(DropShadowFilter<'gc>),
|
||||
ColorTransform(GcCell<'gc, ColorTransformObject>),
|
||||
TextFormat(GcCell<'gc, TextFormat>),
|
||||
NetStream(NetStream<'gc>),
|
||||
|
@ -81,7 +81,6 @@ pub enum NativeObject<'gc> {
|
|||
FunctionObject(FunctionObject<'gc>),
|
||||
SharedObject(SharedObject<'gc>),
|
||||
TransformObject(TransformObject<'gc>),
|
||||
DropShadowFilterObject(DropShadowFilterObject<'gc>),
|
||||
ColorMatrixFilterObject(ColorMatrixFilterObject<'gc>),
|
||||
DisplacementMapFilterObject(DisplacementMapFilterObject<'gc>),
|
||||
ConvolutionFilterObject(ConvolutionFilterObject<'gc>),
|
||||
|
@ -609,11 +608,6 @@ pub trait TObject<'gc>: 'gc + Collect + Into<Object<'gc>> + Clone + Copy {
|
|||
None
|
||||
}
|
||||
|
||||
/// Get the underlying `DropShadowFilterObject`, if it exists
|
||||
fn as_drop_shadow_filter_object(&self) -> Option<DropShadowFilterObject<'gc>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Get the underlying `ColorMatrixFilterObject`, if it exists
|
||||
fn as_color_matrix_filter_object(&self) -> Option<ColorMatrixFilterObject<'gc>> {
|
||||
None
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
use crate::add_field_accessors;
|
||||
use crate::avm1::{Object, ScriptObject, TObject};
|
||||
use crate::impl_custom_object;
|
||||
use gc_arena::{Collect, GcCell, MutationContext};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// A DropShadowFilter
|
||||
#[derive(Clone, Copy, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct DropShadowFilterObject<'gc>(GcCell<'gc, DropShadowFilterData<'gc>>);
|
||||
|
||||
#[derive(Clone, Collect)]
|
||||
#[collect(no_drop)]
|
||||
pub struct DropShadowFilterData<'gc> {
|
||||
/// The underlying script object.
|
||||
base: ScriptObject<'gc>,
|
||||
|
||||
alpha: f64,
|
||||
angle: f64,
|
||||
blur_x: f64,
|
||||
blur_y: f64,
|
||||
color: u32,
|
||||
distance: f64,
|
||||
hide_object: bool,
|
||||
inner: bool,
|
||||
knockout: bool,
|
||||
quality: i32,
|
||||
strength: f64,
|
||||
}
|
||||
|
||||
impl fmt::Debug for DropShadowFilterObject<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let this = self.0.read();
|
||||
f.debug_struct("DropShadowFilter")
|
||||
.field("alpha", &this.alpha)
|
||||
.field("angle", &this.angle)
|
||||
.field("blurX", &this.blur_x)
|
||||
.field("blurY", &this.blur_y)
|
||||
.field("color", &this.color)
|
||||
.field("distance", &this.distance)
|
||||
.field("hide_object", &this.hide_object)
|
||||
.field("inner", &this.inner)
|
||||
.field("knockout", &this.knockout)
|
||||
.field("quality", &this.quality)
|
||||
.field("strength", &this.strength)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> DropShadowFilterObject<'gc> {
|
||||
add_field_accessors!(
|
||||
[set_alpha, alpha, alpha, f64],
|
||||
[set_angle, angle, angle, f64],
|
||||
[set_blur_x, blur_x, blur_x, f64],
|
||||
[set_blur_y, blur_y, blur_y, f64],
|
||||
[set_color, color, color, u32],
|
||||
[set_hide_object, hide_object, hide_object, bool],
|
||||
[set_distance, distance, distance, f64],
|
||||
[set_inner, inner, inner, bool],
|
||||
[set_knockout, knockout, knockout, bool],
|
||||
[set_quality, quality, quality, i32],
|
||||
[set_strength, strength, strength, f64],
|
||||
);
|
||||
|
||||
pub fn empty_object(gc_context: MutationContext<'gc, '_>, proto: Object<'gc>) -> Self {
|
||||
DropShadowFilterObject(GcCell::allocate(
|
||||
gc_context,
|
||||
DropShadowFilterData {
|
||||
base: ScriptObject::new(gc_context, Some(proto)),
|
||||
distance: 4.0,
|
||||
hide_object: false,
|
||||
angle: 44.9999999772279,
|
||||
color: 0x000000,
|
||||
alpha: 1.0,
|
||||
blur_x: 4.0,
|
||||
blur_y: 4.0,
|
||||
strength: 1.0,
|
||||
quality: 1,
|
||||
inner: false,
|
||||
knockout: false,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for DropShadowFilterObject<'gc> {
|
||||
impl_custom_object!(base {
|
||||
bare_object(as_drop_shadow_filter_object -> DropShadowFilterObject::empty_object);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue