aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/htmlcanvaselement.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/htmlcanvaselement.rs')
-rw-r--r--components/script/dom/htmlcanvaselement.rs106
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();
}
}
}
-