Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: core/src/fxge/win32/fx_win32_device.cpp

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 8
9 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ 9 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
10 #include <crtdbg.h> 10 #include <crtdbg.h>
11 11
12 #include "../../../include/fxcodec/fx_codec.h" 12 #include "../../../include/fxcodec/fx_codec.h"
13 #include "../../../include/fxge/fx_freetype.h" 13 #include "../../../include/fxge/fx_freetype.h"
14 #include "../../../include/fxge/fx_ge_win32.h" 14 #include "../../../include/fxge/fx_ge_win32.h"
15 #include "../agg/include/fx_agg_driver.h" 15 #include "../agg/include/fx_agg_driver.h"
16 #include "../dib/dib_int.h" 16 #include "../dib/dib_int.h"
17 #include "../ge/text_int.h" 17 #include "../ge/text_int.h"
18 #include "dwrite_int.h" 18 #include "dwrite_int.h"
19 #include "win32_int.h" 19 #include "win32_int.h"
20 20
21 class CFX_Win32FontInfo final : public IFX_SystemFontInfo 21 class CFX_Win32FontInfo final : public IFX_SystemFontInfo {
22 { 22 public:
23 public: 23 CFX_Win32FontInfo();
24 CFX_Win32FontInfo(); 24 ~CFX_Win32FontInfo();
25 ~CFX_Win32FontInfo(); 25 virtual void Release();
26 virtual void» » Release(); 26 virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper);
27 virtual» FX_BOOL»» EnumFontList(CFX_FontMapper* pMapper); 27 virtual void* MapFont(int weight,
28 virtual void*» » MapFont(int weight, FX_BOOL bItalic, int charset , int pitch_family, const FX_CHAR* face, int& iExact); 28 FX_BOOL bItalic,
29 virtual void*» » GetFont(const FX_CHAR* face) 29 int charset,
30 { 30 int pitch_family,
31 return NULL; 31 const FX_CHAR* face,
32 int& iExact);
33 virtual void* GetFont(const FX_CHAR* face) { return NULL; }
34 virtual FX_DWORD GetFontData(void* hFont,
35 FX_DWORD table,
36 uint8_t* buffer,
37 FX_DWORD size);
38 virtual void DeleteFont(void* hFont);
39 virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name);
40 virtual FX_BOOL GetFontCharset(void* hFont, int& charset);
41 FX_BOOL IsOpenTypeFromDiv(const LOGFONTA* plf);
42 FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf);
43 void AddInstalledFont(const LOGFONTA* plf, FX_DWORD FontType);
44 void GetGBPreference(CFX_ByteString& face, int weight, int picth_family);
45 void GetJapanesePreference(CFX_ByteString& face,
46 int weight,
47 int picth_family);
48 CFX_ByteString FindFont(const CFX_ByteString& name);
49 HDC m_hDC;
50 CFX_FontMapper* m_pMapper;
51 CFX_ByteString m_LastFamily;
52 CFX_ByteString m_KaiTi, m_FangSong;
53 };
54 CFX_Win32FontInfo::CFX_Win32FontInfo() {
55 m_hDC = CreateCompatibleDC(NULL);
56 }
57 CFX_Win32FontInfo::~CFX_Win32FontInfo() {
58 m_pMapper = NULL;
59 }
60 void CFX_Win32FontInfo::Release() {
61 DeleteDC(m_hDC);
62 delete this;
63 }
64 #define TT_MAKE_TAG(x1, x2, x3, x4) \
65 (((FX_DWORD)x1 << 24) | ((FX_DWORD)x2 << 16) | ((FX_DWORD)x3 << 8) | \
66 (FX_DWORD)x4)
67 FX_BOOL CFX_Win32FontInfo::IsOpenTypeFromDiv(const LOGFONTA* plf) {
68 HFONT hFont = CreateFontIndirectA(plf);
69 FX_BOOL ret = FALSE;
70 FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
71 if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
72 FX_DWORD lVersion = 0;
73 GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD));
74 lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) |
75 ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 |
76 ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 |
77 ((uint8_t)(lVersion >> 24));
78 if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || lVersion == 0x00010000 ||
79 lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
80 lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') || lVersion == 0x00020000) {
81 ret = TRUE;
32 } 82 }
33 virtual FX_DWORD» GetFontData(void* hFont, FX_DWORD table, uint8_t* buffer , FX_DWORD size); 83 }
34 virtual void» » DeleteFont(void* hFont); 84 DeleteFont(hFont);
35 virtual» FX_BOOL»» GetFaceName(void* hFont, CFX_ByteString& name); 85 return ret;
36 virtual FX_BOOL» » GetFontCharset(void* hFont, int& charset);
37 FX_BOOL» » » » IsOpenTypeFromDiv(const LOGFONTA *plf);
38 FX_BOOL» » » » IsSupportFontFormDiv(const LOGFONTA* plf );
39 void» » » » AddInstalledFont(const LOGFONTA *plf, FX _DWORD FontType);
40 void» » » » GetGBPreference(CFX_ByteString& face, in t weight, int picth_family);
41 void» » » » GetJapanesePreference(CFX_ByteString& fa ce, int weight, int picth_family);
42 CFX_ByteString» » FindFont(const CFX_ByteString& name);
43 HDC»» » » » m_hDC;
44 CFX_FontMapper*» » m_pMapper;
45 CFX_ByteString» » m_LastFamily;
46 CFX_ByteString» » m_KaiTi, m_FangSong;
47 };
48 CFX_Win32FontInfo::CFX_Win32FontInfo()
49 {
50 m_hDC = CreateCompatibleDC(NULL);
51 } 86 }
52 CFX_Win32FontInfo::~CFX_Win32FontInfo() 87 FX_BOOL CFX_Win32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf) {
53 { 88 HFONT hFont = CreateFontIndirectA(plf);
54 m_pMapper = NULL; 89 FX_BOOL ret = FALSE;
90 FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
91 if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
92 FX_DWORD lVersion = 0;
93 GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD));
94 lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) |
95 ((FX_DWORD)((uint8_t)(lVersion >> 8))) << 16 |
96 ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 |
97 ((uint8_t)(lVersion >> 24));
98 if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || lVersion == 0x00010000 ||
99 lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
100 lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') || lVersion == 0x00020000) {
101 ret = TRUE;
102 } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) ||
103 (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
104 ret = TRUE;
105 }
106 }
107 DeleteFont(hFont);
108 return ret;
55 } 109 }
56 void CFX_Win32FontInfo::Release() 110 void CFX_Win32FontInfo::AddInstalledFont(const LOGFONTA* plf,
57 { 111 FX_DWORD FontType) {
58 DeleteDC(m_hDC); 112 CFX_ByteString name(plf->lfFaceName, -1);
59 delete this; 113 if (name[0] == '@') {
114 return;
115 }
116 if (name == m_LastFamily) {
117 m_pMapper->AddInstalledFont(name, plf->lfCharSet);
118 return;
119 }
120 if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
121 return;
122 }
123 if (!(FontType & TRUETYPE_FONTTYPE)) {
124 if (!IsSupportFontFormDiv(plf)) {
125 return;
126 }
127 }
128 m_pMapper->AddInstalledFont(name, plf->lfCharSet);
129 m_LastFamily = name;
60 } 130 }
61 #define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_ DWORD)x3<<8)|(FX_DWORD)x4) 131 static int CALLBACK FontEnumProc(const LOGFONTA* plf,
62 FX_BOOL CFX_Win32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf) 132 const TEXTMETRICA* lpntme,
63 { 133 FX_DWORD FontType,
64 HFONT hFont = CreateFontIndirectA(plf); 134 LPARAM lParam) {
65 FX_BOOL ret = FALSE; 135 CFX_Win32FontInfo* pFontInfo = (CFX_Win32FontInfo*)lParam;
66 FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0); 136 if (pFontInfo->m_pMapper->GetFontEnumerator()) {
67 if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) { 137 pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
68 FX_DWORD lVersion = 0; 138 }
69 GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD)); 139 pFontInfo->AddInstalledFont(plf, FontType);
70 lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | ((FX_DWORD)((uint8_ t)(lVersion >> 8))) << 16 | 140 return 1;
71 ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | ((uint8_t)(lVe rsion >> 24));
72 if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
73 lVersion == 0x00010000 ||
74 lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
75 lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
76 lVersion == 0x00020000) {
77 ret = TRUE;
78 }
79 }
80 DeleteFont(hFont);
81 return ret;
82 } 141 }
83 FX_BOOL CFX_Win32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf) 142 FX_BOOL CFX_Win32FontInfo::EnumFontList(CFX_FontMapper* pMapper) {
84 { 143 m_pMapper = pMapper;
85 HFONT hFont = CreateFontIndirectA(plf); 144 LOGFONTA lf;
86 FX_BOOL ret = FALSE; 145 FXSYS_memset(&lf, 0, sizeof(LOGFONTA));
87 FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0); 146 lf.lfCharSet = DEFAULT_CHARSET;
88 if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) { 147 lf.lfFaceName[0] = 0;
89 FX_DWORD lVersion = 0; 148 lf.lfPitchAndFamily = 0;
90 GetFontData(hFont, 0, (uint8_t*)(&lVersion), sizeof(FX_DWORD)); 149 EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (uintptr_t) this,
91 lVersion = (((FX_DWORD)(uint8_t)(lVersion)) << 24) | ((FX_DWORD)((uint8_ t)(lVersion >> 8))) << 16 | 150 0);
92 ((FX_DWORD)((uint8_t)(lVersion >> 16))) << 8 | ((uint8_t)(lVe rsion >> 24)); 151 if (pMapper->GetFontEnumerator()) {
93 if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') || 152 pMapper->GetFontEnumerator()->Finish();
94 lVersion == 0x00010000 || 153 }
95 lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') || 154 return TRUE;
96 lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
97 lVersion == 0x00020000) {
98 ret = TRUE;
99 } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00 ) ||
100 (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
101 ret = TRUE;
102 }
103 }
104 DeleteFont(hFont);
105 return ret;
106 }
107 void CFX_Win32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType)
108 {
109 CFX_ByteString name(plf->lfFaceName, -1);
110 if (name[0] == '@') {
111 return;
112 }
113 if (name == m_LastFamily) {
114 m_pMapper->AddInstalledFont(name, plf->lfCharSet);
115 return;
116 }
117 if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
118 return;
119 }
120 if (!(FontType & TRUETYPE_FONTTYPE)) {
121 if (!IsSupportFontFormDiv(plf)) {
122 return;
123 }
124 }
125 m_pMapper->AddInstalledFont(name, plf->lfCharSet);
126 m_LastFamily = name;
127 }
128 static int CALLBACK FontEnumProc(
129 const LOGFONTA *plf,
130 const TEXTMETRICA *lpntme,
131 FX_DWORD FontType,
132 LPARAM lParam
133 )
134 {
135 CFX_Win32FontInfo* pFontInfo = (CFX_Win32FontInfo*)lParam;
136 if (pFontInfo->m_pMapper->GetFontEnumerator()) {
137 pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
138 }
139 pFontInfo->AddInstalledFont(plf, FontType);
140 return 1;
141 }
142 FX_BOOL CFX_Win32FontInfo::EnumFontList(CFX_FontMapper* pMapper)
143 {
144 m_pMapper = pMapper;
145 LOGFONTA lf;
146 FXSYS_memset(&lf, 0, sizeof(LOGFONTA));
147 lf.lfCharSet = DEFAULT_CHARSET;
148 lf.lfFaceName[0] = 0;
149 lf.lfPitchAndFamily = 0;
150 EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (uintptr_t)this , 0);
151 if (pMapper->GetFontEnumerator()) {
152 pMapper->GetFontEnumerator()->Finish();
153 }
154 return TRUE;
155 } 155 }
156 static const struct { 156 static const struct {
157 const FX_CHAR*» m_pFaceName; 157 const FX_CHAR* m_pFaceName;
158 const FX_CHAR*» m_pVariantName; 158 const FX_CHAR* m_pVariantName;
159 } 159 } VariantNames[] = {
160 VariantNames[] = {
161 {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"}, 160 {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"},
162 }; 161 };
163 static const struct { 162 static const struct {
164 const FX_CHAR*» m_pName; 163 const FX_CHAR* m_pName;
165 const FX_CHAR*» m_pWinName; 164 const FX_CHAR* m_pWinName;
166 FX_BOOL» » m_bBold; 165 FX_BOOL m_bBold;
167 FX_BOOL» » m_bItalic; 166 FX_BOOL m_bItalic;
168 } 167 } Base14Substs[] = {
169 Base14Substs[] = {
170 {"Courier", "Courier New", FALSE, FALSE}, 168 {"Courier", "Courier New", FALSE, FALSE},
171 {"Courier-Bold", "Courier New", TRUE, FALSE}, 169 {"Courier-Bold", "Courier New", TRUE, FALSE},
172 {"Courier-BoldOblique", "Courier New", TRUE, TRUE}, 170 {"Courier-BoldOblique", "Courier New", TRUE, TRUE},
173 {"Courier-Oblique", "Courier New", FALSE, TRUE}, 171 {"Courier-Oblique", "Courier New", FALSE, TRUE},
174 {"Helvetica", "Arial", FALSE, FALSE}, 172 {"Helvetica", "Arial", FALSE, FALSE},
175 {"Helvetica-Bold", "Arial", TRUE, FALSE}, 173 {"Helvetica-Bold", "Arial", TRUE, FALSE},
176 {"Helvetica-BoldOblique", "Arial", TRUE, TRUE}, 174 {"Helvetica-BoldOblique", "Arial", TRUE, TRUE},
177 {"Helvetica-Oblique", "Arial", FALSE, TRUE}, 175 {"Helvetica-Oblique", "Arial", FALSE, TRUE},
178 {"Times-Roman", "Times New Roman", FALSE, FALSE}, 176 {"Times-Roman", "Times New Roman", FALSE, FALSE},
179 {"Times-Bold", "Times New Roman", TRUE, FALSE}, 177 {"Times-Bold", "Times New Roman", TRUE, FALSE},
180 {"Times-BoldItalic", "Times New Roman", TRUE, TRUE}, 178 {"Times-BoldItalic", "Times New Roman", TRUE, TRUE},
181 {"Times-Italic", "Times New Roman", FALSE, TRUE}, 179 {"Times-Italic", "Times New Roman", FALSE, TRUE},
182 }; 180 };
183 CFX_ByteString CFX_Win32FontInfo::FindFont(const CFX_ByteString& name) 181 CFX_ByteString CFX_Win32FontInfo::FindFont(const CFX_ByteString& name) {
184 { 182 if (m_pMapper == NULL) {
185 if (m_pMapper == NULL) { 183 return name;
186 return name; 184 }
187 } 185 int nFonts = m_pMapper->m_InstalledTTFonts.GetSize();
188 int nFonts = m_pMapper->m_InstalledTTFonts.GetSize(); 186 for (int i = 0; i < nFonts; i++) {
189 for (int i = 0; i < nFonts; i ++) { 187 CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i];
190 CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i]; 188 if (thisname[0] == ' ') {
191 if (thisname[0] == ' ') { 189 if (thisname.Mid(1, name.GetLength()) == name) {
192 if (thisname.Mid(1, name.GetLength()) == name) { 190 return m_pMapper->m_InstalledTTFonts[i + 1];
193 return m_pMapper->m_InstalledTTFonts[i + 1]; 191 }
194 } 192 } else if (thisname.Left(name.GetLength()) == name) {
195 } else if (thisname.Left(name.GetLength()) == name) { 193 return m_pMapper->m_InstalledTTFonts[i];
196 return m_pMapper->m_InstalledTTFonts[i]; 194 }
197 } 195 }
198 } 196 return CFX_ByteString();
199 return CFX_ByteString();
200 } 197 }
201 struct _FontNameMap { 198 struct _FontNameMap {
202 const FX_CHAR*» m_pSubFontName; 199 const FX_CHAR* m_pSubFontName;
203 const FX_CHAR*» m_pSrcFontName; 200 const FX_CHAR* m_pSrcFontName;
204 }; 201 };
205 const _FontNameMap g_JpFontNameMap[] = { 202 const _FontNameMap g_JpFontNameMap[] = {
206 {"MS Mincho", "Heiseimin-W3"}, 203 {"MS Mincho", "Heiseimin-W3"},
207 {"MS Gothic", "Jun101-Light"}, 204 {"MS Gothic", "Jun101-Light"},
208 }; 205 };
209 extern "C" { 206 extern "C" {
210 static int compareString(const void* key, const void* element) 207 static int compareString(const void* key, const void* element) {
211 { 208 return FXSYS_stricmp((const FX_CHAR*)key,
212 return FXSYS_stricmp((const FX_CHAR*)key, ((_FontNameMap*)element)->m_pS rcFontName); 209 ((_FontNameMap*)element)->m_pSrcFontName);
213 } 210 }
214 } 211 }
215 FX_BOOL _GetSubFontName(CFX_ByteString& name) 212 FX_BOOL _GetSubFontName(CFX_ByteString& name) {
216 { 213 int size = sizeof g_JpFontNameMap;
217 int size = sizeof g_JpFontNameMap; 214 void* pFontnameMap = (void*)g_JpFontNameMap;
218 void* pFontnameMap = (void*)g_JpFontNameMap; 215 _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch(
219 _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch(name.c_str(), pFontnameMa p, 216 name.c_str(), pFontnameMap, size / sizeof(_FontNameMap),
220 size / sizeof (_FontNameMap), sizeof (_FontNameMap), c ompareString); 217 sizeof(_FontNameMap), compareString);
221 if (found == NULL) { 218 if (found == NULL) {
222 return FALSE; 219 return FALSE;
223 } 220 }
224 name = found->m_pSubFontName; 221 name = found->m_pSubFontName;
225 return TRUE; 222 return TRUE;
226 } 223 }
227 void CFX_Win32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int pi cth_family) 224 void CFX_Win32FontInfo::GetGBPreference(CFX_ByteString& face,
228 { 225 int weight,
229 if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) { 226 int picth_family) {
230 if (m_KaiTi.IsEmpty()) { 227 if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) {
231 m_KaiTi = FindFont("KaiTi"); 228 if (m_KaiTi.IsEmpty()) {
232 if (m_KaiTi.IsEmpty()) { 229 m_KaiTi = FindFont("KaiTi");
233 m_KaiTi = "SimSun"; 230 if (m_KaiTi.IsEmpty()) {
234 } 231 m_KaiTi = "SimSun";
235 } 232 }
236 face = m_KaiTi; 233 }
237 } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) { 234 face = m_KaiTi;
238 if (m_FangSong.IsEmpty()) { 235 } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) {
239 m_FangSong = FindFont("FangSong"); 236 if (m_FangSong.IsEmpty()) {
240 if (m_FangSong.IsEmpty()) { 237 m_FangSong = FindFont("FangSong");
241 m_FangSong = "SimSun"; 238 if (m_FangSong.IsEmpty()) {
242 } 239 m_FangSong = "SimSun";
243 } 240 }
244 face = m_FangSong; 241 }
245 } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) { 242 face = m_FangSong;
246 face = "SimSun"; 243 } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) {
247 } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) { 244 face = "SimSun";
248 face = "SimHei"; 245 } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) {
249 } else if (!(picth_family & FF_ROMAN) && weight > 550) { 246 face = "SimHei";
250 face = "SimHei"; 247 } else if (!(picth_family & FF_ROMAN) && weight > 550) {
248 face = "SimHei";
249 } else {
250 face = "SimSun";
251 }
252 }
253 void CFX_Win32FontInfo::GetJapanesePreference(CFX_ByteString& face,
254 int weight,
255 int picth_family) {
256 if (face.Find("Gothic") >= 0 ||
257 face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
258 if (face.Find("PGothic") >= 0 ||
259 face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
260 face = "MS PGothic";
261 } else if (face.Find("UI Gothic") >= 0) {
262 face = "MS UI Gothic";
251 } else { 263 } else {
252 face = "SimSun"; 264 if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
253 }
254 }
255 void CFX_Win32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
256 {
257 if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e" ) >= 0) {
258 if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83 \x62\x83\x4e") >= 0) {
259 face = "MS PGothic";
260 } else if (face.Find("UI Gothic") >= 0) {
261 face = "MS UI Gothic";
262 } else {
263 if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
264 face = "MS PGothic";
265 } else {
266 face = "MS Gothic";
267 }
268 }
269 return;
270 }
271 if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
272 if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") > = 0) {
273 face = "MS PMincho";
274 } else {
275 face = "MS Mincho";
276 }
277 return;
278 }
279 if (_GetSubFontName(face)) {
280 return;
281 }
282 if (!(picth_family & FF_ROMAN) && weight > 400) {
283 face = "MS PGothic"; 265 face = "MS PGothic";
266 } else {
267 face = "MS Gothic";
268 }
269 }
270 return;
271 }
272 if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
273 if (face.Find("PMincho") >= 0 ||
274 face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
275 face = "MS PMincho";
284 } else { 276 } else {
285 face = "MS PMincho"; 277 face = "MS Mincho";
286 } 278 }
287 } 279 return;
288 void* CFX_Win32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int p itch_family, const FX_CHAR* cstr_face, int& iExact) 280 }
289 { 281 if (_GetSubFontName(face)) {
290 CFX_ByteString face = cstr_face; 282 return;
291 int iBaseFont; 283 }
292 for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++) 284 if (!(picth_family & FF_ROMAN) && weight > 400) {
293 if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) { 285 face = "MS PGothic";
294 face = Base14Substs[iBaseFont].m_pWinName; 286 } else {
295 weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL; 287 face = "MS PMincho";
296 bItalic = Base14Substs[iBaseFont].m_bItalic; 288 }
297 iExact = TRUE; 289 }
298 break; 290 void* CFX_Win32FontInfo::MapFont(int weight,
299 } 291 FX_BOOL bItalic,
300 if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) { 292 int charset,
301 charset = DEFAULT_CHARSET; 293 int pitch_family,
302 } 294 const FX_CHAR* cstr_face,
303 int subst_pitch_family = pitch_family; 295 int& iExact) {
304 switch (charset) { 296 CFX_ByteString face = cstr_face;
305 case SHIFTJIS_CHARSET: 297 int iBaseFont;
306 subst_pitch_family = FF_ROMAN; 298 for (iBaseFont = 0; iBaseFont < 12; iBaseFont++)
307 break; 299 if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
308 case CHINESEBIG5_CHARSET: 300 face = Base14Substs[iBaseFont].m_pWinName;
309 case HANGUL_CHARSET: 301 weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL;
310 case GB2312_CHARSET: 302 bItalic = Base14Substs[iBaseFont].m_bItalic;
311 subst_pitch_family = 0; 303 iExact = TRUE;
312 break; 304 break;
313 } 305 }
314 HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OU T_TT_ONLY_PRECIS, 306 if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) {
315 0, 0, subst_pitch_family, face); 307 charset = DEFAULT_CHARSET;
316 char facebuf[100]; 308 }
317 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont); 309 int subst_pitch_family = pitch_family;
318 int ret = ::GetTextFaceA(m_hDC, 100, facebuf); 310 switch (charset) {
319 ::SelectObject(m_hDC, hOldFont); 311 case SHIFTJIS_CHARSET:
320 if (face.EqualNoCase(facebuf)) { 312 subst_pitch_family = FF_ROMAN;
313 break;
314 case CHINESEBIG5_CHARSET:
315 case HANGUL_CHARSET:
316 case GB2312_CHARSET:
317 subst_pitch_family = 0;
318 break;
319 }
320 HFONT hFont =
321 ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset,
322 OUT_TT_ONLY_PRECIS, 0, 0, subst_pitch_family, face);
323 char facebuf[100];
324 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont);
325 int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
326 ::SelectObject(m_hDC, hOldFont);
327 if (face.EqualNoCase(facebuf)) {
328 return hFont;
329 }
330 int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]);
331 for (int i = 0; i < iCount; ++i) {
332 if (face == VariantNames[i].m_pFaceName) {
333 CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf);
334 const unsigned short* pName =
335 (const unsigned short*)VariantNames[i].m_pVariantName;
336 FX_STRSIZE len = CFX_WideString::WStringLength(pName);
337 CFX_WideString wsName = CFX_WideString::FromUTF16LE(pName, len);
338 if (wsFace == wsName) {
321 return hFont; 339 return hFont;
322 } 340 }
323 int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]); 341 }
324 for (int i = 0; i < iCount; ++i) { 342 }
325 if (face == VariantNames[i].m_pFaceName) { 343 ::DeleteObject(hFont);
326 CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf); 344 if (charset == DEFAULT_CHARSET) {
327 const unsigned short* pName = (const unsigned short*)VariantNames[i] .m_pVariantName; 345 return NULL;
328 FX_STRSIZE len = CFX_WideString::WStringLength(pName); 346 }
329 CFX_WideString wsName = CFX_WideString::FromUTF16LE(pName, len); 347 switch (charset) {
330 if (wsFace == wsName) { 348 case SHIFTJIS_CHARSET:
331 return hFont; 349 GetJapanesePreference(face, weight, pitch_family);
332 } 350 break;
333 } 351 case GB2312_CHARSET:
334 } 352 GetGBPreference(face, weight, pitch_family);
335 ::DeleteObject(hFont); 353 break;
336 if (charset == DEFAULT_CHARSET) { 354 case HANGUL_CHARSET:
337 return NULL; 355 face = "Gulim";
338 } 356 break;
339 switch (charset) { 357 case CHINESEBIG5_CHARSET:
340 case SHIFTJIS_CHARSET: 358 if (face.Find("MSung") >= 0) {
341 GetJapanesePreference(face, weight, pitch_family); 359 face = "MingLiU";
342 break; 360 } else {
343 case GB2312_CHARSET: 361 face = "PMingLiU";
344 GetGBPreference(face, weight, pitch_family); 362 }
345 break; 363 break;
346 case HANGUL_CHARSET: 364 }
347 face = "Gulim"; 365 hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset,
348 break; 366 OUT_TT_ONLY_PRECIS, 0, 0, subst_pitch_family, face);
349 case CHINESEBIG5_CHARSET: 367 return hFont;
350 if (face.Find("MSung") >= 0) { 368 }
351 face = "MingLiU"; 369 void CFX_Win32FontInfo::DeleteFont(void* hFont) {
352 } else { 370 ::DeleteObject(hFont);
353 face = "PMingLiU"; 371 }
354 } 372 FX_DWORD CFX_Win32FontInfo::GetFontData(void* hFont,
355 break; 373 FX_DWORD table,
356 } 374 uint8_t* buffer,
357 hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_O NLY_PRECIS, 375 FX_DWORD size) {
358 0, 0, subst_pitch_family, face); 376 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
359 return hFont; 377 table = FXDWORD_FROM_MSBFIRST(table);
360 } 378 size = ::GetFontData(m_hDC, table, 0, buffer, size);
361 void CFX_Win32FontInfo::DeleteFont(void* hFont) 379 ::SelectObject(m_hDC, hOldFont);
362 { 380 if (size == GDI_ERROR) {
363 ::DeleteObject(hFont); 381 return 0;
364 } 382 }
365 FX_DWORD CFX_Win32FontInfo::GetFontData(void* hFont, FX_DWORD table, uint8_t* bu ffer, FX_DWORD size) 383 return size;
366 { 384 }
367 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); 385 FX_BOOL CFX_Win32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name) {
368 table = FXDWORD_FROM_MSBFIRST(table); 386 char facebuf[100];
369 size = ::GetFontData(m_hDC, table, 0, buffer, size); 387 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
370 ::SelectObject(m_hDC, hOldFont); 388 int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
371 if (size == GDI_ERROR) { 389 ::SelectObject(m_hDC, hOldFont);
372 return 0; 390 if (ret == 0) {
373 } 391 return FALSE;
374 return size; 392 }
375 } 393 name = facebuf;
376 FX_BOOL CFX_Win32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name) 394 return TRUE;
377 { 395 }
378 char facebuf[100]; 396 FX_BOOL CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) {
379 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); 397 TEXTMETRIC tm;
380 int ret = ::GetTextFaceA(m_hDC, 100, facebuf); 398 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
381 ::SelectObject(m_hDC, hOldFont); 399 ::GetTextMetrics(m_hDC, &tm);
382 if (ret == 0) { 400 ::SelectObject(m_hDC, hOldFont);
383 return FALSE; 401 charset = tm.tmCharSet;
384 } 402 return TRUE;
385 name = facebuf; 403 }
386 return TRUE; 404 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() {
387 } 405 return new CFX_Win32FontInfo;
388 FX_BOOL CFX_Win32FontInfo::GetFontCharset(void* hFont, int& charset) 406 }
389 { 407 void CFX_GEModule::InitPlatform() {
390 TEXTMETRIC tm; 408 CWin32Platform* pPlatformData = new CWin32Platform;
391 HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont); 409 OSVERSIONINFO ver;
392 ::GetTextMetrics(m_hDC, &tm); 410 ver.dwOSVersionInfoSize = sizeof(ver);
393 ::SelectObject(m_hDC, hOldFont); 411 GetVersionEx(&ver);
394 charset = tm.tmCharSet; 412 pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
395 return TRUE; 413 pPlatformData->m_GdiplusExt.Load();
396 } 414 m_pPlatformData = pPlatformData;
397 IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault() 415 m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
398 { 416 }
399 return new CFX_Win32FontInfo; 417 void CFX_GEModule::DestroyPlatform() {
400 } 418 delete (CWin32Platform*)m_pPlatformData;
401 void CFX_GEModule::InitPlatform() 419 m_pPlatformData = NULL;
402 { 420 }
403 CWin32Platform* pPlatformData = new CWin32Platform; 421 CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class) {
404 OSVERSIONINFO ver; 422 m_hDC = hDC;
405 ver.dwOSVersionInfoSize = sizeof(ver); 423 m_DeviceClass = device_class;
406 GetVersionEx(&ver); 424 CWin32Platform* pPlatform =
407 pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5; 425 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
408 pPlatformData->m_GdiplusExt.Load(); 426 SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR);
409 m_pPlatformData = pPlatformData; 427 if (GetObjectType(m_hDC) == OBJ_MEMDC) {
410 m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault()); 428 HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL);
411 } 429 hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
412 void CFX_GEModule::DestroyPlatform() 430 BITMAP bitmap;
413 { 431 GetObject(hBitmap, sizeof bitmap, &bitmap);
414 delete (CWin32Platform*)m_pPlatformData; 432 m_nBitsPerPixel = bitmap.bmBitsPixel;
415 m_pPlatformData = NULL; 433 m_Width = bitmap.bmWidth;
416 } 434 m_Height = abs(bitmap.bmHeight);
417 CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class) 435 hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
418 { 436 DeleteObject(hBitmap);
419 m_hDC = hDC; 437 } else {
420 m_DeviceClass = device_class; 438 m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
421 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor mData(); 439 m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
422 SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR); 440 m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
423 if (GetObjectType(m_hDC) == OBJ_MEMDC) { 441 }
424 HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL); 442 if (m_DeviceClass != FXDC_DISPLAY) {
425 hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap); 443 m_RenderCaps = FXRC_BIT_MASK;
426 BITMAP bitmap; 444 } else {
427 GetObject(hBitmap, sizeof bitmap, &bitmap); 445 m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK;
428 m_nBitsPerPixel = bitmap.bmBitsPixel; 446 }
429 m_Width = bitmap.bmWidth; 447 }
430 m_Height = abs(bitmap.bmHeight); 448 int CGdiDeviceDriver::GetDeviceCaps(int caps_id) {
431 hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap); 449 switch (caps_id) {
432 DeleteObject(hBitmap); 450 case FXDC_DEVICE_CLASS:
451 return m_DeviceClass;
452 case FXDC_PIXEL_WIDTH:
453 return m_Width;
454 case FXDC_PIXEL_HEIGHT:
455 return m_Height;
456 case FXDC_BITS_PIXEL:
457 return m_nBitsPerPixel;
458 case FXDC_RENDER_CAPS:
459 return m_RenderCaps;
460 }
461 return 0;
462 }
463 void* CGdiDeviceDriver::GetClipRgn() {
464 HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
465 if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
466 DeleteObject(hClipRgn);
467 hClipRgn = NULL;
468 }
469 return (void*)hClipRgn;
470 }
471 FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1,
472 const FX_RECT* pSrcRect,
473 int left,
474 int top,
475 void* pIccTransform) {
476 if (m_DeviceClass == FXDC_PRINTER) {
477 CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
478 if (pBitmap == NULL) {
479 return FALSE;
480 }
481 if ((pBitmap->IsCmykImage() || pIccTransform) &&
482 !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
483 return FALSE;
484 }
485 int width = pSrcRect->Width(), height = pSrcRect->Height();
486 int pitch = pBitmap->GetPitch();
487 LPBYTE pBuffer = pBitmap->GetBuffer();
488 CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
489 ((BITMAPINFOHEADER*)info.c_str())->biHeight *= -1;
490 FX_RECT dst_rect(0, 0, width, height);
491 dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
492 int dst_width = dst_rect.Width();
493 int dst_height = dst_rect.Height();
494 ::StretchDIBits(m_hDC, left, top, dst_width, dst_height, 0, 0, dst_width,
495 dst_height, pBuffer, (BITMAPINFO*)info.c_str(),
496 DIB_RGB_COLORS, SRCCOPY);
497 delete pBitmap;
498 } else {
499 CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
500 if ((pBitmap->IsCmykImage() || pIccTransform) &&
501 (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) ==
502 NULL) {
503 return FALSE;
504 }
505 int width = pSrcRect->Width(), height = pSrcRect->Height();
506 int pitch = pBitmap->GetPitch();
507 LPBYTE pBuffer = pBitmap->GetBuffer();
508 CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
509 ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left,
510 pBitmap->GetHeight() - pSrcRect->bottom, 0,
511 pBitmap->GetHeight(), pBuffer,
512 (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS);
513 if (pBitmap != pBitmap1) {
514 delete pBitmap;
515 }
516 }
517 return TRUE;
518 }
519 FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1,
520 int dest_left,
521 int dest_top,
522 int dest_width,
523 int dest_height,
524 FX_DWORD flags,
525 void* pIccTransform) {
526 CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
527 if (pBitmap == NULL || dest_width == 0 || dest_height == 0) {
528 return FALSE;
529 }
530 if ((pBitmap->IsCmykImage() || pIccTransform) &&
531 !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
532 return FALSE;
533 }
534 CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
535 if ((int64_t)abs(dest_width) * abs(dest_height) <
536 (int64_t)pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 ||
537 (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) {
538 SetStretchBltMode(m_hDC, HALFTONE);
539 } else {
540 SetStretchBltMode(m_hDC, COLORONCOLOR);
541 }
542 CFX_DIBitmap* pToStrechBitmap = pBitmap;
543 bool del = false;
544 if (m_DeviceClass == FXDC_PRINTER &&
545 ((int64_t)pBitmap->GetWidth() * pBitmap->GetHeight() >
546 (int64_t)abs(dest_width) * abs(dest_height))) {
547 pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height);
548 del = true;
549 }
550 CFX_ByteString toStrechBitmapInfo =
551 CFX_WindowsDIB::GetBitmapInfo(pToStrechBitmap);
552 ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, 0, 0,
553 pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(),
554 pToStrechBitmap->GetBuffer(),
555 (BITMAPINFO*)toStrechBitmapInfo.c_str(), DIB_RGB_COLORS,
556 SRCCOPY);
557 if (del) {
558 delete pToStrechBitmap;
559 }
560 return TRUE;
561 }
562 FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1,
563 int dest_left,
564 int dest_top,
565 int dest_width,
566 int dest_height,
567 FX_DWORD bitmap_color,
568 FX_DWORD flags,
569 int alpha_flag,
570 void* pIccTransform) {
571 CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
572 if (pBitmap == NULL || dest_width == 0 || dest_height == 0) {
573 return FALSE;
574 }
575 _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24),
576 pIccTransform);
577 int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
578 struct {
579 BITMAPINFOHEADER bmiHeader;
580 FX_DWORD bmiColors[2];
581 } bmi;
582 FXSYS_memset(&bmi.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
583 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
584 bmi.bmiHeader.biBitCount = 1;
585 bmi.bmiHeader.biCompression = BI_RGB;
586 bmi.bmiHeader.biHeight = -height;
587 bmi.bmiHeader.biPlanes = 1;
588 bmi.bmiHeader.biWidth = width;
589 if (m_nBitsPerPixel != 1) {
590 SetStretchBltMode(m_hDC, HALFTONE);
591 }
592 bmi.bmiColors[0] = 0xffffff;
593 bmi.bmiColors[1] = 0;
594
595 HBRUSH hPattern = CreateSolidBrush(bitmap_color & 0xffffff);
596 HBRUSH hOld = (HBRUSH)SelectObject(m_hDC, hPattern);
597
598 // In PDF, when image mask is 1, use device bitmap; when mask is 0, use brush
599 // bitmap.
600 // A complete list of the boolen operations is as follows:
601
602 /* P(bitmap_color) S(ImageMask) D(DeviceBitmap) Result
603 * 0 0 0 0
604 * 0 0 1 0
605 * 0 1 0 0
606 * 0 1 1 1
607 * 1 0 0 1
608 * 1 0 1 1
609 * 1 1 0 0
610 * 1 1 1 1
611 */
612 // The boolen codes is B8. Based on
613 // http://msdn.microsoft.com/en-us/library/aa932106.aspx, the ROP3 code is
614 // 0xB8074A
615
616 ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height, 0, 0,
617 width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi,
618 DIB_RGB_COLORS, 0xB8074A);
619
620 SelectObject(m_hDC, hOld);
621 DeleteObject(hPattern);
622
623 return TRUE;
624 }
625 FX_BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect) {
626 return ::GetClipBox(m_hDC, (RECT*)pRect);
627 }
628 FX_BOOL CGdiDeviceDriver::SetClipRgn(void* hRgn) {
629 ::SelectClipRgn(m_hDC, (HRGN)hRgn);
630 return TRUE;
631 }
632 static HPEN _CreatePen(const CFX_GraphStateData* pGraphState,
633 const CFX_AffineMatrix* pMatrix,
634 FX_DWORD argb) {
635 FX_FLOAT width;
636 FX_FLOAT scale = 1.f;
637 if (pMatrix)
638 scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b)
639 ? FXSYS_fabs(pMatrix->a)
640 : FXSYS_fabs(pMatrix->b);
641 if (pGraphState) {
642 width = scale * pGraphState->m_LineWidth;
643 } else {
644 width = 1.0f;
645 }
646 FX_DWORD PenStyle = PS_GEOMETRIC;
647 if (width < 1) {
648 width = 1;
649 }
650 if (pGraphState->m_DashCount) {
651 PenStyle |= PS_USERSTYLE;
652 } else {
653 PenStyle |= PS_SOLID;
654 }
655 switch (pGraphState->m_LineCap) {
656 case 0:
657 PenStyle |= PS_ENDCAP_FLAT;
658 break;
659 case 1:
660 PenStyle |= PS_ENDCAP_ROUND;
661 break;
662 case 2:
663 PenStyle |= PS_ENDCAP_SQUARE;
664 break;
665 }
666 switch (pGraphState->m_LineJoin) {
667 case 0:
668 PenStyle |= PS_JOIN_MITER;
669 break;
670 case 1:
671 PenStyle |= PS_JOIN_ROUND;
672 break;
673 case 2:
674 PenStyle |= PS_JOIN_BEVEL;
675 break;
676 }
677 int a;
678 FX_COLORREF rgb;
679 ArgbDecode(argb, a, rgb);
680 LOGBRUSH lb;
681 lb.lbColor = rgb;
682 lb.lbStyle = BS_SOLID;
683 lb.lbHatch = 0;
684 FX_DWORD* pDash = NULL;
685 if (pGraphState->m_DashCount) {
686 pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
687 for (int i = 0; i < pGraphState->m_DashCount; i++) {
688 pDash[i] = FXSYS_round(
689 pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i])
690 : pGraphState->m_DashArray[i]);
691 if (pDash[i] < 1) {
692 pDash[i] = 1;
693 }
694 }
695 }
696 HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb,
697 pGraphState->m_DashCount, (const DWORD*)pDash);
698 if (pDash) {
699 FX_Free(pDash);
700 }
701 return hPen;
702 }
703 static HBRUSH _CreateBrush(FX_DWORD argb) {
704 int a;
705 FX_COLORREF rgb;
706 ArgbDecode(argb, a, rgb);
707 return CreateSolidBrush(rgb);
708 }
709 static void _SetPathToDC(HDC hDC,
710 const CFX_PathData* pPathData,
711 const CFX_AffineMatrix* pMatrix) {
712 BeginPath(hDC);
713 int nPoints = pPathData->GetPointCount();
714 FX_PATHPOINT* pPoints = pPathData->GetPoints();
715 for (int i = 0; i < nPoints; i++) {
716 FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
717 if (pMatrix) {
718 pMatrix->Transform(posx, posy);
719 }
720 int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
721 int point_type = pPoints[i].m_Flag & FXPT_TYPE;
722 if (point_type == PT_MOVETO) {
723 MoveToEx(hDC, screen_x, screen_y, NULL);
724 } else if (point_type == PT_LINETO) {
725 if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY &&
726 pPoints[i].m_PointX == pPoints[i - 1].m_PointX) {
727 screen_x++;
728 }
729 LineTo(hDC, screen_x, screen_y);
730 } else if (point_type == PT_BEZIERTO) {
731 POINT lppt[3];
732 lppt[0].x = screen_x;
733 lppt[0].y = screen_y;
734 posx = pPoints[i + 1].m_PointX;
735 posy = pPoints[i + 1].m_PointY;
736 if (pMatrix) {
737 pMatrix->Transform(posx, posy);
738 }
739 lppt[1].x = FXSYS_round(posx);
740 lppt[1].y = FXSYS_round(posy);
741 posx = pPoints[i + 2].m_PointX;
742 posy = pPoints[i + 2].m_PointY;
743 if (pMatrix) {
744 pMatrix->Transform(posx, posy);
745 }
746 lppt[2].x = FXSYS_round(posx);
747 lppt[2].y = FXSYS_round(posy);
748 PolyBezierTo(hDC, lppt, 3);
749 i += 2;
750 }
751 if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
752 CloseFigure(hDC);
753 }
754 }
755 EndPath(hDC);
756 }
757 void CGdiDeviceDriver::DrawLine(FX_FLOAT x1,
758 FX_FLOAT y1,
759 FX_FLOAT x2,
760 FX_FLOAT y2) {
761 int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) |
762 ((y1 > m_Height) << 3);
763 int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) |
764 ((y2 > m_Height) << 3);
765 if (flag1 & flag2) {
766 return;
767 }
768 if (flag1 || flag2) {
769 agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width),
770 (FX_FLOAT)(m_Height));
771 FX_FLOAT x[2], y[2];
772 int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
773 if (np == 0) {
774 return;
775 }
776 if (np == 1) {
777 x2 = x[0];
778 y2 = y[0];
433 } else { 779 } else {
434 m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL); 780 x1 = x[0];
435 m_Width = ::GetDeviceCaps(m_hDC, HORZRES); 781 y1 = y[0];
436 m_Height = ::GetDeviceCaps(m_hDC, VERTRES); 782 x2 = x[np - 1];
437 } 783 y2 = y[np - 1];
438 if (m_DeviceClass != FXDC_DISPLAY) { 784 }
439 m_RenderCaps = FXRC_BIT_MASK; 785 }
440 } else { 786 MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
441 m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK; 787 LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
442 } 788 }
443 } 789 static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix) {
444 int CGdiDeviceDriver::GetDeviceCaps(int caps_id) 790 return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 &&
445 { 791 pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
446 switch (caps_id) {
447 case FXDC_DEVICE_CLASS:
448 return m_DeviceClass;
449 case FXDC_PIXEL_WIDTH:
450 return m_Width;
451 case FXDC_PIXEL_HEIGHT:
452 return m_Height;
453 case FXDC_BITS_PIXEL:
454 return m_nBitsPerPixel;
455 case FXDC_RENDER_CAPS:
456 return m_RenderCaps;
457 }
458 return 0;
459 }
460 void* CGdiDeviceDriver::GetClipRgn()
461 {
462 HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
463 if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
464 DeleteObject(hClipRgn);
465 hClipRgn = NULL;
466 }
467 return (void*)hClipRgn;
468 }
469 FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_R ECT* pSrcRect, int left, int top, void* pIccTransform)
470 {
471 if (m_DeviceClass == FXDC_PRINTER) {
472 CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
473 if (pBitmap == NULL) {
474 return FALSE;
475 }
476 if ((pBitmap->IsCmykImage() || pIccTransform) &&
477 !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
478 return FALSE;
479 }
480 int width = pSrcRect->Width(), height = pSrcRect->Height();
481 int pitch = pBitmap->GetPitch();
482 LPBYTE pBuffer = pBitmap->GetBuffer();
483 CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
484 ((BITMAPINFOHEADER*)info.c_str())->biHeight *= -1;
485 FX_RECT dst_rect(0, 0, width, height);
486 dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
487 int dst_width = dst_rect.Width();
488 int dst_height = dst_rect.Height();
489 ::StretchDIBits(m_hDC, left, top, dst_width, dst_height,
490 0, 0, dst_width, dst_height, pBuffer, (BITMAPINFO*)info.c_str(), DIB _RGB_COLORS, SRCCOPY);
491 delete pBitmap;
492 } else {
493 CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
494 if ((pBitmap->IsCmykImage() || pIccTransform) &&
495 (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform) ) == NULL) {
496 return FALSE;
497 }
498 int width = pSrcRect->Width(), height = pSrcRect->Height();
499 int pitch = pBitmap->GetPitch();
500 LPBYTE pBuffer = pBitmap->GetBuffer();
501 CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
502 ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBi tmap->GetHeight() - pSrcRect->bottom,
503 0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)info.c_str(), DIB_RGB _COLORS);
504 if (pBitmap != pBitmap1) {
505 delete pBitmap;
506 }
507 }
508 return TRUE;
509 }
510 FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int de st_left, int dest_top,
511 int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform)
512 {
513 CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
514 if (pBitmap == NULL || dest_width == 0 || dest_height == 0) {
515 return FALSE;
516 }
517 if ((pBitmap->IsCmykImage() || pIccTransform) &&
518 !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
519 return FALSE;
520 }
521 CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
522 if ((int64_t)abs(dest_width) * abs(dest_height) < (int64_t)pBitmap1->GetWidt h() * pBitmap1->GetHeight() * 4 ||
523 (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) {
524 SetStretchBltMode(m_hDC, HALFTONE);
525 } else {
526 SetStretchBltMode(m_hDC, COLORONCOLOR);
527 }
528 CFX_DIBitmap* pToStrechBitmap = pBitmap;
529 bool del = false;
530 if (m_DeviceClass == FXDC_PRINTER && ((int64_t)pBitmap->GetWidth() * pBitmap ->GetHeight() > (int64_t)abs(dest_width) * abs(dest_height))) {
531 pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height);
532 del = true;
533 }
534 CFX_ByteString toStrechBitmapInfo = CFX_WindowsDIB::GetBitmapInfo(pToStrechB itmap);
535 ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
536 0, 0, pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeigh t(), pToStrechBitmap->GetBuffer(),
537 (BITMAPINFO*)toStrechBitmapInfo.c_str(), DIB_RGB_COLORS, SRC COPY);
538 if (del) {
539 delete pToStrechBitmap;
540 }
541 return TRUE;
542 }
543 FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int d est_left, int dest_top,
544 int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
545 int alpha_flag, void* pIccTransform)
546 {
547 CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
548 if (pBitmap == NULL || dest_width == 0 || dest_height == 0) {
549 return FALSE;
550 }
551 _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), pIccTransfor m);
552 int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
553 struct {
554 BITMAPINFOHEADER bmiHeader;
555 FX_DWORD bmiColors[2];
556 } bmi;
557 FXSYS_memset(&bmi.bmiHeader, 0, sizeof (BITMAPINFOHEADER));
558 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
559 bmi.bmiHeader.biBitCount = 1;
560 bmi.bmiHeader.biCompression = BI_RGB;
561 bmi.bmiHeader.biHeight = -height;
562 bmi.bmiHeader.biPlanes = 1;
563 bmi.bmiHeader.biWidth = width;
564 if (m_nBitsPerPixel != 1) {
565 SetStretchBltMode(m_hDC, HALFTONE);
566 }
567 bmi.bmiColors[0] = 0xffffff;
568 bmi.bmiColors[1] = 0;
569
570 HBRUSH hPattern = CreateSolidBrush(bitmap_color & 0xffffff);
571 HBRUSH hOld = (HBRUSH)SelectObject(m_hDC, hPattern);
572
573
574 // In PDF, when image mask is 1, use device bitmap; when mask is 0, use brus h bitmap.
575 // A complete list of the boolen operations is as follows:
576
577 /* P(bitmap_color) S(ImageMask) D(DeviceBitmap) Result
578 * 0 0 0 0
579 * 0 0 1 0
580 * 0 1 0 0
581 * 0 1 1 1
582 * 1 0 0 1
583 * 1 0 1 1
584 * 1 1 0 0
585 * 1 1 1 1
586 */
587 // The boolen codes is B8. Based on http://msdn.microsoft.com/en-us/library/ aa932106.aspx, the ROP3 code is 0xB8074A
588
589 ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
590 0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi , DIB_RGB_COLORS, 0xB8074A);
591
592 SelectObject(m_hDC, hOld);
593 DeleteObject(hPattern);
594
595 return TRUE;
596 }
597 FX_BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect)
598 {
599 return ::GetClipBox(m_hDC, (RECT*)pRect);
600 }
601 FX_BOOL CGdiDeviceDriver::SetClipRgn(void* hRgn)
602 {
603 ::SelectClipRgn(m_hDC, (HRGN)hRgn);
604 return TRUE;
605 }
606 static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMa trix* pMatrix, FX_DWORD argb)
607 {
608 FX_FLOAT width;
609 FX_FLOAT scale = 1.f;
610 if (pMatrix)
611 scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ?
612 FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b);
613 if (pGraphState) {
614 width = scale * pGraphState->m_LineWidth;
615 } else {
616 width = 1.0f;
617 }
618 FX_DWORD PenStyle = PS_GEOMETRIC;
619 if (width < 1) {
620 width = 1;
621 }
622 if(pGraphState->m_DashCount) {
623 PenStyle |= PS_USERSTYLE;
624 } else {
625 PenStyle |= PS_SOLID;
626 }
627 switch(pGraphState->m_LineCap) {
628 case 0:
629 PenStyle |= PS_ENDCAP_FLAT;
630 break;
631 case 1:
632 PenStyle |= PS_ENDCAP_ROUND;
633 break;
634 case 2:
635 PenStyle |= PS_ENDCAP_SQUARE;
636 break;
637 }
638 switch(pGraphState->m_LineJoin) {
639 case 0:
640 PenStyle |= PS_JOIN_MITER;
641 break;
642 case 1:
643 PenStyle |= PS_JOIN_ROUND;
644 break;
645 case 2:
646 PenStyle |= PS_JOIN_BEVEL;
647 break;
648 }
649 int a;
650 FX_COLORREF rgb;
651 ArgbDecode(argb, a, rgb);
652 LOGBRUSH lb;
653 lb.lbColor = rgb;
654 lb.lbStyle = BS_SOLID;
655 lb.lbHatch = 0;
656 FX_DWORD* pDash = NULL;
657 if (pGraphState->m_DashCount) {
658 pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
659 for (int i = 0; i < pGraphState->m_DashCount; i ++) {
660 pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphSt ate->m_DashArray[i]) : pGraphState->m_DashArray[i]);
661 if (pDash[i] < 1) {
662 pDash[i] = 1;
663 }
664 }
665 }
666 HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphStat e->m_DashCount, (const DWORD*)pDash);
667 if (pDash) {
668 FX_Free(pDash);
669 }
670 return hPen;
671 }
672 static HBRUSH _CreateBrush(FX_DWORD argb)
673 {
674 int a;
675 FX_COLORREF rgb;
676 ArgbDecode(argb, a, rgb);
677 return CreateSolidBrush(rgb);
678 }
679 static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_Affin eMatrix* pMatrix)
680 {
681 BeginPath(hDC);
682 int nPoints = pPathData->GetPointCount();
683 FX_PATHPOINT* pPoints = pPathData->GetPoints();
684 for(int i = 0; i < nPoints; i++) {
685 FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
686 if (pMatrix) {
687 pMatrix->Transform(posx, posy);
688 }
689 int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
690 int point_type = pPoints[i].m_Flag & FXPT_TYPE;
691 if(point_type == PT_MOVETO) {
692 MoveToEx(hDC, screen_x, screen_y, NULL);
693 } else if(point_type == PT_LINETO) {
694 if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_P ointX == pPoints[i - 1].m_PointX) {
695 screen_x ++;
696 }
697 LineTo(hDC, screen_x, screen_y);
698 } else if(point_type == PT_BEZIERTO) {
699 POINT lppt[3];
700 lppt[0].x = screen_x;
701 lppt[0].y = screen_y;
702 posx = pPoints[i + 1].m_PointX;
703 posy = pPoints[i + 1].m_PointY;
704 if (pMatrix) {
705 pMatrix->Transform(posx, posy);
706 }
707 lppt[1].x = FXSYS_round(posx);
708 lppt[1].y = FXSYS_round(posy);
709 posx = pPoints[i + 2].m_PointX;
710 posy = pPoints[i + 2].m_PointY;
711 if (pMatrix) {
712 pMatrix->Transform(posx, posy);
713 }
714 lppt[2].x = FXSYS_round(posx);
715 lppt[2].y = FXSYS_round(posy);
716 PolyBezierTo(hDC, lppt, 3);
717 i += 2;
718 }
719 if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
720 CloseFigure(hDC);
721 }
722 }
723 EndPath(hDC);
724 }
725 void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
726 {
727 int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_He ight) << 3);
728 int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_He ight) << 3);
729 if (flag1 & flag2) {
730 return;
731 }
732 if (flag1 || flag2) {
733 agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT )(m_Height));
734 FX_FLOAT x[2], y[2];
735 int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
736 if (np == 0) {
737 return;
738 }
739 if (np == 1) {
740 x2 = x[0];
741 y2 = y[0];
742 } else {
743 x1 = x[0];
744 y1 = y[0];
745 x2 = x[np - 1];
746 y2 = y[np - 1];
747 }
748 }
749 MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
750 LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
751 }
752 static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix)
753 {
754 return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
755 } 792 }
756 FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData, 793 FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
757 const CFX_AffineMatrix* pMatrix, 794 const CFX_AffineMatrix* pMatrix,
758 const CFX_GraphStateData* pGraphState, 795 const CFX_GraphStateData* pGraphState,
759 FX_DWORD fill_color, 796 FX_DWORD fill_color,
760 FX_DWORD stroke_color, 797 FX_DWORD stroke_color,
761 int fill_mode, 798 int fill_mode,
762 int alpha_flag, 799 int alpha_flag,
763 void* pIccTransform, 800 void* pIccTransform,
764 int» blend_type 801 int blend_type) {
765 ) 802 if (blend_type != FXDIB_BLEND_NORMAL) {
766 { 803 return FALSE;
767 if (blend_type != FXDIB_BLEND_NORMAL) { 804 }
768 return FALSE; 805 _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
769 } 806 _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
770 _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform); 807 CWin32Platform* pPlatform =
771 _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform); 808 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
772 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor mData(); 809 if ((pGraphState == NULL || stroke_color == 0) &&
773 if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.I sAvailable()) { 810 !pPlatform->m_GdiplusExt.IsAvailable()) {
774 CFX_FloatRect bbox_f = pPathData->GetBoundingBox(); 811 CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
775 if (pMatrix) { 812 if (pMatrix) {
776 bbox_f.Transform(pMatrix); 813 bbox_f.Transform(pMatrix);
814 }
815 FX_RECT bbox = bbox_f.GetInnerRect();
816 if (bbox.Width() <= 0) {
817 return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top),
818 (FX_FLOAT)(bbox.left),
819 (FX_FLOAT)(bbox.bottom + 1), fill_color,
820 alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
821 } else if (bbox.Height() <= 0) {
822 return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top),
823 (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top),
824 fill_color, alpha_flag, pIccTransform,
825 FXDIB_BLEND_NORMAL);
826 }
827 }
828 int fill_alpha = FXARGB_A(fill_color);
829 int stroke_alpha = FXARGB_A(stroke_color);
830 FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) ||
831 (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState);
832 if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) {
833 return FALSE;
834 }
835 if (pPlatform->m_GdiplusExt.IsAvailable()) {
836 if (bDrawAlpha ||
837 ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) ||
838 (pGraphState && pGraphState->m_DashCount))) {
839 if (!((NULL == pMatrix || _MatrixNoScaled(pMatrix)) && pGraphState &&
840 pGraphState->m_LineWidth == 1.f &&
841 (pPathData->GetPointCount() == 5 ||
842 pPathData->GetPointCount() == 4) &&
843 pPathData->IsRect())) {
844 if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix,
845 pGraphState, fill_color,
846 stroke_color, fill_mode)) {
847 return TRUE;
777 } 848 }
778 FX_RECT bbox = bbox_f.GetInnerRect(); 849 }
779 if (bbox.Width() <= 0) { 850 }
780 return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color, 851 }
781 alpha_flag, pIccTransform, FXDIB_BLEND_NORMA L); 852 int old_fill_mode = fill_mode;
782 } else if (bbox.Height() <= 0) { 853 fill_mode &= 3;
783 return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color, 854 HPEN hPen = NULL;
784 alpha_flag, pIccTransform, FXDIB_BLEND_NORMA L); 855 HBRUSH hBrush = NULL;
856 if (pGraphState && stroke_alpha) {
857 SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
858 hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
859 hPen = (HPEN)SelectObject(m_hDC, hPen);
860 }
861 if (fill_mode && fill_alpha) {
862 SetPolyFillMode(m_hDC, fill_mode);
863 hBrush = _CreateBrush(fill_color);
864 hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
865 }
866 if (pPathData->GetPointCount() == 2 && pGraphState &&
867 pGraphState->m_DashCount) {
868 FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
869 if (pMatrix) {
870 pMatrix->Transform(x1, y1);
871 }
872 FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
873 if (pMatrix) {
874 pMatrix->Transform(x2, y2);
875 }
876 DrawLine(x1, y1, x2, y2);
877 } else {
878 _SetPathToDC(m_hDC, pPathData, pMatrix);
879 if (pGraphState && stroke_alpha) {
880 if (fill_mode && fill_alpha) {
881 if (old_fill_mode & FX_FILL_TEXT_MODE) {
882 StrokeAndFillPath(m_hDC);
883 } else {
884 FillPath(m_hDC);
885 _SetPathToDC(m_hDC, pPathData, pMatrix);
886 StrokePath(m_hDC);
785 } 887 }
786 } 888 } else {
787 int fill_alpha = FXARGB_A(fill_color); 889 StrokePath(m_hDC);
788 int stroke_alpha = FXARGB_A(stroke_color); 890 }
789 FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState); 891 } else if (fill_mode && fill_alpha) {
790 if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) { 892 FillPath(m_hDC);
791 return FALSE; 893 }
792 } 894 }
793 if (pPlatform->m_GdiplusExt.IsAvailable()) { 895 if (hPen) {
794 if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFIL L_FULLCOVER)) || (pGraphState && pGraphState->m_DashCount))) {
795 if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) &&
796 pGraphState && pGraphState->m_LineWidth == 1.f &&
797 (pPathData->GetPointCount() == 5 || pPathData->GetPointCount () == 4) &&
798 pPathData->IsRect()) ) {
799 if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) {
800 return TRUE;
801 }
802 }
803 }
804 }
805 int old_fill_mode = fill_mode;
806 fill_mode &= 3;
807 HPEN hPen = NULL;
808 HBRUSH hBrush = NULL;
809 if (pGraphState && stroke_alpha) {
810 SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
811 hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
812 hPen = (HPEN)SelectObject(m_hDC, hPen);
813 }
814 if (fill_mode && fill_alpha) {
815 SetPolyFillMode(m_hDC, fill_mode);
816 hBrush = _CreateBrush(fill_color);
817 hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
818 }
819 if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCou nt) {
820 FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
821 if (pMatrix) {
822 pMatrix->Transform(x1, y1);
823 }
824 FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
825 if (pMatrix) {
826 pMatrix->Transform(x2, y2);
827 }
828 DrawLine(x1, y1, x2, y2);
829 } else {
830 _SetPathToDC(m_hDC, pPathData, pMatrix);
831 if (pGraphState && stroke_alpha) {
832 if (fill_mode && fill_alpha) {
833 if (old_fill_mode & FX_FILL_TEXT_MODE) {
834 StrokeAndFillPath(m_hDC);
835 } else {
836 FillPath(m_hDC);
837 _SetPathToDC(m_hDC, pPathData, pMatrix);
838 StrokePath(m_hDC);
839 }
840 } else {
841 StrokePath(m_hDC);
842 }
843 } else if (fill_mode && fill_alpha) {
844 FillPath(m_hDC);
845 }
846 }
847 if (hPen) {
848 hPen = (HPEN)SelectObject(m_hDC, hPen);
849 DeleteObject(hPen);
850 }
851 if (hBrush) {
852 hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
853 DeleteObject(hBrush);
854 }
855 return TRUE;
856 }
857 FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, in t alpha_flag, void* pIccTransform, int blend_type)
858 {
859 if (blend_type != FXDIB_BLEND_NORMAL) {
860 return FALSE;
861 }
862 _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
863 int alpha;
864 FX_COLORREF rgb;
865 ArgbDecode(fill_color, alpha, rgb);
866 if (alpha == 0) {
867 return TRUE;
868 }
869 if (alpha < 255) {
870 return FALSE;
871 }
872 HBRUSH hBrush = CreateSolidBrush(rgb);
873 ::FillRect(m_hDC, (RECT*)pRect, hBrush);
874 DeleteObject(hBrush);
875 return TRUE;
876 }
877 FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
878 const CFX_AffineMatrix* pMatrix,
879 int fill_mode
880 )
881 {
882 if (pPathData->GetPointCount() == 5) {
883 CFX_FloatRect rectf;
884 if (pPathData->IsRect(pMatrix, &rectf)) {
885 FX_RECT rect = rectf.GetOutterRect();
886 IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.botto m);
887 return TRUE;
888 }
889 }
890 _SetPathToDC(m_hDC, pPathData, pMatrix);
891 SetPolyFillMode(m_hDC, fill_mode & 3);
892 SelectClipPath(m_hDC, RGN_AND);
893 return TRUE;
894 }
895 FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
896 const CFX_AffineMatrix* pMatrix,
897 const CFX_GraphStateData* pGraphState
898 )
899 {
900 HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
901 hPen = (HPEN)SelectObject(m_hDC, hPen);
902 _SetPathToDC(m_hDC, pPathData, pMatrix);
903 WidenPath(m_hDC);
904 SetPolyFillMode(m_hDC, WINDING);
905 FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
906 hPen = (HPEN)SelectObject(m_hDC, hPen); 896 hPen = (HPEN)SelectObject(m_hDC, hPen);
907 DeleteObject(hPen); 897 DeleteObject(hPen);
908 return ret; 898 }
909 } 899 if (hBrush) {
910 FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2 , FX_FLOAT y2, FX_DWORD color, 900 hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
911 int alpha_flag, void* pIccTransform, int» blend_type) 901 DeleteObject(hBrush);
912 { 902 }
913 if (blend_type != FXDIB_BLEND_NORMAL) { 903 return TRUE;
904 }
905 FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect,
906 FX_DWORD fill_color,
907 int alpha_flag,
908 void* pIccTransform,
909 int blend_type) {
910 if (blend_type != FXDIB_BLEND_NORMAL) {
911 return FALSE;
912 }
913 _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
914 int alpha;
915 FX_COLORREF rgb;
916 ArgbDecode(fill_color, alpha, rgb);
917 if (alpha == 0) {
918 return TRUE;
919 }
920 if (alpha < 255) {
921 return FALSE;
922 }
923 HBRUSH hBrush = CreateSolidBrush(rgb);
924 ::FillRect(m_hDC, (RECT*)pRect, hBrush);
925 DeleteObject(hBrush);
926 return TRUE;
927 }
928 FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
929 const CFX_AffineMatrix* pMatrix,
930 int fill_mode) {
931 if (pPathData->GetPointCount() == 5) {
932 CFX_FloatRect rectf;
933 if (pPathData->IsRect(pMatrix, &rectf)) {
934 FX_RECT rect = rectf.GetOutterRect();
935 IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom);
936 return TRUE;
937 }
938 }
939 _SetPathToDC(m_hDC, pPathData, pMatrix);
940 SetPolyFillMode(m_hDC, fill_mode & 3);
941 SelectClipPath(m_hDC, RGN_AND);
942 return TRUE;
943 }
944 FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(
945 const CFX_PathData* pPathData,
946 const CFX_AffineMatrix* pMatrix,
947 const CFX_GraphStateData* pGraphState) {
948 HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
949 hPen = (HPEN)SelectObject(m_hDC, hPen);
950 _SetPathToDC(m_hDC, pPathData, pMatrix);
951 WidenPath(m_hDC);
952 SetPolyFillMode(m_hDC, WINDING);
953 FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
954 hPen = (HPEN)SelectObject(m_hDC, hPen);
955 DeleteObject(hPen);
956 return ret;
957 }
958 FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
959 FX_FLOAT y1,
960 FX_FLOAT x2,
961 FX_FLOAT y2,
962 FX_DWORD color,
963 int alpha_flag,
964 void* pIccTransform,
965 int blend_type) {
966 if (blend_type != FXDIB_BLEND_NORMAL) {
967 return FALSE;
968 }
969 _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
970 int a;
971 FX_COLORREF rgb;
972 ArgbDecode(color, a, rgb);
973 if (a == 0) {
974 return TRUE;
975 }
976 HPEN hPen = CreatePen(PS_SOLID, 1, rgb);
977 hPen = (HPEN)SelectObject(m_hDC, hPen);
978 MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
979 LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
980 hPen = (HPEN)SelectObject(m_hDC, hPen);
981 DeleteObject(hPen);
982 return TRUE;
983 }
984 FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(void* pRgn) {
985 DeleteObject((HGDIOBJ)pRgn);
986 return TRUE;
987 }
988 CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC)
989 : CGdiDeviceDriver(hDC, FXDC_DISPLAY) {
990 CWin32Platform* pPlatform =
991 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
992 if (pPlatform->m_GdiplusExt.IsAvailable()) {
993 m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE;
994 }
995 }
996 FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap,
997 int left,
998 int top,
999 void* pIccTransform,
1000 FX_BOOL bDEdge) {
1001 FX_BOOL ret = FALSE;
1002 int width = pBitmap->GetWidth();
1003 int height = pBitmap->GetHeight();
1004 HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height);
1005 HDC hDCMemory = CreateCompatibleDC(m_hDC);
1006 HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp);
1007 BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY);
1008 SelectObject(hDCMemory, holdbmp);
1009 BITMAPINFO bmi;
1010 FXSYS_memset(&bmi, 0, sizeof bmi);
1011 bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
1012 bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
1013 bmi.bmiHeader.biHeight = -height;
1014 bmi.bmiHeader.biPlanes = 1;
1015 bmi.bmiHeader.biWidth = width;
1016 if (!CFX_GEModule::Get()->GetCodecModule() ||
1017 !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
1018 pIccTransform = NULL;
1019 }
1020 if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() &&
1021 pIccTransform == NULL) {
1022 ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi,
1023 DIB_RGB_COLORS) == height;
1024 } else {
1025 CFX_DIBitmap bitmap;
1026 if (bitmap.Create(width, height, FXDIB_Rgb)) {
1027 bmi.bmiHeader.biBitCount = 24;
1028 ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi,
1029 DIB_RGB_COLORS);
1030 ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0,
1031 pIccTransform);
1032 } else {
1033 ret = FALSE;
1034 }
1035 }
1036 if (pBitmap->HasAlpha() && ret) {
1037 pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
1038 }
1039 DeleteObject(hbmp);
1040 DeleteObject(hDCMemory);
1041 return ret;
1042 }
1043 FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource,
1044 FX_DWORD color,
1045 const FX_RECT* pSrcRect,
1046 int left,
1047 int top,
1048 int blend_type,
1049 int alpha_flag,
1050 void* pIccTransform) {
1051 ASSERT(blend_type == FXDIB_BLEND_NORMAL);
1052 if (pSource->IsAlphaMask()) {
1053 int width = pSource->GetWidth(), height = pSource->GetHeight();
1054 int alpha = FXGETFLAG_COLORTYPE(alpha_flag)
1055 ? FXGETFLAG_ALPHA_FILL(alpha_flag)
1056 : FXARGB_A(color);
1057 FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255;
1058 if (!bGDI) {
1059 CFX_DIBitmap background;
1060 if (!background.Create(width, height, FXDIB_Rgb32) ||
1061 !GetDIBits(&background, left, top, NULL) ||
1062 !background.CompositeMask(0, 0, width, height, pSource, color, 0, 0,
1063 FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag,
1064 pIccTransform)) {
914 return FALSE; 1065 return FALSE;
915 } 1066 }
916 _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform); 1067 FX_RECT src_rect(0, 0, width, height);
917 int a; 1068 return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL,
918 FX_COLORREF rgb; 1069 0, NULL);
919 ArgbDecode(color, a, rgb); 1070 }
920 if (a == 0) { 1071 FX_RECT clip_rect(left, top, left + pSrcRect->Width(),
921 return TRUE; 1072 top + pSrcRect->Height());
922 } 1073 return StretchDIBits(pSource, color, left - pSrcRect->left,
923 HPEN hPen = CreatePen(PS_SOLID, 1, rgb); 1074 top - pSrcRect->top, width, height, &clip_rect, 0,
924 hPen = (HPEN)SelectObject(m_hDC, hPen); 1075 alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
925 MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL); 1076 }
926 LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2)); 1077 int width = pSrcRect->Width(), height = pSrcRect->Height();
927 hPen = (HPEN)SelectObject(m_hDC, hPen); 1078 if (pSource->HasAlpha()) {
928 DeleteObject(hPen); 1079 CFX_DIBitmap bitmap;
1080 if (!bitmap.Create(width, height, FXDIB_Rgb) ||
1081 !GetDIBits(&bitmap, left, top, NULL) ||
1082 !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left,
1083 pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE,
1084 pIccTransform)) {
1085 return FALSE;
1086 }
1087 FX_RECT src_rect(0, 0, width, height);
1088 return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0,
1089 NULL);
1090 }
1091 CFX_DIBExtractor temp(pSource);
1092 CFX_DIBitmap* pBitmap = temp;
1093 if (pBitmap) {
1094 return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
1095 }
1096 return FALSE;
1097 }
1098 FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource,
1099 FX_DWORD color,
1100 int dest_left,
1101 int dest_top,
1102 int dest_width,
1103 int dest_height,
1104 const FX_RECT* pClipRect,
1105 int render_flags,
1106 int alpha_flag,
1107 void* pIccTransform,
1108 int blend_type) {
1109 FX_RECT bitmap_clip = *pClipRect;
1110 if (dest_width < 0) {
1111 dest_left += dest_width;
1112 }
1113 if (dest_height < 0) {
1114 dest_top += dest_height;
1115 }
1116 bitmap_clip.Offset(-dest_left, -dest_top);
1117 CFX_DIBitmap* pStretched =
1118 pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip);
1119 if (pStretched == NULL) {
929 return TRUE; 1120 return TRUE;
930 } 1121 }
931 FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(void* pRgn) 1122 FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
932 { 1123 FX_BOOL ret =
933 DeleteObject((HGDIOBJ)pRgn); 1124 SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top,
934 return TRUE; 1125 FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
935 } 1126 delete pStretched;
936 CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_DISPL AY) 1127 return ret;
937 { 1128 }
938 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor mData(); 1129 FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource,
939 if (pPlatform->m_GdiplusExt.IsAvailable()) { 1130 FX_DWORD color,
940 m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE; 1131 int dest_left,
941 } 1132 int dest_top,
942 } 1133 int dest_width,
943 FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, v oid* pIccTransform, FX_BOOL bDEdge) 1134 int dest_height,
944 { 1135 const FX_RECT* pClipRect,
945 FX_BOOL ret = FALSE; 1136 FX_DWORD flags,
946 int width = pBitmap->GetWidth(); 1137 int alpha_flag,
947 int height = pBitmap->GetHeight(); 1138 void* pIccTransform,
948 HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height); 1139 int blend_type) {
949 HDC hDCMemory = CreateCompatibleDC(m_hDC); 1140 ASSERT(pSource != NULL && pClipRect != NULL);
950 HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp); 1141 if (flags || dest_width > 10000 || dest_width < -10000 ||
951 BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY); 1142 dest_height > 10000 || dest_height < -10000) {
952 SelectObject(hDCMemory, holdbmp); 1143 return UseFoxitStretchEngine(pSource, color, dest_left, dest_top,
953 BITMAPINFO bmi; 1144 dest_width, dest_height, pClipRect, flags,
954 FXSYS_memset(&bmi, 0, sizeof bmi); 1145 alpha_flag, pIccTransform, blend_type);
955 bmi.bmiHeader.biSize = sizeof bmi.bmiHeader; 1146 }
956 bmi.bmiHeader.biBitCount = pBitmap->GetBPP(); 1147 if (pSource->IsAlphaMask()) {
957 bmi.bmiHeader.biHeight = -height; 1148 FX_RECT image_rect;
958 bmi.bmiHeader.biPlanes = 1; 1149 image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width;
959 bmi.bmiHeader.biWidth = width; 1150 image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left;
960 if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodec Module()->GetIccModule()) { 1151 image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height;
961 pIccTransform = NULL; 1152 image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top;
962 } 1153 FX_RECT clip_rect = image_rect;
963 if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NUL L) { 1154 clip_rect.Intersect(*pClipRect);
964 ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi , DIB_RGB_COLORS) == height; 1155 clip_rect.Offset(-image_rect.left, -image_rect.top);
965 } else { 1156 int clip_width = clip_rect.Width(), clip_height = clip_rect.Height();
966 CFX_DIBitmap bitmap; 1157 CFX_DIBitmap* pStretched =
967 if (bitmap.Create(width, height, FXDIB_Rgb)) { 1158 pSource->StretchTo(dest_width, dest_height, flags, &clip_rect);
968 bmi.bmiHeader.biBitCount = 24;
969 ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DI B_RGB_COLORS);
970 ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pI ccTransform);
971 } else {
972 ret = FALSE;
973 }
974 }
975 if (pBitmap->HasAlpha() && ret) {
976 pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
977 }
978 DeleteObject(hbmp);
979 DeleteObject(hDCMemory);
980 return ret;
981 }
982 FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD colo r, const FX_RECT* pSrcRect, int left, int top, int blend_type,
983 int alpha_flag, void* pIccTransform)
984 {
985 ASSERT(blend_type == FXDIB_BLEND_NORMAL);
986 if (pSource->IsAlphaMask()) {
987 int width = pSource->GetWidth(), height = pSource->GetHeight();
988 int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha _flag) : FXARGB_A(color);
989 FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255;
990 if (!bGDI) {
991 CFX_DIBitmap background;
992 if (!background.Create(width, height, FXDIB_Rgb32) ||
993 !GetDIBits(&background, left, top, NULL) ||
994 !background.CompositeMask(0, 0, width, height, pSource, color,
995 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE,
996 alpha_flag, pIccTransform)) {
997 return FALSE;
998 }
999 FX_RECT src_rect(0, 0, width, height);
1000 return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_N ORMAL, 0, NULL);
1001 }
1002 FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->H eight());
1003 return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRe ct->top, width, height,
1004 &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLE ND_NORMAL);
1005 }
1006 int width = pSrcRect->Width(), height = pSrcRect->Height();
1007 if (pSource->HasAlpha()) {
1008 CFX_DIBitmap bitmap;
1009 if (!bitmap.Create(width, height, FXDIB_Rgb) ||
1010 !GetDIBits(&bitmap, left, top, NULL) ||
1011 !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left , pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) {
1012 return FALSE;
1013 }
1014 FX_RECT src_rect(0, 0, width, height);
1015 return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0 , NULL);
1016 }
1017 CFX_DIBExtractor temp(pSource);
1018 CFX_DIBitmap* pBitmap = temp;
1019 if (pBitmap) {
1020 return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
1021 }
1022 return FALSE;
1023 }
1024 FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, F X_DWORD color, int dest_left, int dest_top,
1025 int dest_width, int dest_height, const FX_RECT* pClipRect, int render_fl ags,
1026 int alpha_flag, void* pIccTransform, int blend_type)
1027 {
1028 FX_RECT bitmap_clip = *pClipRect;
1029 if (dest_width < 0) {
1030 dest_left += dest_width;
1031 }
1032 if (dest_height < 0) {
1033 dest_top += dest_height;
1034 }
1035 bitmap_clip.Offset(-dest_left, -dest_top);
1036 CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, rende r_flags, &bitmap_clip);
1037 if (pStretched == NULL) { 1159 if (pStretched == NULL) {
1038 return TRUE; 1160 return TRUE;
1039 } 1161 }
1040 FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight()); 1162 CFX_DIBitmap background;
1041 FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClip Rect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform); 1163 if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) ||
1164 !GetDIBits(&background, image_rect.left + clip_rect.left,
1165 image_rect.top + clip_rect.top, NULL) ||
1166 !background.CompositeMask(0, 0, clip_width, clip_height, pStretched,
1167 color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE,
1168 alpha_flag, pIccTransform)) {
1169 delete pStretched;
1170 return FALSE;
1171 }
1172 FX_RECT src_rect(0, 0, clip_width, clip_height);
1173 FX_BOOL ret =
1174 SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left,
1175 image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL);
1042 delete pStretched; 1176 delete pStretched;
1043 return ret; 1177 return ret;
1044 } 1178 }
1045 FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top, 1179 if (pSource->HasAlpha()) {
1046 int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flag s, 1180 CWin32Platform* pPlatform =
1047 int alpha_flag, void* pIccTransform, int blend_type) 1181 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
1048 { 1182 if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL &&
1049 ASSERT(pSource != NULL && pClipRect != NULL); 1183 !pSource->IsCmykImage()) {
1050 if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 1000 0 || dest_height < -10000) { 1184 CFX_DIBExtractor temp(pSource);
1051 return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_w idth, dest_height, 1185 CFX_DIBitmap* pBitmap = temp;
1052 pClipRect, flags, alpha_flag, pIccTransform , blend_type); 1186 if (pBitmap == NULL) {
1053 } 1187 return FALSE;
1054 if (pSource->IsAlphaMask()) { 1188 }
1055 FX_RECT image_rect; 1189 return pPlatform->m_GdiplusExt.StretchDIBits(
1056 image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width; 1190 m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height,
1057 image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left; 1191 pClipRect, flags);
1058 image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height; 1192 }
1059 image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top; 1193 return UseFoxitStretchEngine(pSource, color, dest_left, dest_top,
1060 FX_RECT clip_rect = image_rect; 1194 dest_width, dest_height, pClipRect, flags,
1061 clip_rect.Intersect(*pClipRect); 1195 alpha_flag, pIccTransform, blend_type);
1062 clip_rect.Offset(-image_rect.left, -image_rect.top); 1196 }
1063 int clip_width = clip_rect.Width(), clip_height = clip_rect.Height(); 1197 CFX_DIBExtractor temp(pSource);
1064 CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, f lags, &clip_rect); 1198 CFX_DIBitmap* pBitmap = temp;
1065 if (pStretched == NULL) { 1199 if (pBitmap) {
1066 return TRUE; 1200 return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width,
1067 } 1201 dest_height, flags, pIccTransform);
1068 CFX_DIBitmap background; 1202 }
1069 if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) || 1203 return FALSE;
1070 !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect .top + clip_rect.top, NULL) || 1204 }
1071 !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) { 1205 #define GET_PS_FEATURESETTING 4121
1072 delete pStretched; 1206 #define FEATURESETTING_PSLEVEL 2
1073 return FALSE; 1207 int GetPSLevel(HDC hDC) {
1074 } 1208 int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
1075 FX_RECT src_rect(0, 0, clip_width, clip_height); 1209 if (device_type != DT_RASPRINTER) {
1076 FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + cli p_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL); 1210 return 0;
1077 delete pStretched; 1211 }
1078 return ret; 1212 FX_DWORD esc = GET_PS_FEATURESETTING;
1079 } 1213 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
1080 if (pSource->HasAlpha()) { 1214 int param = FEATURESETTING_PSLEVEL;
1081 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPla tformData(); 1215 if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param,
1082 if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !p Source->IsCmykImage()) { 1216 sizeof(int), (char*)&param) > 0) {
1083 CFX_DIBExtractor temp(pSource); 1217 return param;
1084 CFX_DIBitmap* pBitmap = temp; 1218 }
1085 if (pBitmap == NULL) { 1219 }
1086 return FALSE; 1220 esc = POSTSCRIPT_IDENTIFY;
1087 } 1221 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) {
1088 return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_le ft, dest_top, dest_width, dest_height, pClipRect, flags); 1222 esc = POSTSCRIPT_DATA;
1089 }
1090 return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_w idth, dest_height,
1091 pClipRect, flags, alpha_flag, pIccTransform , blend_type);
1092 }
1093 CFX_DIBExtractor temp(pSource);
1094 CFX_DIBitmap* pBitmap = temp;
1095 if (pBitmap) {
1096 return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_ height, flags, pIccTransform);
1097 }
1098 return FALSE;
1099 }
1100 #define GET_PS_FEATURESETTING 4121
1101 #define FEATURESETTING_PSLEVEL 2
1102 int GetPSLevel(HDC hDC)
1103 {
1104 int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
1105 if (device_type != DT_RASPRINTER) {
1106 return 0;
1107 }
1108 FX_DWORD esc = GET_PS_FEATURESETTING;
1109 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) { 1223 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
1110 int param = FEATURESETTING_PSLEVEL; 1224 return 2;
1111 if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, si zeof(int), (char*)&param) > 0) { 1225 }
1112 return param; 1226 return 0;
1113 } 1227 }
1114 } 1228 esc = PSIDENT_GDICENTRIC;
1115 esc = POSTSCRIPT_IDENTIFY; 1229 if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0,
1116 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) { 1230 NULL) <= 0) {
1117 esc = POSTSCRIPT_DATA;
1118 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
1119 return 2;
1120 }
1121 return 0;
1122 }
1123 esc = PSIDENT_GDICENTRIC;
1124 if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NU LL) <= 0) {
1125 return 2;
1126 }
1127 esc = GET_PS_FEATURESETTING;
1128 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
1129 int param = FEATURESETTING_PSLEVEL;
1130 if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, si zeof(int), (char*)&param) > 0) {
1131 return param;
1132 }
1133 }
1134 return 2; 1231 return 2;
1232 }
1233 esc = GET_PS_FEATURESETTING;
1234 if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
1235 int param = FEATURESETTING_PSLEVEL;
1236 if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param,
1237 sizeof(int), (char*)&param) > 0) {
1238 return param;
1239 }
1240 }
1241 return 2;
1135 } 1242 }
1136 int CFX_WindowsDevice::m_psLevel = 2; 1243 int CFX_WindowsDevice::m_psLevel = 2;
1137 CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForc ePSOutput, int psLevel) 1244 CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC,
1138 { 1245 FX_BOOL bCmykOutput,
1139 m_bForcePSOutput = bForcePSOutput; 1246 FX_BOOL bForcePSOutput,
1140 m_psLevel = psLevel; 1247 int psLevel) {
1141 if (bForcePSOutput) { 1248 m_bForcePSOutput = bForcePSOutput;
1142 IFX_RenderDeviceDriver* pDriver = new CPSPrinterDriver; 1249 m_psLevel = psLevel;
1143 ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput); 1250 if (bForcePSOutput) {
1144 SetDeviceDriver(pDriver); 1251 IFX_RenderDeviceDriver* pDriver = new CPSPrinterDriver;
1145 return; 1252 ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput);
1146 }
1147 SetDeviceDriver(CreateDriver(hDC, bCmykOutput));
1148 }
1149 HDC CFX_WindowsDevice::GetDC() const
1150 {
1151 IFX_RenderDeviceDriver *pRDD = GetDeviceDriver();
1152 if (!pRDD) {
1153 return NULL;
1154 }
1155 return (HDC)pRDD->GetPlatformSurface();
1156 }
1157 IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC, FX_BOOL bCmykOu tput)
1158 {
1159 int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
1160 int obj_type = ::GetObjectType(hDC);
1161 int device_class;
1162 if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC) {
1163 device_class = FXDC_PRINTER;
1164 } else {
1165 device_class = FXDC_DISPLAY;
1166 }
1167 if (device_class == FXDC_PRINTER) {
1168 return new CGdiPrinterDriver(hDC);
1169 }
1170 return new CGdiDisplayDriver(hDC);
1171 }
1172 CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format for mat)
1173 {
1174 BITMAPINFOHEADER bmih;
1175 FXSYS_memset(&bmih, 0, sizeof (BITMAPINFOHEADER));
1176 bmih.biSize = sizeof(BITMAPINFOHEADER);
1177 bmih.biBitCount = format & 0xff;
1178 bmih.biHeight = -height;
1179 bmih.biPlanes = 1;
1180 bmih.biWidth = width;
1181 uint8_t* pBuffer;
1182 m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void **)&pBuffer, NULL, 0);
1183 if (m_hBitmap == NULL) {
1184 return;
1185 }
1186 CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
1187 pBitmap->Create(width, height, format, pBuffer);
1188 SetBitmap(pBitmap);
1189 m_hDC = ::CreateCompatibleDC(NULL);
1190 m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
1191 IFX_RenderDeviceDriver* pDriver = new CGdiDisplayDriver(m_hDC);
1192 SetDeviceDriver(pDriver); 1253 SetDeviceDriver(pDriver);
1193 } 1254 return;
1194 CFX_WinBitmapDevice::~CFX_WinBitmapDevice() 1255 }
1195 { 1256 SetDeviceDriver(CreateDriver(hDC, bCmykOutput));
1196 if (m_hDC) { 1257 }
1197 SelectObject(m_hDC, m_hOldBitmap); 1258 HDC CFX_WindowsDevice::GetDC() const {
1198 DeleteDC(m_hDC); 1259 IFX_RenderDeviceDriver* pRDD = GetDeviceDriver();
1199 } 1260 if (!pRDD) {
1200 if (m_hBitmap) { 1261 return NULL;
1201 DeleteObject(m_hBitmap); 1262 }
1202 } 1263 return (HDC)pRDD->GetPlatformSurface();
1203 delete GetBitmap(); 1264 }
1265 IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC,
1266 FX_BOOL bCmykOutput) {
1267 int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
1268 int obj_type = ::GetObjectType(hDC);
1269 int device_class;
1270 if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER ||
1271 obj_type == OBJ_ENHMETADC) {
1272 device_class = FXDC_PRINTER;
1273 } else {
1274 device_class = FXDC_DISPLAY;
1275 }
1276 if (device_class == FXDC_PRINTER) {
1277 return new CGdiPrinterDriver(hDC);
1278 }
1279 return new CGdiDisplayDriver(hDC);
1280 }
1281 CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width,
1282 int height,
1283 FXDIB_Format format) {
1284 BITMAPINFOHEADER bmih;
1285 FXSYS_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
1286 bmih.biSize = sizeof(BITMAPINFOHEADER);
1287 bmih.biBitCount = format & 0xff;
1288 bmih.biHeight = -height;
1289 bmih.biPlanes = 1;
1290 bmih.biWidth = width;
1291 uint8_t* pBuffer;
1292 m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS,
1293 (void**)&pBuffer, NULL, 0);
1294 if (m_hBitmap == NULL) {
1295 return;
1296 }
1297 CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
1298 pBitmap->Create(width, height, format, pBuffer);
1299 SetBitmap(pBitmap);
1300 m_hDC = ::CreateCompatibleDC(NULL);
1301 m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
1302 IFX_RenderDeviceDriver* pDriver = new CGdiDisplayDriver(m_hDC);
1303 SetDeviceDriver(pDriver);
1304 }
1305 CFX_WinBitmapDevice::~CFX_WinBitmapDevice() {
1306 if (m_hDC) {
1307 SelectObject(m_hDC, m_hOldBitmap);
1308 DeleteDC(m_hDC);
1309 }
1310 if (m_hBitmap) {
1311 DeleteObject(m_hBitmap);
1312 }
1313 delete GetBitmap();
1204 } 1314 }
1205 1315
1206 #endif // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_ 1316 #endif // _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698