use api::{BorderRadius, BoxShadowClipMode};
use api::units::*;
use api::ColorF;
use crate::pattern::{Pattern, PatternBuilder, PatternBuilderContext, PatternBuilderState, PatternKind, PatternShaderInput, PatternTextureInput};
use crate::render_task_graph::RenderTaskId;
use crate::renderer::BlendMode;
pub struct BoxShadowPatternData {
pub color: ColorF,
pub render_task: RenderTaskId,
pub shadow_rect_alloc_size: LayoutSize,
pub dest_rect_size: LayoutSize,
pub dest_rect_offset: LayoutVector2D,
pub clip_mode: BoxShadowClipMode,
pub element_offset_rel_prim: LayoutVector2D,
pub element_size: LayoutSize,
pub element_radius: BorderRadius,
}
impl PatternBuilder for BoxShadowPatternData {
fn build(
&self,
_sub_rect: Option<DeviceRect>,
_offset: LayoutVector2D,
_ctx: &PatternBuilderContext,
state: &mut PatternBuilderState,
) -> Pattern {
let mut writer = state.frame_gpu_data.f32.write_blocks(5);
writer.push_one([
self.shadow_rect_alloc_size.width,
self.shadow_rect_alloc_size.height,
self.dest_rect_size.width,
self.dest_rect_size.height,
]);
writer.push_one([
self.dest_rect_offset.x,
self.dest_rect_offset.y,
if self.clip_mode == BoxShadowClipMode::Inset { 1.0 } else { 0.0 },
0.0,
]);
writer.push_one([
self.element_offset_rel_prim.x,
self.element_offset_rel_prim.y,
self.element_size.width,
self.element_size.height,
]);
writer.push_one([
self.element_radius.top_left.width,
self.element_radius.top_left.height,
self.element_radius.top_right.width,
self.element_radius.top_right.height,
]);
writer.push_one([
self.element_radius.bottom_right.width,
self.element_radius.bottom_right.height,
self.element_radius.bottom_left.width,
self.element_radius.bottom_left.height,
]);
let addr = writer.finish();
Pattern {
kind: PatternKind::BoxShadow,
shader_input: PatternShaderInput(addr.as_int(), 0),
texture_input: PatternTextureInput::new(self.render_task),
base_color: self.color,
is_opaque: false,
blend_mode: BlendMode::PremultipliedAlpha,
}
}
}