1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
7 #include "../../../include/fxge/fx_ge.h"
8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
10 #include "../../../include/fxge/fx_ge_win32.h"
11 #include "win32_int.h"
12 CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap)
14 CFX_ByteString result;
15 int len = sizeof (BITMAPINFOHEADER);
16 if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
17 len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP());
19 BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
20 FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
21 pbmih->biSize = sizeof(BITMAPINFOHEADER);
22 pbmih->biBitCount = pBitmap->GetBPP();
23 pbmih->biCompression = BI_RGB;
24 pbmih->biHeight = -(int)pBitmap->GetHeight();
26 pbmih->biWidth = pBitmap->GetWidth();
27 if (pBitmap->GetBPP() == 8) {
28 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
29 if (pBitmap->GetPalette() == NULL) {
30 for (int i = 0; i < 256; i ++) {
31 pPalette[i] = i * 0x010101;
34 for (int i = 0; i < 256; i ++) {
35 pPalette[i] = pBitmap->GetPalette()[i];
39 if (pBitmap->GetBPP() == 1) {
40 FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
41 if (pBitmap->GetPalette() == NULL) {
43 pPalette[1] = 0xffffff;
45 pPalette[0] = pBitmap->GetPalette()[0];
46 pPalette[1] = pBitmap->GetPalette()[1];
49 result.ReleaseBuffer(len);
52 CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha)
54 int width = pbmi->bmiHeader.biWidth;
55 int height = pbmi->bmiHeader.biHeight;
56 BOOL bBottomUp = TRUE;
61 int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
62 CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
66 FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
67 FX_BOOL ret = pBitmap->Create(width, height, format);
72 FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height);
74 FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch);
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->GetBuffer() + bottom * pitch, pitch);
85 FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
92 if (pbmi->bmiHeader.biBitCount == 1) {
93 for (int i = 0; i < 2; i ++) {
94 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
96 } else if (pbmi->bmiHeader.biBitCount == 8) {
97 for (int i = 0; i < 256; i ++) {
98 pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
103 CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData)
105 return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE);
107 HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC)
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);
115 void GetBitmapSize(HBITMAP hBitmap, int& w, int& h)
118 GetObject(hBitmap, sizeof bmp, &bmp);
122 CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename)
124 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
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);
131 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
132 if (hBitmap == NULL) {
135 HDC hDC = CreateCompatibleDC(NULL);
137 GetBitmapSize(hBitmap, width, height);
138 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
143 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
148 CFX_ByteString info = GetBitmapInfo(pDIBitmap);
149 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
159 CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args)
161 CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
162 if (pPlatform->m_GdiplusExt.IsAvailable()) {
163 return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
164 } else if (args.flags == WINDIB_OPEN_MEMORY) {
167 HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
168 if (hBitmap == NULL) {
171 HDC hDC = CreateCompatibleDC(NULL);
173 GetBitmapSize(hBitmap, width, height);
174 CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
179 if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
184 CFX_ByteString info = GetBitmapInfo(pDIBitmap);
185 int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
195 CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
197 FX_BOOL bCreatedDC = hDC == NULL;
199 hDC = CreateCompatibleDC(NULL);
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;
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;
219 BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size);
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 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
241 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
244 pDIBitmap->CopyPalette(pPalette, palsize);
246 if (bmih.biBitCount <= 24) {
247 bmih.biBitCount = 24;
249 bmih.biBitCount = 32;
251 if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
258 ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&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 * pitch);
263 for (int col = 0; col < width; col++) {
281 CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height)
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;
290 bmih.biWidth = width;
291 m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0);
292 m_hMemDC = CreateCompatibleDC(hDC);
293 m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
295 CFX_WindowsDIB::~CFX_WindowsDIB()
297 SelectObject(m_hMemDC, m_hOldBitmap);
299 DeleteObject(m_hBitmap);
301 void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top)
303 ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
305 void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top)
307 ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);