Source code
Revision control
Copy as Markdown
Other Tools
/* 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<ColorU>,
}
pub type RectangleKey = PrimKey<RectanglePrim>;
pub type RectangleDataHandle = intern::Handle<RectanglePrim>;
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<ColorF>,
}
pub type RectangleTemplate = PrimTemplate<RectangleData>;
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<DeviceRect>,
_offset: LayoutVector2D,
ctx: &PatternBuilderContext,
_state: &mut PatternBuilderState,
) -> Pattern {
Pattern::color(ctx.scene_properties.resolve_color(&self.kind.color))
}
}
impl From<RectangleKey> 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::<RectanglePrim>(), 16, "RectanglePrim size changed");
assert_eq!(mem::size_of::<RectangleTemplate>(), 56, "RectangleTemplate size changed");
assert_eq!(mem::size_of::<RectangleKey>(), 36, "RectangleKey size changed");
}