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)
{
PrepareRender(rt);
PrepareToRender(rt);
for (const auto& pipeline : pipelines_)
{
pipeline.second();

View File

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

View File

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

View File

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

View File

@ -183,11 +183,21 @@ namespace kiwano
/// @param color 填充颜色
void SetFillColor(Color const& color);
/// \~chinese
/// @brief ÉèÖÃÌî³ä»­Ë¢
/// @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
/// @brief 设置轮廓宽度
/// @param width 轮廓宽度
@ -204,17 +214,17 @@ namespace kiwano
void SetTextStyle(TextStyle const& text_style);
/// \~chinese
/// @brief 设置画笔透明度
/// @param opacity 透明度,范围 [0.0 - 1.0]
void SetBrushOpacity(float opacity);
/// @brief ÉèÖû­Ë¢
/// @param[in] brush »­Ë¢
void SetBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置画笔二维变换
/// @brief ÉèÖû­Ë¢¶þά±ä»»
/// @param transform 二维变换
void SetBrushTransform(Transform const& transform);
/// \~chinese
/// @brief 设置画笔二维变换矩阵
/// @brief ÉèÖû­Ë¢¶þά±ä»»¾ØÕó
/// @param transform 二维变换矩阵
void SetBrushTransform(Matrix3x2 const& transform);
@ -236,21 +246,17 @@ namespace kiwano
/// @brief 删除最近添加的裁剪区域
void PopClipRect();
/// \~chinese
/// @brief 获取填充颜色
Color GetFillColor() const;
/// \~chinese
/// @brief 获取轮廓颜色
Color GetStrokeColor() const;
/// \~chinese
/// @brief 获取轮廓宽度
float GetStrokeWidth() const;
/// \~chinese
/// @brief 获取画笔透明度
float GetBrushOpacity() const;
/// @brief »ñÈ¡Ìî³ä»­Ë¢
BrushPtr GetFillBrush() const;
/// \~chinese
/// @brief »ñÈ¡ÂÖÀª»­Ë¢
BrushPtr GetStrokeBrush() const;
/// \~chinese
/// @brief 导出纹理
@ -259,21 +265,70 @@ namespace kiwano
void OnRender(RenderTarget* rt) override;
private:
void InitRenderTargetAndBrushs();
void UpdateCache() const;
private:
float stroke_width_;
Color fill_color_;
Color stroke_color_;
TextStyle text_style_;
StrokeStyle stroke_style_;
GeometrySink geo_sink_;
TextureRenderTargetPtr rt_;
float stroke_width_;
TextStyle text_style_;
StrokeStyle stroke_style_;
GeometrySink geo_sink_;
BrushPtr fill_brush_;
BrushPtr stroke_brush_;
mutable bool cache_expired_;
mutable TexturePtr texture_cached_;
mutable bool cache_expired_;
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()
: background_color_(0.0f, 0.0f, 0.0f, 0.7f)
{
SetName(L"kiwano-debug-actor");
SetPosition(Point{ 10, 10 });
SetResponsible(true);
SetCascadeOpacityEnabled(true);
background_brush_->SetColor(Color(0.0f, 0.0f, 0.0f, 0.7f));
debug_text_ = new TextActor;
debug_text_->SetPosition(Point{ 10, 10 });
this->AddChild(debug_text_);
@ -75,9 +76,7 @@ namespace kiwano
void DebugActor::OnRender(RenderTarget* rt)
{
PrepareRender(rt);
rt->SetDefaultBrushColor(background_color_);
rt->SetCurrentBrush(background_brush_);
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/TextActor.h>
#include <kiwano/renderer/Color.h>
#include <kiwano/renderer/Brush.h>
namespace kiwano
{
@ -46,8 +47,11 @@ namespace kiwano
void OnUpdate(Duration dt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
private:
Color background_color_;
BrushPtr background_brush_;
TextActorPtr debug_text_;
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)
{
TexturePtr texture = TextureCache::instance().AddOrGetTexture(file_path);

View File

@ -38,54 +38,29 @@ namespace kiwano
/// @brief 构建空图像帧
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
/// @brief 加载图像
/// @param file_path 图像路径
bool Load(
String const& file_path
);
bool Load(String const& file_path);
/// \~chinese
/// @brief 加载图像
/// @param res 图像资源
bool Load(
Resource const& res
);
bool Load(Resource const& res);
/// \~chinese
/// @brief 裁剪图像帧为矩形
/// @param crop_rect 裁剪矩形定义
void SetCropRect(
Rect const& crop_rect
);
void SetCropRect(Rect const& crop_rect);
/// \~chinese
/// @brief 设置纹理
/// @param texture 纹理
void SetTexture(
TexturePtr texture
);
void SetTexture(TexturePtr texture);
/// \~chinese
/// @brief 是否有效
bool IsValid() const;
/// \~chinese
/// @brief 获取宽度
@ -116,7 +91,7 @@ namespace kiwano
Rect crop_rect_;
};
inline bool Frame::IsValid() const { return texture_ && texture_->IsValid(); }
inline float Frame::GetWidth() const { return crop_rect_.GetWidth(); }
inline float Frame::GetHeight() const { return crop_rect_.GetHeight(); }
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)
{
GifImagePtr image = TextureCache::instance().AddOrGetGifImage(file_path);
@ -91,7 +75,7 @@ namespace kiwano
{
if (frame_to_render_ && CheckVisibilty(rt))
{
PrepareRender(rt);
PrepareToRender(rt);
rt->DrawTexture(*frame_to_render_, &frame_.rect, nullptr);
}
@ -197,8 +181,12 @@ namespace kiwano
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();
}
@ -218,9 +206,10 @@ namespace kiwano
void GifSprite::SaveComposedFrame()
{
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))
{
@ -248,9 +237,9 @@ namespace kiwano
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))
{

View File

@ -51,21 +51,6 @@ namespace kiwano
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
/// @brief ¼ÓÔØGIFͼƬ
/// @param file_path GIFͼƬ·¾¶

View File

@ -27,16 +27,6 @@ namespace kiwano
Layer::Layer()
: 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()
@ -84,50 +74,17 @@ namespace kiwano
void Layer::Render(RenderTarget* rt)
{
PrepareRender(rt);
rt->PushLayer(area_);
Actor::Render(rt);
rt->PopLayer();
}
void Layer::HandleMessages(Event& evt)
bool Layer::CheckVisibilty(RenderTarget* rt) const
{
if (evt.IsType<MouseDownEvent>())
{
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);
}
// Do not need to render Layer
return false;
}
}

View File

@ -82,48 +82,12 @@ namespace kiwano
/// @brief 获取图层区域
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;
protected:
void Render(RenderTarget* rt) override;
void HandleMessages(Event& evt);
bool CheckVisibilty(RenderTarget* rt) const override;
private:
bool swallow_;

View File

@ -25,19 +25,11 @@
namespace kiwano
{
ShapeActor::ShapeActor()
: fill_color_(Color::White)
, stroke_color_(Color(Color::Black, 0))
, stroke_width_(1.f)
: stroke_width_(1.f)
, stroke_style_(StrokeStyle::Miter)
{
}
ShapeActor::ShapeActor(Geometry const& geometry)
: ShapeActor()
{
SetGeometry(geometry);
}
ShapeActor::~ShapeActor()
{
}
@ -60,16 +52,6 @@ namespace kiwano
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)
{
stroke_width_ = std::max(width, 0.f);
@ -97,22 +79,29 @@ namespace kiwano
void ShapeActor::OnRender(RenderTarget* rt)
{
if (geo_.IsValid() && CheckVisibilty(rt))
// Create default brush
if (!fill_brush_)
{
PrepareRender(rt);
rt->SetDefaultBrushColor(stroke_color_);
rt->DrawGeometry(
geo_,
stroke_width_ * 2, // twice width for widening
stroke_style_
);
rt->SetDefaultBrushColor(fill_color_);
rt->FillGeometry(
geo_
);
fill_brush_ = new Brush;
fill_brush_->SetColor(Color::White);
}
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()
{
}
@ -151,11 +135,6 @@ namespace kiwano
{
}
RectActor::RectActor(Size const& size)
{
SetRectSize(size);
}
RectActor::~RectActor()
{
}
@ -178,11 +157,6 @@ namespace kiwano
{
}
RoundRectActor::RoundRectActor(Size const& size, Vec2 const& radius)
{
SetRoundedRect(size, radius);
}
RoundRectActor::~RoundRectActor()
{
}
@ -217,11 +191,6 @@ namespace kiwano
{
}
CircleActor::CircleActor(float radius)
{
SetRadius(radius);
}
CircleActor::~CircleActor()
{
}
@ -244,11 +213,6 @@ namespace kiwano
{
}
EllipseActor::EllipseActor(Vec2 const& radius)
{
SetRadius(radius);
}
EllipseActor::~EllipseActor()
{
}
@ -271,11 +235,6 @@ namespace kiwano
{
}
PolygonActor::PolygonActor(Vector<Point> const& points)
{
SetVertices(points);
}
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);
}
void PathActor::EndPath(bool closed)
void PathShapeActor::EndPath(bool closed)
{
sink_.EndPath(closed);
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);
}
void PathActor::AddLines(Vector<Point> const& points)
void PathShapeActor::AddLines(Vector<Point> const& 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);
}
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);
}
void PathActor::ClearPath()
void PathShapeActor::ClearPath()
{
SetGeometry(Geometry());
}

View File

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

View File

@ -46,4 +46,21 @@ namespace kiwano
// 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
#include <kiwano/2d/Actor.h>
#include <kiwano/renderer/Brush.h>
namespace kiwano
{
@ -56,8 +57,51 @@ namespace kiwano
/// @brief 退出舞台时
/// @details 重载该函数以处理退出舞台前的行为
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)
{
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())
{
@ -73,4 +67,9 @@ namespace kiwano
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);
/// \~chinese
/// @brief 设置文字颜色(默认值为 Color::White
void SetColor(Color const& color);
/// @brief 设置文字填充画刷
void SetFillBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置文字填充颜色(默认值为 Color::White
void SetFillColor(Color const& color);
/// \~chinese
/// @brief 设置文字斜体(默认值为 false
@ -118,19 +122,19 @@ namespace kiwano
void SetAlignment(TextAlign align);
/// \~chinese
/// @brief 设置是否显示描边
void SetOutline(bool enable);
/// @brief 设置文字描边画刷
void SetOutlineBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置描边颜色
/// @brief 设置文字描边颜色
void SetOutlineColor(Color const& outline_color);
/// \~chinese
/// @brief 设置描边线宽
/// @brief 设置文字描边线宽
void SetOutlineWidth(float outline_width);
/// \~chinese
/// @brief 设置描边线相交样式
/// @brief 设置文字描边线相交样式
void SetOutlineStroke(StrokeStyle outline_stroke);
/// \~chinese
@ -141,16 +145,17 @@ namespace kiwano
/// @brief 设置是否显示删除线(默认值为 false
void SetStrikethrough(bool enable);
/// \~chinese
/// @brief 更新文本布局
void UpdateLayout();
/// \~chinese
/// @brief 设置默认文字样式
static void SetDefaultStyle(TextStyle const& style);
void OnRender(RenderTarget* rt) override;
void OnUpdate(Duration dt) override;
protected:
bool CheckVisibilty(RenderTarget* rt) const override;
private:
TextLayout text_layout_;
};
@ -237,14 +242,19 @@ namespace kiwano
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)

View File

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

View File

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

View File

@ -24,8 +24,15 @@
namespace kiwano
{
SolidColorStyle::SolidColorStyle(Color const& color)
: color(color)
GradientStop::GradientStop()
: 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
{
return raw_ != nullptr;
}
Brush::Brush(ComPtr<ID2D1Brush> brush)
: Brush()
{
SetBrush(brush);
}
float Brush::GetOpacity() const
{
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_)
{
auto solid_brush = dynamic_cast<ID2D1SolidColorBrush*>(raw_.get());
KGE_ASSERT(solid_brush != nullptr);
solid_brush->SetColor(DX::ConvertToColorF(style.color));
solid_brush->SetColor(DX::ConvertToColorF(color));
}
else
{
Renderer::instance().CreateSolidBrush(*this, style.color);
Renderer::instance().CreateSolidBrush(*this, color);
type_ = Type::SolidColor;
}
}
@ -128,11 +105,10 @@ namespace kiwano
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;
if (raw_)
{
raw_->SetOpacity(opacity_);

View File

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

View File

@ -24,51 +24,56 @@
namespace kiwano
{
// 颜色
//
// 使用枚举表示颜色: Color blue = Color::Blue;
// 使用 RGB 表示一个颜色: Color red(1.0f, 0.0f, 0.0f);
// 使用 RGBA 表示一个带透明度的颜色: Color not_black(1.0f, 1.0f, 1.0f, 0.5f);
// 使用一个 uint32_t 类型的值表示 RGB: Color black(0x000000);
//
/*
* \~chinese
* @brief
* @details
* 使: @code Color blue = Color::Blue; @endcode
* 使 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
{
public:
/// \~chinese
/// @brief 构造颜色
/// @details 默认颜色为 R: 0.0, G: 0.0, B: 0.0, A: 1.0
Color();
Color(
float r,
float g,
float b
);
/// \~chinese
/// @brief 构造 RGB 颜色
/// @param r 红色值,范围 0.0 - 1.0
/// @param g 绿色值,范围 0.0 - 1.0
/// @param b 蓝色值,范围 0.0 - 1.0
Color(float r, float g, float b);
Color(
float r,
float g,
float b,
float alpha
);
/// \~chinese
/// @brief 构造 RGBA 颜色
/// @param r 红色值,范围 0.0 - 1.0
/// @param g 绿色值,范围 0.0 - 1.0
/// @param b 蓝色值,范围 0.0 - 1.0
/// @param a Alpha值范围 0.0 - 1.0
Color(float r, float g, float b, float alpha);
Color(
uint32_t rgb
);
/// \~chinese
/// @brief 构造 RGB 颜色
/// @param rgb 使用16进制整形值表示 RGB颜色
Color(uint32_t rgb);
Color(
uint32_t rgb,
float alpha
);
/// \~chinese
/// @brief 构造 RGBA 颜色
/// @param rgb 使用16进制整形值表示 RGB 颜色
/// @param a Alpha值范围 0.0 - 1.0
Color(uint32_t rgb, float alpha);
inline bool operator== (const Color& rhs) const
{
return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
}
bool operator== (const Color& rhs) const;
inline bool operator!= (const Color& rhs) const
{
return !((*this) == rhs);
}
bool operator!= (const Color& rhs) const;
public:
/// \~chinese
/// @brief 常见颜色枚举
enum Value : uint32_t
{
Black = 0x000000,
@ -112,12 +117,24 @@ namespace kiwano
YellowGreen = 0x9ACD32
};
/// \~chinese
/// @brief 透明色
static const Color Transparent;
public:
float r;
float g;
float b;
float a;
float r; ///< 红色值
float g; ///< 绿色值
float b; ///< 蓝色值
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()
: opacity_(1.f)
, collecting_status_(false)
: collecting_status_(false)
, fast_global_transform_(true)
, antialias_(true)
, 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))
{
SetAntialiasMode(antialias_);
SetTextAntialiasMode(text_antialias_);
current_brush_ = default_brush_;
current_brush_.reset();
}
return hr;
@ -82,7 +71,6 @@ namespace kiwano
{
text_renderer_.reset();
render_target_.reset();
default_brush_.reset();
current_brush_.reset();
device_resources_.reset();
}
@ -128,7 +116,7 @@ namespace kiwano
{
render_target_->DrawGeometry(
geometry.GetGeometry().get(),
current_brush_.get(),
current_brush_->GetBrush().get(),
stroke_width,
GetStrokeStyle(stroke).get()
);
@ -151,7 +139,7 @@ namespace kiwano
{
render_target_->FillGeometry(
geometry.GetGeometry().get(),
current_brush_.get()
current_brush_->GetBrush().get()
);
IncreasePrimitivesCount();
@ -173,7 +161,7 @@ namespace kiwano
render_target_->DrawLine(
DX::ConvertToPoint2F(point1),
DX::ConvertToPoint2F(point2),
current_brush_.get(),
current_brush_->GetBrush().get(),
stroke_width,
GetStrokeStyle(stroke).get()
);
@ -197,7 +185,7 @@ namespace kiwano
{
render_target_->DrawRectangle(
DX::ConvertToRectF(rect),
current_brush_.get(),
current_brush_->GetBrush().get(),
stroke_width,
GetStrokeStyle(stroke).get()
);
@ -220,7 +208,7 @@ namespace kiwano
{
render_target_->FillRectangle(
DX::ConvertToRectF(rect),
current_brush_.get()
current_brush_->GetBrush().get()
);
IncreasePrimitivesCount();
@ -245,7 +233,7 @@ namespace kiwano
radius.x,
radius.y
),
current_brush_.get(),
current_brush_->GetBrush().get(),
stroke_width,
GetStrokeStyle(stroke).get()
);
@ -272,7 +260,7 @@ namespace kiwano
radius.x,
radius.y
),
current_brush_.get()
current_brush_->GetBrush().get()
);
IncreasePrimitivesCount();
@ -297,7 +285,7 @@ namespace kiwano
radius.x,
radius.y
),
current_brush_.get(),
current_brush_->GetBrush().get(),
stroke_width,
GetStrokeStyle(stroke).get()
);
@ -324,7 +312,7 @@ namespace kiwano
radius.x,
radius.y
),
current_brush_.get()
current_brush_->GetBrush().get()
);
IncreasePrimitivesCount();
@ -333,12 +321,12 @@ namespace kiwano
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;
if (!render_target_)
@ -355,7 +343,7 @@ namespace kiwano
render_target_->DrawBitmap(
texture.GetBitmap().get(),
dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
opacity_,
opacity,
mode,
src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr
);
@ -377,11 +365,9 @@ namespace kiwano
if (SUCCEEDED(hr))
{
const TextStyle& style = layout.GetStyle();
text_renderer_->SetTextStyle(
opacity_,
DX::ConvertToColorF(style.color),
style.outline,
DX::ConvertToColorF(style.outline_color),
text_renderer_->SetStyle(
style.fill_brush ? style.fill_brush->GetBrush().get() : nullptr,
style.outline_brush ? style.outline_brush->GetBrush().get() : nullptr,
style.outline_width,
GetStrokeStyle(style.outline_stroke).get()
);
@ -552,21 +538,6 @@ namespace kiwano
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)
{
switch (style)
@ -602,11 +573,6 @@ namespace kiwano
ThrowIfFailed(hr);
}
void RenderTarget::SetGlobalTransform(const Matrix3x2& matrix)
{
SetGlobalTransform(&matrix);
}
void RenderTarget::SetGlobalTransform(const Matrix3x2* 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)
{
HRESULT hr = S_OK;
@ -737,27 +672,22 @@ namespace kiwano
{
}
TexturePtr TextureRenderTarget::GetOutput() const
bool TextureRenderTarget::GetOutput(Texture& texture)
{
HRESULT hr = E_FAIL;
TexturePtr output;
if (bitmap_rt_)
{
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt = bitmap_rt_;
ComPtr<ID2D1Bitmap> bitmap;
hr = bitmap_rt->GetBitmap(&bitmap);
hr = bitmap_rt_->GetBitmap(&bitmap);
if (SUCCEEDED(hr))
{
output = new Texture;
output->SetBitmap(bitmap);
texture.SetBitmap(bitmap);
}
}
ThrowIfFailed(hr);
return output;
return SUCCEEDED(hr);
}
}

View File

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

View File

@ -907,7 +907,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
brush.SetBrush(output);
brush.SetBrush(output, Brush::Type::SolidColor);
}
ThrowIfFailed(hr);
@ -946,7 +946,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
brush.SetBrush(output);
brush.SetBrush(output, Brush::Type::LinearGradient);
}
}
}
@ -990,7 +990,7 @@ namespace kiwano
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);
/// \~chinese
/// @brief 设置文字颜色(默认值为 Color::White
void SetColor(Color const& color);
/// @brief 设置文字填充画刷
void SetFillBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置文字填充颜色(默认值为 Color::White
void SetFillColor(Color const& color);
/// \~chinese
/// @brief 设置文字斜体(默认值为 false
@ -113,19 +117,19 @@ namespace kiwano
void SetAlignment(TextAlign align);
/// \~chinese
/// @brief 设置是否显示描边
void SetOutline(bool enable);
/// @brief 设置文字描边画刷
void SetOutlineBrush(BrushPtr brush);
/// \~chinese
/// @brief 设置描边颜色
/// @brief 设置文字描边颜色
void SetOutlineColor(Color const& outline_color);
/// \~chinese
/// @brief 设置描边线宽
/// @brief 设置文字描边线宽
void SetOutlineWidth(float outline_width);
/// \~chinese
/// @brief 设置描边线相交样式
/// @brief 设置文字描边线相交样式
void SetOutlineStroke(StrokeStyle outline_stroke);
/// \~chinese
@ -197,9 +201,14 @@ namespace kiwano
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)
@ -212,14 +221,14 @@ namespace kiwano
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)
{
style_.outline_color = outline_color;
style_.SetOutlineColor(outline_color);
}
inline void TextLayout::SetOutlineWidth(float outline_width)

View File

@ -20,8 +20,9 @@
#pragma once
#include <kiwano/renderer/Color.h>
#include <kiwano/renderer/StrokeStyle.h>
#include <kiwano/renderer/Font.h>
#include <kiwano/renderer/Brush.h>
#include <kiwano/renderer/StrokeStyle.h>
namespace kiwano
{
@ -68,61 +69,80 @@ namespace kiwano
float font_size; ///< 字号
uint32_t font_weight; ///< 粗细值
bool italic; ///< 是否斜体
Color color; ///< 颜色
TextAlign alignment; ///< 对齐方式
float wrap_width; ///< 自动换行宽度
float line_spacing; ///< 行间距
bool outline; ///< 描边
Color outline_color; ///< 描边颜色
BrushPtr fill_brush; ///< 填充画刷
BrushPtr outline_brush; ///< 描边画刷
float outline_width; ///< 描边线宽
StrokeStyle outline_stroke; ///< 描边线相交样式
public:
/**
* \~chinese
* @brief
*/
TextStyle();
/**
* \~chinese
* @brief
* @param font
* @param font_family
* @param font_size
* @param font_weight
* @param italic
* @param color
* @param alignment
* @param wrap_width
* @param line_spacing
* @param outline
* @param outline_color
* @param outline_width 线
* @param outline_stroke 线
* @param color
*/
TextStyle(
FontPtr font = nullptr,
const String& font_family = String(),
float font_size = 18,
uint32_t font_weight = FontWeight::Normal,
bool italic = false,
Color color = Color::White,
TextAlign alignment = TextAlign::Left,
float wrap_width = 0.f,
float line_spacing = 0.f,
bool outline = false,
Color outline_color = Color(Color::Black, 0.5),
float outline_width = 1.f,
StrokeStyle outline_stroke = StrokeStyle::Round
)
: font(nullptr)
, font_family(font_family)
, font_size(font_size)
, font_weight(font_weight)
, italic(italic)
, color(color)
, alignment(alignment)
, wrap_width(wrap_width)
, line_spacing(line_spacing)
, outline(outline)
, outline_color(outline_color)
, outline_width(outline_width)
, outline_stroke(outline_stroke)
{}
TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal, Color color = Color::White);
void SetFillColor(Color const& color);
void SetOutlineColor(Color const& color);
};
inline TextStyle::TextStyle()
: font(nullptr)
, font_family()
, font_size(18)
, font_weight(FontWeight::Normal)
, italic(false)
, 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_family(font_family)
, font_size(font_size)
, font_weight(font_weight)
, italic(false)
, alignment(TextAlign::Left)
, wrap_width(0)
, line_spacing(0)
, outline_width(1.0f)
, outline_stroke(StrokeStyle::Round)
{
}
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
// THE SOFTWARE.
#include <kiwano/core/win32/ComPtr.hpp>
#include <kiwano/renderer/win32/TextRenderer.h>
namespace kiwano
@ -26,21 +27,19 @@ namespace kiwano
: public ITextRenderer
{
public:
TextRenderer(
ID2D1RenderTarget* pRT
);
TextRenderer();
~TextRenderer();
STDMETHOD(CreateDeviceResources)();
STDMETHOD(CreateDeviceResources)(
_In_ ID2D1RenderTarget* pRT
);
STDMETHOD_(void, SetTextStyle)(
_In_ float opacity,
_In_ CONST D2D1_COLOR_F &fillColor,
_In_ BOOL outline,
_In_ CONST D2D1_COLOR_F &outlineColor,
_In_ float outlineWidth,
_In_ ID2D1StrokeStyle* outlineJoin
STDMETHOD_(void, SetStyle)(
_In_opt_ ID2D1Brush* pFillBrush,
_In_opt_ ID2D1Brush* pOutlineBrush,
float fOutlineWidth,
_In_opt_ ID2D1StrokeStyle* pStrokeStyle
);
STDMETHOD(DrawGlyphRun)(
@ -103,15 +102,13 @@ namespace kiwano
);
private:
unsigned long cRefCount_;
D2D1_COLOR_F sFillColor_;
D2D1_COLOR_F sOutlineColor_;
float fOutlineWidth;
BOOL bShowOutline_;
ID2D1Factory* pFactory_;
ID2D1RenderTarget* pRT_;
ID2D1SolidColorBrush* pBrush_;
ID2D1StrokeStyle* pCurrStrokeStyle_;
unsigned long cRefCount_;
float fOutlineWidth_;
ComPtr<ID2D1Factory> pFactory_;
ComPtr<ID2D1RenderTarget> pRT_;
ComPtr<ID2D1Brush> pFillBrush_;
ComPtr<ID2D1Brush> pOutlineBrush_;
ComPtr<ID2D1StrokeStyle> pCurrStrokeStyle_;
};
HRESULT ITextRenderer::Create(
@ -122,10 +119,10 @@ namespace kiwano
if (ppTextRenderer)
{
TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer(pRT);
TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer;
if (pTextRenderer)
{
hr = pTextRenderer->CreateDeviceResources();
hr = pTextRenderer->CreateDeviceResources(pRT);
if (SUCCEEDED(hr))
{
@ -145,63 +142,46 @@ namespace kiwano
return hr;
}
TextRenderer::TextRenderer(ID2D1RenderTarget* pRT)
TextRenderer::TextRenderer()
: cRefCount_(0)
, pFactory_(NULL)
, pRT_(pRT)
, pBrush_(NULL)
, sFillColor_()
, sOutlineColor_()
, fOutlineWidth(1)
, bShowOutline_(TRUE)
, pCurrStrokeStyle_(NULL)
, fOutlineWidth_(1)
{
if (pRT_)
{
pRT_->AddRef();
pRT_->GetFactory(&pFactory_);
}
}
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(
D2D1::ColorF(D2D1::ColorF::White),
&pBrush_
);
pRT_ = pRT;
pRT_->GetFactory(&pFactory_);
hr = S_OK;
}
return hr;
}
STDMETHODIMP_(void) TextRenderer::SetTextStyle(
_In_ float opacity,
_In_ CONST D2D1_COLOR_F &fillColor,
_In_ BOOL outline,
_In_ CONST D2D1_COLOR_F &outlineColor,
_In_ float outlineWidth,
_In_ ID2D1StrokeStyle* outlineJoin)
STDMETHODIMP_(void) TextRenderer::SetStyle(
_In_opt_ ID2D1Brush* pFillBrush,
_In_opt_ ID2D1Brush* pOutlineBrush,
float fOutlineWidth,
_In_opt_ ID2D1StrokeStyle* pStrokeStyle)
{
sFillColor_ = fillColor;
bShowOutline_ = outline;
sOutlineColor_ = outlineColor;
fOutlineWidth = outlineWidth;
pCurrStrokeStyle_ = outlineJoin;
if (pBrush_) pBrush_->SetOpacity(opacity);
pFillBrush_ = pFillBrush;
pOutlineBrush_ = pOutlineBrush;
fOutlineWidth_ = fOutlineWidth;
pCurrStrokeStyle_ = pStrokeStyle;
}
STDMETHODIMP TextRenderer::DrawGlyphRun(
@ -220,11 +200,11 @@ namespace kiwano
HRESULT hr = S_OK;
if (bShowOutline_)
if (pOutlineBrush_)
{
ID2D1GeometrySink* pSink = NULL;
ID2D1PathGeometry* pPathGeometry = NULL;
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
ComPtr<ID2D1GeometrySink> pSink;
ComPtr<ID2D1PathGeometry> pPathGeometry;
ComPtr<ID2D1TransformedGeometry> pTransformedGeometry;
hr = pFactory_->CreatePathGeometry(
&pPathGeometry
@ -246,7 +226,7 @@ namespace kiwano
glyphRun->glyphCount,
glyphRun->isSideways,
glyphRun->bidiLevel % 2,
pSink
pSink.get()
);
}
@ -266,7 +246,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
hr = pFactory_->CreateTransformedGeometry(
pPathGeometry,
pPathGeometry.get(),
&matrix,
&pTransformedGeometry
);
@ -274,31 +254,23 @@ namespace kiwano
if (SUCCEEDED(hr))
{
pBrush_->SetColor(sOutlineColor_);
pRT_->DrawGeometry(
pTransformedGeometry,
pBrush_,
fOutlineWidth * 2, // twice width for widening
pCurrStrokeStyle_
pTransformedGeometry.get(),
pOutlineBrush_.get(),
fOutlineWidth_ * 2, // twice width for widening
pCurrStrokeStyle_.get()
);
}
}
}
DX::SafeRelease(pPathGeometry);
DX::SafeRelease(pSink);
DX::SafeRelease(pTransformedGeometry);
}
if (SUCCEEDED(hr))
if (SUCCEEDED(hr) && pFillBrush_)
{
pBrush_->SetColor(sFillColor_);
pRT_->DrawGlyphRun(
D2D1::Point2F(baselineOriginX, baselineOriginY),
glyphRun,
pBrush_
pFillBrush_.get()
);
}
return hr;
@ -323,7 +295,7 @@ namespace kiwano
underline->offset + underline->thickness
);
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
ComPtr<ID2D1RectangleGeometry> pRectangleGeometry;
hr = pFactory_->CreateRectangleGeometry(
&rect,
&pRectangleGeometry
@ -335,41 +307,33 @@ namespace kiwano
baselineOriginX, baselineOriginY
);
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
ComPtr<ID2D1TransformedGeometry> pTransformedGeometry;
if (SUCCEEDED(hr))
{
hr = pFactory_->CreateTransformedGeometry(
pRectangleGeometry,
pRectangleGeometry.get(),
&matrix,
&pTransformedGeometry
);
}
if (SUCCEEDED(hr) && bShowOutline_)
if (SUCCEEDED(hr) && pOutlineBrush_)
{
pBrush_->SetColor(sOutlineColor_);
pRT_->DrawGeometry(
pTransformedGeometry,
pBrush_,
fOutlineWidth * 2,
pCurrStrokeStyle_
pTransformedGeometry.get(),
pOutlineBrush_.get(),
fOutlineWidth_ * 2,
pCurrStrokeStyle_.get()
);
}
if (SUCCEEDED(hr))
{
pBrush_->SetColor(sFillColor_);
pRT_->FillGeometry(
pTransformedGeometry,
pBrush_
pTransformedGeometry.get(),
pFillBrush_.get()
);
}
DX::SafeRelease(pRectangleGeometry);
DX::SafeRelease(pTransformedGeometry);
return S_OK;
}
@ -392,7 +356,7 @@ namespace kiwano
strikethrough->offset + strikethrough->thickness
);
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
ComPtr<ID2D1RectangleGeometry> pRectangleGeometry;
hr = pFactory_->CreateRectangleGeometry(
&rect,
&pRectangleGeometry
@ -404,41 +368,33 @@ namespace kiwano
baselineOriginX, baselineOriginY
);
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
ComPtr<ID2D1TransformedGeometry> pTransformedGeometry;
if (SUCCEEDED(hr))
{
hr = pFactory_->CreateTransformedGeometry(
pRectangleGeometry,
pRectangleGeometry.get(),
&matrix,
&pTransformedGeometry
);
}
if (SUCCEEDED(hr) && bShowOutline_)
if (SUCCEEDED(hr) && pOutlineBrush_)
{
pBrush_->SetColor(sOutlineColor_);
pRT_->DrawGeometry(
pTransformedGeometry,
pBrush_,
fOutlineWidth * 2,
pCurrStrokeStyle_
pTransformedGeometry.get(),
pOutlineBrush_.get(),
fOutlineWidth_ * 2,
pCurrStrokeStyle_.get()
);
}
if (SUCCEEDED(hr))
{
pBrush_->SetColor(sFillColor_);
pRT_->FillGeometry(
pTransformedGeometry,
pBrush_
pTransformedGeometry.get(),
pFillBrush_.get()
);
}
DX::SafeRelease(pRectangleGeometry);
DX::SafeRelease(pTransformedGeometry);
return S_OK;
}

View File

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

View File

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