aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/osx/graphics/quartz/Geometry.hpp93
-rw-r--r--src/osx/graphics/quartz/CMakeLists.txt2
-rw-r--r--src/osx/graphics/quartz/Geometry.cpp48
3 files changed, 143 insertions, 0 deletions
diff --git a/include/cru/osx/graphics/quartz/Geometry.hpp b/include/cru/osx/graphics/quartz/Geometry.hpp
new file mode 100644
index 00000000..33a2d8a8
--- /dev/null
+++ b/include/cru/osx/graphics/quartz/Geometry.hpp
@@ -0,0 +1,93 @@
+#pragma once
+#include "Resource.hpp"
+#include "cru/platform/graphics/Geometry.hpp"
+
+#include <memory>
+
+#include <CoreGraphics/CoreGraphics.h>
+
+namespace cru::platform::graphics::osx::quartz {
+class QuartzGeometry : public OsxQuartzResource, public virtual IGeometry {
+ public:
+ QuartzGeometry(IGraphFactory *graphics_factory, CGContextRef cg_context,
+ CGPathRef cg_path);
+
+ CRU_DELETE_COPY(QuartzGeometry)
+ CRU_DELETE_MOVE(QuartzGeometry)
+
+ ~QuartzGeometry() override;
+
+ CGPathRef GetCGPath() const { return cg_path_; }
+
+ bool FillContains(const Point &point) override;
+
+ private:
+ CGContextRef cg_context_;
+ CGPathRef cg_path_;
+};
+
+namespace details {
+struct GeometryBeginFigureAction : Object {
+ explicit GeometryBeginFigureAction(Point point) : point(point) {}
+
+ Point point;
+};
+
+struct GeometryCloseFigureAction : Object {
+ explicit GeometryCloseFigureAction(bool close) : close(close) {}
+
+ bool close;
+};
+
+struct GeometryLineToAction : Object {
+ explicit GeometryLineToAction(Point point) : point(point) {}
+
+ Point point;
+};
+
+struct GeometryQuadraticBezierToAction : Object {
+ GeometryQuadraticBezierToAction(Point control_point, Point end_point)
+ : control_point(control_point), end_point(end_point) {}
+
+ Point control_point;
+ Point end_point;
+};
+} // namespace details
+
+class QuartzGeometryBuilder : public OsxQuartzResource,
+ public virtual IGeometryBuilder {
+ public:
+ explicit QuartzGeometryBuilder(IGraphFactory *graphics_factory,
+ CGContextRef cg_context);
+
+ CRU_DELETE_COPY(QuartzGeometryBuilder)
+ CRU_DELETE_MOVE(QuartzGeometryBuilder)
+
+ ~QuartzGeometryBuilder() override = default;
+
+ void BeginFigure(const Point &point) override {
+ actions_.push_back(
+ std::make_unique<details::GeometryBeginFigureAction>(point));
+ }
+ void CloseFigure(bool close) override {
+ actions_.push_back(
+ std::make_unique<details::GeometryCloseFigureAction>(close));
+ }
+ void LineTo(const Point &point) override {
+ actions_.push_back(std::make_unique<details::GeometryLineToAction>(point));
+ }
+ void QuadraticBezierTo(const Point &control_point,
+ const Point &end_point) override {
+ actions_.push_back(
+ std::make_unique<details::GeometryQuadraticBezierToAction>(
+ control_point, end_point));
+ }
+
+ std::unique_ptr<IGeometry> Build() override;
+
+ private:
+ CGContextRef cg_context_;
+
+ std::vector<std::unique_ptr<Object>> actions_;
+};
+} // namespace cru::platform::graphics::osx::quartz
diff --git a/src/osx/graphics/quartz/CMakeLists.txt b/src/osx/graphics/quartz/CMakeLists.txt
index fcbda648..6c978b18 100644
--- a/src/osx/graphics/quartz/CMakeLists.txt
+++ b/src/osx/graphics/quartz/CMakeLists.txt
@@ -4,6 +4,7 @@ add_library(cru_osx_graphics_quartz SHARED
Brush.cpp
Convert.cpp
Factory.cpp
+ Geometry.cpp
Painter.cpp
Resource.cpp
)
@@ -11,6 +12,7 @@ target_sources(cru_osx_graphics_quartz PUBLIC
${CRU_OSX_GRAPHICS_NATIVE_INCLUDE_DIR}/Brush.hpp
${CRU_OSX_GRAPHICS_NATIVE_INCLUDE_DIR}/Convert.hpp
${CRU_OSX_GRAPHICS_NATIVE_INCLUDE_DIR}/Factory.hpp
+ ${CRU_OSX_GRAPHICS_NATIVE_INCLUDE_DIR}/Geometry.hpp
${CRU_OSX_GRAPHICS_NATIVE_INCLUDE_DIR}/Painter.hpp
${CRU_OSX_GRAPHICS_NATIVE_INCLUDE_DIR}/Resource.hpp
)
diff --git a/src/osx/graphics/quartz/Geometry.cpp b/src/osx/graphics/quartz/Geometry.cpp
new file mode 100644
index 00000000..428b24ab
--- /dev/null
+++ b/src/osx/graphics/quartz/Geometry.cpp
@@ -0,0 +1,48 @@
+#include "cru/osx/graphics/quartz/Geometry.hpp"
+
+#include <memory>
+
+namespace cru::platform::graphics::osx::quartz {
+QuartzGeometry::QuartzGeometry(IGraphFactory* graphics_factory,
+ CGContextRef cg_context, CGPathRef cg_path)
+ : OsxQuartzResource(graphics_factory),
+ cg_context_(cg_context),
+ cg_path_(cg_path) {}
+
+QuartzGeometry::~QuartzGeometry() { CGPathRelease(cg_path_); }
+
+bool QuartzGeometry::FillContains(const Point& point) {
+ CGContextBeginPath(cg_context_);
+ CGContextAddPath(cg_context_, cg_path_);
+ return CGContextPathContainsPoint(cg_context_, CGPoint{point.x, point.y},
+ kCGPathFill);
+}
+
+QuartzGeometryBuilder::QuartzGeometryBuilder(IGraphFactory* graphics_factory,
+ CGContextRef cg_context)
+ : OsxQuartzResource(graphics_factory), cg_context_(cg_context) {}
+
+std::unique_ptr<IGeometry> QuartzGeometryBuilder::Build() {
+ CGContextBeginPath(cg_context_);
+
+ for (const auto& action : actions_) {
+ Object* o = action.get();
+
+ if (auto a = dynamic_cast<details::GeometryBeginFigureAction*>(o)) {
+ CGContextMoveToPoint(cg_context_, a->point.x, a->point.y);
+ } else if (auto a = dynamic_cast<details::GeometryCloseFigureAction*>(o)) {
+ if (a->close) CGContextClosePath(cg_context_);
+ } else if (auto a = dynamic_cast<details::GeometryLineToAction*>(o)) {
+ CGContextAddLineToPoint(cg_context_, a->point.x, a->point.y);
+ } else if (auto a =
+ dynamic_cast<details::GeometryQuadraticBezierToAction*>(o)) {
+ CGContextAddQuadCurveToPoint(cg_context_, a->control_point.x,
+ a->control_point.y, a->end_point.x,
+ a->end_point.y);
+ }
+ }
+
+ return std::make_unique<QuartzGeometry>(GetGraphFactory(), cg_context_,
+ CGContextCopyPath(cg_context_));
+}
+} // namespace cru::platform::graphics::osx::quartz