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