--- a/WinWorkstation.st Mon Aug 03 19:18:14 2009 +0200
+++ b/WinWorkstation.st Mon Aug 03 19:19:53 2009 +0200
@@ -10406,12 +10406,47 @@
!
drawBits: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
- with:aGCId
+ width:imageWidth height:imageHeight
+ x:srcx y:srcy
+ into:ignoredDrawableId
+ x:dstx y:dsty
+ width:w height:h
+ sourceAlpha:sourceAlphaOrNil
+ with:aGCId
+
+ "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.
+ Individual source pixels have bitsPerPixel bits, allowing to draw
+ depth and pixel-units to be different.
+ It has to be checked elsewhere, that the server can do it with the given
+ depth - otherwise, primitive failure will be signalled.
+ Also it is assumed, that the colormap is setup correctly and the
+ colors are allocated - otherwise the colors may be wrong."
+
+ (self 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)
+ ifFalse:[
+ "
+ also happens, if a segmentation violation occurs in the
+ XPutImage ...
+ "
+ self primitiveFailed
+ ].
+!
+
+drawBits: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
+ with:aGCId
"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.
@@ -10427,18 +10462,19 @@
an unlimited stack, and thus cannot send primitiveFailed
"
(self 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
- with:aGCId)
+ width:imageWidth height:imageHeight
+ x:srcx y:srcy
+ into:ignoredDrawableId
+ x:dstx y:dsty
+ width:w height:h
+ sourceAlpha:nil
+ with:aGCId)
ifFalse:[
- "
- also happens, if a segmentation violation occurs in the
- XPutImage ...
- "
- self primitiveFailed
+ "
+ also happens, if a segmentation violation occurs in the
+ XPutImage ...
+ "
+ self primitiveFailed
].
!
@@ -10650,6 +10686,209 @@
%}
!
+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
+!
+
primDrawBits:imageBits bitsPerPixel:bitsPerPixel depth:imageDepth padding:padd
width:imageWidth height:imageHeight
x:srcx y:srcy
@@ -18287,7 +18526,7 @@
!WinWorkstation class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.395 2009-05-29 14:55:46 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/WinWorkstation.st,v 1.396 2009-08-03 17:19:53 cg Exp $'
! !
WinWorkstation initialize!