OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../../include/fxge/fx_ge.h" | 7 #include "../../../include/fxge/fx_ge.h" |
8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ | 8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ |
9 #include <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_memset(pbmih, 0, sizeof(BITMAPINFOHEADER)); |
20 FXSYS_memset(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 = new CFX_DIBitmap; |
| 63 FXDIB_Format format = bAlpha |
| 64 ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) |
| 65 : (FXDIB_Format)pbmi->bmiHeader.biBitCount; |
| 66 FX_BOOL ret = pBitmap->Create(width, height, format); |
| 67 if (!ret) { |
| 68 delete pBitmap; |
| 69 return NULL; |
| 70 } |
| 71 FXSYS_memcpy(pBitmap->GetBuffer(), pData, pitch * height); |
| 72 if (bBottomUp) { |
| 73 uint8_t* temp_buf = FX_Alloc(uint8_t, pitch); |
| 74 int top = 0, bottom = height - 1; |
| 75 while (top < bottom) { |
| 76 FXSYS_memcpy(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); |
| 77 FXSYS_memcpy(pBitmap->GetBuffer() + top * pitch, |
| 78 pBitmap->GetBuffer() + bottom * pitch, pitch); |
| 79 FXSYS_memcpy(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch); |
| 80 top++; |
| 81 bottom--; |
| 82 } |
| 83 FX_Free(temp_buf); |
| 84 temp_buf = NULL; |
| 85 } |
| 86 if (pbmi->bmiHeader.biBitCount == 1) { |
| 87 for (int i = 0; i < 2; i++) { |
| 88 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); |
| 89 } |
| 90 } else if (pbmi->bmiHeader.biBitCount == 8) { |
| 91 for (int i = 0; i < 256; i++) { |
| 92 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); |
| 93 } |
| 94 } |
| 95 return pBitmap; |
| 96 } |
| 97 CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) { |
| 98 return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); |
| 99 } |
| 100 HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) { |
| 101 CFX_ByteString info = GetBitmapInfo(pBitmap); |
| 102 HBITMAP hBitmap = NULL; |
| 103 hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)info.c_str(), CBM_INIT, |
| 104 pBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), |
| 105 DIB_RGB_COLORS); |
| 106 return hBitmap; |
| 107 } |
| 108 void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) { |
| 109 BITMAP bmp; |
| 110 GetObject(hBitmap, sizeof bmp, &bmp); |
| 111 w = bmp.bmWidth; |
| 112 h = bmp.bmHeight; |
| 113 } |
| 114 CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(const FX_WCHAR* filename) { |
| 115 CWin32Platform* pPlatform = |
| 116 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); |
| 117 if (pPlatform->m_GdiplusExt.IsAvailable()) { |
| 118 WINDIB_Open_Args_ args; |
| 119 args.flags = WINDIB_OPEN_PATHNAME; |
| 120 args.path_name = filename; |
| 121 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); |
| 122 } |
| 123 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, |
| 124 0, 0, LR_LOADFROMFILE); |
| 125 if (hBitmap == NULL) { |
| 126 return NULL; |
| 127 } |
| 128 HDC hDC = CreateCompatibleDC(NULL); |
| 129 int width, height; |
| 130 GetBitmapSize(hBitmap, width, height); |
| 131 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; |
| 132 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { |
| 133 delete pDIBitmap; |
| 134 DeleteDC(hDC); |
| 135 return NULL; |
| 136 } |
| 137 CFX_ByteString info = GetBitmapInfo(pDIBitmap); |
| 138 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), |
| 139 (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); |
| 140 if (!ret) { |
| 141 delete pDIBitmap; |
| 142 pDIBitmap = NULL; |
| 143 } |
| 144 DeleteDC(hDC); |
| 145 return pDIBitmap; |
| 146 } |
| 147 CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) { |
| 148 CWin32Platform* pPlatform = |
| 149 (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); |
| 150 if (pPlatform->m_GdiplusExt.IsAvailable()) { |
| 151 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); |
| 152 } |
| 153 if (args.flags == WINDIB_OPEN_MEMORY) { |
| 154 return NULL; |
| 155 } |
| 156 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, |
| 157 IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); |
| 158 if (hBitmap == NULL) { |
| 159 return NULL; |
| 160 } |
| 161 HDC hDC = CreateCompatibleDC(NULL); |
| 162 int width, height; |
| 163 GetBitmapSize(hBitmap, width, height); |
| 164 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; |
| 165 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { |
| 166 delete pDIBitmap; |
| 167 DeleteDC(hDC); |
| 168 return NULL; |
| 169 } |
| 170 CFX_ByteString info = GetBitmapInfo(pDIBitmap); |
| 171 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), |
| 172 (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); |
| 173 if (!ret) { |
| 174 delete pDIBitmap; |
| 175 pDIBitmap = NULL; |
| 176 } |
| 177 DeleteDC(hDC); |
| 178 return pDIBitmap; |
| 179 } |
| 180 CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, |
| 181 HBITMAP hBitmap, |
| 182 FX_DWORD* pPalette, |
| 183 FX_DWORD palsize) { |
| 184 FX_BOOL bCreatedDC = hDC == NULL; |
| 185 if (hDC == NULL) { |
| 186 hDC = CreateCompatibleDC(NULL); |
| 187 } |
| 188 BITMAPINFOHEADER bmih; |
| 189 FXSYS_memset(&bmih, 0, sizeof bmih); |
| 190 bmih.biSize = sizeof bmih; |
| 191 GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); |
| 192 int width = bmih.biWidth; |
| 193 int height = abs(bmih.biHeight); |
| 194 bmih.biHeight = -height; |
| 195 bmih.biCompression = BI_RGB; |
| 196 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; |
| 197 int ret = 0; |
| 198 if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { |
| 199 int size = sizeof(BITMAPINFOHEADER) + 8; |
| 200 if (bmih.biBitCount == 8) { |
| 201 size += sizeof(FX_DWORD) * 254; |
| 202 } |
| 203 BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size); |
| 204 pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| 205 pbmih->bmiHeader.biBitCount = bmih.biBitCount; |
| 206 pbmih->bmiHeader.biCompression = BI_RGB; |
| 207 pbmih->bmiHeader.biHeight = -height; |
| 208 pbmih->bmiHeader.biPlanes = 1; |
| 209 pbmih->bmiHeader.biWidth = bmih.biWidth; |
| 210 if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 |
| 211 ? FXDIB_1bppRgb |
| 212 : FXDIB_8bppRgb)) { |
| 213 delete pDIBitmap; |
| 214 FX_Free(pbmih); |
| 215 if (bCreatedDC) { |
| 216 DeleteDC(hDC); |
| 217 } |
| 218 return NULL; |
| 219 } |
| 220 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), |
| 221 (BITMAPINFO*)pbmih, DIB_RGB_COLORS); |
| 222 FX_Free(pbmih); |
| 223 pbmih = NULL; |
| 224 pDIBitmap->CopyPalette(pPalette, palsize); |
| 225 } else { |
| 226 if (bmih.biBitCount <= 24) { |
| 227 bmih.biBitCount = 24; |
| 228 } else { |
| 229 bmih.biBitCount = 32; |
| 230 } |
| 231 if (!pDIBitmap->Create(bmih.biWidth, height, |
| 232 bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) { |
| 233 delete pDIBitmap; |
| 234 if (bCreatedDC) { |
| 235 DeleteDC(hDC); |
| 236 } |
| 237 return NULL; |
| 238 } |
| 239 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), |
| 240 (BITMAPINFO*)&bmih, DIB_RGB_COLORS); |
| 241 if (ret != 0 && bmih.biBitCount == 32) { |
| 242 int pitch = pDIBitmap->GetPitch(); |
| 243 for (int row = 0; row < height; row++) { |
| 244 uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * pitch); |
| 245 for (int col = 0; col < width; col++) { |
| 246 dest_scan[3] = 255; |
| 247 dest_scan += 4; |
37 } | 248 } |
38 } | 249 } |
39 if (pBitmap->GetBPP() == 1) { | 250 } |
40 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); | 251 } |
41 if (pBitmap->GetPalette() == NULL) { | 252 if (ret == 0) { |
42 pPalette[0] = 0; | 253 delete pDIBitmap; |
43 pPalette[1] = 0xffffff; | 254 pDIBitmap = NULL; |
44 } else { | 255 } |
45 pPalette[0] = pBitmap->GetPalette()[0]; | 256 if (bCreatedDC) { |
46 pPalette[1] = pBitmap->GetPalette()[1]; | |
47 } | |
48 } | |
49 result.ReleaseBuffer(len); | |
50 return result; | |
51 } | |
52 CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL
bAlpha) | |
53 { | |
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 = new CFX_DIBitmap; | |
63 FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0
x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount; | |
64 FX_BOOL ret = pBitmap->Create(width, height, format); | |
65 if (!ret) { | |
66 delete pBitmap; | |
67 return NULL; | |
68 } | |
69 FXSYS_memcpy(pBitmap->GetBuffer(), pData, pitch * height); | |
70 if (bBottomUp) { | |
71 uint8_t* temp_buf = FX_Alloc(uint8_t, pitch); | |
72 int top = 0, bottom = height - 1; | |
73 while (top < bottom) { | |
74 FXSYS_memcpy(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); | |
75 FXSYS_memcpy(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer(
) + bottom * pitch, pitch); | |
76 FXSYS_memcpy(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch)
; | |
77 top ++; | |
78 bottom --; | |
79 } | |
80 FX_Free(temp_buf); | |
81 temp_buf = NULL; | |
82 } | |
83 if (pbmi->bmiHeader.biBitCount == 1) { | |
84 for (int i = 0; i < 2; i ++) { | |
85 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff00
0000); | |
86 } | |
87 } else if (pbmi->bmiHeader.biBitCount == 8) { | |
88 for (int i = 0; i < 256; i ++) { | |
89 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff00
0000); | |
90 } | |
91 } | |
92 return pBitmap; | |
93 } | |
94 CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) | |
95 { | |
96 return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); | |
97 } | |
98 HBITMAP»CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) | |
99 { | |
100 CFX_ByteString info = GetBitmapInfo(pBitmap); | |
101 HBITMAP hBitmap = NULL; | |
102 hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)info.c_str(), CBM_INIT, | |
103 pBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); | |
104 return hBitmap; | |
105 } | |
106 void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) | |
107 { | |
108 BITMAP bmp; | |
109 GetObject(hBitmap, sizeof bmp, &bmp); | |
110 w = bmp.bmWidth; | |
111 h = bmp.bmHeight; | |
112 } | |
113 CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(const FX_WCHAR* filename) | |
114 { | |
115 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor
mData(); | |
116 if (pPlatform->m_GdiplusExt.IsAvailable()) { | |
117 WINDIB_Open_Args_ args; | |
118 args.flags = WINDIB_OPEN_PATHNAME; | |
119 args.path_name = filename; | |
120 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); | |
121 } | |
122 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP
, 0, 0, LR_LOADFROMFILE); | |
123 if (hBitmap == NULL) { | |
124 return NULL; | |
125 } | |
126 HDC hDC = CreateCompatibleDC(NULL); | |
127 int width, height; | |
128 GetBitmapSize(hBitmap, width, height); | |
129 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; | |
130 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { | |
131 delete pDIBitmap; | |
132 DeleteDC(hDC); | |
133 return NULL; | |
134 } | |
135 CFX_ByteString info = GetBitmapInfo(pDIBitmap); | |
136 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)info.c_str(), DIB_RGB_COLORS); | |
137 if (!ret) { | |
138 delete pDIBitmap; | |
139 pDIBitmap = NULL; | |
140 } | |
141 DeleteDC(hDC); | 257 DeleteDC(hDC); |
142 return pDIBitmap; | 258 } |
143 } | 259 return pDIBitmap; |
144 CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) | 260 } |
145 { | 261 CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) { |
146 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatfor
mData(); | 262 Create(width, height, FXDIB_Rgb, (uint8_t*)1); |
147 if (pPlatform->m_GdiplusExt.IsAvailable()) { | 263 BITMAPINFOHEADER bmih; |
148 return pPlatform->m_GdiplusExt.LoadDIBitmap(args); | 264 FXSYS_memset(&bmih, 0, sizeof bmih); |
149 } | 265 bmih.biSize = sizeof bmih; |
150 if (args.flags == WINDIB_OPEN_MEMORY) { | 266 bmih.biBitCount = 24; |
151 return NULL; | 267 bmih.biHeight = -height; |
152 } | 268 bmih.biPlanes = 1; |
153 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_
BITMAP, 0, 0, LR_LOADFROMFILE); | 269 bmih.biWidth = width; |
154 if (hBitmap == NULL) { | 270 m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, |
155 return NULL; | 271 (LPVOID*)&m_pBuffer, NULL, 0); |
156 } | 272 m_hMemDC = CreateCompatibleDC(hDC); |
157 HDC hDC = CreateCompatibleDC(NULL); | 273 m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); |
158 int width, height; | 274 } |
159 GetBitmapSize(hBitmap, width, height); | 275 CFX_WindowsDIB::~CFX_WindowsDIB() { |
160 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; | 276 SelectObject(m_hMemDC, m_hOldBitmap); |
161 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { | 277 DeleteDC(m_hMemDC); |
162 delete pDIBitmap; | 278 DeleteObject(m_hBitmap); |
163 DeleteDC(hDC); | 279 } |
164 return NULL; | 280 void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) { |
165 } | 281 ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); |
166 CFX_ByteString info = GetBitmapInfo(pDIBitmap); | 282 } |
167 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)info.c_str(), DIB_RGB_COLORS); | 283 void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) { |
168 if (!ret) { | 284 ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); |
169 delete pDIBitmap; | |
170 pDIBitmap = NULL; | |
171 } | |
172 DeleteDC(hDC); | |
173 return pDIBitmap; | |
174 } | |
175 CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pP
alette, FX_DWORD palsize) | |
176 { | |
177 FX_BOOL bCreatedDC = hDC == NULL; | |
178 if (hDC == NULL) { | |
179 hDC = CreateCompatibleDC(NULL); | |
180 } | |
181 BITMAPINFOHEADER bmih; | |
182 FXSYS_memset(&bmih, 0, sizeof bmih); | |
183 bmih.biSize = sizeof bmih; | |
184 GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); | |
185 int width = bmih.biWidth; | |
186 int height = abs(bmih.biHeight); | |
187 bmih.biHeight = -height; | |
188 bmih.biCompression = BI_RGB; | |
189 CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; | |
190 int ret = 0; | |
191 if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { | |
192 int size = sizeof (BITMAPINFOHEADER) + 8; | |
193 if (bmih.biBitCount == 8) { | |
194 size += sizeof (FX_DWORD) * 254; | |
195 } | |
196 BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size); | |
197 pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); | |
198 pbmih->bmiHeader.biBitCount = bmih.biBitCount; | |
199 pbmih->bmiHeader.biCompression = BI_RGB; | |
200 pbmih->bmiHeader.biHeight = -height; | |
201 pbmih->bmiHeader.biPlanes = 1; | |
202 pbmih->bmiHeader.biWidth = bmih.biWidth; | |
203 if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDI
B_1bppRgb : FXDIB_8bppRgb)) { | |
204 delete pDIBitmap; | |
205 FX_Free(pbmih); | |
206 if (bCreatedDC) { | |
207 DeleteDC(hDC); | |
208 } | |
209 return NULL; | |
210 } | |
211 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)pbmih, DIB_RGB_COLORS); | |
212 FX_Free(pbmih); | |
213 pbmih = NULL; | |
214 pDIBitmap->CopyPalette(pPalette, palsize); | |
215 } else { | |
216 if (bmih.biBitCount <= 24) { | |
217 bmih.biBitCount = 24; | |
218 } else { | |
219 bmih.biBitCount = 32; | |
220 } | |
221 if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXD
IB_Rgb : FXDIB_Rgb32)) { | |
222 delete pDIBitmap; | |
223 if (bCreatedDC) { | |
224 DeleteDC(hDC); | |
225 } | |
226 return NULL; | |
227 } | |
228 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAP
INFO*)&bmih, DIB_RGB_COLORS); | |
229 if (ret != 0 && bmih.biBitCount == 32) { | |
230 int pitch = pDIBitmap->GetPitch(); | |
231 for (int row = 0; row < height; row ++) { | |
232 uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * p
itch); | |
233 for (int col = 0; col < width; col++) { | |
234 dest_scan[3] = 255; | |
235 dest_scan += 4; | |
236 } | |
237 } | |
238 } | |
239 } | |
240 if (ret == 0) { | |
241 delete pDIBitmap; | |
242 pDIBitmap = NULL; | |
243 } | |
244 if (bCreatedDC) { | |
245 DeleteDC(hDC); | |
246 } | |
247 return pDIBitmap; | |
248 } | |
249 CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) | |
250 { | |
251 Create(width, height, FXDIB_Rgb, (uint8_t*)1); | |
252 BITMAPINFOHEADER bmih; | |
253 FXSYS_memset(&bmih, 0, sizeof bmih); | |
254 bmih.biSize = sizeof bmih; | |
255 bmih.biBitCount = 24; | |
256 bmih.biHeight = -height; | |
257 bmih.biPlanes = 1; | |
258 bmih.biWidth = width; | |
259 m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOI
D*)&m_pBuffer, NULL, 0); | |
260 m_hMemDC = CreateCompatibleDC(hDC); | |
261 m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); | |
262 } | |
263 CFX_WindowsDIB::~CFX_WindowsDIB() | |
264 { | |
265 SelectObject(m_hMemDC, m_hOldBitmap); | |
266 DeleteDC(m_hMemDC); | |
267 DeleteObject(m_hBitmap); | |
268 } | |
269 void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) | |
270 { | |
271 ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); | |
272 } | |
273 void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) | |
274 { | |
275 ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); | |
276 } | 285 } |
277 #endif | 286 #endif |
OLD | NEW |