Implement basic shadows (no blur yet)

This commit is contained in:
Patrick Walton 2019-06-03 21:09:04 -07:00
parent bd248bf850
commit 7973148603
3 changed files with 47 additions and 2 deletions

View File

@ -192,6 +192,18 @@ impl CanvasRenderingContext2D {
self.current_state.stroke_paint = new_stroke_style.to_paint(); self.current_state.stroke_paint = new_stroke_style.to_paint();
} }
// Shadows
#[inline]
pub fn set_shadow_color(&mut self, new_shadow_color: ColorU) {
self.current_state.shadow_paint = Paint { color: new_shadow_color };
}
#[inline]
pub fn set_shadow_offset(&mut self, new_shadow_offset: Vector2F) {
self.current_state.shadow_offset = new_shadow_offset;
}
// Drawing paths // Drawing paths
#[inline] #[inline]
@ -202,7 +214,7 @@ impl CanvasRenderingContext2D {
let paint = self.current_state.resolve_paint(self.current_state.fill_paint); let paint = self.current_state.resolve_paint(self.current_state.fill_paint);
let paint_id = self.scene.push_paint(&paint); let paint_id = self.scene.push_paint(&paint);
self.scene.push_path(PathObject::new(outline, paint_id, String::new())) self.push_path(outline, paint_id);
} }
#[inline] #[inline]
@ -227,6 +239,19 @@ impl CanvasRenderingContext2D {
outline = stroke_to_fill.into_outline(); outline = stroke_to_fill.into_outline();
outline.transform(&self.current_state.transform); outline.transform(&self.current_state.transform);
self.push_path(outline, paint_id);
}
fn push_path(&mut self, outline: Outline, paint_id: PaintId) {
if !self.current_state.shadow_paint.is_fully_transparent() {
let paint = self.current_state.resolve_paint(self.current_state.shadow_paint);
let paint_id = self.scene.push_paint(&paint);
let mut outline = outline.clone();
outline.transform(&Transform2DF::from_translation(self.current_state.shadow_offset));
self.scene.push_path(PathObject::new(outline, paint_id, String::new()))
}
self.scene.push_path(PathObject::new(outline, paint_id, String::new())) self.scene.push_path(PathObject::new(outline, paint_id, String::new()))
} }
@ -287,6 +312,8 @@ struct State {
line_dash_offset: f32, line_dash_offset: f32,
fill_paint: Paint, fill_paint: Paint,
stroke_paint: Paint, stroke_paint: Paint,
shadow_paint: Paint,
shadow_offset: Vector2F,
text_align: TextAlign, text_align: TextAlign,
global_alpha: f32, global_alpha: f32,
} }
@ -305,6 +332,8 @@ impl State {
line_dash_offset: 0.0, line_dash_offset: 0.0,
fill_paint: Paint { color: ColorU::black() }, fill_paint: Paint { color: ColorU::black() },
stroke_paint: Paint { color: ColorU::black() }, stroke_paint: Paint { color: ColorU::black() },
shadow_paint: Paint { color: ColorU::transparent_black() },
shadow_offset: Vector2F::default(),
text_align: TextAlign::Left, text_align: TextAlign::Left,
global_alpha: 1.0, global_alpha: 1.0,
} }

View File

@ -21,6 +21,11 @@ pub struct ColorU {
} }
impl ColorU { impl ColorU {
#[inline]
pub fn transparent_black() -> ColorU {
ColorU::from_u32(0)
}
#[inline] #[inline]
pub fn from_u32(rgba: u32) -> ColorU { pub fn from_u32(rgba: u32) -> ColorU {
ColorU { ColorU {
@ -46,6 +51,11 @@ impl ColorU {
let color = F32x4::new(self.r as f32, self.g as f32, self.b as f32, self.a as f32); let color = F32x4::new(self.r as f32, self.g as f32, self.b as f32, self.a as f32);
ColorF(color * F32x4::splat(1.0 / 255.0)) ColorF(color * F32x4::splat(1.0 / 255.0))
} }
#[inline]
pub fn is_fully_transparent(&self) -> bool {
self.a == 0
}
} }
impl Debug for ColorU { impl Debug for ColorU {

View File

@ -25,9 +25,15 @@ pub struct Paint {
pub struct PaintId(pub u16); pub struct PaintId(pub u16);
impl Paint { impl Paint {
pub(crate) fn is_opaque(&self) -> bool { #[inline]
pub fn is_opaque(&self) -> bool {
self.color.a == 255 self.color.a == 255
} }
#[inline]
pub fn is_fully_transparent(&self) -> bool {
self.color.is_fully_transparent()
}
} }
impl Scene { impl Scene {