mirror of
https://github.com/servo/servo.git
synced 2025-08-07 06:25:32 +01:00
Inline dirty rect computation
This commit is contained in:
parent
48c24f8492
commit
7bcb911cea
1 changed files with 46 additions and 58 deletions
|
@ -56,55 +56,6 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
|
|
||||||
image_data
|
image_data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// dirty_rect: original dirty_rect provided by the putImageData call
|
|
||||||
/// image_data_rect: the area of the image to be copied
|
|
||||||
/// Result: It retuns the modified dirty_rect by the rules described in
|
|
||||||
/// the spec https://html.spec.whatwg.org/#dom-context-2d-putimagedata
|
|
||||||
fn calculate_dirty_rect(&self,
|
|
||||||
mut dirty_rect: Rect<f64>,
|
|
||||||
image_data_rect: Rect<f64>) -> Rect<f64>{
|
|
||||||
// 1) If dirtyWidth is negative,
|
|
||||||
// let dirtyX be dirtyX+dirtyWidth,
|
|
||||||
// and let dirtyWidth be equal to the absolute magnitude of dirtyWidth.
|
|
||||||
if dirty_rect.size.width < 0.0f64 {
|
|
||||||
dirty_rect.origin.x = dirty_rect.origin.x + dirty_rect.size.width;
|
|
||||||
dirty_rect.size.width = -dirty_rect.size.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2) If dirtyHeight is negative, let dirtyY be dirtyY+dirtyHeight,
|
|
||||||
// and let dirtyHeight be equal to the absolute magnitude of dirtyHeight.
|
|
||||||
if dirty_rect.size.height < 0.0f64 {
|
|
||||||
dirty_rect.origin.y = dirty_rect.origin.y + dirty_rect.size.height;
|
|
||||||
dirty_rect.size.height = -dirty_rect.size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) If dirtyX is negative, let dirtyWidth be dirtyWidth+dirtyX, and let dirtyX be zero.
|
|
||||||
if dirty_rect.origin.x < 0.0f64 {
|
|
||||||
dirty_rect.size.width += dirty_rect.origin.x;
|
|
||||||
dirty_rect.origin.x = 0.0f64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3) If dirtyY is negative, let dirtyHeight be dirtyHeight+dirtyY, and let dirtyY be zero.
|
|
||||||
if dirty_rect.origin.y < 0.0f64 {
|
|
||||||
dirty_rect.size.height += dirty_rect.origin.y;
|
|
||||||
dirty_rect.origin.y = 0.0f64;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4) If dirtyX+dirtyWidth is greater than the width attribute of the imagedata argument,
|
|
||||||
// let dirtyWidth be the value of that width attribute, minus the value of dirtyX.
|
|
||||||
if dirty_rect.origin.x + dirty_rect.size.width > image_data_rect.size.width {
|
|
||||||
dirty_rect.size.width = image_data_rect.size.width - dirty_rect.origin.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4) If dirtyY+dirtyHeight is greater than the height attribute of the imagedata argument,
|
|
||||||
// let dirtyHeight be the value of that height attribute, minus the value of dirtyY.
|
|
||||||
if dirty_rect.origin.y + dirty_rect.size.height > image_data_rect.size.height {
|
|
||||||
dirty_rect.size.height = image_data_rect.size.height - dirty_rect.origin.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirty_rect
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CanvasPaintTask<'a> {
|
pub struct CanvasPaintTask<'a> {
|
||||||
|
@ -594,7 +545,8 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
|
|
||||||
fn put_image_data(&mut self, mut imagedata: Vec<u8>,
|
fn put_image_data(&mut self, mut imagedata: Vec<u8>,
|
||||||
image_data_rect: Rect<f64>,
|
image_data_rect: Rect<f64>,
|
||||||
dirty_rect: Rect<f64>) {
|
mut dirty_rect: Rect<f64>) {
|
||||||
|
|
||||||
|
|
||||||
if image_data_rect.size.width <= 0.0 || image_data_rect.size.height <= 0.0 {
|
if image_data_rect.size.width <= 0.0 || image_data_rect.size.height <= 0.0 {
|
||||||
return
|
return
|
||||||
|
@ -604,13 +556,49 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
// rgba -> bgra
|
// rgba -> bgra
|
||||||
byte_swap(&mut imagedata);
|
byte_swap(&mut imagedata);
|
||||||
|
|
||||||
// Dirty rectangle defines the area of the source image to be copied
|
// 1) If dirtyWidth is negative,
|
||||||
// on the destination canvas
|
// let dirtyX be dirtyX+dirtyWidth,
|
||||||
let source_rect = self.calculate_dirty_rect(dirty_rect, image_data_rect);
|
// and let dirtyWidth be equal to the absolute magnitude of dirtyWidth.
|
||||||
|
if dirty_rect.size.width < 0.0f64 {
|
||||||
|
dirty_rect.origin.x = dirty_rect.origin.x + dirty_rect.size.width;
|
||||||
|
dirty_rect.size.width = -dirty_rect.size.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) If dirtyHeight is negative, let dirtyY be dirtyY+dirtyHeight,
|
||||||
|
// and let dirtyHeight be equal to the absolute magnitude of dirtyHeight.
|
||||||
|
if dirty_rect.size.height < 0.0f64 {
|
||||||
|
dirty_rect.origin.y = dirty_rect.origin.y + dirty_rect.size.height;
|
||||||
|
dirty_rect.size.height = -dirty_rect.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) If dirtyX is negative, let dirtyWidth be dirtyWidth+dirtyX, and let dirtyX be zero.
|
||||||
|
if dirty_rect.origin.x < 0.0f64 {
|
||||||
|
dirty_rect.size.width += dirty_rect.origin.x;
|
||||||
|
dirty_rect.origin.x = 0.0f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3) If dirtyY is negative, let dirtyHeight be dirtyHeight+dirtyY, and let dirtyY be zero.
|
||||||
|
if dirty_rect.origin.y < 0.0f64 {
|
||||||
|
dirty_rect.size.height += dirty_rect.origin.y;
|
||||||
|
dirty_rect.origin.y = 0.0f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) If dirtyX+dirtyWidth is greater than the width attribute of the imagedata argument,
|
||||||
|
// let dirtyWidth be the value of that width attribute, minus the value of dirtyX.
|
||||||
|
if dirty_rect.origin.x + dirty_rect.size.width > image_data_rect.size.width {
|
||||||
|
dirty_rect.size.width = image_data_rect.size.width - dirty_rect.origin.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) If dirtyY+dirtyHeight is greater than the height attribute of the imagedata argument,
|
||||||
|
// let dirtyHeight be the value of that height attribute, minus the value of dirtyY.
|
||||||
|
if dirty_rect.origin.y + dirty_rect.size.height > image_data_rect.size.height {
|
||||||
|
dirty_rect.size.height = image_data_rect.size.height - dirty_rect.origin.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 5) If either dirtyWidth or dirtyHeight is negative or zero,
|
// 5) If either dirtyWidth or dirtyHeight is negative or zero,
|
||||||
// stop without affecting any bitmaps
|
// stop without affecting any bitmaps
|
||||||
if source_rect.size.width <= 0.0 || source_rect.size.height <= 0.0 {
|
if dirty_rect.size.width <= 0.0 || dirty_rect.size.height <= 0.0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -621,11 +609,11 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
// (dx+x, dy+y) in the rendering context's scratch bitmap.
|
// (dx+x, dy+y) in the rendering context's scratch bitmap.
|
||||||
// It also clips the destination rectangle to the canvas area
|
// It also clips the destination rectangle to the canvas area
|
||||||
let dest_rect = Rect::new(
|
let dest_rect = Rect::new(
|
||||||
Point2D::new(image_data_rect.origin.x + source_rect.origin.x,
|
Point2D::new(image_data_rect.origin.x + dirty_rect.origin.x,
|
||||||
image_data_rect.origin.y + source_rect.origin.y),
|
image_data_rect.origin.y + dirty_rect.origin.y),
|
||||||
Size2D::new(source_rect.size.width, source_rect.size.height));
|
Size2D::new(dirty_rect.size.width, dirty_rect.size.height));
|
||||||
|
|
||||||
write_pixels(&self.drawtarget, &imagedata, image_data_rect.size, source_rect,
|
write_pixels(&self.drawtarget, &imagedata, image_data_rect.size, dirty_rect,
|
||||||
dest_rect, true, self.state.draw_options.composition, self.state.draw_options.alpha)
|
dest_rect, true, self.state.draw_options.composition, self.state.draw_options.alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue