diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-08-12 14:48:11 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-08-14 11:30:40 +0200 |
commit | aa87b9699eb098097ae322206f3a22afc3f553fa (patch) | |
tree | 9c180492d297cc7499054d7b73ba858e515f1ae7 /Userland | |
parent | 08e6071ebbe9b468284bdd887d862aa7c81a2129 (diff) | |
download | serenity-aa87b9699eb098097ae322206f3a22afc3f553fa.zip |
LibWeb: Extract CanvasTransform class from CRC2D
The implementation of this got a little funky, because it has to access
methods from CanvasState.
Diffstat (limited to 'Userland')
5 files changed, 101 insertions, 69 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.h b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.h new file mode 100644 index 0000000000..6a73a5939b --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> + * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org> + * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Debug.h> +#include <LibWeb/HTML/Canvas/CanvasState.h> + +namespace Web::HTML { + +// https://html.spec.whatwg.org/multipage/canvas.html#canvastransform +template<typename IncludingClass> +class CanvasTransform { +public: + ~CanvasTransform() = default; + + void scale(float sx, float sy) + { + dbgln_if(CANVAS_RENDERING_CONTEXT_2D_DEBUG, "CanvasTransform::scale({}, {})", sx, sy); + + my_drawing_state().transform.scale(sx, sy); + } + + void translate(float tx, float ty) + { + dbgln_if(CANVAS_RENDERING_CONTEXT_2D_DEBUG, "CanvasTransform::translate({}, {})", tx, ty); + my_drawing_state().transform.translate(tx, ty); + } + + void rotate(float radians) + { + dbgln_if(CANVAS_RENDERING_CONTEXT_2D_DEBUG, "CanvasTransform::rotate({})", radians); + my_drawing_state().transform.rotate_radians(radians); + } + + // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform + void transform(double a, double b, double c, double d, double e, double f) + { + // 1. If any of the arguments are infinite or NaN, then return. + if (!isfinite(a) || !isfinite(b) || !isfinite(c) || !isfinite(d) || !isfinite(e) || !isfinite(f)) + return; + + // 2. Replace the current transformation matrix with the result of multiplying the current transformation matrix with the matrix described by: + // a c e + // b d f + // 0 0 1 + my_drawing_state().transform.multiply({ static_cast<float>(a), static_cast<float>(b), static_cast<float>(c), static_cast<float>(d), static_cast<float>(e), static_cast<float>(f) }); + } + + // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-settransform + void set_transform(double a, double b, double c, double d, double e, double f) + { + // 1. If any of the arguments are infinite or NaN, then return. + if (!isfinite(a) || !isfinite(b) || !isfinite(c) || !isfinite(d) || !isfinite(e) || !isfinite(f)) + return; + + // 2. Reset the current transformation matrix to the identity matrix. + my_drawing_state().transform = {}; + + // 3. Invoke the transform(a, b, c, d, e, f) method with the same arguments. + transform(a, b, c, d, e, f); + } + + // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-resettransform + void reset_transform() + { + // The resetTransform() method, when invoked, must reset the current transformation matrix to the identity matrix. + my_drawing_state().transform = {}; + } + +protected: + CanvasTransform() = default; + +private: + CanvasState::DrawingState& my_drawing_state() { return reinterpret_cast<IncludingClass&>(*this).drawing_state(); } + CanvasState::DrawingState const& my_drawing_state() const { return reinterpret_cast<IncludingClass const&>(*this).drawing_state(); } +}; + +} diff --git a/Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.idl b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.idl new file mode 100644 index 0000000000..423b10ba86 --- /dev/null +++ b/Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.idl @@ -0,0 +1,12 @@ +// https://html.spec.whatwg.org/multipage/canvas.html#canvastransform +interface mixin CanvasTransform { + undefined scale(unrestricted double x, unrestricted double y); + undefined rotate(unrestricted double radians); + undefined translate(unrestricted double x, unrestricted double y); + undefined transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); + + // FIXME: [NewObject] DOMMatrix getTransform(); + undefined setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); + // FIXME: undefined setTransform(optional DOMMatrix2DInit transform = {}); + undefined resetTransform(); +}; diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp index 08d42cb396..d20449d17e 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp @@ -263,24 +263,6 @@ DOM::ExceptionOr<void> CanvasRenderingContext2D::draw_image(CanvasImageSource co return {}; } -void CanvasRenderingContext2D::scale(float sx, float sy) -{ - dbgln_if(CANVAS_RENDERING_CONTEXT_2D_DEBUG, "CanvasRenderingContext2D::scale({}, {})", sx, sy); - drawing_state().transform.scale(sx, sy); -} - -void CanvasRenderingContext2D::translate(float tx, float ty) -{ - dbgln_if(CANVAS_RENDERING_CONTEXT_2D_DEBUG, "CanvasRenderingContext2D::translate({}, {})", tx, ty); - drawing_state().transform.translate(tx, ty); -} - -void CanvasRenderingContext2D::rotate(float radians) -{ - dbgln_if(CANVAS_RENDERING_CONTEXT_2D_DEBUG, "CanvasRenderingContext2D::rotate({})", radians); - drawing_state().transform.rotate_radians(radians); -} - void CanvasRenderingContext2D::did_draw(Gfx::FloatRect const&) { // FIXME: Make use of the rect to reduce the invalidated area when possible. @@ -601,41 +583,6 @@ NonnullRefPtr<CanvasGradient> CanvasRenderingContext2D::create_conic_gradient(do return CanvasGradient::create_conic(start_angle, x, y); } -// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-transform -void CanvasRenderingContext2D::transform(double a, double b, double c, double d, double e, double f) -{ - // 1. If any of the arguments are infinite or NaN, then return. - if (!isfinite(a) || !isfinite(b) || !isfinite(c) || !isfinite(d) || !isfinite(e) || !isfinite(f)) - return; - - // 2. Replace the current transformation matrix with the result of multiplying the current transformation matrix with the matrix described by: - // a c e - // b d f - // 0 0 1 - drawing_state().transform.multiply({ static_cast<float>(a), static_cast<float>(b), static_cast<float>(c), static_cast<float>(d), static_cast<float>(e), static_cast<float>(f) }); -} - -// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-settransform -void CanvasRenderingContext2D::set_transform(double a, double b, double c, double d, double e, double f) -{ - // 1. If any of the arguments are infinite or NaN, then return. - if (!isfinite(a) || !isfinite(b) || !isfinite(c) || !isfinite(d) || !isfinite(e) || !isfinite(f)) - return; - - // 2. Reset the current transformation matrix to the identity matrix. - drawing_state().transform = {}; - - // 3. Invoke the transform(a, b, c, d, e, f) method with the same arguments. - transform(a, b, c, d, e, f); -} - -// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-resettransform -void CanvasRenderingContext2D::reset_transform() -{ - // The resetTransform() method, when invoked, must reset the current transformation matrix to the identity matrix. - drawing_state().transform = {}; -} - void CanvasRenderingContext2D::clip() { // FIXME: Implement. diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h index 9951dd5973..ee4c1f2b9c 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h @@ -18,6 +18,7 @@ #include <LibWeb/DOM/ExceptionOr.h> #include <LibWeb/HTML/Canvas/CanvasPath.h> #include <LibWeb/HTML/Canvas/CanvasState.h> +#include <LibWeb/HTML/Canvas/CanvasTransform.h> #include <LibWeb/HTML/CanvasGradient.h> #include <LibWeb/Layout/InlineNode.h> #include <LibWeb/Layout/LineBox.h> @@ -32,7 +33,8 @@ class CanvasRenderingContext2D : public RefCountForwarder<HTMLCanvasElement> , public Bindings::Wrappable , public CanvasPath - , public CanvasState { + , public CanvasState + , public CanvasTransform<CanvasRenderingContext2D> { AK_MAKE_NONCOPYABLE(CanvasRenderingContext2D); AK_MAKE_NONMOVABLE(CanvasRenderingContext2D); @@ -57,10 +59,6 @@ public: DOM::ExceptionOr<void> draw_image(CanvasImageSource const&, float destination_x, float destination_y, float destination_width, float destination_height); DOM::ExceptionOr<void> draw_image(CanvasImageSource const&, float source_x, float source_y, float source_width, float source_height, float destination_x, float destination_y, float destination_width, float destination_height); - void scale(float sx, float sy); - void translate(float x, float y); - void rotate(float degrees); - void set_line_width(float line_width) { drawing_state().line_width = line_width; } float line_width() const { return drawing_state().line_width; } @@ -88,9 +86,6 @@ public: NonnullRefPtr<CanvasGradient> create_linear_gradient(double x0, double y0, double x1, double y1); NonnullRefPtr<CanvasGradient> create_conic_gradient(double start_angle, double x, double y); - void transform(double a, double b, double c, double d, double e, double f); - void set_transform(double a, double b, double c, double d, double e, double f); - void reset_transform(); void clip(); private: diff --git a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl index 041c00b770..8191f524ae 100644 --- a/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl +++ b/Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl @@ -5,6 +5,7 @@ #import <HTML/CanvasGradient.idl> #import <HTML/Canvas/CanvasPath.idl> #import <HTML/Canvas/CanvasState.idl> +#import <HTML/Canvas/CanvasTransform.idl> #import <HTML/Path2D.idl> // https://html.spec.whatwg.org/multipage/canvas.html#canvasrenderingcontext2d @@ -15,10 +16,6 @@ interface CanvasRenderingContext2D { undefined strokeRect(double x, double y, double w, double h); undefined clearRect(double x, double y, double w, double h); - undefined scale(double x, double y); - undefined translate(double x, double y); - undefined rotate(double radians); - undefined beginPath(); // FIXME: `DOMString` should be `CanvasFillRule` undefined fill(optional DOMString fillRule = "nonzero"); @@ -50,10 +47,6 @@ interface CanvasRenderingContext2D { CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1); CanvasGradient createConicGradient(double startAngle, double x, double y); - undefined transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); - undefined setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); - undefined resetTransform(); - // undefined clip(optional CanvasFillRule fillRule = "nonzero"); // undefined clip(Path2D path, optional CanvasFillRule fillRule = "nonzero"); // FIXME: Replace this with the two definitions above. @@ -62,4 +55,5 @@ interface CanvasRenderingContext2D { }; CanvasRenderingContext2D includes CanvasState; +CanvasRenderingContext2D includes CanvasTransform; CanvasRenderingContext2D includes CanvasPath; |