diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 681af26f..49b0bd4d 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -39,10 +39,12 @@ namespace kiwano Actor::Actor() : visible_(true) + , visible_in_rt_(true) , update_pausing_(false) , hover_(false) , pressed_(false) , responsible_(false) + , dirty_visibility_(true) , dirty_transform_(false) , dirty_transform_inverse_(false) , cascade_opacity_(false) @@ -139,6 +141,16 @@ namespace kiwano } } + bool Actor::CheckVisibilty(RenderTarget* rt) const + { + if (dirty_visibility_) + { + dirty_visibility_ = false; + visible_in_rt_ = rt->CheckVisibility(GetBounds(), GetTransformMatrix()); + } + return visible_in_rt_; + } + void Actor::Dispatch(Event& evt) { if (!visible_) @@ -224,6 +236,7 @@ namespace kiwano dirty_transform_ = false; dirty_transform_inverse_ = true; + dirty_visibility_ = true; if (is_fast_transform_) { diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index e08037bc..45e13233 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -390,6 +390,8 @@ namespace kiwano virtual void RenderBorder(RenderTarget* rt); + virtual bool CheckVisibilty(RenderTarget* rt) const; + void UpdateTransform() const; void UpdateOpacity(); @@ -400,12 +402,12 @@ namespace kiwano protected: bool visible_; - bool hover_; - bool pressed_; - bool responsible_; bool update_pausing_; bool cascade_opacity_; bool show_border_; + bool hover_; + bool pressed_; + bool responsible_; Int32 z_order_; Float32 opacity_; Float32 displayed_opacity_; @@ -419,6 +421,8 @@ namespace kiwano Transform transform_; bool is_fast_transform_; + mutable bool visible_in_rt_; + mutable bool dirty_visibility_; mutable bool dirty_transform_; mutable bool dirty_transform_inverse_; mutable Matrix3x2 transform_matrix_; diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 78d76fcb..19ab6b0e 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -163,17 +163,17 @@ namespace kiwano Color const& color ); - // 设置线条颜色 + // 设置轮廓颜色 void SetStrokeColor( Color const& color ); - // 设置线条宽度 + // 设置轮廓宽度 void SetStrokeWidth( Float32 width ); - // 设置线条样式 + // 设置轮廓样式 void SetStrokeStyle( StrokeStyle stroke_style ); @@ -222,10 +222,10 @@ namespace kiwano // 获取填充颜色 Color GetFillColor() const; - // 获取线条颜色 + // 获取轮廓颜色 Color GetStrokeColor() const; - // 获取线条宽度 + // 获取轮廓宽度 Float32 GetStrokeWidth() const; // 获取画笔透明度 diff --git a/src/kiwano/2d/Frame.h b/src/kiwano/2d/Frame.h index 1c58955f..494639ef 100644 --- a/src/kiwano/2d/Frame.h +++ b/src/kiwano/2d/Frame.h @@ -19,6 +19,7 @@ // THE SOFTWARE. #pragma once +#include "../base/ObjectBase.h" #include "../renderer/Texture.h" namespace kiwano diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index 7918f955..a3a4e1ef 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -89,7 +89,7 @@ namespace kiwano void GifSprite::OnRender(RenderTarget* rt) { - if (frame_.raw.IsValid() && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) + if (frame_.raw.IsValid() && CheckVisibilty(rt)) { PrepareRender(rt); diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index 5bd96330..b01477c0 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -32,7 +32,7 @@ namespace kiwano { } - ShapeActor::ShapeActor(Geometry geometry) + ShapeActor::ShapeActor(Geometry const& geometry) : ShapeActor() { SetGeometry(geometry); @@ -80,12 +80,12 @@ namespace kiwano stroke_style_ = stroke_style; } - void ShapeActor::SetGeometry(Geometry geometry) + void ShapeActor::SetGeometry(Geometry const& geometry) { geo_ = geometry; if (geo_) { - bounds_ = geo_.GetBoundingBox(Matrix3x2()); + bounds_ = geo_.GetBoundingBox(); SetSize(bounds_.GetSize()); } else @@ -97,21 +97,21 @@ namespace kiwano void ShapeActor::OnRender(RenderTarget* rt) { - if (geo_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) + if (geo_ && CheckVisibilty(rt)) { PrepareRender(rt); - rt->FillGeometry( - geo_, - fill_color_ - ); - rt->DrawGeometry( geo_, stroke_color_, - stroke_width_, + stroke_width_ * 2, // twice width for widening stroke_style_ ); + + rt->FillGeometry( + geo_, + fill_color_ + ); } } @@ -123,23 +123,22 @@ namespace kiwano { } - LineActor::LineActor(Point const& point) + LineActor::LineActor(Point const& begin, Point const& end) { - SetPoint(point); + SetLine(begin, end); } LineActor::~LineActor() { } - void LineActor::SetPoint(Point const& point) + void LineActor::SetLine(Point const& begin, Point const& end) { - Geometry geo = Geometry::CreateLine(Point{}, point); - - if (geo) + if (begin_ != begin || end_ != end) { - point_ = point; - SetGeometry(geo); + begin_ = begin; + end_ = end; + SetGeometry(Geometry::CreateLine(begin, end)); } } @@ -163,12 +162,10 @@ namespace kiwano void RectActor::SetRectSize(Size const& size) { - Geometry geo = Geometry::CreateRect(Rect{ Point{}, size }); - - if (geo) + if (size != rect_size_) { rect_size_ = size; - SetGeometry(geo); + SetGeometry(Geometry::CreateRect(Rect{ Point{}, size })); } } @@ -202,12 +199,11 @@ namespace kiwano void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) { - Geometry geo = Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius); - - if (geo) + if (rect_size_ != size || radius_ != radius) { rect_size_ = size; - SetGeometry(geo); + radius_ = radius; + SetGeometry(Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius)); } } @@ -232,11 +228,10 @@ namespace kiwano void CircleActor::SetRadius(Float32 radius) { - Geometry geo = Geometry::CreateCircle(Point{}, radius); - - if (geo) + if (radius_ != radius) { - SetGeometry(geo); + radius_ = radius; + SetGeometry(Geometry::CreateCircle(Point{ radius, radius }, radius)); } } @@ -260,11 +255,42 @@ namespace kiwano void EllipseActor::SetRadius(Vec2 const& radius) { - Geometry geo = Geometry::CreateEllipse(Point{}, radius); - - if (geo) + if (radius_ != radius) { - SetGeometry(geo); + radius_ = radius; + SetGeometry(Geometry::CreateEllipse(radius, radius)); + } + } + + + //------------------------------------------------------- + // PolygonActor + //------------------------------------------------------- + + PolygonActor::PolygonActor() + { + } + + PolygonActor::PolygonActor(Vector const& points) + { + SetVertices(points); + } + + PolygonActor::~PolygonActor() + { + } + + void PolygonActor::SetVertices(Vector const& points) + { + if (points.size() > 1) + { + SetGeometry( + GeometrySink() + .BeginPath(points[0]) + .AddLines(&points[1], points.size() - 1) + .EndPath(true) + .GetGeometry() + ); } } diff --git a/src/kiwano/2d/ShapeActor.h b/src/kiwano/2d/ShapeActor.h index 0ead7c30..91de4e21 100644 --- a/src/kiwano/2d/ShapeActor.h +++ b/src/kiwano/2d/ShapeActor.h @@ -33,7 +33,7 @@ namespace kiwano ShapeActor(); ShapeActor( - Geometry geometry + Geometry const& geometry ); virtual ~ShapeActor(); @@ -75,7 +75,7 @@ namespace kiwano void SetStrokeStyle(StrokeStyle stroke_style); // 设置形状 - void SetGeometry(Geometry geometry); + void SetGeometry(Geometry const& geometry); void OnRender(RenderTarget* rt) override; @@ -97,19 +97,34 @@ namespace kiwano LineActor(); LineActor( - Point const& point + Point const& begin, + Point const& end ); virtual ~LineActor(); - Point const& GetPoint() const { return point_; } + inline Point const& GetBeginPoint() const { return begin_; } + + inline Point const& GetEndPoint() const { return end_; } - void SetPoint( - Point const& point + inline void SetBeginPoint(Point const& begin) + { + SetLine(begin, end_); + } + + inline void SetEndPoint(Point const& end) + { + SetLine(begin_, end); + } + + void SetLine( + Point const& begin, + Point const& end ); protected: - Point point_; + Point begin_; + Point end_; }; @@ -126,10 +141,10 @@ namespace kiwano virtual ~RectActor(); - void SetRectSize(Size const& size); - inline Size const& GetRectSize() const { return rect_size_; } + void SetRectSize(Size const& size); + protected: Size rect_size_; }; @@ -149,6 +164,10 @@ namespace kiwano virtual ~RoundRectActor(); + inline Vec2 GetRadius() const { return radius_; } + + inline Size GetRectSize() const { return size_; } + void SetRadius( Vec2 const& radius ); @@ -162,10 +181,6 @@ namespace kiwano Vec2 const& radius ); - inline Vec2 GetRadius() const { return radius_; } - - inline Size GetRectSize() const { return size_; } - protected: Size rect_size_; Vec2 radius_; @@ -218,6 +233,25 @@ namespace kiwano }; + // 多边形角色 + class KGE_API PolygonActor + : public ShapeActor + { + public: + PolygonActor(); + + PolygonActor( + Vector const& points + ); + + virtual ~PolygonActor(); + + void SetVertices( + Vector const& points + ); + }; + + // 路径角色 class KGE_API PathActor : public ShapeActor diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index ab331cfe..8e997884 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -104,7 +104,7 @@ namespace kiwano void Sprite::OnRender(RenderTarget* rt) { - if (frame_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) + if (frame_ && CheckVisibilty(rt)) { PrepareRender(rt); diff --git a/src/kiwano/2d/Text.cpp b/src/kiwano/2d/Text.cpp index 875bfdc2..c8933f8b 100644 --- a/src/kiwano/2d/Text.cpp +++ b/src/kiwano/2d/Text.cpp @@ -204,7 +204,7 @@ namespace kiwano { UpdateLayout(); - if (text_layout_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) + if (text_layout_ && CheckVisibilty(rt)) { PrepareRender(rt); rt->DrawTextLayout(text_layout_); diff --git a/src/kiwano/2d/Text.h b/src/kiwano/2d/Text.h index 286e96e8..a9e5d571 100644 --- a/src/kiwano/2d/Text.h +++ b/src/kiwano/2d/Text.h @@ -35,17 +35,17 @@ namespace kiwano String const& text /* 文字内容 */ ); - explicit Text( + Text( String const& text, /* 文字内容 */ const Font& font /* 字体 */ ); - explicit Text( + Text( String const& text, /* 文字内容 */ const TextStyle& style /* 文本样式 */ ); - explicit Text( + Text( String const& text, /* 文字内容 */ const Font& font, /* 字体 */ const TextStyle& style /* 文本样式 */ diff --git a/src/kiwano/2d/TextStyle.hpp b/src/kiwano/2d/TextStyle.hpp index 023ed954..4f54c982 100644 --- a/src/kiwano/2d/TextStyle.hpp +++ b/src/kiwano/2d/TextStyle.hpp @@ -48,29 +48,16 @@ namespace kiwano StrokeStyle outline_stroke; // 描边线相交样式 public: - TextStyle() - : color(Color::White) - , alignment(TextAlign::Left) - , wrap_width(0.f) - , line_spacing(0.f) - , underline(false) - , strikethrough(false) - , outline(true) - , outline_color(Color(Color::Black, 0.5)) - , outline_width(1.f) - , outline_stroke(StrokeStyle::Round) - {} - TextStyle( - Color color, + Color color = Color::White, TextAlign alignment = TextAlign::Left, Float32 wrap_width = 0.f, - Float32 line_spacing = 0.f, + Float32 line_spacing = 0.f, bool underline = false, bool strikethrough = false, - bool outline = true, + bool outline = false, Color outline_color = Color(Color::Black, 0.5), - Float32 outline_width = 1.f, + Float32 outline_width = 1.f, StrokeStyle outline_stroke = StrokeStyle::Round ) : color(color) diff --git a/src/kiwano/2d/action/ActionWalk.h b/src/kiwano/2d/action/ActionWalk.h index 9d05c893..eeaae114 100644 --- a/src/kiwano/2d/action/ActionWalk.h +++ b/src/kiwano/2d/action/ActionWalk.h @@ -90,10 +90,10 @@ namespace kiwano void ClearPath(); // 获取路线 - inline Geometry GetPath() const { return path_; } + inline Geometry const& GetPath() const { return path_; } // 设置路径 - inline void SetPath(Geometry path) { path_ = path; } + inline void SetPath(Geometry const& path) { path_ = path; } protected: void Init(ActorPtr target) override; diff --git a/src/kiwano/2d/include-forwards.h b/src/kiwano/2d/include-forwards.h index bbe73ae7..047488e0 100644 --- a/src/kiwano/2d/include-forwards.h +++ b/src/kiwano/2d/include-forwards.h @@ -45,6 +45,7 @@ namespace kiwano KGE_DECLARE_SMART_PTR(RoundRectActor); KGE_DECLARE_SMART_PTR(CircleActor); KGE_DECLARE_SMART_PTR(EllipseActor); + KGE_DECLARE_SMART_PTR(PolygonActor); KGE_DECLARE_SMART_PTR(PathActor); KGE_DECLARE_SMART_PTR(Action); diff --git a/src/kiwano/core/intrusive_ptr.hpp b/src/kiwano/core/intrusive_ptr.hpp index 582eda5e..ec988f68 100644 --- a/src/kiwano/core/intrusive_ptr.hpp +++ b/src/kiwano/core/intrusive_ptr.hpp @@ -78,9 +78,9 @@ public: inline pointer_type get() const noexcept { return ptr_; } - inline void reset() noexcept + inline void reset(pointer_type ptr = nullptr) noexcept { - intrusive_ptr{}.swap(*this); + intrusive_ptr{ ptr }.swap(*this); } inline void swap(intrusive_ptr& other) noexcept diff --git a/src/kiwano/core/string.hpp b/src/kiwano/core/string.hpp index 5c0ffc51..cded1a22 100644 --- a/src/kiwano/core/string.hpp +++ b/src/kiwano/core/string.hpp @@ -35,7 +35,7 @@ inline namespace core // // basic_string<> -// Lightweight ::std::basic_string<>-like class +// Lightweight std::basic_string<>-like class // When using basic_string<> with a c-style string (char* or wchar_t*), constructor and operator=() just hold // a pointer to the character array but don't copy its content, considering performance issues. // Use assign() and basic_string<>::cstr() to work fine with c-style strings. @@ -48,11 +48,11 @@ public: template struct iterator_impl { - using iterator_category = typename ::std::iterator_traits<_Ty*>::iterator_category; - using value_type = typename ::std::iterator_traits<_Ty*>::value_type; - using difference_type = typename ::std::iterator_traits<_Ty*>::difference_type; - using pointer = typename ::std::iterator_traits<_Ty*>::pointer; - using reference = typename ::std::iterator_traits<_Ty*>::reference; + using iterator_category = typename std::iterator_traits<_Ty*>::iterator_category; + using value_type = typename std::iterator_traits<_Ty*>::value_type; + using difference_type = typename std::iterator_traits<_Ty*>::difference_type; + using pointer = typename std::iterator_traits<_Ty*>::pointer; + using reference = typename std::iterator_traits<_Ty*>::reference; // disable warning 4996 using _Unchecked_type = _Ty; @@ -101,16 +101,16 @@ public: using const_reference = const value_type &; using iterator = iterator_impl; using const_iterator = iterator_impl; - using reverse_iterator = ::std::reverse_iterator; - using const_reverse_iterator = ::std::reverse_iterator; - using traits_type = ::std::char_traits; - using allocator_type = ::std::allocator; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + using traits_type = std::char_traits; + using allocator_type = std::allocator; basic_string(); basic_string(const char_type* cstr, bool const_str = true); basic_string(const char_type* cstr, size_type count); basic_string(size_type count, char_type ch); - basic_string(::std::basic_string const& str); + basic_string(std::basic_string const& str); basic_string(basic_string const& rhs); basic_string(basic_string const& rhs, size_type pos, size_type count = npos); basic_string(basic_string && rhs) noexcept; @@ -140,7 +140,7 @@ public: basic_string& append(basic_string const& other, size_type pos, size_type count = npos); inline basic_string& append(const char_type* cstr) { return append(cstr, traits_type::length(cstr)); } inline basic_string& append(basic_string const& other) { return append(other.const_str_, 0, npos); } - inline basic_string& append(::std::basic_string const& other) { return append(other.c_str()); } + inline basic_string& append(std::basic_string const& other) { return append(other.c_str()); } size_type find(const char_type ch, size_type offset = 0) const; size_type find(const char_type* const str, size_type offset, size_type count) const; @@ -170,7 +170,7 @@ public: basic_string& assign(const char_type* cstr, size_type count); inline basic_string& assign(const char_type* cstr) { basic_string(cstr, false).swap(*this); return *this; } inline basic_string& assign(basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; } - inline basic_string& assign(::std::basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; } + inline basic_string& assign(std::basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; } basic_string& assign(basic_string const& rhs, size_type pos, size_type count = npos); template @@ -191,7 +191,7 @@ public: inline iterator insert(const_iterator pos, char_type ch) { return insert(pos, 1, ch); } inline void push_back(const char_type ch) { append(1, ch); } - inline char_type pop_back() { if (empty()) throw ::std::out_of_range("pop_back() called on empty string"); check_operability(); char_type ch = str_[--size_]; str_[size_] = value_type(); return ch; } + inline char_type pop_back() { if (empty()) throw std::out_of_range("pop_back() called on empty string"); check_operability(); char_type ch = str_[--size_]; str_[size_] = value_type(); return ch; } size_type copy(char_type* cstr, size_type count, size_type pos = 0) const; @@ -227,14 +227,14 @@ public: inline reverse_iterator rend() { check_operability(); return reverse_iterator(begin()); } inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } inline const_reverse_iterator crend() const { return rend(); } - inline reference front() { if (empty()) throw ::std::out_of_range("front() called on empty string"); check_operability(); return str_[0]; } - inline const_reference front() const { if (empty()) throw ::std::out_of_range("front() called on empty string"); return const_str_[0]; } - inline reference back() { if (empty()) throw ::std::out_of_range("back() called on empty string"); check_operability(); return str_[size_ - 1]; } - inline const_reference back() const { if (empty()) throw ::std::out_of_range("back() called on empty string"); return const_str_[size_ - 1]; } + inline reference front() { if (empty()) throw std::out_of_range("front() called on empty string"); check_operability(); return str_[0]; } + inline const_reference front() const { if (empty()) throw std::out_of_range("front() called on empty string"); return const_str_[0]; } + inline reference back() { if (empty()) throw std::out_of_range("back() called on empty string"); check_operability(); return str_[size_ - 1]; } + inline const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty string"); return const_str_[size_ - 1]; } public: - inline char_type operator[](size_type off) const { if (off >= size_) throw ::std::out_of_range("string subscript out of range"); return const_str_[off]; } - inline char_type& operator[](size_type off) { if (off >= size_) throw ::std::out_of_range("string subscript out of range"); check_operability(); return str_[off]; } + inline char_type operator[](size_type off) const { if (off >= size_) throw std::out_of_range("string subscript out of range"); return const_str_[off]; } + inline char_type& operator[](size_type off) { if (off >= size_) throw std::out_of_range("string subscript out of range"); check_operability(); return str_[off]; } public: inline const basic_string operator+(const char_type ch) const { return basic_string{ *this }.append(1, ch); } @@ -247,7 +247,7 @@ public: public: inline basic_string& operator=(const char_type* cstr) { if (const_str_ != cstr) basic_string{ cstr }.swap(*this); return *this; } - inline basic_string& operator=(::std::basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; } + inline basic_string& operator=(std::basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; } inline basic_string& operator=(basic_string const& rhs) { if (this != &rhs) basic_string{ rhs }.swap(*this); return *this; } inline basic_string& operator=(basic_string && rhs) noexcept { if (this != &rhs) basic_string{ rhs }.swap(*this); return *this; } @@ -269,13 +269,13 @@ private: void discard_const_data(); void check_operability(); - void check_offset(size_type offset) const { if (offset > size()) throw ::std::out_of_range("invalid string position"); } - size_type clamp_suffix_size(size_type off, size_type count) const { return ::std::min(size() - off, count); } + void check_offset(size_type offset) const { if (offset > size()) throw std::out_of_range("invalid string position"); } + size_type clamp_suffix_size(size_type off, size_type count) const { return std::min(size() - off, count); } template void assign_iter(_Iter first, _Iter last) { - size_type diff = static_cast(::std::distance(first, last)); + size_type diff = static_cast(std::distance(first, last)); if (diff == 0) return; @@ -375,17 +375,10 @@ inline bool operator>=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> c // template -::std::basic_ostream::char_type>& operator<<(::std::basic_ostream::char_type>& os, const basic_string<_CharTy>& str); +std::basic_ostream::char_type>& operator<<(std::basic_ostream::char_type>& os, const basic_string<_CharTy>& str); template -::std::basic_istream::char_type>& operator>>(::std::basic_istream::char_type>& is, basic_string<_CharTy>& str); - - -// -// string && wstring -// -using string = ::kiwano::core::basic_string; -using wstring = ::kiwano::core::basic_string; +std::basic_istream::char_type>& operator>>(std::basic_istream::char_type>& is, basic_string<_CharTy>& str); // @@ -419,37 +412,45 @@ basic_string<_CharTy> to_basic_string(Float64 val); template basic_string<_CharTy> to_basic_string(long double val); -string to_string(Int32 val); -string to_string(UInt32 val); -string to_string(long val); -string to_string(unsigned long val); -string to_string(long long val); -string to_string(unsigned long long val); -string to_string(Float32 val); -string to_string(Float64 val); -string to_string(long double val); - -wstring to_wstring(Int32 val); -wstring to_wstring(UInt32 val); -wstring to_wstring(long val); -wstring to_wstring(unsigned long val); -wstring to_wstring(long long val); -wstring to_wstring(unsigned long long val); -wstring to_wstring(Float32 val); -wstring to_wstring(Float64 val); -wstring to_wstring(long double val); - // -// format_wstring +// format_string // template -basic_string format_string(const char* const fmt, _Args&&... args); +basic_string format_string(const char* const fmt, _Args&& ... args); template basic_string format_string(const WChar* const fmt, _Args&& ... args); +// +// string && wstring +// +using string = ::kiwano::core::basic_string; +using wstring = ::kiwano::core::basic_string; + + +inline string to_string(Int32 val) { return to_basic_string(val); } +inline string to_string(UInt32 val) { return to_basic_string(val); } +inline string to_string(long val) { return to_basic_string(val); } +inline string to_string(unsigned long val) { return to_basic_string(val); } +inline string to_string(long long val) { return to_basic_string(val); } +inline string to_string(unsigned long long val) { return to_basic_string(val); } +inline string to_string(Float32 val) { return to_basic_string(val); } +inline string to_string(Float64 val) { return to_basic_string(val); } +inline string to_string(long double val) { return to_basic_string(val); } + +inline wstring to_wstring(Int32 val) { return to_basic_string(val); } +inline wstring to_wstring(UInt32 val) { return to_basic_string(val); } +inline wstring to_wstring(long val) { return to_basic_string(val); } +inline wstring to_wstring(unsigned long val) { return to_basic_string(val); } +inline wstring to_wstring(long long val) { return to_basic_string(val); } +inline wstring to_wstring(unsigned long long val) { return to_basic_string(val); } +inline wstring to_wstring(Float32 val) { return to_basic_string(val); } +inline wstring to_wstring(Float64 val) { return to_basic_string(val); } +inline wstring to_wstring(long double val) { return to_basic_string(val); } + + } // inline namespace core } // namespace kiwano @@ -499,7 +500,7 @@ namespace __string_details { if (count != 0 && first_size != 0) { - for (auto iter = first + ::std::min(pos, first_size - 1); ; --iter) + for (auto iter = first + std::min(pos, first_size - 1); ; --iter) { if (typename _Traits::find(second, count, *iter)) { @@ -577,7 +578,7 @@ inline namespace core } template - inline basic_string<_CharTy>::basic_string(::std::basic_string const& str) + inline basic_string<_CharTy>::basic_string(std::basic_string const& str) : basic_string(str.c_str(), false) { } @@ -927,7 +928,7 @@ inline namespace core { size_type count1 = size(); size_type count2 = traits_type::length(str); - size_type rlen = ::std::min(count1, count2); + size_type rlen = std::min(count1, count2); Int32 ret = traits_type::compare(const_str_, str, rlen); if (ret != 0) @@ -966,7 +967,7 @@ inline namespace core if (offset >= size_) return basic_string<_CharTy>::npos; - const_iterator citer = ::std::find_first_of(cbegin().base() + offset, cend().base(), str, str + count); + const_iterator citer = std::find_first_of(cbegin().base() + offset, cend().base(), str, str + count); return (citer != cend()) ? (citer - cbegin()) : basic_string<_CharTy>::npos; } @@ -976,7 +977,7 @@ inline namespace core if (pos == 0 || pos > size_ || pos == npos) return npos; - const_reverse_iterator criter = ::std::find(crbegin(), crend(), ch); + const_reverse_iterator criter = std::find(crbegin(), crend(), ch); return (criter != crend()) ? (criter.base() - cbegin()) : basic_string<_CharTy>::npos; } @@ -1124,12 +1125,12 @@ inline namespace core template inline void basic_string<_CharTy>::swap(basic_string& rhs) noexcept { - ::std::swap(const_str_, rhs.const_str_); - ::std::swap(size_, rhs.size_); - ::std::swap(capacity_, rhs.capacity_); + std::swap(const_str_, rhs.const_str_); + std::swap(size_, rhs.size_); + std::swap(capacity_, rhs.capacity_); // swap const datas - ::std::swap(*const_cast(&operable_), *const_cast(&rhs.operable_)); + std::swap(*const_cast(&operable_), *const_cast(&rhs.operable_)); } template @@ -1193,7 +1194,7 @@ inline namespace core template inline basic_string<_CharTy> basic_string<_CharTy>::format(const char_type* fmt, _Args&& ... args) { - return ::kiwano::format_string(fmt, ::std::forward<_Args>(args)...); + return ::kiwano::format_string(fmt, std::forward<_Args>(args)...); } // @@ -1201,18 +1202,18 @@ inline namespace core // template - inline ::std::basic_ostream::char_type>& operator<<(::std::basic_ostream::char_type>& os, const basic_string<_CharTy>& str) + inline std::basic_ostream::char_type>& operator<<(std::basic_ostream::char_type>& os, const basic_string<_CharTy>& str) { - using ostream = ::std::basic_ostream::char_type, typename basic_string<_CharTy>::traits_type>; + using ostream = std::basic_ostream::char_type, typename basic_string<_CharTy>::traits_type>; using size_type = typename basic_string<_CharTy>::size_type; using traits = typename basic_string<_CharTy>::traits_type; const ostream::sentry ok(os); - ::std::ios_base::iostate state = ::std::ios_base::goodbit; + std::ios_base::iostate state = std::ios_base::goodbit; if (!ok) { - state |= ::std::ios_base::badbit; + state |= std::ios_base::badbit; } else { @@ -1221,22 +1222,22 @@ inline namespace core try { - if ((os.flags() & ::std::ios_base::adjustfield) != ::std::ios_base::left) + if ((os.flags() & std::ios_base::adjustfield) != std::ios_base::left) { for (; 0 < pad; --pad) { if (traits::eq_int_type(traits::eof(), os.rdbuf()->sputc(os.fill()))) { - state |= ::std::ios_base::badbit; + state |= std::ios_base::badbit; break; } } } - if (state == ::std::ios_base::goodbit - && os.rdbuf()->sputn(str.data(), (::std::streamsize)str_size) != (::std::streamsize)str_size) + if (state == std::ios_base::goodbit + && os.rdbuf()->sputn(str.data(), (std::streamsize)str_size) != (std::streamsize)str_size) { - state |= ::std::ios_base::badbit; + state |= std::ios_base::badbit; } else { @@ -1244,7 +1245,7 @@ inline namespace core { if (traits::eq_int_type(traits::eof(), os.rdbuf()->sputc(os.fill()))) { - state |= ::std::ios_base::badbit; + state |= std::ios_base::badbit; break; } } @@ -1253,7 +1254,7 @@ inline namespace core } catch (...) { - os.setstate(::std::ios_base::badbit, true); + os.setstate(std::ios_base::badbit, true); } } @@ -1262,20 +1263,20 @@ inline namespace core } template - inline ::std::basic_istream::char_type>& operator>>(::std::basic_istream::char_type>& is, basic_string<_CharTy>& str) + inline std::basic_istream::char_type>& operator>>(std::basic_istream::char_type>& is, basic_string<_CharTy>& str) { - using ctype = ::std::ctype::char_type>; - using istream = ::std::basic_istream::char_type, typename basic_string<_CharTy>::traits_type>; + using ctype = std::ctype::char_type>; + using istream = std::basic_istream::char_type, typename basic_string<_CharTy>::traits_type>; using size_type = typename basic_string<_CharTy>::size_type; using traits = typename basic_string<_CharTy>::traits_type; bool changed = false; const istream::sentry ok(is); - ::std::ios_base::iostate state = ::std::ios_base::goodbit; + std::ios_base::iostate state = std::ios_base::goodbit; if (ok) { - const ctype& ctype_fac = ::std::use_facet(is.getloc()); + const ctype& ctype_fac = std::use_facet(is.getloc()); str.erase(); try { @@ -1286,7 +1287,7 @@ inline namespace core { if (traits::eq_int_type(traits::eof(), meta)) { - state |= ::std::ios_base::eofbit; + state |= std::ios_base::eofbit; break; } else if (ctype_fac.is(ctype::space, traits::to_char_type(meta))) @@ -1302,13 +1303,13 @@ inline namespace core } catch (...) { - is.setstate(::std::ios_base::badbit, true); + is.setstate(std::ios_base::badbit, true); } } is.width(0); if (!changed) - state |= ::std::ios_base::failbit; + state |= std::ios_base::failbit; is.setstate(state); return is; } @@ -1388,35 +1389,15 @@ inline namespace core return (__to_string_detail::FloatingToString<_CharTy>::convert(val)); } - inline string to_string(Int32 val) { return to_basic_string(val); } - inline string to_string(UInt32 val) { return to_basic_string(val); } - inline string to_string(long val) { return to_basic_string(val); } - inline string to_string(unsigned long val) { return to_basic_string(val); } - inline string to_string(long long val) { return to_basic_string(val); } - inline string to_string(unsigned long long val) { return to_basic_string(val); } - inline string to_string(Float32 val) { return to_basic_string(val); } - inline string to_string(Float64 val) { return to_basic_string(val); } - inline string to_string(long double val) { return to_basic_string(val); } - - inline wstring to_wstring(Int32 val) { return to_basic_string(val); } - inline wstring to_wstring(UInt32 val) { return to_basic_string(val); } - inline wstring to_wstring(long val) { return to_basic_string(val); } - inline wstring to_wstring(unsigned long val) { return to_basic_string(val); } - inline wstring to_wstring(long long val) { return to_basic_string(val); } - inline wstring to_wstring(unsigned long long val) { return to_basic_string(val); } - inline wstring to_wstring(Float32 val) { return to_basic_string(val); } - inline wstring to_wstring(Float64 val) { return to_basic_string(val); } - inline wstring to_wstring(long double val) { return to_basic_string(val); } - template inline basic_string format_string(const char* const fmt, _Args&& ... args) { using string_type = basic_string; - const auto len = static_cast(::_scprintf(fmt, ::std::forward<_Args>(args)...)); + const auto len = static_cast(::_scprintf(fmt, std::forward<_Args>(args)...)); if (len) { string_type str(len, '\0'); - ::sprintf_s(&str[0], len + 1, fmt, ::std::forward<_Args>(args)...); + ::sprintf_s(&str[0], len + 1, fmt, std::forward<_Args>(args)...); return str; } return string_type{}; @@ -1426,11 +1407,11 @@ inline namespace core inline basic_string format_string(const WChar* const fmt, _Args&& ... args) { using string_type = basic_string; - const auto len = static_cast(::_scwprintf(fmt, ::std::forward<_Args>(args)...)); + const auto len = static_cast(::_scwprintf(fmt, std::forward<_Args>(args)...)); if (len) { string_type str(len, L'\0'); - ::swprintf_s(&str[0], len + 1, fmt, ::std::forward<_Args>(args)...); + ::swprintf_s(&str[0], len + 1, fmt, std::forward<_Args>(args)...); return str; } return string_type{}; @@ -1441,7 +1422,7 @@ inline namespace core template _Elem* __IntegerToStringBufferEnd(const _Ty val, _Elem* const buffer_end) { - using _UTy = ::std::make_unsigned_t<_Ty>; + using _UTy = std::make_unsigned_t<_Ty>; _Elem* next = buffer_end; auto uval = static_cast<_UTy>(val); @@ -1467,12 +1448,12 @@ inline namespace core template static basic_string convert(const _Ty val) { - static_assert(::std::is_integral<_Ty>::value, "_Ty must be integral"); + static_assert(std::is_integral<_Ty>::value, "_Ty must be integral"); using _Elem = typename basic_string::traits_type::char_type; _Elem buffer[21]; - _Elem* const buffer_end = ::std::end(buffer); + _Elem* const buffer_end = std::end(buffer); _Elem* buffer_begin = __IntegerToStringBufferEnd(val, buffer_end); return basic_string(buffer_begin, buffer_end); @@ -1485,12 +1466,12 @@ inline namespace core template static basic_string convert(const _Ty val) { - static_assert(::std::is_integral<_Ty>::value, "_Ty must be integral"); + static_assert(std::is_integral<_Ty>::value, "_Ty must be integral"); using _Elem = typename basic_string::traits_type::char_type; _Elem buffer[21]; - _Elem* const buffer_end = ::std::end(buffer); + _Elem* const buffer_end = std::end(buffer); _Elem* buffer_begin = __IntegerToStringBufferEnd(val, buffer_end); return basic_string(buffer_begin, buffer_end); @@ -1564,7 +1545,7 @@ public: , loc_() , conv_num_(0) { - loc_ = ::std::locale(loc_, cvt_); + loc_ = std::locale(loc_, cvt_); } virtual ~string_convert() { } @@ -1580,7 +1561,7 @@ public: wide_string from_bytes(const char* ptr) { - return from_bytes(ptr, ptr + ::std::strlen(ptr)); + return from_bytes(ptr, ptr + std::strlen(ptr)); } wide_string from_bytes(const byte_string& byte_str) @@ -1617,7 +1598,7 @@ public: } else { - throw (::std::range_error("bad conversion")); + throw (std::range_error("bad conversion")); } break; } @@ -1632,7 +1613,7 @@ public: } default: - throw (::std::range_error("bad conversion")); + throw (std::range_error("bad conversion")); } } return wstr; @@ -1685,7 +1666,7 @@ public: } else { - throw (::std::range_error("bad conversion")); + throw (std::range_error("bad conversion")); } break; } @@ -1700,7 +1681,7 @@ public: } default: - throw (::std::range_error("bad conversion")); + throw (std::range_error("bad conversion")); } } return bstr; @@ -1711,13 +1692,13 @@ public: private: const codecvt_type* cvt_; - ::std::locale loc_; + std::locale loc_; state_type state_; UInt32 conv_num_; }; class chs_codecvt - : public ::std::codecvt_byname + : public std::codecvt_byname { public: chs_codecvt() : codecvt_byname("chs") {} diff --git a/src/kiwano/core/vector.hpp b/src/kiwano/core/vector.hpp index 785e3bf4..66011583 100644 --- a/src/kiwano/core/vector.hpp +++ b/src/kiwano/core/vector.hpp @@ -31,7 +31,7 @@ inline namespace core // -// ArrayManager<> with memory operations +// vector_memory_manager<> with memory operations // namespace __vector_details { @@ -64,77 +64,77 @@ public: using initializer_list = std::initializer_list; public: - inline vector() : size_(0), capacity_(0), data_(nullptr) { } - inline vector(size_type count) : vector() { reserve(count); } - inline vector(size_type count, const _Ty& val) : vector() { assign(count, val); } - inline vector(initializer_list list) : vector() { assign(list); } - inline vector(const vector& src) : vector() { assign(src); } - inline vector(vector&& src) noexcept : vector() { swap(src); } - inline ~vector() { destroy(); } + inline vector() : size_(0), capacity_(0), data_(nullptr) { } + inline vector(size_type count) : vector() { reserve(count); } + inline vector(size_type count, const _Ty& val) : vector() { assign(count, val); } + inline vector(initializer_list list) : vector() { assign(list); } + inline vector(const vector& src) : vector() { assign(src); } + inline vector(vector&& src) noexcept : vector() { swap(src); } + inline ~vector() { destroy(); } template - inline vector(_Iter first, _Iter last) : vector() { assign(first, last); } + inline vector(_Iter first, _Iter last) : vector() { assign(first, last); } - inline vector& operator=(const vector& src) { if (&src != this) { resize(src.size_); manager::copy_data(begin(), src.cbegin(), size_); } return (*this); } - inline vector& operator=(vector&& src) noexcept { swap(src); return *this; } - inline vector& operator=(initializer_list list) { if (list.size()) { assign(list.begin(), list.end()); } else clear(); return (*this); } + inline vector& operator=(const vector& src) { if (&src != this) { resize(src.size_); manager::copy_data(begin(), src.cbegin(), size_); } return (*this); } + inline vector& operator=(vector&& src) noexcept { swap(src); return *this; } + inline vector& operator=(initializer_list list) { if (list.size()) { assign(list.begin(), list.end()); } else clear(); return (*this); } - inline vector& assign(size_type count, const _Ty& val) { if (count > 0) { resize(count); manager::copy_data(begin(), count, val); } else clear(); return (*this); } - inline vector& assign(const vector& src) { return operator=(src); } - inline vector& assign(initializer_list list) { return operator=(list); } + inline vector& assign(size_type count, const _Ty& val) { if (count > 0) { resize(count); manager::copy_data(begin(), count, val); } else clear(); return (*this); } + inline vector& assign(const vector& src) { return operator=(src); } + inline vector& assign(initializer_list list) { return operator=(list); } template - inline void assign(_Iter first, _Iter last) { auto diff = std::distance(first, last); resize((size_type)diff); auto data = begin(); while (first != last) (*data++) = (*first++); } + inline void assign(_Iter first, _Iter last) { auto diff = std::distance(first, last); resize((size_type)diff); auto data = begin(); while (first != last) (*data++) = (*first++); } - inline void clear() { destroy(); size_ = capacity_ = 0; data_ = nullptr; } - inline void swap(vector& rhs) noexcept { std::swap(size_, rhs.size_); std::swap(capacity_, rhs.capacity_); std::swap(data_, rhs.data_); } + inline void clear() { destroy(); size_ = capacity_ = 0; data_ = nullptr; } + inline void swap(vector& rhs) noexcept { std::swap(size_, rhs.size_); std::swap(capacity_, rhs.capacity_); std::swap(data_, rhs.data_); } - inline void resize(size_type new_size) { resize(new_size, _Ty()); } + inline void resize(size_type new_size) { resize(new_size, _Ty()); } void resize(size_type new_size, const _Ty& v); void reserve(size_type new_capacity); - inline void push_back(const _Ty& val) { resize(size_ + 1, val); } - inline void pop_back() { if (empty()) throw std::out_of_range("pop() called on empty vector"); resize(size_ - 1); } - inline void push_front(const _Ty& val) { if (size_ == 0) push_back(val); else insert(begin(), val); } + inline void push_back(const _Ty& val) { resize(size_ + 1, val); } + inline void pop_back() { if (empty()) throw std::out_of_range("pop() called on empty vector"); resize(size_ - 1); } + inline void push_front(const _Ty& val) { if (size_ == 0) push_back(val); else insert(begin(), val); } - inline iterator erase(const_iterator where) { return erase(where, where + 1); } + inline iterator erase(const_iterator where) { return erase(where, where + 1); } iterator erase(const_iterator first, const_iterator last); iterator insert(const_iterator where, const _Ty& v); - inline bool empty() const { return size_ == 0; } - inline size_type size() const { return size_; } - inline size_type size_in_bytes() const { return size_ * ((size_type)sizeof(_Ty)); } - inline size_type capacity() const { return capacity_; } - inline reference operator[](size_type off) { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; } - inline const_reference operator[](size_type off) const { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; } + inline bool empty() const { return size_ == 0; } + inline size_type size() const { return size_; } + inline size_type size_in_bytes() const { return size_ * ((size_type)sizeof(_Ty)); } + inline size_type capacity() const { return capacity_; } + inline reference operator[](size_type off) { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; } + inline const_reference operator[](size_type off) const { if (off < 0 || off >= size_) throw std::out_of_range("vector subscript out of range"); return data_[off]; } - inline bool contains(const _Ty& v) const { auto data = cbegin(); const auto data_end = cend(); while (data != data_end) if (*(data++) == v) return true; return false; } - inline size_type index_of(const_iterator it) const { check_offset(it - cbegin(), "invalid array position"); return it - data_; } + inline bool contains(const _Ty& v) const { auto data = cbegin(); const auto data_end = cend(); while (data != data_end) if (*(data++) == v) return true; return false; } + inline size_type index_of(const_iterator it) const { check_offset(it - cbegin(), "invalid array position"); return it - data_; } - inline iterator begin() { return iterator(data_); } - inline const_iterator begin() const { return const_iterator(data_); } - inline const_iterator cbegin() const { return begin(); } - inline iterator end() { return iterator(data_ + size_); } - inline const_iterator end() const { return const_iterator(data_ + size_); } - inline const_iterator cend() const { return end(); } - inline reverse_iterator rbegin() { return reverse_iterator(end()); } - inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } - inline const_reverse_iterator crbegin() const { return rbegin(); } - inline reverse_iterator rend() { return reverse_iterator(begin()); } - inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } - inline const_reverse_iterator crend() const { return rend(); } - inline reference front() { if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; } - inline const_reference front() const { if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; } - inline reference back() { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; } - inline const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; } + inline iterator begin() { return iterator(data_); } + inline const_iterator begin() const { return const_iterator(data_); } + inline const_iterator cbegin() const { return begin(); } + inline iterator end() { return iterator(data_ + size_); } + inline const_iterator end() const { return const_iterator(data_ + size_); } + inline const_iterator cend() const { return end(); } + inline reverse_iterator rbegin() { return reverse_iterator(end()); } + inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } + inline const_reverse_iterator crbegin() const { return rbegin(); } + inline reverse_iterator rend() { return reverse_iterator(begin()); } + inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } + inline const_reverse_iterator crend() const { return rend(); } + inline reference front() { if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; } + inline const_reference front() const { if (empty()) throw std::out_of_range("front() called on empty array"); return data_[0]; } + inline reference back() { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; } + inline const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; } private: - inline size_type grow_capacity(size_type sz) const { size_type new_capacity = capacity_ ? (capacity_ + capacity_ / 2) : 8; return new_capacity > sz ? new_capacity : sz; } - inline void check_offset(const size_type off) const { if (off < 0 || off >= size_) throw std::out_of_range("invalid vector position"); } + inline size_type grow_capacity(size_type sz) const { size_type new_capacity = capacity_ ? (capacity_ + capacity_ / 2) : 8; return new_capacity > sz ? new_capacity : sz; } + inline void check_offset(const size_type off) const { if (off < 0 || off >= size_) throw std::out_of_range("invalid vector position"); } - inline void destroy() { manager::destroy(data_, size_); manager::deallocate(data_, capacity_); } + inline void destroy() { manager::destroy(data_, size_); manager::deallocate(data_, capacity_); } protected: size_type size_; size_type capacity_; diff --git a/src/kiwano/math/Matrix.hpp b/src/kiwano/math/Matrix.hpp index 084e7561..f859c91c 100644 --- a/src/kiwano/math/Matrix.hpp +++ b/src/kiwano/math/Matrix.hpp @@ -78,6 +78,9 @@ namespace kiwano { } +#pragma warning (push) +#pragma warning (disable: 26495) // ignore warning "always initialize member variables" + template Matrix3x2T(_MTy const& other) { @@ -85,6 +88,8 @@ namespace kiwano m[i] = other[i]; } +#pragma warning (pop) + inline value_type operator [](UInt32 index) const { return m[index]; diff --git a/src/kiwano/renderer/Color.h b/src/kiwano/renderer/Color.h index 6761b9e6..d5cce8b9 100644 --- a/src/kiwano/renderer/Color.h +++ b/src/kiwano/renderer/Color.h @@ -58,6 +58,16 @@ namespace kiwano Float32 alpha ); + inline bool operator== (const Color& rhs) const + { + return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a; + } + + inline bool operator!= (const Color& rhs) const + { + return !((*this) == rhs); + } + public: enum Value : UInt32 { diff --git a/src/kiwano/renderer/Geometry.cpp b/src/kiwano/renderer/Geometry.cpp index 5858ba1d..9cac826e 100644 --- a/src/kiwano/renderer/Geometry.cpp +++ b/src/kiwano/renderer/Geometry.cpp @@ -43,15 +43,26 @@ namespace kiwano return geo_ != nullptr; } + Rect Geometry::GetBoundingBox() const + { + Rect bounds; + if (geo_) + { + // no matter it failed or not + geo_->GetBounds(nullptr, DX::ConvertToRectF(&bounds)); + } + return bounds; + } + Rect Geometry::GetBoundingBox(Matrix3x2 const& transform) const { - if (!geo_) - return Rect{}; - - Rect rect; - // no matter it failed or not - geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&rect)); - return rect; + Rect bounds; + if (geo_) + { + // no matter it failed or not + geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&bounds)); + } + return bounds; } Float32 Geometry::GetLength() const @@ -246,6 +257,14 @@ namespace kiwano return (*this); } + GeometrySink& kiwano::GeometrySink::AddLines(const Point* points, UInt32 count) + { + if (!sink_) BeginPath(); + + sink_->AddLines(reinterpret_cast(points), count); + return (*this); + } + GeometrySink& GeometrySink::AddBezier(Point const& point1, Point const& point2, Point const& point3) { if (!sink_) BeginPath(); diff --git a/src/kiwano/renderer/Geometry.h b/src/kiwano/renderer/Geometry.h index 86b2f290..da202ff4 100644 --- a/src/kiwano/renderer/Geometry.h +++ b/src/kiwano/renderer/Geometry.h @@ -44,9 +44,12 @@ namespace kiwano bool IsValid() const; + // 获取外切包围盒 + Rect GetBoundingBox() const; + // 获取外切包围盒 Rect GetBoundingBox( - Matrix3x2 const& transform = Matrix3x2() + Matrix3x2 const& transform ) const; // 判断图形是否包含点 @@ -151,6 +154,12 @@ namespace kiwano Vector const& points ); + // 添加多条线段 + GeometrySink& AddLines( + const Point* points, + UInt32 count + ); + // 添加一条三次方贝塞尔曲线 GeometrySink& AddBezier( Point const& point1, /* 贝塞尔曲线的第一个控制点 */ @@ -162,7 +171,7 @@ namespace kiwano GeometrySink& AddArc( Point const& point, /* 终点 */ Size const& radius, /* 椭圆半径 */ - Float32 rotation, /* 椭圆旋转角度 */ + Float32 rotation, /* 椭圆旋转角度 */ bool clockwise = true, /* 顺时针 or 逆时针 */ bool is_small = true /* 是否取小于 180° 的弧 */ ); diff --git a/src/kiwano/renderer/GifImage.h b/src/kiwano/renderer/GifImage.h index 339c63f1..13a77494 100644 --- a/src/kiwano/renderer/GifImage.h +++ b/src/kiwano/renderer/GifImage.h @@ -20,6 +20,7 @@ #pragma once #include "Texture.h" +#include "../base/time.h" namespace kiwano { diff --git a/src/kiwano/renderer/RenderTarget.cpp b/src/kiwano/renderer/RenderTarget.cpp index 6bfe1eed..c6441c03 100644 --- a/src/kiwano/renderer/RenderTarget.cpp +++ b/src/kiwano/renderer/RenderTarget.cpp @@ -391,12 +391,12 @@ namespace kiwano layout.GetTextStyle().outline_width, GetStrokeStyle(layout.GetTextStyle().outline_stroke).get() ); + + hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y); } if (SUCCEEDED(hr)) { - hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y); - IncreasePrimitivesCount(); } diff --git a/src/kiwano/renderer/RenderTarget.h b/src/kiwano/renderer/RenderTarget.h index 019ea940..bc95876a 100644 --- a/src/kiwano/renderer/RenderTarget.h +++ b/src/kiwano/renderer/RenderTarget.h @@ -190,6 +190,8 @@ namespace kiwano Int32 primitives; Time start; Duration duration; + + Status() : primitives(0) {} }; void SetCollectingStatus(bool collecting); diff --git a/src/kiwano/renderer/win32/D2DDeviceResources.cpp b/src/kiwano/renderer/win32/D2DDeviceResources.cpp index 8a90e67e..7a85934e 100644 --- a/src/kiwano/renderer/win32/D2DDeviceResources.cpp +++ b/src/kiwano/renderer/win32/D2DDeviceResources.cpp @@ -190,16 +190,16 @@ namespace kiwano imaging_factory_.reset(); dwrite_factory_.reset(); - d2d_miter_stroke_style_.reset(); - d2d_bevel_stroke_style_.reset(); - d2d_round_stroke_style_.reset(); + miter_stroke_style_.reset(); + bevel_stroke_style_.reset(); + round_stroke_style_.reset(); } HRESULT D2DDeviceResources::CreateDeviceIndependentResources() { HRESULT hr = S_OK; - ComPtr d2d_factory; + ComPtr factory; ComPtr imaging_factory; ComPtr dwrite_factory; @@ -213,12 +213,12 @@ namespace kiwano D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), &config, - reinterpret_cast(&d2d_factory) + reinterpret_cast(&factory) ); if (SUCCEEDED(hr)) { - factory_ = d2d_factory; + factory_ = factory; hr = CoCreateInstance( CLSID_WICImagingFactory, @@ -244,9 +244,9 @@ namespace kiwano { dwrite_factory_ = dwrite_factory; - ComPtr d2d_miter_stroke_style; - ComPtr d2d_bevel_stroke_style; - ComPtr d2d_round_stroke_style; + ComPtr miter_stroke_style; + ComPtr bevel_stroke_style; + ComPtr round_stroke_style; D2D1_STROKE_STYLE_PROPERTIES stroke_style = D2D1::StrokeStyleProperties( D2D1_CAP_STYLE_FLAT, @@ -262,7 +262,7 @@ namespace kiwano stroke_style, nullptr, 0, - &d2d_miter_stroke_style + &miter_stroke_style ); if (SUCCEEDED(hr)) @@ -272,7 +272,7 @@ namespace kiwano stroke_style, nullptr, 0, - &d2d_bevel_stroke_style + &bevel_stroke_style ); } @@ -283,15 +283,15 @@ namespace kiwano stroke_style, nullptr, 0, - &d2d_round_stroke_style + &round_stroke_style ); } if (SUCCEEDED(hr)) { - d2d_miter_stroke_style_ = d2d_miter_stroke_style; - d2d_bevel_stroke_style_ = d2d_bevel_stroke_style; - d2d_round_stroke_style_ = d2d_round_stroke_style; + miter_stroke_style_ = miter_stroke_style; + bevel_stroke_style_ = bevel_stroke_style; + round_stroke_style_ = round_stroke_style; } } @@ -300,17 +300,17 @@ namespace kiwano HRESULT D2DDeviceResources::SetD2DDevice(_In_ ComPtr const& device) { - ComPtr d2d_device_ctx; + ComPtr device_ctx; HRESULT hr = device->CreateDeviceContext( D2D1_DEVICE_CONTEXT_OPTIONS_NONE, - &d2d_device_ctx + &device_ctx ); if (SUCCEEDED(hr)) { device_ = device; - device_context_ = d2d_device_ctx; + device_context_ = device_ctx; device_context_->SetDpi(dpi_, dpi_); } diff --git a/src/kiwano/renderer/win32/D2DDeviceResources.h b/src/kiwano/renderer/win32/D2DDeviceResources.h index 5c117a29..a6ece50e 100644 --- a/src/kiwano/renderer/win32/D2DDeviceResources.h +++ b/src/kiwano/renderer/win32/D2DDeviceResources.h @@ -23,7 +23,6 @@ #include "../Color.h" #include "../../math/math.h" #include "../../base/Resource.h" -#include "../../2d/TextStyle.hpp" #include #include #include @@ -243,9 +242,9 @@ namespace kiwano inline ID2D1DeviceContext* GetDeviceContext() const { KGE_ASSERT(device_context_); return device_context_.get(); } inline ID2D1Bitmap1* GetTargetBitmap() const { KGE_ASSERT(target_bitmap_); return target_bitmap_.get(); } - inline ID2D1StrokeStyle* GetMiterStrokeStyle() const { KGE_ASSERT(d2d_miter_stroke_style_); return d2d_miter_stroke_style_.get(); } - inline ID2D1StrokeStyle* GetBevelStrokeStyle() const { KGE_ASSERT(d2d_bevel_stroke_style_); return d2d_bevel_stroke_style_.get(); } - inline ID2D1StrokeStyle* GetRoundStrokeStyle() const { KGE_ASSERT(d2d_round_stroke_style_); return d2d_round_stroke_style_.get(); } + inline ID2D1StrokeStyle* GetMiterStrokeStyle() const { KGE_ASSERT(miter_stroke_style_); return miter_stroke_style_.get(); } + inline ID2D1StrokeStyle* GetBevelStrokeStyle() const { KGE_ASSERT(bevel_stroke_style_); return bevel_stroke_style_.get(); } + inline ID2D1StrokeStyle* GetRoundStrokeStyle() const { KGE_ASSERT(round_stroke_style_); return round_stroke_style_.get(); } protected: ComPtr factory_; @@ -256,9 +255,9 @@ namespace kiwano ComPtr imaging_factory_; ComPtr dwrite_factory_; - ComPtr d2d_miter_stroke_style_; - ComPtr d2d_bevel_stroke_style_; - ComPtr d2d_round_stroke_style_; + ComPtr miter_stroke_style_; + ComPtr bevel_stroke_style_; + ComPtr round_stroke_style_; }; } diff --git a/src/kiwano/renderer/win32/TextRenderer.cpp b/src/kiwano/renderer/win32/TextRenderer.cpp index 136138d5..7b0c7502 100644 --- a/src/kiwano/renderer/win32/TextRenderer.cpp +++ b/src/kiwano/renderer/win32/TextRenderer.cpp @@ -198,7 +198,7 @@ namespace kiwano sFillColor_ = fillColor; bShowOutline_ = outline; sOutlineColor_ = outlineColor; - fOutlineWidth = 2 * outlineWidth; + fOutlineWidth = outlineWidth; pCurrStrokeStyle_ = outlineJoin; if (pBrush_) pBrush_->SetOpacity(opacity); @@ -220,80 +220,87 @@ namespace kiwano HRESULT hr = S_OK; - ID2D1PathGeometry* pPathGeometry = NULL; - hr = pFactory_->CreatePathGeometry( - &pPathGeometry - ); - - ID2D1GeometrySink* pSink = NULL; - if (SUCCEEDED(hr)) + if (bShowOutline_) { - hr = pPathGeometry->Open( - &pSink + ID2D1GeometrySink* pSink = NULL; + ID2D1PathGeometry* pPathGeometry = NULL; + ID2D1TransformedGeometry* pTransformedGeometry = NULL; + + hr = pFactory_->CreatePathGeometry( + &pPathGeometry ); - } - if (SUCCEEDED(hr)) - { - hr = glyphRun->fontFace->GetGlyphRunOutline( - glyphRun->fontEmSize, - glyphRun->glyphIndices, - glyphRun->glyphAdvances, - glyphRun->glyphOffsets, - glyphRun->glyphCount, - glyphRun->isSideways, - glyphRun->bidiLevel % 2, - pSink - ); - } + if (SUCCEEDED(hr)) + { + hr = pPathGeometry->Open( + &pSink + ); - if (SUCCEEDED(hr)) - { - hr = pSink->Close(); - } + if (SUCCEEDED(hr)) + { + hr = glyphRun->fontFace->GetGlyphRunOutline( + glyphRun->fontEmSize, + glyphRun->glyphIndices, + glyphRun->glyphAdvances, + glyphRun->glyphOffsets, + glyphRun->glyphCount, + glyphRun->isSideways, + glyphRun->bidiLevel % 2, + pSink + ); + } - D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F( - 1.0f, 0.0f, - 0.0f, 1.0f, - baselineOriginX, baselineOriginY - ); + if (SUCCEEDED(hr)) + { + hr = pSink->Close(); + } - ID2D1TransformedGeometry* pTransformedGeometry = NULL; - if (SUCCEEDED(hr)) - { - hr = pFactory_->CreateTransformedGeometry( - pPathGeometry, - &matrix, - &pTransformedGeometry - ); - } + if (SUCCEEDED(hr)) + { + D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F( + 1.0f, 0.0f, + 0.0f, 1.0f, + baselineOriginX, baselineOriginY + ); - if (SUCCEEDED(hr) && bShowOutline_) - { - pBrush_->SetColor(sOutlineColor_); + if (SUCCEEDED(hr)) + { + hr = pFactory_->CreateTransformedGeometry( + pPathGeometry, + &matrix, + &pTransformedGeometry + ); + } - pRT_->DrawGeometry( - pTransformedGeometry, - pBrush_, - fOutlineWidth, - pCurrStrokeStyle_ - ); + if (SUCCEEDED(hr)) + { + pBrush_->SetColor(sOutlineColor_); + + pRT_->DrawGeometry( + pTransformedGeometry, + pBrush_, + fOutlineWidth * 2, // twice width for widening + pCurrStrokeStyle_ + ); + } + } + } + + DX::SafeRelease(pPathGeometry); + DX::SafeRelease(pSink); + DX::SafeRelease(pTransformedGeometry); } if (SUCCEEDED(hr)) { pBrush_->SetColor(sFillColor_); - pRT_->FillGeometry( - pTransformedGeometry, + pRT_->DrawGlyphRun( + D2D1::Point2F(baselineOriginX, baselineOriginY), + glyphRun, pBrush_ ); } - - DX::SafeRelease(pPathGeometry); - DX::SafeRelease(pSink); - DX::SafeRelease(pTransformedGeometry); - return hr; } @@ -345,7 +352,7 @@ namespace kiwano pRT_->DrawGeometry( pTransformedGeometry, pBrush_, - fOutlineWidth, + fOutlineWidth * 2, pCurrStrokeStyle_ ); } @@ -414,7 +421,7 @@ namespace kiwano pRT_->DrawGeometry( pTransformedGeometry, pBrush_, - fOutlineWidth, + fOutlineWidth * 2, pCurrStrokeStyle_ ); }