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 <windows.h> | 9 #include <windows.h> |
10 #include "../../../include/fxge/fx_ge_win32.h" | 10 #include "../../../include/fxge/fx_ge_win32.h" |
11 #include "win32_int.h" | 11 #include "win32_int.h" |
12 CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap) | 12 CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap) { |
13 { | 13 CFX_ByteString result; |
14 CFX_ByteString result; | 14 int len = sizeof(BITMAPINFOHEADER); |
15 int len = sizeof (BITMAPINFOHEADER); | 15 if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) { |
16 if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) { | 16 len += sizeof(DWORD) * (int)(1 << pBitmap->GetBPP()); |
17 len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP()); | 17 } |
18 } | 18 BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len); |
19 BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len); | 19 FXSYS_memset32(pbmih, 0, sizeof(BITMAPINFOHEADER)); |
20 FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER)); | 20 pbmih->biSize = sizeof(BITMAPINFOHEADER); |
21 pbmih->biSize = sizeof(BITMAPINFOHEADER); | 21 pbmih->biBitCount = pBitmap->GetBPP(); |
22 pbmih->biBitCount = pBitmap->GetBPP(); | 22 pbmih->biCompression = BI_RGB; |
23 pbmih->biCompression = BI_RGB; | 23 pbmih->biHeight = -(int)pBitmap->GetHeight(); |
24 pbmih->biHeight = -(int)pBitmap->GetHeight(); | 24 pbmih->biPlanes = 1; |
25 pbmih->biPlanes = 1; | 25 pbmih->biWidth = pBitmap->GetWidth(); |
26 pbmih->biWidth = pBitmap->GetWidth(); | 26 if (pBitmap->GetBPP() == 8) { |
27 if (pBitmap->GetBPP() == 8) { | 27 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); |
28 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); | 28 if (pBitmap->GetPalette() == NULL) { |
29 if (pBitmap->GetPalette() == NULL) { | 29 for (int i = 0; i < 256; i++) { |
30 for (int i = 0; i < 256; i ++) { | 30 pPalette[i] = i * 0x010101; |
31 pPalette[i] = i * 0x010101; | 31 } |
32 } | 32 } else { |
33 } else { | 33 for (int i = 0; i < 256; i++) { |
34 for (int i = 0; i < 256; i ++) { | 34 pPalette[i] = pBitmap->GetPalette()[i]; |
35 pPalette[i] = pBitmap->GetPalette()[i]; | 35 } |
36 } | 36 } |
| 37 } |
| 38 if (pBitmap->GetBPP() == 1) { |
| 39 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); |
| 40 if (pBitmap->GetPalette() == NULL) { |
| 41 pPalette[0] = 0; |
| 42 pPalette[1] = 0xffffff; |
| 43 } else { |
| 44 pPalette[0] = pBitmap->GetPalette()[0]; |
| 45 pPalette[1] = pBitmap->GetPalette()[1]; |
| 46 } |
| 47 } |
| 48 result.ReleaseBuffer(len); |
| 49 return result; |
| 50 } |
| 51 CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, |
| 52 LPVOID pData, |
| 53 FX_BOOL bAlpha) { |
| 54 int width = pbmi->bmiHeader.biWidth; |
| 55 int height = pbmi->bmiHeader.biHeight; |
| 56 BOOL bBottomUp = TRUE; |
| 57 if (height < 0) { |
| 58 height = -height; |
| 59 bBottomUp = FALSE; |
| 60 } |
| 61 int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4; |
| 62 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap; |
| 63 if (!pBitmap) { |
| 64 return NULL; |
| 65 } |
| 66 FXDIB_Format format = bAlpha |
| 67 ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) |
| 68 : (FXDIB_Format)pbmi->bmiHeader.biBitCount; |
| 69 FX_BOOL ret = pBitmap->Create(width, height, format); |
| 70 if (!ret) { |
| 71 delete pBitmap; |
| 72 return NULL; |
| 73 } |
| 74 FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height); |
| 75 if (bBottomUp) { |
| 76 FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch); |
| 77 if (!temp_buf) { |
| 78 if (pBitmap) { |
| 79 delete pBitmap; |
| 80 } |
| 81 return NULL; |
| 82 } |
| 83 int top = 0, bottom = height - 1; |
| 84 while (top < bottom) { |
| 85 FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); |
| 86 FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, |
| 87 pBitmap->GetBuffer() + bottom * pitch, |
| 88 pitch); |
| 89 FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch); |
| 90 top++; |
| 91 bottom--; |
| 92 } |
| 93 FX_Free(temp_buf); |
| 94 temp_buf = NULL; |
| 95 } |
| 96 if (pbmi->bmiHeader.biBitCount == 1) { |
| 97 for (int i = 0; i < 2; i++) { |
| 98 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); |
| 99 } |
| 100 } else if (pbmi->bmiHeader.biBitCount == 8) { |
| 101 for (int i = 0; i < 256; i++) { |
| 102 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); |
| 103 } |
| 104 } |
| 105 return pBitmap; |
| 106 } |
| 107 CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) { |
| 108 return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); |
| 109 } |
| 110 HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) { |
| 111 CFX_ByteString info = GetBitmapInfo(pBitmap); |
| 112 HBITMAP hBitmap = NULL; |
| 113 hBitmap = CreateDIBitmap(hDC, |
| 114 (BITMAPINFOHEADER*)(FX_LPCSTR) info, |
| 115 CBM_INIT, |
| 116 pBitmap->GetBuffer(), |
| 117 (BITMAPINFO*)(FX_LPCSTR) info, |
| 118 DIB_RGB_COLORS); |
| 119 return hBitmap; |
| 120 } |
| 121 void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) { |
| 122 BITMAP bmp; |
| 123 GetObject(hBitmap, sizeof bmp, &bmp); |
| 124 w = bmp.bmWidth; |
| 125 h = bmp.bmHeight; |
| 126 } |
| 127 CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename) { |
| 128 CWin32Platform* pPlatform = |
| 129 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); |
| 130 if (pPlatform->m_GdiplusExt.IsAvailable()) { |
| 131 WINDIB_Open_Args_ args; |
| 132 args.flags = WINDIB_OPEN_PATHNAME; |
| 133 args.path_name = filename; |
| 134 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); |
| 135 } |
| 136 HBITMAP hBitmap = (HBITMAP)LoadImageW( |
| 137 NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); |
| 138 if (hBitmap == NULL) { |
| 139 return NULL; |
| 140 } |
| 141 HDC hDC = CreateCompatibleDC(NULL); |
| 142 int width, height; |
| 143 GetBitmapSize(hBitmap, width, height); |
| 144 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap; |
| 145 if (!pDIBitmap) { |
| 146 DeleteDC(hDC); |
| 147 return NULL; |
| 148 } |
| 149 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { |
| 150 delete pDIBitmap; |
| 151 DeleteDC(hDC); |
| 152 return NULL; |
| 153 } |
| 154 CFX_ByteString info = GetBitmapInfo(pDIBitmap); |
| 155 int ret = GetDIBits(hDC, |
| 156 hBitmap, |
| 157 0, |
| 158 height, |
| 159 pDIBitmap->GetBuffer(), |
| 160 (BITMAPINFO*)(FX_LPCSTR) info, |
| 161 DIB_RGB_COLORS); |
| 162 if (!ret) { |
| 163 if (pDIBitmap) { |
| 164 delete pDIBitmap; |
| 165 } |
| 166 pDIBitmap = NULL; |
| 167 } |
| 168 DeleteDC(hDC); |
| 169 return pDIBitmap; |
| 170 } |
| 171 CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) { |
| 172 CWin32Platform* pPlatform = |
| 173 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); |
| 174 if (pPlatform->m_GdiplusExt.IsAvailable()) { |
| 175 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); |
| 176 } else if (args.flags == WINDIB_OPEN_MEMORY) { |
| 177 return NULL; |
| 178 } |
| 179 HBITMAP hBitmap = (HBITMAP)LoadImageW( |
| 180 NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); |
| 181 if (hBitmap == NULL) { |
| 182 return NULL; |
| 183 } |
| 184 HDC hDC = CreateCompatibleDC(NULL); |
| 185 int width, height; |
| 186 GetBitmapSize(hBitmap, width, height); |
| 187 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap; |
| 188 if (!pDIBitmap) { |
| 189 DeleteDC(hDC); |
| 190 return NULL; |
| 191 } |
| 192 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { |
| 193 delete pDIBitmap; |
| 194 DeleteDC(hDC); |
| 195 return NULL; |
| 196 } |
| 197 CFX_ByteString info = GetBitmapInfo(pDIBitmap); |
| 198 int ret = GetDIBits(hDC, |
| 199 hBitmap, |
| 200 0, |
| 201 height, |
| 202 pDIBitmap->GetBuffer(), |
| 203 (BITMAPINFO*)(FX_LPCSTR) info, |
| 204 DIB_RGB_COLORS); |
| 205 if (!ret) { |
| 206 if (pDIBitmap) { |
| 207 delete pDIBitmap; |
| 208 } |
| 209 pDIBitmap = NULL; |
| 210 } |
| 211 DeleteDC(hDC); |
| 212 return pDIBitmap; |
| 213 } |
| 214 CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, |
| 215 HBITMAP hBitmap, |
| 216 FX_DWORD* pPalette, |
| 217 FX_DWORD palsize) { |
| 218 FX_BOOL bCreatedDC = hDC == NULL; |
| 219 if (hDC == NULL) { |
| 220 hDC = CreateCompatibleDC(NULL); |
| 221 } |
| 222 BITMAPINFOHEADER bmih; |
| 223 FXSYS_memset32(&bmih, 0, sizeof bmih); |
| 224 bmih.biSize = sizeof bmih; |
| 225 GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); |
| 226 int width = bmih.biWidth; |
| 227 int height = abs(bmih.biHeight); |
| 228 bmih.biHeight = -height; |
| 229 bmih.biCompression = BI_RGB; |
| 230 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap; |
| 231 if (!pDIBitmap) { |
| 232 return NULL; |
| 233 } |
| 234 int ret = 0; |
| 235 if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { |
| 236 int size = sizeof(BITMAPINFOHEADER) + 8; |
| 237 if (bmih.biBitCount == 8) { |
| 238 size += sizeof(FX_DWORD) * 254; |
| 239 } |
| 240 BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size); |
| 241 if (!pbmih) { |
| 242 delete pDIBitmap; |
| 243 if (bCreatedDC) { |
| 244 DeleteDC(hDC); |
| 245 } |
| 246 return NULL; |
| 247 } |
| 248 pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| 249 pbmih->bmiHeader.biBitCount = bmih.biBitCount; |
| 250 pbmih->bmiHeader.biCompression = BI_RGB; |
| 251 pbmih->bmiHeader.biHeight = -height; |
| 252 pbmih->bmiHeader.biPlanes = 1; |
| 253 pbmih->bmiHeader.biWidth = bmih.biWidth; |
| 254 if (!pDIBitmap->Create( |
| 255 bmih.biWidth, |
| 256 height, |
| 257 bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) { |
| 258 delete pDIBitmap; |
| 259 FX_Free(pbmih); |
| 260 if (bCreatedDC) { |
| 261 DeleteDC(hDC); |
| 262 } |
| 263 return NULL; |
| 264 } |
| 265 ret = GetDIBits(hDC, |
| 266 hBitmap, |
| 267 0, |
| 268 height, |
| 269 pDIBitmap->GetBuffer(), |
| 270 (BITMAPINFO*)pbmih, |
| 271 DIB_RGB_COLORS); |
| 272 FX_Free(pbmih); |
| 273 pbmih = NULL; |
| 274 pDIBitmap->CopyPalette(pPalette, palsize); |
| 275 } else { |
| 276 if (bmih.biBitCount <= 24) { |
| 277 bmih.biBitCount = 24; |
| 278 } else { |
| 279 bmih.biBitCount = 32; |
| 280 } |
| 281 if (!pDIBitmap->Create(bmih.biWidth, |
| 282 height, |
| 283 bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) { |
| 284 delete pDIBitmap; |
| 285 if (bCreatedDC) { |
| 286 DeleteDC(hDC); |
| 287 } |
| 288 return NULL; |
| 289 } |
| 290 ret = GetDIBits(hDC, |
| 291 hBitmap, |
| 292 0, |
| 293 height, |
| 294 pDIBitmap->GetBuffer(), |
| 295 (BITMAPINFO*)&bmih, |
| 296 DIB_RGB_COLORS); |
| 297 if (ret != 0 && bmih.biBitCount == 32) { |
| 298 int pitch = pDIBitmap->GetPitch(); |
| 299 for (int row = 0; row < height; row++) { |
| 300 FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * pitch); |
| 301 for (int col = 0; col < width; col++) { |
| 302 dest_scan[3] = 255; |
| 303 dest_scan += 4; |
37 } | 304 } |
38 } | 305 } |
39 if (pBitmap->GetBPP() == 1) { | 306 } |
40 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); | 307 } |
41 if (pBitmap->GetPalette() == NULL) { | 308 if (ret == 0) { |
42 pPalette[0] = 0; | 309 if (pDIBitmap) { |
43 pPalette[1] = 0xffffff; | 310 delete pDIBitmap; |
44 } else { | 311 } |
45 pPalette[0] = pBitmap->GetPalette()[0]; | 312 pDIBitmap = NULL; |
46 pPalette[1] = pBitmap->GetPalette()[1]; | 313 } |
47 } | 314 if (bCreatedDC) { |
48 } | 315 DeleteDC(hDC); |
49 result.ReleaseBuffer(len); | 316 } |
50 return result; | 317 return pDIBitmap; |
51 } | 318 } |
52 CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL
bAlpha) | 319 CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) { |
53 { | 320 Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1); |
54 int width = pbmi->bmiHeader.biWidth; | 321 BITMAPINFOHEADER bmih; |
55 int height = pbmi->bmiHeader.biHeight; | 322 FXSYS_memset32(&bmih, 0, sizeof bmih); |
56 BOOL bBottomUp = TRUE; | 323 bmih.biSize = sizeof bmih; |
57 if (height < 0) { | 324 bmih.biBitCount = 24; |
58 height = -height; | 325 bmih.biHeight = -height; |
59 bBottomUp = FALSE; | 326 bmih.biPlanes = 1; |
60 } | 327 bmih.biWidth = width; |
61 int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4; | 328 m_hBitmap = CreateDIBSection( |
62 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap; | 329 hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0); |
63 if (!pBitmap) { | 330 m_hMemDC = CreateCompatibleDC(hDC); |
64 return NULL; | 331 m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); |
65 } | 332 } |
66 FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0
x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount; | 333 CFX_WindowsDIB::~CFX_WindowsDIB() { |
67 FX_BOOL ret = pBitmap->Create(width, height, format); | 334 SelectObject(m_hMemDC, m_hOldBitmap); |
68 if (!ret) { | 335 DeleteDC(m_hMemDC); |
69 delete pBitmap; | 336 DeleteObject(m_hBitmap); |
70 return NULL; | 337 } |
71 } | 338 void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) { |
72 FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height); | 339 ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); |
73 if (bBottomUp) { | 340 } |
74 FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch); | 341 void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) { |
75 if (!temp_buf) { | 342 ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); |
76 if (pBitmap) { | |
77 delete pBitmap; | |
78 } | |
79 return NULL; | |
80 } | |
81 int top = 0, bottom = height - 1; | |
82 while (top < bottom) { | |
83 FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); | |
84 FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffe
r() + bottom * pitch, pitch); | |
85 FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitc
h); | |
86 top ++; | |
87 bottom --; | |
88 } | |
89 FX_Free(temp_buf); | |
90 temp_buf = NULL; | |
91 } | |
92 if (pbmi->bmiHeader.biBitCount == 1) { | |
93 for (int i = 0; i < 2; i ++) { | |
94 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff00
0000); | |
95 } | |
96 } else if (pbmi->bmiHeader.biBitCount == 8) { | |
97 for (int i = 0; i < 256; i ++) { | |
98 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff00
0000); | |
99 } | |
100 } | |
101 return pBitmap; | |
102 } | |
103 CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) | |
104 { | |
105 return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); | |
106 } | |
107 HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) | |
108 { | |
109 CFX_ByteString info = GetBitmapInfo(pBitmap); | |
110 HBITMAP hBitmap = NULL; | |
111 hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)(FX_LPCSTR)info, CBM_INIT, | |
112 pBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info,
DIB_RGB_COLORS); | |
113 return hBitmap; | |
114 } | |
115 void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) | |
116 { | |
117 BITMAP bmp; | |
118 GetObject(hBitmap, sizeof bmp, &bmp); | |
119 w = bmp.bmWidth; | |
120 h = bmp.bmHeight; | |
121 } | |
122 CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename) | |
123 { | |
124 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor
mData(); | |
125 if (pPlatform->m_GdiplusExt.IsAvailable()) { | |
126 WINDIB_Open_Args_ args; | |
127 args.flags = WINDIB_OPEN_PATHNAME; | |
128 args.path_name = filename; | |
129 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); | |
130 } | |
131 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP
, 0, 0, LR_LOADFROMFILE); | |
132 if (hBitmap == NULL) { | |
133 return NULL; | |
134 } | |
135 HDC hDC = CreateCompatibleDC(NULL); | |
136 int width, height; | |
137 GetBitmapSize(hBitmap, width, height); | |
138 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap; | |
139 if (!pDIBitmap) { | |
140 DeleteDC(hDC); | |
141 return NULL; | |
142 } | |
143 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { | |
144 delete pDIBitmap; | |
145 DeleteDC(hDC); | |
146 return NULL; | |
147 } | |
148 CFX_ByteString info = GetBitmapInfo(pDIBitmap); | |
149 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)(FX_LPCSTR)info, DIB_RGB_COLORS); | |
150 if (!ret) { | |
151 if (pDIBitmap) { | |
152 delete pDIBitmap; | |
153 } | |
154 pDIBitmap = NULL; | |
155 } | |
156 DeleteDC(hDC); | |
157 return pDIBitmap; | |
158 } | |
159 CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) | |
160 { | |
161 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor
mData(); | |
162 if (pPlatform->m_GdiplusExt.IsAvailable()) { | |
163 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); | |
164 } else if (args.flags == WINDIB_OPEN_MEMORY) { | |
165 return NULL; | |
166 } | |
167 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_
BITMAP, 0, 0, LR_LOADFROMFILE); | |
168 if (hBitmap == NULL) { | |
169 return NULL; | |
170 } | |
171 HDC hDC = CreateCompatibleDC(NULL); | |
172 int width, height; | |
173 GetBitmapSize(hBitmap, width, height); | |
174 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap; | |
175 if (!pDIBitmap) { | |
176 DeleteDC(hDC); | |
177 return NULL; | |
178 } | |
179 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { | |
180 delete pDIBitmap; | |
181 DeleteDC(hDC); | |
182 return NULL; | |
183 } | |
184 CFX_ByteString info = GetBitmapInfo(pDIBitmap); | |
185 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)(FX_LPCSTR)info, DIB_RGB_COLORS); | |
186 if (!ret) { | |
187 if (pDIBitmap) { | |
188 delete pDIBitmap; | |
189 } | |
190 pDIBitmap = NULL; | |
191 } | |
192 DeleteDC(hDC); | |
193 return pDIBitmap; | |
194 } | |
195 CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pP
alette, FX_DWORD palsize) | |
196 { | |
197 FX_BOOL bCreatedDC = hDC == NULL; | |
198 if (hDC == NULL) { | |
199 hDC = CreateCompatibleDC(NULL); | |
200 } | |
201 BITMAPINFOHEADER bmih; | |
202 FXSYS_memset32(&bmih, 0, sizeof bmih); | |
203 bmih.biSize = sizeof bmih; | |
204 GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); | |
205 int width = bmih.biWidth; | |
206 int height = abs(bmih.biHeight); | |
207 bmih.biHeight = -height; | |
208 bmih.biCompression = BI_RGB; | |
209 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap; | |
210 if (!pDIBitmap) { | |
211 return NULL; | |
212 } | |
213 int ret = 0; | |
214 if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { | |
215 int size = sizeof (BITMAPINFOHEADER) + 8; | |
216 if (bmih.biBitCount == 8) { | |
217 size += sizeof (FX_DWORD) * 254; | |
218 } | |
219 BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size); | |
220 if (!pbmih) { | |
221 delete pDIBitmap; | |
222 if (bCreatedDC) { | |
223 DeleteDC(hDC); | |
224 } | |
225 return NULL; | |
226 } | |
227 pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
228 pbmih->bmiHeader.biBitCount = bmih.biBitCount; | |
229 pbmih->bmiHeader.biCompression = BI_RGB; | |
230 pbmih->bmiHeader.biHeight = -height; | |
231 pbmih->bmiHeader.biPlanes = 1; | |
232 pbmih->bmiHeader.biWidth = bmih.biWidth; | |
233 if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDI
B_1bppRgb : FXDIB_8bppRgb)) { | |
234 delete pDIBitmap; | |
235 FX_Free(pbmih); | |
236 if (bCreatedDC) { | |
237 DeleteDC(hDC); | |
238 } | |
239 return NULL; | |
240 } | |
241 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)pbmih, DIB_RGB_COLORS); | |
242 FX_Free(pbmih); | |
243 pbmih = NULL; | |
244 pDIBitmap->CopyPalette(pPalette, palsize); | |
245 } else { | |
246 if (bmih.biBitCount <= 24) { | |
247 bmih.biBitCount = 24; | |
248 } else { | |
249 bmih.biBitCount = 32; | |
250 } | |
251 if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXD
IB_Rgb : FXDIB_Rgb32)) { | |
252 delete pDIBitmap; | |
253 if (bCreatedDC) { | |
254 DeleteDC(hDC); | |
255 } | |
256 return NULL; | |
257 } | |
258 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)&bmih, DIB_RGB_COLORS); | |
259 if (ret != 0 && bmih.biBitCount == 32) { | |
260 int pitch = pDIBitmap->GetPitch(); | |
261 for (int row = 0; row < height; row ++) { | |
262 FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * p
itch); | |
263 for (int col = 0; col < width; col++) { | |
264 dest_scan[3] = 255; | |
265 dest_scan += 4; | |
266 } | |
267 } | |
268 } | |
269 } | |
270 if (ret == 0) { | |
271 if (pDIBitmap) { | |
272 delete pDIBitmap; | |
273 } | |
274 pDIBitmap = NULL; | |
275 } | |
276 if (bCreatedDC) { | |
277 DeleteDC(hDC); | |
278 } | |
279 return pDIBitmap; | |
280 } | |
281 CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) | |
282 { | |
283 Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1); | |
284 BITMAPINFOHEADER bmih; | |
285 FXSYS_memset32(&bmih, 0, sizeof bmih); | |
286 bmih.biSize = sizeof bmih; | |
287 bmih.biBitCount = 24; | |
288 bmih.biHeight = -height; | |
289 bmih.biPlanes = 1; | |
290 bmih.biWidth = width; | |
291 m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOI
D*)&m_pBuffer, NULL, 0); | |
292 m_hMemDC = CreateCompatibleDC(hDC); | |
293 m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); | |
294 } | |
295 CFX_WindowsDIB::~CFX_WindowsDIB() | |
296 { | |
297 SelectObject(m_hMemDC, m_hOldBitmap); | |
298 DeleteDC(m_hMemDC); | |
299 DeleteObject(m_hBitmap); | |
300 } | |
301 void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) | |
302 { | |
303 ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); | |
304 } | |
305 void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) | |
306 { | |
307 ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); | |
308 } | 343 } |
309 #endif | 344 #endif |
OLD | NEW |