diff options
-rw-r--r-- | components/canvas_traits/lib.rs | 18 | ||||
-rw-r--r-- | components/script/dom/canvasrenderingcontext2d.rs | 12 |
2 files changed, 28 insertions, 2 deletions
diff --git a/components/canvas_traits/lib.rs b/components/canvas_traits/lib.rs index db945750a0c..d148baf0550 100644 --- a/components/canvas_traits/lib.rs +++ b/components/canvas_traits/lib.rs @@ -552,3 +552,21 @@ pub fn byte_swap(data: &mut [u8]) { i += 4; } } + +pub fn byte_swap_and_premultiply(data: &mut [u8]) { + let length = data.len(); + + let mut i = 0; + while i < length { + let r = data[i + 2]; + let g = data[i + 1]; + let b = data[i + 0]; + let a = data[i + 3]; + + data[i + 0] = ((r as u32) * (a as u32) / 255) as u8; + data[i + 1] = ((g as u32) * (a as u32) / 255) as u8; + data[i + 2] = ((b as u32) * (a as u32) / 255) as u8; + + i += 4; + } +} diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs index 09d4a8f04e1..f3c74b59250 100644 --- a/components/script/dom/canvasrenderingcontext2d.rs +++ b/components/script/dom/canvasrenderingcontext2d.rs @@ -5,7 +5,7 @@ use canvas_traits::{Canvas2dMsg, CanvasCommonMsg, CanvasMsg}; use canvas_traits::{CompositionOrBlending, FillOrStrokeStyle, FillRule}; use canvas_traits::{LineCapStyle, LineJoinStyle, LinearGradientStyle}; -use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap}; +use canvas_traits::{RadialGradientStyle, RepetitionStyle, byte_swap, byte_swap_and_premultiply}; use cssparser::Color as CSSColor; use cssparser::{Parser, RGBA}; use dom::bindings::cell::DOMRefCell; @@ -47,6 +47,7 @@ use std::str::FromStr; use std::{cmp, fmt}; use unpremultiplytable::UNPREMULTIPLY_TABLE; use url::Url; +use util::opts; #[must_root] #[derive(JSTraceable, Clone, HeapSizeOf)] @@ -299,7 +300,14 @@ impl CanvasRenderingContext2D { Some((mut data, size)) => { // Pixels come from cache in BGRA order and drawImage expects RGBA so we // have to swap the color values - byte_swap(&mut data); + if opts::get().use_webrender { + // Webrender doesn't pre-multiply alpha when decoding + // images, but canvas expects the images to be + // pre-multiplied alpha. + byte_swap_and_premultiply(&mut data); + } else { + byte_swap(&mut data); + } let size = Size2D::new(size.width as f64, size.height as f64); (data, size) }, |