mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 15:33:07 +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
1 changed files with 195 additions and 26 deletions
|
@ -562,36 +562,200 @@ CopyImage(
|
||||||
IN INT desiredy,
|
IN INT desiredy,
|
||||||
IN UINT flags)
|
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)
|
switch (type)
|
||||||
{
|
{
|
||||||
case IMAGE_BITMAP:
|
case IMAGE_BITMAP:
|
||||||
{
|
{
|
||||||
DPRINT("WARNING: Incomplete implementation of CopyImage!\n");
|
HBITMAP res = NULL;
|
||||||
/*
|
DIBSECTION ds;
|
||||||
* FIXME: Support flags LR_COPYDELETEORG, LR_COPYFROMRESOURCE,
|
int objSize;
|
||||||
* LR_COPYRETURNORG, LR_CREATEDIBSECTION and LR_MONOCHROME.
|
BITMAPINFO * bi;
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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:
|
case IMAGE_ICON:
|
||||||
{
|
{
|
||||||
static BOOL IconMsgDisplayed = FALSE;
|
static BOOL IconMsgDisplayed = FALSE;
|
||||||
|
@ -602,6 +766,7 @@ CopyImage(
|
||||||
IconMsgDisplayed = TRUE;
|
IconMsgDisplayed = TRUE;
|
||||||
}
|
}
|
||||||
return CopyIcon(hnd);
|
return CopyIcon(hnd);
|
||||||
|
// return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
case IMAGE_CURSOR:
|
case IMAGE_CURSOR:
|
||||||
|
@ -613,9 +778,13 @@ CopyImage(
|
||||||
DPRINT("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
|
DPRINT("FIXME: CopyImage doesn't support IMAGE_CURSOR correctly!\n");
|
||||||
IconMsgDisplayed = TRUE;
|
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 CopyCursor(hnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue