[deploy] Merge pull request #38 from KiwanoEngine/dev

Add PolygonActor
This commit is contained in:
Haibo 2019-09-03 15:10:10 +08:00 committed by GitHub
commit 7fcddb6c5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 448 additions and 349 deletions

View File

@ -39,10 +39,12 @@ namespace kiwano
Actor::Actor() Actor::Actor()
: visible_(true) : visible_(true)
, visible_in_rt_(true)
, update_pausing_(false) , update_pausing_(false)
, hover_(false) , hover_(false)
, pressed_(false) , pressed_(false)
, responsible_(false) , responsible_(false)
, dirty_visibility_(true)
, dirty_transform_(false) , dirty_transform_(false)
, dirty_transform_inverse_(false) , dirty_transform_inverse_(false)
, cascade_opacity_(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) void Actor::Dispatch(Event& evt)
{ {
if (!visible_) if (!visible_)
@ -224,6 +236,7 @@ namespace kiwano
dirty_transform_ = false; dirty_transform_ = false;
dirty_transform_inverse_ = true; dirty_transform_inverse_ = true;
dirty_visibility_ = true;
if (is_fast_transform_) if (is_fast_transform_)
{ {

View File

@ -390,6 +390,8 @@ namespace kiwano
virtual void RenderBorder(RenderTarget* rt); virtual void RenderBorder(RenderTarget* rt);
virtual bool CheckVisibilty(RenderTarget* rt) const;
void UpdateTransform() const; void UpdateTransform() const;
void UpdateOpacity(); void UpdateOpacity();
@ -400,12 +402,12 @@ namespace kiwano
protected: protected:
bool visible_; bool visible_;
bool hover_;
bool pressed_;
bool responsible_;
bool update_pausing_; bool update_pausing_;
bool cascade_opacity_; bool cascade_opacity_;
bool show_border_; bool show_border_;
bool hover_;
bool pressed_;
bool responsible_;
Int32 z_order_; Int32 z_order_;
Float32 opacity_; Float32 opacity_;
Float32 displayed_opacity_; Float32 displayed_opacity_;
@ -419,6 +421,8 @@ namespace kiwano
Transform transform_; Transform transform_;
bool is_fast_transform_; bool is_fast_transform_;
mutable bool visible_in_rt_;
mutable bool dirty_visibility_;
mutable bool dirty_transform_; mutable bool dirty_transform_;
mutable bool dirty_transform_inverse_; mutable bool dirty_transform_inverse_;
mutable Matrix3x2 transform_matrix_; mutable Matrix3x2 transform_matrix_;

View File

@ -163,17 +163,17 @@ namespace kiwano
Color const& color Color const& color
); );
// ノ靹テマ゚フ<EFBFBD>ユノォ // ノ靹テツヨタェムユノォ
void SetStrokeColor( void SetStrokeColor(
Color const& color Color const& color
); );
// ノ靹テマ゚フ<EFBFBD>昮ネ // ノ靹テツヨタェソ昮ネ
void SetStrokeWidth( void SetStrokeWidth(
Float32 width Float32 width
); );
// ノ靹テマ゚フ<EFBFBD><EFBFBD> // ノ靹テツヨタェム<EFBFBD>
void SetStrokeStyle( void SetStrokeStyle(
StrokeStyle stroke_style StrokeStyle stroke_style
); );
@ -222,10 +222,10 @@ namespace kiwano
// ťńČĄĚîłäŃŐÉŤ // ťńČĄĚîłäŃŐÉŤ
Color GetFillColor() const; Color GetFillColor() const;
// サ<>マ゚フ<EFBFBD>ユノォ // サ<>ツヨタェムユノォ
Color GetStrokeColor() const; Color GetStrokeColor() const;
// サ<>マ゚フ<EFBFBD>昮ネ // サ<>ツヨタェソ昮ネ
Float32 GetStrokeWidth() const; Float32 GetStrokeWidth() const;
// ťńČĄť­ąĘ͸Ă÷śČ // ťńČĄť­ąĘ͸Ă÷śČ

View File

@ -19,6 +19,7 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include "../base/ObjectBase.h"
#include "../renderer/Texture.h" #include "../renderer/Texture.h"
namespace kiwano namespace kiwano

View File

@ -89,7 +89,7 @@ namespace kiwano
void GifSprite::OnRender(RenderTarget* rt) void GifSprite::OnRender(RenderTarget* rt)
{ {
if (frame_.raw.IsValid() && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) if (frame_.raw.IsValid() && CheckVisibilty(rt))
{ {
PrepareRender(rt); PrepareRender(rt);

View File

@ -32,7 +32,7 @@ namespace kiwano
{ {
} }
ShapeActor::ShapeActor(Geometry geometry) ShapeActor::ShapeActor(Geometry const& geometry)
: ShapeActor() : ShapeActor()
{ {
SetGeometry(geometry); SetGeometry(geometry);
@ -80,12 +80,12 @@ namespace kiwano
stroke_style_ = stroke_style; stroke_style_ = stroke_style;
} }
void ShapeActor::SetGeometry(Geometry geometry) void ShapeActor::SetGeometry(Geometry const& geometry)
{ {
geo_ = geometry; geo_ = geometry;
if (geo_) if (geo_)
{ {
bounds_ = geo_.GetBoundingBox(Matrix3x2()); bounds_ = geo_.GetBoundingBox();
SetSize(bounds_.GetSize()); SetSize(bounds_.GetSize());
} }
else else
@ -97,21 +97,21 @@ namespace kiwano
void ShapeActor::OnRender(RenderTarget* rt) void ShapeActor::OnRender(RenderTarget* rt)
{ {
if (geo_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) if (geo_ && CheckVisibilty(rt))
{ {
PrepareRender(rt); PrepareRender(rt);
rt->FillGeometry(
geo_,
fill_color_
);
rt->DrawGeometry( rt->DrawGeometry(
geo_, geo_,
stroke_color_, stroke_color_,
stroke_width_, stroke_width_ * 2, // twice width for widening
stroke_style_ 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() LineActor::~LineActor()
{ {
} }
void LineActor::SetPoint(Point const& point) void LineActor::SetLine(Point const& begin, Point const& end)
{ {
Geometry geo = Geometry::CreateLine(Point{}, point); if (begin_ != begin || end_ != end)
if (geo)
{ {
point_ = point; begin_ = begin;
SetGeometry(geo); end_ = end;
SetGeometry(Geometry::CreateLine(begin, end));
} }
} }
@ -163,12 +162,10 @@ namespace kiwano
void RectActor::SetRectSize(Size const& size) void RectActor::SetRectSize(Size const& size)
{ {
Geometry geo = Geometry::CreateRect(Rect{ Point{}, size }); if (size != rect_size_)
if (geo)
{ {
rect_size_ = 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) void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius)
{ {
Geometry geo = Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius); if (rect_size_ != size || radius_ != radius)
if (geo)
{ {
rect_size_ = size; 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) void CircleActor::SetRadius(Float32 radius)
{ {
Geometry geo = Geometry::CreateCircle(Point{}, radius); if (radius_ != radius)
if (geo)
{ {
SetGeometry(geo); radius_ = radius;
SetGeometry(Geometry::CreateCircle(Point{ radius, radius }, radius));
} }
} }
@ -260,11 +255,42 @@ namespace kiwano
void EllipseActor::SetRadius(Vec2 const& radius) void EllipseActor::SetRadius(Vec2 const& radius)
{ {
Geometry geo = Geometry::CreateEllipse(Point{}, radius); if (radius_ != radius)
if (geo)
{ {
SetGeometry(geo); radius_ = radius;
SetGeometry(Geometry::CreateEllipse(radius, radius));
}
}
//-------------------------------------------------------
// PolygonActor
//-------------------------------------------------------
PolygonActor::PolygonActor()
{
}
PolygonActor::PolygonActor(Vector<Point> const& points)
{
SetVertices(points);
}
PolygonActor::~PolygonActor()
{
}
void PolygonActor::SetVertices(Vector<Point> const& points)
{
if (points.size() > 1)
{
SetGeometry(
GeometrySink()
.BeginPath(points[0])
.AddLines(&points[1], points.size() - 1)
.EndPath(true)
.GetGeometry()
);
} }
} }

View File

@ -33,7 +33,7 @@ namespace kiwano
ShapeActor(); ShapeActor();
ShapeActor( ShapeActor(
Geometry geometry Geometry const& geometry
); );
virtual ~ShapeActor(); virtual ~ShapeActor();
@ -75,7 +75,7 @@ namespace kiwano
void SetStrokeStyle(StrokeStyle stroke_style); void SetStrokeStyle(StrokeStyle stroke_style);
// ÉèÖÃÐÎ×´ // ÉèÖÃÐÎ×´
void SetGeometry(Geometry geometry); void SetGeometry(Geometry const& geometry);
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
@ -97,19 +97,34 @@ namespace kiwano
LineActor(); LineActor();
LineActor( LineActor(
Point const& point Point const& begin,
Point const& end
); );
virtual ~LineActor(); virtual ~LineActor();
Point const& GetPoint() const { return point_; } inline Point const& GetBeginPoint() const { return begin_; }
inline Point const& GetEndPoint() const { return end_; }
void SetPoint( inline void SetBeginPoint(Point const& begin)
Point const& point {
SetLine(begin, end_);
}
inline void SetEndPoint(Point const& end)
{
SetLine(begin_, end);
}
void SetLine(
Point const& begin,
Point const& end
); );
protected: protected:
Point point_; Point begin_;
Point end_;
}; };
@ -126,10 +141,10 @@ namespace kiwano
virtual ~RectActor(); virtual ~RectActor();
void SetRectSize(Size const& size);
inline Size const& GetRectSize() const { return rect_size_; } inline Size const& GetRectSize() const { return rect_size_; }
void SetRectSize(Size const& size);
protected: protected:
Size rect_size_; Size rect_size_;
}; };
@ -149,6 +164,10 @@ namespace kiwano
virtual ~RoundRectActor(); virtual ~RoundRectActor();
inline Vec2 GetRadius() const { return radius_; }
inline Size GetRectSize() const { return size_; }
void SetRadius( void SetRadius(
Vec2 const& radius Vec2 const& radius
); );
@ -162,10 +181,6 @@ namespace kiwano
Vec2 const& radius Vec2 const& radius
); );
inline Vec2 GetRadius() const { return radius_; }
inline Size GetRectSize() const { return size_; }
protected: protected:
Size rect_size_; Size rect_size_;
Vec2 radius_; Vec2 radius_;
@ -218,6 +233,25 @@ namespace kiwano
}; };
// ¶à±ßÐνÇÉ«
class KGE_API PolygonActor
: public ShapeActor
{
public:
PolygonActor();
PolygonActor(
Vector<Point> const& points
);
virtual ~PolygonActor();
void SetVertices(
Vector<Point> const& points
);
};
// ·¾¶½ÇÉ« // ·¾¶½ÇÉ«
class KGE_API PathActor class KGE_API PathActor
: public ShapeActor : public ShapeActor

View File

@ -104,7 +104,7 @@ namespace kiwano
void Sprite::OnRender(RenderTarget* rt) void Sprite::OnRender(RenderTarget* rt)
{ {
if (frame_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) if (frame_ && CheckVisibilty(rt))
{ {
PrepareRender(rt); PrepareRender(rt);

View File

@ -204,7 +204,7 @@ namespace kiwano
{ {
UpdateLayout(); UpdateLayout();
if (text_layout_ && rt->CheckVisibility(GetBounds(), GetTransformMatrix())) if (text_layout_ && CheckVisibilty(rt))
{ {
PrepareRender(rt); PrepareRender(rt);
rt->DrawTextLayout(text_layout_); rt->DrawTextLayout(text_layout_);

View File

@ -35,17 +35,17 @@ namespace kiwano
String const& text /* 文字内容 */ String const& text /* 文字内容 */
); );
explicit Text( Text(
String const& text, /* 文字内容 */ String const& text, /* 文字内容 */
const Font& font /* 字体 */ const Font& font /* 字体 */
); );
explicit Text( Text(
String const& text, /* 文字内容 */ String const& text, /* 文字内容 */
const TextStyle& style /* 文本样式 */ const TextStyle& style /* 文本样式 */
); );
explicit Text( Text(
String const& text, /* 文字内容 */ String const& text, /* 文字内容 */
const Font& font, /* 字体 */ const Font& font, /* 字体 */
const TextStyle& style /* 文本样式 */ const TextStyle& style /* 文本样式 */

View File

@ -48,29 +48,16 @@ namespace kiwano
StrokeStyle outline_stroke; // ĂčąßĎßĎཝŃůĘ˝ StrokeStyle outline_stroke; // ĂčąßĎßĎཝŃůĘ˝
public: 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( TextStyle(
Color color, Color color = Color::White,
TextAlign alignment = TextAlign::Left, TextAlign alignment = TextAlign::Left,
Float32 wrap_width = 0.f, Float32 wrap_width = 0.f,
Float32 line_spacing = 0.f, Float32 line_spacing = 0.f,
bool underline = false, bool underline = false,
bool strikethrough = false, bool strikethrough = false,
bool outline = true, bool outline = false,
Color outline_color = Color(Color::Black, 0.5), Color outline_color = Color(Color::Black, 0.5),
Float32 outline_width = 1.f, Float32 outline_width = 1.f,
StrokeStyle outline_stroke = StrokeStyle::Round StrokeStyle outline_stroke = StrokeStyle::Round
) )
: color(color) : color(color)

View File

@ -90,10 +90,10 @@ namespace kiwano
void ClearPath(); 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: protected:
void Init(ActorPtr target) override; void Init(ActorPtr target) override;

View File

@ -45,6 +45,7 @@ namespace kiwano
KGE_DECLARE_SMART_PTR(RoundRectActor); KGE_DECLARE_SMART_PTR(RoundRectActor);
KGE_DECLARE_SMART_PTR(CircleActor); KGE_DECLARE_SMART_PTR(CircleActor);
KGE_DECLARE_SMART_PTR(EllipseActor); KGE_DECLARE_SMART_PTR(EllipseActor);
KGE_DECLARE_SMART_PTR(PolygonActor);
KGE_DECLARE_SMART_PTR(PathActor); KGE_DECLARE_SMART_PTR(PathActor);
KGE_DECLARE_SMART_PTR(Action); KGE_DECLARE_SMART_PTR(Action);

View File

@ -78,9 +78,9 @@ public:
inline pointer_type get() const noexcept { return ptr_; } 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 inline void swap(intrusive_ptr& other) noexcept

View File

@ -35,7 +35,7 @@ inline namespace core
// //
// basic_string<> // 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 // 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. // 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. // Use assign() and basic_string<>::cstr() to work fine with c-style strings.
@ -48,11 +48,11 @@ public:
template <typename _Ty> template <typename _Ty>
struct iterator_impl struct iterator_impl
{ {
using iterator_category = typename ::std::iterator_traits<_Ty*>::iterator_category; using iterator_category = typename std::iterator_traits<_Ty*>::iterator_category;
using value_type = typename ::std::iterator_traits<_Ty*>::value_type; using value_type = typename std::iterator_traits<_Ty*>::value_type;
using difference_type = typename ::std::iterator_traits<_Ty*>::difference_type; using difference_type = typename std::iterator_traits<_Ty*>::difference_type;
using pointer = typename ::std::iterator_traits<_Ty*>::pointer; using pointer = typename std::iterator_traits<_Ty*>::pointer;
using reference = typename ::std::iterator_traits<_Ty*>::reference; using reference = typename std::iterator_traits<_Ty*>::reference;
// disable warning 4996 // disable warning 4996
using _Unchecked_type = _Ty; using _Unchecked_type = _Ty;
@ -101,16 +101,16 @@ public:
using const_reference = const value_type &; using const_reference = const value_type &;
using iterator = iterator_impl<value_type>; using iterator = iterator_impl<value_type>;
using const_iterator = iterator_impl<const value_type>; using const_iterator = iterator_impl<const value_type>;
using reverse_iterator = ::std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = ::std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
using traits_type = ::std::char_traits<value_type>; using traits_type = std::char_traits<value_type>;
using allocator_type = ::std::allocator<value_type>; using allocator_type = std::allocator<value_type>;
basic_string(); basic_string();
basic_string(const char_type* cstr, bool const_str = true); basic_string(const char_type* cstr, bool const_str = true);
basic_string(const char_type* cstr, size_type count); basic_string(const char_type* cstr, size_type count);
basic_string(size_type count, char_type ch); basic_string(size_type count, char_type ch);
basic_string(::std::basic_string<char_type> const& str); basic_string(std::basic_string<char_type> const& str);
basic_string(basic_string const& rhs); basic_string(basic_string const& rhs);
basic_string(basic_string const& rhs, size_type pos, size_type count = npos); basic_string(basic_string const& rhs, size_type pos, size_type count = npos);
basic_string(basic_string && rhs) noexcept; 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); 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(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(basic_string const& other) { return append(other.const_str_, 0, npos); }
inline basic_string& append(::std::basic_string<char_type> const& other) { return append(other.c_str()); } inline basic_string& append(std::basic_string<char_type> 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 ch, size_type offset = 0) const;
size_type find(const char_type* const str, size_type offset, size_type count) 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); 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(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(basic_string const& rhs) { basic_string{ rhs }.swap(*this); return *this; }
inline basic_string& assign(::std::basic_string<char_type> const& rhs) { basic_string{ rhs }.swap(*this); return *this; } inline basic_string& assign(std::basic_string<char_type> const& rhs) { basic_string{ rhs }.swap(*this); return *this; }
basic_string& assign(basic_string const& rhs, size_type pos, size_type count = npos); basic_string& assign(basic_string const& rhs, size_type pos, size_type count = npos);
template <typename _Iter> template <typename _Iter>
@ -191,7 +191,7 @@ public:
inline iterator insert(const_iterator pos, char_type ch) { return insert(pos, 1, ch); } 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 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; 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 reverse_iterator rend() { check_operability(); return reverse_iterator(begin()); }
inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
inline const_reverse_iterator crend() const { return rend(); } 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 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 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 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 const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty string"); return const_str_[size_ - 1]; }
public: 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) 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) { if (off >= size_) throw std::out_of_range("string subscript out of range"); check_operability(); return str_[off]; }
public: public:
inline const basic_string operator+(const char_type ch) const { return basic_string{ *this }.append(1, ch); } inline const basic_string operator+(const char_type ch) const { return basic_string{ *this }.append(1, ch); }
@ -247,7 +247,7 @@ public:
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=(const char_type* cstr) { if (const_str_ != cstr) basic_string{ cstr }.swap(*this); return *this; }
inline basic_string& operator=(::std::basic_string<char_type> const& rhs) { basic_string{ rhs }.swap(*this); return *this; } inline basic_string& operator=(std::basic_string<char_type> 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 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; } 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 discard_const_data();
void check_operability(); void check_operability();
void check_offset(size_type offset) const { if (offset > size()) throw ::std::out_of_range("invalid string position"); } 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); } size_type clamp_suffix_size(size_type off, size_type count) const { return std::min(size() - off, count); }
template <typename _Iter> template <typename _Iter>
void assign_iter(_Iter first, _Iter last) void assign_iter(_Iter first, _Iter last)
{ {
size_type diff = static_cast<size_type>(::std::distance(first, last)); size_type diff = static_cast<size_type>(std::distance(first, last));
if (diff == 0) if (diff == 0)
return; return;
@ -375,17 +375,10 @@ inline bool operator>=(basic_string<_CharTy> const& lhs, basic_string<_CharTy> c
// //
template <typename _CharTy> template <typename _CharTy>
::std::basic_ostream<typename basic_string<_CharTy>::char_type>& operator<<(::std::basic_ostream<typename basic_string<_CharTy>::char_type>& os, const basic_string<_CharTy>& str); std::basic_ostream<typename basic_string<_CharTy>::char_type>& operator<<(std::basic_ostream<typename basic_string<_CharTy>::char_type>& os, const basic_string<_CharTy>& str);
template <typename _CharTy> template <typename _CharTy>
::std::basic_istream<typename basic_string<_CharTy>::char_type>& operator>>(::std::basic_istream<typename basic_string<_CharTy>::char_type>& is, basic_string<_CharTy>& str); std::basic_istream<typename basic_string<_CharTy>::char_type>& operator>>(std::basic_istream<typename basic_string<_CharTy>::char_type>& is, basic_string<_CharTy>& str);
//
// string && wstring
//
using string = ::kiwano::core::basic_string<char>;
using wstring = ::kiwano::core::basic_string<WChar>;
// //
@ -419,37 +412,45 @@ basic_string<_CharTy> to_basic_string(Float64 val);
template <typename _CharTy> template <typename _CharTy>
basic_string<_CharTy> to_basic_string(long double val); 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 <typename ..._Args> template <typename ..._Args>
basic_string<char> format_string(const char* const fmt, _Args&&... args); basic_string<char> format_string(const char* const fmt, _Args&& ... args);
template <typename ..._Args> template <typename ..._Args>
basic_string<WChar> format_string(const WChar* const fmt, _Args&& ... args); basic_string<WChar> format_string(const WChar* const fmt, _Args&& ... args);
//
// string && wstring
//
using string = ::kiwano::core::basic_string<char>;
using wstring = ::kiwano::core::basic_string<WChar>;
inline string to_string(Int32 val) { return to_basic_string<char>(val); }
inline string to_string(UInt32 val) { return to_basic_string<char>(val); }
inline string to_string(long val) { return to_basic_string<char>(val); }
inline string to_string(unsigned long val) { return to_basic_string<char>(val); }
inline string to_string(long long val) { return to_basic_string<char>(val); }
inline string to_string(unsigned long long val) { return to_basic_string<char>(val); }
inline string to_string(Float32 val) { return to_basic_string<char>(val); }
inline string to_string(Float64 val) { return to_basic_string<char>(val); }
inline string to_string(long double val) { return to_basic_string<char>(val); }
inline wstring to_wstring(Int32 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(UInt32 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(unsigned long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(long long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(unsigned long long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(Float32 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(Float64 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(long double val) { return to_basic_string<WChar>(val); }
} // inline namespace core } // inline namespace core
} // namespace kiwano } // namespace kiwano
@ -499,7 +500,7 @@ namespace __string_details
{ {
if (count != 0 && first_size != 0) 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)) if (typename _Traits::find(second, count, *iter))
{ {
@ -577,7 +578,7 @@ inline namespace core
} }
template <typename _CharTy> template <typename _CharTy>
inline basic_string<_CharTy>::basic_string(::std::basic_string<char_type> const& str) inline basic_string<_CharTy>::basic_string(std::basic_string<char_type> const& str)
: basic_string(str.c_str(), false) : basic_string(str.c_str(), false)
{ {
} }
@ -927,7 +928,7 @@ inline namespace core
{ {
size_type count1 = size(); size_type count1 = size();
size_type count2 = traits_type::length(str); 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); Int32 ret = traits_type::compare(const_str_, str, rlen);
if (ret != 0) if (ret != 0)
@ -966,7 +967,7 @@ inline namespace core
if (offset >= size_) if (offset >= size_)
return basic_string<_CharTy>::npos; 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; return (citer != cend()) ? (citer - cbegin()) : basic_string<_CharTy>::npos;
} }
@ -976,7 +977,7 @@ inline namespace core
if (pos == 0 || pos > size_ || pos == npos) if (pos == 0 || pos > size_ || pos == npos)
return 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; return (criter != crend()) ? (criter.base() - cbegin()) : basic_string<_CharTy>::npos;
} }
@ -1124,12 +1125,12 @@ inline namespace core
template <typename _CharTy> template <typename _CharTy>
inline void basic_string<_CharTy>::swap(basic_string& rhs) noexcept inline void basic_string<_CharTy>::swap(basic_string& rhs) noexcept
{ {
::std::swap(const_str_, rhs.const_str_); std::swap(const_str_, rhs.const_str_);
::std::swap(size_, rhs.size_); std::swap(size_, rhs.size_);
::std::swap(capacity_, rhs.capacity_); std::swap(capacity_, rhs.capacity_);
// swap const datas // swap const datas
::std::swap(*const_cast<bool*>(&operable_), *const_cast<bool*>(&rhs.operable_)); std::swap(*const_cast<bool*>(&operable_), *const_cast<bool*>(&rhs.operable_));
} }
template <typename _CharTy> template <typename _CharTy>
@ -1193,7 +1194,7 @@ inline namespace core
template <typename ..._Args> template <typename ..._Args>
inline basic_string<_CharTy> basic_string<_CharTy>::format(const char_type* fmt, _Args&& ... args) 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 <typename _CharTy> template <typename _CharTy>
inline ::std::basic_ostream<typename basic_string<_CharTy>::char_type>& operator<<(::std::basic_ostream<typename basic_string<_CharTy>::char_type>& os, const basic_string<_CharTy>& str) inline std::basic_ostream<typename basic_string<_CharTy>::char_type>& operator<<(std::basic_ostream<typename basic_string<_CharTy>::char_type>& os, const basic_string<_CharTy>& str)
{ {
using ostream = ::std::basic_ostream<typename basic_string<_CharTy>::char_type, typename basic_string<_CharTy>::traits_type>; using ostream = std::basic_ostream<typename basic_string<_CharTy>::char_type, typename basic_string<_CharTy>::traits_type>;
using size_type = typename basic_string<_CharTy>::size_type; using size_type = typename basic_string<_CharTy>::size_type;
using traits = typename basic_string<_CharTy>::traits_type; using traits = typename basic_string<_CharTy>::traits_type;
const ostream::sentry ok(os); 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) if (!ok)
{ {
state |= ::std::ios_base::badbit; state |= std::ios_base::badbit;
} }
else else
{ {
@ -1221,22 +1222,22 @@ inline namespace core
try 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) for (; 0 < pad; --pad)
{ {
if (traits::eq_int_type(traits::eof(), os.rdbuf()->sputc(os.fill()))) if (traits::eq_int_type(traits::eof(), os.rdbuf()->sputc(os.fill())))
{ {
state |= ::std::ios_base::badbit; state |= std::ios_base::badbit;
break; break;
} }
} }
} }
if (state == ::std::ios_base::goodbit if (state == std::ios_base::goodbit
&& os.rdbuf()->sputn(str.data(), (::std::streamsize)str_size) != (::std::streamsize)str_size) && os.rdbuf()->sputn(str.data(), (std::streamsize)str_size) != (std::streamsize)str_size)
{ {
state |= ::std::ios_base::badbit; state |= std::ios_base::badbit;
} }
else else
{ {
@ -1244,7 +1245,7 @@ inline namespace core
{ {
if (traits::eq_int_type(traits::eof(), os.rdbuf()->sputc(os.fill()))) if (traits::eq_int_type(traits::eof(), os.rdbuf()->sputc(os.fill())))
{ {
state |= ::std::ios_base::badbit; state |= std::ios_base::badbit;
break; break;
} }
} }
@ -1253,7 +1254,7 @@ inline namespace core
} }
catch (...) catch (...)
{ {
os.setstate(::std::ios_base::badbit, true); os.setstate(std::ios_base::badbit, true);
} }
} }
@ -1262,20 +1263,20 @@ inline namespace core
} }
template <typename _CharTy> template <typename _CharTy>
inline ::std::basic_istream<typename basic_string<_CharTy>::char_type>& operator>>(::std::basic_istream<typename basic_string<_CharTy>::char_type>& is, basic_string<_CharTy>& str) inline std::basic_istream<typename basic_string<_CharTy>::char_type>& operator>>(std::basic_istream<typename basic_string<_CharTy>::char_type>& is, basic_string<_CharTy>& str)
{ {
using ctype = ::std::ctype<typename basic_string<_CharTy>::char_type>; using ctype = std::ctype<typename basic_string<_CharTy>::char_type>;
using istream = ::std::basic_istream<typename basic_string<_CharTy>::char_type, typename basic_string<_CharTy>::traits_type>; using istream = std::basic_istream<typename basic_string<_CharTy>::char_type, typename basic_string<_CharTy>::traits_type>;
using size_type = typename basic_string<_CharTy>::size_type; using size_type = typename basic_string<_CharTy>::size_type;
using traits = typename basic_string<_CharTy>::traits_type; using traits = typename basic_string<_CharTy>::traits_type;
bool changed = false; bool changed = false;
const istream::sentry ok(is); 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) if (ok)
{ {
const ctype& ctype_fac = ::std::use_facet<ctype>(is.getloc()); const ctype& ctype_fac = std::use_facet<ctype>(is.getloc());
str.erase(); str.erase();
try try
{ {
@ -1286,7 +1287,7 @@ inline namespace core
{ {
if (traits::eq_int_type(traits::eof(), meta)) if (traits::eq_int_type(traits::eof(), meta))
{ {
state |= ::std::ios_base::eofbit; state |= std::ios_base::eofbit;
break; break;
} }
else if (ctype_fac.is(ctype::space, traits::to_char_type(meta))) else if (ctype_fac.is(ctype::space, traits::to_char_type(meta)))
@ -1302,13 +1303,13 @@ inline namespace core
} }
catch (...) catch (...)
{ {
is.setstate(::std::ios_base::badbit, true); is.setstate(std::ios_base::badbit, true);
} }
} }
is.width(0); is.width(0);
if (!changed) if (!changed)
state |= ::std::ios_base::failbit; state |= std::ios_base::failbit;
is.setstate(state); is.setstate(state);
return is; return is;
} }
@ -1388,35 +1389,15 @@ inline namespace core
return (__to_string_detail::FloatingToString<_CharTy>::convert(val)); return (__to_string_detail::FloatingToString<_CharTy>::convert(val));
} }
inline string to_string(Int32 val) { return to_basic_string<char>(val); }
inline string to_string(UInt32 val) { return to_basic_string<char>(val); }
inline string to_string(long val) { return to_basic_string<char>(val); }
inline string to_string(unsigned long val) { return to_basic_string<char>(val); }
inline string to_string(long long val) { return to_basic_string<char>(val); }
inline string to_string(unsigned long long val) { return to_basic_string<char>(val); }
inline string to_string(Float32 val) { return to_basic_string<char>(val); }
inline string to_string(Float64 val) { return to_basic_string<char>(val); }
inline string to_string(long double val) { return to_basic_string<char>(val); }
inline wstring to_wstring(Int32 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(UInt32 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(unsigned long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(long long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(unsigned long long val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(Float32 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(Float64 val) { return to_basic_string<WChar>(val); }
inline wstring to_wstring(long double val) { return to_basic_string<WChar>(val); }
template <typename ..._Args> template <typename ..._Args>
inline basic_string<char> format_string(const char* const fmt, _Args&& ... args) inline basic_string<char> format_string(const char* const fmt, _Args&& ... args)
{ {
using string_type = basic_string<char>; using string_type = basic_string<char>;
const auto len = static_cast<typename string_type::size_type>(::_scprintf(fmt, ::std::forward<_Args>(args)...)); const auto len = static_cast<typename string_type::size_type>(::_scprintf(fmt, std::forward<_Args>(args)...));
if (len) if (len)
{ {
string_type str(len, '\0'); 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 str;
} }
return string_type{}; return string_type{};
@ -1426,11 +1407,11 @@ inline namespace core
inline basic_string<WChar> format_string(const WChar* const fmt, _Args&& ... args) inline basic_string<WChar> format_string(const WChar* const fmt, _Args&& ... args)
{ {
using string_type = basic_string<WChar>; using string_type = basic_string<WChar>;
const auto len = static_cast<typename string_type::size_type>(::_scwprintf(fmt, ::std::forward<_Args>(args)...)); const auto len = static_cast<typename string_type::size_type>(::_scwprintf(fmt, std::forward<_Args>(args)...));
if (len) if (len)
{ {
string_type str(len, L'\0'); 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 str;
} }
return string_type{}; return string_type{};
@ -1441,7 +1422,7 @@ inline namespace core
template <typename _Ty, typename _Elem> template <typename _Ty, typename _Elem>
_Elem* __IntegerToStringBufferEnd(const _Ty val, _Elem* const buffer_end) _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; _Elem* next = buffer_end;
auto uval = static_cast<_UTy>(val); auto uval = static_cast<_UTy>(val);
@ -1467,12 +1448,12 @@ inline namespace core
template <typename _Ty> template <typename _Ty>
static basic_string<char> convert(const _Ty val) static basic_string<char> 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<char>::traits_type::char_type; using _Elem = typename basic_string<char>::traits_type::char_type;
_Elem buffer[21]; _Elem buffer[21];
_Elem* const buffer_end = ::std::end(buffer); _Elem* const buffer_end = std::end(buffer);
_Elem* buffer_begin = __IntegerToStringBufferEnd(val, buffer_end); _Elem* buffer_begin = __IntegerToStringBufferEnd(val, buffer_end);
return basic_string<char>(buffer_begin, buffer_end); return basic_string<char>(buffer_begin, buffer_end);
@ -1485,12 +1466,12 @@ inline namespace core
template <typename _Ty> template <typename _Ty>
static basic_string<WChar> convert(const _Ty val) static basic_string<WChar> 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<WChar>::traits_type::char_type; using _Elem = typename basic_string<WChar>::traits_type::char_type;
_Elem buffer[21]; _Elem buffer[21];
_Elem* const buffer_end = ::std::end(buffer); _Elem* const buffer_end = std::end(buffer);
_Elem* buffer_begin = __IntegerToStringBufferEnd(val, buffer_end); _Elem* buffer_begin = __IntegerToStringBufferEnd(val, buffer_end);
return basic_string<WChar>(buffer_begin, buffer_end); return basic_string<WChar>(buffer_begin, buffer_end);
@ -1564,7 +1545,7 @@ public:
, loc_() , loc_()
, conv_num_(0) , conv_num_(0)
{ {
loc_ = ::std::locale(loc_, cvt_); loc_ = std::locale(loc_, cvt_);
} }
virtual ~string_convert() { } virtual ~string_convert() { }
@ -1580,7 +1561,7 @@ public:
wide_string from_bytes(const char* ptr) 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) wide_string from_bytes(const byte_string& byte_str)
@ -1617,7 +1598,7 @@ public:
} }
else else
{ {
throw (::std::range_error("bad conversion")); throw (std::range_error("bad conversion"));
} }
break; break;
} }
@ -1632,7 +1613,7 @@ public:
} }
default: default:
throw (::std::range_error("bad conversion")); throw (std::range_error("bad conversion"));
} }
} }
return wstr; return wstr;
@ -1685,7 +1666,7 @@ public:
} }
else else
{ {
throw (::std::range_error("bad conversion")); throw (std::range_error("bad conversion"));
} }
break; break;
} }
@ -1700,7 +1681,7 @@ public:
} }
default: default:
throw (::std::range_error("bad conversion")); throw (std::range_error("bad conversion"));
} }
} }
return bstr; return bstr;
@ -1711,13 +1692,13 @@ public:
private: private:
const codecvt_type* cvt_; const codecvt_type* cvt_;
::std::locale loc_; std::locale loc_;
state_type state_; state_type state_;
UInt32 conv_num_; UInt32 conv_num_;
}; };
class chs_codecvt class chs_codecvt
: public ::std::codecvt_byname<WChar, char, ::std::mbstate_t> : public std::codecvt_byname<WChar, char, std::mbstate_t>
{ {
public: public:
chs_codecvt() : codecvt_byname("chs") {} chs_codecvt() : codecvt_byname("chs") {}

View File

@ -31,7 +31,7 @@ inline namespace core
// //
// ArrayManager<> with memory operations // vector_memory_manager<> with memory operations
// //
namespace __vector_details namespace __vector_details
{ {
@ -64,77 +64,77 @@ public:
using initializer_list = std::initializer_list<value_type>; using initializer_list = std::initializer_list<value_type>;
public: public:
inline vector() : size_(0), capacity_(0), data_(nullptr) { } inline vector() : size_(0), capacity_(0), data_(nullptr) { }
inline vector(size_type count) : vector() { reserve(count); } inline vector(size_type count) : vector() { reserve(count); }
inline vector(size_type count, const _Ty& val) : vector() { assign(count, val); } inline vector(size_type count, const _Ty& val) : vector() { assign(count, val); }
inline vector(initializer_list list) : vector() { assign(list); } inline vector(initializer_list list) : vector() { assign(list); }
inline vector(const vector& src) : vector() { assign(src); } inline vector(const vector& src) : vector() { assign(src); }
inline vector(vector&& src) noexcept : vector() { swap(src); } inline vector(vector&& src) noexcept : vector() { swap(src); }
inline ~vector() { destroy(); } inline ~vector() { destroy(); }
template <typename _Iter> template <typename _Iter>
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=(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=(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=(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(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(const vector& src) { return operator=(src); }
inline vector& assign(initializer_list list) { return operator=(list); } inline vector& assign(initializer_list list) { return operator=(list); }
template <typename _Iter> template <typename _Iter>
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 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 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 resize(size_type new_size, const _Ty& v);
void reserve(size_type new_capacity); void reserve(size_type new_capacity);
inline void push_back(const _Ty& val) { resize(size_ + 1, 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 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_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 erase(const_iterator first, const_iterator last);
iterator insert(const_iterator where, const _Ty& v); iterator insert(const_iterator where, const _Ty& v);
inline bool empty() const { return size_ == 0; } inline bool empty() const { return size_ == 0; }
inline size_type size() const { return size_; } inline size_type size() const { return size_; }
inline size_type size_in_bytes() const { return size_ * ((size_type)sizeof(_Ty)); } inline size_type size_in_bytes() const { return size_ * ((size_type)sizeof(_Ty)); }
inline size_type capacity() const { return capacity_; } 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 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 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 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 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 iterator begin() { return iterator(data_); }
inline const_iterator begin() const { return const_iterator(data_); } inline const_iterator begin() const { return const_iterator(data_); }
inline const_iterator cbegin() const { return begin(); } inline const_iterator cbegin() const { return begin(); }
inline iterator end() { return iterator(data_ + size_); } inline iterator end() { return iterator(data_ + size_); }
inline const_iterator end() const { return const_iterator(data_ + size_); } inline const_iterator end() const { return const_iterator(data_ + size_); }
inline const_iterator cend() const { return end(); } inline const_iterator cend() const { return end(); }
inline reverse_iterator rbegin() { return reverse_iterator(end()); } inline reverse_iterator rbegin() { return reverse_iterator(end()); }
inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
inline const_reverse_iterator crbegin() const { return rbegin(); } inline const_reverse_iterator crbegin() const { return rbegin(); }
inline reverse_iterator rend() { return reverse_iterator(begin()); } inline reverse_iterator rend() { return reverse_iterator(begin()); }
inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
inline const_reverse_iterator crend() const { return rend(); } 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 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 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 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 const_reference back() const { if (empty()) throw std::out_of_range("back() called on empty array"); return data_[size_ - 1]; }
private: 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 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 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: protected:
size_type size_; size_type size_;
size_type capacity_; size_type capacity_;

View File

@ -78,6 +78,9 @@ namespace kiwano
{ {
} }
#pragma warning (push)
#pragma warning (disable: 26495) // ignore warning "always initialize member variables"
template <typename _MTy> template <typename _MTy>
Matrix3x2T(_MTy const& other) Matrix3x2T(_MTy const& other)
{ {
@ -85,6 +88,8 @@ namespace kiwano
m[i] = other[i]; m[i] = other[i];
} }
#pragma warning (pop)
inline value_type operator [](UInt32 index) const inline value_type operator [](UInt32 index) const
{ {
return m[index]; return m[index];

View File

@ -58,6 +58,16 @@ namespace kiwano
Float32 alpha 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: public:
enum Value : UInt32 enum Value : UInt32
{ {

View File

@ -43,15 +43,26 @@ namespace kiwano
return geo_ != nullptr; 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 Rect Geometry::GetBoundingBox(Matrix3x2 const& transform) const
{ {
if (!geo_) Rect bounds;
return Rect{}; if (geo_)
{
Rect rect; // no matter it failed or not
// no matter it failed or not geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&bounds));
geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&rect)); }
return rect; return bounds;
} }
Float32 Geometry::GetLength() const Float32 Geometry::GetLength() const
@ -246,6 +257,14 @@ namespace kiwano
return (*this); return (*this);
} }
GeometrySink& kiwano::GeometrySink::AddLines(const Point* points, UInt32 count)
{
if (!sink_) BeginPath();
sink_->AddLines(reinterpret_cast<const D2D_POINT_2F*>(points), count);
return (*this);
}
GeometrySink& GeometrySink::AddBezier(Point const& point1, Point const& point2, Point const& point3) GeometrySink& GeometrySink::AddBezier(Point const& point1, Point const& point2, Point const& point3)
{ {
if (!sink_) BeginPath(); if (!sink_) BeginPath();

View File

@ -44,9 +44,12 @@ namespace kiwano
bool IsValid() const; bool IsValid() const;
// 삿혤棍학관鍋분
Rect GetBoundingBox() const;
// 获取外切包围盒 // 获取外切包围盒
Rect GetBoundingBox( Rect GetBoundingBox(
Matrix3x2 const& transform = Matrix3x2() Matrix3x2 const& transform
) const; ) const;
// 判断图形是否包含点 // 判断图形是否包含点
@ -151,6 +154,12 @@ namespace kiwano
Vector<Point> const& points Vector<Point> const& points
); );
// 警속뜩係窟뙈
GeometrySink& AddLines(
const Point* points,
UInt32 count
);
// 添加一条三次方贝塞尔曲线 // 添加一条三次方贝塞尔曲线
GeometrySink& AddBezier( GeometrySink& AddBezier(
Point const& point1, /* 贝塞尔曲线的第一个控制点 */ Point const& point1, /* 贝塞尔曲线的第一个控制点 */
@ -162,7 +171,7 @@ namespace kiwano
GeometrySink& AddArc( GeometrySink& AddArc(
Point const& point, /* 终点 */ Point const& point, /* 终点 */
Size const& radius, /* 椭圆半径 */ Size const& radius, /* 椭圆半径 */
Float32 rotation, /* ÍÖÔ²Ðýת½Ç¶È */ Float32 rotation, /* 哭途旗瘻실똑 */
bool clockwise = true, /* 顺时针 or 逆时针 */ bool clockwise = true, /* 顺时针 or 逆时针 */
bool is_small = true /* 是否取小于 180° 的弧 */ bool is_small = true /* 是否取小于 180° 的弧 */
); );

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include "Texture.h" #include "Texture.h"
#include "../base/time.h"
namespace kiwano namespace kiwano
{ {

View File

@ -391,12 +391,12 @@ namespace kiwano
layout.GetTextStyle().outline_width, layout.GetTextStyle().outline_width,
GetStrokeStyle(layout.GetTextStyle().outline_stroke).get() GetStrokeStyle(layout.GetTextStyle().outline_stroke).get()
); );
hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y);
IncreasePrimitivesCount(); IncreasePrimitivesCount();
} }

View File

@ -190,6 +190,8 @@ namespace kiwano
Int32 primitives; Int32 primitives;
Time start; Time start;
Duration duration; Duration duration;
Status() : primitives(0) {}
}; };
void SetCollectingStatus(bool collecting); void SetCollectingStatus(bool collecting);

View File

@ -190,16 +190,16 @@ namespace kiwano
imaging_factory_.reset(); imaging_factory_.reset();
dwrite_factory_.reset(); dwrite_factory_.reset();
d2d_miter_stroke_style_.reset(); miter_stroke_style_.reset();
d2d_bevel_stroke_style_.reset(); bevel_stroke_style_.reset();
d2d_round_stroke_style_.reset(); round_stroke_style_.reset();
} }
HRESULT D2DDeviceResources::CreateDeviceIndependentResources() HRESULT D2DDeviceResources::CreateDeviceIndependentResources()
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
ComPtr<ID2D1Factory1> d2d_factory; ComPtr<ID2D1Factory1> factory;
ComPtr<IWICImagingFactory> imaging_factory; ComPtr<IWICImagingFactory> imaging_factory;
ComPtr<IDWriteFactory> dwrite_factory; ComPtr<IDWriteFactory> dwrite_factory;
@ -213,12 +213,12 @@ namespace kiwano
D2D1_FACTORY_TYPE_SINGLE_THREADED, D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1), __uuidof(ID2D1Factory1),
&config, &config,
reinterpret_cast<void**>(&d2d_factory) reinterpret_cast<void**>(&factory)
); );
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
factory_ = d2d_factory; factory_ = factory;
hr = CoCreateInstance( hr = CoCreateInstance(
CLSID_WICImagingFactory, CLSID_WICImagingFactory,
@ -244,9 +244,9 @@ namespace kiwano
{ {
dwrite_factory_ = dwrite_factory; dwrite_factory_ = dwrite_factory;
ComPtr<ID2D1StrokeStyle> d2d_miter_stroke_style; ComPtr<ID2D1StrokeStyle> miter_stroke_style;
ComPtr<ID2D1StrokeStyle> d2d_bevel_stroke_style; ComPtr<ID2D1StrokeStyle> bevel_stroke_style;
ComPtr<ID2D1StrokeStyle> d2d_round_stroke_style; ComPtr<ID2D1StrokeStyle> round_stroke_style;
D2D1_STROKE_STYLE_PROPERTIES stroke_style = D2D1::StrokeStyleProperties( D2D1_STROKE_STYLE_PROPERTIES stroke_style = D2D1::StrokeStyleProperties(
D2D1_CAP_STYLE_FLAT, D2D1_CAP_STYLE_FLAT,
@ -262,7 +262,7 @@ namespace kiwano
stroke_style, stroke_style,
nullptr, nullptr,
0, 0,
&d2d_miter_stroke_style &miter_stroke_style
); );
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
@ -272,7 +272,7 @@ namespace kiwano
stroke_style, stroke_style,
nullptr, nullptr,
0, 0,
&d2d_bevel_stroke_style &bevel_stroke_style
); );
} }
@ -283,15 +283,15 @@ namespace kiwano
stroke_style, stroke_style,
nullptr, nullptr,
0, 0,
&d2d_round_stroke_style &round_stroke_style
); );
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
d2d_miter_stroke_style_ = d2d_miter_stroke_style; miter_stroke_style_ = miter_stroke_style;
d2d_bevel_stroke_style_ = d2d_bevel_stroke_style; bevel_stroke_style_ = bevel_stroke_style;
d2d_round_stroke_style_ = d2d_round_stroke_style; round_stroke_style_ = round_stroke_style;
} }
} }
@ -300,17 +300,17 @@ namespace kiwano
HRESULT D2DDeviceResources::SetD2DDevice(_In_ ComPtr<ID2D1Device> const& device) HRESULT D2DDeviceResources::SetD2DDevice(_In_ ComPtr<ID2D1Device> const& device)
{ {
ComPtr<ID2D1DeviceContext> d2d_device_ctx; ComPtr<ID2D1DeviceContext> device_ctx;
HRESULT hr = device->CreateDeviceContext( HRESULT hr = device->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE, D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&d2d_device_ctx &device_ctx
); );
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
device_ = device; device_ = device;
device_context_ = d2d_device_ctx; device_context_ = device_ctx;
device_context_->SetDpi(dpi_, dpi_); device_context_->SetDpi(dpi_, dpi_);
} }

View File

@ -23,7 +23,6 @@
#include "../Color.h" #include "../Color.h"
#include "../../math/math.h" #include "../../math/math.h"
#include "../../base/Resource.h" #include "../../base/Resource.h"
#include "../../2d/TextStyle.hpp"
#include <dwrite.h> #include <dwrite.h>
#include <d2d1.h> #include <d2d1.h>
#include <d2d1_1.h> #include <d2d1_1.h>
@ -243,9 +242,9 @@ namespace kiwano
inline ID2D1DeviceContext* GetDeviceContext() const { KGE_ASSERT(device_context_); return device_context_.get(); } 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 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* GetMiterStrokeStyle() const { KGE_ASSERT(miter_stroke_style_); return miter_stroke_style_.get(); }
inline ID2D1StrokeStyle* GetBevelStrokeStyle() const { KGE_ASSERT(d2d_bevel_stroke_style_); return d2d_bevel_stroke_style_.get(); } inline ID2D1StrokeStyle* GetBevelStrokeStyle() const { KGE_ASSERT(bevel_stroke_style_); return bevel_stroke_style_.get(); }
inline ID2D1StrokeStyle* GetRoundStrokeStyle() const { KGE_ASSERT(d2d_round_stroke_style_); return d2d_round_stroke_style_.get(); } inline ID2D1StrokeStyle* GetRoundStrokeStyle() const { KGE_ASSERT(round_stroke_style_); return round_stroke_style_.get(); }
protected: protected:
ComPtr<ID2D1Factory1> factory_; ComPtr<ID2D1Factory1> factory_;
@ -256,9 +255,9 @@ namespace kiwano
ComPtr<IWICImagingFactory> imaging_factory_; ComPtr<IWICImagingFactory> imaging_factory_;
ComPtr<IDWriteFactory> dwrite_factory_; ComPtr<IDWriteFactory> dwrite_factory_;
ComPtr<ID2D1StrokeStyle> d2d_miter_stroke_style_; ComPtr<ID2D1StrokeStyle> miter_stroke_style_;
ComPtr<ID2D1StrokeStyle> d2d_bevel_stroke_style_; ComPtr<ID2D1StrokeStyle> bevel_stroke_style_;
ComPtr<ID2D1StrokeStyle> d2d_round_stroke_style_; ComPtr<ID2D1StrokeStyle> round_stroke_style_;
}; };
} }

View File

@ -198,7 +198,7 @@ namespace kiwano
sFillColor_ = fillColor; sFillColor_ = fillColor;
bShowOutline_ = outline; bShowOutline_ = outline;
sOutlineColor_ = outlineColor; sOutlineColor_ = outlineColor;
fOutlineWidth = 2 * outlineWidth; fOutlineWidth = outlineWidth;
pCurrStrokeStyle_ = outlineJoin; pCurrStrokeStyle_ = outlineJoin;
if (pBrush_) pBrush_->SetOpacity(opacity); if (pBrush_) pBrush_->SetOpacity(opacity);
@ -220,80 +220,87 @@ namespace kiwano
HRESULT hr = S_OK; HRESULT hr = S_OK;
ID2D1PathGeometry* pPathGeometry = NULL; if (bShowOutline_)
hr = pFactory_->CreatePathGeometry(
&pPathGeometry
);
ID2D1GeometrySink* pSink = NULL;
if (SUCCEEDED(hr))
{ {
hr = pPathGeometry->Open( ID2D1GeometrySink* pSink = NULL;
&pSink ID2D1PathGeometry* pPathGeometry = NULL;
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
hr = pFactory_->CreatePathGeometry(
&pPathGeometry
); );
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = glyphRun->fontFace->GetGlyphRunOutline( hr = pPathGeometry->Open(
glyphRun->fontEmSize, &pSink
glyphRun->glyphIndices, );
glyphRun->glyphAdvances,
glyphRun->glyphOffsets,
glyphRun->glyphCount,
glyphRun->isSideways,
glyphRun->bidiLevel % 2,
pSink
);
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = pSink->Close(); 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( if (SUCCEEDED(hr))
1.0f, 0.0f, {
0.0f, 1.0f, hr = pSink->Close();
baselineOriginX, baselineOriginY }
);
ID2D1TransformedGeometry* pTransformedGeometry = NULL; if (SUCCEEDED(hr))
if (SUCCEEDED(hr)) {
{ D2D1::Matrix3x2F const matrix = D2D1::Matrix3x2F(
hr = pFactory_->CreateTransformedGeometry( 1.0f, 0.0f,
pPathGeometry, 0.0f, 1.0f,
&matrix, baselineOriginX, baselineOriginY
&pTransformedGeometry );
);
}
if (SUCCEEDED(hr) && bShowOutline_) if (SUCCEEDED(hr))
{ {
pBrush_->SetColor(sOutlineColor_); hr = pFactory_->CreateTransformedGeometry(
pPathGeometry,
&matrix,
&pTransformedGeometry
);
}
pRT_->DrawGeometry( if (SUCCEEDED(hr))
pTransformedGeometry, {
pBrush_, pBrush_->SetColor(sOutlineColor_);
fOutlineWidth,
pCurrStrokeStyle_ pRT_->DrawGeometry(
); pTransformedGeometry,
pBrush_,
fOutlineWidth * 2, // twice width for widening
pCurrStrokeStyle_
);
}
}
}
DX::SafeRelease(pPathGeometry);
DX::SafeRelease(pSink);
DX::SafeRelease(pTransformedGeometry);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
pBrush_->SetColor(sFillColor_); pBrush_->SetColor(sFillColor_);
pRT_->FillGeometry( pRT_->DrawGlyphRun(
pTransformedGeometry, D2D1::Point2F(baselineOriginX, baselineOriginY),
glyphRun,
pBrush_ pBrush_
); );
} }
DX::SafeRelease(pPathGeometry);
DX::SafeRelease(pSink);
DX::SafeRelease(pTransformedGeometry);
return hr; return hr;
} }
@ -345,7 +352,7 @@ namespace kiwano
pRT_->DrawGeometry( pRT_->DrawGeometry(
pTransformedGeometry, pTransformedGeometry,
pBrush_, pBrush_,
fOutlineWidth, fOutlineWidth * 2,
pCurrStrokeStyle_ pCurrStrokeStyle_
); );
} }
@ -414,7 +421,7 @@ namespace kiwano
pRT_->DrawGeometry( pRT_->DrawGeometry(
pTransformedGeometry, pTransformedGeometry,
pBrush_, pBrush_,
fOutlineWidth, fOutlineWidth * 2,
pCurrStrokeStyle_ pCurrStrokeStyle_
); );
} }