From e94ceefaf188e091d4a3d5580fe21d77a261f902 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Thu, 8 Aug 2019 14:15:06 +0800 Subject: [PATCH] [build] add ShapeNode & remove Geometry --- projects/kiwano.vcxproj | 6 +- projects/kiwano.vcxproj.filters | 18 +- src/kiwano/2d/Canvas.cpp | 29 +- src/kiwano/2d/Canvas.h | 12 +- src/kiwano/2d/GeometryNode.cpp | 87 --- src/kiwano/2d/GeometryNode.h | 89 --- src/kiwano/2d/{Geometry.cpp => ShapeNode.cpp} | 509 ++++++++++-------- src/kiwano/2d/{Geometry.h => ShapeNode.h} | 224 +++++--- src/kiwano/2d/include-forwards.h | 16 +- src/kiwano/kiwano.h | 3 +- 10 files changed, 426 insertions(+), 567 deletions(-) delete mode 100644 src/kiwano/2d/GeometryNode.cpp delete mode 100644 src/kiwano/2d/GeometryNode.h rename src/kiwano/2d/{Geometry.cpp => ShapeNode.cpp} (68%) rename src/kiwano/2d/{Geometry.h => ShapeNode.h} (69%) diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj index 149e7855..2b4e6407 100644 --- a/projects/kiwano.vcxproj +++ b/projects/kiwano.vcxproj @@ -18,8 +18,7 @@ - - + @@ -92,8 +91,7 @@ - - + diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters index e2547547..6415693e 100644 --- a/projects/kiwano.vcxproj.filters +++ b/projects/kiwano.vcxproj.filters @@ -75,12 +75,6 @@ 2d - - 2d - - - 2d - 2d @@ -270,6 +264,9 @@ third-party\tinyxml2 + + 2d + @@ -305,12 +302,6 @@ 2d - - 2d - - - 2d - 2d @@ -410,5 +401,8 @@ third-party\tinyxml2 + + 2d + \ No newline at end of file diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index 378c2bab..be985f0d 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -20,7 +20,6 @@ #include "Canvas.h" #include "Image.h" -#include "Geometry.h" #include "../base/logs.h" #include "../renderer/render.h" @@ -298,20 +297,6 @@ namespace kiwano ); } - void Canvas::DrawGeometry(GeometryPtr geo) - { - if (geo && geo->geo_) - { - render_target_->DrawGeometry( - geo->geo_.Get(), - stroke_brush_.Get(), - stroke_width_, - outline_join_style_.Get() - ); - cache_expired_ = true; - } - } - void Canvas::FillCircle(const Point & center, float radius) { render_target_->FillEllipse( @@ -376,18 +361,6 @@ namespace kiwano cache_expired_ = true; } - void Canvas::FillGeometry(GeometryPtr geo) - { - if (geo && geo->geo_) - { - render_target_->FillGeometry( - geo->geo_.Get(), - fill_brush_.Get() - ); - cache_expired_ = true; - } - } - void Canvas::BeginPath(Point const& begin_pos) { current_geometry_ = nullptr; @@ -508,4 +481,4 @@ namespace kiwano return bitmap_cached_; } -} \ No newline at end of file +} diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 436284aa..310db944 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -95,11 +95,6 @@ namespace kiwano Point const& point /* 文字位置 */ ); - // 画几何图形边框 - void DrawGeometry( - GeometryPtr geo - ); - // 填充圆形 void FillCircle( const Point& center, @@ -125,11 +120,6 @@ namespace kiwano float radius_y ); - // 填充几何图形 - void FillGeometry( - GeometryPtr geo - ); - // 开始绘制路径 void BeginPath( Point const& begin_pos /* 路径起始点 */ @@ -240,4 +230,4 @@ namespace kiwano mutable bool cache_expired_; mutable ComPtr bitmap_cached_; }; -} \ No newline at end of file +} diff --git a/src/kiwano/2d/GeometryNode.cpp b/src/kiwano/2d/GeometryNode.cpp deleted file mode 100644 index 8f29e7c1..00000000 --- a/src/kiwano/2d/GeometryNode.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2016-2018 Kiwano - Nomango -// -// 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: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// 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. - -#include "GeometryNode.h" -#include "../renderer/render.h" - -namespace kiwano -{ - GeometryNode::GeometryNode() - : fill_color_(Color::White) - , stroke_color_(Color(Color::Black, 0)) - , stroke_width_(1.f) - , outline_join_(StrokeStyle::Miter) - { - } - - GeometryNode::GeometryNode(GeometryPtr geometry) - : GeometryNode() - { - SetGeometry(geometry); - } - - GeometryNode::~GeometryNode() - { - } - - void GeometryNode::SetGeometry(GeometryPtr geometry) - { - geometry_ = geometry; - } - - void GeometryNode::SetFillColor(const Color & color) - { - fill_color_ = color; - } - - void GeometryNode::SetStrokeColor(const Color & color) - { - stroke_color_ = color; - } - - void GeometryNode::SetStrokeWidth(float width) - { - stroke_width_ = std::max(width, 0.f); - } - - void GeometryNode::SetOutlineJoinStyle(StrokeStyle outline_join) - { - outline_join_ = outline_join; - } - - void GeometryNode::OnRender() - { - if (geometry_ && geometry_->geo_) - { - Renderer::Instance()->FillGeometry( - geometry_->geo_.Get(), - fill_color_ - ); - - Renderer::Instance()->DrawGeometry( - geometry_->geo_, - stroke_color_, - stroke_width_, - outline_join_ - ); - } - } - -} diff --git a/src/kiwano/2d/GeometryNode.h b/src/kiwano/2d/GeometryNode.h deleted file mode 100644 index 7228933b..00000000 --- a/src/kiwano/2d/GeometryNode.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2016-2018 Kiwano - Nomango -// -// 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: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// 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. - -#pragma once -#include "Geometry.h" -#include "Node.h" - -namespace kiwano -{ - // 几何图形 - class KGE_API GeometryNode - : public VisualNode - { - public: - GeometryNode(); - - GeometryNode( - GeometryPtr geometry - ); - - virtual ~GeometryNode(); - - // 设置形状 - void SetGeometry( - GeometryPtr geometry - ); - - // 设置填充颜色 - void SetFillColor( - const Color& color - ); - - // 设置线条颜色 - void SetStrokeColor( - const Color& color - ); - - // 设置线条宽度 - void SetStrokeWidth( - float width - ); - - // 设置线条相交样式 - void SetOutlineJoinStyle( - StrokeStyle outline_join - ); - - // 获取形状 - GeometryPtr GetGeometry() const { return geometry_; } - - // 获取填充颜色 - Color GetFillColor() const { return fill_color_; } - - // 获取线条颜色 - Color GetStrokeColor() const { return stroke_color_; } - - // 获取线条宽度 - float GetStrokeWidth() const { return stroke_width_; } - - // 获取线条相交样式 - StrokeStyle SetOutlineJoinStyle() const { return outline_join_; } - - void OnRender() override; - - protected: - Color fill_color_; - Color stroke_color_; - float stroke_width_; - StrokeStyle outline_join_; - GeometryPtr geometry_; - }; -} diff --git a/src/kiwano/2d/Geometry.cpp b/src/kiwano/2d/ShapeNode.cpp similarity index 68% rename from src/kiwano/2d/Geometry.cpp rename to src/kiwano/2d/ShapeNode.cpp index 5c2cfe63..d3bc288f 100644 --- a/src/kiwano/2d/Geometry.cpp +++ b/src/kiwano/2d/ShapeNode.cpp @@ -18,25 +18,30 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "Geometry.h" -#include "../renderer/render.h" +#include "ShapeNode.h" #include "../base/logs.h" namespace kiwano { - //------------------------------------------------------- - // Geometry - //------------------------------------------------------- - - Geometry::Geometry() + ShapeNode::ShapeNode() + : fill_color_(Color::White) + , stroke_color_(Color(Color::Black, 0)) + , stroke_width_(1.f) + , outline_join_(StrokeStyle::Miter) { } - Geometry::~Geometry() + ShapeNode::ShapeNode(ComPtr geometry) + : ShapeNode() + { + SetGeometry(geometry); + } + + ShapeNode::~ShapeNode() { } - Rect Geometry::GetBoundingBox() + Rect ShapeNode::GetBoundingBox() { if (!geo_) return Rect{}; @@ -47,7 +52,7 @@ namespace kiwano return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; } - float Geometry::GetLength() + float ShapeNode::GetLength() { float length = 0.f; if (geo_) @@ -58,28 +63,23 @@ namespace kiwano return length; } - bool Geometry::ComputePointAt(float length, Point* point, Point* tangent) + bool ShapeNode::ComputePointAtLength(float length, Point& point, Vec2& tangent) { if (geo_) { - D2D1_POINT_2F point_tmp, tangent_tmp; if (SUCCEEDED(geo_->ComputePointAtLength( length, D2D1::Matrix3x2F::Identity(), - &point_tmp, - &tangent_tmp))) + DX::ConvertToPoint2F(&point), + DX::ConvertToPoint2F(&tangent)))) { - (*point).x = point_tmp.x; - (*point).y = point_tmp.y; - (*tangent).x = tangent_tmp.x; - (*tangent).y = tangent_tmp.y; return true; } } return false; } - float Geometry::ComputeArea() + float ShapeNode::ComputeArea() { if (!geo_) return 0.f; @@ -90,7 +90,7 @@ namespace kiwano return area; } - bool Geometry::ContainsPoint(Point const & point) + bool ShapeNode::ContainsPoint(Point const& point) { if (!geo_) return false; @@ -105,25 +105,62 @@ namespace kiwano return !!ret; } + void ShapeNode::SetFillColor(const Color & color) + { + fill_color_ = color; + } + + void ShapeNode::SetStrokeColor(const Color & color) + { + stroke_color_ = color; + } + + void ShapeNode::SetStrokeWidth(float width) + { + stroke_width_ = std::max(width, 0.f); + } + + void ShapeNode::SetOutlineJoinStyle(StrokeStyle outline_join) + { + outline_join_ = outline_join; + } + + void ShapeNode::OnRender() + { + if (geo_) + { + Renderer::Instance()->FillGeometry( + geo_, + fill_color_ + ); + + Renderer::Instance()->DrawGeometry( + geo_, + stroke_color_, + stroke_width_, + outline_join_ + ); + } + } //------------------------------------------------------- - // LineGeometry + // LineNode //------------------------------------------------------- - LineGeometry::LineGeometry() + LineNode::LineNode() { } - LineGeometry::LineGeometry(Point const & begin, Point const & end) + LineNode::LineNode(Point const& begin, Point const& end) { SetLine(begin, end); } - LineGeometry::~LineGeometry() + LineNode::~LineNode() { } - void LineGeometry::SetLine(Point const & begin, Point const & end) + void LineNode::SetLine(Point const& begin, Point const& end) { ComPtr path_geo; ComPtr path_sink; @@ -149,40 +186,40 @@ namespace kiwano } } - void LineGeometry::SetBegin(Point const & begin) + void LineNode::SetBegin(Point const& begin) { SetLine(begin, end_); } - void LineGeometry::SetEnd(Point const & end) + void LineNode::SetEnd(Point const& end) { SetLine(begin_, end); } //------------------------------------------------------- - // RectangleGeometry + // RectNode //------------------------------------------------------- - RectangleGeometry::RectangleGeometry() + RectNode::RectNode() { } - RectangleGeometry::RectangleGeometry(Rect const & rect) + RectNode::RectNode(Rect const& rect) { SetRect(rect); } - RectangleGeometry::RectangleGeometry(Point const & left_top, Size const & size) + RectNode::RectNode(Point const& left_top, Size const& size) { SetRect(Rect{ left_top, size }); } - RectangleGeometry::~RectangleGeometry() + RectNode::~RectNode() { } - void RectangleGeometry::SetRect(Rect const & rect) + void RectNode::SetRect(Rect const& rect) { ComPtr geo; auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); @@ -196,230 +233,35 @@ namespace kiwano //------------------------------------------------------- - // CircleGeometry + // RoundedRectNode //------------------------------------------------------- - CircleGeometry::CircleGeometry() - : radius_(0.f) - { - } - - CircleGeometry::CircleGeometry(Point const & center, float radius) - { - SetCircle(center, radius); - } - - CircleGeometry::~CircleGeometry() - { - } - - void CircleGeometry::SetRadius(float radius) - { - SetCircle(center_, radius); - } - - void CircleGeometry::SetCenter(Point const & center) - { - SetCircle(center, radius_); - } - - void CircleGeometry::SetCircle(Point const & center, float radius) - { - ComPtr geo; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); - - if (SUCCEEDED(factory->CreateEllipseGeometry( - D2D1::Ellipse( - DX::ConvertToPoint2F(center), - radius, - radius), - &geo))) - { - geo_ = geo; - center_ = center; - radius_ = radius; - } - } - - - //------------------------------------------------------- - // EllipseGeometry - //------------------------------------------------------- - - EllipseGeometry::EllipseGeometry() + RoundedRectNode::RoundedRectNode() : radius_x_(0.f) , radius_y_(0.f) { } - EllipseGeometry::EllipseGeometry(Point const & center, float radius_x, float radius_y) - { - SetEllipse(center, radius_x, radius_y); - } - - EllipseGeometry::~EllipseGeometry() - { - } - - void EllipseGeometry::SetRadius(float radius_x, float radius_y) - { - SetEllipse(center_, radius_x, radius_y); - } - - void EllipseGeometry::SetCenter(Point const & center) - { - SetEllipse(center, radius_x_, radius_y_); - } - - void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y) - { - ComPtr geo; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); - - if (SUCCEEDED(factory->CreateEllipseGeometry( - D2D1::Ellipse( - DX::ConvertToPoint2F(center), - radius_x, - radius_y), - &geo))) - { - geo_ = geo; - radius_x_ = radius_x; - radius_y_ = radius_y; - } - } - - - //------------------------------------------------------- - // PathGeometry - //------------------------------------------------------- - - PathGeometry::PathGeometry() - { - } - - PathGeometry::~PathGeometry() - { - } - - void PathGeometry::BeginPath(Point const& begin_pos) - { - current_geometry_ = nullptr; - - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); - - ThrowIfFailed( - factory->CreatePathGeometry(¤t_geometry_) - ); - - ThrowIfFailed( - current_geometry_->Open(¤t_sink_) - ); - - current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); - } - - void PathGeometry::EndPath(bool closed) - { - if (current_sink_) - { - current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); - ThrowIfFailed( - current_sink_->Close() - ); - - geo_ = current_geometry_; - - current_sink_ = nullptr; - current_geometry_ = nullptr; - } - } - - void PathGeometry::AddLine(Point const & point) - { - if (current_sink_) - current_sink_->AddLine(DX::ConvertToPoint2F(point)); - } - - void PathGeometry::AddLines(Array const& points) - { - if (current_sink_ && !points.empty()) - { - current_sink_->AddLines( - reinterpret_cast(&points[0]), - static_cast(points.size()) - ); - } - } - - void PathGeometry::AddBezier(Point const & point1, Point const & point2, Point const & point3) - { - if (current_sink_) - { - current_sink_->AddBezier( - D2D1::BezierSegment( - DX::ConvertToPoint2F(point1), - DX::ConvertToPoint2F(point2), - DX::ConvertToPoint2F(point3) - ) - ); - } - } - - void PathGeometry::AddArc(Point const & point, Size const & radius, float rotation, bool clockwise, bool is_small) - { - if (current_sink_) - { - current_sink_->AddArc( - D2D1::ArcSegment( - DX::ConvertToPoint2F(point), - DX::ConvertToSizeF(radius), - rotation, - clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, - is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE - ) - ); - } - } - - void PathGeometry::ClearPath() - { - geo_ = nullptr; - current_sink_ = nullptr; - current_geometry_ = nullptr; - } - - - //------------------------------------------------------- - // RoundedRectGeometry - //------------------------------------------------------- - - RoundedRectGeometry::RoundedRectGeometry() - : radius_x_(0.f) - , radius_y_(0.f) - { - } - - RoundedRectGeometry::RoundedRectGeometry(Rect const & rect, float radius_x, float radius_y) + RoundedRectNode::RoundedRectNode(Rect const& rect, float radius_x, float radius_y) { SetRoundedRect(rect, radius_x, radius_y); } - RoundedRectGeometry::~RoundedRectGeometry() + RoundedRectNode::~RoundedRectNode() { } - void RoundedRectGeometry::SetRadius(float radius_x, float radius_y) + void RoundedRectNode::SetRadius(float radius_x, float radius_y) { SetRoundedRect(rect_, radius_x, radius_y); } - void RoundedRectGeometry::SetRect(Rect const & rect) + void RoundedRectNode::SetRect(Rect const& rect) { SetRoundedRect(rect, radius_x_, radius_y_); } - void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y) + void RoundedRectNode::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) { ComPtr geo; auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); @@ -439,4 +281,199 @@ namespace kiwano } } -} \ No newline at end of file + + //------------------------------------------------------- + // CircleNode + //------------------------------------------------------- + + CircleNode::CircleNode() + : radius_(0.f) + { + } + + CircleNode::CircleNode(Point const& center, float radius) + { + SetCircle(center, radius); + } + + CircleNode::~CircleNode() + { + } + + void CircleNode::SetRadius(float radius) + { + SetCircle(center_, radius); + } + + void CircleNode::SetCenter(Point const& center) + { + SetCircle(center, radius_); + } + + void CircleNode::SetCircle(Point const& center, float radius) + { + ComPtr geo; + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + + if (SUCCEEDED(factory->CreateEllipseGeometry( + D2D1::Ellipse( + DX::ConvertToPoint2F(center), + radius, + radius), + &geo))) + { + geo_ = geo; + center_ = center; + radius_ = radius; + } + } + + + //------------------------------------------------------- + // EllipseNode + //------------------------------------------------------- + + EllipseNode::EllipseNode() + : radius_x_(0.f) + , radius_y_(0.f) + { + } + + EllipseNode::EllipseNode(Point const& center, float radius_x, float radius_y) + { + SetEllipse(center, radius_x, radius_y); + } + + EllipseNode::~EllipseNode() + { + } + + void EllipseNode::SetRadius(float radius_x, float radius_y) + { + SetEllipse(center_, radius_x, radius_y); + } + + void EllipseNode::SetCenter(Point const& center) + { + SetEllipse(center, radius_x_, radius_y_); + } + + void EllipseNode::SetEllipse(Point const& center, float radius_x, float radius_y) + { + ComPtr geo; + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + + if (SUCCEEDED(factory->CreateEllipseGeometry( + D2D1::Ellipse( + DX::ConvertToPoint2F(center), + radius_x, + radius_y), + &geo))) + { + geo_ = geo; + radius_x_ = radius_x; + radius_y_ = radius_y; + } + } + + + //------------------------------------------------------- + // PathNode + //------------------------------------------------------- + + PathNode::PathNode() + { + } + + PathNode::~PathNode() + { + } + + void PathNode::BeginPath(Point const& begin_pos) + { + current_geometry_ = nullptr; + + auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + + ThrowIfFailed( + factory->CreatePathGeometry(¤t_geometry_) + ); + + ThrowIfFailed( + current_geometry_->Open(¤t_sink_) + ); + + current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); + } + + void PathNode::EndPath(bool closed) + { + if (current_sink_) + { + current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); + ThrowIfFailed( + current_sink_->Close() + ); + + geo_ = current_geometry_; + + current_sink_ = nullptr; + current_geometry_ = nullptr; + } + } + + void PathNode::AddLine(Point const& point) + { + if (current_sink_) + current_sink_->AddLine(DX::ConvertToPoint2F(point)); + } + + void PathNode::AddLines(Array const& points) + { + if (current_sink_ && !points.empty()) + { + current_sink_->AddLines( + reinterpret_cast(&points[0]), + static_cast(points.size()) + ); + } + } + + void PathNode::AddBezier(Point const& point1, Point const& point2, Point const& point3) + { + if (current_sink_) + { + current_sink_->AddBezier( + D2D1::BezierSegment( + DX::ConvertToPoint2F(point1), + DX::ConvertToPoint2F(point2), + DX::ConvertToPoint2F(point3) + ) + ); + } + } + + void PathNode::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) + { + if (current_sink_) + { + current_sink_->AddArc( + D2D1::ArcSegment( + DX::ConvertToPoint2F(point), + DX::ConvertToSizeF(radius), + rotation, + clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, + is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE + ) + ); + } + } + + void PathNode::ClearPath() + { + geo_ = nullptr; + current_sink_ = nullptr; + current_geometry_ = nullptr; + } + +} diff --git a/src/kiwano/2d/Geometry.h b/src/kiwano/2d/ShapeNode.h similarity index 69% rename from src/kiwano/2d/Geometry.h rename to src/kiwano/2d/ShapeNode.h index 6f54a492..75d40318 100644 --- a/src/kiwano/2d/Geometry.h +++ b/src/kiwano/2d/ShapeNode.h @@ -19,22 +19,35 @@ // THE SOFTWARE. #pragma once -#include "include-forwards.h" -#include +#include "Node.h" +#include "../renderer/render.h" // ID2D1Geometry namespace kiwano { - // 几何抽象 - class KGE_API Geometry - : public Object + // 二维图形节点 + class KGE_API ShapeNode + : public VisualNode { - friend class Canvas; - friend class GeometryNode; - public: - Geometry(); + ShapeNode(); - virtual ~Geometry(); + ShapeNode( + ComPtr geometry + ); + + virtual ~ShapeNode(); + + // 获取填充颜色 + Color GetFillColor() const { return fill_color_; } + + // 获取线条颜色 + Color GetStrokeColor() const { return stroke_color_; } + + // 获取线条宽度 + float GetStrokeWidth() const { return stroke_width_; } + + // 获取线条相交样式 + StrokeStyle SetOutlineJoinStyle() const { return outline_join_; } // 获取外切包围盒 Rect GetBoundingBox(); @@ -47,34 +60,66 @@ namespace kiwano // 获取图形展开成一条直线的长度 float GetLength(); - // 计算图形路径上点的位置和切线向量 - bool ComputePointAt( - float length, - Point* point, - Point* tangent - ); - // 计算面积 float ComputeArea(); + // 计算图形路径上点的位置和切线向量 + bool ComputePointAtLength( + float length, + Point& point, + Vec2& tangent + ); + + // 设置填充颜色 + void SetFillColor( + const Color& color + ); + + // 设置线条颜色 + void SetStrokeColor( + const Color& color + ); + + // 设置线条宽度 + void SetStrokeWidth( + float width + ); + + // 设置线条相交样式 + void SetOutlineJoinStyle( + StrokeStyle outline_join + ); + + // 设置形状 + inline void SetGeometry(ComPtr geometry) { geo_ = geometry; } + + // 获取形状 + inline ComPtr GetGeometry() const { return geo_; } + + void OnRender() override; + protected: - ComPtr geo_; + Color fill_color_; + Color stroke_color_; + float stroke_width_; + StrokeStyle outline_join_; + ComPtr geo_; }; // 直线 - class KGE_API LineGeometry - : public Geometry + class KGE_API LineNode + : public ShapeNode { public: - LineGeometry(); + LineNode(); - LineGeometry( + LineNode( Point const& begin, Point const& end ); - virtual ~LineGeometry(); + virtual ~LineNode(); Point const& GetBegin() const { return begin_; } @@ -99,23 +144,23 @@ namespace kiwano }; - // 几何矩形 - class KGE_API RectangleGeometry - : public Geometry + // 矩形节点 + class KGE_API RectNode + : public ShapeNode { public: - RectangleGeometry(); + RectNode(); - RectangleGeometry( + RectNode( Rect const& rect ); - RectangleGeometry( + RectNode( Point const& left_top, Size const& size ); - virtual ~RectangleGeometry(); + virtual ~RectNode(); Rect const& GetRect() const { return rect_; } @@ -126,19 +171,62 @@ namespace kiwano }; - // 几何圆形 - class KGE_API CircleGeometry - : public Geometry + // 圆角矩形节点 + class KGE_API RoundedRectNode + : public ShapeNode { public: - CircleGeometry(); + RoundedRectNode(); - CircleGeometry( + RoundedRectNode( + Rect const& rect, + float radius_x, + float radius_y + ); + + virtual ~RoundedRectNode(); + + float GetRadiusX() const { return radius_x_; } + + float GetRadiusY() const { return radius_y_; } + + void SetRadius( + float radius_x, + float radius_y + ); + + Rect const& GetRect() const { return rect_; } + + void SetRect( + Rect const& rect + ); + + void SetRoundedRect( + Rect const& rect, + float radius_x, + float radius_y + ); + + protected: + Rect rect_; + float radius_x_; + float radius_y_; + }; + + + // 圆形节点 + class KGE_API CircleNode + : public ShapeNode + { + public: + CircleNode(); + + CircleNode( Point const& center, float radius ); - virtual ~CircleGeometry(); + virtual ~CircleNode(); float GetRadius() const { return radius_; } @@ -163,20 +251,20 @@ namespace kiwano }; - // 几何椭圆 - class KGE_API EllipseGeometry - : public Geometry + // 椭圆节点 + class KGE_API EllipseNode + : public ShapeNode { public: - EllipseGeometry(); + EllipseNode(); - EllipseGeometry( + EllipseNode( Point const& center, float radius_x, float radius_y ); - virtual ~EllipseGeometry(); + virtual ~EllipseNode(); float GetRadiusX() const { return radius_x_; } @@ -206,14 +294,14 @@ namespace kiwano }; - // 几何路径 - class KGE_API PathGeometry - : public Geometry + // 路径节点 + class KGE_API PathNode + : public ShapeNode { public: - PathGeometry(); + PathNode(); - virtual ~PathGeometry(); + virtual ~PathNode(); // 开始添加路径 void BeginPath( @@ -259,46 +347,4 @@ namespace kiwano ComPtr current_sink_; }; - - // 几何圆角矩形 - class KGE_API RoundedRectGeometry - : public Geometry - { - public: - RoundedRectGeometry(); - - RoundedRectGeometry( - Rect const& rect, - float radius_x, - float radius_y - ); - - virtual ~RoundedRectGeometry(); - - float GetRadiusX() const { return radius_x_; } - - float GetRadiusY() const { return radius_y_; } - - void SetRadius( - float radius_x, - float radius_y - ); - - Rect const& GetRect() const { return rect_; } - - void SetRect( - Rect const& rect - ); - - void SetRoundedRect( - Rect const& rect, - float radius_x, - float radius_y - ); - - protected: - Rect rect_; - float radius_x_; - float radius_y_; - }; } diff --git a/src/kiwano/2d/include-forwards.h b/src/kiwano/2d/include-forwards.h index 16607b34..620fb3da 100644 --- a/src/kiwano/2d/include-forwards.h +++ b/src/kiwano/2d/include-forwards.h @@ -38,14 +38,6 @@ namespace kiwano KGE_DECLARE_SMART_PTR(GifImage); KGE_DECLARE_SMART_PTR(Frames); - KGE_DECLARE_SMART_PTR(Geometry); - KGE_DECLARE_SMART_PTR(LineGeometry); - KGE_DECLARE_SMART_PTR(RectangleGeometry); - KGE_DECLARE_SMART_PTR(RoundedRectGeometry); - KGE_DECLARE_SMART_PTR(CircleGeometry); - KGE_DECLARE_SMART_PTR(EllipseGeometry); - KGE_DECLARE_SMART_PTR(PathGeometry); - KGE_DECLARE_SMART_PTR(Node); KGE_DECLARE_SMART_PTR(Scene); KGE_DECLARE_SMART_PTR(Layer); @@ -53,7 +45,13 @@ namespace kiwano KGE_DECLARE_SMART_PTR(GifSprite); KGE_DECLARE_SMART_PTR(Text); KGE_DECLARE_SMART_PTR(Canvas); - KGE_DECLARE_SMART_PTR(GeometryNode); + KGE_DECLARE_SMART_PTR(ShapeNode); + KGE_DECLARE_SMART_PTR(LineNode); + KGE_DECLARE_SMART_PTR(RectNode); + KGE_DECLARE_SMART_PTR(RoundedRectNode); + KGE_DECLARE_SMART_PTR(CircleNode); + KGE_DECLARE_SMART_PTR(EllipseNode); + KGE_DECLARE_SMART_PTR(PathNode); KGE_DECLARE_SMART_PTR(Action); KGE_DECLARE_SMART_PTR(ActionTween); diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 85f7450f..30489ed3 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -85,7 +85,6 @@ #include "2d/Image.h" #include "2d/GifImage.h" #include "2d/Frames.h" -#include "2d/Geometry.h" #include "2d/Action.h" #include "2d/ActionGroup.h" #include "2d/ActionTween.h" @@ -101,7 +100,7 @@ #include "2d/GifSprite.h" #include "2d/Text.h" #include "2d/Canvas.h" -#include "2d/GeometryNode.h" +#include "2d/ShapeNode.h" #include "2d/DebugNode.h"