mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Make fill_rect() draw patterns correctly
This commit is contained in:
parent
d42835b238
commit
967fabb0d0
5 changed files with 42 additions and 47 deletions
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use crate::canvas_paint_thread::AntialiasMode;
|
use crate::canvas_paint_thread::AntialiasMode;
|
||||||
|
use crate::raqote_backend::Repetition;
|
||||||
use canvas_traits::canvas::*;
|
use canvas_traits::canvas::*;
|
||||||
use cssparser::RGBA;
|
use cssparser::RGBA;
|
||||||
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
|
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
|
||||||
|
@ -78,7 +79,6 @@ pub trait Backend {
|
||||||
);
|
);
|
||||||
fn create_drawtarget(&self, size: Size2D<u64>) -> Box<dyn GenericDrawTarget>;
|
fn create_drawtarget(&self, size: Size2D<u64>) -> Box<dyn GenericDrawTarget>;
|
||||||
fn recreate_paint_state<'a>(&self, state: &CanvasPaintState<'a>) -> CanvasPaintState<'a>;
|
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.
|
/// A generic PathBuilder that abstracts the interface for azure's and raqote's PathBuilder.
|
||||||
|
@ -470,12 +470,41 @@ impl<'a> CanvasData<'a> {
|
||||||
return; // Paint nothing if gradient size is zero.
|
return; // Paint nothing if gradient size is zero.
|
||||||
}
|
}
|
||||||
|
|
||||||
let draw_rect = Rect::new(
|
let draw_rect = match &self.state.fill_style {
|
||||||
rect.origin,
|
Pattern::Raqote(pattern) => match pattern {
|
||||||
self.backend
|
crate::raqote_backend::Pattern::Surface(pattern) => {
|
||||||
.size_from_pattern(&rect, &self.state.fill_style)
|
let pattern_rect = Rect::new(Point2D::origin(), pattern.size());
|
||||||
.unwrap_or(rect.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() {
|
if self.need_to_draw_shadow() {
|
||||||
self.draw_with_shadow(&draw_rect, |new_draw_target: &mut dyn GenericDrawTarget| {
|
self.draw_with_shadow(&draw_rect, |new_draw_target: &mut dyn GenericDrawTarget| {
|
||||||
|
|
|
@ -28,31 +28,6 @@ impl Backend for RaqoteBackend {
|
||||||
color.as_raqote().a != 0
|
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>) {
|
fn set_shadow_color<'a>(&mut self, color: RGBA, state: &mut CanvasPaintState<'a>) {
|
||||||
state.shadow_color = Color::Raqote(color.to_raqote_style());
|
state.shadow_color = Color::Raqote(color.to_raqote_style());
|
||||||
}
|
}
|
||||||
|
@ -208,6 +183,12 @@ impl<'a> SurfacePattern<'a> {
|
||||||
fn set_transform(&mut self, transform: Transform2D<f32>) {
|
fn set_transform(&mut self, transform: Transform2D<f32>) {
|
||||||
self.transform = transform;
|
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)]
|
#[derive(Clone)]
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.pattern.paint.norepeat.coord3.html]
|
|
||||||
type: testharness
|
|
||||||
[Canvas test: 2d.pattern.paint.norepeat.coord3]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.pattern.paint.repeatx.coord1.html]
|
|
||||||
type: testharness
|
|
||||||
[Canvas test: 2d.pattern.paint.repeatx.coord1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.pattern.paint.repeaty.coord1.html]
|
|
||||||
type: testharness
|
|
||||||
[Canvas test: 2d.pattern.paint.repeaty.coord1]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue