From 39855fe9ef924a1cd46b64489fc5738d32b93363 Mon Sep 17 00:00:00 2001 From: Brian Gianforcaro Date: Tue, 7 Apr 2020 01:09:17 -0700 Subject: [PATCH] LibWeb: Add canvas.strokeRect(), and fix scale & translate Add an implementation of CanvasRenderingContext2DWrapper.strokeRect(). While implementing this I fixed fillRect() and the new strokeRect() to honor the .scale() and .translate() values that had previously been plumbed. Also enhance the canvas.html demo to utilize strokeRect(), scale(), and translate(). --- Base/home/anon/www/canvas.html | 16 ++++++++-- .../CanvasRenderingContext2DWrapper.cpp | 27 ++++++++++++++++ .../CanvasRenderingContext2DWrapper.h | 3 ++ .../LibWeb/DOM/CanvasRenderingContext2D.cpp | 31 ++++++++++++++++++- .../LibWeb/DOM/CanvasRenderingContext2D.h | 6 ++++ 5 files changed, 80 insertions(+), 3 deletions(-) diff --git a/Base/home/anon/www/canvas.html b/Base/home/anon/www/canvas.html index b82f553315..8d277ae9b8 100644 --- a/Base/home/anon/www/canvas.html +++ b/Base/home/anon/www/canvas.html @@ -16,8 +16,20 @@ canvas { diff --git a/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp b/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp index 64ae861ff1..37ba819612 100644 --- a/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp +++ b/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.cpp @@ -47,6 +47,8 @@ CanvasRenderingContext2DWrapper::CanvasRenderingContext2DWrapper(CanvasRendering put_native_function("fillRect", fill_rect, 4); put_native_function("scale", scale, 2); put_native_function("translate", translate, 2); + put_native_property("strokeStyle", stroke_style_getter, stroke_style_setter); + put_native_function("strokeRect", stroke_rect, 4); } CanvasRenderingContext2DWrapper::~CanvasRenderingContext2DWrapper() @@ -73,6 +75,17 @@ JS::Value CanvasRenderingContext2DWrapper::fill_rect(JS::Interpreter& interprete return JS::js_undefined(); } +JS::Value CanvasRenderingContext2DWrapper::stroke_rect(JS::Interpreter& interpreter) +{ + auto* impl = impl_from(interpreter); + if (!impl) + return {}; + auto& arguments = interpreter.call_frame().arguments; + if (arguments.size() >= 4) + impl->stroke_rect(arguments[0].to_i32(), arguments[1].to_i32(), arguments[2].to_i32(), arguments[3].to_i32()); + return JS::js_undefined(); +} + JS::Value CanvasRenderingContext2DWrapper::scale(JS::Interpreter& interpreter) { auto* impl = impl_from(interpreter); @@ -109,5 +122,19 @@ void CanvasRenderingContext2DWrapper::fill_style_setter(JS::Interpreter& interpr impl->set_fill_style(value.to_string()); } +JS::Value CanvasRenderingContext2DWrapper::stroke_style_getter(JS::Interpreter& interpreter) +{ + auto* impl = impl_from(interpreter); + if (!impl) + return {}; + return JS::js_string(interpreter, impl->stroke_style()); +} + +void CanvasRenderingContext2DWrapper::stroke_style_setter(JS::Interpreter& interpreter, JS::Value value) +{ + if (auto* impl = impl_from(interpreter)) + impl->set_stroke_style(value.to_string()); +} + } } diff --git a/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.h b/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.h index 5ab2e0ce97..962978806c 100644 --- a/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.h +++ b/Libraries/LibWeb/Bindings/CanvasRenderingContext2DWrapper.h @@ -43,10 +43,13 @@ private: virtual const char* class_name() const override { return "CanvasRenderingContext2DWrapper"; } static JS::Value fill_rect(JS::Interpreter&); + static JS::Value stroke_rect(JS::Interpreter&); static JS::Value scale(JS::Interpreter&); static JS::Value translate(JS::Interpreter&); static JS::Value fill_style_getter(JS::Interpreter&); static void fill_style_setter(JS::Interpreter&, JS::Value); + static JS::Value stroke_style_getter(JS::Interpreter&); + static void stroke_style_setter(JS::Interpreter&, JS::Value); NonnullRefPtr m_impl; }; diff --git a/Libraries/LibWeb/DOM/CanvasRenderingContext2D.cpp b/Libraries/LibWeb/DOM/CanvasRenderingContext2D.cpp index a26fdd7048..3f4f6b885c 100644 --- a/Libraries/LibWeb/DOM/CanvasRenderingContext2D.cpp +++ b/Libraries/LibWeb/DOM/CanvasRenderingContext2D.cpp @@ -56,11 +56,32 @@ void CanvasRenderingContext2D::fill_rect(int x, int y, int width, int height) if (!painter) return; - Gfx::Rect rect(x, y, width, height); + Gfx::Rect rect = compute_rect(x, y, width, height); painter->fill_rect(rect, m_fill_style); did_draw(rect); } +void CanvasRenderingContext2D::set_stroke_style(String style) +{ + m_stroke_style = Gfx::Color::from_string(style).value_or(Color::Black); +} + +String CanvasRenderingContext2D::stroke_style() const +{ + return m_fill_style.to_string(); +} + +void CanvasRenderingContext2D::stroke_rect(int x, int y, int width, int height) +{ + auto painter = this->painter(); + if (!painter) + return; + + Gfx::Rect rect = compute_rect(x, y, width, height); + painter->draw_rect(rect, m_stroke_style); + did_draw(rect); +} + void CanvasRenderingContext2D::scale(double sx, double sy) { // FIXME: Actually do something with the scale factor! @@ -77,6 +98,14 @@ void CanvasRenderingContext2D::translate(double x, double y) m_translate_y = y; } +Gfx::Rect CanvasRenderingContext2D::compute_rect(int x, int y, int width, int height) +{ + return Gfx::Rect((x + m_translate_x) * m_scale_x, + (y + m_translate_y) * m_scale_y, + width * m_scale_x, + height * m_scale_y); +} + void CanvasRenderingContext2D::did_draw(const Gfx::Rect&) { // FIXME: Make use of the rect to reduce the invalidated area when possible. diff --git a/Libraries/LibWeb/DOM/CanvasRenderingContext2D.h b/Libraries/LibWeb/DOM/CanvasRenderingContext2D.h index 7294b5bb7f..adb46295a6 100644 --- a/Libraries/LibWeb/DOM/CanvasRenderingContext2D.h +++ b/Libraries/LibWeb/DOM/CanvasRenderingContext2D.h @@ -49,13 +49,18 @@ public: void set_fill_style(String); String fill_style() const; + void set_stroke_style(String); + String stroke_style() const; + void fill_rect(int x, int y, int width, int height); + void stroke_rect(int x, int y, int width, int height); void scale(double sx, double sy); void translate(double x, double y); private: explicit CanvasRenderingContext2D(HTMLCanvasElement&); + Gfx::Rect compute_rect(int x, int y, int width, int height); void did_draw(const Gfx::Rect&); OwnPtr painter(); @@ -67,6 +72,7 @@ private: double m_translate_x { 0 }; double m_translate_y { 0 }; Gfx::Color m_fill_style; + Gfx::Color m_stroke_style; }; }