Commit 9c978ab1 authored by Marcus Meissner's avatar Marcus Meissner Committed by Alexandre Julliard

Overlay indices are signed shorts (-1 means no overlay)

(ImageList_SetOverlayIndex) should accept -1 as overlayindex. (ImageList_Read) We can read a NxM bitmap from the stream and have to convert it into a 1x(M*N) bitmap, set cCurImage,cMaxImage. Added documentation. (others) removed some potential operator precendence problems.
parent 382354e6
......@@ -7,7 +7,7 @@
* - Fix ImageList_DrawIndirect (xBitmap, yBitmap, rgbFg, rgbBk, dwRop).
* - Fix ImageList_GetIcon.
* - Fix drag functions.
* - Fix ImageList_Read and ImageList_Write.
* - Fix ImageList_Write.
* - Fix ImageList_SetFilter (undocumented).
* BTW does anybody know anything about this function???
* - It removes 12 Bytes from the stack (3 Parameters).
......@@ -149,6 +149,7 @@ IMAGELIST_InternalDraw(IMAGELISTDRAWPARAMS *pimldp, INT cx, INT cy)
{
HDC hImageDC;
HBITMAP hOldBitmap;
hImageDC = CreateCompatibleDC(0);
hOldBitmap = SelectObject(hImageDC, pimldp->himl->hbmImage);
BitBlt(pimldp->hdcDst,
......@@ -203,7 +204,7 @@ IMAGELIST_InternalDrawMask(IMAGELISTDRAWPARAMS *pimldp, INT cx, INT cy)
/* Draw the Background for the appropriate Styles
*/
if( bUseCustomBackground && (pimldp->fStyle == ILD_NORMAL
|| pimldp->fStyle & ILD_IMAGE
|| (pimldp->fStyle & ILD_IMAGE)
|| bBlendFlag))
{
hBrush = CreateSolidBrush (himlLocal->clrBk);
......@@ -218,7 +219,7 @@ IMAGELIST_InternalDrawMask(IMAGELISTDRAWPARAMS *pimldp, INT cx, INT cy)
/* Draw Image Transparently over the current background
*/
if(pimldp->fStyle == ILD_NORMAL
|| pimldp->fStyle & ILD_TRANSPARENT
|| (pimldp->fStyle & ILD_TRANSPARENT)
|| ((pimldp->fStyle & ILD_IMAGE) && bUseCustomBackground)
|| bBlendFlag)
{
......@@ -245,7 +246,7 @@ IMAGELIST_InternalDrawMask(IMAGELISTDRAWPARAMS *pimldp, INT cx, INT cy)
}
/* Draw the image when no Background is specified
*/
else if(pimldp->fStyle & ILD_IMAGE && !bUseCustomBackground)
else if((pimldp->fStyle & ILD_IMAGE) && !bUseCustomBackground)
{
BitBlt(pimldp->hdcDst,
pimldp->x, pimldp->y, cx, cy,
......@@ -1252,8 +1253,10 @@ ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
return FALSE;
if (pimldp->himl == NULL)
return FALSE;
if ((pimldp->i < 0) || (pimldp->i > pimldp->himl->cCurImage))
if ((pimldp->i < 0) || (pimldp->i > pimldp->himl->cCurImage)) {
ERR("%d not within range (max %d)\n",pimldp->i,pimldp->himl->cCurImage);
return FALSE;
}
/*
Get the Height and Width to display
*/
......@@ -1334,8 +1337,10 @@ ImageList_Duplicate (HIMAGELIST himlSrc)
DeleteDC (hdcDst);
DeleteDC (hdcSrc);
}
himlDst->cCurImage = himlSrc->cCurImage;
himlDst->cMaxImage = himlSrc->cMaxImage;
}
return himlDst;
}
......@@ -1451,8 +1456,10 @@ ImageList_GetIcon (HIMAGELIST himl, INT i, UINT fStyle)
HBITMAP hOldSrcBitmap,hOldDstBitmap;
HDC hdcSrc, hdcDst;
if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage))
if ((himl == NULL) || (i < 0) || (i >= himl->cCurImage)) {
FIXME("(%p,%d,%x), params out of range!\n",himl,i,fStyle);
return 0;
}
hdcSrc = CreateCompatibleDC(0);
hdcDst = CreateCompatibleDC(0);
......@@ -1883,6 +1890,7 @@ ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
}
/* helper for _read_bitmap currently unused */
static int may_use_dibsection(HDC hdc) {
int bitspixel = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
if (bitspixel>8)
......@@ -1892,7 +1900,8 @@ static int may_use_dibsection(HDC hdc) {
return GetDeviceCaps(hdc,94) & 0x10;
}
static HBITMAP _read_bitmap(LPSTREAM pstm,int x) {
/* helper for ImageList_Read, see comments below */
static HBITMAP _read_bitmap(LPSTREAM pstm,int ilcFlag,int cx,int cy) {
HDC xdc = 0;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
......@@ -1900,7 +1909,8 @@ static HBITMAP _read_bitmap(LPSTREAM pstm,int x) {
LPBITMAPINFOHEADER bmihc = NULL;
int result = 0;
HBITMAP hbitmap = 0;
LPBYTE bits = NULL;
LPBYTE bits = NULL,nbits = NULL;
int nbytesperline,bytesperline;
if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)) ||
(bmfh.bfType != (('M'<<8)|'B')) ||
......@@ -1922,38 +1932,62 @@ static HBITMAP _read_bitmap(LPSTREAM pstm,int x) {
bmihc->biSizeImage = (longsperline*height)<<2;
/* read the palette right after the end of the bitmapinfoheader */
if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL)))
goto ret1;
if (palspace)
if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL)))
goto ret1;
xdc = GetDC(0);
#if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */
if ((bitsperpixel>1) &&
((x!=0xfe) && (!x || may_use_dibsection(xdc)))
((ilcFlag!=ILC_COLORDDB) && (!ilcFlag || may_use_dibsection(xdc)))
) {
hbitmap = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0);
if (!hbitmap)
goto ret1;
if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL)))
goto ret1;
bits = NULL;
result = 1;
} else {
} else
#endif
{
int i,nwidth,nheight;
nwidth = width*(height/cy);
nheight = cy;
if (bitsperpixel==1)
hbitmap = CreateBitmap(width,height,1,1,NULL);
hbitmap = CreateBitmap(nwidth,nheight,1,1,NULL);
else
hbitmap = CreateCompatibleBitmap(xdc,width,height);
hbitmap = CreateCompatibleBitmap(xdc,nwidth,nheight);
/* Might be a bit excessive memory use here */
bits = (LPBYTE)LocalAlloc(0,longsperline*4*height);
if (!SUCCEEDED(IStream_Read ( pstm, bits, longsperline*4*height, NULL)))
bits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage);
nbits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage);
if (!SUCCEEDED(IStream_Read ( pstm, bits, bmihc->biSizeImage, NULL)))
goto ret1;
if (!SetDIBits(xdc,hbitmap,0,height,bits,(BITMAPINFO*)bmihc,0))
/* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
/* Do not forget that windows bitmaps are bottom->top */
bytesperline = longsperline*4;
nbytesperline = (height/cy)*bytesperline;
for (i=0;i<height;i++) {
memcpy(
nbits+((height-i)%cy)*nbytesperline+(i/cy)*bytesperline,
bits+bytesperline*(height-i),
bytesperline
);
}
bmihc->biWidth = nwidth;
bmihc->biHeight = nheight;
if (!SetDIBits(xdc,hbitmap,0,nheight,nbits,(BITMAPINFO*)bmihc,0))
goto ret1;
LocalFree((HLOCAL)nbits);
LocalFree((HLOCAL)bits);
result = 1;
}
ret1:
if (xdc) ReleaseDC(0,xdc);
if (bmihc) LocalFree((HLOCAL)bmihc);
if (bits) LocalFree((HLOCAL)bits);
if (!result) {
if (hbitmap) {
DeleteObject(hbitmap);
......@@ -1975,8 +2009,27 @@ ret1:
* Success: handle to image list
* Failure: NULL
*
* BUGS
* still not complete functional
* The format is like this:
* ILHEAD ilheadstruct;
*
* for the color image part:
* BITMAPFILEHEADER bmfh;
* BITMAPINFOHEADER bmih;
* only if it has a palette:
* RGBQUAD rgbs[nr_of_paletted_colors];
*
* BYTE colorbits[imagesize];
*
* the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
* BITMAPFILEHEADER bmfh_mask;
* BITMAPINFOHEADER bmih_mask;
* only if it has a palette (it usually does not):
* RGBQUAD rgbs[nr_of_paletted_colors];
*
* BYTE maskbits[imagesize];
*
* CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect.
* _read_bitmap needs to convert them.
*/
HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
{
......@@ -1995,7 +2048,7 @@ HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
#if 0
FIXME(" ilHead.cCurImage = %d\n",ilHead.cCurImage);
FIXME(" ilHead.cMaxImage = %d\n",ilHead.cMaxImage);
FIXME(" ilHead.grow = %d\n",ilHead.grow);
FIXME(" ilHead.cGrow = %d\n",ilHead.cGrow);
FIXME(" ilHead.cx = %d\n",ilHead.cx);
FIXME(" ilHead.cy = %d\n",ilHead.cy);
FIXME(" ilHead.flags = %x\n",ilHead.flags);
......@@ -2005,11 +2058,11 @@ HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
FIXME(" ilHead.ovls[3] = %d\n",ilHead.ovls[3]);
#endif
hbmColor = _read_bitmap(pstm,ilHead.flags & 0xfe);
hbmColor = _read_bitmap(pstm,ilHead.flags & ~ILC_MASK,ilHead.cx,ilHead.cy);
if (!hbmColor)
return NULL;
if (ilHead.flags & 1) {
hbmMask = _read_bitmap(pstm,0);
if (ilHead.flags & ILC_MASK) {
hbmMask = _read_bitmap(pstm,0,ilHead.cx,ilHead.cy);
if (!hbmMask) {
DeleteObject(hbmColor);
return NULL;
......@@ -2021,22 +2074,21 @@ HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
ilHead.cy,
ilHead.flags,
1, /* initial */
ilHead.grow
ilHead.cGrow
);
if (!himl) {
DeleteObject(hbmColor);
DeleteObject(hbmMask);
return NULL;
}
}
himl->hbmImage = hbmColor;
himl->hbmMask = hbmMask;
himl->cCurImage = ilHead.cCurImage;
himl->cMaxImage = ilHead.cMaxImage;
ImageList_SetBkColor(himl,ilHead.bkcolor);
for (i=0;i<4;i++)
ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
return himl;
}
......@@ -2593,9 +2645,8 @@ ImageList_SetOverlayImage (HIMAGELIST himl, INT iImage, INT iOverlay)
return FALSE;
if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
return FALSE;
if ((iImage < 0) || (iImage > himl->cCurImage))
if ((iImage!=-1) && ((iImage < 0) || (iImage > himl->cCurImage)))
return FALSE;
himl->nOvlIdx[iOverlay - 1] = iImage;
return TRUE;
}
......
......@@ -48,12 +48,12 @@ typedef struct _ILHEAD
USHORT usVersion;
WORD cCurImage;
WORD cMaxImage;
WORD grow; /* unclear */
WORD cGrow;
WORD cx;
WORD cy;
COLORREF bkcolor;
WORD flags;
WORD ovls[4];
SHORT ovls[4];
} ILHEAD;
#include "poppack.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment