| 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 |