summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-08-12 14:48:11 +0100
committerAndreas Kling <kling@serenityos.org>2022-08-14 11:30:40 +0200
commitaa87b9699eb098097ae322206f3a22afc3f553fa (patch)
tree9c180492d297cc7499054d7b73ba858e515f1ae7 /Userland
parent08e6071ebbe9b468284bdd887d862aa7c81a2129 (diff)
downloadserenity-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')
-rw-r--r--Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.h84
-rw-r--r--Userland/Libraries/LibWeb/HTML/Canvas/CanvasTransform.idl12
-rw-r--r--Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.cpp53
-rw-r--r--Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.h11
-rw-r--r--Userland/Libraries/LibWeb/HTML/CanvasRenderingContext2D.idl10
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;