| 
									
										
										
										
											2019-04-11 14:40:54 +08:00
										 |  |  | // Copyright (c) 2016-2018 Kiwano - Nomango
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					
						
							|  |  |  | // of this software and associated documentation files (the "Software"), to deal
 | 
					
						
							|  |  |  | // in the Software without restriction, including without limitation the rights
 | 
					
						
							|  |  |  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					
						
							|  |  |  | // copies of the Software, and to permit persons to whom the Software is
 | 
					
						
							|  |  |  | // furnished to do so, subject to the following conditions:
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					
						
							|  |  |  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					
						
							|  |  |  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					
						
							|  |  |  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					
						
							|  |  |  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					
						
							|  |  |  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					
						
							|  |  |  | // THE SOFTWARE.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-11 21:55:29 +08:00
										 |  |  | #include <kiwano/2d/ShapeActor.h>
 | 
					
						
							| 
									
										
										
										
											2019-11-13 14:33:15 +08:00
										 |  |  | #include <kiwano/core/Logger.h>
 | 
					
						
							| 
									
										
										
										
											2020-01-17 16:55:47 +08:00
										 |  |  | #include <kiwano/render/Renderer.h>
 | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-04-11 14:40:54 +08:00
										 |  |  | namespace kiwano | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | ShapeActorPtr ShapeActor::Create() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ShapeActorPtr ptr = new (std::nothrow) ShapeActor; | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | ShapeActor::ShapeActor() | 
					
						
							|  |  |  |     : stroke_width_(1.f) | 
					
						
							|  |  |  |     , stroke_style_() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ShapeActor::~ShapeActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rect ShapeActor::GetBounds() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return bounds_; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Rect ShapeActor::GetBoundingBox() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |     if (!shape_) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         return Rect{}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |     return shape_->GetBoundingBox(GetTransformMatrix()); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ShapeActor::ContainsPoint(const Point& point) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |     if (!shape_) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return shape_->ContainsPoint(point, &GetTransformMatrix()); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ShapeActor::SetStrokeWidth(float width) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     stroke_width_ = std::max(width, 0.f); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | void ShapeActor::SetStrokeStyle(StrokeStylePtr stroke_style) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     stroke_style_ = stroke_style; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  | void ShapeActor::SetShape(ShapePtr shape) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |     shape_ = shape; | 
					
						
							|  |  |  |     if (shape_) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         bounds_ = shape_->GetBoundingBox(); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |         SetSize(bounds_.GetSize()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         bounds_ = Rect{}; | 
					
						
							|  |  |  |         SetSize(0.f, 0.f); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ShapeActor::OnRender(RenderContext& ctx) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |     if (shape_) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         if (stroke_brush_) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             ctx.SetCurrentBrush(stroke_brush_); | 
					
						
							| 
									
										
										
										
											2020-02-08 00:17:31 +08:00
										 |  |  |             ctx.DrawShape(*shape_, stroke_style_, stroke_width_ * 2 /* twice width for widening */); | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (fill_brush_) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             ctx.SetCurrentBrush(fill_brush_); | 
					
						
							|  |  |  |             ctx.FillShape(*shape_); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool ShapeActor::CheckVisibility(RenderContext& ctx) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |     return shape_ && Actor::CheckVisibility(ctx); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | // LineActor
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | LineActorPtr LineActor::Create(Point const& begin, Point const& end) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     LineActorPtr ptr = new (std::nothrow) LineActor; | 
					
						
							|  |  |  |     if (ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ptr->SetLine(begin, end); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | LineActor::LineActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LineActor::~LineActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LineActor::SetLine(Point const& begin, Point const& end) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (begin_ != begin || end_ != end) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         begin_ = begin; | 
					
						
							|  |  |  |         end_   = end; | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         SetShape(Shape::CreateLine(begin, end)); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | // RectActor
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | RectActorPtr RectActor::Create(Size const& size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     RectActorPtr ptr = new (std::nothrow) RectActor; | 
					
						
							|  |  |  |     if (ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ptr->SetRectSize(size); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | RectActor::RectActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RectActor::~RectActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void RectActor::SetRectSize(Size const& size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (size != rect_size_) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         rect_size_ = size; | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         SetShape(Shape::CreateRect(Rect{ Point{}, size })); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | // RoundedRectActor
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | RoundedRectActorPtr RoundedRectActor::Create(Size const& size, Vec2 const& radius) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     RoundedRectActorPtr ptr = new (std::nothrow) RoundedRectActor; | 
					
						
							|  |  |  |     if (ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ptr->SetRoundedRect(size, radius); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RoundedRectActor::RoundedRectActor() {} | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | RoundedRectActor::~RoundedRectActor() {} | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | void RoundedRectActor::SetRadius(Vec2 const& radius) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     SetRoundedRect(GetSize(), radius); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | void RoundedRectActor::SetRectSize(Size const& size) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     SetRoundedRect(size, radius_); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | void RoundedRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     if (rect_size_ != size || radius_ != radius) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         rect_size_ = size; | 
					
						
							|  |  |  |         radius_    = radius; | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         SetShape(Shape::CreateRoundedRect(Rect{ Point{}, size }, radius)); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | // CircleActor
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | CircleActorPtr CircleActor::Create(float radius) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     CircleActorPtr ptr = new (std::nothrow) CircleActor; | 
					
						
							|  |  |  |     if (ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ptr->SetRadius(radius); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | CircleActor::CircleActor() | 
					
						
							|  |  |  |     : radius_(0.f) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CircleActor::~CircleActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CircleActor::SetRadius(float radius) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (radius_ != radius) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         radius_ = radius; | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         SetShape(Shape::CreateCircle(Point{ radius, radius }, radius)); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | // EllipseActor
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | EllipseActorPtr EllipseActor::Create(Vec2 const& radius) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     EllipseActorPtr ptr = new (std::nothrow) EllipseActor; | 
					
						
							|  |  |  |     if (ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ptr->SetRadius(radius); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | EllipseActor::EllipseActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | EllipseActor::~EllipseActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void EllipseActor::SetRadius(Vec2 const& radius) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (radius_ != radius) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         radius_ = radius; | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         SetShape(Shape::CreateEllipse(radius, radius)); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | // PolygonActor
 | 
					
						
							|  |  |  | //-------------------------------------------------------
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-06 16:54:47 +08:00
										 |  |  | PolygonActorPtr PolygonActor::Create(Vector<Point> const& points) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PolygonActorPtr ptr = new (std::nothrow) PolygonActor; | 
					
						
							|  |  |  |     if (ptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ptr->SetVertices(points); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | PolygonActor::PolygonActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PolygonActor::~PolygonActor() {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void PolygonActor::SetVertices(Vector<Point> const& points) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (points.size() > 1) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-02-05 19:56:22 +08:00
										 |  |  |         SetShape(ShapeSink().BeginPath(points[0]).AddLines(&points[1], points.size() - 1).EndPath(true).GetShape()); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-31 01:37:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:09:55 +08:00
										 |  |  | }  // namespace kiwano
 |