*** empty log message ***
authorsr
Fri, 07 Aug 2009 17:35:34 +0200
changeset 5322 bdb7b311d584
parent 5321 714fd27c7de8
child 5323 a90a212f9429
*** empty log message ***
WinWorkstation.st
--- a/WinWorkstation.st	Fri Aug 07 12:52:03 2009 +0200
+++ b/WinWorkstation.st	Fri Aug 07 17:35:34 2009 +0200
@@ -10414,8 +10414,8 @@
     into:ignoredDrawableId
     x:dstx y:dsty
     width:w height:h
-    sourceAlpha:sourceAlphaOrNil
     with:aGCId
+    parameters:parameters
 
     "draw a bitImage which has depth id, width iw and height ih into
      the drawable. draw a region of w/h pixels from srcx/srcy to dstx/dsty.
@@ -10436,8 +10436,8 @@
 	x:dstx y:dsty
 	width:w height:h
 	with:aGCId
-	parameters:(Array with:sourceAlphaOrNil with:padd with:nil with:nil with:nil)
-	"/ the params array is ONLY used, because there is a 15-argument limit in st/x !
+	parameters:parameters
+	"/ the params array is ONLY used, because there is a 15-argument limit in st/x !!
     ) ifFalse:[
 	"
 	 also happens, if a segmentation violation occurs in the
@@ -10477,7 +10477,7 @@
 	width:w height:h
 	with:aGCId
 	parameters:(Array with:nil with:padd with:nil with:nil with:nil)
-	"/ the params array is ONLY used, because there is a 15-argument limit in st/x !
+	"/ the params array is ONLY used, because there is a 15-argument limit in st/x !!
     ) ifFalse:[
 	"
 	 also happens, if a segmentation violation occurs in the
@@ -10943,6 +10943,209 @@
     ^ false
 !
 
+primDrawBits:imageBits
+	bitsPerPixel:bitsPerPixel depth:imageDepth padding:padd
+	width:imageWidth height:imageHeight
+	x:srcx y:srcy
+	into:ignoredDrawableId
+	x:dstx y:dsty
+	width:w height:h
+	sourceAlpha:sourceAlphaOrNil
+	with:aGCId
+
+%{
+    unsigned char fastBits[10000];
+    unsigned char *b_bits = 0;
+    unsigned char *allocatedBits = 0;
+    struct gcData *gcData = 0;
+    HDC hDC = (HDC)0;
+    unsigned char *__imageBits = 0;
+    int _sourceAlpha = 0;
+
+    if (__isByteArray(imageBits)) {
+	__imageBits = __ByteArrayInstPtr(imageBits)->ba_element;
+    } else if (__isExternalBytesLike(imageBits)) {
+	__imageBits = (unsigned char *)(__externalBytesAddress(imageBits));
+    }
+
+    if (ISCONNECTED
+     && __isExternalAddress(aGCId)
+     && __bothSmallInteger(srcx, srcy)
+     && __bothSmallInteger(dstx, dsty)
+     && __bothSmallInteger(w, h)
+     && __bothSmallInteger(imageWidth, imageHeight)
+     && __bothSmallInteger(imageDepth, bitsPerPixel)
+     && __isSmallInteger(padd)
+     && __imageBits)
+     {
+	struct
+	{
+	  BITMAPINFOHEADER bmiHeader;
+	  DWORD r;
+	  DWORD g;
+	  DWORD b;
+	} bitmap;
+
+	gcData = _GCDATA(aGCId);
+	if (! gcData )
+	    goto fail;
+	hDC = _getDC(gcData);
+	DDPRINTF(("hDC = %x\n", hDC));
+
+	if (__intVal(padd) != WIN32PADDING) {
+	    int row, col;
+	    unsigned char *cp;
+	    unsigned char *pBits;
+	    int b_width, b_height, bytesPerRowST, bytesPerRowWN, padding, nBytes;
+	    int bi = __intVal(bitsPerPixel);
+
+	    b_width = __intVal(w);
+	    b_height = __intVal(h);
+	    bytesPerRowST = (b_width * bi + (__intVal(padd)-1)) / __intVal(padd);
+	    bytesPerRowWN = (b_width * bi + (WIN32PADDING-1)) / WIN32PADDING * (WIN32PADDING/8);
+	    padding = bytesPerRowWN - bytesPerRowST;
+	    nBytes = b_height * bytesPerRowWN;
+	    /*console_printf("padd %d bs %d bw %d p %d\n",__intVal(padd),bytesPerRowST,bytesPerRowWN,padding);*/
+	    if (padding) {
+		if (nBytes < sizeof(fastBits)) {
+		    cp = b_bits = fastBits;
+		} else {
+		    cp = b_bits = allocatedBits = (unsigned char *) malloc(nBytes);
+		}
+		if (cp) {
+		    pBits = __imageBits;
+		    for (row = b_height; row; row--) {
+			for (col = bytesPerRowST; col; col--) {
+			    *cp++ = *pBits++;
+			}
+			cp += padding;
+		    }
+		} else
+		    goto fail;
+	    }
+	}
+
+	if (b_bits == 0) {
+	    b_bits = __imageBits;
+	}
+
+	bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+	bitmap.bmiHeader.biPlanes = 1;
+	switch (__intVal(imageDepth)) {
+	    case 16:
+		/*bitmap.bmiHeader.biCompression = BI_RGB;
+		bitmap.bmiHeader.biCompression = BI_BITFIELDS;
+		bitmap.b = 0x001f;
+		bitmap.g = 0x07e0;
+		bitmap.r = 0xf800;*/
+		bitmap.b = 0;
+		bitmap.g = 0;
+		bitmap.r = 0;
+		bitmap.bmiHeader.biCompression = BI_RGB;
+		break;
+
+	    case 24:
+		/*bitmap.bmiHeader.biCompression = BI_BITFIELDS;
+		bitmap.r = 0xff0000;
+		bitmap.g = 0x00ff00;
+		bitmap.b = 0x0000ff;*/
+		bitmap.bmiHeader.biCompression = BI_RGB;
+		break;
+
+	    case 32:
+		/*bitmap.bmiHeader.biCompression = BI_BITFIELDS;
+		bitmap.r = 0xff0000;
+		bitmap.g = 0x00ff00;
+		bitmap.b = 0x0000ff;*/
+		bitmap.bmiHeader.biCompression = BI_RGB;
+		_sourceAlpha = __intVal(sourceAlphaOrNil);
+		break;
+	}
+
+	bitmap.bmiHeader.biSizeImage = 0;
+	bitmap.bmiHeader.biXPelsPerMeter = 0;
+	bitmap.bmiHeader.biYPelsPerMeter = 0;
+	bitmap.bmiHeader.biClrUsed = 0;
+	bitmap.bmiHeader.biClrImportant = 0;
+	bitmap.bmiHeader.biWidth = __intVal(imageWidth);
+	bitmap.bmiHeader.biHeight = -(__intVal(imageHeight));
+	bitmap.bmiHeader.biBitCount = __intVal(bitsPerPixel);
+	/*console_printf("drawBits depth:%d bitsPerPixel:%d IW%d W:%d H:%d\n",__intVal(imageDepth),bitmap.bmiHeader.biBitCount,bitmap.bmiHeader.biWidth,__intVal(w),bitmap.bmiHeader.biHeight);*/
+
+	if (sourceAlphaOrNil == nil) {
+	    SetDIBitsToDevice(hDC,
+				__intVal(dstx), __intVal(dsty),
+				__intVal(w), __intVal(h),
+				__intVal(srcx), __intVal(srcy),
+				0, __intVal(h),
+				(void *)b_bits,
+				(BITMAPINFO*)&bitmap,
+				DIB_RGB_COLORS);
+	} else {
+	    HDC ahdc;
+	    HBITMAP ahbitmap;
+	    void *pvBits;
+	    BLENDFUNCTION bf;
+	    static BOOL (__stdcall *P_AlphaBlend)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION );
+
+	    if (P_AlphaBlend == 0) {
+		/* as I dont have AlphaBlend in the inport32.lib (bcc sucks),
+		 * fetch its address dynamically...
+		 */
+		HINSTANCE hWinGDI = LoadLibrary("wingdi.dll");
+
+		if (hWinGDI) {
+		    P_AlphaBlend = (BOOL (__stdcall *)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION ))
+					GetProcAddress(hWinGDI, "AlphaBlend");
+		}
+	    }
+	    if (P_AlphaBlend != 0) {
+		ahdc = CreateCompatibleDC(hDC);
+		ahbitmap = CreateDIBSection(ahdc, &(bitmap.bmiHeader),
+					    DIB_RGB_COLORS, &pvBits, NULL, 0);
+		SelectObject(ahdc, ahbitmap);
+
+		bf.BlendOp = AC_SRC_OVER;
+		bf.BlendFlags = 0;
+		bf.SourceConstantAlpha = 0xFF;
+		bf.AlphaFormat = AC_SRC_ALPHA;
+
+		(*P_AlphaBlend) (hDC,
+				__intVal(dstx), __intVal(dsty),
+				__intVal(w), __intVal(h),
+				ahdc,
+				__intVal(srcx), __intVal(srcy),
+				0, __intVal(h),
+				bf);
+		DeleteObject(ahbitmap);
+		DeleteDC(ahdc);
+	    }
+	}
+	if (allocatedBits) {
+	    free(allocatedBits);
+	}
+#ifndef CACHE_LAST_DC
+	_releaseDC(gcData);
+#endif
+	RETURN ( true );
+    }
+
+fail: ;
+    PRINTF(("create temp bitmap FAILED!!!\n"));
+    if (allocatedBits) {
+	PRINTF(("freeing up temp bitmap bits ...\n"));
+	free(allocatedBits);
+    }
+#ifndef CACHE_LAST_DC
+    if (hDC) {
+	_releaseDC(gcData);
+    }
+#endif
+%}
+.
+    ^ false
+!
+
 primFillPolygon:aPolygon n:numberOfPoints in:ignoredDrawableId with:aGCId
 
 %{
@@ -18435,7 +18638,7 @@
 !WinWorkstation class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.397 2009-08-05 09:24:23 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.398 2009-08-07 15:35:34 sr Exp $'
 ! !
 
 WinWorkstation initialize!