diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj
index 070d909b..39a9021c 100644
--- a/projects/kiwano.vcxproj
+++ b/projects/kiwano.vcxproj
@@ -67,6 +67,7 @@
+
@@ -127,6 +128,7 @@
+
diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters
index e3db99d4..8995881e 100644
--- a/projects/kiwano.vcxproj.filters
+++ b/projects/kiwano.vcxproj.filters
@@ -303,6 +303,9 @@
renderer
+
+ renderer
+
@@ -473,5 +476,8 @@
renderer
+
+ renderer
+
\ No newline at end of file
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 cb9da0a0..8ad90766 100644
--- a/src/kiwano-audio/src/Player.h
+++ b/src/kiwano-audio/src/Player.h
@@ -33,42 +33,45 @@ namespace kiwano
class KGE_API Player
: 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 9cf9e71f..d39f457f 100644
--- a/src/kiwano-audio/src/Sound.h
+++ b/src/kiwano-audio/src/Sound.h
@@ -37,12 +37,21 @@ namespace kiwano
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 7189690c..0e38305e 100644
--- a/src/kiwano-audio/src/Transcoder.cpp
+++ b/src/kiwano-audio/src/Transcoder.cpp
@@ -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/2d/Frame.cpp b/src/kiwano/2d/Frame.cpp
index 9fbd506e..ff99edde 100644
--- a/src/kiwano/2d/Frame.cpp
+++ b/src/kiwano/2d/Frame.cpp
@@ -27,19 +27,35 @@ namespace kiwano
{
}
+ Frame::Frame(String const& file_path)
+ {
+ Load(file_path);
+ }
+
Frame::Frame(Resource const& res)
{
Load(res);
}
Frame::Frame(Image const& image)
- : image_(image)
{
+ SetImage(image);
+ }
+
+ bool Frame::Load(String const& file_path)
+ {
+ Image image = ImageCache::GetInstance()->AddOrGetImage(file_path);
+ if (image.IsValid())
+ {
+ SetImage(image);
+ return true;
+ }
+ return false;
}
bool Frame::Load(Resource const& res)
{
- Image image = ImageCache::GetInstance()->AddImage(res);
+ Image image = ImageCache::GetInstance()->AddOrGetImage(res);
if (image.IsValid())
{
SetImage(image);
diff --git a/src/kiwano/2d/Frame.h b/src/kiwano/2d/Frame.h
index 3ee92fb3..9f13d4f0 100644
--- a/src/kiwano/2d/Frame.h
+++ b/src/kiwano/2d/Frame.h
@@ -30,6 +30,10 @@ namespace kiwano
public:
Frame();
+ explicit Frame(
+ String const& file_path
+ );
+
explicit Frame(
Resource const& res
);
@@ -38,6 +42,10 @@ namespace kiwano
Image const& image
);
+ bool Load(
+ String const& file_path
+ );
+
bool Load(
Resource const& res
);
@@ -47,6 +55,11 @@ namespace kiwano
Rect const& crop_rect /* 裁剪矩形 */
);
+ // 设置位图
+ void SetImage(
+ Image const& image
+ );
+
// 获取宽度
float GetWidth() const { return crop_rect_.size.x; }
@@ -65,9 +78,6 @@ namespace kiwano
// 获取位图
inline Image const& GetImage() const { return image_; }
- // 设置位图
- void SetImage(Image const& image);
-
protected:
Image image_;
Rect crop_rect_;
diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp
index e331fcf8..08c9c471 100644
--- a/src/kiwano/2d/GifSprite.cpp
+++ b/src/kiwano/2d/GifSprite.cpp
@@ -34,26 +34,37 @@ namespace kiwano
{
}
+ 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 = ImageCache::GetInstance()->AddGifImage(res);
+ 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;
@@ -62,8 +73,8 @@ namespace kiwano
disposal_type_ = DisposalType::None;
SetSize(
- static_cast(image_->GetWidthInPixels()),
- static_cast(image_->GetHeightInPixels())
+ static_cast(image_.GetWidthInPixels()),
+ static_cast(image_.GetHeightInPixels())
);
if (!frame_rt_.IsValid())
@@ -71,7 +82,7 @@ namespace kiwano
Renderer::GetInstance()->CreateImageRenderTarget(frame_rt_);
}
- if (image_->GetFramesCount() > 0)
+ if (image_.GetFramesCount() > 0)
{
ComposeNextFrame();
}
@@ -94,7 +105,7 @@ namespace kiwano
{
Actor::Update(dt);
- if (image_ && animating_)
+ if (image_.IsValid() && animating_)
{
frame_elapsed_ += dt;
if (frame_delay_ <= frame_elapsed_)
@@ -124,7 +135,7 @@ namespace kiwano
OverlayNextFrame();
} while (frame_delay_.IsZero() && !IsLastFrame());
- animating_ = (!EndOfAnimation() && image_->GetFramesCount() > 1);
+ animating_ = (!EndOfAnimation() && image_.GetFramesCount() > 1);
}
}
@@ -157,7 +168,7 @@ namespace kiwano
{
Image raw_image;
- HRESULT hr = image_->GetRawFrame(next_index_, raw_image, frame_rect_, frame_delay_, disposal_type_);
+ HRESULT hr = image_.GetRawFrame(next_index_, raw_image, frame_rect_, frame_delay_, disposal_type_);
if (SUCCEEDED(hr))
{
@@ -174,7 +185,7 @@ namespace kiwano
if (next_index_ == 0)
{
// 重新绘制背景
- frame_rt_.Clear(image_->GetBackgroundColor());
+ frame_rt_.Clear(image_.GetBackgroundColor());
loop_count_++;
}
@@ -192,7 +203,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
frame_ = frame_to_render;
- next_index_ = (++next_index_) % image_->GetFramesCount();
+ next_index_ = (++next_index_) % image_.GetFramesCount();
}
}
@@ -266,7 +277,7 @@ namespace kiwano
frame_rt_.BeginDraw();
frame_rt_.PushClipRect(frame_rect_);
- frame_rt_.Clear(image_->GetBackgroundColor());
+ 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 4e1f2a41..6fec6a03 100644
--- a/src/kiwano/2d/GifSprite.h
+++ b/src/kiwano/2d/GifSprite.h
@@ -37,12 +37,20 @@ namespace kiwano
GifSprite();
+ GifSprite(
+ String const& file_path
+ );
+
GifSprite(
Resource const& res
);
GifSprite(
- GifImagePtr image
+ GifImage image
+ );
+
+ bool Load(
+ String const& file_path
);
bool Load(
@@ -50,7 +58,7 @@ namespace kiwano
);
bool Load(
- GifImagePtr image
+ GifImage image
);
// 设置 GIF 动画循环次数
@@ -100,7 +108,7 @@ namespace kiwano
DisposalType disposal_type_;
LoopDoneCallback loop_cb_;
DoneCallback done_cb_;
- GifImagePtr image_;
+ GifImage image_;
Image frame_;
Rect frame_rect_;
Image saved_frame_;
diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp
index 64331909..688faf90 100644
--- a/src/kiwano/2d/Sprite.cpp
+++ b/src/kiwano/2d/Sprite.cpp
@@ -24,18 +24,26 @@
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);
SetCropRect(crop_rect);
@@ -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;
diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h
index 8cd03aad..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,6 +55,11 @@ namespace kiwano
virtual ~Sprite();
+ // 加载图像
+ bool Load(
+ String const& file_path
+ );
+
// 加载图像资源
bool Load(
Resource const& res
diff --git a/src/kiwano/base/Resource.cpp b/src/kiwano/base/Resource.cpp
index b20d87f3..1ea7ee67 100644
--- a/src/kiwano/base/Resource.cpp
+++ b/src/kiwano/base/Resource.cpp
@@ -21,114 +21,63 @@
#include "Resource.h"
#include "../base/Logger.h"
+#include
namespace kiwano
{
- Resource::Resource(LPCWSTR file_name)
- : type_(Type::File)
- , bin_id_(0)
- , bin_type_(nullptr)
+ Resource::Resource()
+ : id_(0)
+ , type_(nullptr)
{
- if (file_name)
- file_name_ = new (std::nothrow) String(file_name);
- }
- Resource::Resource(String const& file_name)
- : type_(Type::File)
- , bin_id_(0)
- , bin_type_(nullptr)
- {
- if (!file_name.empty())
- file_name_ = new (std::nothrow) String(file_name);
}
Resource::Resource(UINT id, LPCWSTR type)
- : type_(Type::Binary)
- , bin_id_(id)
- , bin_type_(type)
+ : id_(id)
+ , type_(type)
{
}
- Resource::Resource(Resource const & rhs)
+ Resource::Data Resource::GetData() const
{
- operator=(rhs);
- }
-
- Resource::~Resource()
- {
- if (IsFileType() && file_name_)
- delete file_name_;
- }
-
- size_t Resource::GetHashCode() const
- {
- return (type_ == Type::File) ? GetFileName().hash() : static_cast(bin_id_);
- }
-
- Resource & Resource::operator=(Resource const & rhs)
- {
- if (&rhs != this)
+ do
{
- if (IsFileType() && file_name_)
+ if (data_.buffer && data_.size)
{
- delete file_name_;
- file_name_ = nullptr;
+ break;
}
- type_ = rhs.type_;
- if (IsFileType())
+ HRSRC res_info = FindResourceW(nullptr, MAKEINTRESOURCE(id_), type_);
+ if (res_info == nullptr)
{
- if (rhs.file_name_)
- {
- file_name_ = new (std::nothrow) String(*rhs.file_name_);
- }
+ KGE_ERROR_LOG(L"FindResource failed");
+ break;
}
- else
+
+ HGLOBAL res_data = LoadResource(nullptr, res_info);
+ if (res_data == nullptr)
{
- bin_id_ = rhs.bin_id_;
- bin_type_ = rhs.bin_type_;
+ KGE_ERROR_LOG(L"LoadResource failed");
+ break;
}
- }
- return *this;
- }
- bool Resource::Load(LPVOID& buffer, DWORD& buffer_size) const
- {
- if (type_ != Type::Binary)
- {
- KGE_ERROR_LOG(L"Only binary resource can be loaded");
- return false;
- }
+ DWORD size = SizeofResource(nullptr, res_info);
+ if (size == 0)
+ {
+ KGE_ERROR_LOG(L"SizeofResource failed");
+ break;
+ }
- HGLOBAL res_data;
- HRSRC res_info;
+ LPVOID buffer = LockResource(res_data);
+ if (buffer == nullptr)
+ {
+ KGE_ERROR_LOG(L"LockResource failed");
+ break;
+ }
- res_info = FindResourceW(nullptr, MAKEINTRESOURCE(bin_id_), bin_type_);
- if (res_info == nullptr)
- {
- KGE_ERROR_LOG(L"FindResource failed");
- return false;
- }
+ data_.buffer = static_cast(buffer);
+ data_.size = static_cast(size);
+ } while (0);
- res_data = LoadResource(nullptr, res_info);
- if (res_data == nullptr)
- {
- KGE_ERROR_LOG(L"LoadResource failed");
- return false;
- }
-
- buffer_size = SizeofResource(nullptr, res_info);
- if (buffer_size == 0)
- {
- KGE_ERROR_LOG(L"SizeofResource failed");
- return false;
- }
-
- buffer = LockResource(res_data);
- if (buffer == nullptr)
- {
- KGE_ERROR_LOG(L"LockResource failed");
- return false;
- }
- return true;
+ return data_;
}
}
diff --git a/src/kiwano/base/Resource.h b/src/kiwano/base/Resource.h
index 80a1129a..32f990d3 100644
--- a/src/kiwano/base/Resource.h
+++ b/src/kiwano/base/Resource.h
@@ -26,64 +26,43 @@ namespace kiwano
{
// 资源
//
- // 资源可以是文件类型,也可以是保存在 exe 中的二进制资源
+ // 资源是保存在 exe 中的二进制数据
// 例如, 一份音频资源的类型为 L"WAVE", 名称标识符为 IDR_WAVE_1,
- // 那么可以这样指定该资源: Resource res(IDR_WAVE_1, L"WAVE");
+ // 那么可以这样指定该资源: Resource(IDR_WAVE_1, L"WAVE");
//
// 了解资源的更多信息: https://docs.microsoft.com/en-us/windows/desktop/menurc/resources
//
class KGE_API Resource
{
- enum class Type { File, Binary };
-
public:
- Resource(
- LPCWSTR file_name /* 文件路径 */
- );
+ // 二进制数据
+ struct Data
+ {
+ void* buffer;
+ UINT32 size;
+
+ inline Data() : buffer(nullptr), size(0) {}
+
+ inline operator bool() const { return buffer && size; }
+ };
+
+ Resource();
Resource(
- String const& file_name /* 文件路径 */
+ UINT id, /* 资源名称 */
+ LPCWSTR type /* 资源类型 */
);
- Resource(
- UINT id, /* 资源名称 */
- LPCWSTR type /* 资源类型 */
- );
+ // 获取二进制数据
+ Resource::Data GetData() const;
- Resource(
- Resource const& rhs
- );
+ inline UINT GetId() const { return id_; }
- virtual ~Resource();
-
- bool Load(LPVOID& buffer, DWORD& buffer_size) const;
-
- size_t GetHashCode() const;
-
- Resource& operator= (Resource const& rhs);
-
- inline bool IsFileType() const { return type_ == Type::File; }
-
- inline String GetFileName() const { return file_name_ ? (*file_name_) : L""; }
-
- inline UINT GetResourceId() const { return bin_id_; }
-
- inline LPCWSTR GetResourceType() const { return bin_type_; }
+ inline LPCWSTR GetType() const { return type_; }
private:
- Type type_;
- union
- {
- struct
- {
- String* file_name_;
- };
-
- struct
- {
- UINT bin_id_;
- LPCWSTR bin_type_;
- };
- };
+ UINT id_;
+ LPCWSTR type_;
+ mutable Resource::Data data_;
};
}
diff --git a/src/kiwano/renderer/Font.cpp b/src/kiwano/renderer/Font.cpp
index 8ab74f91..1c0016c3 100644
--- a/src/kiwano/renderer/Font.cpp
+++ b/src/kiwano/renderer/Font.cpp
@@ -19,34 +19,9 @@
// THE SOFTWARE.
#include "Font.h"
-#include "Renderer.h"
namespace kiwano
{
- //
- // FontCollection
- //
-
- FontCollection::FontCollection()
- {
- }
-
- FontCollection::FontCollection(Resource const& res)
- {
- Load(res);
- }
-
- bool FontCollection::Load(Resource const& res)
- {
- Renderer::GetInstance()->CreateFontFromResource(*this, res);
- return false;
- }
-
-
- //
- // Font
- //
-
Font::Font(const String& family, float size, unsigned int weight, bool italic, FontCollection collection)
: family(family)
, size(size)
diff --git a/src/kiwano/renderer/Font.h b/src/kiwano/renderer/Font.h
index 43aa6441..f389df68 100644
--- a/src/kiwano/renderer/Font.h
+++ b/src/kiwano/renderer/Font.h
@@ -19,10 +19,7 @@
// THE SOFTWARE.
#pragma once
-#include "../core/core.h"
-#include "../base/Resource.h"
-#include "win32/ComPtr.hpp"
-#include
+#include "FontCollection.h"
namespace kiwano
{
@@ -40,28 +37,6 @@ namespace kiwano
ExtraBlack = 950
};
-
- // 字体集
- class FontCollection
- {
- public:
- FontCollection();
-
- FontCollection(Resource const& res);
-
- // 从资源加载字体集
- bool Load(Resource const& res);
-
- public:
- inline ComPtr GetFontCollection() const { return collection_; }
-
- inline void SetFontCollection(ComPtr collection) { collection_ = collection; }
-
- protected:
- ComPtr collection_;
- };
-
-
// 字体
class Font
{
diff --git a/src/kiwano/renderer/FontCollection.cpp b/src/kiwano/renderer/FontCollection.cpp
new file mode 100644
index 00000000..87661691
--- /dev/null
+++ b/src/kiwano/renderer/FontCollection.cpp
@@ -0,0 +1,73 @@
+// Copyright (c) 2016-2018 Kiwano - Nomango
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "FontCollection.h"
+#include "Renderer.h"
+
+namespace kiwano
+{
+ FontCollection::FontCollection()
+ {
+ }
+
+ FontCollection::FontCollection(String const& file)
+ {
+ Load(file);
+ }
+
+ FontCollection::FontCollection(Vector const& files)
+ {
+ Load(files);
+ }
+
+ FontCollection::FontCollection(Resource const& res)
+ {
+ Load(res);
+ }
+
+ FontCollection::FontCollection(Vector const& res_arr)
+ {
+ Load(res_arr);
+ }
+
+ bool FontCollection::Load(String const& file)
+ {
+ Renderer::GetInstance()->CreateFontCollection(*this, { file });
+ return false;
+ }
+
+ bool FontCollection::Load(Vector const& files)
+ {
+ Renderer::GetInstance()->CreateFontCollection(*this, files);
+ return false;
+ }
+
+ bool FontCollection::Load(Resource const& res)
+ {
+ Renderer::GetInstance()->CreateFontCollection(*this, { res });
+ return false;
+ }
+
+ bool FontCollection::Load(Vector const& res_arr)
+ {
+ Renderer::GetInstance()->CreateFontCollection(*this, res_arr);
+ return false;
+ }
+}
diff --git a/src/kiwano/renderer/FontCollection.h b/src/kiwano/renderer/FontCollection.h
new file mode 100644
index 00000000..e4297181
--- /dev/null
+++ b/src/kiwano/renderer/FontCollection.h
@@ -0,0 +1,62 @@
+// Copyright (c) 2016-2018 Kiwano - Nomango
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#pragma once
+#include "../base/Resource.h"
+#include "win32/ComPtr.hpp"
+#include
+
+namespace kiwano
+{
+ // 字体集
+ class FontCollection
+ {
+ public:
+ FontCollection();
+
+ FontCollection(String const& file);
+
+ FontCollection(Vector const& files);
+
+ FontCollection(Resource const& res);
+
+ FontCollection(Vector const& res_arr);
+
+ // 从本地文件加载字体
+ bool Load(String const& file);
+
+ // 从多个本地文件加载字体
+ bool Load(Vector const& files);
+
+ // 从资源加载字体
+ bool Load(Resource const& res);
+
+ // 从多个资源加载字体
+ bool Load(Vector const& res_arr);
+
+ public:
+ inline ComPtr GetFontCollection() const { return collection_; }
+
+ inline void SetFontCollection(ComPtr collection) { collection_ = collection; }
+
+ protected:
+ ComPtr collection_;
+ };
+}
diff --git a/src/kiwano/renderer/GifImage.cpp b/src/kiwano/renderer/GifImage.cpp
index 49c54acd..a057a663 100644
--- a/src/kiwano/renderer/GifImage.cpp
+++ b/src/kiwano/renderer/GifImage.cpp
@@ -32,12 +32,33 @@ namespace kiwano
{
}
+ GifImage::GifImage(String const& file_path)
+ {
+ Load(file_path);
+ }
+
GifImage::GifImage(Resource const& res)
: GifImage()
{
Load(res);
}
+ bool GifImage::Load(String const& file_path)
+ {
+ Renderer::GetInstance()->CreateGifImage(*this, file_path);
+
+ if (IsValid())
+ {
+ if (FAILED(GetGlobalMetadata()))
+ {
+ SetDecoder(nullptr);
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
bool GifImage::Load(Resource const& res)
{
Renderer::GetInstance()->CreateGifImage(*this, res);
diff --git a/src/kiwano/renderer/GifImage.h b/src/kiwano/renderer/GifImage.h
index bcd6efff..30538924 100644
--- a/src/kiwano/renderer/GifImage.h
+++ b/src/kiwano/renderer/GifImage.h
@@ -24,15 +24,17 @@
namespace kiwano
{
// GIF 图像
- KGE_DECLARE_SMART_PTR(GifImage);
class KGE_API GifImage
- : public ObjectBase
{
public:
GifImage();
+ GifImage(String const& file_path);
+
GifImage(Resource const& res);
+ bool Load(String const& file_path);
+
bool Load(Resource const& res);
bool IsValid() const;
diff --git a/src/kiwano/renderer/Image.cpp b/src/kiwano/renderer/Image.cpp
index 5fbd80ae..ef001ad6 100644
--- a/src/kiwano/renderer/Image.cpp
+++ b/src/kiwano/renderer/Image.cpp
@@ -28,13 +28,17 @@ namespace kiwano
{
}
+ Image::Image(String const& file_path)
+ {
+ Load(file_path);
+ }
+
Image::Image(Resource const& res)
{
Load(res);
}
Image::Image(ComPtr const & bitmap)
- : Image()
{
SetBitmap(bitmap);
}
@@ -43,6 +47,12 @@ namespace kiwano
{
}
+ bool Image::Load(String const& file_path)
+ {
+ Renderer::GetInstance()->CreateImage(*this, file_path);
+ return IsValid();
+ }
+
bool Image::Load(Resource const& res)
{
Renderer::GetInstance()->CreateImage(*this, res);
diff --git a/src/kiwano/renderer/Image.h b/src/kiwano/renderer/Image.h
index 2444aaae..ec3aa193 100644
--- a/src/kiwano/renderer/Image.h
+++ b/src/kiwano/renderer/Image.h
@@ -29,6 +29,10 @@ namespace kiwano
public:
Image();
+ explicit Image(
+ String const& file_path
+ );
+
explicit Image(
Resource const& res
);
@@ -39,6 +43,11 @@ namespace kiwano
virtual ~Image();
+ // 加载本地文件
+ bool Load(
+ String const& file_path
+ );
+
// 加载资源
bool Load(
Resource const& res
diff --git a/src/kiwano/renderer/ImageCache.cpp b/src/kiwano/renderer/ImageCache.cpp
index e950d1bc..3437c6c4 100644
--- a/src/kiwano/renderer/ImageCache.cpp
+++ b/src/kiwano/renderer/ImageCache.cpp
@@ -24,6 +24,32 @@
namespace kiwano
{
+ template
+ _Ty CreateOrGetCache(_CacheTy& cache, _PathTy const& path, size_t hash)
+ {
+ auto iter = cache.find(hash);
+ if (iter != cache.end())
+ {
+ return iter->second;
+ }
+
+ _Ty image;
+ if (image.Load(path))
+ {
+ cache.insert(std::make_pair(hash, image));
+ }
+ return image;
+ }
+
+ template
+ void RemoveCache(_CacheTy& cache, size_t hash)
+ {
+ auto iter = cache.find(hash);
+ if (iter != cache.end())
+ {
+ cache.erase(iter);
+ }
+ }
ImageCache::ImageCache()
{
@@ -33,62 +59,44 @@ namespace kiwano
{
}
- Image ImageCache::AddImage(Resource const& res)
+ Image ImageCache::AddOrGetImage(String const& file_path)
{
- size_t hash_code = res.GetHashCode();
+ return CreateOrGetCache(image_cache_, file_path, file_path.hash());
+ }
- auto iter = image_cache_.find(hash_code);
- if (iter != image_cache_.end())
- {
- return iter->second;
- }
+ Image ImageCache::AddOrGetImage(Resource const& res)
+ {
+ return CreateOrGetCache(image_cache_, res, res.GetId());
+ }
- Image image;
- if (image.Load(res))
- {
- image_cache_.insert(std::make_pair(hash_code, image));
- }
- return image;
+ GifImage ImageCache::AddOrGetGifImage(String const& file_path)
+ {
+ return CreateOrGetCache(gif_image_cache_, file_path, file_path.hash());
+ }
+
+ GifImage ImageCache::AddOrGetGifImage(Resource const& res)
+ {
+ return CreateOrGetCache(gif_image_cache_, res, res.GetId());
+ }
+
+ void ImageCache::RemoveImage(String const& file_path)
+ {
+ RemoveCache(image_cache_, file_path.hash());
}
void ImageCache::RemoveImage(Resource const& res)
{
- size_t hash_code = res.GetHashCode();
-
- auto iter = image_cache_.find(hash_code);
- if (iter != image_cache_.end())
- {
- image_cache_.erase(iter);
- }
+ RemoveCache(image_cache_, res.GetId());
}
- GifImagePtr ImageCache::AddGifImage(Resource const& res)
+ void ImageCache::RemoveGifImage(String const& file_path)
{
- size_t hash_code = res.GetHashCode();
-
- auto iter = gif_image_cache_.find(hash_code);
- if (iter != gif_image_cache_.end())
- {
- return iter->second;
- }
-
- GifImagePtr ptr = new GifImage;
- if (ptr->Load(res))
- {
- gif_image_cache_.insert(std::make_pair(hash_code, ptr));
- }
- return ptr;
+ RemoveCache(gif_image_cache_, file_path.hash());
}
void ImageCache::RemoveGifImage(Resource const& res)
{
- size_t hash_code = res.GetHashCode();
-
- auto iter = gif_image_cache_.find(hash_code);
- if (iter != gif_image_cache_.end())
- {
- gif_image_cache_.erase(iter);
- }
+ RemoveCache(gif_image_cache_, res.GetId());
}
void ImageCache::Clear()
diff --git a/src/kiwano/renderer/ImageCache.h b/src/kiwano/renderer/ImageCache.h
index f6b62162..25076f12 100644
--- a/src/kiwano/renderer/ImageCache.h
+++ b/src/kiwano/renderer/ImageCache.h
@@ -30,12 +30,14 @@ namespace kiwano
KGE_DECLARE_SINGLETON(ImageCache);
public:
- Image AddImage(Resource const& res);
+ Image AddOrGetImage(String const& file_path);
+ Image AddOrGetImage(Resource const& res);
+ GifImage AddOrGetGifImage(String const& file_path);
+ GifImage AddOrGetGifImage(Resource const& res);
+ void RemoveImage(String const& file_path);
void RemoveImage(Resource const& res);
-
- GifImagePtr AddGifImage(Resource const& res);
-
+ void RemoveGifImage(String const& file_path);
void RemoveGifImage(Resource const& res);
void Clear();
@@ -49,7 +51,7 @@ namespace kiwano
using ImageMap = UnorderedMap;
ImageMap image_cache_;
- using GifImageMap = UnorderedMap;
+ using GifImageMap = UnorderedMap;
GifImageMap gif_image_cache_;
};
}
diff --git a/src/kiwano/renderer/Renderer.cpp b/src/kiwano/renderer/Renderer.cpp
index fcba68cc..74bb8f18 100644
--- a/src/kiwano/renderer/Renderer.cpp
+++ b/src/kiwano/renderer/Renderer.cpp
@@ -232,6 +232,31 @@ namespace kiwano
return hr;
}
+ void Renderer::CreateImage(Image& image, String const& file_path)
+ {
+ HRESULT hr = S_OK;
+ if (!d2d_res_)
+ {
+ hr = E_UNEXPECTED;
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ ComPtr bitmap;
+ hr = d2d_res_->CreateBitmapFromFile(bitmap, file_path);
+
+ if (SUCCEEDED(hr))
+ {
+ image.SetBitmap(bitmap);
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ KGE_WARNING_LOG(L"Load image failed with HRESULT of %08X!", hr);
+ }
+ }
+
void Renderer::CreateImage(Image& image, Resource const& res)
{
HRESULT hr = S_OK;
@@ -240,19 +265,15 @@ namespace kiwano
hr = E_UNEXPECTED;
}
- ComPtr bitmap;
- if (res.IsFileType())
- {
- hr = d2d_res_->CreateBitmapFromFile(bitmap, res.GetFileName());
- }
- else
- {
- hr = d2d_res_->CreateBitmapFromResource(bitmap, res);
- }
-
if (SUCCEEDED(hr))
{
- image.SetBitmap(bitmap);
+ ComPtr bitmap;
+ hr = d2d_res_->CreateBitmapFromResource(bitmap, res);
+
+ if (SUCCEEDED(hr))
+ {
+ image.SetBitmap(bitmap);
+ }
}
if (FAILED(hr))
@@ -261,6 +282,43 @@ namespace kiwano
}
}
+ void Renderer::CreateGifImage(GifImage& image, String const& file_path)
+ {
+ HRESULT hr = S_OK;
+ if (!d2d_res_)
+ {
+ hr = E_UNEXPECTED;
+ }
+
+ if (!FileUtil::ExistsFile(file_path))
+ {
+ KGE_WARNING_LOG(L"Gif image file '%s' not found!", file_path.c_str());
+ hr = E_FAIL;
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ ComPtr decoder;
+ hr = d2d_res_->GetWICImagingFactory()->CreateDecoderFromFilename(
+ file_path.c_str(),
+ nullptr,
+ GENERIC_READ,
+ WICDecodeMetadataCacheOnLoad,
+ &decoder
+ );
+
+ if (SUCCEEDED(hr))
+ {
+ image.SetDecoder(decoder);
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ KGE_WARNING_LOG(L"Load GIF image failed with HRESULT of %08X!", hr);
+ }
+ }
+
void Renderer::CreateGifImage(GifImage& image, Resource const& res)
{
HRESULT hr = S_OK;
@@ -269,61 +327,38 @@ namespace kiwano
hr = E_UNEXPECTED;
}
- ComPtr decoder;
- if (res.IsFileType())
- {
- if (!FileUtil::ExistsFile(res.GetFileName().c_str()))
- {
- KGE_WARNING_LOG(L"Gif image file '%s' not found!", res.GetFileName().c_str());
- hr = E_FAIL;
- }
+ Resource::Data res_data = res.GetData();
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->GetWICImagingFactory()->CreateDecoderFromFilename(
- res.GetFileName().c_str(),
- nullptr,
- GENERIC_READ,
- WICDecodeMetadataCacheOnLoad,
- &decoder
- );
- }
- }
- else
- {
- LPVOID buffer;
- DWORD buffer_size;
- HRESULT hr = res.Load(buffer, buffer_size) ? S_OK : E_FAIL;
+ hr = res_data ? S_OK : E_FAIL;
+ if (SUCCEEDED(hr))
+ {
ComPtr stream;
-
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->GetWICImagingFactory()->CreateStream(&stream);
- }
+ hr = d2d_res_->GetWICImagingFactory()->CreateStream(&stream);
if (SUCCEEDED(hr))
{
hr = stream->InitializeFromMemory(
- static_cast(buffer),
- buffer_size
+ static_cast(res_data.buffer),
+ res_data.size
);
}
if (SUCCEEDED(hr))
{
+ ComPtr decoder;
hr = d2d_res_->GetWICImagingFactory()->CreateDecoderFromStream(
stream.get(),
nullptr,
WICDecodeMetadataCacheOnLoad,
&decoder
);
- }
- }
- if (SUCCEEDED(hr))
- {
- image.SetDecoder(decoder);
+ if (SUCCEEDED(hr))
+ {
+ image.SetDecoder(decoder);
+ }
+ }
}
if (FAILED(hr))
@@ -332,7 +367,7 @@ namespace kiwano
}
}
- void Renderer::CreateFontFromResource(FontCollection& collection, Resource const& res)
+ void Renderer::CreateFontCollection(FontCollection& collection, Vector const& file_paths)
{
HRESULT hr = S_OK;
if (!d2d_res_)
@@ -340,37 +375,78 @@ namespace kiwano
hr = E_UNEXPECTED;
}
- ComPtr font_collection;
- if (res.IsFileType())
+ if (SUCCEEDED(hr))
{
- String file_path = res.GetFileName();
- if (!FileUtil::ExistsFile(file_path.c_str()))
+ for (const auto& file_path : file_paths)
{
- KGE_WARNING_LOG(L"Font file '%s' not found!", file_path.c_str());
- hr = E_FAIL;
+ if (!FileUtil::ExistsFile(file_path))
+ {
+ KGE_WARNING_LOG(L"Font file '%s' not found!", file_path.c_str());
+ hr = E_FAIL;
+ }
}
-
- hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(
- font_collection_loader_.get(),
- reinterpret_cast(&file_path),
- sizeof(file_path),
- &font_collection
- );
- }
- else
- {
- UINT id = res.GetResourceId();
- hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(
- res_font_collection_loader_.get(),
- reinterpret_cast(&id),
- sizeof(id),
- &font_collection
- );
}
if (SUCCEEDED(hr))
{
- collection.SetFontCollection(font_collection);
+ LPVOID collection_key = nullptr;
+ UINT32 collection_key_size = 0;
+
+ hr = font_collection_loader_->AddFilePaths(file_paths, &collection_key, &collection_key_size);
+
+ if (SUCCEEDED(hr))
+ {
+ ComPtr font_collection;
+ hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(
+ font_collection_loader_.get(),
+ collection_key,
+ collection_key_size,
+ &font_collection
+ );
+
+ if (SUCCEEDED(hr))
+ {
+ collection.SetFontCollection(font_collection);
+ }
+ }
+ }
+
+ if (FAILED(hr))
+ {
+ KGE_WARNING_LOG(L"Load font failed with HRESULT of %08X!", hr);
+ }
+ }
+
+ void Renderer::CreateFontCollection(FontCollection& collection, Vector const& res_arr)
+ {
+ HRESULT hr = S_OK;
+ if (!d2d_res_)
+ {
+ hr = E_UNEXPECTED;
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ LPVOID collection_key = nullptr;
+ UINT32 collection_key_size = 0;
+
+ hr = res_font_collection_loader_->AddResources(res_arr, &collection_key, &collection_key_size);
+
+ if (SUCCEEDED(hr))
+ {
+ ComPtr font_collection;
+ hr = d2d_res_->GetDWriteFactory()->CreateCustomFontCollection(
+ res_font_collection_loader_.get(),
+ collection_key,
+ collection_key_size,
+ &font_collection
+ );
+
+ if (SUCCEEDED(hr))
+ {
+ collection.SetFontCollection(font_collection);
+ }
+ }
}
if (FAILED(hr))
diff --git a/src/kiwano/renderer/Renderer.h b/src/kiwano/renderer/Renderer.h
index 1a77f295..a0fc0d39 100644
--- a/src/kiwano/renderer/Renderer.h
+++ b/src/kiwano/renderer/Renderer.h
@@ -58,19 +58,34 @@ namespace kiwano
);
public:
+ void CreateImage(
+ Image& image,
+ String const& file_path
+ );
+
void CreateImage(
Image& image,
Resource const& res
);
+ void CreateGifImage(
+ GifImage& image,
+ String const& file_path
+ );
+
void CreateGifImage(
GifImage& image,
Resource const& res
);
- void CreateFontFromResource(
+ void CreateFontCollection(
FontCollection& collection,
- Resource const& res
+ Vector const& file_paths
+ );
+
+ void CreateFontCollection(
+ FontCollection& collection,
+ Vector const& res_arr
);
void CreateTextFormat(
diff --git a/src/kiwano/renderer/win32/D2DDeviceResources.cpp b/src/kiwano/renderer/win32/D2DDeviceResources.cpp
index 2ebc880e..9e5459f5 100644
--- a/src/kiwano/renderer/win32/D2DDeviceResources.cpp
+++ b/src/kiwano/renderer/win32/D2DDeviceResources.cpp
@@ -392,9 +392,8 @@ namespace kiwano
ComPtr bitmap_tmp;
// 加载资源
- LPVOID buffer;
- DWORD buffer_size;
- HRESULT hr = res.Load(buffer, buffer_size) ? S_OK : E_FAIL;
+ Resource::Data res_data = res.GetData();
+ HRESULT hr = res_data ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
@@ -404,8 +403,8 @@ namespace kiwano
if (SUCCEEDED(hr))
{
hr = stream->InitializeFromMemory(
- static_cast(buffer),
- buffer_size
+ static_cast(res_data.buffer),
+ res_data.size
);
}
diff --git a/src/kiwano/renderer/win32/FontCollectionLoader.cpp b/src/kiwano/renderer/win32/FontCollectionLoader.cpp
index ad97e532..304cd72d 100644
--- a/src/kiwano/renderer/win32/FontCollectionLoader.cpp
+++ b/src/kiwano/renderer/win32/FontCollectionLoader.cpp
@@ -37,6 +37,12 @@ namespace kiwano
{
}
+ STDMETHOD(AddFilePaths)(
+ Vector const& filePaths,
+ _Out_ LPVOID* pCollectionKey,
+ _Out_ UINT32* pCollectionKeySize
+ );
+
// IUnknown methods
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
@@ -52,6 +58,10 @@ namespace kiwano
private:
ULONG refCount_;
+
+ typedef Vector FileCollection;
+ Vector filePaths_;
+ Vector collectionKeys_;
};
HRESULT IFontCollectionLoader::Create(_Out_ IFontCollectionLoader** ppCollectionLoader)
@@ -77,6 +87,37 @@ namespace kiwano
return hr;
}
+ STDMETHODIMP FontCollectionLoader::AddFilePaths(
+ Vector const& filePaths,
+ _Out_ LPVOID* pCollectionKey,
+ _Out_ UINT32* pCollectionKeySize
+ )
+ {
+ if (!pCollectionKey || !pCollectionKeySize)
+ {
+ return E_INVALIDARG;
+ }
+
+ try
+ {
+ UINT32 collectionKey = filePaths_.size();
+ collectionKeys_.push_back(collectionKey);
+ filePaths_.push_back(filePaths);
+
+ *pCollectionKey = reinterpret_cast(&collectionKeys_.back());
+ *pCollectionKeySize = sizeof(collectionKey);
+ }
+ catch (std::bad_alloc&)
+ {
+ return E_OUTOFMEMORY;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+
HRESULT STDMETHODCALLTYPE FontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject)
{
if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader))
@@ -115,7 +156,7 @@ namespace kiwano
{
HRESULT hr = S_OK;
- if (collectionKey == NULL || collectionKeySize != sizeof(String))
+ if (collectionKey == NULL || collectionKeySize % sizeof(UINT32) != 0)
hr = E_INVALIDARG;
if (SUCCEEDED(hr))
@@ -125,10 +166,8 @@ namespace kiwano
if (SUCCEEDED(hr))
{
- String const* filePath = static_cast(collectionKey);
- UINT32 const fileCount = collectionKeySize / sizeof(String);
-
- hr = pEnumerator->SetFilePaths(filePath, fileCount);
+ const UINT32 fileIndex = *static_cast(collectionKey);
+ hr = pEnumerator->SetFilePaths(filePaths_[fileIndex]);
}
if (SUCCEEDED(hr))
@@ -157,8 +196,7 @@ namespace kiwano
);
STDMETHOD(SetFilePaths)(
- String const* filePath,
- UINT32 const fileCount
+ Vector const& filePaths
);
~FontFileEnumerator()
@@ -234,13 +272,12 @@ namespace kiwano
}
STDMETHODIMP FontFileEnumerator::SetFilePaths(
- String const* filePath,
- UINT32 const fileCount
+ Vector const& filePaths
)
{
try
{
- filePaths_.assign(filePath, filePath + fileCount);
+ filePaths_.assign(filePaths);
}
catch (std::bad_alloc&)
{
@@ -332,6 +369,12 @@ namespace kiwano
{
}
+ STDMETHOD(AddResources)(
+ Vector const& resources,
+ _Out_ LPVOID* pCollectionKey,
+ _Out_ UINT32* pCollectionKeySize
+ );
+
// IUnknown methods
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef();
@@ -348,6 +391,10 @@ namespace kiwano
private:
ULONG refCount_;
IDWriteFontFileLoader* pFileLoader_;
+
+ typedef Vector ResourceCollection;
+ Vector resources_;
+ Vector collectionKeys_;
};
HRESULT IResourceFontCollectionLoader::Create(_Out_ IResourceFontCollectionLoader** ppCollectionLoader, IDWriteFontFileLoader* pFileLoader)
@@ -373,6 +420,37 @@ namespace kiwano
return hr;
}
+ STDMETHODIMP ResourceFontCollectionLoader::AddResources(
+ Vector const& resources,
+ _Out_ LPVOID* pCollectionKey,
+ _Out_ UINT32* pCollectionKeySize
+ )
+ {
+ if (!pCollectionKey || !pCollectionKeySize)
+ {
+ return E_INVALIDARG;
+ }
+
+ try
+ {
+ UINT32 collectionKey = resources_.size();
+ collectionKeys_.push_back(collectionKey);
+ resources_.push_back(resources);
+
+ *pCollectionKey = reinterpret_cast(&collectionKeys_.back());
+ *pCollectionKeySize = sizeof(collectionKey);
+ }
+ catch (std::bad_alloc&)
+ {
+ return E_OUTOFMEMORY;
+ }
+ catch (...)
+ {
+ return E_FAIL;
+ }
+ return S_OK;
+ }
+
HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject)
{
if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader))
@@ -411,7 +489,7 @@ namespace kiwano
{
HRESULT hr = S_OK;
- if (collectionKey == NULL || collectionKeySize % sizeof(UINT) != 0)
+ if (collectionKey == NULL || collectionKeySize % sizeof(Resource*) != 0)
hr = E_INVALIDARG;
if (SUCCEEDED(hr))
@@ -421,10 +499,9 @@ namespace kiwano
if (SUCCEEDED(hr))
{
- UINT const* resourceID = static_cast(collectionKey);
- UINT32 const resourceCount = collectionKeySize / sizeof(UINT);
+ const UINT32 resourceIndex = *static_cast(collectionKey);
- hr = pEnumerator->SetResources(resourceID, resourceCount);
+ hr = pEnumerator->SetResources(resources_[resourceIndex]);
}
if (SUCCEEDED(hr))
@@ -527,16 +604,16 @@ namespace kiwano
HRESULT hr = S_OK;
// Make sure the key is the right size.
- if (fontFileReferenceKeySize != sizeof(UINT))
+ if (fontFileReferenceKeySize != sizeof(Resource))
hr = E_INVALIDARG;
if (SUCCEEDED(hr))
{
// Create the pFileStream object.
IResourceFontFileStream* pFileStream = NULL;
- UINT resourceID = *static_cast(fontFileReferenceKey);
+ Resource resource = *static_cast(fontFileReferenceKey);
- hr = IResourceFontFileStream::Create(&pFileStream, resourceID);
+ hr = IResourceFontFileStream::Create(&pFileStream, resource);
if (SUCCEEDED(hr))
{
@@ -566,8 +643,7 @@ namespace kiwano
);
STDMETHOD(SetResources)(
- UINT const* resourceID,
- UINT32 const resourceCount
+ Vector const& resources
);
~ResourceFontFileEnumerator()
@@ -591,7 +667,7 @@ namespace kiwano
IDWriteFactory* pFactory_;
IDWriteFontFile* currentFile_;
IDWriteFontFileLoader* pLoader_;
- Vector resourceIDs_;
+ Vector resources_;
size_t nextIndex_;
};
@@ -647,13 +723,12 @@ namespace kiwano
}
STDMETHODIMP ResourceFontFileEnumerator::SetResources(
- UINT const* resourceID,
- UINT32 const resourceCount
+ Vector const& resources
)
{
try
{
- resourceIDs_.assign(resourceID, resourceID + resourceCount);
+ resources_.assign(resources);
}
catch (std::bad_alloc&)
{
@@ -702,11 +777,11 @@ namespace kiwano
*hasCurrentFile = FALSE;
DX::SafeRelease(currentFile_);
- if (nextIndex_ < resourceIDs_.size())
+ if (nextIndex_ < resources_.size())
{
hr = pFactory_->CreateCustomFontFileReference(
- &resourceIDs_[nextIndex_],
- sizeof(UINT),
+ &resources_[nextIndex_],
+ sizeof(Resource),
pLoader_,
¤tFile_
);
@@ -743,7 +818,7 @@ namespace kiwano
ResourceFontFileStream();
STDMETHOD(Initialize)(
- const UINT resourceID
+ Resource const resources
);
// IUnknown methods
@@ -782,7 +857,7 @@ namespace kiwano
DWORD resourceSize_;
};
- HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream, const UINT resourceID)
+ HRESULT IResourceFontFileStream::Create(_Out_ IResourceFontFileStream** ppStream, const Resource resource)
{
HRESULT hr = S_OK;
@@ -798,7 +873,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
- hr = pFileStream->Initialize(resourceID);
+ hr = pFileStream->Initialize(resource);
}
if (SUCCEEDED(hr))
@@ -818,14 +893,16 @@ namespace kiwano
}
STDMETHODIMP ResourceFontFileStream::Initialize(
- const UINT resourceID
+ const Resource resource
)
{
- HRESULT hr = S_OK;
+ Resource::Data data = resource.GetData();
+ HRESULT hr = data ? S_OK : E_FAIL;
- if (!Resource{ resourceID, RT_FONT }.Load(resourcePtr_, resourceSize_))
+ if (SUCCEEDED(hr))
{
- hr = E_FAIL;
+ resourcePtr_ = data.buffer;
+ resourceSize_ = data.size;
}
return hr;
}
diff --git a/src/kiwano/renderer/win32/FontCollectionLoader.h b/src/kiwano/renderer/win32/FontCollectionLoader.h
index 49479d48..c5e01c20 100644
--- a/src/kiwano/renderer/win32/FontCollectionLoader.h
+++ b/src/kiwano/renderer/win32/FontCollectionLoader.h
@@ -30,6 +30,12 @@ namespace kiwano
static HRESULT Create(
_Out_ IFontCollectionLoader** ppCollectionLoader
);
+
+ STDMETHOD(AddFilePaths)(
+ Vector const& filePaths,
+ _Out_ LPVOID * pCollectionKey,
+ _Out_ UINT32 * pCollectionKeySize
+ ) PURE;
};
@@ -43,8 +49,7 @@ namespace kiwano
);
STDMETHOD(SetFilePaths)(
- String const* filePath,
- UINT32 const fileCount
+ Vector const& filePaths
) PURE;
};
@@ -57,6 +62,12 @@ namespace kiwano
_Out_ IResourceFontCollectionLoader** ppCollectionLoader,
IDWriteFontFileLoader * pFileLoader
);
+
+ STDMETHOD(AddResources)(
+ Vector const& resources,
+ _Out_ LPVOID * pCollectionKey,
+ _Out_ UINT32 * pCollectionKeySize
+ ) PURE;
};
@@ -81,8 +92,7 @@ namespace kiwano
);
STDMETHOD(SetResources)(
- UINT const* resourceID,
- UINT32 const resourceCount
+ Vector const& resources
) PURE;
};
@@ -93,7 +103,7 @@ namespace kiwano
public:
static HRESULT Create(
_Out_ IResourceFontFileStream** ppStream,
- const UINT resourceID
+ const Resource resource
);
};
}
diff --git a/src/kiwano/utils/FileUtil.cpp b/src/kiwano/utils/FileUtil.cpp
index 942a7dc7..519346e5 100644
--- a/src/kiwano/utils/FileUtil.cpp
+++ b/src/kiwano/utils/FileUtil.cpp
@@ -46,12 +46,11 @@ namespace kiwano
if (file_handle == INVALID_HANDLE_VALUE)
return false;
- LPVOID buffer;
- DWORD buffer_size;
- if (res.Load(buffer, buffer_size))
+ Resource::Data data = res.GetData();
+ if (data)
{
DWORD written_bytes = 0;
- ::WriteFile(file_handle, buffer, buffer_size, &written_bytes, NULL);
+ ::WriteFile(file_handle, data.buffer, data.size, &written_bytes, NULL);
::CloseHandle(file_handle);
return true;
diff --git a/src/kiwano/utils/ResourceCache.cpp b/src/kiwano/utils/ResourceCache.cpp
index 1e821f7c..9340e3d1 100644
--- a/src/kiwano/utils/ResourceCache.cpp
+++ b/src/kiwano/utils/ResourceCache.cpp
@@ -173,12 +173,12 @@ namespace kiwano
return false;
}
- bool ResourceCache::AddFrame(String const& id, Resource const& res)
+ bool ResourceCache::AddFrame(String const& id, String const& file_path)
{
FramePtr ptr = new (std::nothrow) Frame;
if (ptr)
{
- if (ptr->Load(res))
+ if (ptr->Load(file_path))
{
return AddFrame(id, ptr);
}
@@ -196,43 +196,20 @@ namespace kiwano
return false;
}
- bool ResourceCache::AddGifImage(String const& id, Resource const& res)
+ size_t ResourceCache::AddFrameSequence(String const& id, Vector const& files)
{
- GifImagePtr ptr = new (std::nothrow) GifImage;
- if (ptr)
- {
- if (ptr->Load(res))
- {
- return AddGifImage(id, ptr);
- }
- }
- return false;
- }
-
- bool ResourceCache::AddGifImage(String const& id, GifImagePtr image)
- {
- if (image)
- {
- cache_.insert(std::make_pair(id, image));
- return true;
- }
- return false;
- }
-
- size_t ResourceCache::AddFrameSequence(String const& id, Vector const& images)
- {
- if (images.empty())
+ if (files.empty())
return 0;
Vector image_arr;
- image_arr.reserve(images.size());
+ image_arr.reserve(files.size());
- for (const auto& image : images)
+ for (const auto& file : files)
{
FramePtr ptr = new (std::nothrow) Frame;
if (ptr)
{
- if (ptr->Load(image))
+ if (ptr->Load(file))
{
image_arr.push_back(ptr);
}
@@ -247,22 +224,13 @@ namespace kiwano
return 0;
}
- size_t ResourceCache::AddFrameSequence(String const& id, Vector const& images)
- {
- if (images.empty())
- return 0;
-
- FrameSequencePtr frames = new (std::nothrow) FrameSequence(images);
- return AddFrameSequence(id, frames);
- }
-
- size_t ResourceCache::AddFrameSequence(String const & id, Resource const & image, int cols, int rows)
+ size_t ResourceCache::AddFrameSequence(String const & id, String const& file_path, int cols, int rows)
{
if (cols <= 0 || rows <= 0)
return 0;
FramePtr raw = new (std::nothrow) Frame;
- if (!raw || !raw->Load(image))
+ if (!raw || !raw->Load(file_path))
return false;
float raw_width = raw->GetWidth();
@@ -290,29 +258,6 @@ namespace kiwano
return AddFrameSequence(id, frames);
}
- size_t ResourceCache::AddFrameSequence(String const & id, Resource const & image, Vector const & crop_rects)
- {
- FramePtr raw = new (std::nothrow) Frame;
- if (!raw || !raw->Load(image))
- return 0;
-
- Vector image_arr;
- image_arr.reserve(crop_rects.size());
-
- for (const auto& rect : crop_rects)
- {
- FramePtr ptr = new (std::nothrow) Frame(raw->GetImage());
- if (ptr)
- {
- ptr->SetCropRect(rect);
- image_arr.push_back(ptr);
- }
- }
-
- FrameSequencePtr frames = new (std::nothrow) FrameSequence(image_arr);
- return AddFrameSequence(id, frames);
- }
-
size_t ResourceCache::AddFrameSequence(String const & id, FrameSequencePtr frames)
{
if (frames)
@@ -338,11 +283,6 @@ namespace kiwano
return Get(id);
}
- GifImagePtr ResourceCache::GetGifImage(String const& id) const
- {
- return Get(id);
- }
-
FrameSequencePtr ResourceCache::GetFrameSequence(String const & id) const
{
return Get(id);
@@ -376,23 +316,17 @@ namespace kiwano
if (file)
{
- // Gif image
- if (type && (*type) == L"gif")
- {
- return loader->AddGifImage(*id, Resource(gdata->path + (*file)));
- }
-
if (!(*file).empty())
{
if (rows || cols)
{
// Frame slices
- return !!loader->AddFrameSequence(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1));
+ return !!loader->AddFrameSequence(*id, gdata->path + (*file), std::max(cols, 1), std::max(rows, 1));
}
else
{
// Simple image
- return loader->AddFrame(*id, Resource(gdata->path + (*file)));
+ return loader->AddFrame(*id, gdata->path + (*file));
}
}
}
@@ -410,7 +344,8 @@ namespace kiwano
frames.push_back(frame);
}
}
- return !!loader->AddFrameSequence(*id, frames);
+ FrameSequencePtr frame_seq = new FrameSequence(frames);
+ return !!loader->AddFrameSequence(*id, frame_seq);
}
return false;
}
diff --git a/src/kiwano/utils/ResourceCache.h b/src/kiwano/utils/ResourceCache.h
index 06f2b6c7..76559d32 100644
--- a/src/kiwano/utils/ResourceCache.h
+++ b/src/kiwano/utils/ResourceCache.h
@@ -46,31 +46,18 @@ namespace kiwano
// 从 XML 文档对象加载资源信息
bool LoadFromXml(tinyxml2::XMLDocument* doc);
- // 添加图片
- bool AddFrame(String const& id, Resource const& res);
+ // 添加帧图像
+ bool AddFrame(String const& id, String const& file_path);
- // 添加图片
+ // 添加帧图像
bool AddFrame(String const& id, FramePtr frame);
- // 添加 GIF 图片
- bool AddGifImage(String const& id, Resource const& res);
-
- // 添加 GIF 图片
- bool AddGifImage(String const& id, GifImagePtr image);
-
// 添加序列帧
- size_t AddFrameSequence(String const& id, Vector const& frames);
-
- // 添加序列帧
- size_t AddFrameSequence(String const& id, Vector const& frames);
+ size_t AddFrameSequence(String const& id, Vector const& files);
// 添加序列帧
// 按行列数裁剪图片
- size_t AddFrameSequence(String const& id, Resource const& frame, int cols, int rows = 1);
-
- // 添加序列帧
- // 按指定裁剪矩形裁剪图片
- size_t AddFrameSequence(String const& id, Resource const& frame, Vector const& crop_rects);
+ size_t AddFrameSequence(String const& id, String const& file_path, int cols, int rows = 1);
// 添加序列帧
size_t AddFrameSequence(String const& id, FrameSequencePtr frames);
@@ -78,12 +65,9 @@ namespace kiwano
// 添加对象
bool AddObjectBase(String const& id, ObjectBasePtr obj);
- // 获取图片资源
+ // 获取帧图像
FramePtr GetFrame(String const& id) const;
- // 获取 GIF 图片资源
- GifImagePtr GetGifImage(String const& id) const;
-
// 获取序列帧
FrameSequencePtr GetFrameSequence(String const& id) const;