1 use webcore::value::{Reference, ConversionError};
2 use webcore::try_from::{TryFrom, TryInto};
3 use webcore::value::{Undefined, Value};
4 use webapi::html_elements::{CanvasElement, ImageElement};
5 use webapi::html_element::IHtmlElement;
6 use webapi::dom_exception::{SyntaxError, IndexSizeError, InvalidStateError, SecurityError, NotSupportedError};
7 use webapi::error::TypeError;
8 
9 /// Trait implemented by rendering contexts which can be obtained from a canvas.
10 pub trait RenderingContext {
11     /// Type of error which can occur whilst creating this context
12     type Error;
13     /// Name which identifies this kind of rendering context.
from_canvas(canvas: &CanvasElement) -> Result<Self, Self::Error> where Self: Sized14     fn from_canvas(canvas: &CanvasElement) -> Result<Self, Self::Error> where Self: Sized;
15 }
16 
17 /// Used for drawing rectangles, text, images and other objects onto the canvas element.
18 ///
19 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D)
20 // https://html.spec.whatwg.org/#canvasrenderingcontext2d
21 #[derive(Clone, Debug, PartialEq, Eq, ReferenceType)]
22 #[reference(instance_of = "CanvasRenderingContext2D")]
23 pub struct CanvasRenderingContext2d(Reference);
24 
25 /// The CanvasGradient struct represents an opaque object describing a gradient.
26 /// It is returned by the methods CanvasRenderingContext2D.createLinearGradient() or
27 /// CanvasRenderingContext2D.createRadialGradient().
28 ///
29 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient)
30 // https://html.spec.whatwg.org/#canvasgradient
31 #[derive(Clone, Debug, Eq, PartialEq, ReferenceType)]
32 #[reference(instance_of = "CanvasGradient")]
33 pub struct CanvasGradient(Reference);
34 
35 /// The CanvasPattern struct represents an opaque object describing a pattern, based on an image,
36 /// a canvas or a video, created by the CanvasRenderingContext2D.createPattern() method.
37 /// Intentionally blank, no non-experimental properties or methods.
38 ///
39 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern)
40 // https://html.spec.whatwg.org/#canvaspattern
41 #[derive(Clone, Debug, Eq, PartialEq, ReferenceType)]
42 #[reference(instance_of = "CanvasPattern")]
43 pub struct CanvasPattern(Reference);
44 
45 /// The ImageData struct represents the underlying pixel data of an area of a `<canvas>` element.
46 /// You can create a new instance by calling [`CanvasRenderingContext2d::create_image_data`](struct.CanvasRenderingContext2d.html#method.create_image_data)
47 /// or [`CanvasRenderingContext2d::create_image_data_size_of`](struct.CanvasRenderingContext2d.html#method.create_image_data_size_of).
48 ///
49 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ImageData)
50 // https://html.spec.whatwg.org/#imagedata
51 #[derive(Clone, Debug, ReferenceType)]
52 #[reference(instance_of = "ImageData")]
53 pub struct ImageData(Reference);
54 
55 /// The TextMetrics struct represents the dimension of a text in the canvas, as created by the CanvasRenderingContext2D.measureText() method.
56 ///
57 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics)
58 // https://html.spec.whatwg.org/#textmetrics
59 #[derive(Clone, Debug, ReferenceType)]
60 #[reference(instance_of = "TextMetrics")]
61 pub struct TextMetrics(Reference);
62 
63 /// The type of compositing operation to apply when drawing new shapes
64 ///
65 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation)
66 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
67 pub enum CompositeOperation {
68     /// Draws new shapes over existing canvas content
69     SourceOver,
70     /// Draws new shapes over existing canvas content, but only where existing canvas content overlaps. Anything not in that area becomes transparent.
71     SourceIn,
72     /// New shapes are drawn where there is no existing canvas content. Everything else (including old canvas content) is made transparent.
73     SourceOut,
74     /// Draws new shapes only where there is existing canvas content, over existing canvas content
75     SourceAtop,
76     /// Draws new shapes behind existing canvas content
77     DestinationOver,
78     /// Keeps existing canvas content where it overlaps with the new shape. Everything outside the overlap is made transparent.
79     DestinationIn,
80     /// The existing content is kept where it doesn't overlap with the new shape. Everything else, including the new shape area, is made transparent.
81     DestinationOut,
82     /// Existing content is kept only where it overlaps with the new shape. The new shape is drawn behind the existing content.
83     DestinationAtop,
84     /// Where both shapes overlap, the new color is determined by adding color values
85     Lighter,
86     /// Only the new shape is shown
87     Copy,
88     /// Where both shapes overlap, make it transparent
89     Xor,
90     /// The pixels of the new and old layer are multiplied. (Pixel values are in the range of [0,1], so this makes a darker picture)
91     Multiply,
92     /// Pixels from both new and old are inverted, multiplied together, then inverted again. (Pixel values are in the range of [0,1], so this makes a lighter picture)
93     Screen,
94     /// Applies Multiply to dark colors in the existing content, and Screen to bright colors in the existing content
95     Overlay,
96     /// Retains the darkest pixels
97     Darken,
98     /// Retains the lighest pixels
99     Lighten,
100     /// Divides the bottom layer by the inverted top layer.
101     ColorDodge,
102     /// Divides the inverted bottom layer by the top layer, and then inverts the result.
103     ColorBurn,
104     /// A combination of multiply and screen like overlay, but with top and bottom layer swapped.
105     HardLight,
106     /// A softer version of hard-light. Pure black or white does not result in pure black or white.
107     SoftLight,
108     /// Subtracts the bottom layer from the top layer or the other way round to always get a positive value.
109     Difference,
110     /// Like difference, but with lower contrast.
111     Exclusion,
112     /// Preserves the luma and chroma of the bottom layer, while adopting the hue of the top layer.
113     Hue,
114     /// Preserves the luma and hue of the bottom layer, while adopting the chroma of the top layer.
115     Saturation,
116     /// Preserves the luma of the bottom layer, while adopting the hue and chroma of the top layer.
117     Color,
118     /// Preserves the hue and chroma of the bottom layer, while adopting the luma of the top layer.
119     Luminosity
120 }
121 
122 /// The algorithm by which to determine if a point is inside a path or outside a path.
123 ///
124 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill)
125 // https://html.spec.whatwg.org/#canvasfillrule
126 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
127 pub enum FillRule {
128     /// [Non-zero winding rule](https://en.wikipedia.org/wiki/Nonzero-rule)
129     NonZero,
130     /// [Even-odd winding rule](https://en.wikipedia.org/wiki/Even%E2%80%93odd_rule)
131     EvenOdd
132 }
133 
134 /// Certain style functions can return multiple types
135 #[derive(Debug, Clone, PartialEq, Eq)]
136 pub enum CanvasStyle {
137     /// String representing the style
138     String(String),
139     /// CanvasGradient representing the style
140     CanvasGradient(CanvasGradient),
141     /// CanvasPattern representing the style
142     CanvasPattern(CanvasPattern),
143 }
144 
145 /// How the end points of every line are drawn.
146 ///
147 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)
148 // https://html.spec.whatwg.org/#canvaslinecap
149 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
150 pub enum LineCap {
151     /// The ends of lines are squared off at the endpoints
152     Butt,
153     /// The ends of lines are rounded
154     Round,
155     /// The ends of lines are squared off by adding a box with an equal width and half the height of the line's thickness.
156     Square
157 }
158 
159 /// determines how two connecting segments (of lines, arcs or curves) with non-zero lengths in a shape are
160 /// joined together (degenerate segments with zero lengths, whose specified endpoints and control points are
161 /// exactly at the same position, are skipped).
162 ///
163 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
164 // https://html.spec.whatwg.org/#canvaslinejoin
165 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
166 pub enum LineJoin {
167     /// Fills an additional triangular area
168     Bevel,
169     /// Rounds off the corners of a shape
170     Round,
171     /// Connected segments are joined by extending their outside edges to connect at a single point
172     Miter
173 }
174 
175 /// An enum indicating how to repeat the image.
176 ///
177 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern)
178 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
179 pub enum Repetition {
180     /// Repeat in both directions
181     Repeat,
182     /// Repeat horizontally
183     RepeatX,
184     /// Repeat vertically
185     RepeatY,
186     /// Don't repeat
187     NoRepeat
188 }
189 
190 /// Specifies text alignment
191 ///
192 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign)
193 // https://html.spec.whatwg.org/#canvastextalign
194 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
195 pub enum TextAlign {
196     /// Text is left-aligned
197     Left,
198     /// Text is right-aligned
199     Right,
200     /// Text is centered
201     Center,
202     /// Text is aligned at the normal start of the line for the current locale
203     Start,
204     /// Text is aligned at the normal end of the line for the current locale
205     End
206 }
207 
208 /// Text baseline being used when drawing text
209 ///
210 /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline)
211 // https://html.spec.whatwg.org/#canvastextbaseline
212 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
213 pub enum TextBaseline {
214     /// Text baseline is top of the em square
215     Top,
216     /// Text baseline is the hanging baseline.
217     Hanging,
218     /// Text baseline is the middle of the em square
219     Middle,
220     /// Text baseline is the normal alphabetic baseline. (default)
221     Alphabetic,
222     /// Text baseline is the ideographic baseline
223     Ideographic,
224     /// Text baseline is the bottom of the bounding box.
225     Bottom
226 }
227 
228 error_enum_boilerplate! {
229     /// A enum of the exceptions that CanvasGradient.add_color_stop() may throw
230     // https://html.spec.whatwg.org/multipage/canvas.html#dom-canvasgradient-addcolorstop
231     AddColorStopError,
232     /// A SyntaxError if the color could not be parsed as a valid CSS color
233     SyntaxError,
234     /// An IndexSizeError if the offset was not between 0 and 1, inclusive
235     IndexSizeError
236 }
237 
238 error_enum_boilerplate! {
239     /// A enum of the exceptions that CanvasRenderingContext2D.draw_image() and similar may throw
240     DrawImageError,
241     /// An IndexSizeError if the source or destination rectangle has an width or height of 0
242     IndexSizeError,
243     /// An InvalidStateError if the image has no image data
244     InvalidStateError,
245     /// A NotSupportedError
246     NotSupportedError,
247     /// A TypeError if the specified source element isn't supported
248     TypeError
249 }
250 
251 error_enum_boilerplate! {
252     /// A enum of the exceptions that CanvasRenderingContext2D.get_image_data() may throw
253     GetImageDataError,
254     /// An IndexSizeError if thw width or height is 0
255     IndexSizeError,
256     /// A SecurityError
257     SecurityError
258 }
259 
260 impl TryFrom<Value> for CanvasStyle {
261     type Error = ConversionError;
262 
263     /// Performs the conversion.
try_from(value: Value) -> Result<Self, Self::Error>264     fn try_from(value: Value) -> Result<Self, Self::Error> {
265         if let Ok(v) = String::try_from(value.clone()) {
266             return Ok(CanvasStyle::String(v));
267         }
268         if let Ok(v) = CanvasGradient::try_from(value.clone()) {
269             return Ok(CanvasStyle::CanvasGradient(v));
270         }
271         if let Ok(v) = CanvasPattern::try_from(value.clone()) {
272             return Ok(CanvasStyle::CanvasPattern(v));
273         }
274         Err(::webcore::value::ConversionError::type_mismatch( &value, "String, CanvasGradient or CanvasPattern".into() ))
275     }
276 }
277 
278 impl Default for FillRule {
default() -> FillRule279     fn default() -> FillRule { FillRule::NonZero }
280 }
281 
282 impl Default for Repetition {
default() -> Repetition283     fn default() -> Repetition { Repetition::Repeat }
284 }
285 
286 impl RenderingContext for CanvasRenderingContext2d {
287     type Error = ConversionError;
from_canvas(canvas: &CanvasElement) -> Result<Self, ConversionError>288     fn from_canvas(canvas: &CanvasElement) -> Result<Self, ConversionError> {
289         js!(
290             return @{canvas}.getContext("2d");
291         ).try_into()
292     }
293 }
294 
295 impl CanvasGradient {
296 
297     /// Adds a new stop, defined by an offset and a color, to the gradient. If the offset is
298     /// not between 0 and 1, an INDEX_SIZE_ERR is returned, if the color can't be parsed as a
299     /// CSS <color>, a SYNTAX_ERR is returned.
300     ///
301     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasGradient/addColorStop)
302     // https://html.spec.whatwg.org/#2dcontext:dom-canvasgradient-addcolorstop
add_color_stop(&self, offset: f64, color: &str) -> Result<(), AddColorStopError>303     pub fn add_color_stop(&self, offset: f64, color: &str) -> Result<(), AddColorStopError> {
304         js_try! ( @(no_return)
305             @{&self.0}.addColorStop(@{offset}, @{color});
306         ).unwrap()
307     }
308 }
309 
310 impl ImageData {
311 
312     /*
313     /// Returns a Uint8ClampedArray representing a one-dimensional array containing the data in the RGBA order,
314     /// with integer values between 0 and 255 (included).
315     ///
316     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ImageData/data)
317     // https://html.spec.whatwg.org/#2dcontext:dom-imagedata-data
318     // TODO: Return Uint8ClampedArray reference PR 96: https://github.com/koute/stdweb/pull/96
319 
320     pub fn get_data(&self) -> TypedArray<u8> {
321         js! (
322             return @{&self.0}.data;
323         ).try_into().unwrap()
324     }*/
325 
326     /// Returns the number of rows in the image data object.
327     ///
328     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ImageData/height)
329     // https://html.spec.whatwg.org/#2dcontext:dom-imagedata-height
get_height(&self) -> u32330     pub fn get_height(&self) -> u32 {
331         js! (
332             return @{&self.0}.height;
333         ).try_into().unwrap()
334     }
335 
336     /// Returns the number of pixels per row in the image data object.
337     ///
338     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/ImageData/width)
339     // https://html.spec.whatwg.org/#2dcontext:dom-imagedata-width
get_width(&self) -> u32340     pub fn get_width(&self) -> u32 {
341         js! (
342             return @{&self.0}.width;
343         ).try_into().unwrap()
344     }
345 }
346 
347 impl CanvasRenderingContext2d {
348 
349     /// The CanvasRenderingContext2D.canvas property is a read-only reference to the HTMLCanvasElement
350     /// object that is associated with the context. It might be null if there is no association with an <canvas> element.
351     ///
352     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/canvas)
353     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-canvas
get_canvas(&self) -> CanvasElement354     pub fn get_canvas(&self) -> CanvasElement {
355         js! (
356             return @{&self.0}.canvas;
357         ).try_into().unwrap()
358     }
359 
360     /// The CanvasRenderingContext2D.fillStyle property of the Canvas 2D API specifies the color or style to use inside shapes.
361     /// The default is #000 (black).
362     ///
363     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle)
364     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-fillstyle
get_fill_style(&self) -> CanvasStyle365     pub fn get_fill_style(&self) -> CanvasStyle {
366         js! (
367             return @{&self.0}.fillStyle
368         ).try_into().unwrap()
369     }
370 
371     /// The CanvasRenderingContext2D.fillStyle property of the Canvas 2D API specifies the color or style to use inside shapes.
372     /// The default is #000 (black).
373     ///
374     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle)
375     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-fillstyle
set_fill_style_color(&self, color: &str)376     pub fn set_fill_style_color(&self, color: &str){
377         js! { @(no_return)
378             @{&self.0}.fillStyle = @{color};
379         }
380     }
381 
382     /// The CanvasRenderingContext2D.fillStyle property of the Canvas 2D API specifies the color or style to use inside shapes.
383     /// The default is #000 (black).
384     ///
385     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle)
386     // https://html.spec.whatwg.org/#dom-context-2d-fillstyle
set_fill_style_gradient(&self, gradient: &CanvasGradient)387     pub fn set_fill_style_gradient(&self, gradient: &CanvasGradient){
388         js! { @(no_return)
389             @{&self.0}.fillStyle = @{gradient};
390         }
391     }
392 
393     /// The CanvasRenderingContext2D.fillStyle property of the Canvas 2D API specifies the color or style to use inside shapes.
394     /// The default is #000 (black).
395     ///
396     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle)
397     // https://html.spec.whatwg.org/#dom-context-2d-fillstyle
set_fill_style_pattern(&self, pattern: &CanvasPattern)398     pub fn set_fill_style_pattern(&self, pattern: &CanvasPattern){
399         js! { @(no_return)
400             @{&self.0}.fillStyle = @{pattern};
401         }
402     }
403 
404     /// The CanvasRenderingContext2D.font property of the Canvas 2D API specifies the current
405     /// text style being used when drawing text. This string uses the same syntax as the CSS
406     /// font specifier. The default font is 10px sans-serif.
407     ///
408     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font)
409     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-font
get_font(&self) -> String410     pub fn get_font(&self) -> String {
411         js! (
412             return @{&self.0}.font
413         ).try_into().unwrap()
414     }
415 
416     /// The CanvasRenderingContext2D.font property of the Canvas 2D API specifies the current
417     /// text style being used when drawing text. This string uses the same syntax as the CSS
418     /// font specifier. The default font is 10px sans-serif.
419     ///
420     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font)
421     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-font
set_font(&self, font: &str)422     pub fn set_font(&self, font: &str) {
423         js! { @(no_return)
424             @{&self.0}.font = @{font};
425         }
426     }
427 
428     /// The CanvasRenderingContext2D.globalAlpha property of the Canvas 2D API specifies the alpha
429     /// value that is applied to shapes and images before they are drawn onto the canvas.
430     /// The value is in the range from 0.0 (fully transparent) to 1.0 (fully opaque).
431     ///
432     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha)
433     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-globalalpha
get_global_alpha(&self) -> f64434     pub fn get_global_alpha(&self) -> f64 {
435         js! (
436             return @{&self.0}.globalAlpha
437         ).try_into().unwrap()
438     }
439 
440     /// The CanvasRenderingContext2D.globalAlpha property of the Canvas 2D API specifies the alpha
441     /// value that is applied to shapes and images before they are drawn onto the canvas.
442     /// The value is in the range from 0.0 (fully transparent) to 1.0 (fully opaque).
443     ///
444     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalAlpha)
445     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-globalalpha
set_global_alpha(&self, global_alpha: f64)446     pub fn set_global_alpha(&self, global_alpha: f64) {
447         js! { @(no_return)
448             @{&self.0}.globalAlpha = @{global_alpha};
449         }
450     }
451 
452     /// The CanvasRenderingContext2D.globalCompositeOperation property of the Canvas 2D API sets the
453     /// type of compositing operation to apply when drawing new shapes, where type is a string identifying
454     /// which of the compositing or blending mode operations to use.
455     ///
456     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation)
457     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-globalcompositeoperation
get_global_composite_operation(&self) -> CompositeOperation458     pub fn get_global_composite_operation(&self) -> CompositeOperation {
459         let composite_operation_str: String = js! (
460             return @{&self.0}.globalCompositeOperation
461         ).try_into().unwrap();
462         match composite_operation_str.as_ref() {
463             "source-over" => CompositeOperation::SourceOver,
464             "source-in" => CompositeOperation::SourceIn,
465             "source-out" => CompositeOperation::SourceOut,
466             "source-atop" => CompositeOperation::SourceAtop,
467             "destination-over" => CompositeOperation::DestinationOver,
468             "destination-in" => CompositeOperation::DestinationIn,
469             "destination-out" => CompositeOperation::DestinationOut,
470             "destination-atop" => CompositeOperation::DestinationAtop,
471             "lighter" => CompositeOperation::Lighter,
472             "copy" => CompositeOperation::Copy,
473             "xor" => CompositeOperation::Xor,
474             "multiply" => CompositeOperation::Multiply,
475             "screen" => CompositeOperation::Screen,
476             "overlay" => CompositeOperation::Overlay,
477             "darken" => CompositeOperation::Darken,
478             "lighten" => CompositeOperation::Lighten,
479             "color-dodge" => CompositeOperation::ColorDodge,
480             "color-burn" => CompositeOperation::ColorBurn,
481             "hard-light" => CompositeOperation::HardLight,
482             "soft-light" => CompositeOperation::SoftLight,
483             "difference" => CompositeOperation::Difference,
484             "exclusion" => CompositeOperation::Exclusion,
485             "hue" => CompositeOperation::Hue,
486             "saturation" => CompositeOperation::Saturation,
487             "color" => CompositeOperation::Color,
488             "luminosity" => CompositeOperation::Luminosity,
489             _ => panic!("Unexpected globalCompositeOperation value: {:?}", composite_operation_str),
490         }
491     }
492 
493     /// The CanvasRenderingContext2D.globalCompositeOperation property of the Canvas 2D API sets the
494     /// type of compositing operation to apply when drawing new shapes, where type is a string identifying
495     /// which of the compositing or blending mode operations to use.
496     ///
497     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation)
498     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-globalcompositeoperation
set_global_composite_operation(&self, composite_operation: CompositeOperation)499     pub fn set_global_composite_operation(&self, composite_operation: CompositeOperation) {
500         let composite_string = match composite_operation {
501             CompositeOperation::SourceOver => "source-over",
502             CompositeOperation::SourceIn => "source-in",
503             CompositeOperation::SourceOut => "source-out",
504             CompositeOperation::SourceAtop => "source-atop",
505             CompositeOperation::DestinationOver => "destination-over",
506             CompositeOperation::DestinationIn => "destination-in",
507             CompositeOperation::DestinationOut => "destination-out",
508             CompositeOperation::DestinationAtop => "destination-atop",
509             CompositeOperation::Lighter => "lighter",
510             CompositeOperation::Copy => "copy",
511             CompositeOperation::Xor => "xor",
512             CompositeOperation::Multiply => "multiply",
513             CompositeOperation::Screen => "screen",
514             CompositeOperation::Overlay => "overlay",
515             CompositeOperation::Darken => "darken",
516             CompositeOperation::Lighten => "lighten",
517             CompositeOperation::ColorDodge => "color-dodge",
518             CompositeOperation::ColorBurn => "color-burn",
519             CompositeOperation::HardLight => "hard-light",
520             CompositeOperation::SoftLight => "soft-light",
521             CompositeOperation::Difference => "difference",
522             CompositeOperation::Exclusion => "exclusion",
523             CompositeOperation::Hue => "hue",
524             CompositeOperation::Saturation => "saturation",
525             CompositeOperation::Color => "color",
526             CompositeOperation::Luminosity => "luminosity"
527         };
528         js! {@(no_return)
529             @{&self.0}.globalCompositeOperation = @{composite_string};
530         }
531     }
532 
533     /// Determines how the end points of every line are drawn.
534     /// There are three possible values for this property and those are: butt, round and square.
535     /// By default this property is set to butt.
536     ///
537     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)
538     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linecap
get_line_cap(&self) -> LineCap539     pub fn get_line_cap(&self) -> LineCap {
540         let line_cap_str: String = js! (
541             return @{&self.0}.lineCap
542         ).try_into().unwrap();
543 
544         match line_cap_str.as_ref() {
545             "butt" => LineCap::Butt,
546             "round" => LineCap::Round,
547             "square" => LineCap::Square,
548             _ => panic!("Unexpected lineCap value: {:?}", line_cap_str),
549         }
550     }
551 
552     /// Determines how the end points of every line are drawn.
553     /// There are three possible values for this property and those are: butt, round and square.
554     /// By default this property is set to butt.
555     ///
556     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap)
557     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linecap
set_line_cap(&self, line_cap: LineCap)558     pub fn set_line_cap(&self, line_cap: LineCap) {
559         let line_cap_string = match line_cap {
560             LineCap::Butt => "butt",
561             LineCap::Round => "round",
562             LineCap::Square => "square",
563         };
564         js! { @(no_return)
565             @{&self.0}.lineCap = @{line_cap_string};
566         }
567     }
568 
569     /// Sets the line dash pattern offset or "phase" to achieve a "marching ants" effect, for example.
570     ///
571     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
572     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linedashoffset
get_line_dash_offset(&self) -> f64573     pub fn get_line_dash_offset(&self) -> f64 {
574         js! (
575             return @{&self.0}.lineDashOffset;
576         ).try_into().unwrap()
577     }
578 
579     /// Sets the line dash pattern offset or "phase" to achieve a "marching ants" effect, for example.
580     ///
581     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset)
582     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linedashoffset
set_line_dash_offset(&self, line_dash_offset: f64)583     pub fn set_line_dash_offset(&self, line_dash_offset: f64) {
584         js! { @(no_return)
585             @{&self.0}.lineDashOffset = @{line_dash_offset};
586         }
587     }
588 
589     /// Determines how two connecting segments (of lines, arcs or curves) with non-zero lengths in a shape are
590     /// joined together (degenerate segments with zero lengths, whose specified endpoints and control points are
591     /// exactly at the same position, are skipped).
592     ///
593     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
594     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linejoin
get_line_join(&self) -> LineJoin595     pub fn get_line_join(&self) -> LineJoin {
596         let line_join_str: String = js! (
597             return @{&self.0}.lineJoin;
598         ).try_into().unwrap();
599         match line_join_str.as_ref() {
600             "bevel" => LineJoin::Bevel,
601             "round" => LineJoin::Round,
602             "miter" => LineJoin::Miter,
603             _ => panic!("Unexpected lineJoin value: {:?}", line_join_str),
604         }
605     }
606 
607     /// Determines how two connecting segments (of lines, arcs or curves) with non-zero lengths in a shape are
608     /// joined together (degenerate segments with zero lengths, whose specified endpoints and control points are
609     /// exactly at the same position, are skipped).
610     ///
611     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin)
612     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linejoin
set_line_join(&self, line_join: LineJoin)613     pub fn set_line_join(&self, line_join: LineJoin) {
614         let line_join_str = match line_join {
615             LineJoin::Bevel => "bevel",
616             LineJoin::Round => "round",
617             LineJoin::Miter => "miter",
618         };
619         js! { @(no_return)
620             @{&self.0}.lineJoin = @{line_join_str};
621         }
622     }
623 
624     /// Sets the thickness of lines in space units. When getting, it returns the current value (1.0 by default).
625     /// When setting, zero, negative, Infinity and NaN values are ignored; otherwise the current value is set to the new value.
626     ///
627     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth)
628     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linewidth
get_line_width(&self) -> f64629     pub fn get_line_width(&self) -> f64 {
630         js! (
631             return @{&self.0}.lineWidth;
632         ).try_into().unwrap()
633     }
634 
635     /// Sets the thickness of lines in space units. When getting, it returns the current value (1.0 by default).
636     /// When setting, zero, negative, Infinity and NaN values are ignored; otherwise the current value is set to the new value.
637     ///
638     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth)
639     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-linewidth
set_line_width(&self, line_width: f64)640     pub fn set_line_width(&self, line_width: f64) {
641         js! { @(no_return)
642             @{&self.0}.lineWidth = @{line_width};
643         }
644     }
645 
646     /// sets the miter limit ratio in space units. When getting, it returns the current value (10.0 by default).
647     /// When setting, zero, negative, Infinity and NaN values are ignored; otherwise the current value is set to the new value.
648     ///
649     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/miterLimit)
650     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-miterlimit
get_miter_limit(&self) -> f64651     pub fn get_miter_limit(&self) -> f64 {
652         js! (
653             return @{&self.0}.miterLimit;
654         ).try_into().unwrap()
655     }
656 
657     /// sets the miter limit ratio in space units. When getting, it returns the current value (10.0 by default).
658     /// When setting, zero, negative, Infinity and NaN values are ignored; otherwise the current value is set to the new value.
659     ///
660     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/miterLimit)
661     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-miterlimit
set_miter_limit(&self, miter_limit: f64)662     pub fn set_miter_limit(&self, miter_limit: f64) {
663         js! { @(no_return)
664             @{&self.0}.miterLimit = @{miter_limit};
665         }
666     }
667 
668     /// Specifies the level of the blurring effect; this value doesn't correspond to a number of pixels and is not
669     /// affected by the current transformation matrix. The default value is 0.
670     ///
671     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowBlur)
672     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowblur
get_shadow_blur(&self) -> f64673     pub fn get_shadow_blur(&self) -> f64 {
674         js! (
675             return @{&self.0}.shadowBlur;
676         ).try_into().unwrap()
677     }
678 
679     /// Specifies the level of the blurring effect; this value doesn't correspond to a number of pixels and is not
680     /// affected by the current transformation matrix. The default value is 0.
681     ///
682     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowBlur)
683     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowblur
set_shadow_blur(&self, shadow_blur: f64)684     pub fn set_shadow_blur(&self, shadow_blur: f64) {
685         js! { @(no_return)
686             @{&self.0}.shadowBlur = @{shadow_blur};
687         }
688     }
689 
690     /// Specifies the color of the shadow.
691     ///
692     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowColor)
693     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowcolor
get_shadow_color(&self) -> String694     pub fn get_shadow_color(&self) -> String {
695         js! (
696             return @{&self.0}.shadowColor;
697         ).try_into().unwrap()
698     }
699 
700     /// Specifies the color of the shadow.
701     ///
702     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowColor)
703     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowcolor
set_shadow_color(&self, shadow_color: &str)704     pub fn set_shadow_color(&self, shadow_color: &str) {
705         js! { @(no_return)
706             @{&self.0}.shadowColor = @{shadow_color};
707         }
708     }
709 
710     /// Specifies the distance that the shadow will be offset in horizontal distance.
711     ///
712     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetX)
713     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowoffsetx
get_shadow_offset_x(&self) -> f64714     pub fn get_shadow_offset_x(&self) -> f64 {
715         js! (
716             return @{&self.0}.shadowOffsetX;
717         ).try_into().unwrap()
718     }
719 
720     /// Specifies the distance that the shadow will be offset in horizontal distance.
721     ///
722     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetX)
723     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowoffsetx
set_shadow_offset_x(&self, shadow_offset_x: f64)724     pub fn set_shadow_offset_x(&self, shadow_offset_x: f64) {
725         js! { @(no_return)
726             @{&self.0}.shadowOffsetX = @{shadow_offset_x};
727         }
728     }
729 
730     /// Specifies the distance that the shadow will be offset in vertical distance.
731     ///
732     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetY)
733     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowoffsetx
get_shadow_offset_y(&self) -> f64734     pub fn get_shadow_offset_y(&self) -> f64 {
735         js! (
736             return @{&self.0}.shadowOffsetY;
737         ).try_into().unwrap()
738     }
739 
740     /// Specifies the distance that the shadow will be offset in vertical distance.
741     ///
742     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/shadowOffsetY)
743     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-shadowoffsetx
set_shadow_offset_y(&self, shadow_offset_y: f64)744     pub fn set_shadow_offset_y(&self, shadow_offset_y: f64) {
745         js! { @(no_return)
746             @{&self.0}.shadowOffsetY = @{shadow_offset_y};
747         }
748     }
749 
750     /// Specifies the color or style to use for the lines around shapes. The default is #000 (black).
751     ///
752     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle)
753     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-strokestyle
get_stroke_style(&self) -> CanvasStyle754     pub fn get_stroke_style(&self) -> CanvasStyle {
755         js! (
756             return @{&self.0}.strokeStyle;
757         ).try_into().unwrap()
758     }
759 
760     /// Specifies the color or style to use for the lines around shapes. The default is #000 (black).
761     ///
762     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle)
763     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-strokestyle
set_stroke_style_color(&self, color: &str)764     pub fn set_stroke_style_color(&self, color: &str){
765         js! { @(no_return)
766             @{&self.0}.strokeStyle = @{color};
767         }
768     }
769 
770     /// Specifies the color or style to use for the lines around shapes. The default is #000 (black).
771     ///
772     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle)
773     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-strokestyle
set_stroke_style_gradient(&self, gradient: &CanvasGradient)774     pub fn set_stroke_style_gradient(&self, gradient: &CanvasGradient){
775         js! { @(no_return)
776             @{&self.0}.strokeStyle = @{gradient};
777         }
778     }
779 
780     /// Specifies the color or style to use for the lines around shapes. The default is #000 (black).
781     ///
782     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle)
783     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-strokestyle
set_stroke_style_pattern(&self, pattern: &CanvasPattern)784     pub fn set_stroke_style_pattern(&self, pattern: &CanvasPattern){
785         js! { @(no_return)
786             @{&self.0}.strokeStyle = @{pattern};
787         }
788     }
789 
790     /// specifies the current text alignment being used when drawing text.
791     /// Beware that the alignment is based on the x value of the fillText() method.
792     /// So if textAlign is "center", then the text would be drawn at x - (width / 2).
793     ///
794     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign)
795     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-textalign
get_text_align(&self) -> TextAlign796     pub fn get_text_align(&self) -> TextAlign {
797         let text_align_str: String = js! (
798             return @{&self.0}.textAlign;
799         ).try_into().unwrap();
800         match text_align_str.as_ref() {
801             "center" => TextAlign::Center,
802             "end" => TextAlign::End,
803             "left" => TextAlign::Left,
804             "right" => TextAlign::Right,
805             "start" => TextAlign::Start,
806             _ => panic!("Unexpected textAlign value: {:?}", text_align_str),
807         }
808     }
809 
810     /// specifies the current text alignment being used when drawing text.
811     /// Beware that the alignment is based on the x value of the fillText() method.
812     /// So if textAlign is "center", then the text would be drawn at x - (width / 2).
813     ///
814     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign)
815     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-textalign
set_text_align(&self, text_align: TextAlign)816     pub fn set_text_align(&self, text_align: TextAlign) {
817         let text_align_str = match text_align {
818             TextAlign::Center => "center",
819             TextAlign::End => "end",
820             TextAlign::Left => "left",
821             TextAlign::Right => "right",
822             TextAlign::Start => "start",
823         };
824         js! { @(no_return)
825             @{&self.0}.textAlign = @{text_align_str};
826         }
827     }
828 
829     /// Specifies the current text baseline being used when drawing text.
830     ///
831     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline)
832     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-textbaseline
get_text_baseline(&self) -> TextBaseline833     pub fn get_text_baseline(&self) -> TextBaseline {
834         let text_baseline_str: String = js! (
835             return @{&self.0}.textBaseline;
836         ).try_into().unwrap();
837         match text_baseline_str.as_ref() {
838             "alphabetic" => TextBaseline::Alphabetic,
839             "bottom" => TextBaseline::Bottom,
840             "hanging" => TextBaseline::Hanging,
841             "ideographic" => TextBaseline::Ideographic,
842             "middle" => TextBaseline::Middle,
843             "top" => TextBaseline::Top,
844             _ => panic!("Unexpected textBaseLine value: {:?}", text_baseline_str)
845         }
846     }
847 
848     /// Specifies the current text baseline being used when drawing text.
849     ///
850     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline)
851     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-textbaseline
set_text_baseline(&self, text_baseline: TextBaseline)852     pub fn set_text_baseline(&self, text_baseline: TextBaseline) {
853         let text_baseline_str = match text_baseline {
854             TextBaseline::Alphabetic => "alphabetic",
855             TextBaseline::Bottom => "bottom",
856             TextBaseline::Hanging => "hanging",
857             TextBaseline::Ideographic => "ideographic",
858             TextBaseline::Middle => "middle",
859             TextBaseline::Top => "top"
860         };
861         js! { @(no_return)
862             @{&self.0}.textBaseline = @{text_baseline_str};
863         }
864     }
865 
866     /// Adds an arc to the path which is centered at (x, y) position with radius r starting
867     /// at startAngle and ending at endAngle going in the given direction by anticlockwise
868     /// (defaulting to clockwise).
869     ///
870     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arc)
871     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-arc
arc(&self, x: f64, y: f64, radius: f64, start_angle: f64, end_angle: f64, anticlockwise: bool)872     pub fn arc(&self, x: f64, y: f64, radius: f64, start_angle: f64, end_angle: f64, anticlockwise: bool) {
873         js! { @(no_return)
874             @{&self.0}.arc(@{x}, @{y}, @{radius}, @{start_angle}, @{end_angle}, @{anticlockwise});
875         }
876     }
877 
878     /// Adds an arc to the path with the given control points and radius.
879     /// The arc drawn will be a part of a circle, never elliptical.
880     /// Typical use could be making a rounded corner.
881     /// One way to think about the arc drawn is to imagine two straight segments, from the
882     /// starting point (latest point in current path) to the first control point, and then
883     /// from the first control point to the second control point. These two segments form
884     /// a sharp corner with the first control point being in the corner. Using arcTo, the
885     /// corner will instead be an arc with the given radius.
886     /// The arc is tangential to both segments, which can sometimes produce surprising results,
887     /// e.g. if the radius given is larger than the distance between the starting point and the first control point.
888     /// If the radius specified doesn't make the arc meet the starting point (latest point in the current path),
889     /// the starting point is connected to the arc with a straight line segment.
890     ///
891     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/arcTo)
892     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-arcto
arc_to(&self, x1: f64, y1: f64, x2: f64, y2: f64, radius: f64) -> Result<(), IndexSizeError>893     pub fn arc_to(&self, x1: f64, y1: f64, x2: f64, y2: f64, radius: f64) -> Result<(), IndexSizeError> {
894         js_try! ( @(no_return)
895             @{&self.0}.arcTo(@{x1}, @{y1}, @{x2}, @{y2}, @{radius});
896         ).unwrap()
897     }
898 
899     /// Starts a new path by emptying the list of sub-paths. Call this method when you want to create a new path.
900     ///
901     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath)
902     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-beginpath
begin_path(&self)903     pub fn begin_path(&self) {
904         js! { @(no_return)
905             @{&self.0}.beginPath();
906         }
907     }
908 
909     /// Adds a cubic Bézier curve to the path. It requires three points. The first two points
910     /// are control points and the third one is the end point. The starting point is the last
911     /// point in the current path, which can be changed using moveTo() before creating the Bézier curve.
912     ///
913     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo)
914     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-beziercurveto
bezier_curve_to(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64)915     pub fn bezier_curve_to(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) {
916         js! { @(no_return)
917             @{&self.0}.bezierCurveTo(@{cp1x}, @{cp1y}, @{cp2x}, @{cp2y}, @{x}, @{y});
918         }
919     }
920 
921     /// Sets all pixels in the rectangle defined by starting point (x, y) and size (width, height)
922     /// to transparent black, erasing any previously drawn content.
923     ///
924     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clearRect)
925     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-clearrect
clear_rect(&self, x: f64, y: f64, width: f64, height: f64)926     pub fn clear_rect(&self, x: f64, y: f64, width: f64, height: f64) {
927         js! { @(no_return)
928             @{&self.0}.clearRect(@{x}, @{y}, @{width}, @{height});
929         }
930     }
931 
932     /// Turns the path currently being built into the current clipping path.
933     /// ctx.clip(path, fillRule) is not supported because [(Path2D)](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) is still experimental
934     ///
935     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/clip)
936     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-clip
clip(&self, fill_rule: FillRule)937     pub fn clip(&self, fill_rule: FillRule) {
938         let fill_rule_str = fill_rule_to_str(fill_rule);
939         js! { @(no_return)
940             @{&self.0}.clip(@{fill_rule_str});
941         }
942     }
943 
944     /// Causes the point of the pen to move back to the start of the current sub-path. It tries
945     /// to add a straight line (but does not actually draw it) from the current point to the start.
946     /// If the shape has already been closed or has only one point, this function does nothing.
947     ///
948     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/closePath)
949     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-closepath
close_path(&self)950     pub fn close_path(&self) {
951         js! { @(no_return)
952             @{&self.0}.closePath();
953         }
954     }
955 
956     /// Creates a gradient along the line given by the coordinates represented by the parameters.
957     ///
958     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createLinearGradient)
959     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-createlineargradient
create_linear_gradient(&self, x0: f64, y0: f64, x1: f64, y1: f64) -> CanvasGradient960     pub fn create_linear_gradient(&self, x0: f64, y0: f64, x1: f64, y1: f64) -> CanvasGradient {
961         js! (
962             return @{&self.0}.createLinearGradient(@{x0}, @{y0}, @{x1}, @{y1});
963         ).try_into().unwrap()
964     }
965 
966     /// Creates a new, blank ImageData object with the specified dimensions.
967     /// All of the pixels in the new object are transparent black.
968     ///
969     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createImageData)
970     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-createimagedata
create_image_data(&self, width: f64, height: f64) -> Result<ImageData, IndexSizeError>971     pub fn create_image_data(&self, width: f64, height: f64) -> Result<ImageData, IndexSizeError> {
972         js_try! (
973             return @{&self.0}.createImageData(@{width}, @{height});
974         ).unwrap()
975     }
976 
977     /// Creates a new, blank ImageData object with the specified dimensions.
978     /// All of the pixels in the new object are transparent black.
979     ///
980     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createImageData)
981     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-createimagedata
create_image_data_size_of(&self, image_data: ImageData) -> ImageData982     pub fn create_image_data_size_of(&self, image_data: ImageData) -> ImageData {
983         js! (
984             return @{&self.0}.createImageData(@{image_data});
985         ).try_into().unwrap()
986     }
987 
988     /// Creates a pattern using the specified image (a CanvasImageSource). It repeats the source in
989     /// the directions specified by the repetition argument. This method returns a CanvasPattern.
990     ///
991     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern)
992     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-createpattern
create_pattern_image(&self, image: ImageElement, repetition: Repetition) -> CanvasPattern993     pub fn create_pattern_image(&self, image: ImageElement, repetition: Repetition) -> CanvasPattern {
994         let repetition_string = match repetition {
995             Repetition::Repeat => {
996                 "repeat"
997             }
998 
999             Repetition::RepeatX => {
1000                 "repeat-x"
1001             }
1002 
1003             Repetition::RepeatY => {
1004                 "repeat-y"
1005             }
1006 
1007             Repetition::NoRepeat => {
1008                 "no-repeat"
1009             }
1010         };
1011 
1012         js! (
1013             return @{&self.0}.createPattern(@{image}, @{repetition_string});
1014         ).try_into().unwrap()
1015     }
1016 
1017     /// Creates a radial gradient given by the coordinates of the two circles represented by the parameters.
1018     /// This method returns a CanvasGradient.
1019     ///
1020     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createRadialGradient)
1021     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-createradialgradient
create_radial_gradient(&self, x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64) -> Result<CanvasGradient, IndexSizeError>1022     pub fn create_radial_gradient(&self, x0: f64, y0: f64, r0: f64, x1: f64, y1: f64, r1: f64) -> Result<CanvasGradient, IndexSizeError> {
1023         js_try! (
1024             return @{&self.0}.createRadialGradient(@{x0}, @{y0}, @{r0}, @{x1}, @{y1}, @{r1});
1025         ).unwrap()
1026     }
1027 
1028     /// Draws a focus ring around the current path or given path, If a given element is focused.
1029     ///
1030     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawFocusIfNeeded)
1031     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-drawfocusifneeded
draw_focus_if_needed< T: IHtmlElement >(&self, element: &T)1032     pub fn draw_focus_if_needed< T: IHtmlElement >(&self, element: &T) {
1033         js! { @(no_return)
1034             @{&self.0}.drawFocusIfNeeded(@{element.as_ref()});
1035         }
1036     }
1037 
1038     /// Provides different ways to draw an image onto the canvas.
1039     ///
1040     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage)
1041     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-drawimage
draw_image(&self, image: ImageElement, dx: f64, dy: f64) -> Result<(), DrawImageError>1042     pub fn draw_image(&self, image: ImageElement, dx: f64, dy: f64) -> Result<(), DrawImageError> {
1043         js_try! (@(no_return)
1044             @{&self.0}.drawImage(@{image}, @{dx}, @{dy});
1045         ).unwrap()
1046     }
1047 
1048     /// Provides different ways to draw an image onto the canvas.
1049     ///
1050     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage)
1051     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-drawimage
draw_image_d(&self, image: ImageElement, dx: f64, dy: f64, d_width: f64, d_height: f64) -> Result<(), DrawImageError>1052     pub fn draw_image_d(&self, image: ImageElement, dx: f64, dy: f64, d_width: f64, d_height: f64) -> Result<(), DrawImageError> {
1053         js_try! (@(no_return)
1054             @{&self.0}.drawImage(@{image}, @{dx}, @{dy}, @{d_width}, @{d_height});
1055         ).unwrap()
1056     }
1057 
1058     /// Provides different ways to draw an image onto the canvas.
1059     ///
1060     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage)
1061     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-drawimage
draw_image_s(&self, image: ImageElement, sx: f64, sy: f64, s_width: f64, s_height: f64, dx: f64, dy: f64, d_width: f64, d_height: f64 ) -> Result<(), DrawImageError>1062     pub fn draw_image_s(&self, image: ImageElement,
1063                         sx: f64, sy: f64, s_width: f64, s_height: f64,
1064                         dx: f64, dy: f64, d_width: f64, d_height: f64
1065                     ) -> Result<(), DrawImageError> {
1066         js_try!(@(no_return)
1067             @{&self.0}.drawImage(@{image}, @{sx}, @{sy}, @{s_width}, @{s_height}, @{dx}, @{dy}, @{d_width}, @{d_height});
1068         ).unwrap()
1069     }
1070 
1071     /// Fills the current or given path with the current fill style using the non-zero or even-odd winding rule.
1072     ///
1073     /// ctx.fill(path, fillRule) is not supported because [(Path2D)](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) is still experimental
1074     ///
1075     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill)
1076     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-fill
fill(&self, fill_rule: FillRule)1077     pub fn fill(&self, fill_rule: FillRule) {
1078         let fill_rule_str = fill_rule_to_str(fill_rule);
1079         js! { @(no_return)
1080             @{&self.0}.fill(@{fill_rule_str});
1081         }
1082     }
1083 
1084     /// Draws a filled rectangle whose starting point is at the coordinates (x, y) with the
1085     /// specified width and height and whose style is determined by the fillStyle attribute.
1086     ///
1087     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillRect)
1088     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-fillrect
fill_rect(&self, x: f64, y: f64, width: f64, height: f64)1089     pub fn fill_rect(&self, x: f64, y: f64, width: f64, height: f64) {
1090         js! { @(no_return)
1091             @{&self.0}.fillRect(@{x}, @{y}, @{width}, @{height});
1092         }
1093     }
1094 
1095     /// Draws a text string at the specified coordinates, filling the string's characters
1096     /// with the current foreground color. An optional parameter allows specifying a maximum
1097     /// width for the rendered text, which the user agent will achieve by condensing the
1098     /// text or by using a lower font size.
1099     ///
1100     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillText)
1101     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-filltext
fill_text(&self, text: &str, x: f64, y: f64, max_width: Option<f64>)1102     pub fn fill_text(&self, text: &str, x: f64, y: f64, max_width: Option<f64>) {
1103         if let Some(max_width) = max_width {
1104             js! { @(no_return)
1105                 @{&self.0}.fillText(@{text}, @{x}, @{y}, @{max_width});
1106             }
1107         }
1108         else {
1109             js! { @(no_return)
1110                 @{&self.0}.fillText(@{text}, @{x}, @{y});
1111             }
1112         }
1113     }
1114 
1115     /// Returns an ImageData object representing the underlying pixel data for the area of the
1116     /// canvas denoted by the rectangle which starts at (sx, sy) and has an sw width and sh height.
1117     /// This method is not affected by the canvas transformation matrix.
1118     /// Pixels outside of the canvas area are present as transparent black values in the returned ImageData.
1119     ///
1120     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData)
1121     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-getimagedata
get_image_data(&self, sx: f64, sy: f64, sw: f64, sh: f64) -> Result<ImageData, GetImageDataError>1122     pub fn get_image_data(&self, sx: f64, sy: f64, sw: f64, sh: f64) -> Result<ImageData, GetImageDataError> {
1123         js_try! (
1124             return @{&self.0}.getImageData(@{sx}, @{sy}, @{sw}, @{sh});
1125         ).unwrap()
1126     }
1127 
1128     /// Gets the current line dash pattern.
1129     ///
1130     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getLineDash)
1131     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-getlinedash
get_line_dash(&self) -> Vec<f64>1132     pub fn get_line_dash(&self) -> Vec<f64> {
1133         js! (
1134             return @{&self.0}.getLineDash();
1135         ).try_into().unwrap()
1136     }
1137 
1138     /// Reports whether or not the specified point is contained in the current path.
1139     ///
1140     /// ctx.isPointInPath(path, x, y) and ctx.isPointInPath(path, x, y, fillRule)
1141     /// are not supported because [(Path2D)](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) is still experimental
1142     ///
1143     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath)
1144     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-ispointinpath
is_point_in_path(&self, x: f64, y: f64, fill_rule: FillRule) -> bool1145     pub fn is_point_in_path(&self, x: f64, y: f64, fill_rule: FillRule) -> bool {
1146         let fill_rule_str = fill_rule_to_str(fill_rule);
1147         js! (
1148             return @{&self.0}.isPointInPath(@{x}, @{y}, @{fill_rule_str});
1149         ).try_into().unwrap()
1150     }
1151 
1152     /// Reports whether or not the specified point is inside the area contained by the stroking of a path.
1153     ///
1154     /// ctx.isPointInStroke(path, x, y) is not supported because [(Path2D)](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) is still experimental
1155     ///
1156     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInStroke)
1157     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-ispointinstroke
is_point_in_stroke(&self, x: f64, y: f64) -> bool1158     pub fn is_point_in_stroke(&self, x: f64, y: f64) -> bool {
1159         js! (
1160             return @{&self.0}.isPointInStroke(@{x}, @{y});
1161         ).try_into().unwrap()
1162     }
1163 
1164     /// Connects the last point in the sub-path to the x, y coordinates with a straight line (but does not actually draw it).
1165     ///
1166     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineTo)
1167     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-lineto
line_to(&self, x: f64, y: f64)1168     pub fn line_to(&self, x: f64, y: f64) {
1169         js! { @(no_return)
1170             @{&self.0}.lineTo(@{x}, @{y});
1171         }
1172     }
1173 
1174     /// Returns a TextMetrics object that contains information about the measured text (such as its width for example).
1175     ///
1176     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText)
1177     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-measuretext
measure_text(&self, text: &str) -> Result<TextMetrics, SecurityError>1178     pub fn measure_text(&self, text: &str) -> Result<TextMetrics, SecurityError> {
1179         js_try! (
1180             return @{&self.0}.measureText(@{text});
1181         ).unwrap()
1182     }
1183 
1184     /// Moves the starting point of a new sub-path to the (x, y) coordinates.
1185     ///
1186     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/moveTo)
1187     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-moveto
move_to(&self, x: f64, y: f64)1188     pub fn move_to(&self, x: f64, y: f64) {
1189         js! { @(no_return)
1190             @{&self.0}.moveTo(@{x}, @{y});
1191         }
1192     }
1193 
1194     /// Paints data from the given ImageData object onto the bitmap. If a dirty rectangle is provided, only the pixels
1195     /// from that rectangle are painted. This method is not affected by the canvas transformation matrix.
1196     ///
1197     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData)
1198     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-putimagedata
put_image_data(&self, image_data: ImageData, dx: f32, dy: f32 ) -> Result<(), InvalidStateError>1199     pub fn put_image_data(&self,
1200                             image_data: ImageData,
1201                             dx: f32, dy: f32
1202                         ) -> Result<(), InvalidStateError> {
1203         js_try! ( @(no_return)
1204             @{&self.0}.putImageData(@{image_data}, @{dx}, @{dy});
1205         ).unwrap()
1206     }
1207 
1208     /// Paints data from the given ImageData object onto the bitmap. If a dirty rectangle is provided, only the pixels
1209     /// from that rectangle are painted. This method is not affected by the canvas transformation matrix.
1210     ///
1211     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/putImageData)
1212     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-putimagedata
put_image_data_dirty(&self, image_data: ImageData, dx: f32, dy: f32, dirty_x: f32, dirty_y: f32, dirty_width: f32, dirty_height: f32 ) -> Result<(), InvalidStateError>1213     pub fn put_image_data_dirty(&self,
1214                             image_data: ImageData,
1215                             dx: f32, dy: f32,
1216                             dirty_x: f32, dirty_y: f32,
1217                             dirty_width: f32, dirty_height: f32
1218                         ) -> Result<(), InvalidStateError> {
1219         js_try! ( @(no_return)
1220             @{&self.0}.putImageData(@{image_data}, @{dx}, @{dy}, @{dirty_x}, @{dirty_y}, @{dirty_width}, @{dirty_height});
1221         ).unwrap()
1222     }
1223 
1224     /// Adds a quadratic Bézier curve to the path. It requires two points.
1225     /// The first point is a control point and the second one is the end point.
1226     /// The starting point is the last point in the current path, which can be changed using
1227     /// moveTo() before creating the quadratic Bézier curve.
1228     ///
1229     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/quadraticCurveTo)
1230     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-quadraticcurveto
quadratic_curve_to(&self, cpx: f64, cpy: f64, x:f64, y: f64)1231     pub fn quadratic_curve_to(&self, cpx: f64, cpy: f64, x:f64, y: f64) {
1232         js! { @(no_return)
1233             @{&self.0}.quadraticCurveTo(@{cpx}, @{cpy}, @{x}, @{y});
1234         }
1235     }
1236 
1237     /// Creates a path for a rectangle at position (x, y) with a size that is determined by width and height.
1238     /// Those four points are connected by straight lines and the sub-path is marked as closed,
1239     /// so that you can fill or stroke this rectangle.
1240     ///
1241     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rect)
1242     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-rect
rect(&self, x: f64, y: f64, width: f64, height: f64)1243     pub fn rect(&self, x: f64, y: f64, width: f64, height: f64) {
1244         js! { @(no_return)
1245             @{&self.0}.rect(@{x}, @{y}, @{width}, @{height});
1246         }
1247     }
1248 
1249     /// Restores the most recently saved canvas state by popping the top entry in the drawing state stack.
1250     /// If there is no saved state, this method does nothing.
1251     ///
1252     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore)
1253     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-restore
restore(&self)1254     pub fn restore(&self) {
1255         js! { @(no_return)
1256             @{&self.0}.restore();
1257         }
1258     }
1259 
1260     /// Adds a rotation to the transformation matrix. The angle argument represents a clockwise rotation angle and is expressed in radians.
1261     ///
1262     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/rotate)
1263     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-rotate
rotate(&self, angle: f64)1264     pub fn rotate(&self, angle: f64) {
1265         js! { @(no_return)
1266             @{&self.0}.rotate(@{angle});
1267         }
1268     }
1269 
1270     /// Saves the entire state of the canvas by pushing the current state onto a stack.
1271     ///
1272     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save)
1273     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-save
save(&self)1274     pub fn save(&self) {
1275         js! { @(no_return)
1276             @{&self.0}.save();
1277         }
1278     }
1279 
1280     /// adds a scaling transformation to the canvas units by x horizontally and by y vertically.
1281     /// By default, one unit on the canvas is exactly one pixel. If we apply, for instance, a scaling factor of 0.5,
1282     /// the resulting unit would become 0.5 pixels and so shapes would be drawn at half size.
1283     /// In a similar way setting the scaling factor to 2.0 would increase the unit size and one unit now becomes two pixels.
1284     /// This results in shapes being drawn twice as large.
1285     ///
1286     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/scale)
1287     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-scale
scale(&self, x: f64, y: f64)1288     pub fn scale(&self, x: f64, y: f64) {
1289         js! { @(no_return)
1290             @{&self.0}.scale(@{x}, @{y});
1291         }
1292     }
1293 
1294     /// Sets the line dash pattern used when stroking lines, using an array of values which specify alternating lengths of lines and gaps which describe the pattern.
1295     ///
1296     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash)
1297     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-setlinedash
set_line_dash(&self, segments: Vec<f64>)1298     pub fn set_line_dash(&self, segments: Vec<f64>) {
1299         js! { @(no_return)
1300             @{&self.0}.setLineDash(@{segments});
1301         }
1302     }
1303 
1304     /// Resets (overrides) the current transformation to the identity matrix and then invokes a transformation described by the arguments of this method.
1305     /// See also the transform() method, which does not override the current transform matrix and multiplies it with a given one.
1306     ///
1307     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setTransform)
1308     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-settransform
set_transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64)1309     pub fn set_transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
1310         js! { @(no_return)
1311             @{&self.0}.setTransform(@{a}, @{b}, @{c}, @{d}, @{e}, @{f});
1312         }
1313     }
1314 
1315     /// Strokes the current or given path with the current stroke style using the non-zero winding rule.
1316     ///
1317     /// ctx.stroke(path) is not supported because [(Path2D)](https://developer.mozilla.org/en-US/docs/Web/API/Path2D) is still experimental
1318     ///
1319     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/stroke)
1320     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-stroke
stroke(&self)1321     pub fn stroke(&self) {
1322         js! { @(no_return)
1323             @{&self.0}.stroke();
1324         }
1325     }
1326 
1327     /// Paints a rectangle which has a starting point at (x, y) and has a w width and an h height onto the canvas, using the current stroke style.
1328     ///
1329     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeRect)
1330     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-strokerect
stroke_rect(&self, x: f64, y: f64, width: f64, height: f64)1331     pub fn stroke_rect(&self, x: f64, y: f64, width: f64, height: f64) {
1332         js! { @(no_return)
1333             @{&self.0}.strokeRect(@{x}, @{y}, @{width}, @{height});
1334         }
1335     }
1336 
1337     /// Strokes — that is, draws the outlines of — the characters of a specified text string at the given (x, y) position.
1338     /// If the optional fourth parameter for a maximum width is provided, the text is scaled to fit that width.
1339     /// See the CanvasRenderingContext2D.fillText() method to draw the text with the characters filled with color rather than having just their outlines drawn.
1340     ///
1341     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeText)
1342     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-stroketext
stroke_text(&self, text: &str, x: f64, y: f64, max_width: Option<f64>)1343     pub fn stroke_text(&self, text: &str, x: f64, y: f64, max_width: Option<f64>) {
1344         if let Some(max_width) = max_width {
1345             js! { @(no_return)
1346                 @{&self.0}.strokeText(@{text}, @{x}, @{y}, @{max_width});
1347             }
1348         }
1349         else {
1350             js! { @(no_return)
1351                 @{&self.0}.strokeText(@{text}, @{x}, @{y}, @{Undefined});
1352             }
1353         }
1354     }
1355 
1356     /// Multiplies the current transformation with the matrix described by the arguments of this method.
1357     /// You are able to scale, rotate, move and skew the context.
1358     /// See also the setTransform() method which resets the current transform to the identity matrix and then invokes transform().
1359     ///
1360     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform)
1361     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-transform
transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64)1362     pub fn transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
1363         js! { @(no_return)
1364             @{&self.0}.transform(@{a}, @{b}, @{c}, @{d}, @{e}, @{f});
1365         }
1366     }
1367 
1368     /// Adds a translation transformation by moving the canvas and its origin x horizontally and y vertically on the grid.
1369     ///
1370     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/translate)
1371     // https://html.spec.whatwg.org/#2dcontext:dom-context-2d-translate
translate(&self, x: f64, y: f64)1372     pub fn translate(&self, x: f64, y: f64) {
1373         js! { @(no_return)
1374             @{&self.0}.translate(@{x}, @{y});
1375         }
1376     }
1377 }
1378 
fill_rule_to_str(fill_rule: FillRule) -> &'static str1379 fn fill_rule_to_str(fill_rule: FillRule) -> &'static str {
1380     match fill_rule {
1381         FillRule::NonZero => {
1382             "nonzero"
1383         }
1384 
1385         FillRule::EvenOdd => {
1386             "evenodd"
1387         }
1388     }
1389 }
1390 
1391 impl TextMetrics {
1392 
1393     /// Contains the text's advance width (the width of that inline box) in CSS pixels.
1394     ///
1395     /// [(JavaScript docs)](https://developer.mozilla.org/en-US/docs/Web/API/TextMetrics/width)
1396     // https://html.spec.whatwg.org/#2dcontext:dom-textmetrics-width
get_width(&self) -> f641397     pub fn get_width(&self) -> f64 {
1398         js! (
1399             return @{&self.0}.width;
1400         ).try_into().unwrap()
1401     }
1402 }
1403 
1404 #[cfg(all(test, feature = "web_test"))]
1405 mod test {
1406     use super::*;
1407     use webapi::document::document;
1408 
new_canvas() -> CanvasRenderingContext2d1409     fn new_canvas() -> CanvasRenderingContext2d {
1410         let canvas: CanvasElement = document().create_element("canvas").unwrap().try_into().unwrap();
1411         let ctx: CanvasRenderingContext2d = canvas.get_context().unwrap();
1412         ctx
1413     }
1414 
1415     #[test]
test_canvas_fill_color()1416     fn test_canvas_fill_color() {
1417         let canvas = new_canvas();
1418 
1419         canvas.set_fill_style_color("rgb(200,0,0)");
1420         let style = canvas.get_fill_style();
1421         match style {
1422             CanvasStyle::String(s) => assert_eq!(s, "#c80000"),
1423             _ => assert!(false, "Expected style to be a string \"#c80000\" was instead {:?}", style),
1424         }
1425     }
1426 
1427     #[test]
test_browser_create_radial_gradient()1428     fn test_browser_create_radial_gradient() {
1429         let canvas = new_canvas();
1430         canvas.fill_rect(10 as f64, 10 as f64, 55 as f64, 50 as f64);
1431 
1432         let res: Result<CanvasGradient, IndexSizeError> = canvas.create_radial_gradient(100 as f64, 100 as f64, -1 as f64, 100 as f64, 100 as f64, 0 as f64);
1433         assert!(res.is_err());
1434     }
1435 }
1436