blob: 64c52e2f8f8c425c2948cf47b7546883f78ad106 [file] [log] [blame]
/*
* Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
#include "stdhdrs.h"
#include "windows.h"
#include <windowsx.h>
#include <zmouse.h>
#include "awt.h"
#include "awt_BitmapUtil.h"
HBITMAP BitmapUtil::CreateTransparencyMaskFromARGB(int width, int height, int* imageData)
{
//Scan lines should be aligned to word boundary
int bufLength = ((width + 15) / 16 * 2) * height;//buf length (bytes)
int* srcPos = imageData;
char* buf = new char[bufLength];
char* bufPos = buf;
int tmp = 0;
int cbit = 0x80;
if (buf == NULL) return NULL;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
//cbit is shifted right for every pixel
//next byte is stored when cbit is zero
if ((cbit & 0xFF) == 0x00) {
*bufPos = tmp;
bufPos++;
tmp = 0;
cbit = 0x80;
}
unsigned char alpha = (*srcPos >> 0x18) & 0xFF;
if (alpha == 0x00) {
tmp |= cbit;
}
cbit >>= 1;
srcPos++;
}
//save last word at the end of scan line even if it's incomplete
*bufPos = tmp;
bufPos++;
tmp = 0;
cbit = 0x80;
//add word-padding byte if necessary
if (((bufPos - buf) & 0x01) == 0x01) {
*bufPos = 0;
bufPos++;
}
}
HBITMAP bmp = CreateBitmap(width, height, 1, 1, buf);
delete[] buf;
return bmp;
}
//BITMAPINFO extended with
typedef struct tagBITMAPINFOEX {
BITMAPINFOHEADER bmiHeader;
DWORD dwMasks[256];
} BITMAPINFOEX, *LPBITMAPINFOEX;
/*
* Creates 32-bit ARGB bitmap from specified RAW data.
* This function may not work on OS prior to Win95.
* See MSDN articles for CreateDIBitmap, BITMAPINFOHEADER,
* BITMAPV4HEADER, BITMAPV5HEADER for additional info.
*/
HBITMAP BitmapUtil::CreateV4BitmapFromARGB(int width, int height, int* imageData)
{
BITMAPINFOEX bitmapInfo;
HDC hDC;
char *bitmapData;
HBITMAP hTempBitmap;
HBITMAP hBitmap;
hDC = ::GetDC(::GetDesktopWindow());
if (!hDC) {
return NULL;
}
memset(&bitmapInfo, 0, sizeof(BITMAPINFOEX));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = -height;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
hTempBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)&(bitmapInfo),
DIB_RGB_COLORS,
(void**)&(bitmapData),
NULL, 0);
if (!bitmapData) {
ReleaseDC(::GetDesktopWindow(), hDC);
return NULL;
}
int* src = imageData;
char* dest = bitmapData;
for (int i = 0; i < height; i++ ) {
for (int j = 0; j < width; j++ ) {
unsigned char alpha = (*src >> 0x18) & 0xFF;
if (alpha == 0) {
dest[3] = dest[2] = dest[1] = dest[0] = 0;
} else {
dest[3] = alpha;
dest[2] = (*src >> 0x10) & 0xFF;
dest[1] = (*src >> 0x08) & 0xFF;
dest[0] = *src & 0xFF;
}
src++;
dest += 4;
}
}
hBitmap = CreateDIBitmap(hDC,
(BITMAPINFOHEADER*)&bitmapInfo,
CBM_INIT,
(void *)bitmapData,
(BITMAPINFO*)&bitmapInfo,
DIB_RGB_COLORS);
::DeleteObject(hTempBitmap);
::ReleaseDC(::GetDesktopWindow(), hDC);
::GdiFlush();
return hBitmap;
}