diff options
Diffstat (limited to 'components/script/dom/htmlcanvaselement.rs')
-rw-r--r-- | components/script/dom/htmlcanvaselement.rs | 106 |
1 files changed, 73 insertions, 33 deletions
diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index e4fc68565a3..0a30989442b 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -2,15 +2,17 @@ * 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 canvas::canvas_paint_task::CanvasMsg; +use canvas::canvas_msg::CanvasMsg; use dom::attr::Attr; use dom::attr::AttrHelpers; use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding; use dom::bindings::codegen::Bindings::HTMLCanvasElementBinding::HTMLCanvasElementMethods; use dom::bindings::codegen::InheritTypes::HTMLCanvasElementDerived; use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast}; +use dom::bindings::codegen::UnionTypes::CanvasRenderingContext2DOrWebGLRenderingContext; use dom::bindings::global::GlobalRef; -use dom::bindings::js::{MutNullableJS, JSRef, LayoutJS, Temporary}; +use dom::bindings::js::{MutNullableJS, JSRef, LayoutJS, Temporary, Unrooted}; +use dom::bindings::utils::{Reflectable}; use dom::canvasrenderingcontext2d::{CanvasRenderingContext2D, LayoutCanvasRenderingContext2DHelpers}; use dom::document::Document; use dom::element::{Element, AttributeHandlers}; @@ -19,6 +21,7 @@ use dom::element::ElementTypeId; use dom::htmlelement::{HTMLElement, HTMLElementTypeId}; use dom::node::{Node, NodeTypeId, window_from_node}; use dom::virtualmethods::VirtualMethods; +use dom::webglrenderingcontext::{WebGLRenderingContext, LayoutCanvasWebGLRenderingContextHelpers}; use util::str::{DOMString, parse_unsigned_integer}; @@ -34,7 +37,8 @@ const DEFAULT_HEIGHT: u32 = 150; #[dom_struct] pub struct HTMLCanvasElement { htmlelement: HTMLElement, - context: MutNullableJS<CanvasRenderingContext2D>, + context_2d: MutNullableJS<CanvasRenderingContext2D>, + context_webgl: MutNullableJS<WebGLRenderingContext>, width: Cell<u32>, height: Cell<u32>, } @@ -49,7 +53,8 @@ impl HTMLCanvasElement { fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLCanvasElement { HTMLCanvasElement { htmlelement: HTMLElement::new_inherited(HTMLElementTypeId::HTMLCanvasElement, localName, prefix, document), - context: Default::default(), + context_2d: Default::default(), + context_webgl: Default::default(), width: Cell::new(DEFAULT_WIDTH), height: Cell::new(DEFAULT_HEIGHT), } @@ -60,6 +65,20 @@ impl HTMLCanvasElement { let element = HTMLCanvasElement::new_inherited(localName, prefix, document); Node::reflect_node(box element, document, HTMLCanvasElementBinding::Wrap) } + + fn recreate_contexts(&self) { + let size = self.get_size(); + if let Some(context) = self.context_2d.get() { + context.root().r().recreate(size) + } + if let Some(context) = self.context_webgl.get() { + context.root().r().recreate(size) + } + } + + pub fn get_size(&self) -> Size2D<i32> { + Size2D(self.width.get() as i32, self.height.get() as i32) + } } pub trait LayoutHTMLCanvasElementHelpers { @@ -74,8 +93,16 @@ pub trait LayoutHTMLCanvasElementHelpers { impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> { #[allow(unsafe_code)] unsafe fn get_renderer(&self) -> Option<Sender<CanvasMsg>> { - let context = (*self.unsafe_get()).context.get_inner_as_layout(); - context.map(|cx| cx.get_renderer()) + let ref canvas = *self.unsafe_get(); + if canvas.context_2d.get().is_some() { + let context = canvas.context_2d.get_inner_as_layout(); + context.map(|cx| cx.get_renderer()) + } else if canvas.context_webgl.get().is_some() { + let context = canvas.context_webgl.get_inner_as_layout(); + context.map(|cx| cx.get_renderer()) + } else { + None + } } #[allow(unsafe_code)] @@ -90,18 +117,30 @@ impl LayoutHTMLCanvasElementHelpers for LayoutJS<HTMLCanvasElement> { } pub trait HTMLCanvasElementHelpers { - fn get_size(&self) -> Size2D<i32>; fn get_2d_context(self) -> Temporary<CanvasRenderingContext2D>; + fn get_webgl_context(self) -> Temporary<WebGLRenderingContext>; fn is_valid(self) -> bool; } impl<'a> HTMLCanvasElementHelpers for JSRef<'a, HTMLCanvasElement> { - fn get_size(&self) -> Size2D<i32> { - Size2D(self.Width() as i32, self.Height() as i32) + fn get_2d_context(self) -> Temporary<CanvasRenderingContext2D> { + let context = self.GetContext(String::from_str("2d")); + match context.unwrap() { + CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D(context) => { + Temporary::new(context.root().r().unrooted()) + } + _ => panic!("Wrong Context Type: Expected 2d context"), + } } - fn get_2d_context(self) -> Temporary<CanvasRenderingContext2D> { - self.GetContext(String::from_str("2d")).unwrap() + fn get_webgl_context(self) -> Temporary<WebGLRenderingContext> { + let context = self.GetContext(String::from_str("webgl")); + match context.unwrap() { + CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext(context) => { + return Temporary::new(context.root().r().unrooted()); + } + _ => panic!("Wrong Context Type: Expected webgl context"), + } } fn is_valid(self) -> bool { @@ -128,17 +167,27 @@ impl<'a> HTMLCanvasElementMethods for JSRef<'a, HTMLCanvasElement> { elem.set_uint_attribute(&atom!("height"), height) } - fn GetContext(self, id: DOMString) -> Option<Temporary<CanvasRenderingContext2D>> { - if id.as_slice() != "2d" { - return None; - } - - Some(self.context.or_init(|| { - let window = window_from_node(self).root(); - let (w, h) = (self.width.get() as i32, self.height.get() as i32); - CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, Size2D(w, h)) - })) - } + fn GetContext(self, id: DOMString) -> Option<CanvasRenderingContext2DOrWebGLRenderingContext> { + match id.as_slice() { + "2d" => { + let context_2d = self.context_2d.or_init(|| { + let window = window_from_node(self).root(); + let size = self.get_size(); + CanvasRenderingContext2D::new(GlobalRef::Window(window.r()), self, size) + }); + Some(CanvasRenderingContext2DOrWebGLRenderingContext::eCanvasRenderingContext2D(Unrooted::from_temporary(context_2d))) + } + "webgl" | "experimental-webgl" => { + let context_webgl = self.context_webgl.or_init(|| { + let window = window_from_node(self).root(); + let size = self.get_size(); + WebGLRenderingContext::new(GlobalRef::Window(window.r()), self, size) + }); + Some(CanvasRenderingContext2DOrWebGLRenderingContext::eWebGLRenderingContext(Unrooted::from_temporary(context_webgl))) + } + _ => return None + } + } } impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> { @@ -165,11 +214,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> { }; if recreate { - let (w, h) = (self.width.get() as i32, self.height.get() as i32); - match self.context.get() { - Some(context) => context.root().r().recreate(Size2D(w, h)), - None => () - } + self.recreate_contexts(); } } @@ -192,12 +237,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLCanvasElement> { }; if recreate { - let (w, h) = (self.width.get() as i32, self.height.get() as i32); - match self.context.get() { - Some(context) => context.root().r().recreate(Size2D(w, h)), - None => () - } + self.recreate_contexts(); } } } - |