aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorHyowon Kim <hw1008.kim@samsung.com>2015-05-14 10:08:10 +0900
committerHyowon Kim <hw1008.kim@samsung.com>2015-06-13 14:35:13 +0900
commit00240e5550f52d49c0308e56498e177d357eb53c (patch)
treeced3ed2ce6657daf7b0102e1d81bc3097fe134ca /components/script
parent2168ec3c96ca9e8e1174be22be07d1168061b4b6 (diff)
downloadservo-00240e5550f52d49c0308e56498e177d357eb53c.tar.gz
servo-00240e5550f52d49c0308e56498e177d357eb53c.zip
Implementation of pattern fill style for canvas.
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/trace.rs5
-rw-r--r--components/script/dom/canvaspattern.rs44
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs48
-rw-r--r--components/script/dom/webidls/CanvasRenderingContext2D.webidl3
4 files changed, 94 insertions, 6 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 1d6fe23c785..a4ef3eb6d9b 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -35,11 +35,12 @@ use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
use script_task::ScriptChan;
use canvas_traits::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
-use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending};
+use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending, RepetitionStyle};
use cssparser::RGBA;
use encoding::types::EncodingRef;
use geom::matrix2d::Matrix2D;
use geom::rect::Rect;
+use geom::size::Size2D;
use html5ever::tree_builder::QuirksMode;
use hyper::header::Headers;
use hyper::method::Method;
@@ -249,6 +250,7 @@ no_jsmanaged_fields!(isize, i8, i16, i32, i64);
no_jsmanaged_fields!(Sender<T>);
no_jsmanaged_fields!(Receiver<T>);
no_jsmanaged_fields!(Rect<T>);
+no_jsmanaged_fields!(Size2D<T>);
no_jsmanaged_fields!(Arc<T>);
no_jsmanaged_fields!(Image, ImageCacheChan, ImageCacheTask, ScriptControlChan);
no_jsmanaged_fields!(Atom, Namespace);
@@ -272,6 +274,7 @@ no_jsmanaged_fields!(Matrix2D<T>);
no_jsmanaged_fields!(StorageType);
no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle);
no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending);
+no_jsmanaged_fields!(RepetitionStyle);
impl JSTraceable for Box<ScriptChan+Send> {
#[inline]
diff --git a/components/script/dom/canvaspattern.rs b/components/script/dom/canvaspattern.rs
index b8b2808d3b9..0be707a1147 100644
--- a/components/script/dom/canvaspattern.rs
+++ b/components/script/dom/canvaspattern.rs
@@ -2,12 +2,54 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use dom::bindings::utils::Reflector;
+use canvas_traits::{FillOrStrokeStyle, SurfaceStyle, RepetitionStyle};
+use dom::bindings::codegen::Bindings::CanvasPatternBinding;
+use dom::bindings::global::GlobalRef;
+use dom::bindings::js::{JSRef, Temporary};
+use dom::bindings::utils::{Reflector, reflect_dom_object};
+use dom::canvasgradient::ToFillOrStrokeStyle;
+use geom::size::Size2D;
// https://html.spec.whatwg.org/multipage/#canvaspattern
#[dom_struct]
pub struct CanvasPattern {
reflector_: Reflector,
+ surface_data: Vec<u8>,
+ surface_size: Size2D<i32>,
+ repeat_x: bool,
+ repeat_y: bool,
}
+impl CanvasPattern {
+ fn new_inherited(surface_data: Vec<u8>, surface_size: Size2D<i32>, repeat: RepetitionStyle) -> CanvasPattern {
+ let (x, y) = match repeat {
+ RepetitionStyle::Repeat => (true, true),
+ RepetitionStyle::RepeatX => (true, false),
+ RepetitionStyle::RepeatY => (false, true),
+ RepetitionStyle::NoRepeat => (false, false),
+ };
+ CanvasPattern {
+ reflector_: Reflector::new(),
+ surface_data: surface_data,
+ surface_size: surface_size,
+ repeat_x: x,
+ repeat_y: y,
+ }
+ }
+ pub fn new(global: GlobalRef,
+ surface_data: Vec<u8>,
+ surface_size: Size2D<i32>,
+ repeat: RepetitionStyle)
+ -> Temporary<CanvasPattern> {
+ reflect_dom_object(box CanvasPattern::new_inherited(surface_data, surface_size, repeat),
+ global, CanvasPatternBinding::Wrap)
+ }
+}
+
+impl<'a> ToFillOrStrokeStyle for JSRef<'a, CanvasPattern> {
+ fn to_fill_or_stroke_style(&self) -> FillOrStrokeStyle {
+ FillOrStrokeStyle::Surface(
+ SurfaceStyle::new(self.surface_data.clone(), self.surface_size, self.repeat_x, self.repeat_y))
+ }
+}
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index b7edc07aaa8..596da8467c3 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -9,13 +9,14 @@ use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
use dom::bindings::codegen::InheritTypes::NodeCast;
use dom::bindings::codegen::UnionTypes::HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D;
use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern;
-use dom::bindings::error::Error::{IndexSize, NotSupported, Type, InvalidState};
+use dom::bindings::error::Error::{IndexSize, NotSupported, Type, InvalidState, Syntax};
use dom::bindings::error::Fallible;
use dom::bindings::global::{GlobalRef, GlobalField};
use dom::bindings::js::{JS, JSRef, LayoutJS, Rootable, Temporary, Unrooted};
use dom::bindings::num::Finite;
use dom::bindings::utils::{Reflector, reflect_dom_object};
use dom::canvasgradient::{CanvasGradient, CanvasGradientStyle, ToFillOrStrokeStyle};
+use dom::canvaspattern::CanvasPattern;
use dom::htmlcanvaselement::{HTMLCanvasElement, HTMLCanvasElementHelpers};
use dom::htmlimageelement::{HTMLImageElement, HTMLImageElementHelpers};
use dom::imagedata::{ImageData, ImageDataHelpers};
@@ -29,7 +30,7 @@ use geom::rect::Rect;
use geom::size::Size2D;
use canvas_traits::{CanvasMsg, Canvas2dMsg, CanvasCommonMsg};
-use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle};
+use canvas_traits::{FillOrStrokeStyle, LinearGradientStyle, RadialGradientStyle, RepetitionStyle};
use canvas_traits::{LineCapStyle, LineJoinStyle, CompositionOrBlending};
use canvas::canvas_paint_task::CanvasPaintTask;
@@ -865,7 +866,10 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
Canvas2dMsg::SetFillStyle(gradient_root.r().to_fill_or_stroke_style()));
self.renderer.send(msg).unwrap();
}
- _ => {}
+ StringOrCanvasGradientOrCanvasPattern::eCanvasPattern(pattern) => {
+ self.renderer.send(CanvasMsg::Canvas2d(Canvas2dMsg::SetFillStyle(
+ pattern.root().r().to_fill_or_stroke_style()))).unwrap();
+ }
}
}
@@ -997,6 +1001,44 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
RadialGradientStyle::new(x0, y0, r0, x1, y1, r1, Vec::new()))))
}
+ // https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
+ fn CreatePattern(self, image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
+ repetition: DOMString) -> Fallible<Temporary<CanvasPattern>> {
+ match image {
+ HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::eHTMLImageElement(image) => {
+ let image = image.root();
+ let image_element = image.r();
+
+ let url = match image_element.get_url() {
+ Some(url) => url,
+ None => return Err(InvalidState),
+ };
+
+ let img = match self.request_image_from_cache(url) {
+ ImageResponse::Loaded(img) => img,
+ ImageResponse::PlaceholderLoaded(_) | ImageResponse::None => return Err(InvalidState),
+ };
+
+ let image_size = Size2D(img.width as f64, img.height as f64);
+ let image_data = match img.pixels {
+ PixelsByColorType::RGBA8(ref pixels) => pixels.to_vec(),
+ PixelsByColorType::K8(_) => panic!("K8 color type not supported"),
+ PixelsByColorType::RGB8(_) => panic!("RGB8 color type not supported"),
+ PixelsByColorType::KA8(_) => panic!("KA8 color type not supported"),
+ };
+
+ if let Some(rep) = RepetitionStyle::from_str(&repetition) {
+ return Ok(CanvasPattern::new(self.global.root().r(),
+ image_data,
+ Size2D(image_size.width as i32, image_size.height as i32),
+ rep));
+ }
+ return Err(Syntax);
+ },
+ _ => return Err(Type("Not implemented".to_owned())),
+ }
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
fn LineWidth(self) -> f64 {
let state = self.state.borrow();
diff --git a/components/script/dom/webidls/CanvasRenderingContext2D.webidl b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
index c8816864afb..c1fa7dae4b7 100644
--- a/components/script/dom/webidls/CanvasRenderingContext2D.webidl
+++ b/components/script/dom/webidls/CanvasRenderingContext2D.webidl
@@ -62,7 +62,8 @@ interface CanvasRenderingContext2D {
CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1);
[Throws]
CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1);
- //CanvasPattern createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition);
+ [Throws]
+ CanvasPattern createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition);
// shadows
attribute unrestricted double shadowOffsetX; // (default 0)