render: Add Filter::DropShadowFilter

This commit is contained in:
Nathan Adams 2023-02-23 03:06:30 +01:00
parent dbe2efff00
commit c9656c429e
2 changed files with 134 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use ruffle_render::filters::{
BevelFilter, BevelFilterType, BlurFilter, ColorMatrixFilter, ConvolutionFilter,
DisplacementMapFilter, DisplacementMapFilterMode, Filter,
DisplacementMapFilter, DisplacementMapFilterMode, DropShadowFilter, Filter,
};
use swf::Color;
@ -49,6 +49,11 @@ impl FilterAvm2Ext for Filter {
return DisplacementMapFilter::from_avm2_object(activation, object);
}
let drop_shadow_filter = activation.avm2().classes().dropshadowfilter;
if object.is_of_type(drop_shadow_filter, activation) {
return DropShadowFilter::from_avm2_object(activation, object);
}
Err(Error::AvmError(type_error(
activation,
&format!(
@ -68,6 +73,7 @@ impl FilterAvm2Ext for Filter {
Filter::ColorMatrixFilter(filter) => filter.as_avm2_object(activation),
Filter::ConvolutionFilter(filter) => filter.as_avm2_object(activation),
Filter::DisplacementMapFilter(filter) => filter.as_avm2_object(activation),
Filter::DropShadowFilter(filter) => filter.as_avm2_object(activation),
}
}
}
@ -428,3 +434,78 @@ impl FilterAvm2Ext for DisplacementMapFilter {
)
}
}
impl FilterAvm2Ext for DropShadowFilter {
fn from_avm2_object<'gc>(
activation: &mut Activation<'_, 'gc>,
object: Object<'gc>,
) -> Result<Filter, Error<'gc>> {
let alpha = object
.get_public_property("alpha", activation)?
.coerce_to_number(activation)?;
let angle = object
.get_public_property("angle", activation)?
.coerce_to_number(activation)?;
let blur_x = object
.get_public_property("blurX", activation)?
.coerce_to_number(activation)?;
let blur_y = object
.get_public_property("blurY", activation)?
.coerce_to_number(activation)?;
let color = object
.get_public_property("color", activation)?
.coerce_to_u32(activation)?;
let distance = object
.get_public_property("distance", activation)?
.coerce_to_number(activation)?;
let hide_object = object
.get_public_property("hideObject", activation)?
.coerce_to_boolean();
let inner = object
.get_public_property("inner", activation)?
.coerce_to_boolean();
let knockout = object
.get_public_property("knockout", activation)?
.coerce_to_boolean();
let quality = object
.get_public_property("quality", activation)?
.coerce_to_u32(activation)?;
let strength = object
.get_public_property("strength", activation)?
.coerce_to_u32(activation)?;
Ok(Filter::DropShadowFilter(DropShadowFilter {
color: Color::from_rgb(color, (alpha * 255.0) as u8),
angle: angle as f32,
blur_x: blur_x as f32,
blur_y: blur_y as f32,
distance: distance as f32,
hide_object,
inner,
knockout,
strength: strength.clamp(0, 255) as u8,
quality: quality.clamp(1, 15) as u8,
}))
}
fn as_avm2_object<'gc>(
&self,
activation: &mut Activation<'_, 'gc>,
) -> Result<Object<'gc>, Error<'gc>> {
activation.avm2().classes().dropshadowfilter.construct(
activation,
&[
self.distance.into(),
self.angle.into(),
self.color.to_rgb().into(),
(f64::from(self.color.a) / 255.0).into(),
self.blur_x.into(),
self.blur_y.into(),
self.strength.into(),
self.quality.into(),
self.inner.into(),
self.knockout.into(),
self.hide_object.into(),
],
)
}
}

View File

@ -8,6 +8,7 @@ pub enum Filter {
ColorMatrixFilter(ColorMatrixFilter),
ConvolutionFilter(ConvolutionFilter),
DisplacementMapFilter(DisplacementMapFilter),
DropShadowFilter(DropShadowFilter),
}
impl Default for Filter {
@ -219,3 +220,54 @@ impl Default for DisplacementMapFilter {
}
}
}
#[derive(Debug, Clone)]
pub struct DropShadowFilter {
pub color: Color,
pub angle: f32,
pub blur_x: f32,
pub blur_y: f32,
pub distance: f32,
pub hide_object: bool,
pub inner: bool,
pub knockout: bool,
pub quality: u8,
pub strength: u8,
}
impl From<swf::DropShadowFilter> for DropShadowFilter {
fn from(value: swf::DropShadowFilter) -> Self {
let inner = value.is_inner();
let knockout = value.is_knockout();
let quality = value.num_passes();
DropShadowFilter {
color: value.color,
angle: value.angle.to_f32(),
blur_x: value.blur_x.to_f32(),
blur_y: value.blur_y.to_f32(),
distance: value.distance.to_f32(),
hide_object: false,
inner,
knockout,
quality,
strength: (value.strength.to_f32() * 255.0) as u8,
}
}
}
impl Default for DropShadowFilter {
fn default() -> Self {
Self {
color: Color::from_rgba(0),
angle: 45.0,
blur_x: 4.0,
blur_y: 4.0,
distance: 4.0,
hide_object: false,
inner: false,
knockout: false,
quality: 1,
strength: 1,
}
}
}