aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-05-25 16:01:23 +0800
committercrupest <crupest@outlook.com>2022-05-25 16:01:23 +0800
commitb84cd6a0b6fc3e7f9493d50ce32cfb33095e7954 (patch)
tree3cde83841ca20375e96ad036aefbf2a02990e971
parentad4f06c133dc0475ef6a98cac0fa97f6e0527bf1 (diff)
downloadcru-b84cd6a0b6fc3e7f9493d50ce32cfb33095e7954.tar.gz
cru-b84cd6a0b6fc3e7f9493d50ce32cfb33095e7954.tar.bz2
cru-b84cd6a0b6fc3e7f9493d50ce32cfb33095e7954.zip
...
-rw-r--r--include/cru/platform/graphics/Geometry.h6
-rw-r--r--include/cru/platform/graphics/cairo/CairoGeometry.h1
-rw-r--r--src/platform/graphics/Geometry.cpp5
-rw-r--r--src/platform/graphics/cairo/CairoGeometry.cpp27
4 files changed, 38 insertions, 1 deletions
diff --git a/include/cru/platform/graphics/Geometry.h b/include/cru/platform/graphics/Geometry.h
index 19620789..d1045b59 100644
--- a/include/cru/platform/graphics/Geometry.h
+++ b/include/cru/platform/graphics/Geometry.h
@@ -5,6 +5,12 @@
namespace cru::platform::graphics {
struct CRU_PLATFORM_GRAPHICS_API IGeometry : virtual IGraphicsResource {
+ /**
+ * \remarks Because I designed CreateStrokeGeometry first, which might be not
+ * that rational. So the default implementation calls that method and do the
+ * test. New implementation should override this.
+ */
+ virtual bool StrokeContains(float width, const Point& point);
virtual bool FillContains(const Point& point) = 0;
virtual Rect GetBounds() = 0;
virtual std::unique_ptr<IGeometry> Transform(const Matrix& matrix) = 0;
diff --git a/include/cru/platform/graphics/cairo/CairoGeometry.h b/include/cru/platform/graphics/cairo/CairoGeometry.h
index f8391670..f510d687 100644
--- a/include/cru/platform/graphics/cairo/CairoGeometry.h
+++ b/include/cru/platform/graphics/cairo/CairoGeometry.h
@@ -13,6 +13,7 @@ class CRU_PLATFORM_GRAPHICS_CAIRO_API CairoGeometry : public CairoResource,
bool auto_destroy = true);
~CairoGeometry();
+ bool StrokeContains(float width, const Point& point) override;
bool FillContains(const Point& point) override;
Rect GetBounds() override;
std::unique_ptr<IGeometry> Transform(const Matrix& matrix) override;
diff --git a/src/platform/graphics/Geometry.cpp b/src/platform/graphics/Geometry.cpp
index c215ad30..20197153 100644
--- a/src/platform/graphics/Geometry.cpp
+++ b/src/platform/graphics/Geometry.cpp
@@ -7,6 +7,11 @@
#include <unordered_set>
namespace cru::platform::graphics {
+bool IGeometry::StrokeContains(float width, const Point& point) {
+ auto geometry = CreateStrokeGeometry(width);
+ return geometry->FillContains(point);
+}
+
constexpr float PI = 3.14159265358979323846f;
using std::abs;
diff --git a/src/platform/graphics/cairo/CairoGeometry.cpp b/src/platform/graphics/cairo/CairoGeometry.cpp
index 43ba08d8..3b6ca874 100644
--- a/src/platform/graphics/cairo/CairoGeometry.cpp
+++ b/src/platform/graphics/cairo/CairoGeometry.cpp
@@ -1,4 +1,5 @@
#include "cru/platform/graphics/cairo/CairoGeometry.h"
+#include "cru/platform/graphics/Geometry.h"
#include "cru/platform/graphics/cairo/CairoGraphicsFactory.h"
namespace cru::platform::graphics::cairo {
@@ -19,9 +20,24 @@ CairoGeometry::~CairoGeometry() {
}
}
+bool CairoGeometry::StrokeContains(float width, const Point& point) {
+ auto cairo = GetCairoGraphicsFactory()->GetDefaultCairo();
+ cairo_save(cairo);
+ auto matrix = Convert(transform_);
+ cairo_transform(cairo, &matrix);
+ cairo_new_path(cairo);
+ cairo_append_path(cairo, cairo_path_);
+ cairo_set_line_width(cairo, width);
+ auto result = cairo_in_stroke(cairo, point.x, point.y);
+ cairo_restore(cairo);
+ return result;
+}
+
bool CairoGeometry::FillContains(const Point& point) {
auto cairo = GetCairoGraphicsFactory()->GetDefaultCairo();
cairo_save(cairo);
+ auto matrix = Convert(transform_);
+ cairo_transform(cairo, &matrix);
cairo_new_path(cairo);
cairo_append_path(cairo, cairo_path_);
auto result = cairo_in_fill(cairo, point.x, point.y);
@@ -32,6 +48,8 @@ bool CairoGeometry::FillContains(const Point& point) {
Rect CairoGeometry::GetBounds() {
auto cairo = GetCairoGraphicsFactory()->GetDefaultCairo();
cairo_save(cairo);
+ auto matrix = Convert(transform_);
+ cairo_transform(cairo, &matrix);
cairo_new_path(cairo);
cairo_append_path(cairo, cairo_path_);
double l, t, r, b;
@@ -41,7 +59,14 @@ Rect CairoGeometry::GetBounds() {
}
std::unique_ptr<IGeometry> CairoGeometry::Transform(const Matrix& matrix) {
-
+ auto cairo = GetCairoGraphicsFactory()->GetDefaultCairo();
+ cairo_save(cairo);
+ cairo_new_path(cairo);
+ cairo_append_path(cairo, cairo_path_);
+ auto path = cairo_copy_path(cairo);
+ cairo_restore(cairo);
+ return std::unique_ptr<IGeometry>(new CairoGeometry(
+ GetCairoGraphicsFactory(), path, transform_ * matrix, true));
}
std::unique_ptr<IGeometry> CairoGeometry::CreateStrokeGeometry(float width) {