diff options
author | Dan Sinclair <dsinclair@chromium.org> | 2016-03-14 13:35:12 -0400 |
---|---|---|
committer | Dan Sinclair <dsinclair@chromium.org> | 2016-03-14 13:35:12 -0400 |
commit | 764ec513eecbebd12781bcc96ce81ed5e736ee92 (patch) | |
tree | 12763fde4be1f10ea1183d92185917b2b587e00b /core/fxge/win32/fx_win32_dib.cpp | |
parent | 97da97662417085774f75c26e535c6fbe70266ae (diff) | |
download | pdfium-764ec513eecbebd12781bcc96ce81ed5e736ee92.tar.xz |
Move core/src/ up to core/.
This CL moves the core/src/ files up to core/ and fixes up the include guards,
includes and build files.
R=tsepez@chromium.org
Review URL: https://codereview.chromium.org/1800523005 .
Diffstat (limited to 'core/fxge/win32/fx_win32_dib.cpp')
-rw-r--r-- | core/fxge/win32/fx_win32_dib.cpp | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/core/fxge/win32/fx_win32_dib.cpp b/core/fxge/win32/fx_win32_dib.cpp new file mode 100644 index 0000000000..cd48d07554 --- /dev/null +++ b/core/fxge/win32/fx_win32_dib.cpp @@ -0,0 +1,289 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "core/include/fxge/fx_ge.h" + +#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_ +#include <windows.h> + +#include "core/fxge/win32/win32_int.h" +#include "core/include/fxge/fx_ge_win32.h" + +CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap) { + CFX_ByteString result; + int len = sizeof(BITMAPINFOHEADER); + if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) { + len += sizeof(DWORD) * (int)(1 << pBitmap->GetBPP()); + } + BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len); + FXSYS_memset(pbmih, 0, sizeof(BITMAPINFOHEADER)); + pbmih->biSize = sizeof(BITMAPINFOHEADER); + pbmih->biBitCount = pBitmap->GetBPP(); + pbmih->biCompression = BI_RGB; + pbmih->biHeight = -(int)pBitmap->GetHeight(); + pbmih->biPlanes = 1; + pbmih->biWidth = pBitmap->GetWidth(); + if (pBitmap->GetBPP() == 8) { + FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); + if (pBitmap->GetPalette()) { + for (int i = 0; i < 256; i++) { + pPalette[i] = pBitmap->GetPalette()[i]; + } + } else { + for (int i = 0; i < 256; i++) { + pPalette[i] = i * 0x010101; + } + } + } + if (pBitmap->GetBPP() == 1) { + FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1); + if (pBitmap->GetPalette()) { + pPalette[0] = pBitmap->GetPalette()[0]; + pPalette[1] = pBitmap->GetPalette()[1]; + } else { + pPalette[0] = 0; + pPalette[1] = 0xffffff; + } + } + result.ReleaseBuffer(len); + return result; +} +CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, + LPVOID pData, + FX_BOOL bAlpha) { + int width = pbmi->bmiHeader.biWidth; + int height = pbmi->bmiHeader.biHeight; + BOOL bBottomUp = TRUE; + if (height < 0) { + height = -height; + bBottomUp = FALSE; + } + int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4; + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + FXDIB_Format format = bAlpha + ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) + : (FXDIB_Format)pbmi->bmiHeader.biBitCount; + FX_BOOL ret = pBitmap->Create(width, height, format); + if (!ret) { + delete pBitmap; + return NULL; + } + FXSYS_memcpy(pBitmap->GetBuffer(), pData, pitch * height); + if (bBottomUp) { + uint8_t* temp_buf = FX_Alloc(uint8_t, pitch); + int top = 0, bottom = height - 1; + while (top < bottom) { + FXSYS_memcpy(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch); + FXSYS_memcpy(pBitmap->GetBuffer() + top * pitch, + pBitmap->GetBuffer() + bottom * pitch, pitch); + FXSYS_memcpy(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch); + top++; + bottom--; + } + FX_Free(temp_buf); + temp_buf = NULL; + } + if (pbmi->bmiHeader.biBitCount == 1) { + for (int i = 0; i < 2; i++) { + pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); + } + } else if (pbmi->bmiHeader.biBitCount == 8) { + for (int i = 0; i < 256; i++) { + pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000); + } + } + return pBitmap; +} +CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData) { + return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE); +} +HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC) { + CFX_ByteString info = GetBitmapInfo(pBitmap); + HBITMAP hBitmap = NULL; + hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)info.c_str(), CBM_INIT, + pBitmap->GetBuffer(), (BITMAPINFO*)info.c_str(), + DIB_RGB_COLORS); + return hBitmap; +} +void GetBitmapSize(HBITMAP hBitmap, int& w, int& h) { + BITMAP bmp; + GetObject(hBitmap, sizeof bmp, &bmp); + w = bmp.bmWidth; + h = bmp.bmHeight; +} +CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(const FX_WCHAR* filename) { + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if (pPlatform->m_GdiplusExt.IsAvailable()) { + WINDIB_Open_Args_ args; + args.flags = WINDIB_OPEN_PATHNAME; + args.path_name = filename; + return pPlatform->m_GdiplusExt.LoadDIBitmap(args); + } + HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, + 0, 0, LR_LOADFROMFILE); + if (!hBitmap) { + return NULL; + } + HDC hDC = CreateCompatibleDC(NULL); + int width, height; + GetBitmapSize(hBitmap, width, height); + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { + delete pDIBitmap; + DeleteDC(hDC); + return NULL; + } + CFX_ByteString info = GetBitmapInfo(pDIBitmap); + int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); + if (!ret) { + delete pDIBitmap; + pDIBitmap = NULL; + } + DeleteDC(hDC); + return pDIBitmap; +} +CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args) { + CWin32Platform* pPlatform = + (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData(); + if (pPlatform->m_GdiplusExt.IsAvailable()) { + return pPlatform->m_GdiplusExt.LoadDIBitmap(args); + } + if (args.flags == WINDIB_OPEN_MEMORY) { + return NULL; + } + HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, + IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); + if (!hBitmap) { + return NULL; + } + HDC hDC = CreateCompatibleDC(NULL); + int width, height; + GetBitmapSize(hBitmap, width, height); + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) { + delete pDIBitmap; + DeleteDC(hDC); + return NULL; + } + CFX_ByteString info = GetBitmapInfo(pDIBitmap); + int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)info.c_str(), DIB_RGB_COLORS); + if (!ret) { + delete pDIBitmap; + pDIBitmap = NULL; + } + DeleteDC(hDC); + return pDIBitmap; +} +CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, + HBITMAP hBitmap, + FX_DWORD* pPalette, + FX_DWORD palsize) { + FX_BOOL bCreatedDC = !hDC; + if (bCreatedDC) { + hDC = CreateCompatibleDC(NULL); + } + BITMAPINFOHEADER bmih; + FXSYS_memset(&bmih, 0, sizeof bmih); + bmih.biSize = sizeof bmih; + GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS); + int width = bmih.biWidth; + int height = abs(bmih.biHeight); + bmih.biHeight = -height; + bmih.biCompression = BI_RGB; + CFX_DIBitmap* pDIBitmap = new CFX_DIBitmap; + int ret = 0; + if (bmih.biBitCount == 1 || bmih.biBitCount == 8) { + int size = sizeof(BITMAPINFOHEADER) + 8; + if (bmih.biBitCount == 8) { + size += sizeof(FX_DWORD) * 254; + } + BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(uint8_t, size); + pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmih->bmiHeader.biBitCount = bmih.biBitCount; + pbmih->bmiHeader.biCompression = BI_RGB; + pbmih->bmiHeader.biHeight = -height; + pbmih->bmiHeader.biPlanes = 1; + pbmih->bmiHeader.biWidth = bmih.biWidth; + if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 + ? FXDIB_1bppRgb + : FXDIB_8bppRgb)) { + delete pDIBitmap; + FX_Free(pbmih); + if (bCreatedDC) { + DeleteDC(hDC); + } + return NULL; + } + ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)pbmih, DIB_RGB_COLORS); + FX_Free(pbmih); + pbmih = NULL; + pDIBitmap->CopyPalette(pPalette, palsize); + } else { + if (bmih.biBitCount <= 24) { + bmih.biBitCount = 24; + } else { + bmih.biBitCount = 32; + } + if (!pDIBitmap->Create(bmih.biWidth, height, + bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) { + delete pDIBitmap; + if (bCreatedDC) { + DeleteDC(hDC); + } + return NULL; + } + ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), + (BITMAPINFO*)&bmih, DIB_RGB_COLORS); + if (ret != 0 && bmih.biBitCount == 32) { + int pitch = pDIBitmap->GetPitch(); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = (uint8_t*)(pDIBitmap->GetBuffer() + row * pitch); + for (int col = 0; col < width; col++) { + dest_scan[3] = 255; + dest_scan += 4; + } + } + } + } + if (ret == 0) { + delete pDIBitmap; + pDIBitmap = NULL; + } + if (bCreatedDC) { + DeleteDC(hDC); + } + return pDIBitmap; +} +CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height) { + Create(width, height, FXDIB_Rgb, (uint8_t*)1); + BITMAPINFOHEADER bmih; + FXSYS_memset(&bmih, 0, sizeof bmih); + bmih.biSize = sizeof bmih; + bmih.biBitCount = 24; + bmih.biHeight = -height; + bmih.biPlanes = 1; + bmih.biWidth = width; + m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, + (LPVOID*)&m_pBuffer, NULL, 0); + m_hMemDC = CreateCompatibleDC(hDC); + m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap); +} +CFX_WindowsDIB::~CFX_WindowsDIB() { + SelectObject(m_hMemDC, m_hOldBitmap); + DeleteDC(m_hMemDC); + DeleteObject(m_hBitmap); +} +void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top) { + ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY); +} +void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top) { + ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY); +} +#endif |