PATCH/RFC: imagelist rewrite to use N x M grid

Marcus Meissner marcus at jet.franken.de
Mon Nov 28 02:14:05 CST 2005


Hi,

This patch is a rewrite of the imagelist handling
to not use a Nx1 grid, but a NxM grid with M definable
in the source (currently 4).

I have tested against winrar, "file open" and "make check".

It is not completely regression tested, so I am not
wanting to submit it right now.

But I welcome comments. :)

Ciao, Marcus

Index: dlls/comctl32/imagelist.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/imagelist.c,v
retrieving revision 1.101
diff -u -r1.101 imagelist.c
--- dlls/comctl32/imagelist.c	14 Nov 2005 11:20:10 -0000	1.101
+++ dlls/comctl32/imagelist.c	28 Nov 2005 06:21:43 -0000
@@ -55,6 +55,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(imagelist);
 
+#define PER_ROW 4
 
 #define MAX_OVERLAYIMAGE 15
 
@@ -84,6 +85,12 @@
     return himl && himl->magic == IMAGELIST_MAGIC;
 }
 
+static DWORD index2x(INT index, INT cx) { return cx*(index/PER_ROW); }
+static DWORD index2y(INT index, INT cy) { return cy*(index%PER_ROW); }
+
+static DWORD count2x(INT count, INT cx) {
+    return cx*((count+PER_ROW-1)/PER_ROW);
+}
 
 /*************************************************************************
  * IMAGELIST_InternalExpandBitmaps [Internal]
@@ -93,6 +100,8 @@
  * PARAMS
  *     himl        [I] handle to image list
  *     nImageCount [I] number of images to add
+ *     cx          [I] width of image
+ *     cy          [I] height of image
  *
  * RETURNS
  *     nothing
@@ -113,21 +122,22 @@
 
     if (cy == 0) cy = himl->cy;
     nNewCount = himl->cCurImage + nImageCount + himl->cGrow;
-    nNewWidth = nNewCount * himl->cx;
+    nNewWidth = count2x(nNewCount,himl->cx);
 
-    TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl, nNewWidth, cy, nNewCount);
+    TRACE("Create expanded bitmaps : himl=%p x=%d y=%d count=%d\n", himl,
+           nNewWidth, cy*PER_ROW, nNewCount);
     hdcBitmap = CreateCompatibleDC (0);
 
-    hbmNewBitmap = ImageList_CreateImage(hdcBitmap, himl, nNewWidth, cy);
+    hbmNewBitmap = ImageList_CreateImage(hdcBitmap, himl, nNewWidth, cy*PER_ROW);
 
     if (hbmNewBitmap == 0)
-        ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth, cy);
+        ERR("creating new image bitmap (x=%d y=%d)!\n", nNewWidth, cy*PER_ROW);
 
     if(himl->cCurImage)
     {
         hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
-        BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
-                himl->hdcImage, 0, 0, SRCCOPY);
+        BitBlt (hdcBitmap, 0, 0, count2x(himl->cCurImage,himl->cx),
+		cy*PER_ROW, himl->hdcImage, 0, 0, SRCCOPY);
         SelectObject (hdcBitmap, hbmNull);
     }
     SelectObject (himl->hdcImage, hbmNewBitmap);
@@ -136,7 +146,7 @@
 
     if (himl->flags & ILC_MASK)
     {
-        hbmNewBitmap = CreateBitmap (nNewWidth, cy, 1, 1, NULL);
+        hbmNewBitmap = CreateBitmap (nNewWidth, cy*PER_ROW, 1, 1, NULL);
 
         if (hbmNewBitmap == 0)
             ERR("creating new mask bitmap!\n");
@@ -144,8 +154,8 @@
 	if(himl->cCurImage)
 	{
 	    hbmNull = SelectObject (hdcBitmap, hbmNewBitmap);
-	    BitBlt (hdcBitmap, 0, 0, himl->cCurImage * himl->cx, cy,
-		    himl->hdcMask, 0, 0, SRCCOPY);
+	    BitBlt (hdcBitmap, 0, 0, count2x(himl->cCurImage,himl->cx),
+		    cy*PER_ROW, himl->hdcMask, 0, 0, SRCCOPY);
 	    SelectObject (hdcBitmap, hbmNull);
 	}
         SelectObject (himl->hdcMask, hbmNewBitmap);
@@ -179,7 +189,7 @@
 {
     HDC     hdcBitmap;
     INT     nFirstIndex, nImageCount;
-    INT     nStartX;
+    INT     i;
     BITMAP  bmp;
     HBITMAP hOldBitmap;
 
@@ -192,43 +202,42 @@
 
     IMAGELIST_InternalExpandBitmaps (himl, nImageCount, bmp.bmWidth, bmp.bmHeight);
 
-    nStartX = himl->cCurImage * himl->cx;
-
     hdcBitmap = CreateCompatibleDC(0);
-
     hOldBitmap = SelectObject(hdcBitmap, hbmImage);
 
-    /* Copy result to the imagelist
-    */
-    BitBlt (himl->hdcImage, nStartX, 0, bmp.bmWidth, bmp.bmHeight,
-        hdcBitmap, 0, 0, SRCCOPY);
-
-    if(himl->hbmMask)
-    {
-	HDC hdcTemp;
-	HBITMAP hOldBitmapTemp;
-
-        hdcTemp   = CreateCompatibleDC(0);
-        hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);
+    for (i=himl->cCurImage;i<himl->cCurImage+nImageCount;i++) {
+	/* Copy result to the imagelist */
+	BitBlt (himl->hdcImage, index2x(i,himl->cx), index2y(i,himl->cy),
+	    himl->cx, himl->cy, hdcBitmap, himl->cx*(i-himl->cCurImage), 0, SRCCOPY);
 
-        BitBlt (himl->hdcMask,
-            nStartX, 0, bmp.bmWidth, bmp.bmHeight,
-            hdcTemp,
-            0, 0,
-            SRCCOPY);
+	if(himl->hbmMask)
+	{
+	    HDC hdcTemp;
+	    HBITMAP hOldBitmapTemp;
 
-        SelectObject(hdcTemp, hOldBitmapTemp);
-        DeleteDC(hdcTemp);
+	    hdcTemp   = CreateCompatibleDC(0);
+	    hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);
 
-        /* Remove the background from the image
-        */
-        BitBlt (himl->hdcImage,
-            nStartX, 0, bmp.bmWidth, bmp.bmHeight,
-            himl->hdcMask,
-            nStartX, 0,
-            0x220326); /* NOTSRCAND */
+	    BitBlt (himl->hdcMask,
+		index2x(i,himl->cx), index2y(i,himl->cy),
+		himl->cx, himl->cy,
+		hdcTemp,
+		himl->cx*(i-himl->cCurImage), 0,
+		SRCCOPY);
+
+	    SelectObject(hdcTemp, hOldBitmapTemp);
+	    DeleteDC(hdcTemp);
+
+	    /* Remove the background from the image
+	    */
+	    BitBlt (himl->hdcImage,
+		index2x(i,himl->cx), index2y(i,himl->cy),
+		bmp.bmWidth, bmp.bmHeight,
+		himl->hdcMask,
+		index2x(i,himl->cx), index2y(i,himl->cy),
+		0x220326); /* NOTSRCAND */
+	}
     }
-
     SelectObject(hdcBitmap, hOldBitmap);
     DeleteDC(hdcBitmap);
 
@@ -278,12 +287,12 @@
 INT WINAPI
 ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
 {
-    HDC    hdcMask, hdcBitmap;
-    INT    nIndex, nImageCount, nMaskXOffset=0;
+    HDC    hdcBitmap;
+    INT    nIndex, nImageCount;
     BITMAP bmp;
     HBITMAP hOldBitmap;
-    HBITMAP hMaskBitmap=0;
     COLORREF bkColor;
+    int i;
 
     TRACE("himl=%p hbitmap=%p clrmask=%lx\n", himl, hBitmap, clrMask);
     if (!is_valid(himl))
@@ -292,6 +301,8 @@
     if (!GetObjectA (hBitmap, sizeof(BITMAP), &bmp))
         return -1;
 
+    TRACE("bitmap is %d x %d, himl is %d x %d\n",
+	bmp.bmWidth, bmp.bmHeight, himl->cx, himl->cy);
     if (himl->cx > 0)
 	nImageCount = bmp.bmWidth / himl->cx;
     else
@@ -304,67 +315,55 @@
 
     hdcBitmap = CreateCompatibleDC(0);
 
-
     hOldBitmap = SelectObject(hdcBitmap, hBitmap);
-    if(himl->hbmMask)
-    {
-        hdcMask = himl->hdcMask;
-        nMaskXOffset = nIndex * himl->cx;
-    }
-    else
-    {
-        /*
-            Create a temp Mask so we can remove the background of
-            the Image (Windows does this even if there is no mask)
-        */
-        hdcMask = CreateCompatibleDC(0);
-        hMaskBitmap = CreateBitmap(bmp.bmWidth, bmp.bmHeight, 1, 1, NULL);
-        SelectObject(hdcMask, hMaskBitmap);
-        nMaskXOffset = 0;
-    }
+
     /* create monochrome image to the mask bitmap */
     bkColor = (clrMask != CLR_DEFAULT) ? clrMask :
         GetPixel (hdcBitmap, 0, 0);
-    SetBkColor (hdcBitmap, bkColor);
-    BitBlt (hdcMask,
-        nMaskXOffset, 0, bmp.bmWidth, bmp.bmHeight,
-        hdcBitmap, 0, 0,
-        SRCCOPY);
 
-    SetBkColor(hdcBitmap, RGB(255,255,255));
-    /*Remove the background from the image
-    */
-    /*
-        WINDOWS BUG ALERT!!!!!!
-        The statement below should not be done in common practice
-        but this is how ImageList_AddMasked works in Windows.
-        It overwrites the original bitmap passed, this was discovered
-        by using the same bitmap to iterate the different styles
-        on windows where it failed (BUT ImageList_Add is OK)
-        This is here in case some apps rely on this bug
-    */
-    BitBlt(hdcBitmap,
-        0, 0, bmp.bmWidth, bmp.bmHeight,
-        hdcMask,
-        nMaskXOffset, 0,
-        0x220326); /* NOTSRCAND */
-    /* Copy result to the imagelist
-    */
-    BitBlt (himl->hdcImage,
-        nIndex * himl->cx, 0, bmp.bmWidth, bmp.bmHeight,
-        hdcBitmap,
-        0, 0,
-        SRCCOPY);
+    for (i=nIndex; i<himl->cCurImage; i++) {
+	if (himl->hbmMask) {
+	    SetBkColor (hdcBitmap, bkColor);
+
+	    BitBlt (himl->hdcMask,
+		index2x(i,himl->cx), index2y(i,himl->cy),
+		himl->cx, himl->cy,
+		hdcBitmap, himl->cx*(i-nIndex), 0,
+		SRCCOPY);
+
+	    SetBkColor(hdcBitmap, RGB(255,255,255));
+	    /*Remove the background from the image
+	    */
+	    /*
+		WINDOWS BUG ALERT!!!!!!
+		The statement below should not be done in common practice
+		but this is how ImageList_AddMasked works in Windows.
+		It overwrites the original bitmap passed, this was discovered
+		by using the same bitmap to iterate the different styles
+		on windows where it failed (BUT ImageList_Add is OK)
+		This is here in case some apps rely on this bug
+	    */
+	    BitBlt(hdcBitmap,
+		himl->cx*(i-nIndex), 0, himl->cx, himl->cy,
+		himl->hdcMask,
+		index2x(i,himl->cx), index2y(i,himl->cy),
+		0x220326); /* NOTSRCAND */
+	}
+	/* Copy result to the imagelist
+	*/
+	BitBlt (himl->hdcImage,
+	    index2x(i,himl->cx), index2y(i,himl->cy),
+	    himl->cx, himl->cy,
+	    hdcBitmap,
+	    himl->cx*(i-nIndex), 0,
+	    SRCCOPY);
+    }
+
     /* Clean up
     */
+
     SelectObject(hdcBitmap, hOldBitmap);
     DeleteDC(hdcBitmap);
-    if(!himl->hbmMask)
-    {
-        DeleteObject(hMaskBitmap);
-        DeleteDC(hdcMask);
-    }
-
     return nIndex;
 }
 
@@ -478,19 +477,20 @@
         /* image */
         SelectObject (hdcBmp, hbmTempImage);
         StretchBlt   (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
-                      himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      SRCCOPY);
+                      himlDst->hdcImage, index2x(iDst,himlDst->cx), index2y(iDst,himlDst->cy),
+                      himlDst->cx, himlDst->cy, SRCCOPY);
         /* mask */
         SelectObject (hdcBmp, hbmTempMask);
         StretchBlt   (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
-                      himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      SRCCOPY);
+                      himlDst->hdcMask, index2x(iDst,himlDst->cx), index2y(iDst,himlDst->cy),
+                      himlDst->cx, himlDst->cy, SRCCOPY);
 
         /* copy (and stretch) source to destination */
         /* image */
-        StretchBlt   (himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
-                      SRCCOPY);
+        StretchBlt   (himlDst->hdcImage, index2x(iDst,himlDst->cx), index2y(iDst,himlDst->cy),
+                      himlDst->cx, himlDst->cy,
+                      himlSrc->hdcImage, index2x(iSrc,himlSrc->cx), index2y(iSrc,himlSrc->cy),
+                      himlSrc->cx, himlSrc->cy, SRCCOPY);
         /* mask */
         StretchBlt   (himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
                       himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
@@ -511,13 +511,17 @@
     }
     else {
         /* copy image */
-        StretchBlt   (himlDst->hdcImage, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      himlSrc->hdcImage, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+        StretchBlt   (himlDst->hdcImage,
+                      index2x(iDst,himlDst->cx), index2y(iDst,himlDst->cy), himlDst->cx, himlDst->cy,
+                      himlSrc->hdcImage,
+                      index2x(iSrc,himlSrc->cx), index2y(iSrc,himlSrc->cy), himlSrc->cx, himlSrc->cy,
                       SRCCOPY);
 
         /* copy mask */
-        StretchBlt   (himlDst->hdcMask, iDst * himlDst->cx, 0, himlDst->cx, himlDst->cy,
-                      himlSrc->hdcMask, iSrc * himlSrc->cx, 0, himlSrc->cx, himlSrc->cy,
+        StretchBlt   (himlDst->hdcMask,
+                      index2x(iDst,himlDst->cx), index2y(iDst,himlDst->cy), himlDst->cx, himlDst->cy,
+                      himlSrc->hdcMask,
+                      index2x(iSrc,himlSrc->cx), index2y(iSrc,himlSrc->cy), himlSrc->cx, himlSrc->cy,
                       SRCCOPY);
     }
 
@@ -597,15 +601,15 @@
         himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
 
     if (himl->cMaxImage > 0) {
-        himl->hbmImage = ImageList_CreateImage(himl->hdcImage, himl, cx * himl->cMaxImage, cy);
+        himl->hbmImage = ImageList_CreateImage(himl->hdcImage, himl,
+                         count2x(himl->cMaxImage,cx), cy*PER_ROW);
 	SelectObject(himl->hdcImage, himl->hbmImage);
     } else
         himl->hbmImage = 0;
 
     if ((himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) {
-        himl->hbmMask =
-          CreateBitmap (himl->cx * himl->cMaxImage, himl->cy,
-			1, 1, NULL);
+        himl->hbmMask = CreateBitmap (count2x(himl->cMaxImage,himl->cx),
+                        himl->cy * PER_ROW, 1, 1, NULL);
         if (himl->hbmMask == 0) {
             ERR("Error creating mask bitmap!\n");
             goto cleanup;
@@ -1053,7 +1057,7 @@
  */
 
 BOOL WINAPI
-ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
+ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp) 
 {
     INT cx, cy, lx, ly, nOvlIdx;
     DWORD fState, dwRop;
@@ -1068,8 +1072,8 @@
     if (!is_valid(himl)) return FALSE;
     if ((pimldp->i < 0) || (pimldp->i >= himl->cCurImage)) return FALSE;
 
-    lx = himl->cx * pimldp->i + pimldp->xBitmap;
-    ly = pimldp->yBitmap;
+    lx = index2x(pimldp->i,himl->cx) + pimldp->xBitmap;
+    ly = index2y(pimldp->i,himl->cy) + pimldp->yBitmap;
 
     fState = pimldp->cbSize < sizeof(IMAGELISTDRAWPARAMS) ? ILS_NORMAL : pimldp->fState;
     fStyle = pimldp->fStyle & ~ILD_OVERLAYMASK;
@@ -1187,10 +1191,11 @@
     if ( (nOvlIdx >= 1) && (nOvlIdx <= MAX_OVERLAYIMAGE)) {
     	nOvlIdx = himl->nOvlIdx[nOvlIdx - 1];
     	if ((nOvlIdx >= 0) && (nOvlIdx < himl->cCurImage)) {
-    	    const INT ox = himl->cx * nOvlIdx + pimldp->xBitmap;
+    	    const INT ox = index2x(nOvlIdx,himl->cx) + pimldp->xBitmap;
+    	    const INT oy = index2y(nOvlIdx,himl->cy) + pimldp->yBitmap;
 	    if (himl->hbmMask && !(fStyle & ILD_IMAGE))
-		BitBlt (hImageDC, 0, 0, cx, cy, hMaskListDC, ox, ly, SRCAND);
-	    BitBlt (hImageDC, 0, 0, cx, cy, hImageListDC, ox, ly, SRCPAINT);
+		BitBlt (hImageDC, 0, 0, cx, cy, hMaskListDC, ox, oy, SRCAND);
+	    BitBlt (hImageDC, 0, 0, cx, cy, hImageListDC, ox, oy, SRCPAINT);
 	}
     }
 
@@ -1259,11 +1264,13 @@
 
     if (himlDst)
     {
-        BitBlt (himlDst->hdcImage, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
+        BitBlt (himlDst->hdcImage, 0, 0,
+                count2x(himlSrc->cCurImage,himlSrc->cx), himlSrc->cy*PER_ROW,
                 himlSrc->hdcImage, 0, 0, SRCCOPY);
 
         if (himlDst->hbmMask)
-            BitBlt (himlDst->hdcMask, 0, 0, himlSrc->cCurImage * himlSrc->cx, himlSrc->cy,
+            BitBlt (himlDst->hdcMask, 0, 0,
+                    count2x(himlSrc->cCurImage,himlSrc->cx), himlSrc->cy*PER_ROW,
                     himlSrc->hdcMask, 0, 0, SRCCOPY);
 
 	himlDst->cCurImage = himlSrc->cCurImage;
@@ -1421,7 +1428,9 @@
     hOldDstBitmap = SelectObject (hdcDst, ii.hbmMask);
     if (himl->hbmMask) {
         BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
-                himl->hdcMask, i * himl->cx, 0, SRCCOPY);
+                himl->hdcMask,
+                index2x(i,himl->cx), index2y(i,himl->cy),
+                SRCCOPY);
     }
     else
         PatBlt (hdcDst, 0, 0, himl->cx, himl->cy, BLACKNESS);
@@ -1429,7 +1438,8 @@
     /* draw image*/
     SelectObject (hdcDst, ii.hbmColor);
     BitBlt (hdcDst, 0, 0, himl->cx, himl->cy,
-            himl->hdcImage, i * himl->cx, 0, SRCCOPY);
+            himl->hdcImage,
+            index2x(i,himl->cx), index2y(i,himl->cy), SRCCOPY);
 
     /*
      * CreateIconIndirect requires us to deselect the bitmaps from
@@ -1531,11 +1541,10 @@
     pImageInfo->hbmImage = himl->hbmImage;
     pImageInfo->hbmMask  = himl->hbmMask;
 
-    pImageInfo->rcImage.top    = 0;
-    pImageInfo->rcImage.bottom = himl->cy;
-    pImageInfo->rcImage.left   = i * himl->cx;
-    pImageInfo->rcImage.right  = (i+1) * himl->cx;
-
+    pImageInfo->rcImage.top    = index2y(i,himl->cy);
+    pImageInfo->rcImage.bottom = index2y(i,himl->cy)+himl->cy;
+    pImageInfo->rcImage.left   = index2x(i,himl->cx);
+    pImageInfo->rcImage.right  = index2x(i,himl->cx)+himl->cx;
     return TRUE;
 }
 
@@ -1566,11 +1575,10 @@
     if ((i < 0) || (i >= himl->cCurImage))
 	return FALSE;
 
-    lpRect->left   = i * himl->cx;
-    lpRect->top    = 0;
+    lpRect->left   = index2x(i,himl->cx);
     lpRect->right  = lpRect->left + himl->cx;
-    lpRect->bottom = himl->cy;
-
+    lpRect->top    = index2y(i,himl->cy);
+    lpRect->bottom = lpRect->top  + himl->cy;
     return TRUE;
 }
 
@@ -1724,7 +1732,6 @@
     HIMAGELIST himlDst = NULL;
     INT      cxDst, cyDst;
     INT      xOff1, yOff1, xOff2, yOff2;
-    INT      nX1, nX2;
 
     TRACE("(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2,
 	   i2, dx, dy);
@@ -1768,25 +1775,29 @@
 
     if (himlDst)
     {
-        nX1 = i1 * himl1->cx;
-        nX2 = i2 * himl2->cx;
+        int x1, x2, y1, y2;
+
+        x1 = index2x(i1,himl1->cx);
+        y1 = index2y(i1,himl1->cy);
+        x2 = index2x(i2,himl2->cx);
+        y2 = index2y(i2,himl2->cy);
 
         /* copy image */
         BitBlt (himlDst->hdcImage, 0, 0, cxDst, cyDst, himl1->hdcImage, 0, 0, BLACKNESS);
         if (i1 >= 0 && i1 < himl1->cCurImage)
-            BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, nX1, 0, SRCCOPY);
+            BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, x1, y1, SRCCOPY);
         if (i2 >= 0 && i2 < himl2->cCurImage)
         {
-            BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , nX2, 0, SRCAND);
-            BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, nX2, 0, SRCPAINT);
+            BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , x2, y2, SRCAND);
+            BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, x2, y2, SRCPAINT);
         }
 
         /* copy mask */
         BitBlt (himlDst->hdcMask, 0, 0, cxDst, cyDst, himl1->hdcMask, 0, 0, WHITENESS);
         if (i1 >= 0 && i1 < himl1->cCurImage)
-            BitBlt (himlDst->hdcMask,  xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask,  nX1, 0, SRCCOPY);
+            BitBlt (himlDst->hdcMask,  xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask,  x1, y1, SRCCOPY);
         if (i2 >= 0 && i2 < himl2->cCurImage)
-            BitBlt (himlDst->hdcMask,  xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask,  nX2, 0, SRCAND);
+            BitBlt (himlDst->hdcMask,  xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask,  x2, y2, SRCAND);
 
 	himlDst->cCurImage = 1;
     }
@@ -1862,6 +1873,7 @@
 	nheight	= cy;
         nRows   = (height/cy);
 
+        FIXME("nwidth %d, nheight %d, cy %d\n", nwidth, nheight, cy);
 	if (bitsperpixel==1)
 	    hbitmap = CreateBitmap(nwidth,nheight,1,1,NULL);
 	else
@@ -2048,36 +2060,36 @@
         for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
              himl->nOvlIdx[nCount] = -1;
 
-        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage * himl->cx, himl->cy);
+        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl,
+                      count2x(himl->cMaxImage,himl->cx), himl->cy*PER_ROW);
         SelectObject (himl->hdcImage, hbmNewImage);
         DeleteObject (himl->hbmImage);
         himl->hbmImage = hbmNewImage;
 
         if (himl->hbmMask) {
-            hbmNewMask = CreateBitmap (himl->cMaxImage * himl->cx, himl->cy,
+            hbmNewMask = CreateBitmap (count2x(himl->cMaxImage,himl->cx), himl->cy*PER_ROW,
                                 1, 1, NULL);
             SelectObject (himl->hdcMask, hbmNewMask);
             DeleteObject (himl->hbmMask);
             himl->hbmMask = hbmNewMask;
         }
-    }
-    else {
+    } else {
         /* delete one image */
         TRACE("Remove single image! %d\n", i);
 
         /* create new bitmap(s) */
         nCount = (himl->cCurImage + himl->cGrow - 1);
-	cxNew = nCount * himl->cx;
+	cxNew = count2x(nCount , himl->cx);
 
         TRACE(" - Number of images: %d / %d (Old/New)\n",
                  himl->cCurImage, himl->cCurImage - 1);
         TRACE(" - Max. number of images: %d / %d (Old/New)\n",
                  himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);
 
-        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, cxNew, himl->cy);
+        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, cxNew, himl->cy*PER_ROW);
 
         if (himl->hbmMask)
-            hbmNewMask = CreateBitmap (cxNew, himl->cy, 1, 1, NULL);
+            hbmNewMask = CreateBitmap (cxNew, himl->cy*PER_ROW, 1, 1, NULL);
         else
             hbmNewMask = 0;  /* Just to keep compiler happy! */
 
@@ -2085,31 +2097,45 @@
 
         /* copy all images and masks prior to the "removed" image */
         if (i > 0) {
-            TRACE("Pre image copy: Copy %d images\n", i);
+            int n = count2x(i,1);
 
-            SelectObject (hdcBmp, hbmNewImage);
-            BitBlt (hdcBmp, 0, 0, i * himl->cx, himl->cy,
-                    himl->hdcImage, 0, 0, SRCCOPY);
-
-            if (himl->hbmMask) {
-                SelectObject (hdcBmp, hbmNewMask);
-                BitBlt (hdcBmp, 0, 0, i * himl->cx, himl->cy,
-                        himl->hdcMask, 0, 0, SRCCOPY);
+            TRACE("Pre image copy: Copy %d images\n", i);
+            if (n) { /* copy started rows */
+                SelectObject (hdcBmp, hbmNewImage);
+                BitBlt (hdcBmp, 0, 0, n * himl->cx, himl->cy * PER_ROW,
+                        himl->hdcImage, 0, 0, SRCCOPY);
+
+                if (himl->hbmMask) {
+                    SelectObject (hdcBmp, hbmNewMask);
+                    BitBlt (hdcBmp, 0, 0, n * himl->cx, himl->cy * PER_ROW,
+                            himl->hdcMask, 0, 0, SRCCOPY);
+                }
             }
+            /* this might copy some images more. But we will
+             * overwrite them right afterwards */
         }
 
         /* copy all images and masks behind the removed image */
         if (i < himl->cCurImage - 1) {
+            int j;
+
             TRACE("Post image copy!\n");
-            SelectObject (hdcBmp, hbmNewImage);
-            BitBlt (hdcBmp, i * himl->cx, 0, (himl->cCurImage - i - 1) * himl->cx,
-                      himl->cy, himl->hdcImage, (i + 1) * himl->cx, 0, SRCCOPY);
+
+            /* copy the post-i images one-by-one */
+	    SelectObject (hdcBmp, hbmNewImage);
+            for (j=i;j<himl->cCurImage -1;j++)
+                BitBlt (hdcBmp, index2x(j,himl->cx), index2y(j,himl->cy), himl->cx, himl->cy,
+                        himl->hdcImage, index2x(j+1,himl->cx), index2y(j+1,himl->cy), SRCCOPY);
 
             if (himl->hbmMask) {
                 SelectObject (hdcBmp, hbmNewMask);
-                BitBlt (hdcBmp, i * himl->cx, 0,
-                          (himl->cCurImage - i - 1) * himl->cx,
-                          himl->cy, himl->hdcMask, (i + 1) * himl->cx, 0, SRCCOPY);
+                for (j=i;j<himl->cCurImage -1;j++)
+                    BitBlt (hdcBmp,
+                            index2x(j,himl->cx), index2y(j,himl->cy),
+                            himl->cx, himl->cy,
+                            himl->hdcMask,
+                            index2x(j+1,himl->cx), index2y(j+1,himl->cy),
+                            SRCCOPY);
             }
         }
 
@@ -2290,12 +2316,16 @@
     SetBkColor  (himl->hdcImage, RGB(255,255,255));
     hbmOldSrc = SelectObject (hdcImage, ii.hbmColor);
 
-    StretchBlt (himl->hdcImage, nIndex * himl->cx, 0, himl->cx, himl->cy,
-                  hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
+    StretchBlt (himl->hdcImage,
+                index2x(nIndex,himl->cx), index2y(nIndex,himl->cy),
+                himl->cx, himl->cy,
+                hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
 
     if (himl->hbmMask) {
         SelectObject (hdcImage, ii.hbmMask);
-        StretchBlt   (himl->hdcMask, nIndex * himl->cx, 0, himl->cx, himl->cy,
+        StretchBlt   (himl->hdcMask,
+                      index2x(nIndex,himl->cx), index2y(nIndex,himl->cy),
+                      himl->cx, himl->cy,
                       hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
     }
 



More information about the wine-devel mailing list