mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-05 18:01:34 +00:00
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.
This commit is contained in:
parent
382354e687
commit
9c978ab18e
2 changed files with 86 additions and 35 deletions
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue