avm2: Wire up DisplayObject.blendMode

This commit is contained in:
Mike Welsh 2022-08-18 12:34:41 -07:00
parent bca9b596b9
commit b450b99e3e
1 changed files with 19 additions and 36 deletions

View File

@ -10,9 +10,11 @@ use crate::avm2::Error;
use crate::avm2::Namespace; use crate::avm2::Namespace;
use crate::avm2::QName; use crate::avm2::QName;
use crate::display_object::{HitTestOptions, TDisplayObject}; use crate::display_object::{HitTestOptions, TDisplayObject};
use crate::string::AvmString;
use crate::types::{Degrees, Percent}; use crate::types::{Degrees, Percent};
use crate::vminterface::Instantiator; use crate::vminterface::Instantiator;
use gc_arena::{GcCell, MutationContext}; use gc_arena::{GcCell, MutationContext};
use std::str::FromStr;
use swf::BlendMode; use swf::BlendMode;
use swf::Twips; use swf::Twips;
@ -645,10 +647,15 @@ pub fn set_transform<'gc>(
/// Implements `DisplayObject.blendMode`'s getter. /// Implements `DisplayObject.blendMode`'s getter.
pub fn blend_mode<'gc>( pub fn blend_mode<'gc>(
_activation: &mut Activation<'_, 'gc, '_>, activation: &mut Activation<'_, 'gc, '_>,
_this: Option<Object<'gc>>, this: Option<Object<'gc>>,
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> { ) -> Result<Value<'gc>, Error> {
if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
let mode =
AvmString::new_utf8(activation.context.gc_context, dobj.blend_mode().to_string());
return Ok(mode.into());
}
Ok(Value::Undefined) Ok(Value::Undefined)
} }
@ -659,41 +666,17 @@ pub fn set_blend_mode<'gc>(
args: &[Value<'gc>], args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> { ) -> Result<Value<'gc>, Error> {
if let Some(dobj) = this.and_then(|this| this.as_display_object()) { if let Some(dobj) = this.and_then(|this| this.as_display_object()) {
if let Some(Value::String(mode)) = args.get(0).cloned() { let mode = args
let mode = &*mode; .get(0)
let mode = if mode == b"add" { .cloned()
BlendMode::Add .unwrap_or(Value::Undefined)
} else if mode == b"alpha" { .coerce_to_string(activation)?;
BlendMode::Alpha
} else if mode == b"darken" { if let Ok(mode) = BlendMode::from_str(&mode.to_string()) {
BlendMode::Darken
} else if mode == b"difference" {
BlendMode::Difference
} else if mode == b"erase" {
BlendMode::Erase
} else if mode == b"hardlight" {
BlendMode::HardLight
} else if mode == b"invert" {
BlendMode::Invert
} else if mode == b"layer" {
BlendMode::Layer
} else if mode == b"lighten" {
BlendMode::Lighten
} else if mode == b"multiply" {
BlendMode::Multiply
} else if mode == b"normal" {
BlendMode::Normal
} else if mode == b"overlay" {
BlendMode::Overlay
} else if mode == b"screen" {
BlendMode::Screen
} else if mode == b"subtract" {
BlendMode::Subtract
} else {
log::error!("Unknown blend mode {:?}", mode);
BlendMode::Normal
};
dobj.set_blend_mode(activation.context.gc_context, mode); dobj.set_blend_mode(activation.context.gc_context, mode);
} else {
log::error!("Unknown blend mode {}", mode);
return Err("ArgumentError: Error #2008: Parameter blendMode must be one of the accepted values.".into());
} }
} }
Ok(Value::Undefined) Ok(Value::Undefined)