diff --git a/appveyor.yml b/appveyor.yml
index dc89cd0d..073bdfc0 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,8 +5,8 @@ skip_tags: true
# fetch repository as zip archive
shallow_clone: true
-# pull_requests:
-# do_not_increment_build_number: true
+pull_requests:
+ do_not_increment_build_number: true
# Do not build feature branch with open Pull Requests
# skip_branch_with_pr: true
@@ -47,6 +47,18 @@ only_commits:
- scripts/**/*.ps1
- appveyor.yml
+for:
+-
+ branches:
+ except:
+ - master
+ # only_commits:
+ # message: /\[build\]/
+ environment:
+ matrix:
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ VS_PLATFORM_TOOLSET: v142
+
configuration:
- Debug
- Release
@@ -67,19 +79,8 @@ build:
project: projects/Kiwano.sln
verbosity: minimal
-for:
--
- branches:
- except:
- - master
- only_commits:
- message: /\[build\]/
--
- branches:
- only:
- - master
- after_build:
- - ps: .\scripts\appveyor\wait_for_other_jobs.ps1
+after_build:
+- ps: .\scripts\appveyor\wait_for_other_jobs.ps1
artifacts:
- path: projects/output/**/*.lib
@@ -119,6 +120,6 @@ notifications:
- provider: Email
to:
- 569629550@qq.com
- on_build_success: false
+ on_build_success: true
on_build_failure: true
on_build_status_changed: false
\ No newline at end of file
diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj
index 2931f641..39a9021c 100644
--- a/projects/kiwano.vcxproj
+++ b/projects/kiwano.vcxproj
@@ -11,7 +11,6 @@
-
@@ -28,7 +27,6 @@
-
@@ -49,7 +47,7 @@
-
+
@@ -59,7 +57,7 @@
-
+
@@ -67,17 +65,24 @@
-
-
-
-
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
@@ -96,7 +101,6 @@
-
@@ -113,7 +117,7 @@
-
+
@@ -122,15 +126,22 @@
-
-
-
+
+
+
+
-
+
+
+
+
+
+
+
@@ -193,7 +204,7 @@
Level3
Disabled
true
- None
+ EditAndContinue
true
false
@@ -210,7 +221,7 @@
true
false
true
- None
+ EditAndContinue
true
false
diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters
index 1be66a3b..8995881e 100644
--- a/projects/kiwano.vcxproj.filters
+++ b/projects/kiwano.vcxproj.filters
@@ -37,6 +37,9 @@
{86e2d0f2-a9d0-4456-b6a5-d480228bbf82}
+
+ {30333461-e9bc-4709-84bd-ce6e0e1a3079}
+
@@ -48,9 +51,6 @@
2d
-
- 2d
-
2d
@@ -99,21 +99,6 @@
base
-
- renderer
-
-
- renderer
-
-
- renderer
-
-
- renderer
-
-
- renderer
-
math
@@ -143,9 +128,6 @@
-
- math
-
math
@@ -155,9 +137,6 @@
base
-
- base
-
utils
@@ -177,9 +156,6 @@
utils
-
- renderer
-
base
@@ -201,12 +177,6 @@
2d
-
- renderer
-
-
- renderer
-
2d\action
@@ -225,9 +195,6 @@
2d\action
-
- renderer
-
utils
@@ -258,9 +225,6 @@
core
-
- base
-
core
@@ -270,9 +234,6 @@
2d
-
- renderer
-
2d\action
@@ -285,9 +246,66 @@
base
+
+ math
+
+
+ base
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
renderer
+
+ renderer
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer
+
+
+ renderer
+
@@ -299,9 +317,6 @@
2d
-
- 2d
-
2d
@@ -326,18 +341,6 @@
base
-
- renderer
-
-
- renderer
-
-
- renderer
-
-
- renderer
-
platform
@@ -350,9 +353,6 @@
base
-
- base
-
utils
@@ -389,12 +389,6 @@
2d
-
- renderer
-
-
- renderer
-
2d\action
@@ -410,9 +404,6 @@
2d\action
-
- renderer
-
utils
@@ -425,9 +416,6 @@
2d
-
- renderer
-
2d\action
@@ -440,8 +428,56 @@
base
+
+ base
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
+
+ renderer
+
renderer
+
+ renderer
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer\win32
+
+
+ renderer
+
+
+ renderer
+
\ No newline at end of file
diff --git a/scripts/appveyor/wait_for_other_jobs.ps1 b/scripts/appveyor/wait_for_other_jobs.ps1
index 4a2aa2df..422b65da 100644
--- a/scripts/appveyor/wait_for_other_jobs.ps1
+++ b/scripts/appveyor/wait_for_other_jobs.ps1
@@ -1,5 +1,8 @@
. .\scripts\appveyor\appveyor_get_build.ps1
+# Ignore commits without APPVEYOR_API_TOKEN envrionment variable
+if (-not ($env:APPVEYOR_API_TOKEN)) { return }
+
# Only deploy when commit message contains "[deploy]"
if (!(Get-AppVeyorBuild).build.message.Contains('[deploy]')) { return }
diff --git a/src/kiwano-audio/src/Player.cpp b/src/kiwano-audio/src/Player.cpp
index f460a2c5..a7a862bf 100644
--- a/src/kiwano-audio/src/Player.cpp
+++ b/src/kiwano-audio/src/Player.cpp
@@ -34,13 +34,33 @@ namespace kiwano
ClearCache();
}
- bool Player::Load(Resource const& res)
+ size_t Player::Load(String const& file_path)
{
- size_t hash_code = res.GetHashCode();
+ size_t hash_code = file_path.hash();
if (sound_cache_.end() != sound_cache_.find(hash_code))
return true;
- SoundPtr sound = new (std::nothrow) Sound();
+ SoundPtr sound = new (std::nothrow) Sound;
+
+ if (sound)
+ {
+ if (sound->Load(file_path))
+ {
+ sound->SetVolume(volume_);
+ sound_cache_.insert(std::make_pair(hash_code, sound));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ size_t Player::Load(Resource const& res)
+ {
+ size_t hash_code = res.GetId();
+ if (sound_cache_.end() != sound_cache_.find(hash_code))
+ return true;
+
+ SoundPtr sound = new (std::nothrow) Sound;
if (sound)
{
@@ -54,42 +74,39 @@ namespace kiwano
return false;
}
- void Player::Play(Resource const& res, int loop_count)
+ void Player::Play(size_t id, int loop_count)
{
- if (Load(res))
- {
- size_t hash_code = res.GetHashCode();
- if (sound_cache_.end() != sound_cache_.find(hash_code))
- sound_cache_[hash_code]->Play(loop_count);
- }
+ auto iter = sound_cache_.find(id);
+ if (sound_cache_.end() != iter)
+ iter->second->Play(loop_count);
}
- void Player::Pause(Resource const& res)
+ void Player::Pause(size_t id)
{
- size_t hash_code = res.GetHashCode();
- if (sound_cache_.end() != sound_cache_.find(hash_code))
- sound_cache_[hash_code]->Pause();
+ auto iter = sound_cache_.find(id);
+ if (sound_cache_.end() != iter)
+ iter->second->Pause();
}
- void Player::Resume(Resource const& res)
+ void Player::Resume(size_t id)
{
- size_t hash_code = res.GetHashCode();
- if (sound_cache_.end() != sound_cache_.find(hash_code))
- sound_cache_[hash_code]->Resume();
+ auto iter = sound_cache_.find(id);
+ if (sound_cache_.end() != iter)
+ iter->second->Resume();
}
- void Player::Stop(Resource const& res)
+ void Player::Stop(size_t id)
{
- size_t hash_code = res.GetHashCode();
- if (sound_cache_.end() != sound_cache_.find(hash_code))
- sound_cache_[hash_code]->Stop();
+ auto iter = sound_cache_.find(id);
+ if (sound_cache_.end() != iter)
+ iter->second->Stop();
}
- bool Player::IsPlaying(Resource const& res)
+ bool Player::IsPlaying(size_t id)
{
- size_t hash_code = res.GetHashCode();
- if (sound_cache_.end() != sound_cache_.find(hash_code))
- return sound_cache_[hash_code]->IsPlaying();
+ auto iter = sound_cache_.find(id);
+ if (sound_cache_.end() != iter)
+ return iter->second->IsPlaying();
return false;
}
diff --git a/src/kiwano-audio/src/Player.h b/src/kiwano-audio/src/Player.h
index 290c7de7..8ad90766 100644
--- a/src/kiwano-audio/src/Player.h
+++ b/src/kiwano-audio/src/Player.h
@@ -20,7 +20,7 @@
#pragma once
#include
-#include
+#include
#include "Sound.h"
namespace kiwano
@@ -31,44 +31,47 @@ namespace kiwano
// 音乐播放器
class KGE_API Player
- : protected Object
+ : protected ObjectBase
{
- using MusicMap = Map;
-
public:
Player();
~Player();
- // 加载音乐资源
- bool Load(
+ // 加载本地音频文件, 返回该资源标识符
+ size_t Load(
+ String const& file_path
+ );
+
+ // 加载音乐资源, 返回该资源标识符
+ size_t Load(
Resource const& res /* 音乐资源 */
);
// 播放音乐
void Play(
- Resource const& res, /* 音乐资源 */
+ size_t id, /* 标识符 */
int loop_count = 0 /* 播放循环次数 (-1 为循环播放) */
);
// 暂停音乐
void Pause(
- Resource const& res /* 音乐资源 */
+ size_t id /* 标识符 */
);
// 继续播放音乐
void Resume(
- Resource const& res /* 音乐资源 */
+ size_t id /* 标识符 */
);
// 停止音乐
void Stop(
- Resource const& res /* 音乐资源 */
+ size_t id /* 标识符 */
);
// 获取音乐播放状态
bool IsPlaying(
- Resource const& res /* 音乐资源 */
+ size_t id /* 标识符 */
);
// 获取音量
@@ -92,8 +95,10 @@ namespace kiwano
void ClearCache();
protected:
- float volume_;
- MusicMap sound_cache_;
+ float volume_;
+
+ using MusicMap = Map;
+ MusicMap sound_cache_;
};
}
}
diff --git a/src/kiwano-audio/src/Sound.cpp b/src/kiwano-audio/src/Sound.cpp
index ddf88d6f..cf2c9c2e 100644
--- a/src/kiwano-audio/src/Sound.cpp
+++ b/src/kiwano-audio/src/Sound.cpp
@@ -49,6 +49,46 @@ namespace kiwano
Close();
}
+ bool Sound::Load(String const& file_path)
+ {
+ if (opened_)
+ {
+ Close();
+ }
+
+#if defined(KGE_DEBUG)
+ if (!FileUtil::ExistsFile(file_path))
+ {
+ KGE_WARNING_LOG(L"Media file '%s' not found", file_path.c_str());
+ return false;
+ }
+#endif
+
+ Transcoder transcoder;
+ HRESULT hr = transcoder.LoadMediaFile(file_path, &wave_data_, &size_);
+
+ if (FAILED(hr))
+ {
+ KGE_ERROR_LOG(L"Load media file failed with HRESULT of %08X", hr);
+ return false;
+ }
+
+ hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx());
+ if (FAILED(hr))
+ {
+ if (wave_data_)
+ {
+ delete[] wave_data_;
+ wave_data_ = nullptr;
+ }
+ KGE_ERROR_LOG(L"Create source voice failed with HRESULT of %08X", hr);
+ return false;
+ }
+
+ opened_ = true;
+ return true;
+ }
+
bool Sound::Load(Resource const& res)
{
if (opened_)
@@ -56,28 +96,12 @@ namespace kiwano
Close();
}
- HRESULT hr = S_OK;
Transcoder transcoder;
-
- if (res.IsFileType())
- {
-#if defined(KGE_DEBUG)
- if (!FileUtil::ExistsFile(res.GetFileName()))
- {
- KGE_WARNING_LOG(L"Media file '%s' not found", res.GetFileName().c_str());
- return false;
- }
-#endif
- hr = transcoder.LoadMediaFile(res.GetFileName(), &wave_data_, &size_);
- }
- else
- {
- hr = transcoder.LoadMediaResource(res, &wave_data_, &size_);
- }
+ HRESULT hr = transcoder.LoadMediaResource(res, &wave_data_, &size_);
if (FAILED(hr))
{
- KGE_ERROR_LOG(L"Load media file failed with HRESULT of %08X", hr);
+ KGE_ERROR_LOG(L"Load media resource failed with HRESULT of %08X", hr);
return false;
}
diff --git a/src/kiwano-audio/src/Sound.h b/src/kiwano-audio/src/Sound.h
index fa505676..d39f457f 100644
--- a/src/kiwano-audio/src/Sound.h
+++ b/src/kiwano-audio/src/Sound.h
@@ -20,7 +20,7 @@
#pragma once
#include
-#include
+#include
#include
#include
@@ -32,17 +32,26 @@ namespace kiwano
// 音乐对象
class KGE_API Sound
- : public Object
+ : public ObjectBase
{
public:
Sound();
+ Sound(
+ String const& file_path /* 本地音频文件 */
+ );
+
Sound(
Resource const& res /* 音乐资源 */
);
virtual ~Sound();
+ // 打开本地音频文件
+ bool Load(
+ String const& file_path
+ );
+
// 打开音乐资源
bool Load(
Resource const& res /* 音乐资源 */
diff --git a/src/kiwano-audio/src/Transcoder.cpp b/src/kiwano-audio/src/Transcoder.cpp
index 4d2d7baf..0e38305e 100644
--- a/src/kiwano-audio/src/Transcoder.cpp
+++ b/src/kiwano-audio/src/Transcoder.cpp
@@ -24,9 +24,9 @@
#include
#include
-#include
#include
#include
+#include
#include
#include "audio-modules.h"
#include "Transcoder.h"
@@ -83,13 +83,12 @@ namespace kiwano
ComPtr byte_stream;
ComPtr reader;
- LPVOID buffer;
- DWORD buffer_size;
- if (!res.Load(buffer, buffer_size)) { return E_FAIL; }
+ Resource::Data data = res.GetData();
+ if (!data) { return E_FAIL; }
stream = kiwano::modules::Shlwapi::Get().SHCreateMemStream(
- static_cast(buffer),
- static_cast(buffer_size)
+ static_cast(data.buffer),
+ static_cast(data.size)
);
if (stream == nullptr)
diff --git a/src/kiwano-network/src/HttpRequest.hpp b/src/kiwano-network/src/HttpRequest.hpp
index 79335b4f..5f147e57 100644
--- a/src/kiwano-network/src/HttpRequest.hpp
+++ b/src/kiwano-network/src/HttpRequest.hpp
@@ -21,7 +21,7 @@
#pragma once
#include
#include
-#include
+#include
namespace kiwano
{
@@ -30,7 +30,7 @@ namespace kiwano
typedef Function ResponseCallback;
class KGE_API HttpRequest
- : public Object
+ : public ObjectBase
{
public:
enum class Type
diff --git a/src/kiwano-network/src/HttpResponse.hpp b/src/kiwano-network/src/HttpResponse.hpp
index 094361b4..c5d35ffe 100644
--- a/src/kiwano-network/src/HttpResponse.hpp
+++ b/src/kiwano-network/src/HttpResponse.hpp
@@ -21,14 +21,14 @@
#pragma once
#include
#include
-#include
+#include
namespace kiwano
{
namespace network
{
class KGE_API HttpResponse
- : public Object
+ : public ObjectBase
{
public:
inline HttpResponse(HttpRequestPtr request)
diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp
index 2db554b4..8ef488f5 100644
--- a/src/kiwano/2d/Actor.cpp
+++ b/src/kiwano/2d/Actor.cpp
@@ -71,7 +71,7 @@ namespace kiwano
OnUpdate(dt);
}
- if (!children_.is_empty())
+ if (!children_.item_empty())
{
ActorPtr next;
for (auto child = children_.first_item(); child; child = next)
@@ -89,7 +89,7 @@ namespace kiwano
UpdateTransform();
- if (children_.is_empty())
+ if (children_.item_empty())
{
OnRender(renderer);
}
@@ -131,7 +131,7 @@ namespace kiwano
auto renderer = Renderer::GetInstance();
renderer->SetTransform(transform_matrix_);
renderer->FillRectangle(bounds, Color(Color::Red, .4f));
- renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 4.f);
+ renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 2.f);
}
for (auto child = children_.first_item(); child; child = child->next_item())
@@ -407,7 +407,7 @@ namespace kiwano
{
if (!IsName(name))
{
- Object::SetName(name);
+ ObjectBase::SetName(name);
hash_name_ = std::hash{}(name);
}
}
@@ -609,7 +609,7 @@ namespace kiwano
{
KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception");
- if (children_.is_empty())
+ if (children_.item_empty())
return;
if (child)
@@ -622,7 +622,7 @@ namespace kiwano
void Actor::RemoveChildren(String const& child_name)
{
- if (children_.is_empty())
+ if (children_.item_empty())
{
return;
}
diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h
index 55f8f105..e8764689 100644
--- a/src/kiwano/2d/Actor.h
+++ b/src/kiwano/2d/Actor.h
@@ -32,7 +32,7 @@ namespace kiwano
// 角色
class KGE_API Actor
- : public Object
+ : public ObjectBase
, public TimerManager
, public ActionManager
, public EventDispatcher
diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp
index c9f01d1b..cef8a6fb 100644
--- a/src/kiwano/2d/Canvas.cpp
+++ b/src/kiwano/2d/Canvas.cpp
@@ -27,35 +27,11 @@ namespace kiwano
Canvas::Canvas()
: cache_expired_(false)
, stroke_width_(1.0f)
+ , fill_color_(0, 0, 0)
+ , stroke_color_(Color::White)
+ , stroke_style_(StrokeStyle::Miter)
{
- auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext();
-
- ThrowIfFailed(
- ctx->CreateCompatibleRenderTarget(&render_target_)
- );
-
- ThrowIfFailed(
- render_target_->CreateSolidColorBrush(
- D2D1::ColorF(0, 0, 0, 0),
- D2D1::BrushProperties(),
- &fill_brush_)
- );
-
- ThrowIfFailed(
- render_target_->CreateSolidColorBrush(
- D2D1::ColorF(Color::White),
- D2D1::BrushProperties(),
- &stroke_brush_)
- );
-
- ThrowIfFailed(
- ITextRenderer::Create(
- &text_renderer_,
- render_target_.get()
- )
- );
-
- SetTextStyle(Font{}, TextStyle{});
+ Renderer::GetInstance()->CreateImageRenderTarget(rt_);
}
Canvas::Canvas(float width, float height)
@@ -75,45 +51,36 @@ namespace kiwano
void Canvas::BeginDraw()
{
- render_target_->BeginDraw();
+ rt_.BeginDraw();
}
void Canvas::EndDraw()
{
- ThrowIfFailed(
- render_target_->EndDraw()
- );
+ rt_.EndDraw();
cache_expired_ = true;
}
void Canvas::OnRender(Renderer* renderer)
{
- if (cache_expired_)
- {
- GetBitmap();
- }
+ UpdateCache();
- if (bitmap_cached_)
+ if (image_cached_.IsValid())
{
PrepareRender(renderer);
- Rect bitmap_rect(0.f, 0.f, bitmap_cached_->GetSize().width, bitmap_cached_->GetSize().height);
- renderer->DrawBitmap(
- bitmap_cached_,
- bitmap_rect,
- bitmap_rect
- );
+ Rect bitmap_rect(0.f, 0.f, image_cached_.GetWidth(), image_cached_.GetHeight());
+ renderer->DrawImage(image_cached_, bitmap_rect, bitmap_rect);
}
}
void Canvas::SetStrokeColor(Color const& color)
{
- stroke_brush_->SetColor(DX::ConvertToColorF(color));
+ stroke_color_ = color;
}
void Canvas::SetFillColor(Color const& color)
{
- fill_brush_->SetColor(DX::ConvertToColorF(color));
+ fill_color_ = color;
}
void Canvas::SetStrokeWidth(float width)
@@ -121,39 +88,34 @@ namespace kiwano
stroke_width_ = std::max(width, 0.f);
}
- void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join)
+ void Canvas::SetStrokeStyle(StrokeStyle stroke_style)
{
- outline_join_style_ = Renderer::GetInstance()->GetD2DDeviceResources()->GetStrokeStyle(outline_join);
+ stroke_style_ = stroke_style;
}
- void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style)
+ void Canvas::SetTextFont(Font const& font)
{
text_font_ = font;
+ }
+
+ void Canvas::SetTextStyle(TextStyle const & text_style)
+ {
text_style_ = text_style;
+ }
- text_renderer_->SetTextStyle(
- 1.f,
- DX::ConvertToColorF(text_style_.color),
- text_style_.outline,
- DX::ConvertToColorF(text_style_.outline_color),
- text_style_.outline_width,
- Renderer::GetInstance()->GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke)
- );
-
- // clear text format
- text_format_ = nullptr;
+ void Canvas::SetBrushOpacity(float opacity)
+ {
+ rt_.SetOpacity(opacity);
}
Color Canvas::GetStrokeColor() const
{
- auto color_f = stroke_brush_->GetColor();
- return Color{ color_f.r, color_f.g, color_f.b, color_f.a };
+ return stroke_color_;
}
Color Canvas::GetFillColor() const
{
- auto color_f = fill_brush_->GetColor();
- return Color{ color_f.r, color_f.g, color_f.b, color_f.a };
+ return fill_color_;
}
float Canvas::GetStrokeWidth() const
@@ -161,324 +123,219 @@ namespace kiwano
return stroke_width_;
}
+ float Canvas::GetBrushOpacity() const
+ {
+ return rt_.GetOpacity();
+ }
+
+ void Canvas::SetBrushTransform(Transform const& transform)
+ {
+ Matrix3x2 matrix = Matrix3x2::SRT(transform.position, transform.scale, transform.rotation);
+ if (!transform.skew.IsOrigin())
+ {
+ matrix = Matrix3x2::Skewing(transform.skew) * matrix;
+ }
+
+ rt_.SetTransform(matrix);
+ }
+
void Canvas::SetBrushTransform(Matrix3x2 const & transform)
{
- render_target_->SetTransform(DX::ConvertToMatrix3x2F(transform));
+ rt_.SetTransform(transform);
}
- void Canvas::DrawLine(const Point & begin, const Point & end)
+ void Canvas::DrawLine(Point const& begin, Point const& end)
{
- render_target_->DrawLine(
- D2D1::Point2F(begin.x, begin.y),
- D2D1::Point2F(end.x, end.y),
- stroke_brush_.get(),
+ rt_.DrawLine(
+ begin,
+ end,
+ stroke_color_,
stroke_width_,
- outline_join_style_.get()
+ stroke_style_
);
cache_expired_ = true;
}
- void Canvas::DrawCircle(const Point & center, float radius)
+ void Canvas::DrawCircle(Point const& center, float radius)
{
- render_target_->DrawEllipse(
- D2D1::Ellipse(
- D2D1::Point2F(
- center.x,
- center.y
- ),
- radius,
- radius
- ),
- stroke_brush_.get(),
+ rt_.DrawEllipse(
+ center,
+ Vec2(radius, radius),
+ stroke_color_,
stroke_width_,
- outline_join_style_.get()
+ stroke_style_
);
cache_expired_ = true;
}
- void Canvas::DrawEllipse(const Point & center, float radius_x, float radius_y)
+ void Canvas::DrawEllipse(Point const& center, Vec2 const& radius)
{
- render_target_->DrawEllipse(
- D2D1::Ellipse(
- D2D1::Point2F(
- center.x,
- center.y
- ),
- radius_x,
- radius_y
- ),
- stroke_brush_.get(),
+ rt_.DrawEllipse(
+ center,
+ radius,
+ stroke_color_,
stroke_width_,
- outline_join_style_.get()
+ stroke_style_
);
cache_expired_ = true;
}
- void Canvas::DrawRect(const Rect & rect)
+ void Canvas::DrawRect(Rect const& rect)
{
- render_target_->DrawRectangle(
- D2D1::RectF(
- rect.origin.x,
- rect.origin.y,
- rect.origin.x + rect.size.x,
- rect.origin.y + rect.size.y
- ),
- stroke_brush_.get(),
+ rt_.DrawRectangle(
+ rect,
+ stroke_color_,
stroke_width_,
- outline_join_style_.get()
+ stroke_style_
);
cache_expired_ = true;
}
- void Canvas::DrawRoundedRect(const Rect & rect, float radius_x, float radius_y)
+ void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius)
{
- render_target_->DrawRoundedRectangle(
- D2D1::RoundedRect(
- D2D1::RectF(
- rect.origin.x,
- rect.origin.y,
- rect.origin.x + rect.size.x,
- rect.origin.y + rect.size.y
- ),
- radius_x,
- radius_y
- ),
- stroke_brush_.get(),
+ rt_.DrawRoundedRectangle(
+ rect,
+ radius,
+ stroke_color_,
stroke_width_,
- outline_join_style_.get()
+ stroke_style_
);
cache_expired_ = true;
}
- void Canvas::DrawImage(ImagePtr image, float opacity)
+ void Canvas::FillCircle(Point const& center, float radius)
{
- if (image && image->GetBitmap())
+ rt_.FillEllipse(
+ center,
+ Vec2(radius, radius),
+ fill_color_
+ );
+ cache_expired_ = true;
+ }
+
+ void Canvas::FillEllipse(Point const& center, Vec2 const& radius)
+ {
+ rt_.FillEllipse(
+ center,
+ radius,
+ fill_color_
+ );
+ cache_expired_ = true;
+ }
+
+ void Canvas::FillRect(Rect const& rect)
+ {
+ rt_.FillRectangle(
+ rect,
+ fill_color_
+ );
+ cache_expired_ = true;
+ }
+
+ void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius)
+ {
+ rt_.FillRoundedRectangle(
+ rect,
+ radius,
+ fill_color_
+ );
+ cache_expired_ = true;
+ }
+
+ void Canvas::DrawImage(Image const& image, const Rect* src_rect, const Rect* dest_rect)
+ {
+ if (image.IsValid())
{
- render_target_->DrawBitmap(
- image->GetBitmap().get(),
- D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()),
- opacity,
- D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
- D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight())
- );
+ rt_.DrawImage(image, src_rect, dest_rect);
cache_expired_ = true;
}
}
- void Canvas::DrawText(String const & text, Point const & point)
+ void Canvas::DrawText(String const& text, Point const& point)
{
if (text.empty())
return;
- if (!text_format_)
- {
- ThrowIfFailed(
- Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextFormat(
- text_format_,
- text_font_,
- text_style_
- )
- );
- }
+ TextLayout layout(text, text_font_, text_style_);
- ComPtr text_layout;
- Size layout_size;
- ThrowIfFailed(
- Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextLayout(
- text_layout,
- layout_size,
- text,
- text_format_,
- text_style_
- )
- );
-
- ThrowIfFailed(
- text_layout->Draw(nullptr, text_renderer_.get(), point.x, point.y)
- );
- }
-
- void Canvas::FillCircle(const Point & center, float radius)
- {
- render_target_->FillEllipse(
- D2D1::Ellipse(
- D2D1::Point2F(
- center.x,
- center.y
- ),
- radius,
- radius
- ),
- fill_brush_.get()
- );
- cache_expired_ = true;
- }
-
- void Canvas::FillEllipse(const Point & center, float radius_x, float radius_y)
- {
- render_target_->FillEllipse(
- D2D1::Ellipse(
- D2D1::Point2F(
- center.x,
- center.y
- ),
- radius_x,
- radius_y
- ),
- fill_brush_.get()
- );
- cache_expired_ = true;
- }
-
- void Canvas::FillRect(const Rect & rect)
- {
- render_target_->FillRectangle(
- D2D1::RectF(
- rect.origin.x,
- rect.origin.y,
- rect.origin.x + rect.size.x,
- rect.origin.y + rect.size.y
- ),
- fill_brush_.get()
- );
- cache_expired_ = true;
- }
-
- void Canvas::FillRoundedRect(const Rect & rect, float radius_x, float radius_y)
- {
- render_target_->FillRoundedRectangle(
- D2D1::RoundedRect(
- D2D1::RectF(
- rect.origin.x,
- rect.origin.y,
- rect.origin.x + rect.size.x,
- rect.origin.y + rect.size.y
- ),
- radius_x,
- radius_y
- ),
- fill_brush_.get()
- );
- cache_expired_ = true;
+ rt_.DrawTextLayout(layout, point);
}
void Canvas::BeginPath(Point const& begin_pos)
{
- current_geometry_ = nullptr;
-
- ThrowIfFailed(
- Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_)
- );
-
- ThrowIfFailed(
- current_geometry_->Open(¤t_sink_)
- );
-
- current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
+ geo_sink_.BeginPath(begin_pos);
}
void Canvas::EndPath(bool closed)
{
- if (current_sink_)
- {
- current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
- ThrowIfFailed(
- current_sink_->Close()
- );
- current_sink_ = nullptr;
- }
+ geo_sink_.EndPath(closed);
}
void Canvas::AddLine(Point const & point)
{
- if (current_sink_)
- current_sink_->AddLine(DX::ConvertToPoint2F(point));
+ geo_sink_.AddLine(point);
}
void Canvas::AddLines(Vector const& points)
{
- if (current_sink_ && !points.empty())
- {
- current_sink_->AddLines(
- reinterpret_cast(&points[0]),
- static_cast(points.size())
- );
- }
+ geo_sink_.AddLines(points);
}
void Canvas::AddBezier(Point const & point1, Point const & point2, Point const & point3)
{
- if (current_sink_)
- {
- current_sink_->AddBezier(
- D2D1::BezierSegment(
- DX::ConvertToPoint2F(point1),
- DX::ConvertToPoint2F(point2),
- DX::ConvertToPoint2F(point3)
- )
- );
- }
+ geo_sink_.AddBezier(point1, point2, point3);
}
void Canvas::AddArc(Point const & point, Point const & radius, float rotation, bool clockwise, bool is_small)
{
- if (current_sink_)
- {
- current_sink_->AddArc(
- D2D1::ArcSegment(
- DX::ConvertToPoint2F(point),
- DX::ConvertToSizeF(radius),
- rotation,
- clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
- is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
- )
- );
- }
+ geo_sink_.AddArc(point, radius, rotation, clockwise, is_small);
}
void Canvas::StrokePath()
{
- render_target_->DrawGeometry(
- current_geometry_.get(),
- stroke_brush_.get(),
+ rt_.DrawGeometry(
+ geo_sink_.GetGeometry(),
+ stroke_color_,
stroke_width_,
- outline_join_style_.get()
+ stroke_style_
);
cache_expired_ = true;
}
void Canvas::FillPath()
{
- render_target_->FillGeometry(
- current_geometry_.get(),
- fill_brush_.get()
+ rt_.FillGeometry(
+ geo_sink_.GetGeometry(),
+ fill_color_
);
cache_expired_ = true;
}
void Canvas::Clear()
{
- render_target_->Clear();
+ rt_.Clear();
cache_expired_ = true;
}
- ImagePtr Canvas::ExportToImage() const
+ void Canvas::Clear(Color const& clear_color)
{
- ImagePtr image = new Image(GetBitmap());
- return image;
+ rt_.Clear(clear_color);
+ cache_expired_ = true;
}
- ComPtr const& kiwano::Canvas::GetBitmap() const
+ Image Canvas::ExportToImage() const
+ {
+ UpdateCache();
+ return image_cached_;
+ }
+
+ void Canvas::UpdateCache() const
{
if (cache_expired_)
{
- bitmap_cached_ = nullptr;
- ThrowIfFailed(
- render_target_->GetBitmap(&bitmap_cached_)
- );
+ rt_.GetOutput(image_cached_);
cache_expired_ = false;
}
- return bitmap_cached_;
}
}
diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h
index add2a2c1..6508ebd0 100644
--- a/src/kiwano/2d/Canvas.h
+++ b/src/kiwano/2d/Canvas.h
@@ -20,10 +20,7 @@
#pragma once
#include "Actor.h"
-#include "Font.hpp"
-#include "TextStyle.hpp"
-#include "../renderer/Image.h"
-#include "../renderer/TextRenderer.h"
+#include "../renderer/RenderTarget.h"
#ifdef DrawText
# undef DrawText
@@ -57,39 +54,61 @@ namespace kiwano
// 画直线
void DrawLine(
- const Point& begin,
- const Point& end
+ Point const& begin,
+ Point const& end
);
// 画圆形边框
void DrawCircle(
- const Point& center,
+ Point const& center,
float radius
);
// 画椭圆形边框
void DrawEllipse(
- const Point& center,
- float radius_x,
- float radius_y
+ Point const& center,
+ Vec2 const& radius
);
// 画矩形边框
void DrawRect(
- const Rect& rect
+ Rect const& rect
);
// 画圆角矩形边框
void DrawRoundedRect(
- const Rect& rect,
- float radius_x,
- float radius_y
+ Rect const& rect,
+ Vec2 const& radius
+ );
+
+ // 填充圆形
+ void FillCircle(
+ Point const& center,
+ float radius
+ );
+
+ // 填充椭圆形
+ void FillEllipse(
+ Point const& center,
+ Vec2 const& radius
+ );
+
+ // 填充矩形
+ void FillRect(
+ Rect const& rect
+ );
+
+ // 填充圆角矩形
+ void FillRoundedRect(
+ Rect const& rect,
+ Vec2 const& radius
);
// 画图片
void DrawImage(
- ImagePtr image,
- float opacity = 1.f
+ Image const& image,
+ const Rect* src_rect = nullptr,
+ const Rect* dest_rect = nullptr
);
// 画文字
@@ -98,31 +117,6 @@ namespace kiwano
Point const& point /* 文字位置 */
);
- // 填充圆形
- void FillCircle(
- const Point& center,
- float radius
- );
-
- // 填充椭圆形
- void FillEllipse(
- const Point& center,
- float radius_x,
- float radius_y
- );
-
- // 填充矩形
- void FillRect(
- const Rect& rect
- );
-
- // 填充圆角矩形
- void FillRoundedRect(
- const Rect& rect,
- float radius_x,
- float radius_y
- );
-
// 开始绘制路径
void BeginPath(
Point const& begin_pos /* 路径起始点 */
@@ -168,14 +162,19 @@ namespace kiwano
// 清空画布
void Clear();
+ // 清空画布
+ void Clear(
+ Color const& clear_color
+ );
+
// 设置填充颜色
void SetFillColor(
- const Color& color
+ Color const& color
);
// 设置线条颜色
void SetStrokeColor(
- const Color& color
+ Color const& color
);
// 设置线条宽度
@@ -183,17 +182,26 @@ namespace kiwano
float width
);
- // 设置线条相交样式
- void SetOutlineJoinStyle(
- StrokeStyle outline_join
+ // 设置线条样式
+ void SetStrokeStyle(
+ StrokeStyle stroke_style
+ );
+
+ // 设置文字字体
+ void SetTextFont(
+ Font const& font
);
// 设置文字画刷样式
void SetTextStyle(
- Font const& font,
TextStyle const& text_style
);
+ // 设置画笔透明度
+ void SetBrushOpacity(
+ float opacity
+ );
+
// 获取填充颜色
Color GetFillColor() const;
@@ -203,34 +211,38 @@ namespace kiwano
// 获取线条宽度
float GetStrokeWidth() const;
- // 变换画笔
+ // 获取画笔透明度
+ float GetBrushOpacity() const;
+
+ // 画笔二维变换
+ void SetBrushTransform(
+ Transform const& transform
+ );
+
+ // 画笔二维变换
void SetBrushTransform(
Matrix3x2 const& transform
);
// 导出为图片
- ImagePtr ExportToImage() const;
+ Image ExportToImage() const;
void OnRender(Renderer* renderer) override;
protected:
- ComPtr const& GetBitmap() const;
+ void UpdateCache() const;
protected:
- float stroke_width_;
- Font text_font_;
- TextStyle text_style_;
+ float stroke_width_;
+ Color fill_color_;
+ Color stroke_color_;
+ Font text_font_;
+ TextStyle text_style_;
+ StrokeStyle stroke_style_;
+ GeometrySink geo_sink_;
+ ImageRenderTarget rt_;
- ComPtr current_geometry_;
- ComPtr current_sink_;
- ComPtr outline_join_style_;
- ComPtr fill_brush_;
- ComPtr stroke_brush_;
- ComPtr text_format_;
- ComPtr text_renderer_;
- ComPtr render_target_;
-
- mutable bool cache_expired_;
- mutable ComPtr bitmap_cached_;
+ mutable bool cache_expired_;
+ mutable Image image_cached_;
};
}
diff --git a/src/kiwano/2d/DebugActor.cpp b/src/kiwano/2d/DebugActor.cpp
index e7429567..a2242f93 100644
--- a/src/kiwano/2d/DebugActor.cpp
+++ b/src/kiwano/2d/DebugActor.cpp
@@ -46,7 +46,6 @@ namespace kiwano
debug_text_->SetFont(font);
TextStyle style;
- style.wrap = false;
style.line_spacing = 20.f;
debug_text_->SetStyle(style);
@@ -83,9 +82,9 @@ namespace kiwano
ss << "Fps: " << frame_time_.size() << std::endl;
#if defined(KGE_DEBUG)
- if (Object::IsTracingLeaks())
+ if (ObjectBase::IsTracingLeaks())
{
- ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl;
+ ss << "Objects: " << ObjectBase::__GetTracingObjects().size() << std::endl;
}
#endif
@@ -98,7 +97,7 @@ namespace kiwano
ss << "Memory: " << pmc.PrivateUsage / 1024 << "kb";
debug_text_->SetText(ss.str());
- SetSize(Size{ 20 + debug_text_->GetLayoutSize().x, 20 + debug_text_->GetLayoutSize().y });
+ SetSize(Size{ 20 + debug_text_->GetSize().x, 20 + debug_text_->GetSize().y });
}
}
diff --git a/src/kiwano/2d/Frame.cpp b/src/kiwano/2d/Frame.cpp
index 97781255..ff99edde 100644
--- a/src/kiwano/2d/Frame.cpp
+++ b/src/kiwano/2d/Frame.cpp
@@ -27,20 +27,25 @@ namespace kiwano
{
}
+ Frame::Frame(String const& file_path)
+ {
+ Load(file_path);
+ }
+
Frame::Frame(Resource const& res)
{
Load(res);
}
- Frame::Frame(ImagePtr image)
- : image_(image)
+ Frame::Frame(Image const& image)
{
+ SetImage(image);
}
- bool Frame::Load(Resource const& res)
+ bool Frame::Load(String const& file_path)
{
- ImagePtr image = ImageCache::GetInstance()->AddImage(res);
- if (image && image->IsValid())
+ Image image = ImageCache::GetInstance()->AddOrGetImage(file_path);
+ if (image.IsValid())
{
SetImage(image);
return true;
@@ -48,11 +53,22 @@ namespace kiwano
return false;
}
- void Frame::Crop(Rect const& crop_rect)
+ bool Frame::Load(Resource const& res)
{
- if (image_)
+ Image image = ImageCache::GetInstance()->AddOrGetImage(res);
+ if (image.IsValid())
{
- auto bitmap_size = image_->GetSize();
+ SetImage(image);
+ return true;
+ }
+ return false;
+ }
+
+ void Frame::SetCropRect(Rect const& crop_rect)
+ {
+ if (image_.IsValid())
+ {
+ auto bitmap_size = image_.GetSize();
crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.x);
crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.y);
crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.x - crop_rect.origin.x);
@@ -60,14 +76,14 @@ namespace kiwano
}
}
- void Frame::SetImage(ImagePtr image)
+ void Frame::SetImage(Image const& image)
{
image_ = image;
- if (image_)
+ if (image_.IsValid())
{
crop_rect_.origin.x = crop_rect_.origin.y = 0;
- crop_rect_.size.x = image_->GetWidth();
- crop_rect_.size.y = image_->GetHeight();
+ crop_rect_.size.x = image_.GetWidth();
+ crop_rect_.size.y = image_.GetHeight();
}
}
}
diff --git a/src/kiwano/2d/Frame.h b/src/kiwano/2d/Frame.h
index 360cfd63..9f13d4f0 100644
--- a/src/kiwano/2d/Frame.h
+++ b/src/kiwano/2d/Frame.h
@@ -25,17 +25,25 @@ namespace kiwano
{
// 帧图像
class KGE_API Frame
- : public Object
+ : public ObjectBase
{
public:
Frame();
+ explicit Frame(
+ String const& file_path
+ );
+
explicit Frame(
Resource const& res
);
explicit Frame(
- ImagePtr image
+ Image const& image
+ );
+
+ bool Load(
+ String const& file_path
);
bool Load(
@@ -43,10 +51,15 @@ namespace kiwano
);
// 裁剪矩形
- void Crop(
+ void SetCropRect(
Rect const& crop_rect /* 裁剪矩形 */
);
+ // 设置位图
+ void SetImage(
+ Image const& image
+ );
+
// 获取宽度
float GetWidth() const { return crop_rect_.size.x; }
@@ -63,13 +76,10 @@ namespace kiwano
inline Rect const& GetCropRect() const { return crop_rect_; }
// 获取位图
- inline ImagePtr GetImage() const { return image_; }
-
- // 设置位图
- void SetImage(ImagePtr image);
+ inline Image const& GetImage() const { return image_; }
protected:
- ImagePtr image_;
+ Image image_;
Rect crop_rect_;
};
}
diff --git a/src/kiwano/2d/FrameSequence.h b/src/kiwano/2d/FrameSequence.h
index 863fa38e..09c0ccde 100644
--- a/src/kiwano/2d/FrameSequence.h
+++ b/src/kiwano/2d/FrameSequence.h
@@ -25,7 +25,7 @@ namespace kiwano
{
// 序列帧
class KGE_API FrameSequence
- : public Object
+ : public ObjectBase
{
public:
FrameSequence();
diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp
index bccf256c..08c9c471 100644
--- a/src/kiwano/2d/GifSprite.cpp
+++ b/src/kiwano/2d/GifSprite.cpp
@@ -20,7 +20,8 @@
#include "GifSprite.h"
#include "../base/Logger.h"
-#include "../platform/modules.h"
+#include "../renderer/ImageCache.h"
+#include "../renderer/Renderer.h"
namespace kiwano
{
@@ -29,53 +30,59 @@ namespace kiwano
, next_index_(0)
, total_loop_count_(1)
, loop_count_(0)
+ , disposal_type_(DisposalType::Unknown)
{
}
+ GifSprite::GifSprite(String const& file_path)
+ {
+ Load(file_path);
+ }
+
GifSprite::GifSprite(Resource const& res)
: GifSprite()
{
Load(res);
}
- GifSprite::GifSprite(GifImagePtr image)
+ GifSprite::GifSprite(GifImage image)
{
Load(image);
}
- bool GifSprite::Load(Resource const& res)
+ bool GifSprite::Load(String const& file_path)
{
- GifImagePtr image = new (std::nothrow) GifImage;
- if (image->Load(res))
- {
- return Load(image);
- }
- return false;
+ GifImage image = ImageCache::GetInstance()->AddOrGetGifImage(file_path);
+ return Load(image);
}
- bool GifSprite::Load(GifImagePtr image)
+ bool GifSprite::Load(Resource const& res)
{
- if (image && image_ != image)
+ GifImage image = ImageCache::GetInstance()->AddOrGetGifImage(res);
+ return Load(image);
+ }
+
+ bool GifSprite::Load(GifImage image)
+ {
+ if (image.IsValid())
{
image_ = image;
next_index_ = 0;
loop_count_ = 0;
+ disposal_type_ = DisposalType::None;
SetSize(
- static_cast(image_->GetWidthInPixels()),
- static_cast(image_->GetHeightInPixels())
+ static_cast(image_.GetWidthInPixels()),
+ static_cast(image_.GetHeightInPixels())
);
- if (!frame_rt_)
+ if (!frame_rt_.IsValid())
{
- auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext();
- ThrowIfFailed(
- ctx->CreateCompatibleRenderTarget(&frame_rt_)
- );
+ Renderer::GetInstance()->CreateImageRenderTarget(frame_rt_);
}
- if (image_->GetFramesCount() > 0)
+ if (image_.GetFramesCount() > 0)
{
ComposeNextFrame();
}
@@ -84,11 +91,21 @@ namespace kiwano
return false;
}
+ void GifSprite::OnRender(Renderer* renderer)
+ {
+ if (frame_.IsValid() && renderer->CheckVisibility(size_, transform_matrix_))
+ {
+ PrepareRender(renderer);
+
+ renderer->DrawImage(frame_);
+ }
+ }
+
void GifSprite::Update(Duration dt)
{
Actor::Update(dt);
- if (image_ && animating_)
+ if (image_.IsValid() && animating_)
{
frame_elapsed_ += dt;
if (frame_delay_ <= frame_elapsed_)
@@ -100,84 +117,94 @@ namespace kiwano
}
}
- void GifSprite::OnRender(Renderer* renderer)
- {
- if (frame_to_render_ && renderer->CheckVisibility(size_, transform_matrix_))
- {
- PrepareRender(renderer);
-
- Rect bounds = GetBounds();
- renderer->DrawBitmap(frame_to_render_, bounds, bounds);
- }
- }
-
void GifSprite::RestartAnimation()
{
animating_ = true;
next_index_ = 0;
loop_count_ = 0;
- image_->SetDisposalType(GifImage::DisposalType::None);
+ disposal_type_ = DisposalType::None;
}
void GifSprite::ComposeNextFrame()
{
- if (frame_rt_)
+ if (frame_rt_.IsValid())
{
- // 找到延迟大于 0 的帧 (0 延迟帧是不可见的中间帧)
- HRESULT hr = E_FAIL;
do
{
- hr = image_->DisposeCurrentFrame(frame_rt_);
- if (SUCCEEDED(hr))
- {
- hr = OverlayNextFrame();
- }
-
- if (SUCCEEDED(hr))
- {
- frame_delay_.SetMilliseconds(static_cast(image_->GetFrameDelay()));
- }
- } while (SUCCEEDED(hr) && frame_delay_.IsZero() && !IsLastFrame());
+ DisposeCurrentFrame();
+ OverlayNextFrame();
+ } while (frame_delay_.IsZero() && !IsLastFrame());
- animating_ = (SUCCEEDED(hr) && !EndOfAnimation() && image_->GetFramesCount() > 1);
+ animating_ = (!EndOfAnimation() && image_.GetFramesCount() > 1);
}
}
- HRESULT GifSprite::OverlayNextFrame()
+ void GifSprite::DisposeCurrentFrame()
{
- HRESULT hr = image_->GetRawFrame(next_index_);
+ switch (disposal_type_)
+ {
+ case DisposalType::Unknown:
+ case DisposalType::None:
+ break;
+
+ case DisposalType::Background:
+ {
+ ClearCurrentFrameArea();
+ break;
+ }
+
+ case DisposalType::Previous:
+ {
+ RestoreSavedFrame();
+ break;
+ }
+
+ default:
+ ThrowIfFailed(E_FAIL);
+ }
+ }
+
+ void GifSprite::OverlayNextFrame()
+ {
+ Image raw_image;
+
+ HRESULT hr = image_.GetRawFrame(next_index_, raw_image, frame_rect_, frame_delay_, disposal_type_);
+
if (SUCCEEDED(hr))
{
- if (image_->GetDisposalType() == GifImage::DisposalType::Previous)
+ if (disposal_type_ == DisposalType::Previous)
{
- hr = image_->SaveComposedFrame(frame_rt_);
+ SaveComposedFrame();
}
}
if (SUCCEEDED(hr))
{
- frame_rt_->BeginDraw();
+ frame_rt_.BeginDraw();
if (next_index_ == 0)
{
// 重新绘制背景
- frame_rt_->Clear(image_->GetBackgroundColor());
+ frame_rt_.Clear(image_.GetBackgroundColor());
loop_count_++;
}
- frame_rt_->DrawBitmap(image_->GetRawFrame().get(), image_->GetFramePosition());
- hr = frame_rt_->EndDraw();
+ frame_rt_.DrawImage(raw_image, nullptr, &frame_rect_);
+ frame_rt_.EndDraw();
}
if (SUCCEEDED(hr))
{
- frame_to_render_ = nullptr;
- hr = frame_rt_->GetBitmap(&frame_to_render_);
- }
+ Image frame_to_render;
+ frame_rt_.GetOutput(frame_to_render);
- if (SUCCEEDED(hr))
- {
- next_index_ = (++next_index_) % image_->GetFramesCount();
+ hr = frame_to_render.IsValid() ? S_OK : E_FAIL;
+
+ if (SUCCEEDED(hr))
+ {
+ frame_ = frame_to_render;
+ next_index_ = (++next_index_) % image_.GetFramesCount();
+ }
}
if (IsLastFrame() && loop_cb_)
@@ -189,7 +216,71 @@ namespace kiwano
{
done_cb_();
}
- return hr;
+
+ ThrowIfFailed(hr);
+ }
+
+ void GifSprite::SaveComposedFrame()
+ {
+ Image frame_to_be_saved;
+ frame_rt_.GetOutput(frame_to_be_saved);
+
+ HRESULT hr = frame_to_be_saved.IsValid() ? S_OK : E_FAIL;
+
+ if (SUCCEEDED(hr))
+ {
+ if (!saved_frame_.IsValid())
+ {
+ auto size = frame_to_be_saved.GetSizeInPixels();
+ auto prop = D2D1::BitmapProperties(frame_to_be_saved.GetPixelFormat());
+
+ ComPtr saved_bitmap;
+ hr = frame_rt_.GetRenderTarget()->CreateBitmap(D2D1::SizeU(size.x, size.y), prop, &saved_bitmap);
+
+ if (SUCCEEDED(hr))
+ {
+ saved_frame_.SetBitmap(saved_bitmap);
+ }
+ }
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ saved_frame_.CopyFrom(frame_to_be_saved);
+ }
+
+ ThrowIfFailed(hr);
+ }
+
+ void GifSprite::RestoreSavedFrame()
+ {
+ HRESULT hr = saved_frame_.IsValid() ? S_OK : E_FAIL;
+
+ if (SUCCEEDED(hr))
+ {
+ Image frame_to_copy_to;
+ frame_rt_.GetOutput(frame_to_copy_to);
+
+ hr = frame_to_copy_to.IsValid() ? S_OK : E_FAIL;
+
+ if (SUCCEEDED(hr))
+ {
+ frame_to_copy_to.CopyFrom(saved_frame_);
+ }
+ }
+
+ ThrowIfFailed(hr);
+ }
+
+ void GifSprite::ClearCurrentFrameArea()
+ {
+ frame_rt_.BeginDraw();
+
+ frame_rt_.PushClipRect(frame_rect_);
+ frame_rt_.Clear(image_.GetBackgroundColor());
+ frame_rt_.PopClipRect();
+
+ return frame_rt_.EndDraw();
}
}
diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h
index 0c730c7d..6fec6a03 100644
--- a/src/kiwano/2d/GifSprite.h
+++ b/src/kiwano/2d/GifSprite.h
@@ -21,26 +21,36 @@
#pragma once
#include "Actor.h"
#include "../base/Resource.h"
-#include "../renderer/Renderer.h"
+#include "../renderer/RenderTarget.h"
#include "../renderer/GifImage.h"
namespace kiwano
{
+ // GIF 精灵
class KGE_API GifSprite
: public Actor
{
public:
- using LoopDoneCallback = Function;
- using DoneCallback = Function;
+ using DisposalType = GifImage::DisposalType;
+ using LoopDoneCallback = Function;
+ using DoneCallback = Function;
GifSprite();
+ GifSprite(
+ String const& file_path
+ );
+
GifSprite(
Resource const& res
);
GifSprite(
- GifImagePtr image
+ GifImage image
+ );
+
+ bool Load(
+ String const& file_path
);
bool Load(
@@ -48,7 +58,7 @@ namespace kiwano
);
bool Load(
- GifImagePtr image
+ GifImage image
);
// 设置 GIF 动画循环次数
@@ -72,27 +82,36 @@ namespace kiwano
protected:
void Update(Duration dt) override;
- void ComposeNextFrame();
-
- HRESULT OverlayNextFrame();
-
inline bool IsLastFrame() const { return (next_index_ == 0); }
inline bool EndOfAnimation() const { return IsLastFrame() && loop_count_ == total_loop_count_ + 1; }
- protected:
- bool animating_;
- int total_loop_count_;
- int loop_count_;
- unsigned int next_index_;
- Duration frame_delay_;
- Duration frame_elapsed_;
+ void ComposeNextFrame();
+ void DisposeCurrentFrame();
+
+ void OverlayNextFrame();
+
+ void SaveComposedFrame();
+
+ void RestoreSavedFrame();
+
+ void ClearCurrentFrameArea();
+
+ protected:
+ bool animating_;
+ int total_loop_count_;
+ int loop_count_;
+ UINT next_index_;
+ Duration frame_delay_;
+ Duration frame_elapsed_;
+ DisposalType disposal_type_;
LoopDoneCallback loop_cb_;
DoneCallback done_cb_;
-
- GifImagePtr image_;
- ComPtr frame_to_render_;
- ComPtr frame_rt_;
+ GifImage image_;
+ Image frame_;
+ Rect frame_rect_;
+ Image saved_frame_;
+ ImageRenderTarget frame_rt_;
};
}
diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp
index 3cab94c1..cd6963b3 100644
--- a/src/kiwano/2d/ShapeActor.cpp
+++ b/src/kiwano/2d/ShapeActor.cpp
@@ -28,7 +28,7 @@ namespace kiwano
: fill_color_(Color::White)
, stroke_color_(Color(Color::Black, 0))
, stroke_width_(1.f)
- , outline_join_(StrokeStyle::Miter)
+ , stroke_style_(StrokeStyle::Miter)
{
}
@@ -73,9 +73,9 @@ namespace kiwano
stroke_width_ = std::max(width, 0.f);
}
- void ShapeActor::SetOutlineJoinStyle(StrokeStyle outline_join)
+ void ShapeActor::SetStrokeStyle(StrokeStyle stroke_style)
{
- outline_join_ = outline_join;
+ stroke_style_ = stroke_style;
}
void ShapeActor::OnRender(Renderer* renderer)
@@ -93,7 +93,7 @@ namespace kiwano
geo_,
stroke_color_,
stroke_width_,
- outline_join_
+ stroke_style_
);
}
}
diff --git a/src/kiwano/2d/ShapeActor.h b/src/kiwano/2d/ShapeActor.h
index 940a34df..7ba2a3c4 100644
--- a/src/kiwano/2d/ShapeActor.h
+++ b/src/kiwano/2d/ShapeActor.h
@@ -46,8 +46,8 @@ namespace kiwano
// 获取线条宽度
float GetStrokeWidth() const { return stroke_width_; }
- // 获取线条相交样式
- StrokeStyle SetOutlineJoinStyle() const { return outline_join_; }
+ // 获取线条样式
+ StrokeStyle SetStrokeStyle() const { return stroke_style_; }
// 获取边界
Rect GetBounds() const override;
@@ -70,9 +70,9 @@ namespace kiwano
float width
);
- // 设置线条相交样式
- void SetOutlineJoinStyle(
- StrokeStyle outline_join
+ // 设置线条样式
+ void SetStrokeStyle(
+ StrokeStyle stroke_style
);
// 设置形状
@@ -87,7 +87,7 @@ namespace kiwano
Color fill_color_;
Color stroke_color_;
float stroke_width_;
- StrokeStyle outline_join_;
+ StrokeStyle stroke_style_;
Geometry geo_;
};
diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp
index ac4ffcba..688faf90 100644
--- a/src/kiwano/2d/Sprite.cpp
+++ b/src/kiwano/2d/Sprite.cpp
@@ -24,21 +24,29 @@
namespace kiwano
{
Sprite::Sprite()
- : frame_(nullptr)
{
}
+ 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)
- : frame_(nullptr)
{
Load(res);
}
Sprite::Sprite(Resource const& res, const Rect& crop_rect)
- : frame_(nullptr)
{
Load(res);
- Crop(crop_rect);
+ SetCropRect(crop_rect);
}
Sprite::Sprite(FramePtr frame)
@@ -51,6 +59,17 @@ namespace kiwano
{
}
+ bool Sprite::Load(String const& file_path)
+ {
+ FramePtr frame = new (std::nothrow) Frame;
+ if (frame->Load(file_path))
+ {
+ SetFrame(frame);
+ return true;
+ }
+ return false;
+ }
+
bool Sprite::Load(Resource const& res)
{
FramePtr frame = new (std::nothrow) Frame;
@@ -62,11 +81,11 @@ namespace kiwano
return false;
}
- void Sprite::Crop(const Rect& crop_rect)
+ void Sprite::SetCropRect(const Rect& crop_rect)
{
if (frame_)
{
- frame_->Crop(crop_rect);
+ frame_->SetCropRect(crop_rect);
SetSize(frame_->GetWidth(), frame_->GetHeight());
}
}
@@ -89,7 +108,7 @@ namespace kiwano
{
PrepareRender(renderer);
- renderer->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds());
+ renderer->DrawImage(frame_->GetImage(), &frame_->GetCropRect(), nullptr);
}
}
}
diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h
index 01940df6..8138f5e2 100644
--- a/src/kiwano/2d/Sprite.h
+++ b/src/kiwano/2d/Sprite.h
@@ -32,10 +32,19 @@ namespace kiwano
Sprite();
explicit Sprite(
- Resource const& res
+ String const& file_path
+ );
+
+ Sprite(
+ String const& file_path,
+ Rect const& crop_rect /* 裁剪矩形 */
);
explicit Sprite(
+ Resource const& res
+ );
+
+ Sprite(
Resource const& res,
Rect const& crop_rect /* 裁剪矩形 */
);
@@ -46,13 +55,18 @@ namespace kiwano
virtual ~Sprite();
+ // 加载图像
+ bool Load(
+ String const& file_path
+ );
+
// 加载图像资源
bool Load(
Resource const& res
);
// 裁剪矩形
- void Crop(
+ void SetCropRect(
const Rect& crop_rect
);
diff --git a/src/kiwano/2d/Text.cpp b/src/kiwano/2d/Text.cpp
index 84fae7f8..dc460d0b 100644
--- a/src/kiwano/2d/Text.cpp
+++ b/src/kiwano/2d/Text.cpp
@@ -44,6 +44,7 @@ namespace kiwano
: font_(text_default_font)
, style_(text_default_style)
, layout_dirty_(false)
+ , format_dirty_(false)
{
}
@@ -74,96 +75,6 @@ namespace kiwano
{
}
- String const& Text::GetText() const
- {
- return text_;
- }
-
- const Font& Text::GetFont() const
- {
- return font_;
- }
-
- const TextStyle& Text::GetStyle() const
- {
- return style_;
- }
-
- String const& Text::GetFontFamily() const
- {
- return font_.family;
- }
-
- float Text::GetFontSize() const
- {
- return font_.size;
- }
-
- unsigned int Text::GetFontWeight() const
- {
- return font_.weight;
- }
-
- const Color& Text::GetColor() const
- {
- return style_.color;
- }
-
- const Color& Text::GetOutlineColor() const
- {
- return style_.outline_color;
- }
-
- float Text::GetOutlineWidth() const
- {
- return style_.outline_width;
- }
-
- StrokeStyle Text::GetOutlineStroke() const
- {
- return style_.outline_stroke;
- }
-
- int Text::GetLineCount()
- {
- UpdateLayout();
- if (text_layout_)
- {
- DWRITE_TEXT_METRICS metrics;
- if (SUCCEEDED(text_layout_->GetMetrics(&metrics)))
- {
- return static_cast(metrics.lineCount);
- }
- }
- return 0;
- }
-
- Size const& Text::GetLayoutSize() const
- {
- UpdateLayout();
- return layout_size_;
- }
-
- bool Text::IsItalic() const
- {
- return font_.italic;
- }
-
- bool Text::HasStrikethrough() const
- {
- return style_.strikethrough;
- }
-
- bool Text::HasUnderline() const
- {
- return style_.underline;
- }
-
- bool Text::HasOutline() const
- {
- return style_.outline;
- }
-
void Text::SetText(String const& text)
{
text_ = text;
@@ -179,7 +90,7 @@ namespace kiwano
void Text::SetFont(const Font & font)
{
font_ = font;
- layout_dirty_ = true;
+ format_dirty_ = true;
}
void Text::SetFontFamily(String const& family)
@@ -187,7 +98,7 @@ namespace kiwano
if (font_.family != family)
{
font_.family = family;
- layout_dirty_ = true;
+ format_dirty_ = true;
}
}
@@ -196,7 +107,7 @@ namespace kiwano
if (font_.size != size)
{
font_.size = size;
- layout_dirty_ = true;
+ format_dirty_ = true;
}
}
@@ -205,7 +116,7 @@ namespace kiwano
if (font_.weight != weight)
{
font_.weight = weight;
- layout_dirty_ = true;
+ format_dirty_ = true;
}
}
@@ -219,16 +130,7 @@ namespace kiwano
if (font_.italic != val)
{
font_.italic = val;
- layout_dirty_ = true;
- }
- }
-
- void Text::SetWrapEnabled(bool wrap)
- {
- if (style_.wrap != wrap)
- {
- style_.wrap = wrap;
- layout_dirty_ = true;
+ format_dirty_ = true;
}
}
@@ -236,12 +138,12 @@ namespace kiwano
{
if (style_.wrap_width != wrap_width)
{
- style_.wrap_width = std::max(wrap_width, 0.f);
+ style_.wrap_width = wrap_width;
layout_dirty_ = true;
}
}
- void Text::SetLineacingPtr(float line_spacing)
+ void Text::SetLineSpacing(float line_spacing)
{
if (style_.line_spacing != line_spacing)
{
@@ -301,51 +203,26 @@ namespace kiwano
{
UpdateLayout();
- if (text_layout_ && renderer->CheckVisibility(layout_size_, transform_matrix_))
+ if (text_layout_ && renderer->CheckVisibility(size_, transform_matrix_))
{
PrepareRender(renderer);
- renderer->SetTextStyle(
- GetDisplayedOpacity(),
- style_.color,
- style_.outline,
- style_.outline_color,
- style_.outline_width,
- style_.outline_stroke
- );
- renderer->DrawTextLayout(text_layout_);
+ renderer->DrawTextLayout(text_layout_);
}
}
- void Text::UpdateLayout() const
+ void Text::UpdateLayout()
{
- if (!layout_dirty_)
- return;
+ if (format_dirty_)
+ {
+ format_dirty_ = false;
+ text_layout_.Update(font_);
+ }
- layout_dirty_ = false;
- text_format_ = nullptr;
- text_layout_ = nullptr;
-
- if (text_.empty())
- return;
-
- auto renderer = Renderer::GetInstance();
-
- ThrowIfFailed(
- renderer->GetD2DDeviceResources()->CreateTextFormat(
- text_format_,
- font_,
- style_
- )
- );
-
- ThrowIfFailed(
- renderer->GetD2DDeviceResources()->CreateTextLayout(
- text_layout_,
- layout_size_,
- text_,
- text_format_,
- style_
- )
- );
+ if (layout_dirty_)
+ {
+ layout_dirty_ = false;
+ text_layout_.Update(text_, style_);
+ SetSize(text_layout_.GetLayoutSize());
+ }
}
}
diff --git a/src/kiwano/2d/Text.h b/src/kiwano/2d/Text.h
index d2c07ce3..1877b711 100644
--- a/src/kiwano/2d/Text.h
+++ b/src/kiwano/2d/Text.h
@@ -20,9 +20,7 @@
#pragma once
#include "Actor.h"
-#include "Font.hpp"
-#include "TextStyle.hpp"
-#include
+#include "../renderer/TextLayout.h"
namespace kiwano
{
@@ -56,52 +54,16 @@ namespace kiwano
virtual ~Text();
// 获取文本
- String const& GetText() const;
+ inline String const& GetText() const { return text_; }
// 获取字体
- const Font& GetFont() const;
+ inline Font GetFont() const { return font_; }
// 获取文本样式
- const TextStyle& GetStyle() const;
+ inline TextStyle GetStyle() const { return style_; }
- // 获取字体族
- String const& GetFontFamily() const;
-
- // 获取当前字号
- float GetFontSize() const;
-
- // 获取当前字体粗细值
- unsigned int GetFontWeight() const;
-
- // 获取文字颜色
- const Color& GetColor() const;
-
- // 获取描边颜色
- const Color& GetOutlineColor() const;
-
- // 获取描边线宽
- float GetOutlineWidth() const;
-
- // 获取描边线相交样式
- StrokeStyle GetOutlineStroke() const;
-
- // 获取文本显示行数
- int GetLineCount();
-
- // 获取文字布局大小
- Size const& GetLayoutSize() const;
-
- // 是否是斜体
- bool IsItalic() const;
-
- // 是否显示删除线
- bool HasStrikethrough() const;
-
- // 是否显示下划线
- bool HasUnderline() const;
-
- // 是否显示描边
- bool HasOutline() const;
+ // 获取文本布局
+ inline TextLayout GetLayout() const { return text_layout_; }
// 设置文本
void SetText(
@@ -143,18 +105,13 @@ namespace kiwano
bool val
);
- // 打开或关闭文本自动换行(默认为关闭)
- void SetWrapEnabled(
- bool wrap
- );
-
// 设置文本自动换行的宽度(默认为 0)
void SetWrapWidth(
float wrap_width
);
// 设置行间距(默认为 0)
- void SetLineacingPtr(
+ void SetLineSpacing(
float line_spacing
);
@@ -206,16 +163,14 @@ namespace kiwano
void OnRender(Renderer* renderer) override;
protected:
- void UpdateLayout() const;
+ void UpdateLayout();
protected:
+ bool format_dirty_;
+ bool layout_dirty_;
+ TextLayout text_layout_;
String text_;
Font font_;
TextStyle style_;
-
- mutable bool layout_dirty_;
- mutable Size layout_size_;
- mutable ComPtr text_format_;
- mutable ComPtr text_layout_;
};
}
diff --git a/src/kiwano/2d/TextStyle.hpp b/src/kiwano/2d/TextStyle.hpp
index 0cc3c51b..1e5a299d 100644
--- a/src/kiwano/2d/TextStyle.hpp
+++ b/src/kiwano/2d/TextStyle.hpp
@@ -37,7 +37,6 @@ namespace kiwano
public:
Color color; // 颜色
TextAlign alignment; // 对齐方式
- bool wrap; // 打开自动换行
float wrap_width; // 自动换行宽度
float line_spacing; // 行间距
bool underline; // 下划线
@@ -51,7 +50,6 @@ namespace kiwano
TextStyle()
: color(Color::White)
, alignment(TextAlign::Left)
- , wrap(false)
, wrap_width(0.f)
, line_spacing(0.f)
, underline(false)
@@ -65,7 +63,6 @@ namespace kiwano
TextStyle(
Color color,
TextAlign alignment = TextAlign::Left,
- bool wrap = false,
float wrap_width = 0.f,
float line_spacing = 0.f,
bool underline = false,
@@ -77,7 +74,6 @@ namespace kiwano
)
: color(color)
, alignment(alignment)
- , wrap(wrap)
, wrap_width(wrap_width)
, line_spacing(line_spacing)
, underline(underline)
@@ -88,4 +84,4 @@ namespace kiwano
, outline_stroke(outline_stroke)
{}
};
-}
\ No newline at end of file
+}
diff --git a/src/kiwano/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp
index af2876c5..8fe41b9c 100644
--- a/src/kiwano/2d/Transition.cpp
+++ b/src/kiwano/2d/Transition.cpp
@@ -39,10 +39,8 @@ namespace kiwano
, window_size_()
, out_scene_(nullptr)
, in_scene_(nullptr)
- , out_layer_(nullptr)
- , in_layer_(nullptr)
- , out_layer_prop_()
- , in_layer_prop_()
+ , out_layer_()
+ , in_layer_()
{
}
@@ -74,7 +72,8 @@ namespace kiwano
}
window_size_ = Renderer::GetInstance()->GetOutputSize();
- out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f };
+ out_layer_.SetAreaRect(Rect{ Point(), window_size_ });
+ in_layer_.SetAreaRect(Rect{ Point(), window_size_ });
}
void Transition::Update(Duration dt)
@@ -99,30 +98,26 @@ namespace kiwano
{
if (out_scene_)
{
- renderer->PushClip(
- out_scene_->GetTransformMatrix(),
- window_size_
- );
- renderer->PushLayer(out_layer_, out_layer_prop_);
+ renderer->SetTransform(out_scene_->GetTransformMatrix());
+ renderer->PushClipRect(Rect{ Point{}, window_size_ });
+ renderer->PushLayer(out_layer_);
out_scene_->Render(renderer);
renderer->PopLayer();
- renderer->PopClip();
+ renderer->PopClipRect();
}
if (in_scene_)
{
- renderer->PushClip(
- in_scene_->GetTransformMatrix(),
- window_size_
- );
- renderer->PushLayer(in_layer_, in_layer_prop_);
+ renderer->SetTransform(in_scene_->GetTransformMatrix());
+ renderer->PushClipRect(Rect{ Point{}, window_size_ });
+ renderer->PushLayer(in_layer_);
in_scene_->Render(renderer);
renderer->PopLayer();
- renderer->PopClip();
+ renderer->PopClipRect();
}
}
@@ -145,7 +140,7 @@ namespace kiwano
{
Transition::Init(prev, next);
- in_layer_prop_.opacity = 0;
+ in_layer_.SetOpacity(0.f);
}
void BoxTransition::Update(Duration dt)
@@ -154,22 +149,26 @@ namespace kiwano
if (process_ < .5f)
{
- out_layer_prop_.area = Rect(
- window_size_.x * process_,
- window_size_.y * process_,
- window_size_.x * (1 - process_ * 2),
- window_size_.y * (1 - process_ * 2)
+ out_layer_.SetAreaRect(
+ Rect(
+ window_size_.x * process_,
+ window_size_.y * process_,
+ window_size_.x * (1 - process_ * 2),
+ window_size_.y * (1 - process_ * 2)
+ )
);
}
else
{
- out_layer_prop_.opacity = 0;
- in_layer_prop_.opacity = 1;
- in_layer_prop_.area = Rect(
- window_size_.x * (1 - process_),
- window_size_.y * (1 - process_),
- window_size_.x * (2 * process_ - 1),
- window_size_.y * (2 * process_ - 1)
+ out_layer_.SetOpacity(0.f);
+ in_layer_.SetOpacity(1.f);
+ in_layer_.SetAreaRect(
+ Rect(
+ window_size_.x * (1 - process_),
+ window_size_.y * (1 - process_),
+ window_size_.x * (2 * process_ - 1),
+ window_size_.y * (2 * process_ - 1)
+ )
);
}
}
@@ -187,16 +186,16 @@ namespace kiwano
{
Transition::Init(prev, next);
- out_layer_prop_.opacity = 1;
- in_layer_prop_.opacity = 0;
+ out_layer_.SetOpacity(1.f);
+ in_layer_.SetOpacity(0.f);
}
void EmergeTransition::Update(Duration dt)
{
Transition::Update(dt);
- out_layer_prop_.opacity = 1 - process_;
- in_layer_prop_.opacity = process_;
+ out_layer_.SetOpacity(1 - process_);
+ in_layer_.SetOpacity(process_);
}
//-------------------------------------------------------
@@ -212,8 +211,8 @@ namespace kiwano
{
Transition::Init(prev, next);
- out_layer_prop_.opacity = 1;
- in_layer_prop_.opacity = 0;
+ out_layer_.SetOpacity(1.f);
+ in_layer_.SetOpacity(0.f);
}
void FadeTransition::Update(Duration dt)
@@ -222,13 +221,13 @@ namespace kiwano
if (process_ < 0.5)
{
- out_layer_prop_.opacity = 1 - process_ * 2;
- in_layer_prop_.opacity = 0;
+ out_layer_.SetOpacity(1 - process_ * 2);
+ in_layer_.SetOpacity(0.f);
}
else
{
- out_layer_prop_.opacity = 0;
- in_layer_prop_.opacity = (process_ - 0.5f) * 2;
+ out_layer_.SetOpacity(0.f);
+ in_layer_.SetOpacity((process_ - 0.5f) * 2);
}
}
@@ -340,7 +339,7 @@ namespace kiwano
in_scene_->SetAnchor(0.5f, 0.5f);
}
- in_layer_prop_.opacity = 0;
+ in_layer_.SetOpacity(0.f);
}
void RotationTransition::Update(Duration dt)
@@ -361,8 +360,8 @@ namespace kiwano
{
if (in_scene_)
{
- out_layer_prop_.opacity = 0;
- in_layer_prop_.opacity = 1;
+ out_layer_.SetOpacity(0.f);
+ in_layer_.SetOpacity(1.f);
auto transform = in_scene_->GetTransform();
transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 };
diff --git a/src/kiwano/2d/Transition.h b/src/kiwano/2d/Transition.h
index 63cd9642..a70b89cd 100644
--- a/src/kiwano/2d/Transition.h
+++ b/src/kiwano/2d/Transition.h
@@ -20,7 +20,7 @@
#pragma once
#include "include-forwards.h"
-#include
+#include "../renderer/LayerArea.h"
namespace kiwano
{
@@ -29,7 +29,7 @@ namespace kiwano
// 舞台过渡
class KGE_API Transition
- : public Object
+ : public ObjectBase
{
friend class Director;
@@ -57,17 +57,15 @@ namespace kiwano
virtual void Reset() { };
protected:
- bool done_;
- float process_;
- Duration duration_;
- Duration delta_;
- Size window_size_;
- StagePtr out_scene_;
- StagePtr in_scene_;
- ComPtr out_layer_;
- ComPtr in_layer_;
- LayerProperties out_layer_prop_;
- LayerProperties in_layer_prop_;
+ bool done_;
+ float process_;
+ Duration duration_;
+ Duration delta_;
+ Size window_size_;
+ StagePtr out_scene_;
+ StagePtr in_scene_;
+ LayerArea out_layer_;
+ LayerArea in_layer_;
};
diff --git a/src/kiwano/2d/action/Action.h b/src/kiwano/2d/action/Action.h
index 427bb215..ce7eb0c2 100644
--- a/src/kiwano/2d/action/Action.h
+++ b/src/kiwano/2d/action/Action.h
@@ -28,7 +28,7 @@ namespace kiwano
class ActionManager;
class KGE_API Action
- : public Object
+ : public ObjectBase
, protected intrusive_list_item
{
friend class ActionManager;
diff --git a/src/kiwano/2d/action/ActionGroup.cpp b/src/kiwano/2d/action/ActionGroup.cpp
index fd1a646a..0cd36d40 100644
--- a/src/kiwano/2d/action/ActionGroup.cpp
+++ b/src/kiwano/2d/action/ActionGroup.cpp
@@ -45,7 +45,7 @@ namespace kiwano
void ActionGroup::Init(ActorPtr target)
{
- if (actions_.is_empty())
+ if (actions_.item_empty())
{
Done();
return;
@@ -135,7 +135,7 @@ namespace kiwano
ActionPtr ActionGroup::Reverse() const
{
auto group = new (std::nothrow) ActionGroup();
- if (group && !actions_.is_empty())
+ if (group && !actions_.item_empty())
{
for (auto action = actions_.last_item(); action; action = action->prev_item())
{
diff --git a/src/kiwano/2d/action/ActionManager.cpp b/src/kiwano/2d/action/ActionManager.cpp
index 3428bd8a..2a0c5ac5 100644
--- a/src/kiwano/2d/action/ActionManager.cpp
+++ b/src/kiwano/2d/action/ActionManager.cpp
@@ -26,7 +26,7 @@ namespace kiwano
{
void ActionManager::UpdateActions(ActorPtr target, Duration dt)
{
- if (actions_.is_empty() || !target)
+ if (actions_.item_empty() || !target)
return;
ActionPtr next;
@@ -55,7 +55,7 @@ namespace kiwano
ActionPtr ActionManager::GetAction(String const & name)
{
- if (actions_.is_empty())
+ if (actions_.item_empty())
return nullptr;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@@ -66,7 +66,7 @@ namespace kiwano
void ActionManager::ResumeAllActions()
{
- if (actions_.is_empty())
+ if (actions_.item_empty())
return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@@ -77,7 +77,7 @@ namespace kiwano
void ActionManager::PauseAllActions()
{
- if (actions_.is_empty())
+ if (actions_.item_empty())
return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@@ -88,7 +88,7 @@ namespace kiwano
void ActionManager::StopAllActions()
{
- if (actions_.is_empty())
+ if (actions_.item_empty())
return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
diff --git a/src/kiwano/2d/include-forwards.h b/src/kiwano/2d/include-forwards.h
index 98f832e4..edbbf0ae 100644
--- a/src/kiwano/2d/include-forwards.h
+++ b/src/kiwano/2d/include-forwards.h
@@ -19,15 +19,14 @@
// THE SOFTWARE.
#pragma once
-#include "Color.h"
#include "../core/core.h"
#include "../base/time.h"
#include "../base/RefCounter.hpp"
#include "../base/SmartPtr.hpp"
-#include "../base/ComPtr.hpp"
-#include "../base/Object.h"
-#include "../math/helper.h"
+#include "../base/ObjectBase.h"
#include "../base/types.h"
+#include "../math/math.h"
+#include "../renderer/Color.h"
namespace kiwano
{
diff --git a/src/kiwano/base/AsyncTask.h b/src/kiwano/base/AsyncTask.h
index f1d31efa..15551475 100644
--- a/src/kiwano/base/AsyncTask.h
+++ b/src/kiwano/base/AsyncTask.h
@@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "Object.h"
+#include "ObjectBase.h"
#include
#include
@@ -31,7 +31,7 @@ namespace kiwano
typedef Function AsyncTaskCallback;
class AsyncTask
- : public Object
+ : public ObjectBase
{
public:
AsyncTask();
diff --git a/src/kiwano/base/Director.cpp b/src/kiwano/base/Director.cpp
index 89ee9fe4..39d5d36e 100644
--- a/src/kiwano/base/Director.cpp
+++ b/src/kiwano/base/Director.cpp
@@ -146,7 +146,9 @@ namespace kiwano
if (render_border_enabled_)
{
if (curr_scene_)
+ {
curr_scene_->RenderBorder();
+ }
}
}
diff --git a/src/kiwano/base/EventDispatcher.cpp b/src/kiwano/base/EventDispatcher.cpp
index 8dc93e26..d46fbb3b 100644
--- a/src/kiwano/base/EventDispatcher.cpp
+++ b/src/kiwano/base/EventDispatcher.cpp
@@ -25,7 +25,7 @@ namespace kiwano
{
void EventDispatcher::Dispatch(Event& evt)
{
- if (listeners_.is_empty())
+ if (listeners_.item_empty())
return;
EventListenerPtr next;
diff --git a/src/kiwano/base/EventListener.h b/src/kiwano/base/EventListener.h
index 40ed7aa0..f07e83f3 100644
--- a/src/kiwano/base/EventListener.h
+++ b/src/kiwano/base/EventListener.h
@@ -21,7 +21,7 @@
#pragma once
#include "../core/core.h"
#include "../base/SmartPtr.hpp"
-#include "Object.h"
+#include "ObjectBase.h"
#include "Event.hpp"
namespace kiwano
@@ -34,7 +34,7 @@ namespace kiwano
// 事件监听器
class KGE_API EventListener
- : public Object
+ : public ObjectBase
, protected intrusive_list_item
{
friend class EventDispatcher;
diff --git a/src/kiwano/base/Input.h b/src/kiwano/base/Input.h
index e23b3796..2cbc24bc 100644
--- a/src/kiwano/base/Input.h
+++ b/src/kiwano/base/Input.h
@@ -21,7 +21,7 @@
#pragma once
#include "../macros.h"
#include "../core/core.h"
-#include "../math/helper.h"
+#include "../math/math.h"
#include "keys.hpp"
#include "Component.h"
diff --git a/src/kiwano/base/Object.cpp b/src/kiwano/base/ObjectBase.cpp
similarity index 78%
rename from src/kiwano/base/Object.cpp
rename to src/kiwano/base/ObjectBase.cpp
index 888e9108..b3020125 100644
--- a/src/kiwano/base/Object.cpp
+++ b/src/kiwano/base/ObjectBase.cpp
@@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include "Object.h"
+#include "ObjectBase.h"
#include "Logger.h"
#include
@@ -27,12 +27,12 @@ namespace kiwano
namespace
{
bool tracing_leaks = false;
- Vector