From ada7c2b3366efe74eaeedd48d19db84f7de8e831 Mon Sep 17 00:00:00 2001 From: Nomango Date: Mon, 3 Aug 2020 21:55:27 +0800 Subject: [PATCH] update Texture & GifImage cache management --- projects/kiwano/kiwano.vcxproj | 3 +- projects/kiwano/kiwano.vcxproj.filters | 9 ++- src/kiwano/2d/DebugActor.cpp | 2 +- src/kiwano/2d/GifSprite.cpp | 7 +- src/kiwano/2d/Sprite.cpp | 2 +- src/kiwano/2d/TextActor.cpp | 10 --- src/kiwano/2d/TextActor.h | 4 - src/kiwano/platform/Application.cpp | 2 - .../render/DirectX/D2DDeviceResources.cpp | 47 +++++++++++ .../render/DirectX/D2DDeviceResources.h | 5 +- src/kiwano/render/DirectX/RendererImpl.cpp | 77 ++++++------------- src/kiwano/render/DirectX/RendererImpl.h | 4 +- src/kiwano/render/Font.cpp | 51 ++++++------ src/kiwano/render/Font.h | 35 ++++----- src/kiwano/render/Frame.cpp | 5 +- src/kiwano/render/GifImage.cpp | 12 +++ src/kiwano/render/GifImage.h | 8 ++ src/kiwano/render/Renderer.cpp | 71 +++++++++++++++++ src/kiwano/render/Renderer.h | 31 +++++++- src/kiwano/render/TextLayout.h | 2 +- src/kiwano/render/TextStyle.cpp | 57 ++++++++++++++ .../render/{TextStyle.hpp => TextStyle.h} | 29 +++---- src/kiwano/render/Texture.cpp | 12 +++ src/kiwano/render/Texture.h | 12 ++- src/kiwano/render/TextureCache.cpp | 75 ++++++------------ src/kiwano/render/TextureCache.h | 39 ++++------ src/kiwano/utils/ResourceLoader.cpp | 8 +- 27 files changed, 379 insertions(+), 240 deletions(-) create mode 100644 src/kiwano/render/TextStyle.cpp rename src/kiwano/render/{TextStyle.hpp => TextStyle.h} (85%) diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index dcb0634a..d78cedd3 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -94,7 +94,7 @@ - + @@ -174,6 +174,7 @@ + diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index eaef9e8b..0cc9eff1 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -156,9 +156,6 @@ render - - render - render @@ -357,6 +354,9 @@ utils + + render + @@ -584,6 +584,9 @@ utils + + render + diff --git a/src/kiwano/2d/DebugActor.cpp b/src/kiwano/2d/DebugActor.cpp index 2fbdba50..b50105e9 100644 --- a/src/kiwano/2d/DebugActor.cpp +++ b/src/kiwano/2d/DebugActor.cpp @@ -60,7 +60,7 @@ DebugActor::DebugActor() BrushPtr fill_brush = MakePtr(); fill_brush->SetColor(Color::White); - debug_text_style_.font_family = "Arial"; + debug_text_style_.font = new Font("Arial"); debug_text_style_.font_size = 16.f; debug_text_style_.font_weight = FontWeight::Normal; debug_text_style_.line_spacing = 20.f; diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index 50eeb989..ee18cf5a 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -19,8 +19,7 @@ // THE SOFTWARE. #include -#include -#include +#include namespace kiwano { @@ -53,13 +52,13 @@ GifSprite::GifSprite(GifImagePtr gif) bool GifSprite::Load(const String& file_path) { - GifImagePtr image = TextureCache::GetInstance().AddOrGetGifImage(file_path); + GifImagePtr image = GifImage::Preload(file_path); return Load(image); } bool GifSprite::Load(const Resource& res) { - GifImagePtr image = TextureCache::GetInstance().AddOrGetGifImage(res); + GifImagePtr image = GifImage::Preload(res); return Load(image); } diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index 3298be2f..b06af6ce 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include -#include +#include namespace kiwano { diff --git a/src/kiwano/2d/TextActor.cpp b/src/kiwano/2d/TextActor.cpp index 9e4e8305..2d5e1436 100644 --- a/src/kiwano/2d/TextActor.cpp +++ b/src/kiwano/2d/TextActor.cpp @@ -88,16 +88,6 @@ void TextActor::SetFont(FontPtr font) } } -void TextActor::SetFontFamily(const String& family) -{ - if (style_.font_family != family) - { - style_.font_family = family; - if (layout_) - layout_->SetFontFamily(family, { 0, layout_->GetContentLength() }); - } -} - void TextActor::SetFontSize(float size) { if (style_.font_size != size) diff --git a/src/kiwano/2d/TextActor.h b/src/kiwano/2d/TextActor.h index 78ce1593..0293d089 100644 --- a/src/kiwano/2d/TextActor.h +++ b/src/kiwano/2d/TextActor.h @@ -98,10 +98,6 @@ public: /// @brief 设置字体 void SetFont(FontPtr font); - /// \~chinese - /// @brief 设置字体族 - void SetFontFamily(const String& family); - /// \~chinese /// @brief 设置字号(默认值为 18) void SetFontSize(float size); diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index 3b50e79f..4046f303 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include namespace kiwano @@ -129,7 +128,6 @@ void Application::Destroy() modules_.clear(); // Clear device resources - TextureCache::GetInstance().Clear(); Renderer::GetInstance().Destroy(); } diff --git a/src/kiwano/render/DirectX/D2DDeviceResources.cpp b/src/kiwano/render/DirectX/D2DDeviceResources.cpp index c151d133..1e295907 100644 --- a/src/kiwano/render/DirectX/D2DDeviceResources.cpp +++ b/src/kiwano/render/DirectX/D2DDeviceResources.cpp @@ -75,6 +75,9 @@ public: HRESULT CreateFontCollectionFromResources(_Out_ ComPtr& font_collection, const Vector& resources) override; + HRESULT GetFontFamilyNames(_Out_ Vector& family_names, + _In_ ComPtr font_collection) override; + HRESULT SetDpi(float dpi) override; HRESULT SetLogicalSize(float width, float height) override; @@ -549,6 +552,50 @@ HRESULT D2DDeviceResources::CreateFontCollectionFromResources(ComPtr& family_names, + ComPtr font_collection) +{ + HRESULT hr = S_OK; + + if (!font_collection) + hr = E_FAIL; + + if (SUCCEEDED(hr)) + { + UINT32 count = font_collection->GetFontFamilyCount(); + for (UINT32 i = 0; i < count; i++) + { + ComPtr family; + hr = font_collection->GetFontFamily(i, &family); + + if (SUCCEEDED(hr)) + { + ComPtr str; + hr = family->GetFamilyNames(&str); + + if (SUCCEEDED(hr)) + { + UINT32 length; + hr = str->GetStringLength(0, &length); + + if (SUCCEEDED(hr)) + { + WideString name; + name.resize(length + 1); + str->GetString(0, &name[0], UINT32(name.size())); + + if (SUCCEEDED(hr)) + { + family_names.emplace_back(strings::WideToNarrow(name)); + } + } + } + } + } + } + return hr; +} + } // namespace directx } // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/D2DDeviceResources.h b/src/kiwano/render/DirectX/D2DDeviceResources.h index ef6adf0b..929a3222 100644 --- a/src/kiwano/render/DirectX/D2DDeviceResources.h +++ b/src/kiwano/render/DirectX/D2DDeviceResources.h @@ -60,7 +60,10 @@ public: const Vector& file_paths) = 0; virtual HRESULT CreateFontCollectionFromResources(_Out_ ComPtr & font_collection, - const Vector& resources) = 0; + const Vector& resources) = 0; + + virtual HRESULT GetFontFamilyNames(_Out_ Vector & family_names, + _In_ ComPtr font_collection) = 0; virtual HRESULT SetDpi(float dpi) = 0; diff --git a/src/kiwano/render/DirectX/RendererImpl.cpp b/src/kiwano/render/DirectX/RendererImpl.cpp index 2e06e08f..8aef4243 100644 --- a/src/kiwano/render/DirectX/RendererImpl.cpp +++ b/src/kiwano/render/DirectX/RendererImpl.cpp @@ -114,6 +114,8 @@ void RendererImpl::Destroy() { KGE_DEBUG_LOGF("Destroying device resources"); + Renderer::Destroy(); + if (d2d_res_) { render_ctx_.Reset(); @@ -502,36 +504,14 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path) ComPtr font_collection; hr = d2d_res_->CreateFontCollectionFromFiles(font_collection, { full_path }); - Vector family_names; if (SUCCEEDED(hr)) { - UINT32 count = font_collection->GetFontFamilyCount(); - for (UINT32 i = 0; i < count; i++) - { - ComPtr family; - if (SUCCEEDED(font_collection->GetFontFamily(i, &family))) - { - ComPtr str; - if (SUCCEEDED(family->GetFamilyNames(&str))) - { - UINT32 length = 0; - if (SUCCEEDED(str->GetStringLength(0, &length))) - { - WideString name; - name.resize(length + 1); - if (SUCCEEDED(str->GetString(0, &name[0], UINT32(name.size())))) - { - family_names.emplace_back(strings::WideToNarrow(name)); - } - } - } - } - } - } + Vector family_names; + d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result + + if (!family_names.empty()) + font.SetFamilyName(family_names[0]); - if (SUCCEEDED(hr)) - { - font.SetFamilyNames(family_names); NativePtr::Set(font, font_collection); } } @@ -552,36 +532,14 @@ void RendererImpl::CreateFontCollection(Font& font, const Resource& res) ComPtr font_collection; hr = d2d_res_->CreateFontCollectionFromResources(font_collection, Vector{ res }); - Vector family_names; if (SUCCEEDED(hr)) { - UINT32 count = font_collection->GetFontFamilyCount(); - for (UINT32 i = 0; i < count; i++) - { - ComPtr family; - if (SUCCEEDED(font_collection->GetFontFamily(i, &family))) - { - ComPtr str; - if (SUCCEEDED(family->GetFamilyNames(&str))) - { - UINT32 length = 0; - if (SUCCEEDED(str->GetStringLength(0, &length))) - { - WideString name; - name.resize(length + 1); - if (SUCCEEDED(str->GetString(0, &name[0], UINT32(name.size())))) - { - family_names.emplace_back(strings::WideToNarrow(name)); - } - } - } - } - } - } + Vector family_names; + d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result + + if (!family_names.empty()) + font.SetFamilyName(family_names[0]); - if (SUCCEEDED(hr)) - { - font.SetFamilyNames(family_names); NativePtr::Set(font, font_collection); } } @@ -606,11 +564,20 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c if (SUCCEEDED(hr)) { - WideString font_family = style.font_family.empty() ? L"" : strings::NarrowToWide(style.font_family); DWRITE_FONT_WEIGHT font_weight = DWRITE_FONT_WEIGHT(style.font_weight); DWRITE_FONT_STYLE font_style = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; auto collection = NativePtr::Get(style.font); + WideString font_family; + if (style.font) + { + String name = style.font->GetFamilyName(); + if (!name.empty()) + { + font_family = strings::NarrowToWide(name); + } + } + ComPtr format; hr = d2d_res_->CreateTextFormat(format, font_family.c_str(), collection, font_weight, font_style, DWRITE_FONT_STRETCH_NORMAL, style.font_size); diff --git a/src/kiwano/render/DirectX/RendererImpl.h b/src/kiwano/render/DirectX/RendererImpl.h index 747168e9..4a58c3b9 100644 --- a/src/kiwano/render/DirectX/RendererImpl.h +++ b/src/kiwano/render/DirectX/RendererImpl.h @@ -88,8 +88,8 @@ private: using ID2DDeviceResources = kiwano::graphics::directx::ID2DDeviceResources; using ID3DDeviceResources = kiwano::graphics::directx::ID3DDeviceResources; - ComPtr d2d_res_; - ComPtr d3d_res_; + ComPtr d2d_res_; + ComPtr d3d_res_; }; diff --git a/src/kiwano/render/Font.cpp b/src/kiwano/render/Font.cpp index b148ef3f..ccc9bbe8 100644 --- a/src/kiwano/render/Font.cpp +++ b/src/kiwano/render/Font.cpp @@ -24,42 +24,39 @@ namespace kiwano { -Font::Font(const String& file) +FontPtr Font::Preload(const String& file) { - Load(file); + FontPtr ptr = MakePtr(); + try + { + Renderer::GetInstance().CreateFontCollection(*ptr, file); + } + catch (Exception&) + { + return nullptr; + } + return ptr; } -Font::Font(const Resource& resource) +FontPtr Font::Preload(const Resource& resource) { - Load(resource); + FontPtr ptr = MakePtr(); + try + { + Renderer::GetInstance().CreateFontCollection(*ptr, resource); + } + catch (Exception&) + { + return nullptr; + } + return ptr; } Font::Font() {} -bool Font::Load(const String& file) +Font::Font(const String& family_name) + : family_name_(family_name) { - try - { - Renderer::GetInstance().CreateFontCollection(*this, file); - } - catch (RuntimeError&) - { - return false; - } - return true; -} - -bool Font::Load(const Resource& resource) -{ - try - { - Renderer::GetInstance().CreateFontCollection(*this, resource); - } - catch (RuntimeError&) - { - return false; - } - return true; } } // namespace kiwano diff --git a/src/kiwano/render/Font.h b/src/kiwano/render/Font.h index aee5e6e2..dfa59a85 100644 --- a/src/kiwano/render/Font.h +++ b/src/kiwano/render/Font.h @@ -39,49 +39,46 @@ class Renderer; */ class Font : public NativeObject { - friend class Renderer; - public: /// \~chinese /// @brief 创建字体 - Font(const String& file); + /// @param file 字体文件 + static FontPtr Preload(const String& file); /// \~chinese /// @brief 创建字体 - Font(const Resource& resource); + /// @param resource 字体资源 + static FontPtr Preload(const Resource& resource); Font(); /// \~chinese - /// @brief 加载字体文件 - bool Load(const String& file); + /// @brief 创建字体 + /// @param family_name 字体族 + Font(const String& family_name); /// \~chinese - /// @brief 加载字体资源 - bool Load(const Resource& resource); + /// @brief 获取字体族 + String GetFamilyName() const; /// \~chinese - /// @brief 获取字体族名称 - Vector GetFamilyNames() const; - - /// \~chinese - /// @brief 设置字体族名称 - void SetFamilyNames(const Vector& names); + /// @brief 获取字体族 + void SetFamilyName(const String& name); protected: - Vector family_names_; + String family_name_; }; /** @} */ -inline Vector Font::GetFamilyNames() const +inline String Font::GetFamilyName() const { - return family_names_; + return family_name_; } -inline void Font::SetFamilyNames(const Vector& names) +inline void Font::SetFamilyName(const String& name) { - family_names_ = names; + family_name_ = name; } } // namespace kiwano diff --git a/src/kiwano/render/Frame.cpp b/src/kiwano/render/Frame.cpp index f0a66265..54185929 100644 --- a/src/kiwano/render/Frame.cpp +++ b/src/kiwano/render/Frame.cpp @@ -19,7 +19,6 @@ // THE SOFTWARE. #include -#include namespace kiwano { @@ -43,7 +42,7 @@ Frame::Frame() {} bool Frame::Load(const String& file_path) { - TexturePtr texture = TextureCache::GetInstance().AddOrGetTexture(file_path); + TexturePtr texture = Texture::Preload(file_path); if (texture->IsValid()) { SetTexture(texture); @@ -54,7 +53,7 @@ bool Frame::Load(const String& file_path) bool Frame::Load(const Resource& res) { - TexturePtr texture = TextureCache::GetInstance().AddOrGetTexture(res); + TexturePtr texture = Texture::Preload(res); if (texture->IsValid()) { SetTexture(texture); diff --git a/src/kiwano/render/GifImage.cpp b/src/kiwano/render/GifImage.cpp index 0ac90987..a2c102e0 100644 --- a/src/kiwano/render/GifImage.cpp +++ b/src/kiwano/render/GifImage.cpp @@ -25,6 +25,18 @@ namespace kiwano { +GifImagePtr GifImage::Preload(const String& file_path) +{ + GifImagePtr image = Renderer::GetInstance().CreateGifImage(file_path); + return image; +} + +GifImagePtr GifImage::Preload(const Resource& res) +{ + GifImagePtr image = Renderer::GetInstance().CreateGifImage(res); + return image; +} + GifImage::GifImage(const String& file_path) : GifImage() { diff --git a/src/kiwano/render/GifImage.h b/src/kiwano/render/GifImage.h index 23745993..64d98811 100644 --- a/src/kiwano/render/GifImage.h +++ b/src/kiwano/render/GifImage.h @@ -38,6 +38,14 @@ KGE_DECLARE_SMART_PTR(GifImage); class KGE_API GifImage : public NativeObject { public: + /// \~chinese + /// @brief 预加载本地GIF图片 + static GifImagePtr Preload(const String& file_path); + + /// \~chinese + /// @brief 预加载GIF图片资源 + static GifImagePtr Preload(const Resource& res); + /// \~chinese /// @brief 创建GIF图片 GifImage(const String& file_path); diff --git a/src/kiwano/render/Renderer.cpp b/src/kiwano/render/Renderer.cpp index b041c68e..a4459c0e 100644 --- a/src/kiwano/render/Renderer.cpp +++ b/src/kiwano/render/Renderer.cpp @@ -18,6 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +#include // std::hash #include #include @@ -46,6 +47,71 @@ void Renderer::ResetResolutionWhenWindowResized(bool enabled) auto_reset_resolution_ = enabled; } +TexturePtr Renderer::CreateTexture(const String& file_path) +{ + size_t hash_code = std::hash{}(file_path); + if (TexturePtr ptr = texture_cache_.GetTexture(hash_code)) + { + return ptr; + } + TexturePtr ptr = MakePtr(); + if (ptr && ptr->Load(file_path)) + { + texture_cache_.AddTexture(hash_code, ptr); + } + return ptr; +} + +TexturePtr Renderer::CreateTexture(const Resource& resource) +{ + size_t hash_code = resource.GetId(); + if (TexturePtr ptr = texture_cache_.GetTexture(hash_code)) + { + return ptr; + } + TexturePtr ptr = MakePtr(); + if (ptr && ptr->Load(resource)) + { + texture_cache_.AddTexture(hash_code, ptr); + } + return ptr; +} + +GifImagePtr Renderer::CreateGifImage(const String& file_path) +{ + size_t hash_code = std::hash{}(file_path); + if (GifImagePtr ptr = texture_cache_.GetGifImage(hash_code)) + { + return ptr; + } + GifImagePtr ptr = MakePtr(); + if (ptr && ptr->Load(file_path)) + { + texture_cache_.AddGifImage(hash_code, ptr); + } + return ptr; +} + +GifImagePtr Renderer::CreateGifImage(const Resource& resource) +{ + size_t hash_code = resource.GetId(); + if (GifImagePtr ptr = texture_cache_.GetGifImage(hash_code)) + { + return ptr; + } + GifImagePtr ptr = MakePtr(); + if (ptr && ptr->Load(resource)) + { + texture_cache_.AddGifImage(hash_code, ptr); + } + return ptr; +} + +void Renderer::Destroy() +{ + texture_cache_.Clear(); +} + void Renderer::HandleEvent(EventModuleContext& ctx) { if (auto_reset_resolution_) @@ -58,4 +124,9 @@ void Renderer::HandleEvent(EventModuleContext& ctx) } } +TextureCache& Renderer::GetTextureCache() +{ + return texture_cache_; +} + } // namespace kiwano diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h index 4b552405..47a6174f 100644 --- a/src/kiwano/render/Renderer.h +++ b/src/kiwano/render/Renderer.h @@ -22,8 +22,9 @@ #include #include #include -#include +#include #include +#include #include namespace kiwano @@ -79,6 +80,26 @@ public: /// @brief 窗口大小变化时自动调整分辨率 void ResetResolutionWhenWindowResized(bool enabled); + /// \~chinese + /// @brief 创建纹理 + /// @param[in] file_path 图片路径 + TexturePtr CreateTexture(const String& file_path); + + /// \~chinese + /// @brief 创建纹理 + /// @param[in] resource 图片资源 + TexturePtr CreateTexture(const Resource& resource); + + /// \~chinese + /// @brief 创建GIF图像 + /// @param[in] file_path 图片路径 + GifImagePtr CreateGifImage(const String& file_path); + + /// \~chinese + /// @brief 创建GIF图像 + /// @param[in] resource 图片资源 + GifImagePtr CreateGifImage(const Resource& resource); + /// \~chinese /// @brief 创建纹理内部资源 /// @param[out] texture 纹理 @@ -221,6 +242,10 @@ public: /// @throw kiwano::SystemError 创建失败时抛出 virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0; + /// \~chinese + /// @brief 创建纹理渲染上下文 + TextureCache& GetTextureCache(); + public: /// \~chinese /// @brief 清除绘制内容 @@ -237,7 +262,7 @@ public: /// \~chinese /// @brief 销毁渲染器资源 - virtual void Destroy() = 0; + virtual void Destroy(); void HandleEvent(EventModuleContext& ctx) override; @@ -250,6 +275,8 @@ protected: Color clear_color_; Size output_size_; RenderContextPtr render_ctx_; + + TextureCache texture_cache_; }; /** @} */ diff --git a/src/kiwano/render/TextLayout.h b/src/kiwano/render/TextLayout.h index 3dfe0444..764b20be 100644 --- a/src/kiwano/render/TextLayout.h +++ b/src/kiwano/render/TextLayout.h @@ -21,7 +21,7 @@ #pragma once #include #include -#include +#include namespace kiwano { diff --git a/src/kiwano/render/TextStyle.cpp b/src/kiwano/render/TextStyle.cpp new file mode 100644 index 00000000..aad82bf5 --- /dev/null +++ b/src/kiwano/render/TextStyle.cpp @@ -0,0 +1,57 @@ +// 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 + +namespace kiwano +{ + +TextStyle::TextStyle() + : TextStyle(String(), 18, FontWeight::Normal) +{ +} + +TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight) + : font_size(font_size) + , font_weight(font_weight) + , italic(false) + , alignment(TextAlign::Left) + , wrap_width(0) + , line_spacing(0) + , show_underline(false) + , show_strikethrough(false) +{ + font = MakePtr(font_family); +} + +TextStyle::TextStyle(FontPtr font, float font_size, uint32_t font_weight) + : font(font) + , font_size(font_size) + , font_weight(font_weight) + , italic(false) + , alignment(TextAlign::Left) + , wrap_width(0) + , line_spacing(0) + , show_underline(false) + , show_strikethrough(false) +{ +} + +} // namespace kiwano diff --git a/src/kiwano/render/TextStyle.hpp b/src/kiwano/render/TextStyle.h similarity index 85% rename from src/kiwano/render/TextStyle.hpp rename to src/kiwano/render/TextStyle.h index c4d6657e..70d8b652 100644 --- a/src/kiwano/render/TextStyle.hpp +++ b/src/kiwano/render/TextStyle.h @@ -71,7 +71,6 @@ class KGE_API TextStyle { public: FontPtr font; ///< 字体 - String font_family; ///< 字体族 float font_size; ///< 字号 uint32_t font_weight; ///< 粗细值 bool italic; ///< 是否斜体 @@ -99,27 +98,17 @@ public: * @param font_weight 字体粗细 */ TextStyle(const String& font_family, float font_size, uint32_t font_weight = FontWeight::Normal); + + /** + * \~chinese + * @brief 构建文本样式 + * @param font 字体 + * @param font_size 字体大小 + * @param font_weight 字体粗细 + */ + TextStyle(FontPtr font, float font_size, uint32_t font_weight = FontWeight::Normal); }; /** @} */ -inline TextStyle::TextStyle() - : TextStyle(String(), 18, FontWeight::Normal) -{ -} - -inline TextStyle::TextStyle(const String& font_family, float font_size, uint32_t font_weight) - : font(nullptr) - , font_family(font_family) - , font_size(font_size) - , font_weight(font_weight) - , italic(false) - , alignment(TextAlign::Left) - , wrap_width(0) - , line_spacing(0) - , show_underline(false) - , show_strikethrough(false) -{ -} - } // namespace kiwano diff --git a/src/kiwano/render/Texture.cpp b/src/kiwano/render/Texture.cpp index aecc0dc3..3e2bd993 100644 --- a/src/kiwano/render/Texture.cpp +++ b/src/kiwano/render/Texture.cpp @@ -30,6 +30,18 @@ namespace kiwano InterpolationMode Texture::default_interpolation_mode_ = InterpolationMode::Linear; +TexturePtr Texture::Preload(const String& file_path) +{ + TexturePtr image = Renderer::GetInstance().CreateTexture(file_path); + return image; +} + +TexturePtr Texture::Preload(const Resource& res) +{ + TexturePtr image = Renderer::GetInstance().CreateTexture(res); + return image; +} + Texture::Texture(const String& file_path) : Texture() { diff --git a/src/kiwano/render/Texture.h b/src/kiwano/render/Texture.h index f3c4bf51..e837e26c 100644 --- a/src/kiwano/render/Texture.h +++ b/src/kiwano/render/Texture.h @@ -54,6 +54,16 @@ typedef math::Vec2T PixelSize; class KGE_API Texture : public NativeObject { public: + /// \~chinese + /// @brief 预加载本地图片 + static TexturePtr Preload(const String& file_path); + + /// \~chinese + /// @brief 预加载图片资源 + static TexturePtr Preload(const Resource& res); + + Texture(); + /// \~chinese /// @brief 从本地文件创建纹理 Texture(const String& file_path); @@ -62,8 +72,6 @@ public: /// @brief 从资源创建纹理 Texture(const Resource& res); - Texture(); - virtual ~Texture(); /// \~chinese diff --git a/src/kiwano/render/TextureCache.cpp b/src/kiwano/render/TextureCache.cpp index 143d650c..c6922b8c 100644 --- a/src/kiwano/render/TextureCache.cpp +++ b/src/kiwano/render/TextureCache.cpp @@ -18,85 +18,54 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include -#include #include namespace kiwano { -template -RefPtr<_Ty> CreateOrGetCache(_CacheTy& cache, const _PathTy& path, size_t hash) -{ - auto iter = cache.find(hash); - if (iter != cache.end()) - { - return iter->second; - } - - RefPtr<_Ty> texture = MakePtr<_Ty>(); - if (texture->Load(path)) - { - cache.insert(std::make_pair(hash, texture)); - } - return texture; -} - -template -void RemoveCache(_CacheTy& cache, size_t hash) -{ - auto iter = cache.find(hash); - if (iter != cache.end()) - { - cache.erase(iter); - } -} TextureCache::TextureCache() {} -TextureCache::~TextureCache() {} - -TexturePtr TextureCache::AddOrGetTexture(const String& file_path) +TextureCache::~TextureCache() { - size_t hash = std::hash()(file_path); - return CreateOrGetCache(texture_cache_, file_path, hash); + Clear(); } -TexturePtr TextureCache::AddOrGetTexture(const Resource& res) +void TextureCache::AddTexture(size_t key, TexturePtr texture) { - return CreateOrGetCache(texture_cache_, res, res.GetId()); + texture_cache_.insert(std::make_pair(key, texture)); } -GifImagePtr TextureCache::AddOrGetGifImage(const String& file_path) +void TextureCache::AddGifImage(size_t key, GifImagePtr gif) { - size_t hash = std::hash()(file_path); - return CreateOrGetCache(gif_texture_cache_, file_path, hash); + gif_texture_cache_.insert(std::make_pair(key, gif)); } -GifImagePtr TextureCache::AddOrGetGifImage(const Resource& res) +TexturePtr TextureCache::GetTexture(size_t key) const { - return CreateOrGetCache(gif_texture_cache_, res, res.GetId()); + if (texture_cache_.count(key)) + { + return texture_cache_.at(key); + } + return TexturePtr(); } -void TextureCache::RemoveTexture(const String& file_path) +GifImagePtr TextureCache::GetGifImage(size_t key) const { - size_t hash = std::hash()(file_path); - RemoveCache(texture_cache_, hash); + if (gif_texture_cache_.count(key)) + { + return gif_texture_cache_.at(key); + } + return GifImagePtr(); } -void TextureCache::RemoveTexture(const Resource& res) +void TextureCache::RemoveTexture(size_t key) { - RemoveCache(texture_cache_, res.GetId()); + texture_cache_.erase(key); } -void TextureCache::RemoveGifImage(const String& file_path) +void TextureCache::RemoveGifImage(size_t key) { - size_t hash = std::hash()(file_path); - RemoveCache(gif_texture_cache_, hash); -} - -void TextureCache::RemoveGifImage(const Resource& res) -{ - RemoveCache(gif_texture_cache_, res.GetId()); + gif_texture_cache_.erase(key); } void TextureCache::Clear() diff --git a/src/kiwano/render/TextureCache.h b/src/kiwano/render/TextureCache.h index 391755ab..687501f5 100644 --- a/src/kiwano/render/TextureCache.h +++ b/src/kiwano/render/TextureCache.h @@ -33,52 +33,41 @@ namespace kiwano * \~chinese * @brief 纹理缓存 */ -class KGE_API TextureCache final : public Singleton +class KGE_API TextureCache final : Noncopyable { - friend Singleton; - public: - /// \~chinese - /// @brief 添加或获取纹理 - TexturePtr AddOrGetTexture(const String& file_path); + TextureCache(); + + ~TextureCache(); /// \~chinese /// @brief 添加或获取纹理 - TexturePtr AddOrGetTexture(const Resource& res); + void AddTexture(size_t key, TexturePtr texture); /// \~chinese /// @brief 添加或获取GIF图像 - GifImagePtr AddOrGetGifImage(const String& file_path); + void AddGifImage(size_t key, GifImagePtr gif); /// \~chinese - /// @brief 添加或获取GIF图像 - GifImagePtr AddOrGetGifImage(const Resource& res); + /// @brief 获取纹理缓存 + TexturePtr GetTexture(size_t key) const; + + /// \~chinese + /// @brief 获取GIF图像缓存 + GifImagePtr GetGifImage(size_t key) const; /// \~chinese /// @brief 移除纹理缓存 - void RemoveTexture(const String& file_path); - - /// \~chinese - /// @brief 移除纹理缓存 - void RemoveTexture(const Resource& res); + void RemoveTexture(size_t key); /// \~chinese /// @brief 移除GIF图像缓存 - void RemoveGifImage(const String& file_path); - - /// \~chinese - /// @brief 移除GIF图像缓存 - void RemoveGifImage(const Resource& res); + void RemoveGifImage(size_t key); /// \~chinese /// @brief 清空缓存 void Clear(); - virtual ~TextureCache(); - -private: - TextureCache(); - private: using TextureMap = UnorderedMap; TextureMap texture_cache_; diff --git a/src/kiwano/utils/ResourceLoader.cpp b/src/kiwano/utils/ResourceLoader.cpp index 6aa7831e..59ccc770 100644 --- a/src/kiwano/utils/ResourceLoader.cpp +++ b/src/kiwano/utils/ResourceLoader.cpp @@ -185,8 +185,8 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& if (type == "gif") { // GIF image - GifImagePtr gif = MakePtr(); - if (gif && gif->Load(gdata->path + file)) + GifImagePtr gif = GifImage::Preload(gdata->path + file); + if (gif) { cache->AddObject(id, gif); return; @@ -273,8 +273,8 @@ void LoadTexturesFromData(ResourceCache* cache, GlobalData* gdata, const String& void LoadFontsFromData(ResourceCache* cache, GlobalData* gdata, const String& id, const String& file) { - FontPtr font = MakePtr(); - if (font && font->Load(gdata->path + file)) + FontPtr font = Font::Preload(gdata->path + file); + if (font) { cache->AddObject(id, font); return;