From 04aa0383392f4db5560a862428a11532b1a032dd Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 20 Oct 2020 19:36:26 +0900 Subject: [PATCH] common fill: add fill-rule interface. Fill rule is used to select how paths are filled. For both fill rules, wheter or not a point is included in the fill is determined by taking a ray from that point to infinity and looking at intersections with the path. The ray can be in any direction, as long as it doens't pass through the end point of a segment or have a tricky intersection such as intersecting tangent to the path. @API Addtions: enum class TVG_EXPORT FillRule { Winding = 0, EvenOdd }; Result Fill::rule(FillRule r) noexcept; FillRule Fill::rule() const noexcept; @Examples: shape->rule(FillRule::EvenOdd); @issue: 97 --- inc/thorvg.h | 3 +++ src/lib/tvgFill.cpp | 2 +- src/lib/tvgShape.cpp | 14 ++++++++++++++ src/lib/tvgShapeImpl.h | 3 +++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/inc/thorvg.h b/inc/thorvg.h index 5b42f399..00e0163c 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -56,6 +56,7 @@ enum class TVG_EXPORT PathCommand { Close = 0, MoveTo, LineTo, CubicTo }; enum class TVG_EXPORT StrokeCap { Square = 0, Round, Butt }; enum class TVG_EXPORT StrokeJoin { Bevel = 0, Round, Miter }; enum class TVG_EXPORT FillSpread { Pad = 0, Reflect, Repeat }; +enum class TVG_EXPORT FillRule { Winding = 0, EvenOdd }; enum class TVG_EXPORT CompositeMethod { None = 0, ClipPath }; enum class TVG_EXPORT CanvasEngine { Sw = (1 << 1), Gl = (1 << 2)}; @@ -239,12 +240,14 @@ public: //Fill Result fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept; Result fill(std::unique_ptr f) noexcept; + Result fill(FillRule r) noexcept; //Getters uint32_t pathCommands(const PathCommand** cmds) const noexcept; uint32_t pathCoords(const Point** pts) const noexcept; Result fill(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept; const Fill* fill() const noexcept; + FillRule fillRule() const noexcept; float strokeWidth() const noexcept; Result strokeColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const noexcept; diff --git a/src/lib/tvgFill.cpp b/src/lib/tvgFill.cpp index f89ba8b9..59180bd1 100644 --- a/src/lib/tvgFill.cpp +++ b/src/lib/tvgFill.cpp @@ -88,4 +88,4 @@ FillSpread Fill::spread() const noexcept Fill* Fill::duplicate() const noexcept { return pImpl->duplicate(); -} +} \ No newline at end of file diff --git a/src/lib/tvgShape.cpp b/src/lib/tvgShape.cpp index 70f17578..db30c225 100644 --- a/src/lib/tvgShape.cpp +++ b/src/lib/tvgShape.cpp @@ -384,3 +384,17 @@ StrokeJoin Shape::strokeJoin() const noexcept return pImpl->stroke->join; } + + +Result Shape::fill(FillRule r) noexcept +{ + pImpl->rule = r; + + return Result::Success; +} + + +FillRule Shape::fillRule() const noexcept +{ + return pImpl->rule; +} diff --git a/src/lib/tvgShapeImpl.h b/src/lib/tvgShapeImpl.h index e238c0d1..982b62a0 100644 --- a/src/lib/tvgShapeImpl.h +++ b/src/lib/tvgShapeImpl.h @@ -196,6 +196,7 @@ struct Shape::Impl Fill *fill = nullptr; ShapeStroke *stroke = nullptr; uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a + FillRule rule = FillRule::Winding; void *edata = nullptr; //engine data Shape *shape = nullptr; uint32_t flag = RenderUpdateFlag::None; @@ -329,6 +330,7 @@ struct Shape::Impl if (!ret) return nullptr; auto dup = ret.get()->pImpl; + dup->rule = rule; //Color memcpy(dup->color, color, sizeof(color)); @@ -346,6 +348,7 @@ struct Shape::Impl dup->flag |= RenderUpdateFlag::Stroke; } + //Fill if (fill) { dup->fill = fill->duplicate(); dup->flag |= RenderUpdateFlag::Gradient;