/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use api::{PropertyBinding, ColorU, ColorF, Shadow, RasterSpace}; use crate::scene_building::{CreateShadow, IsVisible}; use crate::intern; use crate::internal_types::LayoutPrimitiveInfo; use crate::prim_store::{ PrimKey, InternablePrimitive, PrimitiveStore, PrimitiveInstanceKind, ColorBindingIndex, SegmentInstanceIndex, PrimTemplate, PrimTemplateCommonData, PrimitiveOpacity, }; use api::units::{DeviceRect, LayoutVector2D}; use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState}; use crate::frame_builder::FrameBuildingState; use crate::scene::SceneProperties; use std::ops; #[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash)] #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] pub struct RectanglePrim { pub color: PropertyBinding, } pub type RectangleKey = PrimKey; pub type RectangleDataHandle = intern::Handle; impl RectangleKey { pub fn new(info: &LayoutPrimitiveInfo, kind: RectanglePrim) -> Self { RectangleKey { common: info.into(), kind } } } impl intern::InternDebug for RectangleKey {} impl intern::Internable for RectanglePrim { type Key = RectangleKey; type StoreData = RectangleTemplate; type InternData = (); const PROFILE_COUNTER: usize = crate::profiler::INTERNED_PRIMITIVES; } impl InternablePrimitive for RectanglePrim { fn into_key( self, info: &LayoutPrimitiveInfo, ) -> RectangleKey { RectangleKey::new(info, self) } fn make_instance_kind( key: RectangleKey, data_handle: RectangleDataHandle, prim_store: &mut PrimitiveStore, ) -> PrimitiveInstanceKind { let color_binding_index = match key.kind.color { PropertyBinding::Binding(..) => { prim_store.color_bindings.push(key.kind.color) } PropertyBinding::Value(..) => ColorBindingIndex::INVALID, }; PrimitiveInstanceKind::Rectangle { data_handle, segment_instance_index: SegmentInstanceIndex::INVALID, color_binding_index, use_legacy_path: false, } } } impl IsVisible for RectanglePrim { fn is_visible(&self) -> bool { match self.color { PropertyBinding::Value(value) => value.a > 0, PropertyBinding::Binding(..) => true, } } } impl CreateShadow for RectanglePrim { fn create_shadow( &self, shadow: &Shadow, _: bool, _: RasterSpace, ) -> RectanglePrim { RectanglePrim { color: PropertyBinding::Value(shadow.color.into()), } } } #[cfg_attr(feature = "capture", derive(Serialize))] #[cfg_attr(feature = "replay", derive(Deserialize))] #[derive(MallocSizeOf)] pub struct RectangleData { pub color: PropertyBinding, } pub type RectangleTemplate = PrimTemplate; impl ops::Deref for RectangleTemplate { type Target = PrimTemplateCommonData; fn deref(&self) -> &Self::Target { &self.common } } impl ops::DerefMut for RectangleTemplate { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.common } } impl PatternBuilder for RectangleTemplate { fn build( &self, _sub_rect: Option, _offset: LayoutVector2D, ctx: &PatternBuilderContext, _state: &mut PatternBuilderState, ) -> Pattern { Pattern::color(ctx.scene_properties.resolve_color(&self.kind.color)) } } impl From for RectangleTemplate { fn from(item: RectangleKey) -> Self { RectangleTemplate { common: PrimTemplateCommonData::with_key_common(item.common), kind: RectangleData { color: item.kind.color.into() }, } } } impl RectangleTemplate { pub fn update( &mut self, frame_state: &mut FrameBuildingState, scene_properties: &SceneProperties, ) { let mut writer = frame_state.frame_gpu_data.f32.write_blocks(1); writer.push_one(scene_properties.resolve_color(&self.kind.color).premultiplied()); self.common.gpu_buffer_address = writer.finish(); self.opacity = PrimitiveOpacity::from_alpha( scene_properties.resolve_color(&self.kind.color).a ); } } #[test] #[cfg(target_pointer_width = "64")] fn test_struct_sizes() { use std::mem; assert_eq!(mem::size_of::(), 16, "RectanglePrim size changed"); assert_eq!(mem::size_of::(), 56, "RectangleTemplate size changed"); assert_eq!(mem::size_of::(), 36, "RectangleKey size changed"); }