Skip to content

Commit

Permalink
Make fill_rect() draw patterns correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
pylbrecht committed Mar 3, 2020
1 parent d42835b commit 967fabb
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 47 deletions.
43 changes: 36 additions & 7 deletions components/canvas/canvas_data.rs
Expand Up @@ -3,6 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::canvas_paint_thread::AntialiasMode;
use crate::raqote_backend::Repetition;
use canvas_traits::canvas::*;
use cssparser::RGBA;
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
Expand Down Expand Up @@ -78,7 +79,6 @@ pub trait Backend {
);
fn create_drawtarget(&self, size: Size2D<u64>) -> Box<dyn GenericDrawTarget>;
fn recreate_paint_state<'a>(&self, state: &CanvasPaintState<'a>) -> CanvasPaintState<'a>;
fn size_from_pattern(&self, rect: &Rect<f32>, pattern: &Pattern) -> Option<Size2D<f32>>;
}

/// A generic PathBuilder that abstracts the interface for azure's and raqote's PathBuilder.
Expand Down Expand Up @@ -470,12 +470,41 @@ impl<'a> CanvasData<'a> {
return; // Paint nothing if gradient size is zero.
}

let draw_rect = Rect::new(
rect.origin,
self.backend
.size_from_pattern(&rect, &self.state.fill_style)
.unwrap_or(rect.size),
);
let draw_rect = match &self.state.fill_style {
Pattern::Raqote(pattern) => match pattern {
crate::raqote_backend::Pattern::Surface(pattern) => {
let pattern_rect = Rect::new(Point2D::origin(), pattern.size());
let mut draw_rect = rect.intersection(&pattern_rect).unwrap_or(Rect::zero());

match pattern.repetition() {
Repetition::NoRepeat => {
draw_rect.size.width =
draw_rect.size.width.min(pattern_rect.size.width);
draw_rect.size.height =
draw_rect.size.height.min(pattern_rect.size.height);
},
Repetition::RepeatX => {
draw_rect.size.width = rect.size.width;
draw_rect.size.height =
draw_rect.size.height.min(pattern_rect.size.height);
},
Repetition::RepeatY => {
draw_rect.size.height = rect.size.height;
draw_rect.size.width =
draw_rect.size.width.min(pattern_rect.size.width);
},
Repetition::Repeat => {
draw_rect = *rect;
},
}

draw_rect
},
crate::raqote_backend::Pattern::Color(..) |
crate::raqote_backend::Pattern::LinearGradient(..) |
crate::raqote_backend::Pattern::RadialGradient(..) => *rect,
},
};

if self.need_to_draw_shadow() {
self.draw_with_shadow(&draw_rect, |new_draw_target: &mut dyn GenericDrawTarget| {
Expand Down
31 changes: 6 additions & 25 deletions components/canvas/raqote_backend.rs
Expand Up @@ -28,31 +28,6 @@ impl Backend for RaqoteBackend {
color.as_raqote().a != 0
}

fn size_from_pattern(
&self,
rect: &Rect<f32>,
pattern: &canvas_data::Pattern,
) -> Option<Size2D<f32>> {
match pattern {
canvas_data::Pattern::Raqote(Pattern::Surface(pattern)) => match pattern.repeat {
Repetition::RepeatX => Some(Size2D::new(
rect.size.width as f32,
pattern.image.height as f32,
)),
Repetition::RepeatY => Some(Size2D::new(
pattern.image.width as f32,
rect.size.height as f32,
)),
Repetition::Repeat => Some(rect.size),
Repetition::NoRepeat => Some(Size2D::new(
pattern.image.width as f32,
pattern.image.height as f32,
)),
},
_ => None,
}
}

fn set_shadow_color<'a>(&mut self, color: RGBA, state: &mut CanvasPaintState<'a>) {
state.shadow_color = Color::Raqote(color.to_raqote_style());
}
Expand Down Expand Up @@ -208,6 +183,12 @@ impl<'a> SurfacePattern<'a> {
fn set_transform(&mut self, transform: Transform2D<f32>) {
self.transform = transform;
}
pub fn size(&self) -> Size2D<f32> {
Size2D::new(self.image.width as f32, self.image.height as f32)
}
pub fn repetition(&self) -> &Repetition {
&self.repeat
}
}

#[derive(Clone)]
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

0 comments on commit 967fabb

Please sign in to comment.