script/dom/canvas/2d/
offscreencanvasrenderingcontext2d.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use canvas_traits::canvas::Canvas2dMsg;
6use dom_struct::dom_struct;
7use euclid::default::Size2D;
8use pixels::Snapshot;
9
10use crate::canvas_context::{CanvasContext, HTMLCanvasElementOrOffscreenCanvas};
11use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{
12    CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin,
13    CanvasRenderingContext2DMethods, CanvasTextAlign, CanvasTextBaseline,
14};
15use crate::dom::bindings::codegen::Bindings::DOMMatrixBinding::DOMMatrix2DInit;
16use crate::dom::bindings::codegen::Bindings::OffscreenCanvasRenderingContext2DBinding::OffscreenCanvasRenderingContext2DMethods;
17use crate::dom::bindings::codegen::UnionTypes::{
18    HTMLCanvasElementOrOffscreenCanvas as RootedHTMLCanvasElementOrOffscreenCanvas,
19    StringOrCanvasGradientOrCanvasPattern,
20};
21use crate::dom::bindings::error::{ErrorResult, Fallible};
22use crate::dom::bindings::num::Finite;
23use crate::dom::bindings::reflector::reflect_dom_object;
24use crate::dom::bindings::root::{Dom, DomRoot};
25use crate::dom::bindings::str::DOMString;
26use crate::dom::canvasgradient::CanvasGradient;
27use crate::dom::canvaspattern::CanvasPattern;
28use crate::dom::canvasrenderingcontext2d::CanvasRenderingContext2D;
29use crate::dom::dommatrix::DOMMatrix;
30use crate::dom::globalscope::GlobalScope;
31use crate::dom::imagedata::ImageData;
32use crate::dom::offscreencanvas::OffscreenCanvas;
33use crate::dom::path2d::Path2D;
34use crate::dom::textmetrics::TextMetrics;
35use crate::script_runtime::CanGc;
36
37#[dom_struct]
38pub(crate) struct OffscreenCanvasRenderingContext2D {
39    context: CanvasRenderingContext2D,
40}
41
42impl OffscreenCanvasRenderingContext2D {
43    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
44    fn new_inherited(
45        global: &GlobalScope,
46        canvas: HTMLCanvasElementOrOffscreenCanvas,
47        size: Size2D<u32>,
48    ) -> Option<OffscreenCanvasRenderingContext2D> {
49        Some(OffscreenCanvasRenderingContext2D {
50            context: CanvasRenderingContext2D::new_inherited(global, canvas, size)?,
51        })
52    }
53
54    pub(crate) fn new(
55        global: &GlobalScope,
56        canvas: &OffscreenCanvas,
57        size: Size2D<u32>,
58        can_gc: CanGc,
59    ) -> Option<DomRoot<OffscreenCanvasRenderingContext2D>> {
60        OffscreenCanvasRenderingContext2D::new_inherited(
61            global,
62            HTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(Dom::from_ref(canvas)),
63            size,
64        )
65        .map(|context| reflect_dom_object(Box::new(context), global, can_gc))
66    }
67
68    pub(crate) fn send_canvas_2d_msg(&self, msg: Canvas2dMsg) {
69        self.context.send_canvas_2d_msg(msg)
70    }
71}
72
73impl CanvasContext for OffscreenCanvasRenderingContext2D {
74    type ID = <CanvasRenderingContext2D as CanvasContext>::ID;
75
76    fn context_id(&self) -> Self::ID {
77        self.context.context_id()
78    }
79
80    fn canvas(&self) -> Option<RootedHTMLCanvasElementOrOffscreenCanvas> {
81        self.context.canvas()
82    }
83
84    fn resize(&self) {
85        self.context.resize()
86    }
87
88    fn reset_bitmap(&self) {
89        self.context.reset_bitmap()
90    }
91
92    fn get_image_data(&self) -> Option<Snapshot> {
93        self.context.get_image_data()
94    }
95
96    fn origin_is_clean(&self) -> bool {
97        self.context.origin_is_clean()
98    }
99
100    fn image_key(&self) -> Option<webrender_api::ImageKey> {
101        None
102    }
103
104    fn mark_as_dirty(&self) {}
105}
106
107impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder>
108    for OffscreenCanvasRenderingContext2D
109{
110    // https://html.spec.whatwg.org/multipage/offscreencontext2d-canvas
111    fn Canvas(&self) -> DomRoot<OffscreenCanvas> {
112        match self.context.canvas() {
113            Some(RootedHTMLCanvasElementOrOffscreenCanvas::OffscreenCanvas(canvas)) => canvas,
114            _ => panic!("Should not be called from onscreen canvas"),
115        }
116    }
117
118    // https://html.spec.whatwg.org/multipage/#dom-context-2d-fillrect
119    fn FillRect(&self, x: f64, y: f64, width: f64, height: f64) {
120        self.context.FillRect(x, y, width, height);
121    }
122
123    // https://html.spec.whatwg.org/multipage/#dom-context-2d-clearrect
124    fn ClearRect(&self, x: f64, y: f64, width: f64, height: f64) {
125        self.context.ClearRect(x, y, width, height);
126    }
127
128    // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokerect
129    fn StrokeRect(&self, x: f64, y: f64, width: f64, height: f64) {
130        self.context.StrokeRect(x, y, width, height);
131    }
132
133    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
134    fn ShadowOffsetX(&self) -> f64 {
135        self.context.ShadowOffsetX()
136    }
137
138    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
139    fn SetShadowOffsetX(&self, value: f64) {
140        self.context.SetShadowOffsetX(value)
141    }
142
143    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsety
144    fn ShadowOffsetY(&self) -> f64 {
145        self.context.ShadowOffsetY()
146    }
147
148    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsety
149    fn SetShadowOffsetY(&self, value: f64) {
150        self.context.SetShadowOffsetY(value)
151    }
152
153    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowblur
154    fn ShadowBlur(&self) -> f64 {
155        self.context.ShadowBlur()
156    }
157
158    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowblur
159    fn SetShadowBlur(&self, value: f64) {
160        self.context.SetShadowBlur(value)
161    }
162
163    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
164    fn ShadowColor(&self) -> DOMString {
165        self.context.ShadowColor()
166    }
167
168    // https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowcolor
169    fn SetShadowColor(&self, value: DOMString) {
170        self.context.SetShadowColor(value)
171    }
172
173    // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
174    fn StrokeStyle(&self) -> StringOrCanvasGradientOrCanvasPattern {
175        self.context.StrokeStyle()
176    }
177
178    // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
179    fn SetStrokeStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
180        self.context.SetStrokeStyle(value)
181    }
182
183    // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
184    fn FillStyle(&self) -> StringOrCanvasGradientOrCanvasPattern {
185        self.context.FillStyle()
186    }
187
188    // https://html.spec.whatwg.org/multipage/#dom-context-2d-strokestyle
189    fn SetFillStyle(&self, value: StringOrCanvasGradientOrCanvasPattern) {
190        self.context.SetFillStyle(value)
191    }
192
193    // https://html.spec.whatwg.org/multipage/#dom-context-2d-createlineargradient
194    fn CreateLinearGradient(
195        &self,
196        x0: Finite<f64>,
197        y0: Finite<f64>,
198        x1: Finite<f64>,
199        y1: Finite<f64>,
200        can_gc: CanGc,
201    ) -> DomRoot<CanvasGradient> {
202        self.context.CreateLinearGradient(x0, y0, x1, y1, can_gc)
203    }
204
205    // https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient
206    fn CreateRadialGradient(
207        &self,
208        x0: Finite<f64>,
209        y0: Finite<f64>,
210        r0: Finite<f64>,
211        x1: Finite<f64>,
212        y1: Finite<f64>,
213        r1: Finite<f64>,
214        can_gc: CanGc,
215    ) -> Fallible<DomRoot<CanvasGradient>> {
216        self.context
217            .CreateRadialGradient(x0, y0, r0, x1, y1, r1, can_gc)
218    }
219
220    // https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
221    fn CreatePattern(
222        &self,
223        image: CanvasImageSource,
224        repetition: DOMString,
225        can_gc: CanGc,
226    ) -> Fallible<Option<DomRoot<CanvasPattern>>> {
227        self.context.CreatePattern(image, repetition, can_gc)
228    }
229
230    // https://html.spec.whatwg.org/multipage/#dom-context-2d-save
231    fn Save(&self) {
232        self.context.Save()
233    }
234
235    #[cfg_attr(crown, allow(crown::unrooted_must_root))]
236    // https://html.spec.whatwg.org/multipage/#dom-context-2d-restore
237    fn Restore(&self) {
238        self.context.Restore()
239    }
240
241    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-reset>
242    fn Reset(&self) {
243        self.context.Reset()
244    }
245
246    // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha
247    fn GlobalAlpha(&self) -> f64 {
248        self.context.GlobalAlpha()
249    }
250
251    // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalalpha
252    fn SetGlobalAlpha(&self, alpha: f64) {
253        self.context.SetGlobalAlpha(alpha)
254    }
255
256    // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
257    fn GlobalCompositeOperation(&self) -> DOMString {
258        self.context.GlobalCompositeOperation()
259    }
260
261    // https://html.spec.whatwg.org/multipage/#dom-context-2d-globalcompositeoperation
262    fn SetGlobalCompositeOperation(&self, op_str: DOMString) {
263        self.context.SetGlobalCompositeOperation(op_str)
264    }
265
266    // https://html.spec.whatwg.org/multipage/#dom-context-2d-imagesmoothingenabled
267    fn ImageSmoothingEnabled(&self) -> bool {
268        self.context.ImageSmoothingEnabled()
269    }
270
271    // https://html.spec.whatwg.org/multipage/#dom-context-2d-imagesmoothingenabled
272    fn SetImageSmoothingEnabled(&self, value: bool) {
273        self.context.SetImageSmoothingEnabled(value)
274    }
275
276    // https://html.spec.whatwg.org/multipage/#dom-context-2d-filltext
277    fn FillText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>) {
278        self.context.FillText(text, x, y, max_width)
279    }
280
281    // https://html.spec.whatwg.org/multipage/#dom-context-2d-stroketext
282    fn StrokeText(&self, text: DOMString, x: f64, y: f64, max_width: Option<f64>) {
283        self.context.StrokeText(text, x, y, max_width)
284    }
285
286    // https://html.spec.whatwg.org/multipage/#textmetrics
287    fn MeasureText(&self, text: DOMString, can_gc: CanGc) -> DomRoot<TextMetrics> {
288        self.context.MeasureText(text, can_gc)
289    }
290
291    // https://html.spec.whatwg.org/multipage/#dom-context-2d-font
292    fn Font(&self) -> DOMString {
293        self.context.Font()
294    }
295
296    // https://html.spec.whatwg.org/multipage/#dom-context-2d-font
297    fn SetFont(&self, value: DOMString) {
298        self.context.SetFont(value)
299    }
300
301    // https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
302    fn TextAlign(&self) -> CanvasTextAlign {
303        self.context.TextAlign()
304    }
305
306    // https://html.spec.whatwg.org/multipage/#dom-context-2d-textalign
307    fn SetTextAlign(&self, value: CanvasTextAlign) {
308        self.context.SetTextAlign(value)
309    }
310
311    // https://html.spec.whatwg.org/multipage/#dom-context-2d-textbaseline
312    fn TextBaseline(&self) -> CanvasTextBaseline {
313        self.context.TextBaseline()
314    }
315
316    // https://html.spec.whatwg.org/multipage/#dom-context-2d-textbaseline
317    fn SetTextBaseline(&self, value: CanvasTextBaseline) {
318        self.context.SetTextBaseline(value)
319    }
320
321    // https://html.spec.whatwg.org/multipage/#dom-context-2d-direction
322    fn Direction(&self) -> CanvasDirection {
323        self.context.Direction()
324    }
325
326    // https://html.spec.whatwg.org/multipage/#dom-context-2d-direction
327    fn SetDirection(&self, value: CanvasDirection) {
328        self.context.SetDirection(value)
329    }
330
331    // https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
332    fn LineWidth(&self) -> f64 {
333        self.context.LineWidth()
334    }
335
336    // https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth
337    fn SetLineWidth(&self, width: f64) {
338        self.context.SetLineWidth(width)
339    }
340
341    // https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
342    fn LineCap(&self) -> CanvasLineCap {
343        self.context.LineCap()
344    }
345
346    // https://html.spec.whatwg.org/multipage/#dom-context-2d-linecap
347    fn SetLineCap(&self, cap: CanvasLineCap) {
348        self.context.SetLineCap(cap)
349    }
350
351    // https://html.spec.whatwg.org/multipage/#dom-context-2d-linejoin
352    fn LineJoin(&self) -> CanvasLineJoin {
353        self.context.LineJoin()
354    }
355
356    // https://html.spec.whatwg.org/multipage/#dom-context-2d-linejoin
357    fn SetLineJoin(&self, join: CanvasLineJoin) {
358        self.context.SetLineJoin(join)
359    }
360
361    // https://html.spec.whatwg.org/multipage/#dom-context-2d-miterlimit
362    fn MiterLimit(&self) -> f64 {
363        self.context.MiterLimit()
364    }
365
366    // https://html.spec.whatwg.org/multipage/#dom-context-2d-miterlimit
367    fn SetMiterLimit(&self, limit: f64) {
368        self.context.SetMiterLimit(limit)
369    }
370
371    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-setlinedash>
372    fn SetLineDash(&self, segments: Vec<f64>) {
373        self.context.SetLineDash(segments)
374    }
375
376    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-getlinedash>
377    fn GetLineDash(&self) -> Vec<f64> {
378        self.context.GetLineDash()
379    }
380
381    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
382    fn LineDashOffset(&self) -> f64 {
383        self.context.LineDashOffset()
384    }
385
386    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
387    fn SetLineDashOffset(&self, offset: f64) {
388        self.context.SetLineDashOffset(offset)
389    }
390
391    // https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
392    fn CreateImageData(&self, sw: i32, sh: i32, can_gc: CanGc) -> Fallible<DomRoot<ImageData>> {
393        self.context.CreateImageData(sw, sh, can_gc)
394    }
395
396    // https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
397    fn CreateImageData_(
398        &self,
399        imagedata: &ImageData,
400        can_gc: CanGc,
401    ) -> Fallible<DomRoot<ImageData>> {
402        self.context.CreateImageData_(imagedata, can_gc)
403    }
404
405    // https://html.spec.whatwg.org/multipage/#dom-context-2d-getimagedata
406    fn GetImageData(
407        &self,
408        sx: i32,
409        sy: i32,
410        sw: i32,
411        sh: i32,
412        can_gc: CanGc,
413    ) -> Fallible<DomRoot<ImageData>> {
414        self.context.GetImageData(sx, sy, sw, sh, can_gc)
415    }
416
417    // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
418    fn PutImageData(&self, imagedata: &ImageData, dx: i32, dy: i32) {
419        self.context.PutImageData(imagedata, dx, dy)
420    }
421
422    // https://html.spec.whatwg.org/multipage/#dom-context-2d-putimagedata
423    #[allow(unsafe_code)]
424    fn PutImageData_(
425        &self,
426        imagedata: &ImageData,
427        dx: i32,
428        dy: i32,
429        dirty_x: i32,
430        dirty_y: i32,
431        dirty_width: i32,
432        dirty_height: i32,
433    ) {
434        self.context.PutImageData_(
435            imagedata,
436            dx,
437            dy,
438            dirty_x,
439            dirty_y,
440            dirty_width,
441            dirty_height,
442        )
443    }
444
445    // https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
446    fn DrawImage(&self, image: CanvasImageSource, dx: f64, dy: f64) -> ErrorResult {
447        self.context.DrawImage(image, dx, dy)
448    }
449
450    // https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
451    fn DrawImage_(
452        &self,
453        image: CanvasImageSource,
454        dx: f64,
455        dy: f64,
456        dw: f64,
457        dh: f64,
458    ) -> ErrorResult {
459        self.context.DrawImage_(image, dx, dy, dw, dh)
460    }
461
462    // https://html.spec.whatwg.org/multipage/#dom-context-2d-drawimage
463    fn DrawImage__(
464        &self,
465        image: CanvasImageSource,
466        sx: f64,
467        sy: f64,
468        sw: f64,
469        sh: f64,
470        dx: f64,
471        dy: f64,
472        dw: f64,
473        dh: f64,
474    ) -> ErrorResult {
475        self.context
476            .DrawImage__(image, sx, sy, sw, sh, dx, dy, dw, dh)
477    }
478
479    // https://html.spec.whatwg.org/multipage/#dom-context-2d-beginpath
480    fn BeginPath(&self) {
481        self.context.BeginPath()
482    }
483
484    // https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
485    fn Fill(&self, fill_rule: CanvasFillRule) {
486        self.context.Fill(fill_rule)
487    }
488
489    // https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
490    fn Fill_(&self, path: &Path2D, fill_rule: CanvasFillRule) {
491        self.context.Fill_(path, fill_rule)
492    }
493
494    // https://html.spec.whatwg.org/multipage/#dom-context-2d-stroke
495    fn Stroke(&self) {
496        self.context.Stroke()
497    }
498
499    // https://html.spec.whatwg.org/multipage/#dom-context-2d-stroke
500    fn Stroke_(&self, path: &Path2D) {
501        self.context.Stroke_(path)
502    }
503
504    // https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
505    fn Clip(&self, fill_rule: CanvasFillRule) {
506        self.context.Clip(fill_rule)
507    }
508
509    // https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
510    fn Clip_(&self, path: &Path2D, fill_rule: CanvasFillRule) {
511        self.context.Clip_(path, fill_rule)
512    }
513
514    // https://html.spec.whatwg.org/multipage/#dom-context-2d-ispointinpath
515    fn IsPointInPath(&self, x: f64, y: f64, fill_rule: CanvasFillRule) -> bool {
516        self.context.IsPointInPath(x, y, fill_rule)
517    }
518
519    // https://html.spec.whatwg.org/multipage/#dom-context-2d-ispointinpath
520    fn IsPointInPath_(&self, path: &Path2D, x: f64, y: f64, fill_rule: CanvasFillRule) -> bool {
521        self.context.IsPointInPath_(path, x, y, fill_rule)
522    }
523
524    // https://html.spec.whatwg.org/multipage/#dom-context-2d-scale
525    fn Scale(&self, x: f64, y: f64) {
526        self.context.Scale(x, y)
527    }
528
529    // https://html.spec.whatwg.org/multipage/#dom-context-2d-rotate
530    fn Rotate(&self, angle: f64) {
531        self.context.Rotate(angle)
532    }
533
534    // https://html.spec.whatwg.org/multipage/#dom-context-2d-translate
535    fn Translate(&self, x: f64, y: f64) {
536        self.context.Translate(x, y)
537    }
538
539    // https://html.spec.whatwg.org/multipage/#dom-context-2d-transform
540    fn Transform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) {
541        self.context.Transform(a, b, c, d, e, f)
542    }
543
544    // https://html.spec.whatwg.org/multipage/#dom-context-2d-gettransform
545    fn GetTransform(&self, can_gc: CanGc) -> DomRoot<DOMMatrix> {
546        self.context.GetTransform(can_gc)
547    }
548
549    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform>
550    fn SetTransform(&self, a: f64, b: f64, c: f64, d: f64, e: f64, f: f64) -> ErrorResult {
551        self.context.SetTransform(a, b, c, d, e, f)
552    }
553
554    /// <https://html.spec.whatwg.org/multipage/#dom-context-2d-settransform-matrix>
555    fn SetTransform_(&self, transform: &DOMMatrix2DInit) -> ErrorResult {
556        self.context.SetTransform_(transform)
557    }
558
559    // https://html.spec.whatwg.org/multipage/#dom-context-2d-resettransform
560    fn ResetTransform(&self) {
561        self.context.ResetTransform()
562    }
563
564    // https://html.spec.whatwg.org/multipage/#dom-context-2d-closepath
565    fn ClosePath(&self) {
566        self.context.ClosePath()
567    }
568
569    // https://html.spec.whatwg.org/multipage/#dom-context-2d-moveto
570    fn MoveTo(&self, x: f64, y: f64) {
571        self.context.MoveTo(x, y)
572    }
573
574    // https://html.spec.whatwg.org/multipage/#dom-context-2d-lineto
575    fn LineTo(&self, x: f64, y: f64) {
576        self.context.LineTo(x, y)
577    }
578
579    // https://html.spec.whatwg.org/multipage/#dom-context-2d-rect
580    fn Rect(&self, x: f64, y: f64, width: f64, height: f64) {
581        self.context.Rect(x, y, width, height)
582    }
583
584    // https://html.spec.whatwg.org/multipage/#dom-context-2d-quadraticcurveto
585    fn QuadraticCurveTo(&self, cpx: f64, cpy: f64, x: f64, y: f64) {
586        self.context.QuadraticCurveTo(cpx, cpy, x, y)
587    }
588
589    // https://html.spec.whatwg.org/multipage/#dom-context-2d-beziercurveto
590    fn BezierCurveTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, x: f64, y: f64) {
591        self.context.BezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
592    }
593
594    // https://html.spec.whatwg.org/multipage/#dom-context-2d-arc
595    fn Arc(&self, x: f64, y: f64, r: f64, start: f64, end: f64, ccw: bool) -> ErrorResult {
596        self.context.Arc(x, y, r, start, end, ccw)
597    }
598
599    // https://html.spec.whatwg.org/multipage/#dom-context-2d-arcto
600    fn ArcTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, r: f64) -> ErrorResult {
601        self.context.ArcTo(cp1x, cp1y, cp2x, cp2y, r)
602    }
603
604    // https://html.spec.whatwg.org/multipage/#dom-context-2d-ellipse
605    fn Ellipse(
606        &self,
607        x: f64,
608        y: f64,
609        rx: f64,
610        ry: f64,
611        rotation: f64,
612        start: f64,
613        end: f64,
614        ccw: bool,
615    ) -> ErrorResult {
616        self.context
617            .Ellipse(x, y, rx, ry, rotation, start, end, ccw)
618    }
619}