OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fxge/fx_ge.h" | 7 #include "../../../include/fxge/fx_ge.h" |
8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ | 8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ |
9 #include "../../../include/fxge/fx_ge_win32.h" | 9 #include "../../../include/fxge/fx_ge_win32.h" |
10 #include "dwrite_int.h" | 10 #include "dwrite_int.h" |
11 #include <dwrite.h> | 11 #include <dwrite.h> |
12 typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_T
YPE, __in REFIID, __out IUnknown **); | 12 typedef HRESULT(__stdcall* FuncType_DWriteCreateFactory)( |
| 13 __in DWRITE_FACTORY_TYPE, |
| 14 __in REFIID, |
| 15 __out IUnknown**); |
13 template <typename InterfaceType> | 16 template <typename InterfaceType> |
14 inline void SafeRelease(InterfaceType** currentObject) | 17 inline void SafeRelease(InterfaceType** currentObject) { |
15 { | 18 if (*currentObject != NULL) { |
16 if (*currentObject != NULL) { | 19 (*currentObject)->Release(); |
17 (*currentObject)->Release(); | 20 *currentObject = NULL; |
18 *currentObject = NULL; | 21 } |
| 22 } |
| 23 template <typename InterfaceType> |
| 24 inline InterfaceType* SafeAcquire(InterfaceType* newObject) { |
| 25 if (newObject != NULL) { |
| 26 newObject->AddRef(); |
| 27 } |
| 28 return newObject; |
| 29 } |
| 30 class CDwFontFileStream final : public IDWriteFontFileStream { |
| 31 public: |
| 32 explicit CDwFontFileStream(void const* fontFileReferenceKey, |
| 33 UINT32 fontFileReferenceKeySize); |
| 34 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, |
| 35 void** ppvObject); |
| 36 virtual ULONG STDMETHODCALLTYPE AddRef(); |
| 37 virtual ULONG STDMETHODCALLTYPE Release(); |
| 38 virtual HRESULT STDMETHODCALLTYPE |
| 39 ReadFileFragment(void const** fragmentStart, |
| 40 UINT64 fileOffset, |
| 41 UINT64 fragmentSize, |
| 42 OUT void** fragmentContext); |
| 43 virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext); |
| 44 virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); |
| 45 virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime); |
| 46 bool IsInitialized() { return resourcePtr_ != NULL; } |
| 47 |
| 48 private: |
| 49 ULONG refCount_; |
| 50 void const* resourcePtr_; |
| 51 DWORD resourceSize_; |
| 52 }; |
| 53 class CDwFontFileLoader final : public IDWriteFontFileLoader { |
| 54 public: |
| 55 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, |
| 56 void** ppvObject); |
| 57 virtual ULONG STDMETHODCALLTYPE AddRef(); |
| 58 virtual ULONG STDMETHODCALLTYPE Release(); |
| 59 virtual HRESULT STDMETHODCALLTYPE |
| 60 CreateStreamFromKey(void const* fontFileReferenceKey, |
| 61 UINT32 fontFileReferenceKeySize, |
| 62 OUT IDWriteFontFileStream** fontFileStream); |
| 63 |
| 64 static IDWriteFontFileLoader* GetLoader() { |
| 65 if (instance_ == NULL) { |
| 66 instance_ = new CDwFontFileLoader(); |
19 } | 67 } |
20 } | 68 return instance_; |
21 template <typename InterfaceType> | 69 } |
22 inline InterfaceType* SafeAcquire(InterfaceType* newObject) | 70 static bool IsLoaderInitialized() { return instance_ != NULL; } |
23 { | 71 |
24 if (newObject != NULL) { | 72 private: |
25 newObject->AddRef(); | 73 CDwFontFileLoader(); |
26 } | 74 ULONG refCount_; |
27 return newObject; | 75 static IDWriteFontFileLoader* instance_; |
28 } | |
29 class CDwFontFileStream final : public IDWriteFontFileStream | |
30 { | |
31 public: | |
32 explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFile
ReferenceKeySize); | |
33 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); | |
34 virtual ULONG STDMETHODCALLTYPE AddRef(); | |
35 virtual ULONG STDMETHODCALLTYPE Release(); | |
36 virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStar
t, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext); | |
37 virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext)
; | |
38 virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize); | |
39 virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime
); | |
40 bool IsInitialized() | |
41 { | |
42 return resourcePtr_ != NULL; | |
43 } | |
44 private: | |
45 ULONG refCount_; | |
46 void const* resourcePtr_; | |
47 DWORD resourceSize_; | |
48 }; | 76 }; |
49 class CDwFontFileLoader final : public IDWriteFontFileLoader | 77 class CDwFontContext { |
50 { | 78 public: |
51 public: | 79 CDwFontContext(IDWriteFactory* dwriteFactory); |
52 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec
t); | 80 ~CDwFontContext(); |
53 virtual ULONG STDMETHODCALLTYPE AddRef(); | 81 HRESULT Initialize(); |
54 virtual ULONG STDMETHODCALLTYPE Release(); | 82 |
55 virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileRe
ferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFil
eStream); | 83 private: |
56 | 84 CDwFontContext(CDwFontContext const&); |
57 static IDWriteFontFileLoader* GetLoader() | 85 void operator=(CDwFontContext const&); |
58 { | 86 HRESULT hr_; |
59 if (instance_ == NULL) { | 87 IDWriteFactory* dwriteFactory_; |
60 instance_ = new CDwFontFileLoader(); | |
61 } | |
62 return instance_; | |
63 } | |
64 static bool IsLoaderInitialized() | |
65 { | |
66 return instance_ != NULL; | |
67 } | |
68 private: | |
69 CDwFontFileLoader(); | |
70 ULONG refCount_; | |
71 static IDWriteFontFileLoader* instance_; | |
72 }; | 88 }; |
73 class CDwFontContext | 89 class CDwGdiTextRenderer { |
74 { | 90 public: |
75 public: | 91 CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, |
76 CDwFontContext(IDWriteFactory* dwriteFactory); | 92 IDWriteBitmapRenderTarget* bitmapRenderTarget, |
77 ~CDwFontContext(); | 93 IDWriteRenderingParams* renderingParams); |
78 HRESULT Initialize(); | 94 ~CDwGdiTextRenderer(); |
79 private: | 95 HRESULT STDMETHODCALLTYPE DrawGlyphRun(const FX_RECT& text_bbox, |
80 CDwFontContext(CDwFontContext const&); | 96 __in_opt CFX_ClipRgn* pClipRgn, |
81 void operator=(CDwFontContext const&); | 97 __in_opt DWRITE_MATRIX const* pMatrix, |
82 HRESULT hr_; | 98 FLOAT baselineOriginX, |
83 IDWriteFactory* dwriteFactory_; | 99 FLOAT baselineOriginY, |
| 100 DWRITE_MEASURING_MODE measuringMode, |
| 101 __in DWRITE_GLYPH_RUN const* glyphRun, |
| 102 const COLORREF& textColor); |
| 103 |
| 104 private: |
| 105 CFX_DIBitmap* pBitmap_; |
| 106 IDWriteBitmapRenderTarget* pRenderTarget_; |
| 107 IDWriteRenderingParams* pRenderingParams_; |
84 }; | 108 }; |
85 class CDwGdiTextRenderer | 109 CDWriteExt::CDWriteExt() { |
86 { | 110 m_hModule = NULL; |
87 public: | 111 m_pDWriteFactory = NULL; |
88 CDwGdiTextRenderer( | 112 m_pDwFontContext = NULL; |
89 CFX_DIBitmap* pBitmap, | 113 m_pDwTextRenderer = NULL; |
90 IDWriteBitmapRenderTarget* bitmapRenderTarget, | 114 } |
91 IDWriteRenderingParams* renderingParams | 115 void CDWriteExt::Load() {} |
92 ); | 116 void CDWriteExt::Unload() { |
93 ~CDwGdiTextRenderer(); | 117 if (m_pDwFontContext) { |
94 HRESULT STDMETHODCALLTYPE DrawGlyphRun( | 118 delete (CDwFontContext*)m_pDwFontContext; |
95 const FX_RECT& text_bbox, | |
96 __in_opt CFX_ClipRgn* pClipRgn, | |
97 __in_opt DWRITE_MATRIX const* pMatrix, | |
98 FLOAT baselineOriginX, | |
99 FLOAT baselineOriginY, | |
100 DWRITE_MEASURING_MODE measuringMode, | |
101 __in DWRITE_GLYPH_RUN const* glyphRun, | |
102 const COLORREF& textColor | |
103 ); | |
104 private: | |
105 CFX_DIBitmap* pBitmap_; | |
106 IDWriteBitmapRenderTarget* pRenderTarget_; | |
107 IDWriteRenderingParams* pRenderingParams_; | |
108 }; | |
109 CDWriteExt::CDWriteExt() | |
110 { | |
111 m_hModule = NULL; | |
112 m_pDWriteFactory = NULL; | |
113 m_pDwFontContext = NULL; | 119 m_pDwFontContext = NULL; |
114 m_pDwTextRenderer = NULL; | 120 } |
115 } | 121 SafeRelease((IDWriteFactory**)&m_pDWriteFactory); |
116 void CDWriteExt::Load() | 122 } |
117 { | 123 CDWriteExt::~CDWriteExt() { |
118 } | 124 Unload(); |
119 void CDWriteExt::Unload() | 125 } |
120 { | 126 LPVOID CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, |
121 if (m_pDwFontContext) { | 127 FX_DWORD size, |
122 delete (CDwFontContext*)m_pDwFontContext; | 128 int simulation_style) { |
123 m_pDwFontContext = NULL; | 129 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; |
124 } | 130 IDWriteFontFile* pDwFontFile = NULL; |
125 SafeRelease((IDWriteFactory**)&m_pDWriteFactory); | 131 IDWriteFontFace* pDwFontFace = NULL; |
126 } | 132 BOOL isSupportedFontType = FALSE; |
127 CDWriteExt::~CDWriteExt() | 133 DWRITE_FONT_FILE_TYPE fontFileType; |
128 { | 134 DWRITE_FONT_FACE_TYPE fontFaceType; |
129 Unload(); | 135 UINT32 numberOfFaces; |
130 } | 136 DWRITE_FONT_SIMULATIONS fontStyle = |
131 LPVOID» CDWriteExt::DwCreateFontFaceFromStream(uint8_t* pData, FX_DWORD size, in
t simulation_style) | 137 (DWRITE_FONT_SIMULATIONS)(simulation_style & 3); |
132 { | 138 HRESULT hr = S_OK; |
133 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; | 139 hr = pDwFactory->CreateCustomFontFileReference( |
134 IDWriteFontFile* pDwFontFile = NULL; | 140 (void const*)pData, (UINT32)size, CDwFontFileLoader::GetLoader(), |
135 IDWriteFontFace* pDwFontFace = NULL; | 141 &pDwFontFile); |
136 BOOL isSupportedFontType = FALSE; | 142 if (FAILED(hr)) { |
137 DWRITE_FONT_FILE_TYPE fontFileType; | 143 goto failed; |
138 DWRITE_FONT_FACE_TYPE fontFaceType; | 144 } |
139 UINT32 numberOfFaces; | 145 hr = pDwFontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, |
140 DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_sty
le & 3); | 146 &numberOfFaces); |
141 HRESULT hr = S_OK; | 147 if (FAILED(hr) || !isSupportedFontType || |
142 hr = pDwFactory->CreateCustomFontFileReference( | 148 fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) { |
143 (void const*)pData, | 149 goto failed; |
144 (UINT32)size, | 150 } |
145 CDwFontFileLoader::GetLoader(), | 151 hr = pDwFactory->CreateFontFace(fontFaceType, 1, &pDwFontFile, 0, fontStyle, |
146 &pDwFontFile | 152 &pDwFontFace); |
147 ); | 153 if (FAILED(hr)) { |
148 if (FAILED(hr)) { | 154 goto failed; |
149 goto failed; | 155 } |
150 } | 156 SafeRelease(&pDwFontFile); |
151 hr = pDwFontFile->Analyze( | 157 return pDwFontFace; |
152 &isSupportedFontType, | |
153 &fontFileType, | |
154 &fontFaceType, | |
155 &numberOfFaces | |
156 ); | |
157 if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_T
YPE_UNKNOWN) { | |
158 goto failed; | |
159 } | |
160 hr = pDwFactory->CreateFontFace( | |
161 fontFaceType, | |
162 1, | |
163 &pDwFontFile, | |
164 0, | |
165 fontStyle, | |
166 &pDwFontFace | |
167 ); | |
168 if (FAILED(hr)) { | |
169 goto failed; | |
170 } | |
171 SafeRelease(&pDwFontFile); | |
172 return pDwFontFace; | |
173 failed: | 158 failed: |
174 SafeRelease(&pDwFontFile); | 159 SafeRelease(&pDwFontFile); |
175 return NULL; | 160 return NULL; |
176 } | 161 } |
177 FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** render
Target) | 162 FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, |
178 { | 163 void** renderTarget) { |
179 if (pBitmap->GetFormat() > FXDIB_Argb) { | 164 if (pBitmap->GetFormat() > FXDIB_Argb) { |
180 return FALSE; | 165 return FALSE; |
181 } | 166 } |
182 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; | 167 IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory; |
183 IDWriteGdiInterop* pGdiInterop = NULL; | 168 IDWriteGdiInterop* pGdiInterop = NULL; |
184 IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; | 169 IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL; |
185 IDWriteRenderingParams* pRenderingParams = NULL; | 170 IDWriteRenderingParams* pRenderingParams = NULL; |
186 HRESULT hr = S_OK; | 171 HRESULT hr = S_OK; |
187 hr = pDwFactory->GetGdiInterop(&pGdiInterop); | 172 hr = pDwFactory->GetGdiInterop(&pGdiInterop); |
188 if (FAILED(hr)) { | 173 if (FAILED(hr)) { |
189 goto failed; | 174 goto failed; |
190 } | 175 } |
191 hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitma
p->GetHeight(), | 176 hr = pGdiInterop->CreateBitmapRenderTarget( |
192 &pBitmapRenderTarget); | 177 NULL, pBitmap->GetWidth(), pBitmap->GetHeight(), &pBitmapRenderTarget); |
193 if (FAILED(hr)) { | 178 if (FAILED(hr)) { |
194 goto failed; | 179 goto failed; |
195 } | 180 } |
196 hr = pDwFactory->CreateCustomRenderingParams( | 181 hr = pDwFactory->CreateCustomRenderingParams( |
197 1.0f, | 182 1.0f, 0.0f, 1.0f, DWRITE_PIXEL_GEOMETRY_RGB, |
198 0.0f, | 183 DWRITE_RENDERING_MODE_DEFAULT, &pRenderingParams); |
199 1.0f, | 184 if (FAILED(hr)) { |
200 DWRITE_PIXEL_GEOMETRY_RGB, | 185 goto failed; |
201 DWRITE_RENDERING_MODE_DEFAULT, | 186 } |
202 &pRenderingParams | 187 hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); |
203 ); | 188 if (FAILED(hr)) { |
204 if (FAILED(hr)) { | 189 goto failed; |
205 goto failed; | 190 } |
206 } | 191 *(CDwGdiTextRenderer**)renderTarget = |
207 hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f); | 192 new CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams); |
208 if (FAILED(hr)) { | 193 SafeRelease(&pGdiInterop); |
209 goto failed; | 194 SafeRelease(&pBitmapRenderTarget); |
210 } | 195 SafeRelease(&pRenderingParams); |
211 *(CDwGdiTextRenderer**)renderTarget = new CDwGdiTextRenderer(pBitmap, pBitma
pRenderTarget, pRenderingParams); | 196 return TRUE; |
212 SafeRelease(&pGdiInterop); | 197 failed: |
213 SafeRelease(&pBitmapRenderTarget); | 198 SafeRelease(&pGdiInterop); |
214 SafeRelease(&pRenderingParams); | 199 SafeRelease(&pBitmapRenderTarget); |
| 200 SafeRelease(&pRenderingParams); |
| 201 return FALSE; |
| 202 } |
| 203 FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, |
| 204 CFX_ClipRgn* pClipRgn, |
| 205 FX_RECT& stringRect, |
| 206 CFX_AffineMatrix* pMatrix, |
| 207 void* font, |
| 208 FX_FLOAT font_size, |
| 209 FX_ARGB text_color, |
| 210 int glyph_count, |
| 211 unsigned short* glyph_indices, |
| 212 FX_FLOAT baselineOriginX, |
| 213 FX_FLOAT baselineOriginY, |
| 214 void* glyph_offsets, |
| 215 FX_FLOAT* glyph_advances) { |
| 216 if (renderTarget == NULL) { |
215 return TRUE; | 217 return TRUE; |
216 failed: | 218 } |
217 SafeRelease(&pGdiInterop); | 219 CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; |
218 SafeRelease(&pBitmapRenderTarget); | 220 DWRITE_MATRIX transform; |
219 SafeRelease(&pRenderingParams); | 221 DWRITE_GLYPH_RUN glyphRun; |
220 return FALSE; | 222 HRESULT hr = S_OK; |
221 } | 223 if (pMatrix) { |
222 FX_BOOL»CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, F
X_RECT& stringRect, CFX_AffineMatrix* pMatrix, | 224 transform.m11 = pMatrix->a; |
223 void *font, FX_FLOAT font_size, FX_ARGB text
_color, | 225 transform.m12 = pMatrix->b; |
224 int glyph_count, unsigned short* glyph_indic
es, | 226 transform.m21 = pMatrix->c; |
225 FX_FLOAT baselineOriginX, FX_FLOAT baselineO
riginY, | 227 transform.m22 = pMatrix->d; |
226 void* glyph_offsets, | 228 transform.dx = pMatrix->e; |
227 FX_FLOAT* glyph_advances) | 229 transform.dy = pMatrix->f; |
228 { | 230 } |
229 if (renderTarget == NULL) { | 231 glyphRun.fontFace = (IDWriteFontFace*)font; |
230 return TRUE; | 232 glyphRun.fontEmSize = font_size; |
231 } | 233 glyphRun.glyphCount = glyph_count; |
232 CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget; | 234 glyphRun.glyphIndices = glyph_indices; |
233 DWRITE_MATRIX transform; | 235 glyphRun.glyphAdvances = glyph_advances; |
234 DWRITE_GLYPH_RUN glyphRun; | 236 glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; |
235 HRESULT hr = S_OK; | 237 glyphRun.isSideways = FALSE; |
236 if (pMatrix) { | 238 glyphRun.bidiLevel = 0; |
237 transform.m11 = pMatrix->a; | 239 hr = pTextRenderer->DrawGlyphRun( |
238 transform.m12 = pMatrix->b; | 240 stringRect, pClipRgn, pMatrix ? &transform : NULL, baselineOriginX, |
239 transform.m21 = pMatrix->c; | 241 baselineOriginY, DWRITE_MEASURING_MODE_NATURAL, &glyphRun, |
240 transform.m22 = pMatrix->d; | 242 RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))); |
241 transform.dx = pMatrix->e; | 243 return SUCCEEDED(hr) ? TRUE : FALSE; |
242 transform.dy = pMatrix->f; | 244 } |
243 } | 245 void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) { |
244 glyphRun.fontFace = (IDWriteFontFace*)font; | 246 delete (CDwGdiTextRenderer*)renderTarget; |
245 glyphRun.fontEmSize = font_size; | 247 } |
246 glyphRun.glyphCount = glyph_count; | 248 void CDWriteExt::DwDeleteFont(void* pFont) { |
247 glyphRun.glyphIndices = glyph_indices; | 249 if (pFont) { |
248 glyphRun.glyphAdvances = glyph_advances; | 250 SafeRelease((IDWriteFontFace**)&pFont); |
249 glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets; | 251 } |
250 glyphRun.isSideways = FALSE; | 252 } |
251 glyphRun.bidiLevel = 0; | 253 CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, |
252 hr = pTextRenderer->DrawGlyphRun( | 254 UINT32 fontFileReferenceKeySize) { |
253 stringRect, | 255 refCount_ = 0; |
254 pClipRgn, | 256 resourcePtr_ = fontFileReferenceKey; |
255 pMatrix ? &transform : NULL, | 257 resourceSize_ = fontFileReferenceKeySize; |
256 baselineOriginX, baselineOriginY, | 258 } |
257 DWRITE_MEASURING_MODE_NATURAL, | 259 HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, |
258 &glyphRun, | 260 void** ppvObject) { |
259 RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color
)) | 261 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { |
260 ); | 262 *ppvObject = this; |
261 return SUCCEEDED(hr) ? TRUE : FALSE; | 263 AddRef(); |
262 } | 264 return S_OK; |
263 void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget) | 265 } |
264 { | 266 *ppvObject = NULL; |
265 delete (CDwGdiTextRenderer*)renderTarget; | 267 return E_NOINTERFACE; |
266 } | 268 } |
267 void CDWriteExt::DwDeleteFont(void* pFont) | 269 ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() { |
268 { | 270 return InterlockedIncrement((long*)(&refCount_)); |
269 if (pFont) { | 271 } |
270 SafeRelease((IDWriteFontFace**)&pFont); | 272 ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() { |
271 } | 273 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); |
272 } | 274 if (newCount == 0) { |
273 CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fo
ntFileReferenceKeySize) | 275 delete this; |
274 { | 276 } |
275 refCount_ = 0; | 277 return newCount; |
276 resourcePtr_ = fontFileReferenceKey; | 278 } |
277 resourceSize_ = fontFileReferenceKeySize; | 279 HRESULT STDMETHODCALLTYPE |
278 } | 280 CDwFontFileStream::ReadFileFragment(void const** fragmentStart, |
279 HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** p
pvObject) | 281 UINT64 fileOffset, |
280 { | 282 UINT64 fragmentSize, |
281 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { | 283 OUT void** fragmentContext) { |
282 *ppvObject = this; | 284 if (fileOffset <= resourceSize_ && |
283 AddRef(); | 285 fragmentSize <= resourceSize_ - fileOffset) { |
284 return S_OK; | 286 *fragmentStart = static_cast<uint8_t const*>(resourcePtr_) + |
285 } | 287 static_cast<size_t>(fileOffset); |
286 *ppvObject = NULL; | |
287 return E_NOINTERFACE; | |
288 } | |
289 ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef() | |
290 { | |
291 return InterlockedIncrement((long*)(&refCount_)); | |
292 } | |
293 ULONG STDMETHODCALLTYPE CDwFontFileStream::Release() | |
294 { | |
295 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); | |
296 if (newCount == 0) { | |
297 delete this; | |
298 } | |
299 return newCount; | |
300 } | |
301 HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment( | |
302 void const** fragmentStart, | |
303 UINT64 fileOffset, | |
304 UINT64 fragmentSize, | |
305 OUT void** fragmentContext | |
306 ) | |
307 { | |
308 if (fileOffset <= resourceSize_ && fragmentSize <= resourceSize_ - fileOffse
t) { | |
309 *fragmentStart = static_cast<uint8_t const*>(resourcePtr_) + static_cast
<size_t>(fileOffset); | |
310 *fragmentContext = NULL; | |
311 return S_OK; | |
312 } | |
313 *fragmentStart = NULL; | |
314 *fragmentContext = NULL; | 288 *fragmentContext = NULL; |
315 return E_FAIL; | |
316 } | |
317 void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentCont
ext) | |
318 { | |
319 } | |
320 HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) | |
321 { | |
322 *fileSize = resourceSize_; | |
323 return S_OK; | 289 return S_OK; |
324 } | 290 } |
325 HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWr
iteTime) | 291 *fragmentStart = NULL; |
326 { | 292 *fragmentContext = NULL; |
327 *lastWriteTime = 0; | 293 return E_FAIL; |
328 return E_NOTIMPL; | 294 } |
| 295 void STDMETHODCALLTYPE |
| 296 CDwFontFileStream::ReleaseFileFragment(void* fragmentContext) {} |
| 297 HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize) { |
| 298 *fileSize = resourceSize_; |
| 299 return S_OK; |
| 300 } |
| 301 HRESULT STDMETHODCALLTYPE |
| 302 CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime) { |
| 303 *lastWriteTime = 0; |
| 304 return E_NOTIMPL; |
329 } | 305 } |
330 IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL; | 306 IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL; |
331 CDwFontFileLoader::CDwFontFileLoader() : | 307 CDwFontFileLoader::CDwFontFileLoader() : refCount_(0) {} |
332 refCount_(0) | 308 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, |
333 { | 309 void** ppvObject) { |
334 } | 310 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { |
335 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** p
pvObject) | 311 *ppvObject = this; |
336 { | 312 AddRef(); |
337 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { | 313 return S_OK; |
338 *ppvObject = this; | 314 } |
339 AddRef(); | 315 *ppvObject = NULL; |
340 return S_OK; | 316 return E_NOINTERFACE; |
341 } | 317 } |
342 *ppvObject = NULL; | 318 ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() { |
343 return E_NOINTERFACE; | 319 return InterlockedIncrement((long*)(&refCount_)); |
344 } | 320 } |
345 ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef() | 321 ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() { |
346 { | 322 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); |
347 return InterlockedIncrement((long*)(&refCount_)); | 323 if (newCount == 0) { |
348 } | 324 instance_ = NULL; |
349 ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release() | 325 delete this; |
350 { | 326 } |
351 ULONG newCount = InterlockedDecrement((long*)(&refCount_)); | 327 return newCount; |
352 if (newCount == 0) { | |
353 instance_ = NULL; | |
354 delete this; | |
355 } | |
356 return newCount; | |
357 } | 328 } |
358 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey( | 329 HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey( |
359 void const* fontFileReferenceKey, | 330 void const* fontFileReferenceKey, |
360 UINT32 fontFileReferenceKeySize, | 331 UINT32 fontFileReferenceKeySize, |
361 OUT IDWriteFontFileStream** fontFileStream | 332 OUT IDWriteFontFileStream** fontFileStream) { |
362 ) | 333 *fontFileStream = NULL; |
363 { | 334 CDwFontFileStream* stream = |
364 *fontFileStream = NULL; | 335 new CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize); |
365 CDwFontFileStream* stream = new CDwFontFileStream(fontFileReferenceKey, font
FileReferenceKeySize); | 336 if (!stream->IsInitialized()) { |
366 if (!stream->IsInitialized()) { | 337 delete stream; |
367 delete stream; | 338 return E_FAIL; |
368 return E_FAIL; | 339 } |
369 } | 340 *fontFileStream = SafeAcquire(stream); |
370 *fontFileStream = SafeAcquire(stream); | 341 return S_OK; |
371 return S_OK; | 342 } |
372 } | 343 CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) |
373 CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) : | 344 : hr_(S_FALSE), dwriteFactory_(SafeAcquire(dwriteFactory)) {} |
374 hr_(S_FALSE), | 345 CDwFontContext::~CDwFontContext() { |
375 dwriteFactory_(SafeAcquire(dwriteFactory)) | 346 if (dwriteFactory_ && hr_ == S_OK) { |
376 { | 347 dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader()); |
377 } | 348 } |
378 CDwFontContext::~CDwFontContext() | 349 SafeRelease(&dwriteFactory_); |
379 { | 350 } |
380 if(dwriteFactory_ && hr_ == S_OK) { | 351 HRESULT CDwFontContext::Initialize() { |
381 dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader())
; | 352 if (hr_ == S_FALSE) { |
382 } | 353 return hr_ = dwriteFactory_->RegisterFontFileLoader( |
383 SafeRelease(&dwriteFactory_); | 354 CDwFontFileLoader::GetLoader()); |
384 } | 355 } |
385 HRESULT CDwFontContext::Initialize() | 356 return hr_; |
386 { | 357 } |
387 if (hr_ == S_FALSE) { | 358 CDwGdiTextRenderer::CDwGdiTextRenderer( |
388 return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::G
etLoader()); | 359 CFX_DIBitmap* pBitmap, |
389 } | 360 IDWriteBitmapRenderTarget* bitmapRenderTarget, |
390 return hr_; | 361 IDWriteRenderingParams* renderingParams) |
391 } | 362 : pBitmap_(pBitmap), |
392 CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRende
rTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams): | 363 pRenderTarget_(SafeAcquire(bitmapRenderTarget)), |
393 pBitmap_(pBitmap), | 364 pRenderingParams_(SafeAcquire(renderingParams)) {} |
394 pRenderTarget_(SafeAcquire(bitmapRenderTarget)), | 365 CDwGdiTextRenderer::~CDwGdiTextRenderer() { |
395 pRenderingParams_(SafeAcquire(renderingParams)) | 366 SafeRelease(&pRenderTarget_); |
396 { | 367 SafeRelease(&pRenderingParams_); |
397 } | |
398 CDwGdiTextRenderer::~CDwGdiTextRenderer() | |
399 { | |
400 SafeRelease(&pRenderTarget_); | |
401 SafeRelease(&pRenderingParams_); | |
402 } | 368 } |
403 STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( | 369 STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun( |
404 const FX_RECT& text_bbox, | 370 const FX_RECT& text_bbox, |
405 __in_opt CFX_ClipRgn* pClipRgn, | 371 __in_opt CFX_ClipRgn* pClipRgn, |
406 __in_opt DWRITE_MATRIX const* pMatrix, | 372 __in_opt DWRITE_MATRIX const* pMatrix, |
407 FLOAT baselineOriginX, | 373 FLOAT baselineOriginX, |
408 FLOAT baselineOriginY, | 374 FLOAT baselineOriginY, |
409 DWRITE_MEASURING_MODE measuringMode, | 375 DWRITE_MEASURING_MODE measuringMode, |
410 __in DWRITE_GLYPH_RUN const* glyphRun, | 376 __in DWRITE_GLYPH_RUN const* glyphRun, |
411 const COLORREF& textColor | 377 const COLORREF& textColor) { |
412 ) | 378 HRESULT hr = S_OK; |
413 { | 379 if (pMatrix) { |
414 HRESULT hr = S_OK; | 380 hr = pRenderTarget_->SetCurrentTransform(pMatrix); |
415 if (pMatrix) { | 381 if (FAILED(hr)) { |
416 hr = pRenderTarget_->SetCurrentTransform(pMatrix); | 382 return hr; |
417 if (FAILED(hr)) { | |
418 return hr; | |
419 } | |
420 } | 383 } |
421 HDC hDC = pRenderTarget_->GetMemoryDC(); | 384 } |
422 HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); | 385 HDC hDC = pRenderTarget_->GetMemoryDC(); |
423 BITMAP bitmap; | 386 HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP); |
424 GetObject(hBitmap, sizeof bitmap, &bitmap); | 387 BITMAP bitmap; |
425 CFX_DIBitmap dib; | 388 GetObject(hBitmap, sizeof bitmap, &bitmap); |
426 dib.Create( | 389 CFX_DIBitmap dib; |
427 bitmap.bmWidth, | 390 dib.Create(bitmap.bmWidth, bitmap.bmHeight, |
428 bitmap.bmHeight, | 391 bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, |
429 bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32, | 392 (uint8_t*)bitmap.bmBits); |
430 (uint8_t*)bitmap.bmBits | 393 dib.CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(), |
431 ); | 394 text_bbox.Height(), pBitmap_, text_bbox.left, |
432 dib.CompositeBitmap( | 395 text_bbox.top, FXDIB_BLEND_NORMAL, NULL); |
433 text_bbox.left, | 396 hr = pRenderTarget_->DrawGlyphRun(baselineOriginX, baselineOriginY, |
434 text_bbox.top, | 397 measuringMode, glyphRun, pRenderingParams_, |
435 text_bbox.Width(), | 398 textColor); |
436 text_bbox.Height(), | 399 if (FAILED(hr)) { |
437 pBitmap_, | |
438 text_bbox.left, | |
439 text_bbox.top, | |
440 FXDIB_BLEND_NORMAL, | |
441 NULL | |
442 ); | |
443 hr = pRenderTarget_->DrawGlyphRun( | |
444 baselineOriginX, | |
445 baselineOriginY, | |
446 measuringMode, | |
447 glyphRun, | |
448 pRenderingParams_, | |
449 textColor | |
450 ); | |
451 if (FAILED(hr)) { | |
452 return hr; | |
453 } | |
454 pBitmap_->CompositeBitmap( | |
455 text_bbox.left, | |
456 text_bbox.top, | |
457 text_bbox.Width(), | |
458 text_bbox.Height(), | |
459 &dib, | |
460 text_bbox.left, | |
461 text_bbox.top, | |
462 FXDIB_BLEND_NORMAL, | |
463 pClipRgn | |
464 ); | |
465 return hr; | 400 return hr; |
| 401 } |
| 402 pBitmap_->CompositeBitmap(text_bbox.left, text_bbox.top, text_bbox.Width(), |
| 403 text_bbox.Height(), &dib, text_bbox.left, |
| 404 text_bbox.top, FXDIB_BLEND_NORMAL, pClipRgn); |
| 405 return hr; |
466 } | 406 } |
467 #endif | 407 #endif |
OLD | NEW |