[deploy] add Font::Preload
This commit is contained in:
		
							parent
							
								
									69f298211c
								
							
						
					
					
						commit
						31692c2a70
					
				|  | @ -89,6 +89,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) override; |     void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) override; | ||||||
| 
 | 
 | ||||||
|  |     void ResetTextRenderingParams(_In_ HMONITOR monitor) override; | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     unsigned long STDMETHODCALLTYPE AddRef(); |     unsigned long STDMETHODCALLTYPE AddRef(); | ||||||
| 
 | 
 | ||||||
|  | @ -386,6 +388,18 @@ void D2DDeviceResources::SetTargetBitmap(ComPtr<ID2D1Bitmap1> target) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void D2DDeviceResources::ResetTextRenderingParams(HMONITOR monitor) | ||||||
|  | { | ||||||
|  |     if (!dwrite_factory_ || device_context_) | ||||||
|  |         return; | ||||||
|  | 
 | ||||||
|  |     ComPtr<IDWriteRenderingParams> params; | ||||||
|  |     if (SUCCEEDED(dwrite_factory_->CreateMonitorRenderingParams(monitor, ¶ms))) | ||||||
|  |     { | ||||||
|  |         device_context_->SetTextRenderingParams(params.Get()); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| HRESULT D2DDeviceResources::CreateBitmapConverter(_Out_ ComPtr<IWICFormatConverter>& converter, | HRESULT D2DDeviceResources::CreateBitmapConverter(_Out_ ComPtr<IWICFormatConverter>& converter, | ||||||
|                                                   _In_opt_ ComPtr<IWICBitmapSource> source, |                                                   _In_opt_ ComPtr<IWICBitmapSource> source, | ||||||
|                                                   _In_ REFWICPixelFormatGUID format, WICBitmapDitherType dither, |                                                   _In_ REFWICPixelFormatGUID format, WICBitmapDitherType dither, | ||||||
|  | @ -488,9 +502,9 @@ HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& te | ||||||
|         return E_UNEXPECTED; |         return E_UNEXPECTED; | ||||||
| 
 | 
 | ||||||
|     ComPtr<IDWriteTextFormat> output; |     ComPtr<IDWriteTextFormat> output; | ||||||
|     HRESULT                   hr = |  | ||||||
|         dwrite_factory_->CreateTextFormat(family, collection.Get(), weight, style, stretch, font_size, L"", &output); |  | ||||||
| 
 | 
 | ||||||
|  |     HRESULT hr = | ||||||
|  |         dwrite_factory_->CreateTextFormat(family, collection.Get(), weight, style, stretch, font_size, L"", &output); | ||||||
|     if (SUCCEEDED(hr)) |     if (SUCCEEDED(hr)) | ||||||
|     { |     { | ||||||
|         text_format = output; |         text_format = output; | ||||||
|  |  | ||||||
|  | @ -76,6 +76,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     virtual void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) = 0; |     virtual void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) = 0; | ||||||
| 
 | 
 | ||||||
|  |     virtual void ResetTextRenderingParams(_In_ HMONITOR monitor) = 0; | ||||||
|  | 
 | ||||||
|     inline ID2D1Factory1* GetFactory() |     inline ID2D1Factory1* GetFactory() | ||||||
|     { |     { | ||||||
|         KGE_ASSERT(factory_); |         KGE_ASSERT(factory_); | ||||||
|  |  | ||||||
|  | @ -39,16 +39,16 @@ public: | ||||||
|     STDMETHOD(AddFilePaths) |     STDMETHOD(AddFilePaths) | ||||||
|     (const Vector<String>& filePaths, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); |     (const Vector<String>& filePaths, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); | ||||||
| 
 | 
 | ||||||
|     // IUnknown methods
 |  | ||||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); |  | ||||||
| 
 |  | ||||||
|     // IDWriteFontCollectionLoader methods
 |     // IDWriteFontCollectionLoader methods
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, |     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, | ||||||
|                                                               uint32_t collectionKeySize, |                                                               uint32_t collectionKeySize, | ||||||
|                                                               _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); |                                                               _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); | ||||||
| 
 | 
 | ||||||
|  |     // IUnknown methods
 | ||||||
|  |     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     ULONG refCount_; |     ULONG refCount_; | ||||||
| 
 | 
 | ||||||
|  | @ -108,35 +108,6 @@ STDMETHODIMP FontCollectionLoader::AddFilePaths(const Vector<String>& filePaths, | ||||||
|     return S_OK; |     return S_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT STDMETHODCALLTYPE FontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) |  | ||||||
| { |  | ||||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) |  | ||||||
|     { |  | ||||||
|         *ppvObject = this; |  | ||||||
|         AddRef(); |  | ||||||
|         return S_OK; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         *ppvObject = NULL; |  | ||||||
|         return E_NOINTERFACE; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE FontCollectionLoader::AddRef() |  | ||||||
| { |  | ||||||
|     return InterlockedIncrement(&refCount_); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE FontCollectionLoader::Release() |  | ||||||
| { |  | ||||||
|     ULONG newCount = InterlockedDecrement(&refCount_); |  | ||||||
|     if (newCount == 0) |  | ||||||
|         delete this; |  | ||||||
| 
 |  | ||||||
|     return newCount; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT STDMETHODCALLTYPE FontCollectionLoader::CreateEnumeratorFromKey( | HRESULT STDMETHODCALLTYPE FontCollectionLoader::CreateEnumeratorFromKey( | ||||||
|     IDWriteFactory* pFactory, void const* collectionKey, uint32_t collectionKeySize, |     IDWriteFactory* pFactory, void const* collectionKey, uint32_t collectionKeySize, | ||||||
|     _Out_ IDWriteFontFileEnumerator** fontFileEnumerator) |     _Out_ IDWriteFontFileEnumerator** fontFileEnumerator) | ||||||
|  | @ -166,6 +137,35 @@ HRESULT STDMETHODCALLTYPE FontCollectionLoader::CreateEnumeratorFromKey( | ||||||
|     return hr; |     return hr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | HRESULT STDMETHODCALLTYPE FontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) | ||||||
|  | { | ||||||
|  |     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) | ||||||
|  |     { | ||||||
|  |         *ppvObject = this; | ||||||
|  |         AddRef(); | ||||||
|  |         return S_OK; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         *ppvObject = NULL; | ||||||
|  |         return E_NOINTERFACE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE FontCollectionLoader::AddRef() | ||||||
|  | { | ||||||
|  |     return InterlockedIncrement(&refCount_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE FontCollectionLoader::Release() | ||||||
|  | { | ||||||
|  |     ULONG newCount = InterlockedDecrement(&refCount_); | ||||||
|  |     if (newCount == 0) | ||||||
|  |         delete this; | ||||||
|  | 
 | ||||||
|  |     return newCount; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| //
 | //
 | ||||||
| // FontFileEnumerator
 | // FontFileEnumerator
 | ||||||
|  | @ -177,25 +177,25 @@ class FontFileEnumerator : public IFontFileEnumerator | ||||||
| public: | public: | ||||||
|     FontFileEnumerator(); |     FontFileEnumerator(); | ||||||
| 
 | 
 | ||||||
|     STDMETHOD(Initialize)(IDWriteFactory* pFactory); |  | ||||||
| 
 |  | ||||||
|     STDMETHOD(SetFilePaths)(const Vector<String>& filePaths); |  | ||||||
| 
 |  | ||||||
|     ~FontFileEnumerator() |     ~FontFileEnumerator() | ||||||
|     { |     { | ||||||
|         DX::SafeRelease(currentFile_); |         DX::SafeRelease(currentFile_); | ||||||
|         DX::SafeRelease(pFactory_); |         DX::SafeRelease(pFactory_); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // IUnknown methods
 |     STDMETHOD(Initialize)(IDWriteFactory* pFactory); | ||||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _Out_ void** ppvObject); | 
 | ||||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); |     STDMETHOD(SetFilePaths)(const Vector<String>& filePaths); | ||||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); |  | ||||||
| 
 | 
 | ||||||
|     // IDWriteFontFileEnumerator methods
 |     // IDWriteFontFileEnumerator methods
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); |     virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); | ||||||
|     virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(_Out_ IDWriteFontFile** fontFile); |     virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(_Out_ IDWriteFontFile** fontFile); | ||||||
| 
 | 
 | ||||||
|  |     // IUnknown methods
 | ||||||
|  |     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _Out_ void** ppvObject); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     ULONG refCount_; |     ULONG refCount_; | ||||||
| 
 | 
 | ||||||
|  | @ -268,35 +268,6 @@ STDMETHODIMP FontFileEnumerator::SetFilePaths(const Vector<String>& filePaths) | ||||||
|     return S_OK; |     return S_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT STDMETHODCALLTYPE FontFileEnumerator::QueryInterface(REFIID iid, _Out_ void** ppvObject) |  | ||||||
| { |  | ||||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) |  | ||||||
|     { |  | ||||||
|         *ppvObject = this; |  | ||||||
|         AddRef(); |  | ||||||
|         return S_OK; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         *ppvObject = NULL; |  | ||||||
|         return E_NOINTERFACE; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE FontFileEnumerator::AddRef() |  | ||||||
| { |  | ||||||
|     return InterlockedIncrement(&refCount_); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE FontFileEnumerator::Release() |  | ||||||
| { |  | ||||||
|     ULONG newCount = InterlockedDecrement(&refCount_); |  | ||||||
|     if (newCount == 0) |  | ||||||
|         delete this; |  | ||||||
| 
 |  | ||||||
|     return newCount; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT STDMETHODCALLTYPE FontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFile) | HRESULT STDMETHODCALLTYPE FontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFile) | ||||||
| { | { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
|  | @ -328,6 +299,35 @@ HRESULT STDMETHODCALLTYPE FontFileEnumerator::GetCurrentFontFile(_Out_ IDWriteFo | ||||||
|     return (currentFile_ != NULL) ? S_OK : E_FAIL; |     return (currentFile_ != NULL) ? S_OK : E_FAIL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | HRESULT STDMETHODCALLTYPE FontFileEnumerator::QueryInterface(REFIID iid, _Out_ void** ppvObject) | ||||||
|  | { | ||||||
|  |     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) | ||||||
|  |     { | ||||||
|  |         *ppvObject = this; | ||||||
|  |         AddRef(); | ||||||
|  |         return S_OK; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         *ppvObject = NULL; | ||||||
|  |         return E_NOINTERFACE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE FontFileEnumerator::AddRef() | ||||||
|  | { | ||||||
|  |     return InterlockedIncrement(&refCount_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE FontFileEnumerator::Release() | ||||||
|  | { | ||||||
|  |     ULONG newCount = InterlockedDecrement(&refCount_); | ||||||
|  |     if (newCount == 0) | ||||||
|  |         delete this; | ||||||
|  | 
 | ||||||
|  |     return newCount; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| //
 | //
 | ||||||
| // ResourceFontCollectionLoader
 | // ResourceFontCollectionLoader
 | ||||||
|  | @ -346,16 +346,16 @@ public: | ||||||
|     STDMETHOD(AddResources) |     STDMETHOD(AddResources) | ||||||
|     (const Vector<Resource>& resources, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); |     (const Vector<Resource>& resources, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize); | ||||||
| 
 | 
 | ||||||
|     // IUnknown methods
 |  | ||||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); |  | ||||||
| 
 |  | ||||||
|     // IDWriteFontCollectionLoader methods
 |     // IDWriteFontCollectionLoader methods
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, |     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, | ||||||
|                                                               uint32_t collectionKeySize, |                                                               uint32_t collectionKeySize, | ||||||
|                                                               _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); |                                                               _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); | ||||||
| 
 | 
 | ||||||
|  |     // IUnknown methods
 | ||||||
|  |     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     ULONG                  refCount_; |     ULONG                  refCount_; | ||||||
|     IDWriteFontFileLoader* pFileLoader_; |     IDWriteFontFileLoader* pFileLoader_; | ||||||
|  | @ -417,35 +417,6 @@ STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<Resource>& | ||||||
|     return S_OK; |     return S_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) |  | ||||||
| { |  | ||||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) |  | ||||||
|     { |  | ||||||
|         *ppvObject = this; |  | ||||||
|         AddRef(); |  | ||||||
|         return S_OK; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         *ppvObject = NULL; |  | ||||||
|         return E_NOINTERFACE; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE ResourceFontCollectionLoader::AddRef() |  | ||||||
| { |  | ||||||
|     return InterlockedIncrement(&refCount_); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE ResourceFontCollectionLoader::Release() |  | ||||||
| { |  | ||||||
|     ULONG newCount = InterlockedDecrement(&refCount_); |  | ||||||
|     if (newCount == 0) |  | ||||||
|         delete this; |  | ||||||
| 
 |  | ||||||
|     return newCount; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::CreateEnumeratorFromKey( | HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::CreateEnumeratorFromKey( | ||||||
|     IDWriteFactory* pFactory, void const* collectionKey, uint32_t collectionKeySize, |     IDWriteFactory* pFactory, void const* collectionKey, uint32_t collectionKeySize, | ||||||
|     _Out_ IDWriteFontFileEnumerator** fontFileEnumerator) |     _Out_ IDWriteFontFileEnumerator** fontFileEnumerator) | ||||||
|  | @ -476,6 +447,35 @@ HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::CreateEnumeratorFromKey( | ||||||
|     return hr; |     return hr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) | ||||||
|  | { | ||||||
|  |     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) | ||||||
|  |     { | ||||||
|  |         *ppvObject = this; | ||||||
|  |         AddRef(); | ||||||
|  |         return S_OK; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         *ppvObject = NULL; | ||||||
|  |         return E_NOINTERFACE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE ResourceFontCollectionLoader::AddRef() | ||||||
|  | { | ||||||
|  |     return InterlockedIncrement(&refCount_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE ResourceFontCollectionLoader::Release() | ||||||
|  | { | ||||||
|  |     ULONG newCount = InterlockedDecrement(&refCount_); | ||||||
|  |     if (newCount == 0) | ||||||
|  |         delete this; | ||||||
|  | 
 | ||||||
|  |     return newCount; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| //
 | //
 | ||||||
| // ResourceFontFileLoader
 | // ResourceFontFileLoader
 | ||||||
|  | @ -490,16 +490,16 @@ public: | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // IUnknown methods
 |  | ||||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); |  | ||||||
| 
 |  | ||||||
|     // IDWriteFontFileLoader methods
 |     // IDWriteFontFileLoader methods
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, |     virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, | ||||||
|                                                           uint32_t    fontFileReferenceKeySize, |                                                           uint32_t    fontFileReferenceKeySize, | ||||||
|                                                           _Out_ IDWriteFontFileStream** fontFileStream); |                                                           _Out_ IDWriteFontFileStream** fontFileStream); | ||||||
| 
 | 
 | ||||||
|  |     // IUnknown methods
 | ||||||
|  |     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     ULONG refCount_; |     ULONG refCount_; | ||||||
| }; | }; | ||||||
|  | @ -526,6 +526,33 @@ HRESULT IResourceFontFileLoader::Create(_Out_ IResourceFontFileLoader** ppFileLo | ||||||
|     return hr; |     return hr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | HRESULT STDMETHODCALLTYPE ResourceFontFileLoader::CreateStreamFromKey(void const* fontFileReferenceKey, | ||||||
|  |                                                                       uint32_t    fontFileReferenceKeySize, | ||||||
|  |                                                                       _Out_ IDWriteFontFileStream** fontFileStream) | ||||||
|  | { | ||||||
|  |     HRESULT hr = S_OK; | ||||||
|  | 
 | ||||||
|  |     // Make sure the key is the right size.
 | ||||||
|  |     if (fontFileReferenceKeySize != sizeof(Resource)) | ||||||
|  |         hr = E_INVALIDARG; | ||||||
|  | 
 | ||||||
|  |     if (SUCCEEDED(hr)) | ||||||
|  |     { | ||||||
|  |         // Create the pFileStream object.
 | ||||||
|  |         IResourceFontFileStream* pFileStream = NULL; | ||||||
|  |         Resource                 resource    = *static_cast<Resource const*>(fontFileReferenceKey); | ||||||
|  | 
 | ||||||
|  |         hr = IResourceFontFileStream::Create(&pFileStream, resource); | ||||||
|  | 
 | ||||||
|  |         if (SUCCEEDED(hr)) | ||||||
|  |         { | ||||||
|  |             DX::SafeRelease(*fontFileStream); | ||||||
|  |             (*fontFileStream) = pFileStream; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return hr; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) | HRESULT STDMETHODCALLTYPE ResourceFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) | ||||||
| { | { | ||||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) |     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) | ||||||
|  | @ -555,33 +582,6 @@ ULONG STDMETHODCALLTYPE ResourceFontFileLoader::Release() | ||||||
|     return newCount; |     return newCount; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontFileLoader::CreateStreamFromKey(void const* fontFileReferenceKey, |  | ||||||
|                                                                       uint32_t    fontFileReferenceKeySize, |  | ||||||
|                                                                       _Out_ IDWriteFontFileStream** fontFileStream) |  | ||||||
| { |  | ||||||
|     HRESULT hr = S_OK; |  | ||||||
| 
 |  | ||||||
|     // Make sure the key is the right size.
 |  | ||||||
|     if (fontFileReferenceKeySize != sizeof(Resource)) |  | ||||||
|         hr = E_INVALIDARG; |  | ||||||
| 
 |  | ||||||
|     if (SUCCEEDED(hr)) |  | ||||||
|     { |  | ||||||
|         // Create the pFileStream object.
 |  | ||||||
|         IResourceFontFileStream* pFileStream = NULL; |  | ||||||
|         Resource                 resource    = *static_cast<Resource const*>(fontFileReferenceKey); |  | ||||||
| 
 |  | ||||||
|         hr = IResourceFontFileStream::Create(&pFileStream, resource); |  | ||||||
| 
 |  | ||||||
|         if (SUCCEEDED(hr)) |  | ||||||
|         { |  | ||||||
|             DX::SafeRelease(*fontFileStream); |  | ||||||
|             (*fontFileStream) = pFileStream; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     return hr; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| //
 | //
 | ||||||
| // ResourceFontFileEnumerator
 | // ResourceFontFileEnumerator
 | ||||||
|  | @ -593,25 +593,25 @@ class ResourceFontFileEnumerator : public IResourceFontFileEnumerator | ||||||
| public: | public: | ||||||
|     ResourceFontFileEnumerator(); |     ResourceFontFileEnumerator(); | ||||||
| 
 | 
 | ||||||
|     STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader); |  | ||||||
| 
 |  | ||||||
|     STDMETHOD(SetResources)(const Vector<Resource>& resources); |  | ||||||
| 
 |  | ||||||
|     ~ResourceFontFileEnumerator() |     ~ResourceFontFileEnumerator() | ||||||
|     { |     { | ||||||
|         DX::SafeRelease(currentFile_); |         DX::SafeRelease(currentFile_); | ||||||
|         DX::SafeRelease(pFactory_); |         DX::SafeRelease(pFactory_); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // IUnknown methods
 |     STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader); | ||||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _Out_ void** ppvObject); | 
 | ||||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); |     STDMETHOD(SetResources)(const Vector<Resource>& resources); | ||||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); |  | ||||||
| 
 | 
 | ||||||
|     // IDWriteFontFileEnumerator methods
 |     // IDWriteFontFileEnumerator methods
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); |     virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); | ||||||
|     virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(_Out_ IDWriteFontFile** fontFile); |     virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(_Out_ IDWriteFontFile** fontFile); | ||||||
| 
 | 
 | ||||||
|  |     // IUnknown methods
 | ||||||
|  |     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _Out_ void** ppvObject); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||||
|  |     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     ULONG refCount_; |     ULONG refCount_; | ||||||
| 
 | 
 | ||||||
|  | @ -688,35 +688,6 @@ STDMETHODIMP ResourceFontFileEnumerator::SetResources(const Vector<Resource>& re | ||||||
|     return S_OK; |     return S_OK; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::QueryInterface(REFIID iid, _Out_ void** ppvObject) |  | ||||||
| { |  | ||||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) |  | ||||||
|     { |  | ||||||
|         *ppvObject = this; |  | ||||||
|         AddRef(); |  | ||||||
|         return S_OK; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         *ppvObject = NULL; |  | ||||||
|         return E_NOINTERFACE; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE ResourceFontFileEnumerator::AddRef() |  | ||||||
| { |  | ||||||
|     return InterlockedIncrement(&refCount_); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE ResourceFontFileEnumerator::Release() |  | ||||||
| { |  | ||||||
|     ULONG newCount = InterlockedDecrement(&refCount_); |  | ||||||
|     if (newCount == 0) |  | ||||||
|         delete this; |  | ||||||
| 
 |  | ||||||
|     return newCount; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFile) | HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFile) | ||||||
| { | { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
|  | @ -747,6 +718,35 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::GetCurrentFontFile(_Out_ I | ||||||
|     return (currentFile_ != NULL) ? S_OK : E_FAIL; |     return (currentFile_ != NULL) ? S_OK : E_FAIL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::QueryInterface(REFIID iid, _Out_ void** ppvObject) | ||||||
|  | { | ||||||
|  |     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) | ||||||
|  |     { | ||||||
|  |         *ppvObject = this; | ||||||
|  |         AddRef(); | ||||||
|  |         return S_OK; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         *ppvObject = NULL; | ||||||
|  |         return E_NOINTERFACE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE ResourceFontFileEnumerator::AddRef() | ||||||
|  | { | ||||||
|  |     return InterlockedIncrement(&refCount_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE ResourceFontFileEnumerator::Release() | ||||||
|  | { | ||||||
|  |     ULONG newCount = InterlockedDecrement(&refCount_); | ||||||
|  |     if (newCount == 0) | ||||||
|  |         delete this; | ||||||
|  | 
 | ||||||
|  |     return newCount; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| ////////////////////////////////////////////////////////////////////////////////////////
 | ////////////////////////////////////////////////////////////////////////////////////////
 | ||||||
| //
 | //
 | ||||||
| // ResourceFontFileStream
 | // ResourceFontFileStream
 | ||||||
|  | @ -760,11 +760,6 @@ public: | ||||||
| 
 | 
 | ||||||
|     STDMETHOD(Initialize)(Resource const resources); |     STDMETHOD(Initialize)(Resource const resources); | ||||||
| 
 | 
 | ||||||
|     // IUnknown methods
 |  | ||||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); |  | ||||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); |  | ||||||
| 
 |  | ||||||
|     // IDWriteFontFileStream methods
 |     // IDWriteFontFileStream methods
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, |     virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, | ||||||
|                                                        UINT64 fragmentSize, _Out_ void** fragmentContext); |                                                        UINT64 fragmentSize, _Out_ void** fragmentContext); | ||||||
|  | @ -775,10 +770,10 @@ public: | ||||||
| 
 | 
 | ||||||
|     virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(_Out_ UINT64* lastWriteTime); |     virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(_Out_ UINT64* lastWriteTime); | ||||||
| 
 | 
 | ||||||
|     bool IsInitialized() |     // IUnknown methods
 | ||||||
|     { |     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||||
|         return resourcePtr_ != NULL; |     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||||
|     } |     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     ULONG  refCount_; |     ULONG  refCount_; | ||||||
|  | @ -834,36 +829,6 @@ STDMETHODIMP ResourceFontFileStream::Initialize(const Resource resource) | ||||||
|     return hr; |     return hr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // IUnknown methods
 |  | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontFileStream::QueryInterface(REFIID iid, void** ppvObject) |  | ||||||
| { |  | ||||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) |  | ||||||
|     { |  | ||||||
|         *ppvObject = this; |  | ||||||
|         AddRef(); |  | ||||||
|         return S_OK; |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         *ppvObject = NULL; |  | ||||||
|         return E_NOINTERFACE; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE ResourceFontFileStream::AddRef() |  | ||||||
| { |  | ||||||
|     return InterlockedIncrement(&refCount_); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| ULONG STDMETHODCALLTYPE ResourceFontFileStream::Release() |  | ||||||
| { |  | ||||||
|     ULONG newCount = InterlockedDecrement(&refCount_); |  | ||||||
|     if (newCount == 0) |  | ||||||
|         delete this; |  | ||||||
| 
 |  | ||||||
|     return newCount; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| HRESULT STDMETHODCALLTYPE ResourceFontFileStream::ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, | HRESULT STDMETHODCALLTYPE ResourceFontFileStream::ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, | ||||||
|                                                                    UINT64 fragmentSize, _Out_ void** fragmentContext) |                                                                    UINT64 fragmentSize, _Out_ void** fragmentContext) | ||||||
| { | { | ||||||
|  | @ -896,4 +861,34 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileStream::GetLastWriteTime(_Out_ UINT64* | ||||||
|     return E_NOTIMPL; |     return E_NOTIMPL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // IUnknown methods
 | ||||||
|  | HRESULT STDMETHODCALLTYPE ResourceFontFileStream::QueryInterface(REFIID iid, void** ppvObject) | ||||||
|  | { | ||||||
|  |     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) | ||||||
|  |     { | ||||||
|  |         *ppvObject = this; | ||||||
|  |         AddRef(); | ||||||
|  |         return S_OK; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         *ppvObject = NULL; | ||||||
|  |         return E_NOINTERFACE; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE ResourceFontFileStream::AddRef() | ||||||
|  | { | ||||||
|  |     return InterlockedIncrement(&refCount_); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | ULONG STDMETHODCALLTYPE ResourceFontFileStream::Release() | ||||||
|  | { | ||||||
|  |     ULONG newCount = InterlockedDecrement(&refCount_); | ||||||
|  |     if (newCount == 0) | ||||||
|  |         delete this; | ||||||
|  | 
 | ||||||
|  |     return newCount; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| }  // namespace kiwano
 | }  // namespace kiwano
 | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include <kiwano/utils/Logger.h> | #include <kiwano/utils/Logger.h> | ||||||
|  | #include <kiwano/event/Events.h> | ||||||
| #include <kiwano/platform/FileSystem.h> | #include <kiwano/platform/FileSystem.h> | ||||||
| #include <kiwano/platform/Application.h> | #include <kiwano/platform/Application.h> | ||||||
| #include <kiwano/render/ShapeMaker.h> | #include <kiwano/render/ShapeMaker.h> | ||||||
|  | @ -48,6 +49,7 @@ RendererImpl& RendererImpl::GetInstance() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RendererImpl::RendererImpl() | RendererImpl::RendererImpl() | ||||||
|  |     : monitor_(nullptr) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -62,6 +64,7 @@ void RendererImpl::MakeContextForWindow(WindowPtr window) | ||||||
|     HRESULT    hr            = target_window ? S_OK : E_FAIL; |     HRESULT    hr            = target_window ? S_OK : E_FAIL; | ||||||
| 
 | 
 | ||||||
|     output_size_ = Size{ float(resolution.width), float(resolution.height) }; |     output_size_ = Size{ float(resolution.width), float(resolution.height) }; | ||||||
|  |     monitor_     = ::MonitorFromWindow(target_window, MONITOR_DEFAULTTONULL); | ||||||
| 
 | 
 | ||||||
|     // Initialize Direct3D resources
 |     // Initialize Direct3D resources
 | ||||||
|     if (SUCCEEDED(hr)) |     if (SUCCEEDED(hr)) | ||||||
|  | @ -107,6 +110,28 @@ void RendererImpl::MakeContextForWindow(WindowPtr window) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (SUCCEEDED(hr)) | ||||||
|  |     { | ||||||
|  |         IDWriteFactory* dwrite = d2d_res_->GetDWriteFactory(); | ||||||
|  |         if (dwrite) | ||||||
|  |         { | ||||||
|  |             ComPtr<IDWriteFontCollection> system_collection; | ||||||
|  |             if (SUCCEEDED(dwrite->GetSystemFontCollection(&system_collection, FALSE))) | ||||||
|  |             { | ||||||
|  |                 Vector<String> family_names; | ||||||
|  |                 if (SUCCEEDED(d2d_res_->GetFontFamilyNames(family_names, system_collection))) | ||||||
|  |                 { | ||||||
|  |                     // dummy font
 | ||||||
|  |                     FontPtr font = MakePtr<Font>(); | ||||||
|  |                     for (const auto& name : family_names) | ||||||
|  |                     { | ||||||
|  |                         FontCache::GetInstance().AddFontByFamily(name, font); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     KGE_THROW_IF_FAILED(hr, "Create render resources failed"); |     KGE_THROW_IF_FAILED(hr, "Create render resources failed"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -132,6 +157,26 @@ void RendererImpl::Destroy() | ||||||
|     ::CoUninitialize(); |     ::CoUninitialize(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void RendererImpl::HandleEvent(EventModuleContext& ctx) | ||||||
|  | { | ||||||
|  |     Renderer::HandleEvent(ctx); | ||||||
|  | 
 | ||||||
|  |     if (ctx.evt->IsType<WindowMovedEvent>()) | ||||||
|  |     { | ||||||
|  |         auto evt = ctx.evt->SafeCast<WindowMovedEvent>(); | ||||||
|  |         HMONITOR monitor = ::MonitorFromWindow(evt->window->GetHandle(), MONITOR_DEFAULTTONULL); | ||||||
|  |         if (monitor_ != monitor) | ||||||
|  |         { | ||||||
|  |             monitor_ = monitor; | ||||||
|  | 
 | ||||||
|  |             if (d2d_res_) | ||||||
|  |             { | ||||||
|  |                 d2d_res_->ResetTextRenderingParams(monitor); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void RendererImpl::Clear() | void RendererImpl::Clear() | ||||||
| { | { | ||||||
|     KGE_ASSERT(d3d_res_); |     KGE_ASSERT(d3d_res_); | ||||||
|  | @ -479,7 +524,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& g | ||||||
|     KGE_SET_STATUS_IF_FAILED(hr, const_cast<GifImage&>(gif), "Load GIF frame failed"); |     KGE_SET_STATUS_IF_FAILED(hr, const_cast<GifImage&>(gif), "Load GIF frame failed"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RendererImpl::CreateFontCollection(Font& font, const String& file_path) | void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names, const String& file_path) | ||||||
| { | { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
|     if (!d2d_res_) |     if (!d2d_res_) | ||||||
|  | @ -506,12 +551,7 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path) | ||||||
| 
 | 
 | ||||||
|         if (SUCCEEDED(hr)) |         if (SUCCEEDED(hr)) | ||||||
|         { |         { | ||||||
|             Vector<String> family_names; |  | ||||||
|             d2d_res_->GetFontFamilyNames(family_names, font_collection);  // ignore the result
 |             d2d_res_->GetFontFamilyNames(family_names, font_collection);  // ignore the result
 | ||||||
| 
 |  | ||||||
|             if (!family_names.empty()) |  | ||||||
|                 font.SetFamilyName(family_names[0]); |  | ||||||
| 
 |  | ||||||
|             NativePtr::Set(font, font_collection); |             NativePtr::Set(font, font_collection); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -519,7 +559,7 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path) | ||||||
|     KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed"); |     KGE_SET_STATUS_IF_FAILED(hr, font, "Create font collection failed"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RendererImpl::CreateFontCollection(Font& font, const Resource& res) | void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) | ||||||
| { | { | ||||||
|     HRESULT hr = S_OK; |     HRESULT hr = S_OK; | ||||||
|     if (!d2d_res_) |     if (!d2d_res_) | ||||||
|  | @ -534,12 +574,7 @@ void RendererImpl::CreateFontCollection(Font& font, const Resource& res) | ||||||
| 
 | 
 | ||||||
|         if (SUCCEEDED(hr)) |         if (SUCCEEDED(hr)) | ||||||
|         { |         { | ||||||
|             Vector<String> family_names; |  | ||||||
|             d2d_res_->GetFontFamilyNames(family_names, font_collection);  // ignore the result
 |             d2d_res_->GetFontFamilyNames(family_names, font_collection);  // ignore the result
 | ||||||
| 
 |  | ||||||
|             if (!family_names.empty()) |  | ||||||
|                 font.SetFamilyName(family_names[0]); |  | ||||||
| 
 |  | ||||||
|             NativePtr::Set(font, font_collection); |             NativePtr::Set(font, font_collection); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -564,9 +599,9 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c | ||||||
| 
 | 
 | ||||||
|     if (SUCCEEDED(hr)) |     if (SUCCEEDED(hr)) | ||||||
|     { |     { | ||||||
|         DWRITE_FONT_WEIGHT font_weight = DWRITE_FONT_WEIGHT(style.font_weight); |         auto font_weight = DWRITE_FONT_WEIGHT(style.font_weight); | ||||||
|         DWRITE_FONT_STYLE  font_style  = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; |         auto font_style  = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; | ||||||
|         auto               collection  = NativePtr::Get<IDWriteFontCollection>(style.font); |         auto collection  = NativePtr::Get<IDWriteFontCollection>(style.font); | ||||||
| 
 | 
 | ||||||
|         WideString font_family; |         WideString font_family; | ||||||
|         if (style.font) |         if (style.font) | ||||||
|  |  | ||||||
|  | @ -42,9 +42,9 @@ public: | ||||||
| 
 | 
 | ||||||
|     void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) override; |     void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) override; | ||||||
| 
 | 
 | ||||||
|     void CreateFontCollection(Font& font, const String& file_path) override; |     void CreateFontCollection(Font& font, Vector<String>& family_names, const String& file_path) override; | ||||||
| 
 | 
 | ||||||
|     void CreateFontCollection(Font& font, const Resource& res) override; |     void CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) override; | ||||||
| 
 | 
 | ||||||
|     void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) override; |     void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) override; | ||||||
| 
 | 
 | ||||||
|  | @ -81,6 +81,8 @@ public: | ||||||
| 
 | 
 | ||||||
|     void Destroy() override; |     void Destroy() override; | ||||||
| 
 | 
 | ||||||
|  |     void HandleEvent(EventModuleContext& ctx) override; | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
|     RendererImpl(); |     RendererImpl(); | ||||||
| 
 | 
 | ||||||
|  | @ -90,6 +92,8 @@ private: | ||||||
| 
 | 
 | ||||||
|     ComPtr<ID2DDeviceResources> d2d_res_; |     ComPtr<ID2DDeviceResources> d2d_res_; | ||||||
|     ComPtr<ID3DDeviceResources> d3d_res_; |     ComPtr<ID3DDeviceResources> d3d_res_; | ||||||
|  | 
 | ||||||
|  |     HMONITOR monitor_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,34 +20,65 @@ | ||||||
| 
 | 
 | ||||||
| #include <kiwano/render/Font.h> | #include <kiwano/render/Font.h> | ||||||
| #include <kiwano/render/Renderer.h> | #include <kiwano/render/Renderer.h> | ||||||
|  | #include <functional>  // std::hash
 | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| FontPtr Font::Preload(const String& file) | FontPtr Font::Preload(const String& file) | ||||||
| { | { | ||||||
|     FontPtr ptr = MakePtr<Font>(); |     size_t hash_code = std::hash<String>{}(file); | ||||||
|     try |     if (FontPtr ptr = FontCache::GetInstance().GetFont(hash_code)) | ||||||
|     { |     { | ||||||
|         Renderer::GetInstance().CreateFontCollection(*ptr, file); |         return ptr; | ||||||
|     } |     } | ||||||
|     catch (Exception&) | 
 | ||||||
|  |     FontPtr ptr = MakePtr<Font>(); | ||||||
|  |     if (ptr) | ||||||
|     { |     { | ||||||
|         return nullptr; |         Vector<String> family_names; | ||||||
|  |         Renderer::GetInstance().CreateFontCollection(*ptr, family_names, file); | ||||||
|  |         if (ptr->IsValid()) | ||||||
|  |         { | ||||||
|  |             FontCache::GetInstance().AddFont(hash_code, ptr); | ||||||
|  |             if (!family_names.empty()) | ||||||
|  |             { | ||||||
|  |                 ptr->SetFamilyName(family_names[0]); | ||||||
|  |             } | ||||||
|  |             for (const auto& name : family_names) | ||||||
|  |             { | ||||||
|  |                 FontCache::GetInstance().AddFontByFamily(name, ptr); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     return ptr; |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| FontPtr Font::Preload(const Resource& resource) | FontPtr Font::Preload(const Resource& resource) | ||||||
| { | { | ||||||
|     FontPtr ptr = MakePtr<Font>(); |     size_t hash_code = resource.GetId(); | ||||||
|     try |     if (FontPtr ptr = FontCache::GetInstance().GetFont(hash_code)) | ||||||
|     { |     { | ||||||
|         Renderer::GetInstance().CreateFontCollection(*ptr, resource); |         return ptr; | ||||||
|     } |     } | ||||||
|     catch (Exception&) | 
 | ||||||
|  |     FontPtr ptr = MakePtr<Font>(); | ||||||
|  |     if (ptr) | ||||||
|     { |     { | ||||||
|         return nullptr; |         Vector<String> family_names; | ||||||
|  |         Renderer::GetInstance().CreateFontCollection(*ptr, family_names, resource); | ||||||
|  |         if (ptr->IsValid()) | ||||||
|  |         { | ||||||
|  |             FontCache::GetInstance().AddFont(hash_code, ptr); | ||||||
|  |             if (!family_names.empty()) | ||||||
|  |             { | ||||||
|  |                 ptr->SetFamilyName(family_names[0]); | ||||||
|  |             } | ||||||
|  |             for (const auto& name : family_names) | ||||||
|  |             { | ||||||
|  |                 FontCache::GetInstance().AddFontByFamily(name, ptr); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|     return ptr; |     return ptr; | ||||||
| } | } | ||||||
|  | @ -55,8 +86,80 @@ FontPtr Font::Preload(const Resource& resource) | ||||||
| Font::Font() {} | Font::Font() {} | ||||||
| 
 | 
 | ||||||
| Font::Font(const String& family_name) | Font::Font(const String& family_name) | ||||||
|     : family_name_(family_name) |  | ||||||
| { | { | ||||||
|  |     Load(family_name); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool Font::Load(const String& family_name) | ||||||
|  | { | ||||||
|  |     if (family_name.empty()) | ||||||
|  |         return true; | ||||||
|  | 
 | ||||||
|  |     if (FontPtr font = FontCache::GetInstance().GetFontByFamily(family_name)) | ||||||
|  |     { | ||||||
|  |         ResetNativePointer(font->GetNativePointer()); | ||||||
|  |         SetFamilyName(family_name); | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     Fail(strings::Format("Font::Load failed: cannot find family name \"%s\"", family_name.c_str())); | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FontCache::FontCache() {} | ||||||
|  | 
 | ||||||
|  | FontCache::~FontCache() {} | ||||||
|  | 
 | ||||||
|  | void FontCache::AddFont(size_t key, FontPtr font) | ||||||
|  | { | ||||||
|  |     font_cache_.insert(std::make_pair(key, font)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FontCache::AddFontByFamily(const String& font_family, FontPtr font) | ||||||
|  | { | ||||||
|  |     String family = TransformFamily(font_family); | ||||||
|  |     font_family_cache_.insert(std::make_pair(family, font)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FontPtr FontCache::GetFont(size_t key) const | ||||||
|  | { | ||||||
|  |     if (font_cache_.count(key)) | ||||||
|  |     { | ||||||
|  |         return font_cache_.at(key); | ||||||
|  |     } | ||||||
|  |     return FontPtr(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FontPtr FontCache::GetFontByFamily(const String& font_family) const | ||||||
|  | { | ||||||
|  |     String family = TransformFamily(font_family); | ||||||
|  |     if (font_family_cache_.count(family)) | ||||||
|  |     { | ||||||
|  |         return font_family_cache_.at(family); | ||||||
|  |     } | ||||||
|  |     return FontPtr(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FontCache::RemoveFont(size_t key) | ||||||
|  | { | ||||||
|  |     font_cache_.erase(key); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FontCache::RemoveFontByFamily(const String& font_family) | ||||||
|  | { | ||||||
|  |     String family = TransformFamily(font_family); | ||||||
|  |     font_family_cache_.erase(family); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FontCache::Clear() | ||||||
|  | { | ||||||
|  |     font_cache_.clear(); | ||||||
|  |     font_family_cache_.clear(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | String FontCache::TransformFamily(String family) const | ||||||
|  | { | ||||||
|  |     std::transform(family.begin(), family.end(), family.begin(), std::tolower); | ||||||
|  |     return family; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| }  // namespace kiwano
 | }  // namespace kiwano
 | ||||||
|  |  | ||||||
|  | @ -41,26 +41,32 @@ class Font : public NativeObject | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief ΄΄½¨ΧΦΜε
 |     /// @brief 预加载字体
 | ||||||
|     /// @param file 字体文件
 |     /// @param file 字体文件
 | ||||||
|     static FontPtr Preload(const String& file); |     static FontPtr Preload(const String& file); | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief ΄΄½¨ΧΦΜε
 |     /// @brief 预加载字体
 | ||||||
|     /// @param resource 字体资源
 |     /// @param resource 字体资源
 | ||||||
|     static FontPtr Preload(const Resource& resource); |     static FontPtr Preload(const Resource& resource); | ||||||
| 
 | 
 | ||||||
|     Font(); |     Font(); | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief ΄΄½¨ΧΦΜε
 |     /// @brief 通过字体族创建字体
 | ||||||
|     /// @param family_name 字体族
 |     /// @param family_name 字体族
 | ||||||
|     Font(const String& family_name); |     Font(const String& family_name); | ||||||
| 
 | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 加载字体族
 | ||||||
|  |     /// @param family_name 字体族
 | ||||||
|  |     bool Load(const String& family_name); | ||||||
|  | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 获取字体族
 |     /// @brief 获取字体族
 | ||||||
|     String GetFamilyName() const; |     String GetFamilyName() const; | ||||||
| 
 | 
 | ||||||
|  | protected: | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 获取字体族
 |     /// @brief 获取字体族
 | ||||||
|     void SetFamilyName(const String& name); |     void SetFamilyName(const String& name); | ||||||
|  | @ -69,6 +75,58 @@ protected: | ||||||
|     String family_name_; |     String family_name_; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * \~chinese | ||||||
|  |  * @brief 纹理缓存 | ||||||
|  |  */ | ||||||
|  | class KGE_API FontCache final : public Singleton<FontCache> | ||||||
|  | { | ||||||
|  |     friend Singleton<FontCache>; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 添加字体缓存
 | ||||||
|  |     void AddFont(size_t key, FontPtr font); | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 添加字体族映射字体缓存
 | ||||||
|  |     void AddFontByFamily(const String& font_family, FontPtr font); | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 获取字体缓存
 | ||||||
|  |     FontPtr GetFont(size_t key) const; | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 获取字体族映射字体缓存
 | ||||||
|  |     FontPtr GetFontByFamily(const String& font_family) const; | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 移除字体缓存
 | ||||||
|  |     void RemoveFont(size_t key); | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 移除字体族映射字体缓存
 | ||||||
|  |     void RemoveFontByFamily(const String& font_family); | ||||||
|  | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 清空缓存
 | ||||||
|  |     void Clear(); | ||||||
|  | 
 | ||||||
|  |     ~FontCache(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     FontCache(); | ||||||
|  | 
 | ||||||
|  |     String TransformFamily(String family) const; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     using FontMap = UnorderedMap<size_t, FontPtr>; | ||||||
|  |     FontMap font_cache_; | ||||||
|  | 
 | ||||||
|  |     using FontFamilyMap = UnorderedMap<String, FontPtr>; | ||||||
|  |     FontFamilyMap font_family_cache_; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /** @} */ | /** @} */ | ||||||
| 
 | 
 | ||||||
| inline String Font::GetFamilyName() const | inline String Font::GetFamilyName() const | ||||||
|  |  | ||||||
|  | @ -21,20 +21,40 @@ | ||||||
| #include <kiwano/utils/Logger.h> | #include <kiwano/utils/Logger.h> | ||||||
| #include <kiwano/render/GifImage.h> | #include <kiwano/render/GifImage.h> | ||||||
| #include <kiwano/render/Renderer.h> | #include <kiwano/render/Renderer.h> | ||||||
|  | #include <kiwano/render/TextureCache.h> | ||||||
|  | #include <functional>  // std::hash
 | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| GifImagePtr GifImage::Preload(const String& file_path) | GifImagePtr GifImage::Preload(const String& file_path) | ||||||
| { | { | ||||||
|     GifImagePtr image = Renderer::GetInstance().CreateGifImage(file_path); |     size_t hash_code = std::hash<String>{}(file_path); | ||||||
|     return image; |     if (GifImagePtr ptr = TextureCache::GetInstance().GetGifImage(hash_code)) | ||||||
|  |     { | ||||||
|  |         return ptr; | ||||||
|  |     } | ||||||
|  |     GifImagePtr ptr = MakePtr<GifImage>(); | ||||||
|  |     if (ptr && ptr->Load(file_path)) | ||||||
|  |     { | ||||||
|  |         TextureCache::GetInstance().AddGifImage(hash_code, ptr); | ||||||
|  |     } | ||||||
|  |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GifImagePtr GifImage::Preload(const Resource& res) | GifImagePtr GifImage::Preload(const Resource& res) | ||||||
| { | { | ||||||
|     GifImagePtr image = Renderer::GetInstance().CreateGifImage(res); |     size_t hash_code = res.GetId(); | ||||||
|     return image; |     if (GifImagePtr ptr = TextureCache::GetInstance().GetGifImage(hash_code)) | ||||||
|  |     { | ||||||
|  |         return ptr; | ||||||
|  |     } | ||||||
|  |     GifImagePtr ptr = MakePtr<GifImage>(); | ||||||
|  |     if (ptr && ptr->Load(res)) | ||||||
|  |     { | ||||||
|  |         TextureCache::GetInstance().AddGifImage(hash_code, ptr); | ||||||
|  |     } | ||||||
|  |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GifImage::GifImage(const String& file_path) | GifImage::GifImage(const String& file_path) | ||||||
|  |  | ||||||
|  | @ -46,6 +46,8 @@ public: | ||||||
|     /// @brief 预加载GIF图片资源
 |     /// @brief 预加载GIF图片资源
 | ||||||
|     static GifImagePtr Preload(const Resource& res); |     static GifImagePtr Preload(const Resource& res); | ||||||
| 
 | 
 | ||||||
|  |     GifImage(); | ||||||
|  | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建GIF图片
 |     /// @brief 创建GIF图片
 | ||||||
|     GifImage(const String& file_path); |     GifImage(const String& file_path); | ||||||
|  | @ -54,8 +56,6 @@ public: | ||||||
|     /// @brief 创建GIF图片
 |     /// @brief 创建GIF图片
 | ||||||
|     GifImage(const Resource& res); |     GifImage(const Resource& res); | ||||||
| 
 | 
 | ||||||
|     GifImage(); |  | ||||||
| 
 |  | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 加载本地GIF图片
 |     /// @brief 加载本地GIF图片
 | ||||||
|     bool Load(const String& file_path); |     bool Load(const String& file_path); | ||||||
|  |  | ||||||
|  | @ -18,8 +18,8 @@ | ||||||
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | ||||||
| // THE SOFTWARE.
 | // THE SOFTWARE.
 | ||||||
| 
 | 
 | ||||||
| #include <functional>  // std::hash
 |  | ||||||
| #include <kiwano/render/Renderer.h> | #include <kiwano/render/Renderer.h> | ||||||
|  | #include <kiwano/render/TextureCache.h> | ||||||
| #include <kiwano/event/WindowEvent.h> | #include <kiwano/event/WindowEvent.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -47,69 +47,10 @@ void Renderer::ResetResolutionWhenWindowResized(bool enabled) | ||||||
|     auto_reset_resolution_ = enabled; |     auto_reset_resolution_ = enabled; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TexturePtr Renderer::CreateTexture(const String& file_path) |  | ||||||
| { |  | ||||||
|     size_t hash_code = std::hash<String>{}(file_path); |  | ||||||
|     if (TexturePtr ptr = texture_cache_.GetTexture(hash_code)) |  | ||||||
|     { |  | ||||||
|         return ptr; |  | ||||||
|     } |  | ||||||
|     TexturePtr ptr = MakePtr<Texture>(); |  | ||||||
|     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<Texture>(); |  | ||||||
|     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<String>{}(file_path); |  | ||||||
|     if (GifImagePtr ptr = texture_cache_.GetGifImage(hash_code)) |  | ||||||
|     { |  | ||||||
|         return ptr; |  | ||||||
|     } |  | ||||||
|     GifImagePtr ptr = MakePtr<GifImage>(); |  | ||||||
|     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<GifImage>(); |  | ||||||
|     if (ptr && ptr->Load(resource)) |  | ||||||
|     { |  | ||||||
|         texture_cache_.AddGifImage(hash_code, ptr); |  | ||||||
|     } |  | ||||||
|     return ptr; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Renderer::Destroy() | void Renderer::Destroy() | ||||||
| { | { | ||||||
|     texture_cache_.Clear(); |     TextureCache::GetInstance().Clear(); | ||||||
|  |     FontCache::GetInstance().Clear(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Renderer::HandleEvent(EventModuleContext& ctx) | void Renderer::HandleEvent(EventModuleContext& ctx) | ||||||
|  | @ -124,9 +65,4 @@ void Renderer::HandleEvent(EventModuleContext& ctx) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TextureCache& Renderer::GetTextureCache() |  | ||||||
| { |  | ||||||
|     return texture_cache_; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| }  // namespace kiwano
 | }  // namespace kiwano
 | ||||||
|  |  | ||||||
|  | @ -24,7 +24,6 @@ | ||||||
| #include <kiwano/render/GifImage.h> | #include <kiwano/render/GifImage.h> | ||||||
| #include <kiwano/render/TextStyle.h> | #include <kiwano/render/TextStyle.h> | ||||||
| #include <kiwano/render/RenderContext.h> | #include <kiwano/render/RenderContext.h> | ||||||
| #include <kiwano/render/TextureCache.h> |  | ||||||
| #include <kiwano/platform/Window.h> | #include <kiwano/platform/Window.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
|  | @ -80,52 +79,28 @@ public: | ||||||
|     /// @brief 窗口大小变化时自动调整分辨率
 |     /// @brief 窗口大小变化时自动调整分辨率
 | ||||||
|     void ResetResolutionWhenWindowResized(bool enabled); |     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
 |     /// \~chinese
 | ||||||
|     /// @brief 创建纹理内部资源
 |     /// @brief 创建纹理内部资源
 | ||||||
|     /// @param[out] texture 纹理
 |     /// @param[out] texture 纹理
 | ||||||
|     /// @param[in] file_path 图片路径
 |     /// @param[in] file_path 图片路径
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateTexture(Texture& texture, const String& file_path) = 0; |     virtual void CreateTexture(Texture& texture, const String& file_path) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建纹理内部资源
 |     /// @brief 创建纹理内部资源
 | ||||||
|     /// @param[out] texture 纹理
 |     /// @param[out] texture 纹理
 | ||||||
|     /// @param[in] resource 图片资源
 |     /// @param[in] resource 图片资源
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateTexture(Texture& texture, const Resource& resource) = 0; |     virtual void CreateTexture(Texture& texture, const Resource& resource) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建GIF图像内部资源
 |     /// @brief 创建GIF图像内部资源
 | ||||||
|     /// @param[out] gif GIF图像
 |     /// @param[out] gif GIF图像
 | ||||||
|     /// @param[in] file_path 图片路径
 |     /// @param[in] file_path 图片路径
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateGifImage(GifImage& gif, const String& file_path) = 0; |     virtual void CreateGifImage(GifImage& gif, const String& file_path) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建GIF图像内部资源
 |     /// @brief 创建GIF图像内部资源
 | ||||||
|     /// @param[out] gif GIF图像
 |     /// @param[out] gif GIF图像
 | ||||||
|     /// @param[in] resource 图片资源
 |     /// @param[in] resource 图片资源
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateGifImage(GifImage& gif, const Resource& resource) = 0; |     virtual void CreateGifImage(GifImage& gif, const Resource& resource) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -133,29 +108,27 @@ public: | ||||||
|     /// @param[out] frame GIF图像帧
 |     /// @param[out] frame GIF图像帧
 | ||||||
|     /// @param[in] gif GIF图像
 |     /// @param[in] gif GIF图像
 | ||||||
|     /// @param[in] frame_index 帧下标
 |     /// @param[in] frame_index 帧下标
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) = 0; |     virtual void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建字体集内部资源
 |     /// @brief 创建字体集内部资源
 | ||||||
|     /// @param[out] font 字体
 |     /// @param[out] font 字体
 | ||||||
|  |     /// @param[out] family_names 字体包含的字体族
 | ||||||
|     /// @param[in] file_paths 字体文件路径
 |     /// @param[in] file_paths 字体文件路径
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |     virtual void CreateFontCollection(Font& font, Vector<String>& family_names, const String& file_path) = 0; | ||||||
|     virtual void CreateFontCollection(Font& font, const String& file_path) = 0; |  | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建字体集内部资源
 |     /// @brief 创建字体集内部资源
 | ||||||
|     /// @param[out] font 字体
 |     /// @param[out] font 字体
 | ||||||
|  |     /// @param[out] family_names 字体包含的字体族
 | ||||||
|     /// @param[in] res_arr 字体资源
 |     /// @param[in] res_arr 字体资源
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |     virtual void CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) = 0; | ||||||
|     virtual void CreateFontCollection(Font& font, const Resource& res) = 0; |  | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建文字布局内部资源
 |     /// @brief 创建文字布局内部资源
 | ||||||
|     /// @param[out] layout 字体布局
 |     /// @param[out] layout 字体布局
 | ||||||
|     /// @param text 文字内容
 |     /// @param text 文字内容
 | ||||||
|     /// @param style 文本样式
 |     /// @param style 文本样式
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) = 0; |     virtual void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -163,14 +136,12 @@ public: | ||||||
|     /// @param[out] shape 形状
 |     /// @param[out] shape 形状
 | ||||||
|     /// @param[in] begin_pos 线段起点
 |     /// @param[in] begin_pos 线段起点
 | ||||||
|     /// @param[in] end_pos 线段终点
 |     /// @param[in] end_pos 线段终点
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateLineShape(Shape& shape, const Point& begin_pos, const Point& end_pos) = 0; |     virtual void CreateLineShape(Shape& shape, const Point& begin_pos, const Point& end_pos) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建矩形形状内部资源
 |     /// @brief 创建矩形形状内部资源
 | ||||||
|     /// @param[out] shape 形状
 |     /// @param[out] shape 形状
 | ||||||
|     /// @param[in] rect 矩形大小
 |     /// @param[in] rect 矩形大小
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateRectShape(Shape& shape, const Rect& rect) = 0; |     virtual void CreateRectShape(Shape& shape, const Rect& rect) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -178,7 +149,6 @@ public: | ||||||
|     /// @param[out] shape 形状
 |     /// @param[out] shape 形状
 | ||||||
|     /// @param[in] rect 矩形大小
 |     /// @param[in] rect 矩形大小
 | ||||||
|     /// @param[in] radius 圆角半径
 |     /// @param[in] radius 圆角半径
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateRoundedRectShape(Shape& shape, const Rect& rect, const Vec2& radius) = 0; |     virtual void CreateRoundedRectShape(Shape& shape, const Rect& rect, const Vec2& radius) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -186,41 +156,35 @@ public: | ||||||
|     /// @param[out] shape 形状
 |     /// @param[out] shape 形状
 | ||||||
|     /// @param[in] center 椭圆圆心
 |     /// @param[in] center 椭圆圆心
 | ||||||
|     /// @param[in] radius 椭圆半径
 |     /// @param[in] radius 椭圆半径
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateEllipseShape(Shape& shape, const Point& center, const Vec2& radius) = 0; |     virtual void CreateEllipseShape(Shape& shape, const Point& center, const Vec2& radius) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建几何图形生成器内部资源
 |     /// @brief 创建几何图形生成器内部资源
 | ||||||
|     /// @param[out] maker 形状生成器
 |     /// @param[out] maker 形状生成器
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateShapeSink(ShapeMaker& maker) = 0; |     virtual void CreateShapeSink(ShapeMaker& maker) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建纯色画刷内部资源
 |     /// @brief 创建纯色画刷内部资源
 | ||||||
|     /// @param[out] brush 画刷
 |     /// @param[out] brush 画刷
 | ||||||
|     /// @param[in] color 颜色
 |     /// @param[in] color 颜色
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateBrush(Brush& brush, const Color& color) = 0; |     virtual void CreateBrush(Brush& brush, const Color& color) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建线性渐变画刷内部资源
 |     /// @brief 创建线性渐变画刷内部资源
 | ||||||
|     /// @param[out] brush 画刷
 |     /// @param[out] brush 画刷
 | ||||||
|     /// @param[in] style 线性渐变样式
 |     /// @param[in] style 线性渐变样式
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateBrush(Brush& brush, const LinearGradientStyle& style) = 0; |     virtual void CreateBrush(Brush& brush, const LinearGradientStyle& style) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建径向渐变画刷内部资源
 |     /// @brief 创建径向渐变画刷内部资源
 | ||||||
|     /// @param[out] brush 画刷
 |     /// @param[out] brush 画刷
 | ||||||
|     /// @param[in] style 径向渐变样式
 |     /// @param[in] style 径向渐变样式
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateBrush(Brush& brush, const RadialGradientStyle& style) = 0; |     virtual void CreateBrush(Brush& brush, const RadialGradientStyle& style) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 创建纹理画刷内部资源
 |     /// @brief 创建纹理画刷内部资源
 | ||||||
|     /// @param[out] brush 画刷
 |     /// @param[out] brush 画刷
 | ||||||
|     /// @param[in] texture 纹理
 |     /// @param[in] texture 纹理
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateBrush(Brush& brush, TexturePtr texture) = 0; |     virtual void CreateBrush(Brush& brush, TexturePtr texture) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -231,7 +195,6 @@ public: | ||||||
|     /// @param[in] dash_array 虚线长度与间隙数组
 |     /// @param[in] dash_array 虚线长度与间隙数组
 | ||||||
|     /// @param[in] dash_size 虚线数组大小
 |     /// @param[in] dash_size 虚线数组大小
 | ||||||
|     /// @param[in] dash_offset 虚线偏移量
 |     /// @param[in] dash_offset 虚线偏移量
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual void CreateStrokeStyle(StrokeStyle& stroke_style) = 0; |     virtual void CreateStrokeStyle(StrokeStyle& stroke_style) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -239,13 +202,8 @@ public: | ||||||
|     /// @param[in,out] texture 渲染输出的纹理
 |     /// @param[in,out] texture 渲染输出的纹理
 | ||||||
|     /// @param[in] desired_size 期望的输出大小
 |     /// @param[in] desired_size 期望的输出大小
 | ||||||
|     /// @return 纹理渲染上下文
 |     /// @return 纹理渲染上下文
 | ||||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 |  | ||||||
|     virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0; |     virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |  | ||||||
|     /// @brief 创建纹理渲染上下文
 |  | ||||||
|     TextureCache& GetTextureCache(); |  | ||||||
| 
 |  | ||||||
| public: | public: | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 清除绘制内容
 |     /// @brief 清除绘制内容
 | ||||||
|  | @ -258,12 +216,15 @@ public: | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 为窗口创建渲染上下文
 |     /// @brief 为窗口创建渲染上下文
 | ||||||
|  |     /// @throw kiwano::SystemError 创建上下文失败时抛出
 | ||||||
|     virtual void MakeContextForWindow(WindowPtr window) = 0; |     virtual void MakeContextForWindow(WindowPtr window) = 0; | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 销毁渲染器资源
 |     /// @brief 销毁渲染器资源
 | ||||||
|     virtual void Destroy(); |     virtual void Destroy(); | ||||||
| 
 | 
 | ||||||
|  |     /// \~chinese
 | ||||||
|  |     /// @brief 处理事件
 | ||||||
|     void HandleEvent(EventModuleContext& ctx) override; |     void HandleEvent(EventModuleContext& ctx) override; | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  | @ -275,8 +236,6 @@ protected: | ||||||
|     Color            clear_color_; |     Color            clear_color_; | ||||||
|     Size             output_size_; |     Size             output_size_; | ||||||
|     RenderContextPtr render_ctx_; |     RenderContextPtr render_ctx_; | ||||||
| 
 |  | ||||||
|     TextureCache texture_cache_; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /** @} */ | /** @} */ | ||||||
|  |  | ||||||
|  | @ -20,6 +20,8 @@ | ||||||
| 
 | 
 | ||||||
| #include <kiwano/render/Renderer.h> | #include <kiwano/render/Renderer.h> | ||||||
| #include <kiwano/render/Texture.h> | #include <kiwano/render/Texture.h> | ||||||
|  | #include <kiwano/render/TextureCache.h> | ||||||
|  | #include <functional>  // std::hash
 | ||||||
| 
 | 
 | ||||||
| #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX | #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX | ||||||
| #include <kiwano/render/DirectX/NativePtr.h> | #include <kiwano/render/DirectX/NativePtr.h> | ||||||
|  | @ -32,14 +34,32 @@ InterpolationMode Texture::default_interpolation_mode_ = InterpolationMode::Line | ||||||
| 
 | 
 | ||||||
| TexturePtr Texture::Preload(const String& file_path) | TexturePtr Texture::Preload(const String& file_path) | ||||||
| { | { | ||||||
|     TexturePtr image = Renderer::GetInstance().CreateTexture(file_path); |     size_t hash_code = std::hash<String>{}(file_path); | ||||||
|     return image; |     if (TexturePtr ptr = TextureCache::GetInstance().GetTexture(hash_code)) | ||||||
|  |     { | ||||||
|  |         return ptr; | ||||||
|  |     } | ||||||
|  |     TexturePtr ptr = MakePtr<Texture>(); | ||||||
|  |     if (ptr && ptr->Load(file_path)) | ||||||
|  |     { | ||||||
|  |         TextureCache::GetInstance().AddTexture(hash_code, ptr); | ||||||
|  |     } | ||||||
|  |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TexturePtr Texture::Preload(const Resource& res) | TexturePtr Texture::Preload(const Resource& res) | ||||||
| { | { | ||||||
|     TexturePtr image = Renderer::GetInstance().CreateTexture(res); |     size_t hash_code = res.GetId(); | ||||||
|     return image; |     if (TexturePtr ptr = TextureCache::GetInstance().GetTexture(hash_code)) | ||||||
|  |     { | ||||||
|  |         return ptr; | ||||||
|  |     } | ||||||
|  |     TexturePtr ptr = MakePtr<Texture>(); | ||||||
|  |     if (ptr && ptr->Load(res)) | ||||||
|  |     { | ||||||
|  |         TextureCache::GetInstance().AddTexture(hash_code, ptr); | ||||||
|  |     } | ||||||
|  |     return ptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Texture::Texture(const String& file_path) | Texture::Texture(const String& file_path) | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include <kiwano/render/GifImage.h> | #include <kiwano/render/GifImage.h> | ||||||
| #include <kiwano/render/Texture.h> | #include <kiwano/render/Texture.h> | ||||||
|  | #include <kiwano/core/Singleton.h> | ||||||
| 
 | 
 | ||||||
| namespace kiwano | namespace kiwano | ||||||
| { | { | ||||||
|  | @ -33,19 +34,17 @@ namespace kiwano | ||||||
|  * \~chinese |  * \~chinese | ||||||
|  * @brief 纹理缓存 |  * @brief 纹理缓存 | ||||||
|  */ |  */ | ||||||
| class KGE_API TextureCache final : Noncopyable | class KGE_API TextureCache final : public Singleton<TextureCache> | ||||||
| { | { | ||||||
|  |     friend Singleton<TextureCache>; | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
|     TextureCache(); |  | ||||||
| 
 |  | ||||||
|     ~TextureCache(); |  | ||||||
| 
 |  | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 添加或获取纹理
 |     /// @brief 添加纹理缓存
 | ||||||
|     void AddTexture(size_t key, TexturePtr texture); |     void AddTexture(size_t key, TexturePtr texture); | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|     /// @brief 添加或获取GIF图像
 |     /// @brief 添加GIF图像缓存
 | ||||||
|     void AddGifImage(size_t key, GifImagePtr gif); |     void AddGifImage(size_t key, GifImagePtr gif); | ||||||
| 
 | 
 | ||||||
|     /// \~chinese
 |     /// \~chinese
 | ||||||
|  | @ -68,6 +67,11 @@ public: | ||||||
|     /// @brief 清空缓存
 |     /// @brief 清空缓存
 | ||||||
|     void Clear(); |     void Clear(); | ||||||
| 
 | 
 | ||||||
|  |     ~TextureCache(); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     TextureCache(); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     using TextureMap = UnorderedMap<size_t, TexturePtr>; |     using TextureMap = UnorderedMap<size_t, TexturePtr>; | ||||||
|     TextureMap texture_cache_; |     TextureMap texture_cache_; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue