diff --git a/core/src/display_object.rs b/core/src/display_object.rs index 4711ecf1e..c3d476571 100644 --- a/core/src/display_object.rs +++ b/core/src/display_object.rs @@ -96,6 +96,13 @@ pub struct DisplayObjectBase<'gc> { #[collect(require_static)] blend_mode: BlendMode, + /// The opaque background color of this display object. + /// The bounding box of the display object will be filled with the given color. This also + /// triggers cache-as-bitmap behavior. Only solid backgrounds are supported; the alpha channel + /// is ignored. + #[collect(require_static)] + opaque_background: Option, + /// Bit flags for various display object properties. flags: DisplayObjectFlags, } @@ -119,6 +126,7 @@ impl<'gc> Default for DisplayObjectBase<'gc> { maskee: None, sound_transform: Default::default(), blend_mode: Default::default(), + opaque_background: Default::default(), flags: DisplayObjectFlags::VISIBLE, } } @@ -387,6 +395,23 @@ impl<'gc> DisplayObjectBase<'gc> { self.blend_mode = value; } + /// The opaque background color of this display object. + /// The bounding box of the display object will be filled with this color. + fn opaque_background(&self) -> Option { + self.opaque_background.clone() + } + + /// The opaque background color of this display object. + /// The bounding box of the display object will be filled with the given color. This also + /// triggers cache-as-bitmap behavior. Only solid backgrounds are supported; the alpha channel + /// is ignored. + fn set_opaque_background(&mut self, value: Option) { + self.opaque_background = value.map(|mut color| { + color.a = 255; + color + }); + } + fn is_root(&self) -> bool { self.flags.contains(DisplayObjectFlags::IS_ROOT) } @@ -973,6 +998,19 @@ pub trait TDisplayObject<'gc>: self.base_mut(gc_context).set_blend_mode(value); } + /// The opaque background color of this display object. + fn opaque_background(&self) -> Option { + self.base().opaque_background() + } + + /// Sets the opaque background color of this display object. + /// The bounding box of the display object will be filled with the given color. This also + /// triggers cache-as-bitmap behavior. Only solid backgrounds are supported; the alpha channel + /// is ignored. + fn set_opaque_background(&self, gc_context: MutationContext<'gc, '_>, value: Option) { + self.base_mut(gc_context).set_opaque_background(value); + } + /// Whether this display object represents the root of loaded content. fn is_root(&self) -> bool { self.base().is_root() @@ -1286,6 +1324,16 @@ pub trait TDisplayObject<'gc>: if let Some(visible) = place_object.is_visible { self.set_visible(context.gc_context, visible); } + if let Some(mut color) = place_object.background_color.clone() { + let color = if color.a > 0 { + // Force opaque background to have no transpranecy. + color.a = 255; + Some(color) + } else { + None + }; + self.set_opaque_background(context.gc_context, color); + } } // TODO: Others will go here eventually. } diff --git a/core/src/display_object/movie_clip.rs b/core/src/display_object/movie_clip.rs index 11c26b380..6b5f0a71e 100644 --- a/core/src/display_object/movie_clip.rs +++ b/core/src/display_object/movie_clip.rs @@ -3312,6 +3312,9 @@ impl<'a> GotoPlaceObject<'a> { if place_object.class_name.is_none() { place_object.class_name = Some(Default::default()); } + if place_object.background_color.is_none() { + place_object.background_color = Some(Color::from_rgba(0)); + } } } @@ -3358,9 +3361,6 @@ impl<'a> GotoPlaceObject<'a> { if next_place.class_name.is_some() { cur_place.class_name = next_place.class_name.take(); } - if next_place.background_color.is_some() { - cur_place.background_color = next_place.background_color.take(); - } if next_place.blend_mode.is_some() { cur_place.blend_mode = next_place.blend_mode.take(); } @@ -3370,6 +3370,9 @@ impl<'a> GotoPlaceObject<'a> { if next_place.is_visible.is_some() { cur_place.is_visible = next_place.is_visible.take(); } + if next_place.background_color.is_some() { + cur_place.background_color = next_place.background_color.take(); + } // TODO: Other stuff. } }