[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 ResetTextRenderingParams(_In_ HMONITOR monitor) override; | ||||
| 
 | ||||
| public: | ||||
|     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, | ||||
|                                                   _In_opt_ ComPtr<IWICBitmapSource> source, | ||||
|                                                   _In_ REFWICPixelFormatGUID format, WICBitmapDitherType dither, | ||||
|  | @ -488,9 +502,9 @@ HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat>& te | |||
|         return E_UNEXPECTED; | ||||
| 
 | ||||
|     ComPtr<IDWriteTextFormat> output; | ||||
| 
 | ||||
|     HRESULT hr = | ||||
|         dwrite_factory_->CreateTextFormat(family, collection.Get(), weight, style, stretch, font_size, L"", &output); | ||||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|         text_format = output; | ||||
|  |  | |||
|  | @ -76,6 +76,8 @@ public: | |||
| 
 | ||||
|     virtual void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) = 0; | ||||
| 
 | ||||
|     virtual void ResetTextRenderingParams(_In_ HMONITOR monitor) = 0; | ||||
| 
 | ||||
|     inline ID2D1Factory1* GetFactory() | ||||
|     { | ||||
|         KGE_ASSERT(factory_); | ||||
|  |  | |||
|  | @ -39,16 +39,16 @@ public: | |||
|     STDMETHOD(AddFilePaths) | ||||
|     (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
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, | ||||
|                                                               uint32_t collectionKeySize, | ||||
|                                                               _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); | ||||
| 
 | ||||
|     // IUnknown methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||
| 
 | ||||
| private: | ||||
|     ULONG refCount_; | ||||
| 
 | ||||
|  | @ -108,35 +108,6 @@ STDMETHODIMP FontCollectionLoader::AddFilePaths(const Vector<String>& filePaths, | |||
|     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( | ||||
|     IDWriteFactory* pFactory, void const* collectionKey, uint32_t collectionKeySize, | ||||
|     _Out_ IDWriteFontFileEnumerator** fontFileEnumerator) | ||||
|  | @ -166,6 +137,35 @@ HRESULT STDMETHODCALLTYPE FontCollectionLoader::CreateEnumeratorFromKey( | |||
|     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
 | ||||
|  | @ -177,25 +177,25 @@ class FontFileEnumerator : public IFontFileEnumerator | |||
| public: | ||||
|     FontFileEnumerator(); | ||||
| 
 | ||||
|     STDMETHOD(Initialize)(IDWriteFactory* pFactory); | ||||
| 
 | ||||
|     STDMETHOD(SetFilePaths)(const Vector<String>& filePaths); | ||||
| 
 | ||||
|     ~FontFileEnumerator() | ||||
|     { | ||||
|         DX::SafeRelease(currentFile_); | ||||
|         DX::SafeRelease(pFactory_); | ||||
|     } | ||||
| 
 | ||||
|     // IUnknown methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _Out_ void** ppvObject); | ||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||
|     STDMETHOD(Initialize)(IDWriteFactory* pFactory); | ||||
| 
 | ||||
|     STDMETHOD(SetFilePaths)(const Vector<String>& filePaths); | ||||
| 
 | ||||
|     // IDWriteFontFileEnumerator methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); | ||||
|     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: | ||||
|     ULONG refCount_; | ||||
| 
 | ||||
|  | @ -268,35 +268,6 @@ STDMETHODIMP FontFileEnumerator::SetFilePaths(const Vector<String>& filePaths) | |||
|     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 hr = S_OK; | ||||
|  | @ -328,6 +299,35 @@ HRESULT STDMETHODCALLTYPE FontFileEnumerator::GetCurrentFontFile(_Out_ IDWriteFo | |||
|     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
 | ||||
|  | @ -346,16 +346,16 @@ public: | |||
|     STDMETHOD(AddResources) | ||||
|     (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
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, | ||||
|                                                               uint32_t collectionKeySize, | ||||
|                                                               _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); | ||||
| 
 | ||||
|     // IUnknown methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||
| 
 | ||||
| private: | ||||
|     ULONG                  refCount_; | ||||
|     IDWriteFontFileLoader* pFileLoader_; | ||||
|  | @ -417,35 +417,6 @@ STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<Resource>& | |||
|     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( | ||||
|     IDWriteFactory* pFactory, void const* collectionKey, uint32_t collectionKeySize, | ||||
|     _Out_ IDWriteFontFileEnumerator** fontFileEnumerator) | ||||
|  | @ -476,6 +447,35 @@ HRESULT STDMETHODCALLTYPE ResourceFontCollectionLoader::CreateEnumeratorFromKey( | |||
|     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
 | ||||
|  | @ -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
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, | ||||
|                                                           uint32_t    fontFileReferenceKeySize, | ||||
|                                                           _Out_ IDWriteFontFileStream** fontFileStream); | ||||
| 
 | ||||
|     // IUnknown methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||
| 
 | ||||
| private: | ||||
|     ULONG refCount_; | ||||
| }; | ||||
|  | @ -526,6 +526,33 @@ HRESULT IResourceFontFileLoader::Create(_Out_ IResourceFontFileLoader** ppFileLo | |||
|     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) | ||||
| { | ||||
|     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) | ||||
|  | @ -555,33 +582,6 @@ ULONG STDMETHODCALLTYPE ResourceFontFileLoader::Release() | |||
|     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
 | ||||
|  | @ -593,25 +593,25 @@ class ResourceFontFileEnumerator : public IResourceFontFileEnumerator | |||
| public: | ||||
|     ResourceFontFileEnumerator(); | ||||
| 
 | ||||
|     STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader); | ||||
| 
 | ||||
|     STDMETHOD(SetResources)(const Vector<Resource>& resources); | ||||
| 
 | ||||
|     ~ResourceFontFileEnumerator() | ||||
|     { | ||||
|         DX::SafeRelease(currentFile_); | ||||
|         DX::SafeRelease(pFactory_); | ||||
|     } | ||||
| 
 | ||||
|     // IUnknown methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, _Out_ void** ppvObject); | ||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||
|     STDMETHOD(Initialize)(IDWriteFactory* pFactory, IDWriteFontFileLoader* pLoader); | ||||
| 
 | ||||
|     STDMETHOD(SetResources)(const Vector<Resource>& resources); | ||||
| 
 | ||||
|     // IDWriteFontFileEnumerator methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE MoveNext(_Out_ BOOL* hasCurrentFile); | ||||
|     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: | ||||
|     ULONG refCount_; | ||||
| 
 | ||||
|  | @ -688,35 +688,6 @@ STDMETHODIMP ResourceFontFileEnumerator::SetResources(const Vector<Resource>& re | |||
|     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 hr = S_OK; | ||||
|  | @ -747,6 +718,35 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileEnumerator::GetCurrentFontFile(_Out_ I | |||
|     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
 | ||||
|  | @ -760,11 +760,6 @@ public: | |||
| 
 | ||||
|     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
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, | ||||
|                                                        UINT64 fragmentSize, _Out_ void** fragmentContext); | ||||
|  | @ -775,10 +770,10 @@ public: | |||
| 
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(_Out_ UINT64* lastWriteTime); | ||||
| 
 | ||||
|     bool IsInitialized() | ||||
|     { | ||||
|         return resourcePtr_ != NULL; | ||||
|     } | ||||
|     // IUnknown methods
 | ||||
|     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject); | ||||
|     virtual ULONG STDMETHODCALLTYPE   AddRef(); | ||||
|     virtual ULONG STDMETHODCALLTYPE   Release(); | ||||
| 
 | ||||
| private: | ||||
|     ULONG  refCount_; | ||||
|  | @ -834,36 +829,6 @@ STDMETHODIMP ResourceFontFileStream::Initialize(const Resource resource) | |||
|     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, | ||||
|                                                                    UINT64 fragmentSize, _Out_ void** fragmentContext) | ||||
| { | ||||
|  | @ -896,4 +861,34 @@ HRESULT STDMETHODCALLTYPE ResourceFontFileStream::GetLastWriteTime(_Out_ UINT64* | |||
|     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
 | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <kiwano/utils/Logger.h> | ||||
| #include <kiwano/event/Events.h> | ||||
| #include <kiwano/platform/FileSystem.h> | ||||
| #include <kiwano/platform/Application.h> | ||||
| #include <kiwano/render/ShapeMaker.h> | ||||
|  | @ -48,6 +49,7 @@ RendererImpl& RendererImpl::GetInstance() | |||
| } | ||||
| 
 | ||||
| RendererImpl::RendererImpl() | ||||
|     : monitor_(nullptr) | ||||
| { | ||||
| } | ||||
| 
 | ||||
|  | @ -62,6 +64,7 @@ void RendererImpl::MakeContextForWindow(WindowPtr window) | |||
|     HRESULT    hr            = target_window ? S_OK : E_FAIL; | ||||
| 
 | ||||
|     output_size_ = Size{ float(resolution.width), float(resolution.height) }; | ||||
|     monitor_     = ::MonitorFromWindow(target_window, MONITOR_DEFAULTTONULL); | ||||
| 
 | ||||
|     // Initialize Direct3D resources
 | ||||
|     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"); | ||||
| } | ||||
| 
 | ||||
|  | @ -132,6 +157,26 @@ void RendererImpl::Destroy() | |||
|     ::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() | ||||
| { | ||||
|     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"); | ||||
| } | ||||
| 
 | ||||
| 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; | ||||
|     if (!d2d_res_) | ||||
|  | @ -506,12 +551,7 @@ void RendererImpl::CreateFontCollection(Font& font, const String& file_path) | |||
| 
 | ||||
|         if (SUCCEEDED(hr)) | ||||
|         { | ||||
|             Vector<String> family_names; | ||||
|             d2d_res_->GetFontFamilyNames(family_names, font_collection);  // ignore the result
 | ||||
| 
 | ||||
|             if (!family_names.empty()) | ||||
|                 font.SetFamilyName(family_names[0]); | ||||
| 
 | ||||
|             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"); | ||||
| } | ||||
| 
 | ||||
| void RendererImpl::CreateFontCollection(Font& font, const Resource& res) | ||||
| void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) | ||||
| { | ||||
|     HRESULT hr = S_OK; | ||||
|     if (!d2d_res_) | ||||
|  | @ -534,12 +574,7 @@ void RendererImpl::CreateFontCollection(Font& font, const Resource& res) | |||
| 
 | ||||
|         if (SUCCEEDED(hr)) | ||||
|         { | ||||
|             Vector<String> family_names; | ||||
|             d2d_res_->GetFontFamilyNames(family_names, font_collection);  // ignore the result
 | ||||
| 
 | ||||
|             if (!family_names.empty()) | ||||
|                 font.SetFamilyName(family_names[0]); | ||||
| 
 | ||||
|             NativePtr::Set(font, font_collection); | ||||
|         } | ||||
|     } | ||||
|  | @ -564,8 +599,8 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c | |||
| 
 | ||||
|     if (SUCCEEDED(hr)) | ||||
|     { | ||||
|         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 font_weight = DWRITE_FONT_WEIGHT(style.font_weight); | ||||
|         auto font_style  = style.italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL; | ||||
|         auto collection  = NativePtr::Get<IDWriteFontCollection>(style.font); | ||||
| 
 | ||||
|         WideString font_family; | ||||
|  |  | |||
|  | @ -42,9 +42,9 @@ public: | |||
| 
 | ||||
|     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; | ||||
| 
 | ||||
|  | @ -81,6 +81,8 @@ public: | |||
| 
 | ||||
|     void Destroy() override; | ||||
| 
 | ||||
|     void HandleEvent(EventModuleContext& ctx) override; | ||||
| 
 | ||||
| protected: | ||||
|     RendererImpl(); | ||||
| 
 | ||||
|  | @ -90,6 +92,8 @@ private: | |||
| 
 | ||||
|     ComPtr<ID2DDeviceResources> d2d_res_; | ||||
|     ComPtr<ID3DDeviceResources> d3d_res_; | ||||
| 
 | ||||
|     HMONITOR monitor_; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,34 +20,65 @@ | |||
| 
 | ||||
| #include <kiwano/render/Font.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <functional>  // std::hash
 | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 
 | ||||
| FontPtr Font::Preload(const String& file) | ||||
| { | ||||
|     FontPtr ptr = MakePtr<Font>(); | ||||
|     try | ||||
|     size_t hash_code = std::hash<String>{}(file); | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
| FontPtr Font::Preload(const Resource& resource) | ||||
| { | ||||
|     FontPtr ptr = MakePtr<Font>(); | ||||
|     try | ||||
|     size_t hash_code = resource.GetId(); | ||||
|     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; | ||||
| } | ||||
|  | @ -55,8 +86,80 @@ FontPtr Font::Preload(const Resource& resource) | |||
| Font::Font() {} | ||||
| 
 | ||||
| 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
 | ||||
|  |  | |||
|  | @ -41,26 +41,32 @@ class Font : public NativeObject | |||
| { | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief ΄΄½¨ΧΦΜε
 | ||||
|     /// @brief 预加载字体
 | ||||
|     /// @param file 字体文件
 | ||||
|     static FontPtr Preload(const String& file); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief ΄΄½¨ΧΦΜε
 | ||||
|     /// @brief 预加载字体
 | ||||
|     /// @param resource 字体资源
 | ||||
|     static FontPtr Preload(const Resource& resource); | ||||
| 
 | ||||
|     Font(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief ΄΄½¨ΧΦΜε
 | ||||
|     /// @brief 通过字体族创建字体
 | ||||
|     /// @param family_name 字体族
 | ||||
|     Font(const String& family_name); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 加载字体族
 | ||||
|     /// @param family_name 字体族
 | ||||
|     bool Load(const String& family_name); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取字体族
 | ||||
|     String GetFamilyName() const; | ||||
| 
 | ||||
| protected: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 获取字体族
 | ||||
|     void SetFamilyName(const String& name); | ||||
|  | @ -69,6 +75,58 @@ protected: | |||
|     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 | ||||
|  |  | |||
|  | @ -21,20 +21,40 @@ | |||
| #include <kiwano/utils/Logger.h> | ||||
| #include <kiwano/render/GifImage.h> | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <kiwano/render/TextureCache.h> | ||||
| #include <functional>  // std::hash
 | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
| 
 | ||||
| GifImagePtr GifImage::Preload(const String& file_path) | ||||
| { | ||||
|     GifImagePtr image = Renderer::GetInstance().CreateGifImage(file_path); | ||||
|     return image; | ||||
|     size_t hash_code = std::hash<String>{}(file_path); | ||||
|     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 image = Renderer::GetInstance().CreateGifImage(res); | ||||
|     return image; | ||||
|     size_t hash_code = res.GetId(); | ||||
|     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) | ||||
|  |  | |||
|  | @ -46,6 +46,8 @@ public: | |||
|     /// @brief 预加载GIF图片资源
 | ||||
|     static GifImagePtr Preload(const Resource& res); | ||||
| 
 | ||||
|     GifImage(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建GIF图片
 | ||||
|     GifImage(const String& file_path); | ||||
|  | @ -54,8 +56,6 @@ public: | |||
|     /// @brief 创建GIF图片
 | ||||
|     GifImage(const Resource& res); | ||||
| 
 | ||||
|     GifImage(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 加载本地GIF图片
 | ||||
|     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
 | ||||
| // THE SOFTWARE.
 | ||||
| 
 | ||||
| #include <functional>  // std::hash
 | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <kiwano/render/TextureCache.h> | ||||
| #include <kiwano/event/WindowEvent.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
|  | @ -47,69 +47,10 @@ void Renderer::ResetResolutionWhenWindowResized(bool 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() | ||||
| { | ||||
|     texture_cache_.Clear(); | ||||
|     TextureCache::GetInstance().Clear(); | ||||
|     FontCache::GetInstance().Clear(); | ||||
| } | ||||
| 
 | ||||
| void Renderer::HandleEvent(EventModuleContext& ctx) | ||||
|  | @ -124,9 +65,4 @@ void Renderer::HandleEvent(EventModuleContext& ctx) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| TextureCache& Renderer::GetTextureCache() | ||||
| { | ||||
|     return texture_cache_; | ||||
| } | ||||
| 
 | ||||
| }  // namespace kiwano
 | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ | |||
| #include <kiwano/render/GifImage.h> | ||||
| #include <kiwano/render/TextStyle.h> | ||||
| #include <kiwano/render/RenderContext.h> | ||||
| #include <kiwano/render/TextureCache.h> | ||||
| #include <kiwano/platform/Window.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
|  | @ -80,52 +79,28 @@ 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 纹理
 | ||||
|     /// @param[in] file_path 图片路径
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateTexture(Texture& texture, const String& file_path) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建纹理内部资源
 | ||||
|     /// @param[out] texture 纹理
 | ||||
|     /// @param[in] resource 图片资源
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateTexture(Texture& texture, const Resource& resource) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建GIF图像内部资源
 | ||||
|     /// @param[out] gif GIF图像
 | ||||
|     /// @param[in] file_path 图片路径
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateGifImage(GifImage& gif, const String& file_path) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建GIF图像内部资源
 | ||||
|     /// @param[out] gif GIF图像
 | ||||
|     /// @param[in] resource 图片资源
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateGifImage(GifImage& gif, const Resource& resource) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -133,29 +108,27 @@ public: | |||
|     /// @param[out] frame GIF图像帧
 | ||||
|     /// @param[in] gif GIF图像
 | ||||
|     /// @param[in] frame_index 帧下标
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateGifImageFrame(GifImage::Frame& frame, const GifImage& gif, size_t frame_index) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建字体集内部资源
 | ||||
|     /// @param[out] font 字体
 | ||||
|     /// @param[out] family_names 字体包含的字体族
 | ||||
|     /// @param[in] file_paths 字体文件路径
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateFontCollection(Font& font, const String& file_path) = 0; | ||||
|     virtual void CreateFontCollection(Font& font, Vector<String>& family_names, const String& file_path) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建字体集内部资源
 | ||||
|     /// @param[out] font 字体
 | ||||
|     /// @param[out] family_names 字体包含的字体族
 | ||||
|     /// @param[in] res_arr 字体资源
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateFontCollection(Font& font, const Resource& res) = 0; | ||||
|     virtual void CreateFontCollection(Font& font, Vector<String>& family_names, const Resource& res) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建文字布局内部资源
 | ||||
|     /// @param[out] layout 字体布局
 | ||||
|     /// @param text 文字内容
 | ||||
|     /// @param style 文本样式
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateTextLayout(TextLayout& layout, const String& content, const TextStyle& style) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -163,14 +136,12 @@ public: | |||
|     /// @param[out] shape 形状
 | ||||
|     /// @param[in] begin_pos 线段起点
 | ||||
|     /// @param[in] end_pos 线段终点
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateLineShape(Shape& shape, const Point& begin_pos, const Point& end_pos) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建矩形形状内部资源
 | ||||
|     /// @param[out] shape 形状
 | ||||
|     /// @param[in] rect 矩形大小
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateRectShape(Shape& shape, const Rect& rect) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -178,7 +149,6 @@ public: | |||
|     /// @param[out] shape 形状
 | ||||
|     /// @param[in] rect 矩形大小
 | ||||
|     /// @param[in] radius 圆角半径
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateRoundedRectShape(Shape& shape, const Rect& rect, const Vec2& radius) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -186,41 +156,35 @@ public: | |||
|     /// @param[out] shape 形状
 | ||||
|     /// @param[in] center 椭圆圆心
 | ||||
|     /// @param[in] radius 椭圆半径
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateEllipseShape(Shape& shape, const Point& center, const Vec2& radius) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建几何图形生成器内部资源
 | ||||
|     /// @param[out] maker 形状生成器
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateShapeSink(ShapeMaker& maker) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建纯色画刷内部资源
 | ||||
|     /// @param[out] brush 画刷
 | ||||
|     /// @param[in] color 颜色
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateBrush(Brush& brush, const Color& color) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建线性渐变画刷内部资源
 | ||||
|     /// @param[out] brush 画刷
 | ||||
|     /// @param[in] style 线性渐变样式
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateBrush(Brush& brush, const LinearGradientStyle& style) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建径向渐变画刷内部资源
 | ||||
|     /// @param[out] brush 画刷
 | ||||
|     /// @param[in] style 径向渐变样式
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateBrush(Brush& brush, const RadialGradientStyle& style) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建纹理画刷内部资源
 | ||||
|     /// @param[out] brush 画刷
 | ||||
|     /// @param[in] texture 纹理
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateBrush(Brush& brush, TexturePtr texture) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -231,7 +195,6 @@ public: | |||
|     /// @param[in] dash_array 虚线长度与间隙数组
 | ||||
|     /// @param[in] dash_size 虚线数组大小
 | ||||
|     /// @param[in] dash_offset 虚线偏移量
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual void CreateStrokeStyle(StrokeStyle& stroke_style) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -239,13 +202,8 @@ public: | |||
|     /// @param[in,out] texture 渲染输出的纹理
 | ||||
|     /// @param[in] desired_size 期望的输出大小
 | ||||
|     /// @return 纹理渲染上下文
 | ||||
|     /// @throw kiwano::SystemError 创建失败时抛出
 | ||||
|     virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 创建纹理渲染上下文
 | ||||
|     TextureCache& GetTextureCache(); | ||||
| 
 | ||||
| public: | ||||
|     /// \~chinese
 | ||||
|     /// @brief 清除绘制内容
 | ||||
|  | @ -258,12 +216,15 @@ public: | |||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 为窗口创建渲染上下文
 | ||||
|     /// @throw kiwano::SystemError 创建上下文失败时抛出
 | ||||
|     virtual void MakeContextForWindow(WindowPtr window) = 0; | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 销毁渲染器资源
 | ||||
|     virtual void Destroy(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 处理事件
 | ||||
|     void HandleEvent(EventModuleContext& ctx) override; | ||||
| 
 | ||||
| protected: | ||||
|  | @ -275,8 +236,6 @@ protected: | |||
|     Color            clear_color_; | ||||
|     Size             output_size_; | ||||
|     RenderContextPtr render_ctx_; | ||||
| 
 | ||||
|     TextureCache texture_cache_; | ||||
| }; | ||||
| 
 | ||||
| /** @} */ | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ | |||
| 
 | ||||
| #include <kiwano/render/Renderer.h> | ||||
| #include <kiwano/render/Texture.h> | ||||
| #include <kiwano/render/TextureCache.h> | ||||
| #include <functional>  // std::hash
 | ||||
| 
 | ||||
| #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX | ||||
| #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 image = Renderer::GetInstance().CreateTexture(file_path); | ||||
|     return image; | ||||
|     size_t hash_code = std::hash<String>{}(file_path); | ||||
|     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 image = Renderer::GetInstance().CreateTexture(res); | ||||
|     return image; | ||||
|     size_t hash_code = res.GetId(); | ||||
|     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) | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ | |||
| #pragma once | ||||
| #include <kiwano/render/GifImage.h> | ||||
| #include <kiwano/render/Texture.h> | ||||
| #include <kiwano/core/Singleton.h> | ||||
| 
 | ||||
| namespace kiwano | ||||
| { | ||||
|  | @ -33,19 +34,17 @@ namespace kiwano | |||
|  * \~chinese | ||||
|  * @brief 纹理缓存 | ||||
|  */ | ||||
| class KGE_API TextureCache final : Noncopyable | ||||
| class KGE_API TextureCache final : public Singleton<TextureCache> | ||||
| { | ||||
|     friend Singleton<TextureCache>; | ||||
| 
 | ||||
| public: | ||||
|     TextureCache(); | ||||
| 
 | ||||
|     ~TextureCache(); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 添加或获取纹理
 | ||||
|     /// @brief 添加纹理缓存
 | ||||
|     void AddTexture(size_t key, TexturePtr texture); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|     /// @brief 添加或获取GIF图像
 | ||||
|     /// @brief 添加GIF图像缓存
 | ||||
|     void AddGifImage(size_t key, GifImagePtr gif); | ||||
| 
 | ||||
|     /// \~chinese
 | ||||
|  | @ -68,6 +67,11 @@ public: | |||
|     /// @brief 清空缓存
 | ||||
|     void Clear(); | ||||
| 
 | ||||
|     ~TextureCache(); | ||||
| 
 | ||||
| private: | ||||
|     TextureCache(); | ||||
| 
 | ||||
| private: | ||||
|     using TextureMap = UnorderedMap<size_t, TexturePtr>; | ||||
|     TextureMap texture_cache_; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue