mirror of
https://github.com/reactos/reactos.git
synced 2024-07-31 08:39:05 +00:00
User32 bitmap.c:
- Patch by Michael Kaufmann - CopyImage: Handle the flags LR_COPYDELETEORG, LR_CREATEDIBSECTION, and LR_MONOCHROME. svn path=/trunk/; revision=23906
This commit is contained in:
parent
76b17ae494
commit
ab4e2c9cf4
|
@ -562,36 +562,200 @@ CopyImage(
|
|||
IN INT desiredy,
|
||||
IN UINT flags)
|
||||
{
|
||||
HBITMAP res;
|
||||
BITMAP bm;
|
||||
|
||||
/*
|
||||
* BUGS
|
||||
* Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
|
||||
* all other versions (95/2000/XP have been tested) ignore it.
|
||||
*
|
||||
* NOTES
|
||||
* If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
|
||||
* a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
|
||||
* the copy will have the same depth as the screen.
|
||||
* The content of the image will only be copied if the bit depth of the
|
||||
* original image is compatible with the bit depth of the screen, or
|
||||
* if the source is a DIB section.
|
||||
* The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
|
||||
*/
|
||||
switch (type)
|
||||
{
|
||||
case IMAGE_BITMAP:
|
||||
{
|
||||
DPRINT("WARNING: Incomplete implementation of CopyImage!\n");
|
||||
/*
|
||||
* FIXME: Support flags LR_COPYDELETEORG, LR_COPYFROMRESOURCE,
|
||||
* LR_COPYRETURNORG, LR_CREATEDIBSECTION and LR_MONOCHROME.
|
||||
*/
|
||||
if (!GetObjectW(hnd, sizeof(bm), &bm))
|
||||
return NULL;
|
||||
bm.bmBits = NULL;
|
||||
if ((res = CreateBitmapIndirect(&bm)))
|
||||
{
|
||||
char *buf = HeapAlloc(GetProcessHeap(), 0, bm.bmWidthBytes * bm.bmHeight);
|
||||
if (buf == NULL)
|
||||
{
|
||||
DeleteObject(res);
|
||||
return NULL;
|
||||
}
|
||||
GetBitmapBits(hnd, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
SetBitmapBits(res, bm.bmWidthBytes * bm.bmHeight, buf);
|
||||
HeapFree(GetProcessHeap(), 0, buf);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
HBITMAP res = NULL;
|
||||
DIBSECTION ds;
|
||||
int objSize;
|
||||
BITMAPINFO * bi;
|
||||
|
||||
objSize = GetObjectW( hnd, sizeof(ds), &ds );
|
||||
if (!objSize) return 0;
|
||||
if ((desiredx < 0) || (desiredy < 0)) return 0;
|
||||
|
||||
if (flags & LR_COPYFROMRESOURCE)
|
||||
{
|
||||
DPRINT1("FIXME: The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
|
||||
}
|
||||
|
||||
if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
|
||||
if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
|
||||
|
||||
/* Allocate memory for a BITMAPINFOHEADER structure and a
|
||||
color table. The maximum number of colors in a color table
|
||||
is 256 which corresponds to a bitmap with depth 8.
|
||||
Bitmaps with higher depths don't have color tables. */
|
||||
bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||
if (!bi) return 0;
|
||||
|
||||
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
||||
bi->bmiHeader.biPlanes = ds.dsBm.bmPlanes;
|
||||
bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
|
||||
bi->bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
if (flags & LR_CREATEDIBSECTION)
|
||||
{
|
||||
/* Create a DIB section. LR_MONOCHROME is ignored */
|
||||
void * bits;
|
||||
HDC dc = CreateCompatibleDC(NULL);
|
||||
|
||||
if (objSize == sizeof(DIBSECTION))
|
||||
{
|
||||
/* The source bitmap is a DIB.
|
||||
Get its attributes to create an exact copy */
|
||||
memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
|
||||
}
|
||||
|
||||
/* Get the color table or the color masks */
|
||||
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
|
||||
|
||||
bi->bmiHeader.biWidth = desiredx;
|
||||
bi->bmiHeader.biHeight = desiredy;
|
||||
bi->bmiHeader.biSizeImage = 0;
|
||||
|
||||
res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||
DeleteDC(dc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create a device-dependent bitmap */
|
||||
|
||||
BOOL monochrome = (flags & LR_MONOCHROME);
|
||||
|
||||
if (objSize == sizeof(DIBSECTION))
|
||||
{
|
||||
/* The source bitmap is a DIB section.
|
||||
Get its attributes */
|
||||
HDC dc = CreateCompatibleDC(NULL);
|
||||
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
||||
bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
|
||||
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
|
||||
DeleteDC(dc);
|
||||
|
||||
if (!monochrome && ds.dsBm.bmBitsPixel == 1)
|
||||
{
|
||||
/* Look if the colors of the DIB are black and white */
|
||||
|
||||
monochrome =
|
||||
(bi->bmiColors[0].rgbRed == 0xff
|
||||
&& bi->bmiColors[0].rgbGreen == 0xff
|
||||
&& bi->bmiColors[0].rgbBlue == 0xff
|
||||
&& bi->bmiColors[0].rgbReserved == 0
|
||||
&& bi->bmiColors[1].rgbRed == 0
|
||||
&& bi->bmiColors[1].rgbGreen == 0
|
||||
&& bi->bmiColors[1].rgbBlue == 0
|
||||
&& bi->bmiColors[1].rgbReserved == 0)
|
||||
||
|
||||
(bi->bmiColors[0].rgbRed == 0
|
||||
&& bi->bmiColors[0].rgbGreen == 0
|
||||
&& bi->bmiColors[0].rgbBlue == 0
|
||||
&& bi->bmiColors[0].rgbReserved == 0
|
||||
&& bi->bmiColors[1].rgbRed == 0xff
|
||||
&& bi->bmiColors[1].rgbGreen == 0xff
|
||||
&& bi->bmiColors[1].rgbBlue == 0xff
|
||||
&& bi->bmiColors[1].rgbReserved == 0);
|
||||
}
|
||||
}
|
||||
else if (!monochrome)
|
||||
{
|
||||
monochrome = ds.dsBm.bmBitsPixel == 1;
|
||||
}
|
||||
|
||||
if (monochrome)
|
||||
{
|
||||
res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
HDC screenDC = GetDC(NULL);
|
||||
res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
|
||||
ReleaseDC(NULL, screenDC);
|
||||
}
|
||||
}
|
||||
|
||||
if (res)
|
||||
{
|
||||
/* Only copy the bitmap if it's a DIB section or if it's
|
||||
compatible to the screen */
|
||||
BOOL copyContents;
|
||||
|
||||
if (objSize == sizeof(DIBSECTION))
|
||||
{
|
||||
copyContents = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
HDC screenDC = GetDC(NULL);
|
||||
int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
|
||||
ReleaseDC(NULL, screenDC);
|
||||
|
||||
copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
|
||||
}
|
||||
|
||||
if (copyContents)
|
||||
{
|
||||
/* The source bitmap may already be selected in a device context,
|
||||
use GetDIBits/StretchDIBits and not StretchBlt */
|
||||
|
||||
HDC dc;
|
||||
void * bits;
|
||||
|
||||
dc = CreateCompatibleDC(NULL);
|
||||
|
||||
bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
|
||||
bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
|
||||
bi->bmiHeader.biSizeImage = 0;
|
||||
bi->bmiHeader.biClrUsed = 0;
|
||||
bi->bmiHeader.biClrImportant = 0;
|
||||
|
||||
/* Fill in biSizeImage */
|
||||
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
|
||||
bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
|
||||
|
||||
if (bits)
|
||||
{
|
||||
HBITMAP oldBmp;
|
||||
|
||||
/* Get the image bits of the source bitmap */
|
||||
GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
|
||||
|
||||
/* Copy it to the destination bitmap */
|
||||
oldBmp = SelectObject(dc, res);
|
||||
StretchDIBits(dc, 0, 0, desiredx, desiredy,
|
||||
0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
|
||||
bits, bi, DIB_RGB_COLORS, SRCCOPY);
|
||||
SelectObject(dc, oldBmp);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, bits);
|
||||
}
|
||||
|
||||
DeleteDC(dc);
|
||||
}
|
||||
|
||||
if (flags & LR_COPYDELETEORG)
|
||||
{
|
||||
DeleteObject(hnd);
|
||||
}
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, bi);
|
||||
return (HICON)res;
|
||||
}
|
||||
case IMAGE_ICON:
|
||||
{
|
||||
static BOOL IconMsgDisplayed = FALSE;
|
||||
|
@ -602,6 +766,7 @@ CopyImage(
|
|||
IconMsgDisplayed = TRUE;
|
||||
}
|
||||
return CopyIcon(hnd);
|
||||
// return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
|
||||
}
|
||||
|
||||
case IMAGE_CURSOR:
|
||||
|
@ -613,9 +778,13 @@ CopyImage(
|
|||
DPRINT("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
|
||||
IconMsgDisplayed = TRUE;
|
||||
}
|
||||
/* Should call CURSORICON_ExtCopy but more testing
|
||||
* needs to be done before we change this
|
||||
*/
|
||||
if (flags) DPRINT1("FIXME: Flags are ignored\n");
|
||||
return CopyCursor(hnd);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue