avm1: Implement blur filter conversions

This commit is contained in:
Nathan Adams 2023-06-30 19:41:01 +02:00
parent 73bc637ad7
commit b3629669bd
5 changed files with 54 additions and 0 deletions

View File

@ -3,6 +3,7 @@
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::globals::bevel_filter::BevelFilter;
use crate::avm1::globals::blur_filter::BlurFilter;
use crate::avm1::object::NativeObject;
use crate::avm1::property_decl::{define_properties_on, Declaration};
use crate::avm1::{Attribute, Object, ScriptObject, TObject, Value};
@ -68,6 +69,7 @@ pub fn avm1_to_filter(object: Object) -> Option<Filter> {
let native = object.native();
match native {
NativeObject::BevelFilter(filter) => Some(Filter::BevelFilter(filter.filter())),
NativeObject::BlurFilter(filter) => Some(Filter::BlurFilter(filter.filter())),
// Invalid filters are silently dropped/ignored, no errors are thrown.
_ => None,
@ -83,6 +85,13 @@ pub fn filter_to_avm1<'gc>(activation: &mut Activation<'_, 'gc>, filter: Filter)
)),
activation.context.avm1.prototypes().bevel_filter,
),
Filter::BlurFilter(filter) => (
NativeObject::BlurFilter(BlurFilter::from_filter(
activation.context.gc_context,
filter,
)),
activation.context.avm1.prototypes().blur_filter,
),
_ => {
// Unrepresentable filters (eg Shader) will just return as Null.
// Not sure there's a way to even get to that state though, they can only be added in avm2.

View File

@ -6,6 +6,8 @@ use crate::avm1::property_decl::{define_properties_on, Declaration};
use crate::avm1::{Activation, Error, Object, ScriptObject, TObject, Value};
use crate::context::GcContext;
use gc_arena::{Collect, GcCell, MutationContext};
use std::ops::Deref;
use swf::{BlurFilterFlags, Fixed16};
#[derive(Clone, Debug, Collect)]
#[collect(require_static)]
@ -25,6 +27,26 @@ impl Default for BlurFilterData {
}
}
impl From<&BlurFilterData> for swf::BlurFilter {
fn from(filter: &BlurFilterData) -> swf::BlurFilter {
swf::BlurFilter {
blur_x: Fixed16::from_f64(filter.blur_x),
blur_y: Fixed16::from_f64(filter.blur_y),
flags: BlurFilterFlags::from_passes(filter.quality as u8),
}
}
}
impl From<swf::BlurFilter> for BlurFilterData {
fn from(filter: swf::BlurFilter) -> BlurFilterData {
Self {
quality: filter.num_passes().into(),
blur_x: filter.blur_x.into(),
blur_y: filter.blur_y.into(),
}
}
}
#[derive(Clone, Debug, Collect)]
#[collect(no_drop)]
#[repr(transparent)]
@ -42,6 +64,10 @@ impl<'gc> BlurFilter<'gc> {
Ok(blur_filter)
}
pub fn from_filter(gc_context: MutationContext<'gc, '_>, filter: swf::BlurFilter) -> Self {
Self(GcCell::allocate(gc_context, filter.into()))
}
pub(crate) fn duplicate(&self, gc_context: MutationContext<'gc, '_>) -> Self {
Self(GcCell::allocate(gc_context, self.0.read().clone()))
}
@ -93,6 +119,10 @@ impl<'gc> BlurFilter<'gc> {
}
Ok(())
}
pub fn filter(&self) -> swf::BlurFilter {
self.0.read().deref().into()
}
}
macro_rules! blur_filter_method {

View File

@ -1,3 +1,10 @@
test.filters[0].quality
2
test.filters[0].blurX
9
test.filters[0].blurY
9
// new BlurFilter
[object Object]
// x.clone()
@ -10,6 +17,14 @@ false
4
// x.quality
1
// test.filters = [x]
test.filters[0].quality
1
test.filters[0].blurX
4
test.filters[0].blurY
4
// x.quality(after set to 100)
15
// x.blurX(after set to 100)