aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/platform/graphics/Geometry.h46
-rw-r--r--include/cru/platform/graphics/SvgGeometry.h10
-rw-r--r--include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h27
-rw-r--r--include/cru/platform/graphics/web_canvas/WebCanvasPainter.h8
-rw-r--r--include/cru/platform/web/Js.h17
-rw-r--r--include/cru/platform/web/JsUtility.h9
-rw-r--r--src/platform/graphics/CMakeLists.txt1
-rw-r--r--src/platform/graphics/Geometry.cpp31
-rw-r--r--src/platform/graphics/SvgGeometry.cpp1
-rw-r--r--src/platform/graphics/web_canvas/CMakeLists.txt1
-rw-r--r--src/platform/graphics/web_canvas/Geometry.cpp12
-rw-r--r--src/platform/graphics/web_canvas/Painter.cpp23
-rw-r--r--src/platform/graphics/web_canvas/WebCanvasRef.cpp4
-rw-r--r--src/platform/web/CMakeLists.txt2
-rw-r--r--src/platform/web/Js.cpp13
-rw-r--r--src/platform/web/JsUtility.cpp11
16 files changed, 168 insertions, 48 deletions
diff --git a/include/cru/platform/graphics/Geometry.h b/include/cru/platform/graphics/Geometry.h
index d1045b59..112c95e6 100644
--- a/include/cru/platform/graphics/Geometry.h
+++ b/include/cru/platform/graphics/Geometry.h
@@ -17,49 +17,45 @@ struct CRU_PLATFORM_GRAPHICS_API IGeometry : virtual IGraphicsResource {
virtual std::unique_ptr<IGeometry> CreateStrokeGeometry(float width) = 0;
};
+/**
+ * \remarks We always run into platform porting problems. When I designed this
+ * interface, I thought every platform would support GetCurrentPosition.
+ * However, this is not actually true.
+ * For web canvas, it turns out that it can't get current position. So I have to
+ * not implement or use it, which disables every relative actions because they
+ * depend on it. But luckily, the web canvas path can be constructed from svg
+ * path (see https://developer.mozilla.org/en-US/docs/Web/API/Path2D/Path2D). So
+ * I come up with a new idea that first create a geometry describe itself in
+ * svg, and then construct path from it. And all relative methods should become
+ * virtual so it can override them.
+ */
struct CRU_PLATFORM_GRAPHICS_API IGeometryBuilder : virtual IGraphicsResource {
virtual Point GetCurrentPosition() = 0;
virtual void MoveTo(const Point& point) = 0;
- void RelativeMoveTo(const Point& offset) {
- MoveTo(GetCurrentPosition() + offset);
- }
+ virtual void RelativeMoveTo(const Point& offset);
virtual void LineTo(const Point& point) = 0;
void LineTo(float x, float y) { LineTo(Point(x, y)); }
- void RelativeLineTo(const Point& offset) {
- LineTo(GetCurrentPosition() + offset);
- }
+ virtual void RelativeLineTo(const Point& offset);
void RelativeLineTo(float x, float y) { RelativeLineTo(Point(x, y)); }
virtual void CubicBezierTo(const Point& start_control_point,
const Point& end_control_point,
const Point& end_point) = 0;
- void RelativeCubicBezierTo(const Point& start_control_offset,
- const Point& end_control_offset,
- const Point& end_offset) {
- auto current_position = GetCurrentPosition();
- CubicBezierTo(current_position + start_control_offset,
- current_position + end_control_offset,
- current_position + end_offset);
- }
+ virtual void RelativeCubicBezierTo(const Point& start_control_offset,
+ const Point& end_control_offset,
+ const Point& end_offset);
virtual void QuadraticBezierTo(const Point& control_point,
const Point& end_point) = 0;
- void RelativeQuadraticBezierTo(const Point& control_offset,
- const Point& end_offset) {
- auto current_position = GetCurrentPosition();
- QuadraticBezierTo(current_position + control_offset,
- current_position + end_offset);
- }
+ virtual void RelativeQuadraticBezierTo(const Point& control_offset,
+ const Point& end_offset);
virtual void ArcTo(const Point& radius, float angle, bool is_large_arc,
bool is_clockwise, const Point& end_point);
- void RelativeArcTo(const Point& radius, float angle, bool is_large_arc,
- bool is_clockwise, const Point& end_offset) {
- ArcTo(radius, angle, is_large_arc, is_clockwise,
- GetCurrentPosition() + end_offset);
- }
+ virtual void RelativeArcTo(const Point& radius, float angle, bool is_large_arc,
+ bool is_clockwise, const Point& end_offset);
virtual void CloseFigure(bool close) = 0;
diff --git a/include/cru/platform/graphics/SvgGeometry.h b/include/cru/platform/graphics/SvgGeometry.h
new file mode 100644
index 00000000..281158f0
--- /dev/null
+++ b/include/cru/platform/graphics/SvgGeometry.h
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "Geometry.h"
+
+namespace cru::platform::graphics {
+class CRU_PLATFORM_GRAPHICS_API SvgGeometryBuilder : public virtual IGeometryBuilder {
+
+};
+}
+
diff --git a/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h b/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h
new file mode 100644
index 00000000..af4cee91
--- /dev/null
+++ b/include/cru/platform/graphics/web_canvas/WebCanvasGeometry.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "../Geometry.h"
+#include "WebCanvasResource.h"
+
+#include <emscripten/val.h>
+
+namespace cru::platform::graphics::web_canvas {
+/**
+ * \remarks See IGeometryBuilder for platform limitation.
+ */
+class WebCanvasGeometryBuilder : public WebCanvasResource,
+ public virtual IGeometryBuilder {
+ public:
+ WebCanvasGeometryBuilder(WebCanvasGraphicsFactory* factory);
+
+ ~WebCanvasGeometryBuilder() override;
+
+ Point GetCurrentPosition() override;
+
+ void MoveTo(const Point& point) override;
+
+ private:
+ Point current_postion_;
+ emscripten::val path2d_;
+};
+} // namespace cru::platform::graphics::web_canvas
diff --git a/include/cru/platform/graphics/web_canvas/WebCanvasPainter.h b/include/cru/platform/graphics/web_canvas/WebCanvasPainter.h
index 0832831c..bb092f2f 100644
--- a/include/cru/platform/graphics/web_canvas/WebCanvasPainter.h
+++ b/include/cru/platform/graphics/web_canvas/WebCanvasPainter.h
@@ -35,6 +35,14 @@ class WebCanvasPainter : public WebCanvasResource, public virtual IPainter {
void DrawLine(const Point& start, const Point& end, IBrush* brush,
float width) override;
+ void StrokeRectangle(const Rect& rectangle, IBrush* brush,
+ float width) override;
+
+ void FillRectangle(const Rect& rectangle, IBrush* brush) override;
+ void StrokeEllipse(const Rect& outline_rect, IBrush* brush,
+ float width) override;
+ void FillEllipse(const Rect& outline_rect, IBrush* brush) override;
+
emscripten::val GetCanvas2DContext() const { return context_; }
WebCanvasRef GetCanvas();
diff --git a/include/cru/platform/web/Js.h b/include/cru/platform/web/Js.h
new file mode 100644
index 00000000..b4c91702
--- /dev/null
+++ b/include/cru/platform/web/Js.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <emscripten/val.h>
+#include <utility>
+
+namespace cru::platform::web::js {
+bool IsNotNullAndInstanceOf(const emscripten::val& value,
+ const emscripten::val& type);
+bool IsNotNullAndInstanceOf(const emscripten::val& value,
+ const char* global_type);
+
+template <typename... Args>
+emscripten::val Construct(const char* class_name, Args&&... args) {
+ emscripten::val constructor = emscripten::val::global(class_name);
+ return constructor.new_(std::forward<Args>(args)...);
+}
+} // namespace cru::platform::web
diff --git a/include/cru/platform/web/JsUtility.h b/include/cru/platform/web/JsUtility.h
deleted file mode 100644
index 37c2735d..00000000
--- a/include/cru/platform/web/JsUtility.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include <emscripten/val.h>
-
-namespace cru::platform::web {
- bool IsNotNullAndInstanceOf(const emscripten::val& value, const emscripten::val& type);
- bool IsNotNullAndInstanceOf(const emscripten::val& value, const char* global_type);
-}
-
diff --git a/src/platform/graphics/CMakeLists.txt b/src/platform/graphics/CMakeLists.txt
index b6362961..1b24c22b 100644
--- a/src/platform/graphics/CMakeLists.txt
+++ b/src/platform/graphics/CMakeLists.txt
@@ -3,6 +3,7 @@ add_library(CruPlatformGraphics
Geometry.cpp
Image.cpp
NullPainter.cpp
+ SvgGeometry.cpp
)
target_compile_definitions(CruPlatformGraphics PRIVATE CRU_PLATFORM_GRAPHICS_EXPORT_API)
target_link_libraries(CruPlatformGraphics PUBLIC CruPlatformBase)
diff --git a/src/platform/graphics/Geometry.cpp b/src/platform/graphics/Geometry.cpp
index 20197153..b6f2a724 100644
--- a/src/platform/graphics/Geometry.cpp
+++ b/src/platform/graphics/Geometry.cpp
@@ -12,6 +12,37 @@ bool IGeometry::StrokeContains(float width, const Point& point) {
return geometry->FillContains(point);
}
+void IGeometryBuilder::RelativeMoveTo(const Point& offset) {
+ MoveTo(GetCurrentPosition() + offset);
+}
+
+void IGeometryBuilder::RelativeLineTo(const Point& offset) {
+ LineTo(GetCurrentPosition() + offset);
+}
+
+void IGeometryBuilder::RelativeCubicBezierTo(const Point& start_control_offset,
+ const Point& end_control_offset,
+ const Point& end_offset) {
+ auto current_position = GetCurrentPosition();
+ CubicBezierTo(current_position + start_control_offset,
+ current_position + end_control_offset,
+ current_position + end_offset);
+}
+
+void IGeometryBuilder::RelativeQuadraticBezierTo(const Point& control_offset,
+ const Point& end_offset) {
+ auto current_position = GetCurrentPosition();
+ QuadraticBezierTo(current_position + control_offset,
+ current_position + end_offset);
+}
+
+void IGeometryBuilder::RelativeArcTo(const Point& radius, float angle,
+ bool is_large_arc, bool is_clockwise,
+ const Point& end_offset) {
+ ArcTo(radius, angle, is_large_arc, is_clockwise,
+ GetCurrentPosition() + end_offset);
+}
+
constexpr float PI = 3.14159265358979323846f;
using std::abs;
diff --git a/src/platform/graphics/SvgGeometry.cpp b/src/platform/graphics/SvgGeometry.cpp
new file mode 100644
index 00000000..149c4bb6
--- /dev/null
+++ b/src/platform/graphics/SvgGeometry.cpp
@@ -0,0 +1 @@
+#include "cru/platform/graphics/SvgGeometry.h"
diff --git a/src/platform/graphics/web_canvas/CMakeLists.txt b/src/platform/graphics/web_canvas/CMakeLists.txt
index bbf736e0..d0a1a7d9 100644
--- a/src/platform/graphics/web_canvas/CMakeLists.txt
+++ b/src/platform/graphics/web_canvas/CMakeLists.txt
@@ -1,6 +1,7 @@
add_library(CruPlatformGraphicsWebCanvas
Brush.cpp
Factory.cpp
+ Geometry.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
new file mode 100644
index 00000000..eb4ce84e
--- /dev/null
+++ b/src/platform/graphics/web_canvas/Geometry.cpp
@@ -0,0 +1,12 @@
+#include "cru/platform/graphics/web_canvas/WebCanvasGeometry.h"
+#include "cru/platform/graphics/web_canvas/WebCanvasGraphicsFactory.h"
+#include "cru/platform/graphics/web_canvas/WebCanvasResource.h"
+#include "cru/platform/web/Js.h"
+
+namespace cru::platform::graphics::web_canvas {
+WebCanvasGeometryBuilder::WebCanvasGeometryBuilder(
+ WebCanvasGraphicsFactory* factory)
+ : WebCanvasResource(factory) {
+ path2d_ = web::js::Construct("Path2D");
+}
+} // namespace cru::platform::graphics::web_canvas
diff --git a/src/platform/graphics/web_canvas/Painter.cpp b/src/platform/graphics/web_canvas/Painter.cpp
index a78ab9f1..c9184165 100644
--- a/src/platform/graphics/web_canvas/Painter.cpp
+++ b/src/platform/graphics/web_canvas/Painter.cpp
@@ -59,6 +59,29 @@ void WebCanvasPainter::DrawLine(const Point& start, const Point& end,
context_.call<void>("stroke");
}
+void WebCanvasPainter::StrokeRectangle(const Rect& rectangle, IBrush* brush,
+ float width) {
+ SetStrokeStyle(brush, width);
+ context_.call<void>("strokeRect", rectangle.left, rectangle.top,
+ rectangle.width, rectangle.height);
+}
+
+void WebCanvasPainter::FillRectangle(const Rect& rectangle, IBrush* brush) {
+ SetFillStyle(brush);
+ context_.call<void>("fillRect", rectangle.left, rectangle.top,
+ rectangle.width, rectangle.height);
+}
+
+void WebCanvasPainter::StrokeEllipse(const Rect& outline_rect, IBrush* brush,
+ float width) {
+ SetStrokeStyle(brush);
+ // TODO: Need to use path.
+}
+void WebCanvasPainter::FillEllipse(const Rect& outline_rect, IBrush* brush) {
+ SetFillStyle(brush);
+ // TODO: Need to use path.
+}
+
void WebCanvasPainter::SetStrokeStyle(IBrush* brush, float width) {
context_.set("strokeStyle", ConvertBrush(brush)->GetStyle());
if (width > 0) {
diff --git a/src/platform/graphics/web_canvas/WebCanvasRef.cpp b/src/platform/graphics/web_canvas/WebCanvasRef.cpp
index c4f75626..886131f6 100644
--- a/src/platform/graphics/web_canvas/WebCanvasRef.cpp
+++ b/src/platform/graphics/web_canvas/WebCanvasRef.cpp
@@ -1,5 +1,5 @@
#include "cru/platform/graphics/web_canvas/WebCanvasRef.h"
-#include "cru/platform/web/JsUtility.h"
+#include "cru/platform/web/Js.h"
#include <cassert>
#include <utility>
@@ -7,7 +7,7 @@
namespace cru::platform::graphics::web_canvas {
WebCanvasRef::WebCanvasRef(emscripten::val canvas_val)
: val_(std::move(canvas_val)) {
- assert(web::IsNotNullAndInstanceOf(val_, "HTMLCanvasElement"));
+ assert(web::js::IsNotNullAndInstanceOf(val_, "HTMLCanvasElement"));
}
int WebCanvasRef::GetWidth() const { return val_["width"].as<int>(); }
diff --git a/src/platform/web/CMakeLists.txt b/src/platform/web/CMakeLists.txt
index 0a9bd6dd..3d11e428 100644
--- a/src/platform/web/CMakeLists.txt
+++ b/src/platform/web/CMakeLists.txt
@@ -1,5 +1,5 @@
add_library(CruPlatformBaseWeb
- JsUtility.cpp
+ Js.cpp
Resource.cpp
)
diff --git a/src/platform/web/Js.cpp b/src/platform/web/Js.cpp
new file mode 100644
index 00000000..ea8a0d68
--- /dev/null
+++ b/src/platform/web/Js.cpp
@@ -0,0 +1,13 @@
+#include "cru/platform/web/Js.h"
+
+namespace cru::platform::web {
+bool IsNotNullAndInstanceOf(const emscripten::val& value,
+ const emscripten::val& type) {
+ return !value.isNull() && !type.isNull() && value.instanceof (type);
+}
+
+bool IsNotNullAndInstanceOf(const emscripten::val& value,
+ const char* global_type) {
+ return IsNotNullAndInstanceOf(value, emscripten::val::global(global_type));
+}
+} // namespace cru::platform::web
diff --git a/src/platform/web/JsUtility.cpp b/src/platform/web/JsUtility.cpp
deleted file mode 100644
index b426bbda..00000000
--- a/src/platform/web/JsUtility.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#include "cru/platform/web/JsUtility.h"
-
-namespace cru::platform::web {
-bool IsNotNullAndInstanceOf(const emscripten::val& value, const emscripten::val& type) {
- return !value.isNull() && !type.isNull() && value.instanceof(type);
-}
-
-bool IsNotNullAndInstanceOf(const emscripten::val& value, const char* global_type) {
- return IsNotNullAndInstanceOf(value, emscripten::val::global(global_type));
-}
-}