diff options
8 files changed, 74 insertions, 29 deletions
diff --git a/include/cru/platform/graphics/Geometry.h b/include/cru/platform/graphics/Geometry.h index 71d003f6..b4b05194 100644 --- a/include/cru/platform/graphics/Geometry.h +++ b/include/cru/platform/graphics/Geometry.h @@ -7,18 +7,11 @@ namespace cru::platform::graphics { /** * \remarks Geometry implementation is a disaster zone of platform problems. * Here are some notes. For geometry object: - * 1. Some platforms just lack the concept of geometry, like web canvas. Even if - * there is one, it usually has limited capabilities. They only allow you to - * create path right on the context and use it directly. The geometry itself - * can't be separated from context and stored independently, not to mention run - * some functions. You can't even create a geometry from current state of - * context. In one word, context -x-> geometry, geometry is weak. - * 2. Doing hit test right on the geometry is not supported on some platform. - * The geometry needs to be put on the context first. - * 3. Transform a geometry to create a new geometry is not supported on some - * platforms. You can transform the context, but no for geometry itself - * independently. - * 4. Create a geometry of a stroke of another geometry is not suppored more + * 1. Some platforms just lack the concept of geometry. Even if there is one, it + * usually has limited capabilities. + * 2. Doing hit test right on the geometry out of context is not supported on + * some platform. The geometry needs to be put on the context first. + * 3. Create a geometry of a stroke of another geometry is not suppored more * widely. * * Workarounds: @@ -26,15 +19,7 @@ namespace cru::platform::graphics { * so far, record the commands and replay it on context when it is used. * 2. If the geometry can't do hit test itself, always attach a canvas with it, * and when do hit test, put it on context first. - * 3. If transform a geometry to create a new geometry is not supported, zip the - * original geometry and a transform matrix. When it is used on context, restore - * geometry and matrix the same time. - * 4. There is no good workaround for 4, so don't use it, maybe. - * - * Also note for 3, even we can workaround like that, but there are cases it - * does not work. Like if we add the support for adding an existing path to a - * new path, transform can only be performed on context and we can't construct a - * geometry from context, then it fails. + * 3. There is no good workaround for 4, so don't use it, maybe. * * For geometry builder: * It is hard to conclude the common commands of all platforms. Some have this, diff --git a/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h b/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h index dfb5bbe7..5aca42d1 100644 --- a/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h +++ b/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h @@ -10,14 +10,20 @@ namespace cru::platform::graphics::web_canvas { class WebCanvasGeometry : public WebCanvasResource, public virtual IGeometry { public: - WebCanvasGeometry(WebCanvasGraphicsFactory* factory, emscripten::val path2d); + WebCanvasGeometry(WebCanvasGraphicsFactory* factory, emscripten::val canvas, + emscripten::val path2d); ~WebCanvasGeometry() override; bool StrokeContains(float width, const Point& point) override; - virtual bool FillContains(const Point& point) = 0; - virtual Rect GetBounds() = 0; - virtual std::unique_ptr<IGeometry> Transform(const Matrix& matrix) = 0; + + bool FillContains(const Point& point) override; + + Rect GetBounds() override; + + std::unique_ptr<IGeometry> Transform(const Matrix& matrix) override; + private: + emscripten::val canvas_; emscripten::val path2d_; }; @@ -27,10 +33,14 @@ class WebCanvasGeometry : public WebCanvasResource, public virtual IGeometry { class WebCanvasGeometryBuilder : public WebCanvasResource, public SvgGeometryBuilderMixin { public: - WebCanvasGeometryBuilder(WebCanvasGraphicsFactory* factory); + WebCanvasGeometryBuilder(WebCanvasGraphicsFactory* factory, + emscripten::val canvas); ~WebCanvasGeometryBuilder() override; std::unique_ptr<IGeometry> Build() override; + + private: + emscripten::val canvas_; }; } // namespace cru::platform::graphics::web_canvas diff --git a/include/cru/platform/graphics/web_canvas/WebCanvasMatrix.h b/include/cru/platform/graphics/web_canvas/WebCanvasMatrix.h new file mode 100644 index 00000000..428e0ae5 --- /dev/null +++ b/include/cru/platform/graphics/web_canvas/WebCanvasMatrix.h @@ -0,0 +1,9 @@ +#pragma once + +#include "../../Matrix.h" + +#include <emscripten/val.h> + +namespace cru::platform::graphics::web_canvas { +emscripten::val CreateDomMatrix(const Matrix& matrix); +} diff --git a/include/cru/platform/graphics/web_canvas/WebCanvasRef.h b/include/cru/platform/graphics/web_canvas/WebCanvasRef.h index 4cb960bd..a5d4f395 100644 --- a/include/cru/platform/graphics/web_canvas/WebCanvasRef.h +++ b/include/cru/platform/graphics/web_canvas/WebCanvasRef.h @@ -18,6 +18,9 @@ namespace cru::platform::graphics::web_canvas { int GetWidth() const; int GetHeight() const; + void Save() const; + void Restore() const; + private: emscripten::val val_; }; diff --git a/src/platform/graphics/web_canvas/CMakeLists.txt b/src/platform/graphics/web_canvas/CMakeLists.txt index d0a1a7d9..43e7f463 100644 --- a/src/platform/graphics/web_canvas/CMakeLists.txt +++ b/src/platform/graphics/web_canvas/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(CruPlatformGraphicsWebCanvas Brush.cpp Factory.cpp Geometry.cpp + Matrix.cpp Painter.cpp Resource.cpp WebCanvasRef.cpp diff --git a/src/platform/graphics/web_canvas/Geometry.cpp b/src/platform/graphics/web_canvas/Geometry.cpp index 0f2f5a16..42669d88 100644 --- a/src/platform/graphics/web_canvas/Geometry.cpp +++ b/src/platform/graphics/web_canvas/Geometry.cpp @@ -1,14 +1,37 @@ +#include <memory> #include "cru/platform/graphics/web_canvas/WebCanvasGeometry.h" #include "cru/platform/graphics/web_canvas/WebCanvasGraphicsFactory.h" +#include "cru/platform/graphics/web_canvas/WebCanvasMatrix.h" #include "cru/platform/graphics/web_canvas/WebCanvasResource.h" #include "cru/platform/web/Js.h" namespace cru::platform::graphics::web_canvas { -bool WebCanvasGeometry::StrokeContains(float width, const Point& point) {} +WebCanvasGeometry::WebCanvasGeometry(WebCanvasGraphicsFactory* factory, + emscripten::val canvas, + emscripten::val path2d) + : WebCanvasResource(factory), + canvas_(std::move(canvas)), + path2d_(std::move(path2d)) {} + +WebCanvasGeometry::~WebCanvasGeometry() {} + +std::unique_ptr<IGeometry> WebCanvasGeometry::Transform(const Matrix& matrix) { + auto new_path = web::js::Construct("Path2D"); + auto js_matrix = CreateDomMatrix(matrix); + new_path.call<void>("addPath", js_matrix); + return std::make_unique<WebCanvasGeometry>(GetFactory(), canvas_, + std::move(new_path)); +} WebCanvasGeometryBuilder::WebCanvasGeometryBuilder( - WebCanvasGraphicsFactory* factory) - : WebCanvasResource(factory) {} + WebCanvasGraphicsFactory* factory, emscripten::val canvas) + : WebCanvasResource(factory), canvas_(std::move(canvas)) {} WebCanvasGeometryBuilder::~WebCanvasGeometryBuilder() {} + +std::unique_ptr<IGeometry> WebCanvasGeometryBuilder::Build() { + auto new_path = web::js::Construct("Path2D", GetPathData()); + return std::make_unique<WebCanvasGeometry>(GetFactory(), canvas_, + std::move(new_path)); +} } // namespace cru::platform::graphics::web_canvas diff --git a/src/platform/graphics/web_canvas/Matrix.cpp b/src/platform/graphics/web_canvas/Matrix.cpp new file mode 100644 index 00000000..6c20062e --- /dev/null +++ b/src/platform/graphics/web_canvas/Matrix.cpp @@ -0,0 +1,10 @@ +#include "cru/platform/graphics/web_canvas/WebCanvasMatrix.h" +#include "cru/platform/web/Js.h" + +namespace cru::platform::graphics::web_canvas { +emscripten::val CreateDomMatrix(const Matrix &matrix) { + return web::js::Construct( + "DOMMatrix", std::vector<float>{matrix.m11, matrix.m12, matrix.m21, + matrix.m22, matrix.m31, matrix.m32}); +} +} // namespace cru::platform::graphics::web_canvas diff --git a/src/platform/graphics/web_canvas/WebCanvasRef.cpp b/src/platform/graphics/web_canvas/WebCanvasRef.cpp index 886131f6..c4ad9b17 100644 --- a/src/platform/graphics/web_canvas/WebCanvasRef.cpp +++ b/src/platform/graphics/web_canvas/WebCanvasRef.cpp @@ -13,4 +13,8 @@ WebCanvasRef::WebCanvasRef(emscripten::val canvas_val) int WebCanvasRef::GetWidth() const { return val_["width"].as<int>(); } int WebCanvasRef::GetHeight() const { return val_["height"].as<int>(); } + +void WebCanvasRef::Save() const { val_.call<void>("save"); } + +void WebCanvasRef::Restore() const { val_.call<void>("restore"); } } // namespace cru::platform::graphics::web_canvas |