Update Brush & RenderTarget

This commit is contained in:
Nomango 2019-12-27 23:42:51 +08:00
parent ab50ec78b6
commit ef77e76c6c
34 changed files with 757 additions and 918 deletions

View File

@ -35,7 +35,7 @@ namespace kiwano
void ImGuiLayer::OnRender(RenderTarget* rt) void ImGuiLayer::OnRender(RenderTarget* rt)
{ {
PrepareRender(rt); PrepareToRender(rt);
for (const auto& pipeline : pipelines_) for (const auto& pipeline : pipelines_)
{ {
pipeline.second(); pipeline.second();

View File

@ -93,8 +93,12 @@ namespace kiwano
if (children_.empty()) if (children_.empty())
{ {
if (CheckVisibilty(rt))
{
PrepareToRender(rt);
OnRender(rt); OnRender(rt);
} }
}
else else
{ {
// render children those are less than 0 in Z-Order // render children those are less than 0 in Z-Order
@ -108,7 +112,11 @@ namespace kiwano
child = child->next_item().get(); child = child->next_item().get();
} }
if (CheckVisibilty(rt))
{
PrepareToRender(rt);
OnRender(rt); OnRender(rt);
}
while (child) while (child)
{ {
@ -118,10 +126,9 @@ namespace kiwano
} }
} }
void Actor::PrepareRender(RenderTarget* rt) void Actor::PrepareToRender(RenderTarget* rt)
{ {
rt->SetTransform(transform_matrix_); rt->SetTransform(transform_matrix_);
rt->SetOpacity(displayed_opacity_);
} }
void Actor::RenderBorder(RenderTarget* rt) void Actor::RenderBorder(RenderTarget* rt)
@ -132,10 +139,10 @@ namespace kiwano
rt->SetTransform(transform_matrix_); rt->SetTransform(transform_matrix_);
rt->SetDefaultBrushColor(Color(Color::Red, .4f)); rt->SetCurrentBrush(GetStage()->GetBorderFillBrush());
rt->FillRectangle(bounds); rt->FillRectangle(bounds);
rt->SetDefaultBrushColor(Color(Color::Red, .8f)); rt->SetCurrentBrush(GetStage()->GetBorderStrokeBrush());
rt->DrawRectangle(bounds, 2.f); rt->DrawRectangle(bounds, 2.f);
} }
@ -150,8 +157,16 @@ namespace kiwano
if (dirty_visibility_) if (dirty_visibility_)
{ {
dirty_visibility_ = false; dirty_visibility_ = false;
if (size_.IsOrigin())
{
visible_in_rt_ = false;
}
else
{
visible_in_rt_ = rt->CheckVisibility(GetBounds(), GetTransformMatrix()); visible_in_rt_ = rt->CheckVisibility(GetBounds(), GetTransformMatrix());
} }
}
return visible_in_rt_; return visible_in_rt_;
} }

View File

@ -398,7 +398,7 @@ namespace kiwano
virtual void Render(RenderTarget* rt); virtual void Render(RenderTarget* rt);
virtual void PrepareRender(RenderTarget* rt); virtual void PrepareToRender(RenderTarget* rt);
virtual void RenderBorder(RenderTarget* rt); virtual void RenderBorder(RenderTarget* rt);

View File

@ -27,11 +27,8 @@ namespace kiwano
Canvas::Canvas() Canvas::Canvas()
: cache_expired_(false) : cache_expired_(false)
, stroke_width_(1.0f) , stroke_width_(1.0f)
, fill_color_(0, 0, 0)
, stroke_color_(Color::White)
, stroke_style_(StrokeStyle::Miter) , stroke_style_(StrokeStyle::Miter)
{ {
Renderer::instance().CreateTextureRenderTarget(rt_);
} }
Canvas::~Canvas() Canvas::~Canvas()
@ -40,11 +37,13 @@ namespace kiwano
void Canvas::BeginDraw() void Canvas::BeginDraw()
{ {
InitRenderTargetAndBrushs();
rt_->BeginDraw(); rt_->BeginDraw();
} }
void Canvas::EndDraw() void Canvas::EndDraw()
{ {
InitRenderTargetAndBrushs();
rt_->EndDraw(); rt_->EndDraw();
cache_expired_ = true; cache_expired_ = true;
} }
@ -55,51 +54,17 @@ namespace kiwano
if (texture_cached_ && texture_cached_->IsValid()) if (texture_cached_ && texture_cached_->IsValid())
{ {
PrepareRender(rt); PrepareToRender(rt);
Rect bitmap_rect(0.f, 0.f, texture_cached_->GetWidth(), texture_cached_->GetHeight()); Rect bitmap_rect(0.f, 0.f, texture_cached_->GetWidth(), texture_cached_->GetHeight());
rt->DrawTexture(*texture_cached_, bitmap_rect, bitmap_rect); rt->DrawTexture(*texture_cached_, bitmap_rect, bitmap_rect);
} }
} }
void Canvas::SetStrokeColor(Color const& color) void Canvas::SetBrush(BrushPtr brush)
{ {
stroke_color_ = color; InitRenderTargetAndBrushs();
} rt_->SetCurrentBrush(brush);
void Canvas::SetFillColor(Color const& color)
{
fill_color_ = color;
}
void Canvas::SetStrokeWidth(float width)
{
stroke_width_ = std::max(width, 0.f);
}
void Canvas::SetStrokeStyle(StrokeStyle stroke_style)
{
stroke_style_ = stroke_style;
}
void Canvas::SetTextStyle(TextStyle const & text_style)
{
text_style_ = text_style;
}
void Canvas::SetBrushOpacity(float opacity)
{
rt_->SetOpacity(opacity);
}
Color Canvas::GetStrokeColor() const
{
return stroke_color_;
}
Color Canvas::GetFillColor() const
{
return fill_color_;
} }
float Canvas::GetStrokeWidth() const float Canvas::GetStrokeWidth() const
@ -107,44 +72,46 @@ namespace kiwano
return stroke_width_; return stroke_width_;
} }
float Canvas::GetBrushOpacity() const
{
return rt_->GetOpacity();
}
void Canvas::SetBrushTransform(Transform const& transform) void Canvas::SetBrushTransform(Transform const& transform)
{ {
InitRenderTargetAndBrushs();
rt_->SetTransform(transform.ToMatrix()); rt_->SetTransform(transform.ToMatrix());
} }
void Canvas::SetBrushTransform(Matrix3x2 const & transform) void Canvas::SetBrushTransform(Matrix3x2 const & transform)
{ {
InitRenderTargetAndBrushs();
rt_->SetTransform(transform); rt_->SetTransform(transform);
} }
void Canvas::PushLayerArea(LayerArea& area) void Canvas::PushLayerArea(LayerArea& area)
{ {
InitRenderTargetAndBrushs();
rt_->PushLayer(area); rt_->PushLayer(area);
} }
void Canvas::PopLayerArea() void Canvas::PopLayerArea()
{ {
InitRenderTargetAndBrushs();
rt_->PopLayer(); rt_->PopLayer();
} }
void Canvas::PushClipRect(Rect const& clip_rect) void Canvas::PushClipRect(Rect const& clip_rect)
{ {
InitRenderTargetAndBrushs();
rt_->PushClipRect(clip_rect); rt_->PushClipRect(clip_rect);
} }
void Canvas::PopClipRect() void Canvas::PopClipRect()
{ {
InitRenderTargetAndBrushs();
rt_->PopClipRect(); rt_->PopClipRect();
} }
void Canvas::DrawLine(Point const& begin, Point const& end) void Canvas::DrawLine(Point const& begin, Point const& end)
{ {
rt_->SetDefaultBrushColor(stroke_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_);
rt_->DrawLine( rt_->DrawLine(
begin, begin,
end, end,
@ -156,7 +123,8 @@ namespace kiwano
void Canvas::DrawCircle(Point const& center, float radius) void Canvas::DrawCircle(Point const& center, float radius)
{ {
rt_->SetDefaultBrushColor(stroke_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_);
rt_->DrawEllipse( rt_->DrawEllipse(
center, center,
Vec2(radius, radius), Vec2(radius, radius),
@ -168,7 +136,8 @@ namespace kiwano
void Canvas::DrawEllipse(Point const& center, Vec2 const& radius) void Canvas::DrawEllipse(Point const& center, Vec2 const& radius)
{ {
rt_->SetDefaultBrushColor(stroke_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_);
rt_->DrawEllipse( rt_->DrawEllipse(
center, center,
radius, radius,
@ -180,7 +149,8 @@ namespace kiwano
void Canvas::DrawRect(Rect const& rect) void Canvas::DrawRect(Rect const& rect)
{ {
rt_->SetDefaultBrushColor(stroke_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_);
rt_->DrawRectangle( rt_->DrawRectangle(
rect, rect,
stroke_width_, stroke_width_,
@ -191,7 +161,8 @@ namespace kiwano
void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius) void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius)
{ {
rt_->SetDefaultBrushColor(stroke_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_);
rt_->DrawRoundedRectangle( rt_->DrawRoundedRectangle(
rect, rect,
radius, radius,
@ -203,7 +174,8 @@ namespace kiwano
void Canvas::FillCircle(Point const& center, float radius) void Canvas::FillCircle(Point const& center, float radius)
{ {
rt_->SetDefaultBrushColor(fill_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_);
rt_->FillEllipse( rt_->FillEllipse(
center, center,
Vec2(radius, radius) Vec2(radius, radius)
@ -213,7 +185,8 @@ namespace kiwano
void Canvas::FillEllipse(Point const& center, Vec2 const& radius) void Canvas::FillEllipse(Point const& center, Vec2 const& radius)
{ {
rt_->SetDefaultBrushColor(fill_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_);
rt_->FillEllipse( rt_->FillEllipse(
center, center,
radius radius
@ -223,7 +196,8 @@ namespace kiwano
void Canvas::FillRect(Rect const& rect) void Canvas::FillRect(Rect const& rect)
{ {
rt_->SetDefaultBrushColor(fill_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_);
rt_->FillRectangle( rt_->FillRectangle(
rect rect
); );
@ -232,7 +206,8 @@ namespace kiwano
void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius) void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius)
{ {
rt_->SetDefaultBrushColor(fill_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_);
rt_->FillRoundedRectangle( rt_->FillRoundedRectangle(
rect, rect,
radius radius
@ -244,6 +219,7 @@ namespace kiwano
{ {
if (texture) if (texture)
{ {
InitRenderTargetAndBrushs();
rt_->DrawTexture(*texture, src_rect, dest_rect); rt_->DrawTexture(*texture, src_rect, dest_rect);
cache_expired_ = true; cache_expired_ = true;
} }
@ -262,6 +238,7 @@ namespace kiwano
void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point) void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point)
{ {
InitRenderTargetAndBrushs();
rt_->DrawTextLayout(layout, point); rt_->DrawTextLayout(layout, point);
} }
@ -297,7 +274,8 @@ namespace kiwano
void Canvas::StrokePath() void Canvas::StrokePath()
{ {
rt_->SetDefaultBrushColor(stroke_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(stroke_brush_);
rt_->DrawGeometry( rt_->DrawGeometry(
geo_sink_.GetGeometry(), geo_sink_.GetGeometry(),
stroke_width_, stroke_width_,
@ -308,7 +286,8 @@ namespace kiwano
void Canvas::FillPath() void Canvas::FillPath()
{ {
rt_->SetDefaultBrushColor(fill_color_); InitRenderTargetAndBrushs();
rt_->SetCurrentBrush(fill_brush_);
rt_->FillGeometry( rt_->FillGeometry(
geo_sink_.GetGeometry() geo_sink_.GetGeometry()
); );
@ -317,12 +296,14 @@ namespace kiwano
void Canvas::Clear() void Canvas::Clear()
{ {
InitRenderTargetAndBrushs();
rt_->Clear(); rt_->Clear();
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::Clear(Color const& clear_color) void Canvas::Clear(Color const& clear_color)
{ {
InitRenderTargetAndBrushs();
rt_->Clear(clear_color); rt_->Clear(clear_color);
cache_expired_ = true; cache_expired_ = true;
} }
@ -333,13 +314,40 @@ namespace kiwano
return texture_cached_; return texture_cached_;
} }
void Canvas::InitRenderTargetAndBrushs()
{
if (!rt_)
{
Renderer::instance().CreateTextureRenderTarget(rt_);
}
if (!stroke_brush_)
{
stroke_brush_ = new Brush;
stroke_brush_->SetColor(Color::White);
}
if (!fill_brush_)
{
fill_brush_ = new Brush;
fill_brush_->SetColor(Color::White);
}
}
void Canvas::UpdateCache() const void Canvas::UpdateCache() const
{ {
if (cache_expired_) if (cache_expired_ && rt_)
{
if (!texture_cached_)
{
texture_cached_ = new Texture;
}
if (rt_->GetOutput(*texture_cached_))
{ {
texture_cached_ = rt_->GetOutput();
cache_expired_ = false; cache_expired_ = false;
} }
} }
}
} }

View File

@ -183,11 +183,21 @@ namespace kiwano
/// @param color 填充颜色 /// @param color 填充颜色
void SetFillColor(Color const& color); void SetFillColor(Color const& color);
/// \~chinese
/// @brief ÉèÖÃÌî³ä»­Ë¢
/// @param[in] brush Ìî³ä»­Ë¢
void SetFillBrush(BrushPtr brush);
/// \~chinese /// \~chinese
/// @brief 设置轮廓颜色 /// @brief 设置轮廓颜色
/// @param color 轮廓颜色 /// @param color 轮廓颜色
void SetStrokeColor(Color const& color); void SetStrokeColor(Color const& color);
/// \~chinese
/// @brief ÉèÖÃÂÖÀª»­Ë¢
/// @param[in] brush ÂÖÀª»­Ë¢
void SetStrokeBrush(BrushPtr brush);
/// \~chinese /// \~chinese
/// @brief 设置轮廓宽度 /// @brief 设置轮廓宽度
/// @param width 轮廓宽度 /// @param width 轮廓宽度
@ -204,17 +214,17 @@ namespace kiwano
void SetTextStyle(TextStyle const& text_style); void SetTextStyle(TextStyle const& text_style);
/// \~chinese /// \~chinese
/// @brief 设置画笔透明度 /// @brief ÉèÖû­Ë¢
/// @param opacity 透明度,范围 [0.0 - 1.0] /// @param[in] brush »­Ë¢
void SetBrushOpacity(float opacity); void SetBrush(BrushPtr brush);
/// \~chinese /// \~chinese
/// @brief 设置画笔二维变换 /// @brief ÉèÖû­Ë¢¶þά±ä»»
/// @param transform 二维变换 /// @param transform 二维变换
void SetBrushTransform(Transform const& transform); void SetBrushTransform(Transform const& transform);
/// \~chinese /// \~chinese
/// @brief 设置画笔二维变换矩阵 /// @brief ÉèÖû­Ë¢¶þά±ä»»¾ØÕó
/// @param transform 二维变换矩阵 /// @param transform 二维变换矩阵
void SetBrushTransform(Matrix3x2 const& transform); void SetBrushTransform(Matrix3x2 const& transform);
@ -236,21 +246,17 @@ namespace kiwano
/// @brief 删除最近添加的裁剪区域 /// @brief 删除最近添加的裁剪区域
void PopClipRect(); void PopClipRect();
/// \~chinese
/// @brief 获取填充颜色
Color GetFillColor() const;
/// \~chinese
/// @brief 获取轮廓颜色
Color GetStrokeColor() const;
/// \~chinese /// \~chinese
/// @brief 获取轮廓宽度 /// @brief 获取轮廓宽度
float GetStrokeWidth() const; float GetStrokeWidth() const;
/// \~chinese /// \~chinese
/// @brief 获取画笔透明度 /// @brief »ñÈ¡Ìî³ä»­Ë¢
float GetBrushOpacity() const; BrushPtr GetFillBrush() const;
/// \~chinese
/// @brief »ñÈ¡ÂÖÀª»­Ë¢
BrushPtr GetStrokeBrush() const;
/// \~chinese /// \~chinese
/// @brief 导出纹理 /// @brief 导出纹理
@ -259,21 +265,70 @@ namespace kiwano
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
private: private:
void InitRenderTargetAndBrushs();
void UpdateCache() const; void UpdateCache() const;
private: private:
float stroke_width_; float stroke_width_;
Color fill_color_;
Color stroke_color_;
TextStyle text_style_; TextStyle text_style_;
StrokeStyle stroke_style_; StrokeStyle stroke_style_;
GeometrySink geo_sink_; GeometrySink geo_sink_;
TextureRenderTargetPtr rt_; BrushPtr fill_brush_;
BrushPtr stroke_brush_;
mutable bool cache_expired_; mutable bool cache_expired_;
mutable TexturePtr texture_cached_; mutable TexturePtr texture_cached_;
mutable TextureRenderTargetPtr rt_;
}; };
/** @} */ /** @} */
inline void Canvas::SetStrokeWidth(float width)
{
stroke_width_ = std::max(width, 0.f);
}
inline void Canvas::SetStrokeStyle(StrokeStyle stroke_style)
{
stroke_style_ = stroke_style;
}
inline void Canvas::SetTextStyle(TextStyle const& text_style)
{
text_style_ = text_style;
}
inline void Canvas::SetStrokeColor(Color const& color)
{
InitRenderTargetAndBrushs();
stroke_brush_->SetColor(color);
}
inline void Canvas::SetFillColor(Color const& color)
{
InitRenderTargetAndBrushs();
fill_brush_->SetColor(color);
}
inline void Canvas::SetFillBrush(BrushPtr brush)
{
fill_brush_ = brush;
}
inline void Canvas::SetStrokeBrush(BrushPtr brush)
{
stroke_brush_ = brush;
}
inline BrushPtr Canvas::GetFillBrush() const
{
return fill_brush_;
}
inline BrushPtr Canvas::GetStrokeBrush() const
{
return stroke_brush_;
}
} }

View File

@ -47,13 +47,14 @@ namespace kiwano
} }
DebugActor::DebugActor() DebugActor::DebugActor()
: background_color_(0.0f, 0.0f, 0.0f, 0.7f)
{ {
SetName(L"kiwano-debug-actor"); SetName(L"kiwano-debug-actor");
SetPosition(Point{ 10, 10 }); SetPosition(Point{ 10, 10 });
SetResponsible(true); SetResponsible(true);
SetCascadeOpacityEnabled(true); SetCascadeOpacityEnabled(true);
background_brush_->SetColor(Color(0.0f, 0.0f, 0.0f, 0.7f));
debug_text_ = new TextActor; debug_text_ = new TextActor;
debug_text_->SetPosition(Point{ 10, 10 }); debug_text_->SetPosition(Point{ 10, 10 });
this->AddChild(debug_text_); this->AddChild(debug_text_);
@ -75,9 +76,7 @@ namespace kiwano
void DebugActor::OnRender(RenderTarget* rt) void DebugActor::OnRender(RenderTarget* rt)
{ {
PrepareRender(rt); rt->SetCurrentBrush(background_brush_);
rt->SetDefaultBrushColor(background_color_);
rt->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }); rt->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f });
} }
@ -136,4 +135,9 @@ namespace kiwano
} }
} }
bool DebugActor::CheckVisibilty(RenderTarget* rt) const
{
return true;
}
} }

View File

@ -22,6 +22,7 @@
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/TextActor.h> #include <kiwano/2d/TextActor.h>
#include <kiwano/renderer/Color.h> #include <kiwano/renderer/Color.h>
#include <kiwano/renderer/Brush.h>
namespace kiwano namespace kiwano
{ {
@ -46,8 +47,11 @@ namespace kiwano
void OnUpdate(Duration dt) override; void OnUpdate(Duration dt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
private: private:
Color background_color_; BrushPtr background_brush_;
TextActorPtr debug_text_; TextActorPtr debug_text_;
Vector<Time> frame_time_; Vector<Time> frame_time_;
}; };

View File

@ -27,21 +27,6 @@ namespace kiwano
{ {
} }
Frame::Frame(String const& file_path)
{
Load(file_path);
}
Frame::Frame(Resource const& res)
{
Load(res);
}
Frame::Frame(TexturePtr texture)
{
SetTexture(texture);
}
bool Frame::Load(String const& file_path) bool Frame::Load(String const& file_path)
{ {
TexturePtr texture = TextureCache::instance().AddOrGetTexture(file_path); TexturePtr texture = TextureCache::instance().AddOrGetTexture(file_path);

View File

@ -38,54 +38,29 @@ namespace kiwano
/// @brief 构建空图像帧 /// @brief 构建空图像帧
Frame(); Frame();
/// \~chinese
/// @brief 构建图像帧
/// @param file_path 图像路径
explicit Frame(
String const& file_path
);
/// \~chinese
/// @brief 构建图像帧
/// @param res 图像资源
explicit Frame(
Resource const& res
);
/// \~chinese
/// @brief 构建图像帧
/// @param texture 纹理
explicit Frame(
TexturePtr texture
);
/// \~chinese /// \~chinese
/// @brief 加载图像 /// @brief 加载图像
/// @param file_path 图像路径 /// @param file_path 图像路径
bool Load( bool Load(String const& file_path);
String const& file_path
);
/// \~chinese /// \~chinese
/// @brief 加载图像 /// @brief 加载图像
/// @param res 图像资源 /// @param res 图像资源
bool Load( bool Load(Resource const& res);
Resource const& res
);
/// \~chinese /// \~chinese
/// @brief 裁剪图像帧为矩形 /// @brief 裁剪图像帧为矩形
/// @param crop_rect 裁剪矩形定义 /// @param crop_rect 裁剪矩形定义
void SetCropRect( void SetCropRect(Rect const& crop_rect);
Rect const& crop_rect
);
/// \~chinese /// \~chinese
/// @brief 设置纹理 /// @brief 设置纹理
/// @param texture 纹理 /// @param texture 纹理
void SetTexture( void SetTexture(TexturePtr texture);
TexturePtr texture
); /// \~chinese
/// @brief 是否有效
bool IsValid() const;
/// \~chinese /// \~chinese
/// @brief 获取宽度 /// @brief 获取宽度
@ -116,7 +91,7 @@ namespace kiwano
Rect crop_rect_; Rect crop_rect_;
}; };
inline bool Frame::IsValid() const { return texture_ && texture_->IsValid(); }
inline float Frame::GetWidth() const { return crop_rect_.GetWidth(); } inline float Frame::GetWidth() const { return crop_rect_.GetWidth(); }
inline float Frame::GetHeight() const { return crop_rect_.GetHeight(); } inline float Frame::GetHeight() const { return crop_rect_.GetHeight(); }
inline Size Frame::GetSize() const { return crop_rect_.GetSize(); } inline Size Frame::GetSize() const { return crop_rect_.GetSize(); }

View File

@ -33,22 +33,6 @@ namespace kiwano
{ {
} }
GifSprite::GifSprite(String const& file_path)
{
Load(file_path);
}
GifSprite::GifSprite(Resource const& res)
: GifSprite()
{
Load(res);
}
GifSprite::GifSprite(GifImagePtr gif)
{
Load(gif);
}
bool GifSprite::Load(String const& file_path) bool GifSprite::Load(String const& file_path)
{ {
GifImagePtr image = TextureCache::instance().AddOrGetGifImage(file_path); GifImagePtr image = TextureCache::instance().AddOrGetGifImage(file_path);
@ -91,7 +75,7 @@ namespace kiwano
{ {
if (frame_to_render_ && CheckVisibilty(rt)) if (frame_to_render_ && CheckVisibilty(rt))
{ {
PrepareRender(rt); PrepareToRender(rt);
rt->DrawTexture(*frame_to_render_, &frame_.rect, nullptr); rt->DrawTexture(*frame_to_render_, &frame_.rect, nullptr);
} }
@ -197,8 +181,12 @@ namespace kiwano
frame_rt_->EndDraw(); frame_rt_->EndDraw();
frame_to_render_ = frame_rt_->GetOutput(); if (!frame_to_render_)
if (frame_to_render_) {
frame_to_render_ = new Texture;
}
if (frame_rt_->GetOutput(*frame_to_render_))
{ {
next_index_ = (++next_index_) % gif_->GetFramesCount(); next_index_ = (++next_index_) % gif_->GetFramesCount();
} }
@ -218,9 +206,10 @@ namespace kiwano
void GifSprite::SaveComposedFrame() void GifSprite::SaveComposedFrame()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
TexturePtr frame_to_be_saved = frame_rt_->GetOutput();
HRESULT hr = frame_to_be_saved ? S_OK : E_FAIL; TexturePtr frame_to_be_saved = new Texture;
HRESULT hr = frame_rt_->GetOutput(*frame_to_be_saved) ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -248,9 +237,9 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
TexturePtr frame_to_copy_to = frame_rt_->GetOutput(); TexturePtr frame_to_copy_to = new Texture;
hr = frame_to_copy_to ? S_OK : E_FAIL; hr = frame_rt_->GetOutput(*frame_to_copy_to) ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {

View File

@ -51,21 +51,6 @@ namespace kiwano
GifSprite(); GifSprite();
/// \~chinese
/// @brief ¹¹ÔìGIF¾«Áé
/// @param file_path GIFͼƬ·¾¶
GifSprite(String const& file_path);
/// \~chinese
/// @brief ¹¹ÔìGIF¾«Áé
/// @param res GIFͼƬ×ÊÔ´
GifSprite(Resource const& res);
/// \~chinese
/// @brief ¹¹ÔìGIF¾«Áé
/// @param gif GIFͼƬ
GifSprite(GifImagePtr gif);
/// \~chinese /// \~chinese
/// @brief ¼ÓÔØGIFͼƬ /// @brief ¼ÓÔØGIFͼƬ
/// @param file_path GIFͼƬ·¾¶ /// @param file_path GIFͼƬ·¾¶

View File

@ -27,16 +27,6 @@ namespace kiwano
Layer::Layer() Layer::Layer()
: swallow_(false) : swallow_(false)
{ {
auto handler = Closure(this, &Layer::HandleMessages);
AddListener<MouseDownEvent>(handler);
AddListener<MouseUpEvent>(handler);
AddListener<MouseMoveEvent>(handler);
AddListener<MouseWheelEvent>(handler);
AddListener<KeyDownEvent>(handler);
AddListener<KeyUpEvent>(handler);
AddListener<KeyCharEvent>(handler);
} }
Layer::~Layer() Layer::~Layer()
@ -84,50 +74,17 @@ namespace kiwano
void Layer::Render(RenderTarget* rt) void Layer::Render(RenderTarget* rt)
{ {
PrepareRender(rt);
rt->PushLayer(area_); rt->PushLayer(area_);
Actor::Render(rt); Actor::Render(rt);
rt->PopLayer(); rt->PopLayer();
} }
void Layer::HandleMessages(Event& evt) bool Layer::CheckVisibilty(RenderTarget* rt) const
{ {
if (evt.IsType<MouseDownEvent>()) // Do not need to render Layer
{ return false;
const auto& real_evt = evt.SafeCast<MouseDownEvent>();
OnMouseButtonDown(real_evt.button, real_evt.pos);
}
else if (evt.IsType<MouseUpEvent>())
{
const auto& real_evt = evt.SafeCast<MouseUpEvent>();
OnMouseButtonUp(real_evt.button, real_evt.pos);
}
else if (evt.IsType<MouseMoveEvent>())
{
const auto& real_evt = evt.SafeCast<MouseMoveEvent>();
OnMouseMoved(real_evt.pos);
}
else if (evt.IsType<MouseWheelEvent>())
{
const auto& real_evt = evt.SafeCast<MouseWheelEvent>();
OnMouseWheel(real_evt.wheel);
}
else if (evt.IsType<KeyDownEvent>())
{
const auto& real_evt = evt.SafeCast<KeyDownEvent>();
OnKeyDown(real_evt.code);
}
else if (evt.IsType<KeyUpEvent>())
{
const auto& real_evt = evt.SafeCast<KeyUpEvent>();
OnKeyUp(real_evt.code);
}
else if (evt.IsType<KeyCharEvent>())
{
const auto& real_evt = evt.SafeCast<KeyCharEvent>();
OnChar(real_evt.value);
}
} }
} }

View File

@ -82,48 +82,12 @@ namespace kiwano
/// @brief 获取图层区域 /// @brief 获取图层区域
LayerArea const& GetArea() const; LayerArea const& GetArea() const;
/// \~chinese
/// @brief 重载该函数以处理鼠标按下消息
/// @param btn 鼠标按键键值
/// @param pos 鼠标位置
virtual void OnMouseButtonDown(MouseButton::Value btn, Point const& pos) {}
/// \~chinese
/// @brief 重载该函数以处理鼠标抬起消息
/// @param btn 鼠标按键键值
/// @param pos 鼠标位置
virtual void OnMouseButtonUp(MouseButton::Value btn, Point const& pos) {}
/// \~chinese
/// @brief 重载该函数以处理鼠标移动消息
/// @param pos 鼠标位置
virtual void OnMouseMoved(Point const& pos) {}
/// \~chinese
/// @brief 重载该函数以处理鼠标滚轮消息
virtual void OnMouseWheel(float wheel) {}
/// \~chinese
/// @brief 重载该函数以处理键盘按键按下消息
/// @param key 键盘按键键值
virtual void OnKeyDown(KeyCode::Value key) {}
/// \~chinese
/// @brief 重载该函数以处理键盘按键抬起消息
/// @param key 键盘按键键值
virtual void OnKeyUp(KeyCode::Value key) {}
/// \~chinese
/// @brief 重载该函数以处理键盘字符消息
/// @param c 字符
virtual void OnChar(char c) {}
void Dispatch(Event& evt) override; void Dispatch(Event& evt) override;
protected: protected:
void Render(RenderTarget* rt) override; void Render(RenderTarget* rt) override;
void HandleMessages(Event& evt); bool CheckVisibilty(RenderTarget* rt) const override;
private: private:
bool swallow_; bool swallow_;

View File

@ -25,19 +25,11 @@
namespace kiwano namespace kiwano
{ {
ShapeActor::ShapeActor() ShapeActor::ShapeActor()
: fill_color_(Color::White) : stroke_width_(1.f)
, stroke_color_(Color(Color::Black, 0))
, stroke_width_(1.f)
, stroke_style_(StrokeStyle::Miter) , stroke_style_(StrokeStyle::Miter)
{ {
} }
ShapeActor::ShapeActor(Geometry const& geometry)
: ShapeActor()
{
SetGeometry(geometry);
}
ShapeActor::~ShapeActor() ShapeActor::~ShapeActor()
{ {
} }
@ -60,16 +52,6 @@ namespace kiwano
return geo_.ContainsPoint(point, GetTransformMatrix()); return geo_.ContainsPoint(point, GetTransformMatrix());
} }
void ShapeActor::SetFillColor(const Color & color)
{
fill_color_ = color;
}
void ShapeActor::SetStrokeColor(const Color & color)
{
stroke_color_ = color;
}
void ShapeActor::SetStrokeWidth(float width) void ShapeActor::SetStrokeWidth(float width)
{ {
stroke_width_ = std::max(width, 0.f); stroke_width_ = std::max(width, 0.f);
@ -97,22 +79,29 @@ namespace kiwano
void ShapeActor::OnRender(RenderTarget* rt) void ShapeActor::OnRender(RenderTarget* rt)
{ {
if (geo_.IsValid() && CheckVisibilty(rt)) // Create default brush
if (!fill_brush_)
{ {
PrepareRender(rt); fill_brush_ = new Brush;
fill_brush_->SetColor(Color::White);
rt->SetDefaultBrushColor(stroke_color_);
rt->DrawGeometry(
geo_,
stroke_width_ * 2, // twice width for widening
stroke_style_
);
rt->SetDefaultBrushColor(fill_color_);
rt->FillGeometry(
geo_
);
} }
if (!stroke_brush_)
{
stroke_brush_ = new Brush;
stroke_brush_->SetColor(Color::Transparent);
}
rt->SetCurrentBrush(stroke_brush_);
rt->DrawGeometry(geo_, stroke_width_ * 2 /* twice width for widening */, stroke_style_);
rt->SetCurrentBrush(fill_brush_);
rt->FillGeometry(geo_);
}
bool ShapeActor::CheckVisibilty(RenderTarget* rt) const
{
return geo_.IsValid() && Actor::CheckVisibilty(rt);
} }
//------------------------------------------------------- //-------------------------------------------------------
@ -123,11 +112,6 @@ namespace kiwano
{ {
} }
LineActor::LineActor(Point const& begin, Point const& end)
{
SetLine(begin, end);
}
LineActor::~LineActor() LineActor::~LineActor()
{ {
} }
@ -151,11 +135,6 @@ namespace kiwano
{ {
} }
RectActor::RectActor(Size const& size)
{
SetRectSize(size);
}
RectActor::~RectActor() RectActor::~RectActor()
{ {
} }
@ -178,11 +157,6 @@ namespace kiwano
{ {
} }
RoundRectActor::RoundRectActor(Size const& size, Vec2 const& radius)
{
SetRoundedRect(size, radius);
}
RoundRectActor::~RoundRectActor() RoundRectActor::~RoundRectActor()
{ {
} }
@ -217,11 +191,6 @@ namespace kiwano
{ {
} }
CircleActor::CircleActor(float radius)
{
SetRadius(radius);
}
CircleActor::~CircleActor() CircleActor::~CircleActor()
{ {
} }
@ -244,11 +213,6 @@ namespace kiwano
{ {
} }
EllipseActor::EllipseActor(Vec2 const& radius)
{
SetRadius(radius);
}
EllipseActor::~EllipseActor() EllipseActor::~EllipseActor()
{ {
} }
@ -271,11 +235,6 @@ namespace kiwano
{ {
} }
PolygonActor::PolygonActor(Vector<Point> const& points)
{
SetVertices(points);
}
PolygonActor::~PolygonActor() PolygonActor::~PolygonActor()
{ {
} }
@ -296,23 +255,23 @@ namespace kiwano
//------------------------------------------------------- //-------------------------------------------------------
// PathActor // PathShapeActor
//------------------------------------------------------- //-------------------------------------------------------
PathActor::PathActor() PathShapeActor::PathShapeActor()
{ {
} }
PathActor::~PathActor() PathShapeActor::~PathShapeActor()
{ {
} }
void PathActor::BeginPath(Point const& begin_pos) void PathShapeActor::BeginPath(Point const& begin_pos)
{ {
sink_.BeginPath(begin_pos); sink_.BeginPath(begin_pos);
} }
void PathActor::EndPath(bool closed) void PathShapeActor::EndPath(bool closed)
{ {
sink_.EndPath(closed); sink_.EndPath(closed);
Geometry geo = sink_.GetGeometry(); Geometry geo = sink_.GetGeometry();
@ -323,27 +282,27 @@ namespace kiwano
} }
} }
void PathActor::AddLine(Point const& point) void PathShapeActor::AddLine(Point const& point)
{ {
sink_.AddLine(point); sink_.AddLine(point);
} }
void PathActor::AddLines(Vector<Point> const& points) void PathShapeActor::AddLines(Vector<Point> const& points)
{ {
sink_.AddLines(points); sink_.AddLines(points);
} }
void PathActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) void PathShapeActor::AddBezier(Point const& point1, Point const& point2, Point const& point3)
{ {
sink_.AddBezier(point1, point2, point3); sink_.AddBezier(point1, point2, point3);
} }
void PathActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) void PathShapeActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small)
{ {
sink_.AddArc(point, radius, rotation, clockwise, is_small); sink_.AddArc(point, radius, rotation, clockwise, is_small);
} }
void PathActor::ClearPath() void PathShapeActor::ClearPath()
{ {
SetGeometry(Geometry()); SetGeometry(Geometry());
} }

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Brush.h>
#include <kiwano/renderer/Geometry.h> #include <kiwano/renderer/Geometry.h>
#include <kiwano/renderer/StrokeStyle.h> #include <kiwano/renderer/StrokeStyle.h>
@ -32,7 +33,7 @@ namespace kiwano
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(PolygonActor);
KGE_DECLARE_SMART_PTR(PathActor); KGE_DECLARE_SMART_PTR(PathShapeActor);
/** /**
* \addtogroup Actors * \addtogroup Actors
@ -41,25 +42,25 @@ namespace kiwano
/** /**
* \~chinese * \~chinese
* @brief * @brief þάÐÎ×´½ÇÉ«
*/ */
class KGE_API ShapeActor class KGE_API ShapeActor
: public Actor : public Actor
{ {
public: public:
/// \~chinese
/// @brief ¹¹Ôì¶þάÐÎ×´½ÇÉ«
ShapeActor(); ShapeActor();
ShapeActor(Geometry const& geometry);
virtual ~ShapeActor(); virtual ~ShapeActor();
/// \~chinese /// \~chinese
/// @brief 获取填充颜色 /// @brief »ñÈ¡Ìî³ä»­Ë¢
Color GetFillColor() const; BrushPtr GetFillBrush() const;
/// \~chinese /// \~chinese
/// @brief 获取线条颜色 /// @brief »ñÈ¡ÂÖÀª»­Ë¢
Color GetStrokeColor() const; BrushPtr GetStrokeBrush() const;
/// \~chinese /// \~chinese
/// @brief 获取线条宽度 /// @brief 获取线条宽度
@ -87,11 +88,23 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 设置填充颜色 /// @brief 设置填充颜色
void SetFillColor(const Color& color); /// @param color Ìî³äÑÕÉ«
void SetFillColor(Color const& color);
/// \~chinese /// \~chinese
/// @brief 设置线条颜色 /// @brief ÉèÖÃÌî³ä»­Ë¢
void SetStrokeColor(const Color& color); /// @param[in] brush Ìî³ä»­Ë¢
void SetFillBrush(BrushPtr brush);
/// \~chinese
/// @brief ÉèÖÃÂÖÀªÑÕÉ«
/// @param color ÂÖÀªÑÕÉ«
void SetStrokeColor(Color const& color);
/// \~chinese
/// @brief ÉèÖÃÂÖÀª»­Ë¢
/// @param[in] brush ÂÖÀª»­Ë¢
void SetStrokeBrush(BrushPtr brush);
/// \~chinese /// \~chinese
/// @brief 设置线条宽度,默认为 1.0 /// @brief 设置线条宽度,默认为 1.0
@ -107,9 +120,12 @@ namespace kiwano
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
private: private:
Color fill_color_; BrushPtr fill_brush_;
Color stroke_color_; BrushPtr stroke_brush_;
float stroke_width_; float stroke_width_;
StrokeStyle stroke_style_; StrokeStyle stroke_style_;
Rect bounds_; Rect bounds_;
@ -125,12 +141,6 @@ namespace kiwano
public: public:
LineActor(); LineActor();
/// \~chinese
/// @brief 线段图形角色
/// @param begin 线段起点
/// @param end 线段终点
LineActor(Point const& begin, Point const& end);
virtual ~LineActor(); virtual ~LineActor();
/// \~chinese /// \~chinese
@ -171,11 +181,6 @@ namespace kiwano
public: public:
RectActor(); RectActor();
/// \~chinese
/// @brief 构造矩形角色
/// @param size 矩形大小
RectActor(Size const& size);
virtual ~RectActor(); virtual ~RectActor();
/// \~chinese /// \~chinese
@ -201,12 +206,6 @@ namespace kiwano
public: public:
RoundRectActor(); RoundRectActor();
/// \~chinese
/// @brief 构造圆角矩形角色
/// @param size 圆角矩形大小
/// @param radius 圆角半径
RoundRectActor(Size const& size, Vec2 const& radius);
virtual ~RoundRectActor(); virtual ~RoundRectActor();
/// \~chinese /// \~chinese
@ -247,11 +246,6 @@ namespace kiwano
public: public:
CircleActor(); CircleActor();
/// \~chinese
/// @brief 构造圆形角色
/// @param radius 圆形半径
CircleActor(float radius);
virtual ~CircleActor(); virtual ~CircleActor();
/// \~chinese /// \~chinese
@ -276,11 +270,6 @@ namespace kiwano
public: public:
EllipseActor(); EllipseActor();
/// \~chinese
/// @brief 构造椭圆角色
/// @param radius 椭圆半径
EllipseActor(Vec2 const& radius);
virtual ~EllipseActor(); virtual ~EllipseActor();
/// \~chinese /// \~chinese
@ -305,11 +294,6 @@ namespace kiwano
public: public:
PolygonActor(); PolygonActor();
/// \~chinese
/// @brief 构造多边形角色
/// @param points 多边形端点集合
PolygonActor(Vector<Point> const& points);
virtual ~PolygonActor(); virtual ~PolygonActor();
/// \~chinese /// \~chinese
@ -321,13 +305,13 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 路径图形角色 /// @brief 路径图形角色
class KGE_API PathActor class KGE_API PathShapeActor
: public ShapeActor : public ShapeActor
{ {
public: public:
PathActor(); PathShapeActor();
virtual ~PathActor(); virtual ~PathShapeActor();
/// \~chinese /// \~chinese
/// @brief 开始添加路径 /// @brief 开始添加路径
@ -375,9 +359,28 @@ namespace kiwano
/** @} */ /** @} */
inline void ShapeActor::SetStrokeColor(Color const& color)
{
if (!stroke_brush_)
{
stroke_brush_ = new Brush;
}
stroke_brush_->SetColor(color);
}
inline Color ShapeActor::GetFillColor() const { return fill_color_; } inline void ShapeActor::SetFillColor(Color const& color)
inline Color ShapeActor::GetStrokeColor() const { return stroke_color_; } {
if (!fill_brush_)
{
fill_brush_ = new Brush;
}
fill_brush_->SetColor(color);
}
inline void ShapeActor::SetFillBrush(BrushPtr brush) { fill_brush_ = brush; }
inline void ShapeActor::SetStrokeBrush(BrushPtr brush) { stroke_brush_ = brush; }
inline BrushPtr ShapeActor::GetFillBrush() const { return fill_brush_; }
inline BrushPtr ShapeActor::GetStrokeBrush() const { return stroke_brush_; }
inline float ShapeActor::GetStrokeWidth() const { return stroke_width_; } inline float ShapeActor::GetStrokeWidth() const { return stroke_width_; }
inline StrokeStyle ShapeActor::SetStrokeStyle() const { return stroke_style_; } inline StrokeStyle ShapeActor::SetStrokeStyle() const { return stroke_style_; }
inline Geometry ShapeActor::GetGeometry() const { return geo_; } inline Geometry ShapeActor::GetGeometry() const { return geo_; }

View File

@ -27,34 +27,6 @@ namespace kiwano
{ {
} }
Sprite::Sprite(String const& file_path)
{
Load(file_path);
}
Sprite::Sprite(String const& file_path, Rect const& crop_rect)
{
Load(file_path);
SetCropRect(crop_rect);
}
Sprite::Sprite(Resource const& res)
{
Load(res);
}
Sprite::Sprite(Resource const& res, const Rect& crop_rect)
{
Load(res);
SetCropRect(crop_rect);
}
Sprite::Sprite(FramePtr frame)
: frame_(nullptr)
{
SetFrame(frame);
}
Sprite::~Sprite() Sprite::~Sprite()
{ {
} }
@ -104,11 +76,11 @@ namespace kiwano
void Sprite::OnRender(RenderTarget* rt) void Sprite::OnRender(RenderTarget* rt)
{ {
if (frame_ && CheckVisibilty(rt)) rt->DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds(), GetDisplayedOpacity());
{ }
PrepareRender(rt);
rt->DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds()); bool Sprite::CheckVisibilty(RenderTarget* rt) const
} {
return frame_ && frame_->IsValid() && Actor::CheckVisibilty(rt);
} }
} }

View File

@ -41,33 +41,6 @@ namespace kiwano
public: public:
Sprite(); Sprite();
/// \~chinese
/// @brief 从本地图片构造精灵
/// @param file_path 本地图片路径
explicit Sprite(String const& file_path);
/// \~chinese
/// @brief 从图片资源构造精灵
/// @param res 图片资源
explicit Sprite(Resource const& res);
/// \~chinese
/// @brief 从图像帧构造精灵
/// @param[in] frame 图像帧
explicit Sprite(FramePtr frame);
/// \~chinese
/// @brief 从本地图片构造精灵并裁剪
/// @param file_path 本地图片路径
/// @param crop_rect 裁剪矩形
Sprite(String const& file_path, Rect const& crop_rect);
/// \~chinese
/// @brief 从图片资源构造精灵并裁剪
/// @param res 图片资源
/// @param crop_rect 裁剪矩形
Sprite(Resource const& res, Rect const& crop_rect);
virtual ~Sprite(); virtual ~Sprite();
/// \~chinese /// \~chinese
@ -96,6 +69,9 @@ namespace kiwano
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
private: private:
FramePtr frame_; FramePtr frame_;
}; };

View File

@ -46,4 +46,21 @@ namespace kiwano
// KGE_SYS_LOG(L"Stage exited"); // KGE_SYS_LOG(L"Stage exited");
} }
void Stage::RenderBorder(RenderTarget* rt)
{
if (!border_fill_brush_)
{
border_fill_brush_ = new Brush;
border_fill_brush_->SetColor(Color(Color::Red, .4f));
}
if (!border_stroke_brush_)
{
border_stroke_brush_ = new Brush;
border_stroke_brush_->SetColor(Color(Color::Red, .8f));
}
Actor::RenderBorder(rt);
}
} }

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Brush.h>
namespace kiwano namespace kiwano
{ {
@ -56,8 +57,51 @@ namespace kiwano
/// @brief 退出舞台时 /// @brief 退出舞台时
/// @details 重载该函数以处理退出舞台前的行为 /// @details 重载该函数以处理退出舞台前的行为
virtual void OnExit(); virtual void OnExit();
/// \~chinese
/// @brief »ñÈ¡½ÇÉ«±ß½çÌî³ä»­Ë¢
BrushPtr GetBorderFillBrush() const;
/// \~chinese
/// @brief »ñÈ¡½ÇÉ«±ß½çÂÖÀª»­Ë¢
BrushPtr GetBorderStrokeBrush() const;
/// \~chinese
/// @brief ÉèÖýÇÉ«±ß½çÌî³ä»­Ë¢
void SetBorderFillBrush(BrushPtr brush);
/// \~chinese
/// @brief ÉèÖýÇÉ«±ß½çÂÖÀª»­Ë¢
void SetBorderStrokeBrush(BrushPtr brush);
protected:
void RenderBorder(RenderTarget* rt) override;
private:
BrushPtr border_fill_brush_;
BrushPtr border_stroke_brush_;
}; };
/** @} */ /** @} */
inline BrushPtr Stage::GetBorderFillBrush() const
{
return border_fill_brush_;
}
inline BrushPtr Stage::GetBorderStrokeBrush() const
{
return border_stroke_brush_;
}
inline void Stage::SetBorderFillBrush(BrushPtr brush)
{
border_fill_brush_ = brush;
}
inline void Stage::SetBorderStrokeBrush(BrushPtr brush)
{
border_stroke_brush_ = brush;
}
} }

View File

@ -56,16 +56,10 @@ namespace kiwano
void TextActor::OnRender(RenderTarget* rt) void TextActor::OnRender(RenderTarget* rt)
{ {
UpdateLayout();
if (text_layout_.IsValid() && CheckVisibilty(rt))
{
PrepareRender(rt);
rt->DrawTextLayout(text_layout_); rt->DrawTextLayout(text_layout_);
} }
}
void TextActor::UpdateLayout() void TextActor::OnUpdate(Duration dt)
{ {
if (text_layout_.IsDirty()) if (text_layout_.IsDirty())
{ {
@ -73,4 +67,9 @@ namespace kiwano
SetSize(text_layout_.GetLayoutSize()); SetSize(text_layout_.GetLayoutSize());
} }
} }
bool TextActor::CheckVisibilty(RenderTarget* rt) const
{
return text_layout_.IsValid() && Actor::CheckVisibilty(rt);
}
} }

View File

@ -98,8 +98,12 @@ namespace kiwano
void SetFontWeight(uint32_t weight); void SetFontWeight(uint32_t weight);
/// \~chinese /// \~chinese
/// @brief 设置文字颜色(默认值为 Color::White /// @brief 设置文字填充画刷
void SetColor(Color const& color); void SetFillBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置文字填充颜色(默认值为 Color::White
void SetFillColor(Color const& color);
/// \~chinese /// \~chinese
/// @brief 设置文字斜体(默认值为 false /// @brief 设置文字斜体(默认值为 false
@ -118,19 +122,19 @@ namespace kiwano
void SetAlignment(TextAlign align); void SetAlignment(TextAlign align);
/// \~chinese /// \~chinese
/// @brief 设置是否显示描边 /// @brief 设置文字描边画刷
void SetOutline(bool enable); void SetOutlineBrush(BrushPtr brush);
/// \~chinese /// \~chinese
/// @brief 设置描边颜色 /// @brief 设置文字描边颜色
void SetOutlineColor(Color const& outline_color); void SetOutlineColor(Color const& outline_color);
/// \~chinese /// \~chinese
/// @brief 设置描边线宽 /// @brief 设置文字描边线宽
void SetOutlineWidth(float outline_width); void SetOutlineWidth(float outline_width);
/// \~chinese /// \~chinese
/// @brief 设置描边线相交样式 /// @brief 设置文字描边线相交样式
void SetOutlineStroke(StrokeStyle outline_stroke); void SetOutlineStroke(StrokeStyle outline_stroke);
/// \~chinese /// \~chinese
@ -141,16 +145,17 @@ namespace kiwano
/// @brief 设置是否显示删除线(默认值为 false /// @brief 设置是否显示删除线(默认值为 false
void SetStrikethrough(bool enable); void SetStrikethrough(bool enable);
/// \~chinese
/// @brief 更新文本布局
void UpdateLayout();
/// \~chinese /// \~chinese
/// @brief 设置默认文字样式 /// @brief 设置默认文字样式
static void SetDefaultStyle(TextStyle const& style); static void SetDefaultStyle(TextStyle const& style);
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
void OnUpdate(Duration dt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
private: private:
TextLayout text_layout_; TextLayout text_layout_;
}; };
@ -237,14 +242,19 @@ namespace kiwano
text_layout_.SetStrikethrough(enable, 0, text_layout_.GetText().length()); text_layout_.SetStrikethrough(enable, 0, text_layout_.GetText().length());
} }
inline void TextActor::SetColor(Color const& color) inline void TextActor::SetFillBrush(BrushPtr brush)
{ {
text_layout_.SetColor(color); text_layout_.SetFillBrush(brush);
} }
inline void TextActor::SetOutline(bool enable) inline void TextActor::SetFillColor(Color const& color)
{ {
text_layout_.SetOutline(enable); text_layout_.SetFillColor(color);
}
inline void TextActor::SetOutlineBrush(BrushPtr brush)
{
text_layout_.SetOutlineBrush(brush);
} }
inline void TextActor::SetOutlineColor(Color const& outline_color) inline void TextActor::SetOutlineColor(Color const& outline_color)

View File

@ -95,7 +95,7 @@ namespace kiwano
{ {
if (out_stage_) if (out_stage_)
{ {
out_stage_->PrepareRender(rt); out_stage_->PrepareToRender(rt);
rt->PushClipRect(Rect{ Point{}, window_size_ }); rt->PushClipRect(Rect{ Point{}, window_size_ });
rt->PushLayer(out_layer_); rt->PushLayer(out_layer_);
@ -107,7 +107,7 @@ namespace kiwano
if (in_stage_) if (in_stage_)
{ {
in_stage_->PrepareRender(rt); in_stage_->PrepareToRender(rt);
rt->PushClipRect(Rect{ Point{}, window_size_ }); rt->PushClipRect(Rect{ Point{}, window_size_ });
rt->PushLayer(in_layer_); rt->PushLayer(in_layer_);

View File

@ -167,7 +167,6 @@ namespace kiwano
if (render_border_enabled_) if (render_border_enabled_)
{ {
rt->SetOpacity(1.f);
if (current_stage_) if (current_stage_)
{ {
current_stage_->RenderBorder(rt); current_stage_->RenderBorder(rt);

View File

@ -24,8 +24,15 @@
namespace kiwano namespace kiwano
{ {
SolidColorStyle::SolidColorStyle(Color const& color) GradientStop::GradientStop()
: color(color) : offset(0.f)
, color()
{
}
GradientStop::GradientStop(float offset, Color color)
: offset(offset)
, color(color)
{ {
} }
@ -52,41 +59,11 @@ namespace kiwano
{ {
} }
Brush::Brush(Color const& color)
: Brush()
{
SetColor(color);
}
Brush::Brush(SolidColorStyle const& style)
: Brush()
{
SetStyle(style);
}
Brush::Brush(LinearGradientStyle const& style)
: Brush()
{
SetStyle(style);
}
Brush::Brush(RadialGradientStyle const& style)
: Brush()
{
SetStyle(style);
}
bool Brush::IsValid() const bool Brush::IsValid() const
{ {
return raw_ != nullptr; return raw_ != nullptr;
} }
Brush::Brush(ComPtr<ID2D1Brush> brush)
: Brush()
{
SetBrush(brush);
}
float Brush::GetOpacity() const float Brush::GetOpacity() const
{ {
return opacity_; return opacity_;
@ -101,17 +78,17 @@ namespace kiwano
} }
} }
void Brush::SetStyle(SolidColorStyle const& style) void Brush::SetColor(Color const& color)
{ {
if (type_ == Type::SolidColor && raw_) if (type_ == Type::SolidColor && raw_)
{ {
auto solid_brush = dynamic_cast<ID2D1SolidColorBrush*>(raw_.get()); auto solid_brush = dynamic_cast<ID2D1SolidColorBrush*>(raw_.get());
KGE_ASSERT(solid_brush != nullptr); KGE_ASSERT(solid_brush != nullptr);
solid_brush->SetColor(DX::ConvertToColorF(style.color)); solid_brush->SetColor(DX::ConvertToColorF(color));
} }
else else
{ {
Renderer::instance().CreateSolidBrush(*this, style.color); Renderer::instance().CreateSolidBrush(*this, color);
type_ = Type::SolidColor; type_ = Type::SolidColor;
} }
} }
@ -128,11 +105,10 @@ namespace kiwano
type_ = Type::RadialGradient; type_ = Type::RadialGradient;
} }
void Brush::SetBrush(ComPtr<ID2D1Brush> const& brush) void Brush::SetBrush(ComPtr<ID2D1Brush> brush, Type type)
{ {
type_ = Type::Unknown; type_ = type;
raw_ = brush; raw_ = brush;
if (raw_) if (raw_)
{ {
raw_->SetOpacity(opacity_); raw_->SetOpacity(opacity_);

View File

@ -19,75 +19,61 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/ObjectBase.h>
#include <kiwano/renderer/win32/D2DDeviceResources.h> #include <kiwano/renderer/win32/D2DDeviceResources.h>
namespace kiwano namespace kiwano
{ {
// 渐变转换点 class RenderTarget;
class Renderer;
KGE_DECLARE_SMART_PTR(Brush);
/// \~chinese
/// @brief 渐变转换点
struct GradientStop struct GradientStop
{ {
float offset; float offset; ///< 偏移距离
Color color; Color color; ///< 渐变点颜色
GradientStop() : offset(0.f), color() {} GradientStop();
GradientStop(float offset, Color color) : offset(offset), color(color) {} GradientStop(float offset, Color color);
}; };
/// \~chinese
// 渐变扩充模式 /// @brief 渐变扩充模式
// 该模式用于指定画笔如何绘制正常区域外的部分 /// @details 该模式用于指定画笔如何绘制正常区域外的部分
// Clamp (夹模式): 重复绘制边界颜色
// Wrap (夹模式): 重复画笔内容
// Mirror (镜像模式): 反转画笔内容
enum class GradientExtendMode enum class GradientExtendMode
{ {
Clamp, Clamp, ///< 夹模式,重复绘制边界颜色
Wrap, Wrap, ///< 包裹模式,重复画笔内容
Mirror Mirror ///< 镜像模式,反转画笔内容
}; };
/// \~chinese
// 纯色样式 /// @brief 线性渐变样式
struct SolidColorStyle
{
Color color;
SolidColorStyle(Color const& color);
};
// 线性渐变样式
struct LinearGradientStyle struct LinearGradientStyle
{ {
Point begin; Point begin; ///< 渐变起始点
Point end; Point end; ///< 渐变终止点
Vector<GradientStop> stops; Vector<GradientStop> stops; ///< 渐变转换点集合
GradientExtendMode extend_mode; GradientExtendMode extend_mode; ///< 渐变扩充模式
LinearGradientStyle( LinearGradientStyle(Point const& begin, Point const& end, Vector<GradientStop> const& stops, GradientExtendMode extend_mode = GradientExtendMode::Clamp);
Point const& begin,
Point const& end,
Vector<GradientStop> const& stops,
GradientExtendMode extend_mode = GradientExtendMode::Clamp
);
}; };
// 径向渐变样式 /// \~chinese
/// @brief 径向渐变样式
struct RadialGradientStyle struct RadialGradientStyle
{ {
Point center; Point center; ///< 径向渐变圆心
Vec2 offset; Vec2 offset; ///< 径向渐变偏移
Vec2 radius; Vec2 radius; ///< 径向渐变半径
Vector<GradientStop> stops; Vector<GradientStop> stops; ///< 渐变转换点集合
GradientExtendMode extend_mode; GradientExtendMode extend_mode; ///< 渐变扩充模式
RadialGradientStyle( RadialGradientStyle(Point const& center, Vec2 const& offset, Vec2 const& radius, Vector<GradientStop> const& stops, GradientExtendMode extend_mode = GradientExtendMode::Clamp);
Point const& center,
Vec2 const& offset,
Vec2 const& radius,
Vector<GradientStop> const& stops,
GradientExtendMode extend_mode = GradientExtendMode::Clamp
);
}; };
/** /**
@ -95,49 +81,59 @@ namespace kiwano
* @brief ť­Ë˘ * @brief ť­Ë˘
*/ */
class KGE_API Brush class KGE_API Brush
: public ObjectBase
{ {
friend class RenderTarget;
friend class Renderer;
public: public:
/// \~chinese
/// @brief 构造默认画刷
Brush(); Brush();
Brush(Color const& color); /// \~chinese
/// @brief 是否有效
Brush(SolidColorStyle const& style);
Brush(LinearGradientStyle const& style);
Brush(RadialGradientStyle const& style);
bool IsValid() const; bool IsValid() const;
/// \~chinese
/// @brief 设置纯色画刷颜色
void SetColor(Color const& color); void SetColor(Color const& color);
void SetStyle(SolidColorStyle const& style); /// \~chinese
/// @brief 设置线性渐变样式
void SetStyle(LinearGradientStyle const& style); void SetStyle(LinearGradientStyle const& style);
/// \~chinese
/// @brief 设置径向渐变样式
void SetStyle(RadialGradientStyle const& style); void SetStyle(RadialGradientStyle const& style);
/// \~chinese
/// @brief 获取透明度
float GetOpacity() const; float GetOpacity() const;
/// \~chinese
/// @brief 设置透明度
void SetOpacity(float opacity); void SetOpacity(float opacity);
public: public:
/// \~chinese
/// @brief 画刷类型
enum class Type enum class Type
{ {
Unknown, Unknown,
SolidColor, // 纯色填充 SolidColor, ///< 纯色填充画刷
LinearGradient, // 线性渐变 LinearGradient, ///< 线性渐变画刷
RadialGradient // 径向渐变 RadialGradient ///< 径向渐变画刷
}; };
Type GetType() const { return type_; } /// \~chinese
/// @brief 获取画刷类型
Type GetType() const;
public: private:
Brush(ComPtr<ID2D1Brush> brush); void SetBrush(ComPtr<ID2D1Brush> brush, Type type);
void SetBrush(ComPtr<ID2D1Brush> const& brush); ComPtr<ID2D1Brush> GetBrush() const;
inline ComPtr<ID2D1Brush> const& GetBrush() const { return raw_; }
private: private:
Type type_; Type type_;
@ -145,9 +141,8 @@ namespace kiwano
ComPtr<ID2D1Brush> raw_; ComPtr<ID2D1Brush> raw_;
}; };
inline void Brush::SetColor(Color const& color) inline Brush::Type Brush::GetType() const { return type_; }
{
SetStyle(SolidColorStyle{ color }); inline ComPtr<ID2D1Brush> Brush::GetBrush() const { return raw_; }
}
} }

View File

@ -24,51 +24,56 @@
namespace kiwano namespace kiwano
{ {
// 颜色 /*
// * \~chinese
// 使用枚举表示颜色: Color blue = Color::Blue; * @brief
// 使用 RGB 表示一个颜色: Color red(1.0f, 0.0f, 0.0f); * @details
// 使用 RGBA 表示一个带透明度的颜色: Color not_black(1.0f, 1.0f, 1.0f, 0.5f); * 使: @code Color blue = Color::Blue; @endcode
// 使用一个 uint32_t 类型的值表示 RGB: Color black(0x000000); * 使 RGB : @code Color red = Color(1.0f, 0.0f, 0.0f); @endcode
// * 使 RGBA : @code Color not_white = Color(1.0f, 1.0f, 1.0f, 0.5f); @endcode
* 使16 RGB : @code Color black(0x000000); @endcode
*/
class KGE_API Color class KGE_API Color
{ {
public: public:
/// \~chinese
/// @brief 构造颜色
/// @details 默认颜色为 R: 0.0, G: 0.0, B: 0.0, A: 1.0
Color(); Color();
Color( /// \~chinese
float r, /// @brief 构造 RGB 颜色
float g, /// @param r 红色值,范围 0.0 - 1.0
float b /// @param g 绿色值,范围 0.0 - 1.0
); /// @param b 蓝色值,范围 0.0 - 1.0
Color(float r, float g, float b);
Color( /// \~chinese
float r, /// @brief 构造 RGBA 颜色
float g, /// @param r 红色值,范围 0.0 - 1.0
float b, /// @param g 绿色值,范围 0.0 - 1.0
float alpha /// @param b 蓝色值,范围 0.0 - 1.0
); /// @param a Alpha值范围 0.0 - 1.0
Color(float r, float g, float b, float alpha);
Color( /// \~chinese
uint32_t rgb /// @brief 构造 RGB 颜色
); /// @param rgb 使用16进制整形值表示 RGB颜色
Color(uint32_t rgb);
Color( /// \~chinese
uint32_t rgb, /// @brief 构造 RGBA 颜色
float alpha /// @param rgb 使用16进制整形值表示 RGB 颜色
); /// @param a Alpha值范围 0.0 - 1.0
Color(uint32_t rgb, float alpha);
inline bool operator== (const Color& rhs) const 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 bool operator!= (const Color& rhs) const;
{
return !((*this) == rhs);
}
public: public:
/// \~chinese
/// @brief 常见颜色枚举
enum Value : uint32_t enum Value : uint32_t
{ {
Black = 0x000000, Black = 0x000000,
@ -112,12 +117,24 @@ namespace kiwano
YellowGreen = 0x9ACD32 YellowGreen = 0x9ACD32
}; };
/// \~chinese
/// @brief 透明色
static const Color Transparent; static const Color Transparent;
public: public:
float r; float r; ///< 红色值
float g; float g; ///< 绿色值
float b; float b; ///< 蓝色值
float a; float a; ///< Alpha值
}; };
inline bool Color::operator== (const Color& rhs) const
{
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
}
inline bool Color::operator!= (const Color& rhs) const
{
return !((*this) == rhs);
}
} }

View File

@ -28,8 +28,7 @@ namespace kiwano
// //
RenderTarget::RenderTarget() RenderTarget::RenderTarget()
: opacity_(1.f) : collecting_status_(false)
, collecting_status_(false)
, fast_global_transform_(true) , fast_global_transform_(true)
, antialias_(true) , antialias_(true)
, text_antialias_(TextAntialiasMode::GrayScale) , text_antialias_(TextAntialiasMode::GrayScale)
@ -57,22 +56,12 @@ namespace kiwano
); );
} }
if (SUCCEEDED(hr))
{
default_brush_.reset();
hr = render_target_->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
D2D1::BrushProperties(),
&default_brush_
);
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
SetAntialiasMode(antialias_); SetAntialiasMode(antialias_);
SetTextAntialiasMode(text_antialias_); SetTextAntialiasMode(text_antialias_);
current_brush_ = default_brush_; current_brush_.reset();
} }
return hr; return hr;
@ -82,7 +71,6 @@ namespace kiwano
{ {
text_renderer_.reset(); text_renderer_.reset();
render_target_.reset(); render_target_.reset();
default_brush_.reset();
current_brush_.reset(); current_brush_.reset();
device_resources_.reset(); device_resources_.reset();
} }
@ -128,7 +116,7 @@ namespace kiwano
{ {
render_target_->DrawGeometry( render_target_->DrawGeometry(
geometry.GetGeometry().get(), geometry.GetGeometry().get(),
current_brush_.get(), current_brush_->GetBrush().get(),
stroke_width, stroke_width,
GetStrokeStyle(stroke).get() GetStrokeStyle(stroke).get()
); );
@ -151,7 +139,7 @@ namespace kiwano
{ {
render_target_->FillGeometry( render_target_->FillGeometry(
geometry.GetGeometry().get(), geometry.GetGeometry().get(),
current_brush_.get() current_brush_->GetBrush().get()
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -173,7 +161,7 @@ namespace kiwano
render_target_->DrawLine( render_target_->DrawLine(
DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point1),
DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point2),
current_brush_.get(), current_brush_->GetBrush().get(),
stroke_width, stroke_width,
GetStrokeStyle(stroke).get() GetStrokeStyle(stroke).get()
); );
@ -197,7 +185,7 @@ namespace kiwano
{ {
render_target_->DrawRectangle( render_target_->DrawRectangle(
DX::ConvertToRectF(rect), DX::ConvertToRectF(rect),
current_brush_.get(), current_brush_->GetBrush().get(),
stroke_width, stroke_width,
GetStrokeStyle(stroke).get() GetStrokeStyle(stroke).get()
); );
@ -220,7 +208,7 @@ namespace kiwano
{ {
render_target_->FillRectangle( render_target_->FillRectangle(
DX::ConvertToRectF(rect), DX::ConvertToRectF(rect),
current_brush_.get() current_brush_->GetBrush().get()
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -245,7 +233,7 @@ namespace kiwano
radius.x, radius.x,
radius.y radius.y
), ),
current_brush_.get(), current_brush_->GetBrush().get(),
stroke_width, stroke_width,
GetStrokeStyle(stroke).get() GetStrokeStyle(stroke).get()
); );
@ -272,7 +260,7 @@ namespace kiwano
radius.x, radius.x,
radius.y radius.y
), ),
current_brush_.get() current_brush_->GetBrush().get()
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -297,7 +285,7 @@ namespace kiwano
radius.x, radius.x,
radius.y radius.y
), ),
current_brush_.get(), current_brush_->GetBrush().get(),
stroke_width, stroke_width,
GetStrokeStyle(stroke).get() GetStrokeStyle(stroke).get()
); );
@ -324,7 +312,7 @@ namespace kiwano
radius.x, radius.x,
radius.y radius.y
), ),
current_brush_.get() current_brush_->GetBrush().get()
); );
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -333,12 +321,12 @@ namespace kiwano
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
void RenderTarget::DrawTexture(Texture const& texture, Rect const& src_rect, Rect const& dest_rect) void RenderTarget::DrawTexture(Texture const& texture, Rect const& src_rect, Rect const& dest_rect, float opacity)
{ {
DrawTexture(texture, &src_rect, &dest_rect); DrawTexture(texture, &src_rect, &dest_rect, opacity);
} }
void RenderTarget::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect) void RenderTarget::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect, float opacity)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!render_target_) if (!render_target_)
@ -355,7 +343,7 @@ namespace kiwano
render_target_->DrawBitmap( render_target_->DrawBitmap(
texture.GetBitmap().get(), texture.GetBitmap().get(),
dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr, dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
opacity_, opacity,
mode, mode,
src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr
); );
@ -377,11 +365,9 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
const TextStyle& style = layout.GetStyle(); const TextStyle& style = layout.GetStyle();
text_renderer_->SetTextStyle( text_renderer_->SetStyle(
opacity_, style.fill_brush ? style.fill_brush->GetBrush().get() : nullptr,
DX::ConvertToColorF(style.color), style.outline_brush ? style.outline_brush->GetBrush().get() : nullptr,
style.outline,
DX::ConvertToColorF(style.outline_color),
style.outline_width, style.outline_width,
GetStrokeStyle(style.outline_stroke).get() GetStrokeStyle(style.outline_stroke).get()
); );
@ -552,21 +538,6 @@ namespace kiwano
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
float RenderTarget::GetOpacity() const
{
return opacity_;
}
Brush RenderTarget::GetCurrentBrush() const
{
return Brush( current_brush_ );
}
Matrix3x2 RenderTarget::GetGlobalTransform() const
{
return global_transform_;
}
ComPtr<ID2D1StrokeStyle> RenderTarget::GetStrokeStyle(StrokeStyle style) ComPtr<ID2D1StrokeStyle> RenderTarget::GetStrokeStyle(StrokeStyle style)
{ {
switch (style) switch (style)
@ -602,11 +573,6 @@ namespace kiwano
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
void RenderTarget::SetGlobalTransform(const Matrix3x2& matrix)
{
SetGlobalTransform(&matrix);
}
void RenderTarget::SetGlobalTransform(const Matrix3x2* matrix) void RenderTarget::SetGlobalTransform(const Matrix3x2* matrix)
{ {
if (matrix) if (matrix)
@ -620,37 +586,6 @@ namespace kiwano
} }
} }
void RenderTarget::SetOpacity(float opacity)
{
HRESULT hr = S_OK;
if (!current_brush_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
if (opacity_ != opacity)
{
opacity_ = opacity;
current_brush_->SetOpacity(opacity);
}
}
ThrowIfFailed(hr);
}
void RenderTarget::SetCurrentBrush(Brush const& brush)
{
current_brush_ = brush.GetBrush();
}
void RenderTarget::SetDefaultBrushColor(Color const& color)
{
KGE_ASSERT(default_brush_);
default_brush_->SetColor(DX::ConvertToColorF(color));
}
void RenderTarget::SetAntialiasMode(bool enabled) void RenderTarget::SetAntialiasMode(bool enabled)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -737,27 +672,22 @@ namespace kiwano
{ {
} }
TexturePtr TextureRenderTarget::GetOutput() const bool TextureRenderTarget::GetOutput(Texture& texture)
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
TexturePtr output;
if (bitmap_rt_) if (bitmap_rt_)
{ {
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt = bitmap_rt_;
ComPtr<ID2D1Bitmap> bitmap; ComPtr<ID2D1Bitmap> bitmap;
hr = bitmap_rt->GetBitmap(&bitmap); hr = bitmap_rt_->GetBitmap(&bitmap);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
output = new Texture; texture.SetBitmap(bitmap);
output->SetBitmap(bitmap);
} }
} }
return SUCCEEDED(hr);
ThrowIfFailed(hr);
return output;
} }
} }

View File

@ -111,13 +111,15 @@ namespace kiwano
void DrawTexture( void DrawTexture(
Texture const& texture, Texture const& texture,
Rect const& src_rect, Rect const& src_rect,
Rect const& dest_rect Rect const& dest_rect,
float opacity = 1.0f
); );
void DrawTexture( void DrawTexture(
Texture const& texture, Texture const& texture,
const Rect* src_rect = nullptr, const Rect* src_rect = nullptr,
const Rect* dest_rect = nullptr const Rect* dest_rect = nullptr,
float opacity = 1.0f
); );
void DrawTextLayout( void DrawTextLayout(
@ -153,22 +155,12 @@ namespace kiwano
Color const& clear_color Color const& clear_color
); );
float GetOpacity() const; BrushPtr GetCurrentBrush() const;
Brush GetCurrentBrush() const;
Matrix3x2 GetGlobalTransform() const; Matrix3x2 GetGlobalTransform() const;
void SetOpacity(
float opacity
);
void SetCurrentBrush( void SetCurrentBrush(
Brush const& brush BrushPtr brush
);
void SetDefaultBrushColor(
Color const& color
); );
void SetTransform( void SetTransform(
@ -230,7 +222,6 @@ namespace kiwano
void DiscardDeviceResources(); void DiscardDeviceResources();
private: private:
float opacity_;
bool antialias_; bool antialias_;
bool fast_global_transform_; bool fast_global_transform_;
mutable bool collecting_status_; mutable bool collecting_status_;
@ -238,23 +229,28 @@ namespace kiwano
TextAntialiasMode text_antialias_; TextAntialiasMode text_antialias_;
ComPtr<ITextRenderer> text_renderer_; ComPtr<ITextRenderer> text_renderer_;
ComPtr<ID2D1RenderTarget> render_target_; ComPtr<ID2D1RenderTarget> render_target_;
ComPtr<ID2D1SolidColorBrush> default_brush_;
ComPtr<ID2D1Brush> current_brush_;
ComPtr<ID2DDeviceResources> device_resources_; ComPtr<ID2DDeviceResources> device_resources_;
BrushPtr current_brush_;
Matrix3x2 global_transform_; Matrix3x2 global_transform_;
}; };
// λͼäÖȾĿ±ê /// \~chinese
/// @brief 纹理渲染目标
/// @details 纹理渲染目标将渲染输出到一个纹理对象中
class KGE_API TextureRenderTarget class KGE_API TextureRenderTarget
: public RenderTarget : public RenderTarget
{ {
friend class Renderer; friend class Renderer;
public: public:
/// \~chinese
/// @brief 是否有效
bool IsValid() const; bool IsValid() const;
TexturePtr GetOutput() const; /// \~chinese
/// @brief 获取渲染输出
bool GetOutput(Texture& texture);
private: private:
TextureRenderTarget(); TextureRenderTarget();
@ -267,9 +263,30 @@ namespace kiwano
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt_; ComPtr<ID2D1BitmapRenderTarget> bitmap_rt_;
}; };
inline BrushPtr RenderTarget::GetCurrentBrush() const
{
return current_brush_;
}
inline Matrix3x2 RenderTarget::GetGlobalTransform() const
{
return global_transform_;
}
inline void RenderTarget::SetGlobalTransform(const Matrix3x2& matrix)
{
SetGlobalTransform(&matrix);
}
inline void RenderTarget::SetCurrentBrush(BrushPtr brush)
{
current_brush_ = brush;
}
inline bool TextureRenderTarget::IsValid() const inline bool TextureRenderTarget::IsValid() const
{ {
return !!bitmap_rt_; return bitmap_rt_ != nullptr;
} }
inline ComPtr<ID2D1BitmapRenderTarget> TextureRenderTarget::GetBitmapRenderTarget() const inline ComPtr<ID2D1BitmapRenderTarget> TextureRenderTarget::GetBitmapRenderTarget() const

View File

@ -907,7 +907,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
brush.SetBrush(output); brush.SetBrush(output, Brush::Type::SolidColor);
} }
ThrowIfFailed(hr); ThrowIfFailed(hr);
@ -946,7 +946,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
brush.SetBrush(output); brush.SetBrush(output, Brush::Type::LinearGradient);
} }
} }
} }
@ -990,7 +990,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
brush.SetBrush(output); brush.SetBrush(output, Brush::Type::RadialGradient);
} }
} }
} }

View File

@ -93,8 +93,12 @@ namespace kiwano
void SetFontWeight(uint32_t weight); void SetFontWeight(uint32_t weight);
/// \~chinese /// \~chinese
/// @brief 设置文字颜色(默认值为 Color::White /// @brief 设置文字填充画刷
void SetColor(Color const& color); void SetFillBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置文字填充颜色(默认值为 Color::White
void SetFillColor(Color const& color);
/// \~chinese /// \~chinese
/// @brief 设置文字斜体(默认值为 false /// @brief 设置文字斜体(默认值为 false
@ -113,19 +117,19 @@ namespace kiwano
void SetAlignment(TextAlign align); void SetAlignment(TextAlign align);
/// \~chinese /// \~chinese
/// @brief 设置是否显示描边 /// @brief 设置文字描边画刷
void SetOutline(bool enable); void SetOutlineBrush(BrushPtr brush);
/// \~chinese /// \~chinese
/// @brief 设置描边颜色 /// @brief 设置文字描边颜色
void SetOutlineColor(Color const& outline_color); void SetOutlineColor(Color const& outline_color);
/// \~chinese /// \~chinese
/// @brief 设置描边线宽 /// @brief 设置文字描边线宽
void SetOutlineWidth(float outline_width); void SetOutlineWidth(float outline_width);
/// \~chinese /// \~chinese
/// @brief 设置描边线相交样式 /// @brief 设置文字描边线相交样式
void SetOutlineStroke(StrokeStyle outline_stroke); void SetOutlineStroke(StrokeStyle outline_stroke);
/// \~chinese /// \~chinese
@ -197,9 +201,14 @@ namespace kiwano
return text_layout_; return text_layout_;
} }
inline void TextLayout::SetColor(Color const& color) inline void TextLayout::SetFillBrush(BrushPtr brush)
{ {
style_.color = color; style_.fill_brush = brush;
}
inline void TextLayout::SetFillColor(Color const& color)
{
style_.SetFillColor(color);
} }
inline void TextLayout::SetTextFormat(ComPtr<IDWriteTextFormat> format) inline void TextLayout::SetTextFormat(ComPtr<IDWriteTextFormat> format)
@ -212,14 +221,14 @@ namespace kiwano
text_layout_ = layout; text_layout_ = layout;
} }
inline void TextLayout::SetOutline(bool enable) inline void TextLayout::SetOutlineBrush(BrushPtr brush)
{ {
style_.outline = enable; style_.outline_brush = brush;
} }
inline void TextLayout::SetOutlineColor(Color const& outline_color) inline void TextLayout::SetOutlineColor(Color const& outline_color)
{ {
style_.outline_color = outline_color; style_.SetOutlineColor(outline_color);
} }
inline void TextLayout::SetOutlineWidth(float outline_width) inline void TextLayout::SetOutlineWidth(float outline_width)

View File

@ -20,8 +20,9 @@
#pragma once #pragma once
#include <kiwano/renderer/Color.h> #include <kiwano/renderer/Color.h>
#include <kiwano/renderer/StrokeStyle.h>
#include <kiwano/renderer/Font.h> #include <kiwano/renderer/Font.h>
#include <kiwano/renderer/Brush.h>
#include <kiwano/renderer/StrokeStyle.h>
namespace kiwano namespace kiwano
{ {
@ -68,61 +69,80 @@ namespace kiwano
float font_size; ///< 字号 float font_size; ///< 字号
uint32_t font_weight; ///< 粗细值 uint32_t font_weight; ///< 粗细值
bool italic; ///< 是否斜体 bool italic; ///< 是否斜体
Color color; ///< 颜色
TextAlign alignment; ///< 对齐方式 TextAlign alignment; ///< 对齐方式
float wrap_width; ///< 自动换行宽度 float wrap_width; ///< 自动换行宽度
float line_spacing; ///< 行间距 float line_spacing; ///< 行间距
bool outline; ///< 描边 BrushPtr fill_brush; ///< 填充画刷
Color outline_color; ///< 描边颜色 BrushPtr outline_brush; ///< 描边画刷
float outline_width; ///< 描边线宽 float outline_width; ///< 描边线宽
StrokeStyle outline_stroke; ///< 描边线相交样式 StrokeStyle outline_stroke; ///< 描边线相交样式
public: public:
/**
* \~chinese
* @brief
*/
TextStyle();
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param font
* @param font_family * @param font_family
* @param font_size * @param font_size
* @param font_weight * @param font_weight
* @param italic * @param color
* @param color
* @param alignment
* @param wrap_width
* @param line_spacing
* @param outline
* @param outline_color
* @param outline_width 线
* @param outline_stroke 线
*/ */
TextStyle( TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal, Color color = Color::White);
FontPtr font = nullptr,
const String& font_family = String(), void SetFillColor(Color const& color);
float font_size = 18,
uint32_t font_weight = FontWeight::Normal, void SetOutlineColor(Color const& color);
bool italic = false, };
Color color = Color::White,
TextAlign alignment = TextAlign::Left, inline TextStyle::TextStyle()
float wrap_width = 0.f, : font(nullptr)
float line_spacing = 0.f, , font_family()
bool outline = false, , font_size(18)
Color outline_color = Color(Color::Black, 0.5), , font_weight(FontWeight::Normal)
float outline_width = 1.f, , italic(false)
StrokeStyle outline_stroke = StrokeStyle::Round , alignment(TextAlign::Left)
) , wrap_width(0)
, line_spacing(0)
, outline_width(1.0f)
, outline_stroke(StrokeStyle::Round)
{
}
inline TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight, Color color)
: font(nullptr) : font(nullptr)
, font_family(font_family) , font_family(font_family)
, font_size(font_size) , font_size(font_size)
, font_weight(font_weight) , font_weight(font_weight)
, italic(italic) , italic(false)
, color(color) , alignment(TextAlign::Left)
, alignment(alignment) , wrap_width(0)
, wrap_width(wrap_width) , line_spacing(0)
, line_spacing(line_spacing) , outline_width(1.0f)
, outline(outline) , outline_stroke(StrokeStyle::Round)
, outline_color(outline_color) {
, outline_width(outline_width) }
, outline_stroke(outline_stroke)
{} inline void TextStyle::SetFillColor(Color const& color)
}; {
if (!fill_brush)
{
fill_brush = new Brush;
}
fill_brush->SetColor(color);
}
inline void TextStyle::SetOutlineColor(Color const& color)
{
if (!outline_brush)
{
outline_brush = new Brush;
}
outline_brush->SetColor(color);
}
} }

View File

@ -18,6 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/core/win32/ComPtr.hpp>
#include <kiwano/renderer/win32/TextRenderer.h> #include <kiwano/renderer/win32/TextRenderer.h>
namespace kiwano namespace kiwano
@ -26,21 +27,19 @@ namespace kiwano
: public ITextRenderer : public ITextRenderer
{ {
public: public:
TextRenderer( TextRenderer();
ID2D1RenderTarget* pRT
);
~TextRenderer(); ~TextRenderer();
STDMETHOD(CreateDeviceResources)(); STDMETHOD(CreateDeviceResources)(
_In_ ID2D1RenderTarget* pRT
);
STDMETHOD_(void, SetTextStyle)( STDMETHOD_(void, SetStyle)(
_In_ float opacity, _In_opt_ ID2D1Brush* pFillBrush,
_In_ CONST D2D1_COLOR_F &fillColor, _In_opt_ ID2D1Brush* pOutlineBrush,
_In_ BOOL outline, float fOutlineWidth,
_In_ CONST D2D1_COLOR_F &outlineColor, _In_opt_ ID2D1StrokeStyle* pStrokeStyle
_In_ float outlineWidth,
_In_ ID2D1StrokeStyle* outlineJoin
); );
STDMETHOD(DrawGlyphRun)( STDMETHOD(DrawGlyphRun)(
@ -104,14 +103,12 @@ namespace kiwano
private: private:
unsigned long cRefCount_; unsigned long cRefCount_;
D2D1_COLOR_F sFillColor_; float fOutlineWidth_;
D2D1_COLOR_F sOutlineColor_; ComPtr<ID2D1Factory> pFactory_;
float fOutlineWidth; ComPtr<ID2D1RenderTarget> pRT_;
BOOL bShowOutline_; ComPtr<ID2D1Brush> pFillBrush_;
ID2D1Factory* pFactory_; ComPtr<ID2D1Brush> pOutlineBrush_;
ID2D1RenderTarget* pRT_; ComPtr<ID2D1StrokeStyle> pCurrStrokeStyle_;
ID2D1SolidColorBrush* pBrush_;
ID2D1StrokeStyle* pCurrStrokeStyle_;
}; };
HRESULT ITextRenderer::Create( HRESULT ITextRenderer::Create(
@ -122,10 +119,10 @@ namespace kiwano
if (ppTextRenderer) if (ppTextRenderer)
{ {
TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer(pRT); TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer;
if (pTextRenderer) if (pTextRenderer)
{ {
hr = pTextRenderer->CreateDeviceResources(); hr = pTextRenderer->CreateDeviceResources(pRT);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -145,63 +142,46 @@ namespace kiwano
return hr; return hr;
} }
TextRenderer::TextRenderer(ID2D1RenderTarget* pRT) TextRenderer::TextRenderer()
: cRefCount_(0) : cRefCount_(0)
, pFactory_(NULL) , fOutlineWidth_(1)
, pRT_(pRT)
, pBrush_(NULL)
, sFillColor_()
, sOutlineColor_()
, fOutlineWidth(1)
, bShowOutline_(TRUE)
, pCurrStrokeStyle_(NULL)
{ {
if (pRT_) if (pRT_)
{ {
pRT_->AddRef();
pRT_->GetFactory(&pFactory_);
} }
} }
TextRenderer::~TextRenderer() TextRenderer::~TextRenderer()
{ {
DX::SafeRelease(pFactory_);
DX::SafeRelease(pRT_);
DX::SafeRelease(pBrush_);
} }
STDMETHODIMP TextRenderer::CreateDeviceResources() STDMETHODIMP TextRenderer::CreateDeviceResources(_In_ ID2D1RenderTarget* pRT)
{ {
HRESULT hr = S_OK; HRESULT hr = E_FAIL;
DX::SafeRelease(pBrush_); pFactory_.reset();
pRT_.reset();
if (pRT_) if (pRT)
{ {
hr = pRT_->CreateSolidColorBrush( pRT_ = pRT;
D2D1::ColorF(D2D1::ColorF::White), pRT_->GetFactory(&pFactory_);
&pBrush_ hr = S_OK;
);
} }
return hr; return hr;
} }
STDMETHODIMP_(void) TextRenderer::SetTextStyle( STDMETHODIMP_(void) TextRenderer::SetStyle(
_In_ float opacity, _In_opt_ ID2D1Brush* pFillBrush,
_In_ CONST D2D1_COLOR_F &fillColor, _In_opt_ ID2D1Brush* pOutlineBrush,
_In_ BOOL outline, float fOutlineWidth,
_In_ CONST D2D1_COLOR_F &outlineColor, _In_opt_ ID2D1StrokeStyle* pStrokeStyle)
_In_ float outlineWidth,
_In_ ID2D1StrokeStyle* outlineJoin)
{ {
sFillColor_ = fillColor; pFillBrush_ = pFillBrush;
bShowOutline_ = outline; pOutlineBrush_ = pOutlineBrush;
sOutlineColor_ = outlineColor; fOutlineWidth_ = fOutlineWidth;
fOutlineWidth = outlineWidth; pCurrStrokeStyle_ = pStrokeStyle;
pCurrStrokeStyle_ = outlineJoin;
if (pBrush_) pBrush_->SetOpacity(opacity);
} }
STDMETHODIMP TextRenderer::DrawGlyphRun( STDMETHODIMP TextRenderer::DrawGlyphRun(
@ -220,11 +200,11 @@ namespace kiwano
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (bShowOutline_) if (pOutlineBrush_)
{ {
ID2D1GeometrySink* pSink = NULL; ComPtr<ID2D1GeometrySink> pSink;
ID2D1PathGeometry* pPathGeometry = NULL; ComPtr<ID2D1PathGeometry> pPathGeometry;
ID2D1TransformedGeometry* pTransformedGeometry = NULL; ComPtr<ID2D1TransformedGeometry> pTransformedGeometry;
hr = pFactory_->CreatePathGeometry( hr = pFactory_->CreatePathGeometry(
&pPathGeometry &pPathGeometry
@ -246,7 +226,7 @@ namespace kiwano
glyphRun->glyphCount, glyphRun->glyphCount,
glyphRun->isSideways, glyphRun->isSideways,
glyphRun->bidiLevel % 2, glyphRun->bidiLevel % 2,
pSink pSink.get()
); );
} }
@ -266,7 +246,7 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = pFactory_->CreateTransformedGeometry( hr = pFactory_->CreateTransformedGeometry(
pPathGeometry, pPathGeometry.get(),
&matrix, &matrix,
&pTransformedGeometry &pTransformedGeometry
); );
@ -274,31 +254,23 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
pBrush_->SetColor(sOutlineColor_);
pRT_->DrawGeometry( pRT_->DrawGeometry(
pTransformedGeometry, pTransformedGeometry.get(),
pBrush_, pOutlineBrush_.get(),
fOutlineWidth * 2, // twice width for widening fOutlineWidth_ * 2, // twice width for widening
pCurrStrokeStyle_ pCurrStrokeStyle_.get()
); );
} }
} }
} }
DX::SafeRelease(pPathGeometry);
DX::SafeRelease(pSink);
DX::SafeRelease(pTransformedGeometry);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr) && pFillBrush_)
{ {
pBrush_->SetColor(sFillColor_);
pRT_->DrawGlyphRun( pRT_->DrawGlyphRun(
D2D1::Point2F(baselineOriginX, baselineOriginY), D2D1::Point2F(baselineOriginX, baselineOriginY),
glyphRun, glyphRun,
pBrush_ pFillBrush_.get()
); );
} }
return hr; return hr;
@ -323,7 +295,7 @@ namespace kiwano
underline->offset + underline->thickness underline->offset + underline->thickness
); );
ID2D1RectangleGeometry* pRectangleGeometry = NULL; ComPtr<ID2D1RectangleGeometry> pRectangleGeometry;
hr = pFactory_->CreateRectangleGeometry( hr = pFactory_->CreateRectangleGeometry(
&rect, &rect,
&pRectangleGeometry &pRectangleGeometry
@ -335,41 +307,33 @@ namespace kiwano
baselineOriginX, baselineOriginY baselineOriginX, baselineOriginY
); );
ID2D1TransformedGeometry* pTransformedGeometry = NULL; ComPtr<ID2D1TransformedGeometry> pTransformedGeometry;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = pFactory_->CreateTransformedGeometry( hr = pFactory_->CreateTransformedGeometry(
pRectangleGeometry, pRectangleGeometry.get(),
&matrix, &matrix,
&pTransformedGeometry &pTransformedGeometry
); );
} }
if (SUCCEEDED(hr) && bShowOutline_) if (SUCCEEDED(hr) && pOutlineBrush_)
{ {
pBrush_->SetColor(sOutlineColor_);
pRT_->DrawGeometry( pRT_->DrawGeometry(
pTransformedGeometry, pTransformedGeometry.get(),
pBrush_, pOutlineBrush_.get(),
fOutlineWidth * 2, fOutlineWidth_ * 2,
pCurrStrokeStyle_ pCurrStrokeStyle_.get()
); );
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
pBrush_->SetColor(sFillColor_);
pRT_->FillGeometry( pRT_->FillGeometry(
pTransformedGeometry, pTransformedGeometry.get(),
pBrush_ pFillBrush_.get()
); );
} }
DX::SafeRelease(pRectangleGeometry);
DX::SafeRelease(pTransformedGeometry);
return S_OK; return S_OK;
} }
@ -392,7 +356,7 @@ namespace kiwano
strikethrough->offset + strikethrough->thickness strikethrough->offset + strikethrough->thickness
); );
ID2D1RectangleGeometry* pRectangleGeometry = NULL; ComPtr<ID2D1RectangleGeometry> pRectangleGeometry;
hr = pFactory_->CreateRectangleGeometry( hr = pFactory_->CreateRectangleGeometry(
&rect, &rect,
&pRectangleGeometry &pRectangleGeometry
@ -404,41 +368,33 @@ namespace kiwano
baselineOriginX, baselineOriginY baselineOriginX, baselineOriginY
); );
ID2D1TransformedGeometry* pTransformedGeometry = NULL; ComPtr<ID2D1TransformedGeometry> pTransformedGeometry;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = pFactory_->CreateTransformedGeometry( hr = pFactory_->CreateTransformedGeometry(
pRectangleGeometry, pRectangleGeometry.get(),
&matrix, &matrix,
&pTransformedGeometry &pTransformedGeometry
); );
} }
if (SUCCEEDED(hr) && bShowOutline_) if (SUCCEEDED(hr) && pOutlineBrush_)
{ {
pBrush_->SetColor(sOutlineColor_);
pRT_->DrawGeometry( pRT_->DrawGeometry(
pTransformedGeometry, pTransformedGeometry.get(),
pBrush_, pOutlineBrush_.get(),
fOutlineWidth * 2, fOutlineWidth_ * 2,
pCurrStrokeStyle_ pCurrStrokeStyle_.get()
); );
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
pBrush_->SetColor(sFillColor_);
pRT_->FillGeometry( pRT_->FillGeometry(
pTransformedGeometry, pTransformedGeometry.get(),
pBrush_ pFillBrush_.get()
); );
} }
DX::SafeRelease(pRectangleGeometry);
DX::SafeRelease(pTransformedGeometry);
return S_OK; return S_OK;
} }

View File

@ -32,13 +32,11 @@ namespace kiwano
_In_ ID2D1RenderTarget* pRT _In_ ID2D1RenderTarget* pRT
); );
STDMETHOD_(void, SetTextStyle)( STDMETHOD_(void, SetStyle)(
_In_ float opacity, _In_opt_ ID2D1Brush* pFillBrush,
_In_ CONST D2D1_COLOR_F &fillColor, _In_opt_ ID2D1Brush* pOutlineBrush,
_In_ BOOL outline, float fOutlineWidth,
_In_ CONST D2D1_COLOR_F &outlineColor, _In_opt_ ID2D1StrokeStyle* pStrokeStyle
_In_ float outlineWidth,
_In_ ID2D1StrokeStyle* outlineJoin
) PURE; ) PURE;
}; };
} }

View File

@ -235,9 +235,10 @@ namespace kiwano
float dtx = 0; float dtx = 0;
for (int j = 0; j < cols; j++) for (int j = 0; j < cols; j++)
{ {
FramePtr ptr = new (std::nothrow) Frame(raw->GetTexture()); FramePtr ptr = new (std::nothrow) Frame;
if (ptr) if (ptr)
{ {
ptr->SetTexture(raw->GetTexture());
ptr->SetCropRect(Rect{ dtx, dty, dtx + width, dty + height }); ptr->SetCropRect(Rect{ dtx, dty, dtx + width, dty + height });
frames.push_back(ptr); frames.push_back(ptr);
} }