Update Texture & GifImage

This commit is contained in:
Nomango 2019-12-26 14:15:25 +08:00
parent bd20606041
commit f057b3b737
17 changed files with 165 additions and 113 deletions

View File

@ -53,11 +53,11 @@ namespace kiwano
{ {
UpdateCache(); UpdateCache();
if (texture_cached_.IsValid()) if (texture_cached_ && texture_cached_->IsValid())
{ {
PrepareRender(rt); PrepareRender(rt);
Rect bitmap_rect(0.f, 0.f, texture_cached_.GetWidth(), texture_cached_.GetHeight()); Rect bitmap_rect(0.f, 0.f, texture_cached_->GetWidth(), texture_cached_->GetHeight());
rt->DrawTexture(texture_cached_, bitmap_rect, bitmap_rect); rt->DrawTexture(texture_cached_, bitmap_rect, bitmap_rect);
} }
} }
@ -245,9 +245,9 @@ namespace kiwano
cache_expired_ = true; cache_expired_ = true;
} }
void Canvas::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect) void Canvas::DrawTexture(TexturePtr texture, const Rect* src_rect, const Rect* dest_rect)
{ {
if (texture.IsValid()) if (texture)
{ {
rt_.DrawTexture(texture, src_rect, dest_rect); rt_.DrawTexture(texture, src_rect, dest_rect);
cache_expired_ = true; cache_expired_ = true;
@ -330,7 +330,7 @@ namespace kiwano
cache_expired_ = true; cache_expired_ = true;
} }
Texture Canvas::ExportToTexture() const TexturePtr Canvas::ExportToTexture() const
{ {
UpdateCache(); UpdateCache();
return texture_cached_; return texture_cached_;

View File

@ -111,7 +111,7 @@ namespace kiwano
/// @param texture 纹理 /// @param texture 纹理
/// @param src_rect 纹理裁剪区域 /// @param src_rect 纹理裁剪区域
/// @param dest_rect 绘制目标区域 /// @param dest_rect 绘制目标区域
void DrawTexture(Texture const& texture, const Rect* src_rect = nullptr, const Rect* dest_rect = nullptr); void DrawTexture(TexturePtr texture, const Rect* src_rect = nullptr, const Rect* dest_rect = nullptr);
/// \~chinese /// \~chinese
/// @brief 绘制文字布局 /// @brief 绘制文字布局
@ -259,7 +259,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 导出纹理 /// @brief 导出纹理
Texture ExportToTexture() const; TexturePtr ExportToTexture() const;
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
@ -276,7 +276,7 @@ namespace kiwano
GeometrySink geo_sink_; GeometrySink geo_sink_;
mutable bool cache_expired_; mutable bool cache_expired_;
mutable Texture texture_cached_; mutable TexturePtr texture_cached_;
mutable TextureRenderTarget rt_; mutable TextureRenderTarget rt_;
}; };

View File

@ -37,15 +37,15 @@ namespace kiwano
Load(res); Load(res);
} }
Frame::Frame(Texture const& texture) Frame::Frame(TexturePtr texture)
{ {
SetTexture(texture); SetTexture(texture);
} }
bool Frame::Load(String const& file_path) bool Frame::Load(String const& file_path)
{ {
Texture texture = TextureCache::instance().AddOrGetTexture(file_path); TexturePtr texture = TextureCache::instance().AddOrGetTexture(file_path);
if (texture.IsValid()) if (texture->IsValid())
{ {
SetTexture(texture); SetTexture(texture);
return true; return true;
@ -55,8 +55,8 @@ namespace kiwano
bool Frame::Load(Resource const& res) bool Frame::Load(Resource const& res)
{ {
Texture texture = TextureCache::instance().AddOrGetTexture(res); TexturePtr texture = TextureCache::instance().AddOrGetTexture(res);
if (texture.IsValid()) if (texture->IsValid())
{ {
SetTexture(texture); SetTexture(texture);
return true; return true;
@ -66,9 +66,9 @@ namespace kiwano
void Frame::SetCropRect(Rect const& crop_rect) void Frame::SetCropRect(Rect const& crop_rect)
{ {
if (texture_.IsValid()) if (texture_->IsValid())
{ {
auto bitmap_size = texture_.GetSize(); auto bitmap_size = texture_->GetSize();
crop_rect_.left_top.x = std::min(std::max(crop_rect.left_top.x, 0.f), bitmap_size.x); crop_rect_.left_top.x = std::min(std::max(crop_rect.left_top.x, 0.f), bitmap_size.x);
crop_rect_.left_top.y = std::min(std::max(crop_rect.left_top.y, 0.f), bitmap_size.y); crop_rect_.left_top.y = std::min(std::max(crop_rect.left_top.y, 0.f), bitmap_size.y);
crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x); crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x);
@ -76,14 +76,14 @@ namespace kiwano
} }
} }
void Frame::SetTexture(Texture const& texture) void Frame::SetTexture(TexturePtr texture)
{ {
texture_ = texture; texture_ = texture;
if (texture_.IsValid()) if (texture_->IsValid())
{ {
crop_rect_.left_top.x = crop_rect_.left_top.y = 0; crop_rect_.left_top.x = crop_rect_.left_top.y = 0;
crop_rect_.right_bottom.x = texture_.GetWidth(); crop_rect_.right_bottom.x = texture_->GetWidth();
crop_rect_.right_bottom.y = texture_.GetHeight(); crop_rect_.right_bottom.y = texture_->GetHeight();
} }
} }
} }

View File

@ -56,7 +56,7 @@ namespace kiwano
/// @brief 构建图像帧 /// @brief 构建图像帧
/// @param texture 纹理 /// @param texture 纹理
explicit Frame( explicit Frame(
Texture const& texture TexturePtr texture
); );
/// \~chinese /// \~chinese
@ -84,7 +84,7 @@ namespace kiwano
/// @brief 设置纹理 /// @brief 设置纹理
/// @param texture 纹理 /// @param texture 纹理
void SetTexture( void SetTexture(
Texture const& texture TexturePtr texture
); );
/// \~chinese /// \~chinese
@ -109,10 +109,10 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 获取纹理 /// @brief 获取纹理
Texture const& GetTexture() const; TexturePtr GetTexture() const;
private: private:
Texture texture_; TexturePtr texture_;
Rect crop_rect_; Rect crop_rect_;
}; };
@ -122,5 +122,5 @@ namespace kiwano
inline Size Frame::GetSize() const { return crop_rect_.GetSize(); } inline Size Frame::GetSize() const { return crop_rect_.GetSize(); }
inline Point Frame::GetCropPoint() const { return crop_rect_.GetLeftTop(); } inline Point Frame::GetCropPoint() const { return crop_rect_.GetLeftTop(); }
inline Rect const& Frame::GetCropRect() const { return crop_rect_; } inline Rect const& Frame::GetCropRect() const { return crop_rect_; }
inline Texture const& Frame::GetTexture() const { return texture_; } inline TexturePtr Frame::GetTexture() const { return texture_; }
} }

View File

@ -44,26 +44,26 @@ namespace kiwano
Load(res); Load(res);
} }
GifSprite::GifSprite(GifImage gif) GifSprite::GifSprite(GifImagePtr gif)
{ {
Load(gif); Load(gif);
} }
bool GifSprite::Load(String const& file_path) bool GifSprite::Load(String const& file_path)
{ {
GifImage texture = TextureCache::instance().AddOrGetGifImage(file_path); GifImagePtr image = TextureCache::instance().AddOrGetGifImage(file_path);
return Load(texture); return Load(image);
} }
bool GifSprite::Load(Resource const& res) bool GifSprite::Load(Resource const& res)
{ {
GifImage texture = TextureCache::instance().AddOrGetGifImage(res); GifImagePtr image = TextureCache::instance().AddOrGetGifImage(res);
return Load(texture); return Load(image);
} }
bool GifSprite::Load(GifImage gif) bool GifSprite::Load(GifImagePtr gif)
{ {
if (gif.IsValid()) if (gif && gif->IsValid())
{ {
gif_ = gif; gif_ = gif;
@ -71,14 +71,14 @@ namespace kiwano
loop_count_ = 0; loop_count_ = 0;
frame_.disposal_type = GifImage::DisposalType::None; frame_.disposal_type = GifImage::DisposalType::None;
SetSize(Size{ static_cast<float>(gif_.GetWidthInPixels()), static_cast<float>(gif_.GetHeightInPixels()) }); SetSize(Size{ static_cast<float>(gif_->GetWidthInPixels()), static_cast<float>(gif_->GetHeightInPixels()) });
if (!frame_rt_.IsValid()) if (!frame_rt_.IsValid())
{ {
Renderer::instance().CreateTextureRenderTarget(frame_rt_); Renderer::instance().CreateTextureRenderTarget(frame_rt_);
} }
if (gif_.GetFramesCount() > 0) if (gif_->GetFramesCount() > 0)
{ {
ComposeNextFrame(); ComposeNextFrame();
} }
@ -89,7 +89,7 @@ namespace kiwano
void GifSprite::OnRender(RenderTarget* rt) void GifSprite::OnRender(RenderTarget* rt)
{ {
if (frame_.raw.IsValid() && CheckVisibilty(rt)) if (frame_.raw && frame_.raw->IsValid() && CheckVisibilty(rt))
{ {
PrepareRender(rt); PrepareRender(rt);
@ -101,7 +101,7 @@ namespace kiwano
{ {
Actor::Update(dt); Actor::Update(dt);
if (gif_.IsValid() && animating_) if (gif_ && gif_->IsValid() && animating_)
{ {
frame_elapsed_ += dt; frame_elapsed_ += dt;
if (frame_.delay <= frame_elapsed_) if (frame_.delay <= frame_elapsed_)
@ -113,7 +113,7 @@ namespace kiwano
} }
} }
void GifSprite::SetGifImage(GifImage const& gif) void GifSprite::SetGifImage(GifImagePtr gif)
{ {
gif_ = gif; gif_ = gif;
RestartAnimation(); RestartAnimation();
@ -129,6 +129,8 @@ namespace kiwano
void GifSprite::ComposeNextFrame() void GifSprite::ComposeNextFrame()
{ {
KGE_ASSERT(gif_ && gif_->IsValid());
if (frame_rt_.IsValid()) if (frame_rt_.IsValid())
{ {
do do
@ -137,7 +139,7 @@ namespace kiwano
OverlayNextFrame(); OverlayNextFrame();
} while (frame_.delay.IsZero() && !IsLastFrame()); } while (frame_.delay.IsZero() && !IsLastFrame());
animating_ = (!EndOfAnimation() && gif_.GetFramesCount() > 1); animating_ = (!EndOfAnimation() && gif_->GetFramesCount() > 1);
} }
} }
@ -168,7 +170,9 @@ namespace kiwano
void GifSprite::OverlayNextFrame() void GifSprite::OverlayNextFrame()
{ {
Renderer::instance().CreateGifImageFrame(frame_, gif_, next_index_); KGE_ASSERT(gif_ && gif_->IsValid());
frame_ = gif_->GetFrame(next_index_);
if (frame_.disposal_type == GifImage::DisposalType::Previous) if (frame_.disposal_type == GifImage::DisposalType::Previous)
{ {
@ -187,11 +191,11 @@ namespace kiwano
frame_rt_.DrawTexture(frame_.raw, nullptr, &frame_.rect); frame_rt_.DrawTexture(frame_.raw, nullptr, &frame_.rect);
frame_rt_.EndDraw(); frame_rt_.EndDraw();
Texture frame_to_render = frame_rt_.GetOutput(); TexturePtr frame_to_render = frame_rt_.GetOutput();
if (frame_to_render.IsValid()) if (frame_to_render)
{ {
frame_.raw = frame_to_render; frame_.raw = frame_to_render;
next_index_ = (++next_index_) % gif_.GetFramesCount(); next_index_ = (++next_index_) % gif_->GetFramesCount();
} }
} }
@ -208,30 +212,30 @@ namespace kiwano
void GifSprite::SaveComposedFrame() void GifSprite::SaveComposedFrame()
{ {
Texture frame_to_be_saved = frame_rt_.GetOutput(); TexturePtr frame_to_be_saved = frame_rt_.GetOutput();
HRESULT hr = frame_to_be_saved.IsValid() ? S_OK : E_FAIL; HRESULT hr = frame_to_be_saved ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
if (!saved_frame_.IsValid()) if (!saved_frame_)
{ {
auto size = frame_to_be_saved.GetSizeInPixels(); auto size = frame_to_be_saved->GetSizeInPixels();
auto prop = D2D1::BitmapProperties(frame_to_be_saved.GetPixelFormat()); auto prop = D2D1::BitmapProperties(frame_to_be_saved->GetPixelFormat());
ComPtr<ID2D1Bitmap> saved_bitmap; ComPtr<ID2D1Bitmap> saved_bitmap;
hr = frame_rt_.GetRenderTarget()->CreateBitmap(D2D1::SizeU(size.x, size.y), prop, &saved_bitmap); hr = frame_rt_.GetRenderTarget()->CreateBitmap(D2D1::SizeU(size.x, size.y), prop, &saved_bitmap);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
saved_frame_.SetBitmap(saved_bitmap); saved_frame_->SetBitmap(saved_bitmap);
} }
} }
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
saved_frame_.CopyFrom(frame_to_be_saved); saved_frame_->CopyFrom(frame_to_be_saved);
} }
ThrowIfFailed(hr); ThrowIfFailed(hr);
@ -239,17 +243,17 @@ namespace kiwano
void GifSprite::RestoreSavedFrame() void GifSprite::RestoreSavedFrame()
{ {
HRESULT hr = saved_frame_.IsValid() ? S_OK : E_FAIL; HRESULT hr = saved_frame_ ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
Texture frame_to_copy_to = frame_rt_.GetOutput(); TexturePtr frame_to_copy_to = frame_rt_.GetOutput();
hr = frame_to_copy_to.IsValid() ? S_OK : E_FAIL; hr = frame_to_copy_to ? S_OK : E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame_to_copy_to.CopyFrom(saved_frame_); frame_to_copy_to->CopyFrom(saved_frame_);
} }
} }

View File

@ -64,7 +64,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 构造GIF精灵 /// @brief 构造GIF精灵
/// @param gif GIF图片 /// @param gif GIF图片
GifSprite(GifImage gif); GifSprite(GifImagePtr gif);
/// \~chinese /// \~chinese
/// @brief 加载GIF图片 /// @brief 加载GIF图片
@ -79,7 +79,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 加载GIF图片 /// @brief 加载GIF图片
/// @param gif GIF图片 /// @param gif GIF图片
bool Load(GifImage gif); bool Load(GifImagePtr gif);
/// \~chinese /// \~chinese
/// @brief 设置 GIF 动画循环次数 /// @brief 设置 GIF 动画循环次数
@ -95,7 +95,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 设置 GIF 图像 /// @brief 设置 GIF 图像
void SetGifImage(GifImage const& gif); void SetGifImage(GifImagePtr gif);
/// \~chinese /// \~chinese
/// @brief 重新播放 GIF 动画 /// @brief 重新播放 GIF 动画
@ -111,7 +111,7 @@ namespace kiwano
/// \~chinese /// \~chinese
/// @brief 获取 GIF 图片 /// @brief 获取 GIF 图片
GifImage const& GetGifImage() const; GifImagePtr GetGifImage() const;
void OnRender(RenderTarget* rt) override; void OnRender(RenderTarget* rt) override;
@ -158,9 +158,9 @@ namespace kiwano
Duration frame_elapsed_; Duration frame_elapsed_;
LoopDoneCallback loop_cb_; LoopDoneCallback loop_cb_;
DoneCallback done_cb_; DoneCallback done_cb_;
GifImage gif_; GifImagePtr gif_;
GifImage::Frame frame_; GifImage::Frame frame_;
Texture saved_frame_; TexturePtr saved_frame_;
TextureRenderTarget frame_rt_; TextureRenderTarget frame_rt_;
}; };
@ -176,7 +176,7 @@ namespace kiwano
inline GifSprite::DoneCallback GifSprite::GetDoneCallback() const { return done_cb_; } inline GifSprite::DoneCallback GifSprite::GetDoneCallback() const { return done_cb_; }
inline GifImage const& GifSprite::GetGifImage() const { return gif_; } inline GifImagePtr GifSprite::GetGifImage() const { return gif_; }
inline bool GifSprite::IsLastFrame() const { return (next_index_ == 0); } inline bool GifSprite::IsLastFrame() const { return (next_index_ == 0); }

View File

@ -79,6 +79,13 @@ namespace kiwano
return decoder_ != nullptr; return decoder_ != nullptr;
} }
GifImage::Frame GifImage::GetFrame(uint32_t index)
{
Frame frame;
Renderer::instance().CreateGifImageFrame(frame, *this, index);
return frame;
}
HRESULT GifImage::GetGlobalMetadata() HRESULT GifImage::GetGlobalMetadata()
{ {
HRESULT hr = decoder_ ? S_OK : E_FAIL; HRESULT hr = decoder_ ? S_OK : E_FAIL;

View File

@ -24,8 +24,11 @@
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(GifImage);
// GIF ͼÏñ // GIF ͼÏñ
class KGE_API GifImage class KGE_API GifImage
: public ObjectBase
{ {
public: public:
GifImage(); GifImage();
@ -40,11 +43,11 @@ namespace kiwano
bool IsValid() const; bool IsValid() const;
inline uint32_t GetWidthInPixels() const { return width_in_pixels_; } uint32_t GetWidthInPixels() const;
inline uint32_t GetHeightInPixels() const { return height_in_pixels_; } uint32_t GetHeightInPixels() const;
inline uint32_t GetFramesCount() const { return frames_count_; } uint32_t GetFramesCount() const;
public: public:
enum class DisposalType enum class DisposalType
@ -58,16 +61,18 @@ namespace kiwano
struct Frame struct Frame
{ {
Duration delay; Duration delay;
Texture raw; TexturePtr raw;
Rect rect; Rect rect;
DisposalType disposal_type; DisposalType disposal_type;
Frame() : disposal_type(DisposalType::Unknown) {} Frame();
}; };
inline ComPtr<IWICBitmapDecoder> GetDecoder() const { return decoder_; } Frame GetFrame(uint32_t index);
inline void SetDecoder(ComPtr<IWICBitmapDecoder> decoder) { decoder_ = decoder; } ComPtr<IWICBitmapDecoder> GetDecoder() const;
void SetDecoder(ComPtr<IWICBitmapDecoder> decoder);
private: private:
HRESULT GetGlobalMetadata(); HRESULT GetGlobalMetadata();
@ -79,4 +84,34 @@ namespace kiwano
ComPtr<IWICBitmapDecoder> decoder_; ComPtr<IWICBitmapDecoder> decoder_;
}; };
inline GifImage::Frame::Frame()
: disposal_type(DisposalType::Unknown)
{
}
inline uint32_t GifImage::GetWidthInPixels() const
{
return width_in_pixels_;
}
inline uint32_t GifImage::GetHeightInPixels() const
{
return height_in_pixels_;
}
inline uint32_t GifImage::GetFramesCount() const
{
return frames_count_;
}
inline ComPtr<IWICBitmapDecoder> GifImage::GetDecoder() const
{
return decoder_;
}
inline void GifImage::SetDecoder(ComPtr<IWICBitmapDecoder> decoder)
{
decoder_ = decoder;
}
} }

View File

@ -333,12 +333,12 @@ namespace kiwano
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
void RenderTarget::DrawTexture(Texture const& texture, Rect const& src_rect, Rect const& dest_rect) void RenderTarget::DrawTexture(TexturePtr texture, Rect const& src_rect, Rect const& dest_rect)
{ {
DrawTexture(texture, &src_rect, &dest_rect); DrawTexture(texture, &src_rect, &dest_rect);
} }
void RenderTarget::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect) void RenderTarget::DrawTexture(TexturePtr texture, const Rect* src_rect, const Rect* dest_rect)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!render_target_) if (!render_target_)
@ -346,14 +346,19 @@ namespace kiwano
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
if (SUCCEEDED(hr) && texture.IsValid()) if (!texture)
{ {
auto mode = (texture.GetBitmapInterpolationMode() == InterpolationMode::Linear) hr = E_INVALIDARG;
}
if (SUCCEEDED(hr) && texture->IsValid())
{
auto mode = (texture->GetBitmapInterpolationMode() == InterpolationMode::Linear)
? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR ? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
: D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR; : D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
render_target_->DrawBitmap( render_target_->DrawBitmap(
texture.GetBitmap().get(), texture->GetBitmap().get(),
dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr, dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
opacity_, opacity_,
mode, mode,
@ -713,9 +718,10 @@ namespace kiwano
{ {
} }
Texture TextureRenderTarget::GetOutput() TexturePtr TextureRenderTarget::GetOutput()
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
TexturePtr output;
if (GetRenderTarget()) if (GetRenderTarget())
{ {
@ -729,13 +735,14 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
return Texture(bitmap); output = new Texture;
output->SetBitmap(bitmap);
} }
} }
} }
ThrowIfFailed(hr); ThrowIfFailed(hr);
return Texture(); return output;
} }
} }

View File

@ -106,13 +106,13 @@ namespace kiwano
); );
void DrawTexture( void DrawTexture(
Texture const& texture, TexturePtr texture,
Rect const& src_rect, Rect const& src_rect,
Rect const& dest_rect Rect const& dest_rect
); );
void DrawTexture( void DrawTexture(
Texture const& texture, TexturePtr texture,
const Rect* src_rect = nullptr, const Rect* src_rect = nullptr,
const Rect* dest_rect = nullptr const Rect* dest_rect = nullptr
); );
@ -241,6 +241,6 @@ namespace kiwano
public: public:
TextureRenderTarget(); TextureRenderTarget();
Texture GetOutput(); TexturePtr GetOutput();
}; };
} }

View File

@ -451,7 +451,8 @@ namespace kiwano
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame.raw.SetBitmap(raw_bitmap); frame.raw = new Texture;
frame.raw->SetBitmap(raw_bitmap);
} }
} }
} }

View File

@ -131,23 +131,23 @@ namespace kiwano
return interpolation_mode_; return interpolation_mode_;
} }
void Texture::CopyFrom(Texture const& copy_from) void Texture::CopyFrom(TexturePtr copy_from)
{ {
if (IsValid() && copy_from.IsValid()) if (IsValid() && copy_from)
{ {
HRESULT hr = bitmap_->CopyFromBitmap(nullptr, copy_from.GetBitmap().get(), nullptr); HRESULT hr = bitmap_->CopyFromBitmap(nullptr, copy_from->GetBitmap().get(), nullptr);
ThrowIfFailed(hr); ThrowIfFailed(hr);
} }
} }
void Texture::CopyFrom(Texture const& copy_from, Rect const& src_rect, Point const& dest_point) void Texture::CopyFrom(TexturePtr copy_from, Rect const& src_rect, Point const& dest_point)
{ {
if (IsValid() && copy_from.IsValid()) if (IsValid() && copy_from)
{ {
HRESULT hr = bitmap_->CopyFromBitmap( HRESULT hr = bitmap_->CopyFromBitmap(
&D2D1::Point2U(uint32_t(dest_point.x), uint32_t(dest_point.y)), &D2D1::Point2U(uint32_t(dest_point.x), uint32_t(dest_point.y)),
copy_from.GetBitmap().get(), copy_from->GetBitmap().get(),
&D2D1::RectU( &D2D1::RectU(
uint32_t(src_rect.GetLeft()), uint32_t(src_rect.GetLeft()),
uint32_t(src_rect.GetTop()), uint32_t(src_rect.GetTop()),

View File

@ -20,6 +20,7 @@
#pragma once #pragma once
#include <kiwano/renderer/win32/D2DDeviceResources.h> #include <kiwano/renderer/win32/D2DDeviceResources.h>
#include <kiwano/core/ObjectBase.h>
namespace kiwano namespace kiwano
{ {
@ -33,9 +34,11 @@ namespace kiwano
Nearest, // 最邻近插值 Nearest, // 最邻近插值
}; };
KGE_DECLARE_SMART_PTR(Texture);
// 纹理 // 纹理
class KGE_API Texture class KGE_API Texture
: public ObjectBase
{ {
public: public:
Texture(); Texture();
@ -89,10 +92,10 @@ namespace kiwano
InterpolationMode GetBitmapInterpolationMode() const; InterpolationMode GetBitmapInterpolationMode() const;
// 拷贝位图内存 // 拷贝位图内存
void CopyFrom(Texture const& copy_from); void CopyFrom(TexturePtr copy_from);
// 拷贝位图内存 // 拷贝位图内存
void CopyFrom(Texture const& copy_from, Rect const& src_rect, Point const& dest_point); void CopyFrom(TexturePtr copy_from, Rect const& src_rect, Point const& dest_point);
// 设置像素插值方式 // 设置像素插值方式
void SetInterpolationMode(InterpolationMode mode); void SetInterpolationMode(InterpolationMode mode);

View File

@ -25,7 +25,7 @@
namespace kiwano namespace kiwano
{ {
template <typename _Ty, typename _PathTy, typename _CacheTy> template <typename _Ty, typename _PathTy, typename _CacheTy>
_Ty CreateOrGetCache(_CacheTy& cache, _PathTy const& path, size_t hash) SmartPtr<_Ty> CreateOrGetCache(_CacheTy& cache, _PathTy const& path, size_t hash)
{ {
auto iter = cache.find(hash); auto iter = cache.find(hash);
if (iter != cache.end()) if (iter != cache.end())
@ -33,8 +33,8 @@ namespace kiwano
return iter->second; return iter->second;
} }
_Ty texture; SmartPtr<_Ty> texture = new _Ty;
if (texture.Load(path)) if (texture->Load(path))
{ {
cache.insert(std::make_pair(hash, texture)); cache.insert(std::make_pair(hash, texture));
} }
@ -59,22 +59,22 @@ namespace kiwano
{ {
} }
Texture TextureCache::AddOrGetTexture(String const& file_path) TexturePtr TextureCache::AddOrGetTexture(String const& file_path)
{ {
return CreateOrGetCache<Texture>(texture_cache_, file_path, file_path.hash()); return CreateOrGetCache<Texture>(texture_cache_, file_path, file_path.hash());
} }
Texture TextureCache::AddOrGetTexture(Resource const& res) TexturePtr TextureCache::AddOrGetTexture(Resource const& res)
{ {
return CreateOrGetCache<Texture>(texture_cache_, res, res.GetId()); return CreateOrGetCache<Texture>(texture_cache_, res, res.GetId());
} }
GifImage TextureCache::AddOrGetGifImage(String const& file_path) GifImagePtr TextureCache::AddOrGetGifImage(String const& file_path)
{ {
return CreateOrGetCache<GifImage>(gif_texture_cache_, file_path, file_path.hash()); return CreateOrGetCache<GifImage>(gif_texture_cache_, file_path, file_path.hash());
} }
GifImage TextureCache::AddOrGetGifImage(Resource const& res) GifImagePtr TextureCache::AddOrGetGifImage(Resource const& res)
{ {
return CreateOrGetCache<GifImage>(gif_texture_cache_, res, res.GetId()); return CreateOrGetCache<GifImage>(gif_texture_cache_, res, res.GetId());
} }

View File

@ -30,10 +30,10 @@ namespace kiwano
friend Singleton<TextureCache>; friend Singleton<TextureCache>;
public: public:
Texture AddOrGetTexture(String const& file_path); TexturePtr AddOrGetTexture(String const& file_path);
Texture AddOrGetTexture(Resource const& res); TexturePtr AddOrGetTexture(Resource const& res);
GifImage AddOrGetGifImage(String const& file_path); GifImagePtr AddOrGetGifImage(String const& file_path);
GifImage AddOrGetGifImage(Resource const& res); GifImagePtr AddOrGetGifImage(Resource const& res);
void RemoveTexture(String const& file_path); void RemoveTexture(String const& file_path);
void RemoveTexture(Resource const& res); void RemoveTexture(Resource const& res);
@ -48,10 +48,10 @@ namespace kiwano
virtual ~TextureCache(); virtual ~TextureCache();
private: private:
using TextureMap = UnorderedMap<size_t, Texture>; using TextureMap = UnorderedMap<size_t, TexturePtr>;
TextureMap texture_cache_; TextureMap texture_cache_;
using GifImageMap = UnorderedMap<size_t, GifImage>; using GifImageMap = UnorderedMap<size_t, GifImagePtr>;
GifImageMap gif_texture_cache_; GifImageMap gif_texture_cache_;
}; };
} }

View File

@ -296,11 +296,11 @@ namespace kiwano
return false; return false;
} }
bool ResourceCache::AddGifImage(String const& id, GifImage const& gif) bool ResourceCache::AddGifImage(String const& id, GifImagePtr gif)
{ {
if (gif.IsValid()) if (gif && gif->IsValid())
{ {
gif_cache_.insert(std::make_pair(id, gif)); object_cache_.insert(std::make_pair(id, gif));
return true; return true;
} }
return false; return false;
@ -308,8 +308,8 @@ namespace kiwano
bool ResourceCache::AddGifImage(String const& id, String const& file_path) bool ResourceCache::AddGifImage(String const& id, String const& file_path)
{ {
GifImage gif; GifImagePtr gif = new (std::nothrow) GifImage;
if (gif.Load(file_path)) if (gif && gif->Load(file_path))
{ {
return AddGifImage(id, gif); return AddGifImage(id, gif);
} }
@ -336,12 +336,9 @@ namespace kiwano
return Get<FrameSequence>(id); return Get<FrameSequence>(id);
} }
GifImage ResourceCache::GetGifImage(String const& id) const GifImagePtr ResourceCache::GetGifImage(String const& id) const
{ {
auto iter = gif_cache_.find(id); return Get<GifImage>(id);
if (iter != gif_cache_.end())
return iter->second;
return GifImage();
} }
FontCollection ResourceCache::GetFontCollection(String const& id) const FontCollection ResourceCache::GetFontCollection(String const& id) const
@ -360,7 +357,6 @@ namespace kiwano
void ResourceCache::Clear() void ResourceCache::Clear()
{ {
object_cache_.clear(); object_cache_.clear();
gif_cache_.clear();
font_collection_cache_.clear(); font_collection_cache_.clear();
} }

View File

@ -66,7 +66,7 @@ namespace kiwano
bool AddObjectBase(String const& id, ObjectBasePtr obj); bool AddObjectBase(String const& id, ObjectBasePtr obj);
// Ìí¼Ó GIF ͼÏñ // Ìí¼Ó GIF ͼÏñ
bool AddGifImage(String const& id, GifImage const& gif); bool AddGifImage(String const& id, GifImagePtr gif);
// Ìí¼Ó GIF ͼÏñ // Ìí¼Ó GIF ͼÏñ
bool AddGifImage(String const& id, String const& file_path); bool AddGifImage(String const& id, String const& file_path);
@ -81,7 +81,7 @@ namespace kiwano
FrameSequencePtr GetFrameSequence(String const& id) const; FrameSequencePtr GetFrameSequence(String const& id) const;
// »ñÈ¡ GIF ͼÏñ // »ñÈ¡ GIF ͼÏñ
GifImage GetGifImage(String const& id) const; GifImagePtr GetGifImage(String const& id) const;
// »ñÈ¡×ÖÌ弯 // »ñÈ¡×ÖÌ弯
FontCollection GetFontCollection(String const& id) const; FontCollection GetFontCollection(String const& id) const;
@ -108,7 +108,6 @@ namespace kiwano
private: private:
UnorderedMap<String, ObjectBasePtr> object_cache_; UnorderedMap<String, ObjectBasePtr> object_cache_;
UnorderedMap<String, GifImage> gif_cache_;
UnorderedMap<String, FontCollection> font_collection_cache_; UnorderedMap<String, FontCollection> font_collection_cache_;
}; };
} }