CVS: winex/dlls/msimg32 msimg32_main.c,1.7,1.8

[email protected]
Newsgroups gmane.comp.emulators.winex.cvs
Message-ID <[email protected]>
Subject: winex/dlls/msimg32 msimg32_main.c,1.7,1.8Update of /var/lib/cvsd/cvsroot/winex/dlls/msimg32
In directory agravaine:/tmp/cvs-serv31878/dlls/msimg32

Modified Files:
	msimg32_main.c 
Log Message:

Preliminary attempt at doing alpha blending manually for the AlphaBlend
function.  There are a number of issues with this currently, including
the following:
- Use of BITMAPINFOHEADER instead of BITMAPV5HEADER may mean that the DIB
  sections aren't actually being created with alpha
- Our StretchBlt implementation may not be capable of handling alpha



Index: msimg32_main.c
===================================================================
RCS file: /var/lib/cvsd/cvsroot/winex/dlls/msimg32/msimg32_main.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- msimg32_main.c	30 Mar 2007 21:33:01 -0000	1.7
+++ msimg32_main.c	27 Apr 2007 13:17:50 -0000	1.8
@@ -100,16 +100,93 @@
 		       int nWidthSrc, int nHeightSrc,
 		       BLENDFUNCTION blendFunction)
 {
-  FIXME("(%d, (%d,%d),(%d,%d), %d, (%d,%d),(%d,%d), (%d,%d,%d,%d)) stub!\n",
+  HDC hdcScratch;
+  BITMAPINFO bmiScratch;
+  HBITMAP hbmSrc, hbmDest;
+  BYTE *src, *dest;
+  int x,y,c;
+  
+  TRACE("(%d, (%d,%d),(%d,%d), %d, (%d,%d),(%d,%d), (%d,%d,%d,%d)) stub!\n",
         hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
 	hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, 
 	blendFunction.BlendOp, blendFunction.BlendFlags, 
 	blendFunction.SourceConstantAlpha, blendFunction.AlphaFormat);
-  StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
+  
+  if ((blendFunction.BlendOp != AC_SRC_OVER) || blendFunction.BlendFlags) {
+    FIXME("Invalid parameters\n");
+    return FALSE;
+  }
+  
+  /* Check for opaque case that doesn't need alpha blending */
+  if ((blendFunction.SourceConstantAlpha == 255) && (blendFunction.AlphaFormat == 0))
+  {
+    StretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest,
+               hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
+    return TRUE;
+  }
+  
+  /* create scratch dc and prep the dibsection header */
+  /* FIXME: change bmiScratch to a BITMAPV5HEADER to ensure DIB sections have alpha */
+  memset(&bmiScratch.bmiHeader, 0, sizeof(BITMAPINFOHEADER));
+  bmiScratch.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+  bmiScratch.bmiHeader.biWidth = nWidthDest;
+  bmiScratch.bmiHeader.biHeight = nHeightDest;
+  bmiScratch.bmiHeader.biPlanes = 1;
+  bmiScratch.bmiHeader.biBitCount = 32;
+  bmiScratch.bmiHeader.biCompression = BI_RGB;
+  
+  hdcScratch = CreateCompatibleDC(hdcDest);
+  
+  /* read in src */
+  /* FIXME: Our StretchBlt implementation is likely losing the alpha data during this copy.. */
+  hbmSrc = CreateDIBSection(hdcScratch, &bmiScratch, DIB_RGB_COLORS, (void**)(&src), 0, 0);
+  SelectObject(hdcScratch, hbmSrc);
+  StretchBlt(hdcScratch, 0, 0, nWidthDest, nHeightDest,
              hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
+  
+  /* read in dest */
+  hbmDest = CreateDIBSection(hdcScratch, &bmiScratch, DIB_RGB_COLORS, (void**)(&dest), 0, 0);
+  SelectObject(hdcScratch, hbmDest);
+  BitBlt(hdcScratch, 0, 0, nWidthDest, nHeightDest, hdcDest, nXOriginDest, nYOriginDest, SRCCOPY);
+  
+  /* blend them together in dest */
+  if (blendFunction.AlphaFormat == AC_SRC_ALPHA)
+  {
+    FLOAT sca = blendFunction.SourceConstantAlpha / 255.0;
+    for (y=0; y<nHeightDest; y++) {
+      for (x=0; x<nWidthDest; x++) {
+        FLOAT sa = src[(y * 4 * nWidthDest) + (x * 4) + 3] / 255.0;
+        for (c=0; c<4; c++)
+        {
+          BYTE s = src[(y * 4 * nWidthDest) + (x * 4) + c];
+          BYTE d = dest[(y * 4 * nWidthDest) + (x * 4) + c];
+          FLOAT t = (s * sca) + ((1 - sa) * d);
+          dest[(y * 4 * nWidthDest) + (x * 4) + c] = max(0, min(t, 255));
+        }
+      }
+    }
+  } else {
+    FLOAT sca = blendFunction.SourceConstantAlpha / 255.0;
+    for (y=0; y<nHeightDest; y++) {
+      for (x=0; x<nWidthDest; x++) {
+        for (c=0; c<4; c++)
+        {
+          BYTE s = src[(y * 4 * nWidthDest) + (x * 4) + c];
+          BYTE d = dest[(y * 4 * nWidthDest) + (x * 4) + c];
+          FLOAT t = (s * sca) + ((1 - sca) * d);
+          dest[(y * 4 * nWidthDest) + (x * 4) + c] = max(0, min(t, 255));
+        }
+      }
+    }
+  }
+  
+  /* copy to destination dc */
+  BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hdcScratch, 0, 0, SRCCOPY);
+  
+  /* delete objects */
+  DeleteObject(hbmDest);
+  DeleteObject(hbmSrc);
+  DeleteObject(hdcScratch);
+  
   return TRUE;
-/*
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
-*/
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.