16436 "/ self error:'textOut failed'. |
16438 "/ self error:'textOut failed'. |
16437 ! ! |
16439 ! ! |
16438 |
16440 |
16439 !WinWorkstation methodsFor:'retrieving pixels'! |
16441 !WinWorkstation methodsFor:'retrieving pixels'! |
16440 |
16442 |
16441 getBitsFromId:aDrawableId x:srcx y:srcy width:w height:h into:imageBits |
16443 getBitsFromId:aDrawableId x:srcX y:srcY width:w height:h into:imageBits |
16442 "get bits from a drawable into the imageBits. The storage for the bits |
16444 "get bits from a drawable into the imageBits. The storage for the bits |
16443 must be big enough for the data to fit. If ok, returns an array with some |
16445 must be big enough for the data to fit. If ok, returns an array with some |
16444 info and the bits in imageBits. The info contains the depth, bitOrder and |
16446 info and the bits in imageBits. The info contains the depth, bitOrder and |
16445 number of bytes per scanline. The number of bytes per scanline is not known |
16447 number of bytes per scanline. The number of bytes per scanline is not known |
16446 in advance, since the X-server is free to return whatever it thinks is a good padding." |
16448 in advance, since the Workstation is free to return whatever it thinks is a good padding." |
16447 |
16449 |
16448 |rawInfo info| |
16450 |error bytesPerLine bitmapPad bitsPerPixel| |
16449 |
16451 |
16450 ((w <= 0) or:[h <= 0]) ifTrue:[ |
16452 ((w <= 0) or:[h <= 0]) ifTrue:[ |
16451 self primitiveFailed. |
16453 ^ self primitiveFailed:'zero width or height'. |
16452 ^ nil |
|
16453 ]. |
16454 ]. |
16454 |
|
16455 rawInfo := Array new:11. |
|
16456 "1 -> bit order" |
|
16457 "2 -> depth" |
|
16458 "3 -> bytes_per_line" |
|
16459 "4 -> byte_order" |
|
16460 "5 -> format" |
|
16461 "6 -> bitmap_unit" |
|
16462 "7 -> bitmap_pad" |
|
16463 "8 -> bits_per_pixel" |
|
16464 "9 -> red_mask" |
|
16465 "10 -> green_mask" |
|
16466 "11 -> blue_mask" |
|
16467 |
|
16468 "/ had to extract the getPixel call into a separate method, to specify |
|
16469 "/ unlimitedStack (some implementations use alloca and require huge amounts |
|
16470 "/ of temporary stack space |
|
16471 |
|
16472 (self primGetBitsFrom:aDrawableId x:srcx y:srcy width:w height:h into:imageBits infoInto:rawInfo) ifTrue:[ |
|
16473 info := IdentityDictionary new. |
|
16474 info at:#bitOrder put:(rawInfo at:1). |
|
16475 info at:#depth put:(rawInfo at:2). |
|
16476 info at:#bytesPerLine put:(rawInfo at:3). |
|
16477 info at:#byteOrder put:(rawInfo at:4). |
|
16478 info at:#format put:(rawInfo at:5). |
|
16479 info at:#bitmapUnit put:(rawInfo at:6). |
|
16480 info at:#bitmapPad put:(rawInfo at:7). |
|
16481 info at:#bitsPerPixel put:(rawInfo at:8). |
|
16482 info at:#redMask put:(rawInfo at:9). |
|
16483 info at:#greenMask put:(rawInfo at:10). |
|
16484 info at:#blueMask put:(rawInfo at:11). |
|
16485 ^ info |
|
16486 ]. |
|
16487 " |
|
16488 some error occured - either args are not smallintegers, imageBits is not a ByteArray |
|
16489 or is too small to hold the bits |
|
16490 " |
|
16491 ^ self primitiveFailed |
|
16492 ! |
|
16493 |
|
16494 getBitsFromPixmapId:aDrawableId x:srcx y:srcy width:w height:h into:imageBits |
|
16495 "get bits from a drawable into the imageBits. The storage for the bits |
|
16496 must be big enough for the data to fit. If ok, returns an array with some |
|
16497 info and the bits in imageBits. The info contains the depth, bitOrder and |
|
16498 number of bytes per scanline. The number of bytes per scanline is not known |
|
16499 in advance, since the X-server is free to return whatever it thinks is a good padding." |
|
16500 |
|
16501 |rawInfo info| |
|
16502 |
|
16503 ((w <= 0) or:[h <= 0]) ifTrue:[ |
|
16504 self primitiveFailed. |
|
16505 ^ nil |
|
16506 ]. |
|
16507 |
|
16508 rawInfo := Array new:11. |
|
16509 "1 -> bit order" |
|
16510 "2 -> depth" |
|
16511 "3 -> bytes_per_line" |
|
16512 "4 -> byte_order" |
|
16513 "5 -> format" |
|
16514 "6 -> bitmap_unit" |
|
16515 "7 -> bitmap_pad" |
|
16516 "8 -> bits_per_pixel" |
|
16517 "9 -> red_mask" |
|
16518 "10 -> green_mask" |
|
16519 "11 -> blue_mask" |
|
16520 |
|
16521 "/ had to extract the getPixel call into a separate method, to specify |
|
16522 "/ unlimitedStack (some implementations use alloca and require huge amounts |
|
16523 "/ of temporary stack space |
|
16524 |
|
16525 (self primGetBitsFromPixmap:aDrawableId x:srcx y:srcy width:w height:h into:imageBits infoInto:rawInfo) ifTrue:[ |
|
16526 info := IdentityDictionary new. |
|
16527 info at:#bitOrder put:(rawInfo at:1). |
|
16528 info at:#depth put:(rawInfo at:2). |
|
16529 info at:#bytesPerLine put:(rawInfo at:3). |
|
16530 info at:#byteOrder put:(rawInfo at:4). |
|
16531 info at:#format put:(rawInfo at:5). |
|
16532 info at:#bitmapUnit put:(rawInfo at:6). |
|
16533 info at:#bitmapPad put:(rawInfo at:7). |
|
16534 info at:#bitsPerPixel put:(rawInfo at:8). |
|
16535 info at:#redMask put:(rawInfo at:9). |
|
16536 info at:#greenMask put:(rawInfo at:10). |
|
16537 info at:#blueMask put:(rawInfo at:11). |
|
16538 ^ info |
|
16539 ]. |
|
16540 " |
|
16541 some error occured - either args are not smallintegers, imageBits is not a ByteArray |
|
16542 or is too small to hold the bits |
|
16543 " |
|
16544 ^ self primitiveFailed |
|
16545 ! |
|
16546 |
|
16547 getPixelX:px y:py from:ignoredDrawableId with:aGCId |
|
16548 "return the pixel value at x/y; coordinates start at 0/0 for the upper left. |
|
16549 Nil is returned for invalid coordinates or if any other problem arises." |
|
16550 |
|
16551 %{ /* NOCONTEXT */ |
|
16552 if (__isExternalAddress(aGCId) |
|
16553 && __bothSmallInteger(px, py)) { |
|
16554 struct gcData *gcData = _GCDATA(aGCId); |
|
16555 HDC hDC; |
|
16556 int __x = __intVal(px), __y = __intVal(py); |
|
16557 int pixel; |
|
16558 |
|
16559 hDC = _getDC(gcData); |
|
16560 pixel = GetPixel(hDC, __x, __y); |
|
16561 #ifndef CACHE_LAST_DC |
|
16562 _releaseDC(gcData); |
|
16563 #endif |
|
16564 /* |
|
16565 * for compatibility, returns the pixelValue |
|
16566 * from a monochrome bitmap |
|
16567 */ |
|
16568 if (gcData->hBitmap) { |
|
16569 if (gcData->bitmapColorBitCount == 1) { |
|
16570 pixel = (pixel == 0) ? 0 : 1; |
|
16571 } |
|
16572 } |
|
16573 |
|
16574 RETURN ( __MKSMALLINT(pixel & 0xFFFFFF) ); |
|
16575 } |
|
16576 %}. |
|
16577 ^ nil |
|
16578 ! |
|
16579 |
|
16580 primGetBitsFrom:aDrawableId x:srcX y:srcY width:w height:h into:imageBits infoInto:info |
|
16581 |
16455 |
16582 %{ |
16456 %{ |
16583 int height, width; |
16457 int height, width; |
16584 unsigned int numBytes; |
16458 unsigned int numBytes; |
16585 int bytesPerRow; |
16459 int bytesPerRow; |
16586 HWND hWnd; |
16460 HWND hWnd; |
16587 HBITMAP hBitmap = 0; |
16461 HBITMAP hBitmap = 0; |
16588 HGDIOBJ hPrevious = 0; |
16462 HGDIOBJ hPrevious = 0; |
16589 HDC bDC = 0; |
16463 HDC bDC = 0; |
16590 struct { |
16464 struct { |
16591 BITMAPINFOHEADER bmiHeader; |
16465 BITMAPINFOHEADER bmiHeader; |
16592 DWORD r; |
16466 DWORD r; |
16593 DWORD g; |
16467 DWORD g; |
16594 DWORD b; |
16468 DWORD b; |
16595 } bitmap; |
16469 } bitmap; |
16596 |
16470 |
16597 if (! __isExternalAddress(aDrawableId)) { |
16471 if (! __isExternalAddress(aDrawableId)) { |
16598 INFOFPRINTF((stderr, "WinWorkstation [warning]: externalAddress arg\n")); |
16472 error = __MKSTRING("externalAddress arg"); |
16599 goto fail; |
16473 goto out; |
16600 } |
16474 } |
16601 if (! __bothSmallInteger(srcX, srcY)) { |
16475 if (! __bothSmallInteger(srcX, srcY)) { |
16602 INFOFPRINTF((stderr, "WinWorkstation [warning]: x,y args\n")); |
16476 error = __MKSTRING("x,y args"); |
16603 goto fail; |
16477 goto out; |
16604 } |
16478 } |
16605 if (! __bothSmallInteger(w, h)) { |
16479 if (! __bothSmallInteger(w, h)) { |
16606 INFOFPRINTF((stderr, "WinWorkstation [warning]: w,h args\n")); |
16480 error = __MKSTRING("w,h args"); |
16607 goto fail; |
16481 goto out; |
16608 } |
|
16609 if (! __isArray(info)) { |
|
16610 INFOFPRINTF((stderr, "WinWorkstation [warning]: info arg\n")); |
|
16611 goto fail; |
|
16612 } |
16482 } |
16613 if (! __isByteArray(imageBits)) { |
16483 if (! __isByteArray(imageBits)) { |
16614 INFOFPRINTF((stderr, "WinWorkstation [warning]: info arg\n")); |
16484 error = __MKSTRING("imageBits arg"); |
16615 goto fail; |
16485 goto out; |
16616 } |
16486 } |
16617 |
16487 |
16618 { |
16488 { |
16619 hWnd = _HWNDVal( aDrawableId ); |
16489 hWnd = _HWNDVal( aDrawableId ); |
16620 BMDPRINTF(("primGetBits %x\n",hWnd)); |
16490 BMDPRINTF(("primGetBits %x\n",hWnd)); |
16621 if( hWnd != 0 ) { |
16491 if ( hWnd != 0 ) { |
16622 HDC wDC; |
16492 HDC wDC; |
16623 HANDLE prevBitmap; |
16493 HANDLE prevBitmap; |
16624 int widthRoundedUpToNextMultipleOf4 = ((width + 3 ) / 4) * 4; |
16494 int widthRoundedUpToNextMultipleOf4 = ((width + 3 ) / 4) * 4; |
16625 int widthUsed; |
16495 int widthUsed; |
16626 |
16496 |
16627 bDC = CreateCompatibleDC(__rootDC); |
16497 bDC = CreateCompatibleDC(__rootDC); |
16628 |
16498 |
16629 BMDPRINTF(("primGetBits srcX %d srcY %d w %d h %d\n",__intVal(srcX),__intVal(srcY),__intVal(w),__intVal(h))); |
16499 BMDPRINTF(("primGetBits srcX %d srcY %d w %d h %d\n",__intVal(srcX),__intVal(srcY),__intVal(w),__intVal(h))); |
16630 height = __intVal(h); |
16500 height = __intVal(h); |
16631 width = __intVal(w); |
16501 width = __intVal(w); |
16632 |
16502 |
16633 widthUsed = widthRoundedUpToNextMultipleOf4; |
16503 widthUsed = widthRoundedUpToNextMultipleOf4; |
16634 widthUsed = width; |
16504 widthUsed = width; |
16635 |
16505 |
16636 BMDPRINTF(("width %d height %d\n",width,height)); |
16506 BMDPRINTF(("width %d height %d\n",width,height)); |
16637 hBitmap = CreateCompatibleBitmap(__rootDC, widthUsed, height); |
16507 hBitmap = CreateCompatibleBitmap(__rootDC, widthUsed, height); |
16638 if (!hBitmap) { |
16508 if (!hBitmap) { |
16639 INFOFPRINTF((stderr, "WinWorkstation [warning]: CreateCompatibleBitmap failed\n")); |
16509 error = __MKSTRING("CreateCompatibleBitmap failed"); |
16640 goto fail; |
16510 goto out; |
16641 } |
16511 } |
16642 bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
16512 bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
16643 bitmap.bmiHeader.biPlanes = 1; |
16513 bitmap.bmiHeader.biPlanes = 1; |
16644 #ifdef ALWAYSTRUECOLOR |
16514 #ifdef ALWAYSTRUECOLOR |
16645 bitmap.bmiHeader.biCompression = BI_RGB; |
16515 bitmap.bmiHeader.biCompression = BI_RGB; |
16646 bytesPerRow = (((width*3) + 3 ) / 4) * 4; |
16516 bytesPerRow = (((width*3) + 3 ) / 4) * 4; |
16647 #else |
16517 #else |
16648 if (__depth == 24) { |
16518 if (__depth == 24) { |
16649 bitmap.bmiHeader.biCompression = BI_RGB; |
16519 bitmap.bmiHeader.biCompression = BI_RGB; |
16650 bytesPerRow = (((width*3) + 3 ) / 4) * 4; |
16520 bytesPerRow = (((width*3) + 3 ) / 4) * 4; |
16651 } else if (__depth == 16) { |
16521 } else if (__depth == 16) { |
16652 # if 0 |
16522 # if 0 |
16653 bitmap.bmiHeader.biCompression = BI_BITFIELDS; |
16523 bitmap.bmiHeader.biCompression = BI_BITFIELDS; |
16654 bitmap.b = 0x001f; |
16524 bitmap.b = 0x001f; |
16655 bitmap.g = 0x07e0; |
16525 bitmap.g = 0x07e0; |
16656 bitmap.r = 0xf800; |
16526 bitmap.r = 0xf800; |
16657 bytesPerRow = (((width*2) + 1 ) / 4) * 4; |
16527 bytesPerRow = (((width*2) + 1 ) / 4) * 4; |
16658 # else |
16528 # else |
16659 bitmap.b = 0; |
16529 bitmap.b = 0; |
16660 bitmap.g = 0; |
16530 bitmap.g = 0; |
16661 bitmap.r = 0; |
16531 bitmap.r = 0; |
16662 bitmap.bmiHeader.biCompression = BI_RGB; |
16532 bitmap.bmiHeader.biCompression = BI_RGB; |
16663 bytesPerRow = (((width*3) + 3 ) / 4) * 4; |
16533 bytesPerRow = (((width*3) + 3 ) / 4) * 4; |
16664 # endif |
16534 # endif |
16665 } |
16535 } |
16666 #endif /* ALWAYSTRUECOLOR */ |
16536 #endif /* ALWAYSTRUECOLOR */ |
16667 bitmap.bmiHeader.biSizeImage = 0; |
16537 bitmap.bmiHeader.biSizeImage = 0; |
16668 bitmap.bmiHeader.biXPelsPerMeter = 0; |
16538 bitmap.bmiHeader.biXPelsPerMeter = 0; |
16669 bitmap.bmiHeader.biYPelsPerMeter = 0; |
16539 bitmap.bmiHeader.biYPelsPerMeter = 0; |
16670 bitmap.bmiHeader.biClrUsed = 0; |
16540 bitmap.bmiHeader.biClrUsed = 0; |
16671 bitmap.bmiHeader.biClrImportant = 0; |
16541 bitmap.bmiHeader.biClrImportant = 0; |
16672 bitmap.bmiHeader.biBitCount = __depth; |
16542 bitmap.bmiHeader.biBitCount = __depth; |
16673 |
16543 |
16674 bitmap.bmiHeader.biWidth = widthUsed; |
16544 bitmap.bmiHeader.biWidth = widthUsed; |
16675 bitmap.bmiHeader.biHeight = -height; |
16545 bitmap.bmiHeader.biHeight = -height; |
16676 |
16546 |
16677 wDC = GetDC(hWnd); |
16547 wDC = GetDC(hWnd); |
16678 |
16548 |
16679 hPrevious = SelectObject(bDC, hBitmap); |
16549 hPrevious = SelectObject(bDC, hBitmap); |
16680 if (BitBlt(bDC, |
16550 if (BitBlt(bDC, |
16681 0,0, |
16551 0,0, |
16682 width,height, |
16552 width,height, |
16683 wDC, |
16553 wDC, |
16684 __intVal(srcX), __intVal(srcY), |
16554 __intVal(srcX), __intVal(srcY), |
16685 SRCCOPY|CAPTUREBLT) |
16555 SRCCOPY|CAPTUREBLT) |
16686 == 0 |
16556 == 0 |
16687 ) |
16557 ) |
16688 { |
16558 { |
16689 INFOFPRINTF((stderr, "WinWorkstation [warning]: in primGetBitsFrom: BitBlt\n")); |
16559 INFOFPRINTF((stderr, "WinWorkstation [warning]: in primGetBitsFrom: BitBlt\n")); |
16690 } |
16560 } |
16691 |
16561 |
16692 #ifdef CACHE_LAST_DC |
16562 #ifdef CACHE_LAST_DC |
16693 if (lastGcData && (lastGcData->_hDC == wDC)) { |
16563 if (lastGcData && (lastGcData->_hDC == wDC)) { |
16694 # ifdef DEBUG_DC_REUSE |
16564 # ifdef DEBUG_DC_REUSE |
16695 console_fprintf(stderr, "WinWorkstation [info]: Oops - dont release - cachedDC reuse\n", __LINE__); |
16565 console_fprintf(stderr, "WinWorkstation [info]: Oops - dont release - cachedDC reuse\n", __LINE__); |
16696 # endif |
16566 # endif |
16697 } else |
16567 } else |
16698 #endif |
16568 #endif |
16699 { |
16569 { |
16700 #ifdef CACHE_LAST_WM_PAINT_DC |
16570 #ifdef CACHE_LAST_WM_PAINT_DC |
16701 if (last_wm_paint_dc && (last_wm_paint_dc == wDC)) { |
16571 if (last_wm_paint_dc && (last_wm_paint_dc == wDC)) { |
16702 # ifdef DEBUG_DC_REUSE |
16572 # ifdef DEBUG_DC_REUSE |
16703 console_fprintf(stderr, "WinWorkstation [info]: Oops - dont release - last_wm_paint_dc reuse\n", __LINE__); |
16573 console_fprintf(stderr, "WinWorkstation [info]: Oops - dont release - last_wm_paint_dc reuse\n", __LINE__); |
16704 # endif |
16574 # endif |
16705 } else |
16575 } else |
16706 #endif |
16576 #endif |
16707 { |
16577 { |
16708 ReleaseDC(hWnd, wDC); |
16578 ReleaseDC(hWnd, wDC); |
16709 } |
16579 } |
16710 } |
16580 } |
16711 |
16581 |
16712 if (GetDIBits(bDC,hBitmap,0,height,0,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16582 if (GetDIBits(bDC,hBitmap,0,height,0,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16713 { |
16583 { |
16714 INFOFPRINTF((stderr, "WinWorkstation [warning]: noinfo returned in primGetBits\n")); |
16584 error = __MKSTRING("noinfo returned in primGetBits"); |
16715 goto fail; |
16585 goto out; |
16716 } |
16586 } |
16717 BMDPRINTF(("bitmap info:%d %d %d %d\n", |
16587 BMDPRINTF(("bitmap info:%d %d %d %d\n", |
16718 bitmap.bmiHeader.biWidth, bitmap.bmiHeader.biHeight, |
16588 bitmap.bmiHeader.biWidth, bitmap.bmiHeader.biHeight, |
16719 bitmap.bmiHeader.biBitCount, bitmap.bmiHeader.biSizeImage)); |
16589 bitmap.bmiHeader.biBitCount, bitmap.bmiHeader.biSizeImage)); |
16720 numBytes = bitmap.bmiHeader.biSizeImage; |
16590 numBytes = bitmap.bmiHeader.biSizeImage; |
16721 if( numBytes != 0 ) { |
16591 if ( numBytes != 0 ) { |
16722 if (numBytes > __byteArraySize(imageBits)) { |
16592 if (numBytes > __byteArraySize(imageBits)) { |
16723 /* imageBits too small */ |
16593 /* imageBits too small */ |
16724 INFOFPRINTF((stderr, "WinWorkstation [warning]: primGetBits - byteArray too small (is:%d need:%d; w:%d h:%d)\n", |
16594 INFOFPRINTF((stderr, "WinWorkstation [warning]: primGetBits - byteArray too small (is:%d need:%d; w:%d h:%d)\n", |
16725 __byteArraySize(imageBits), numBytes, |
16595 __byteArraySize(imageBits), numBytes, |
16726 bitmap.bmiHeader.biWidth, -bitmap.bmiHeader.biHeight |
16596 bitmap.bmiHeader.biWidth, -bitmap.bmiHeader.biHeight |
16727 )); |
16597 )); |
16728 goto fail; |
16598 error = __MKSTRING("byteArray too small"); |
16729 } |
16599 goto out; |
16730 BMDPRINTF(("numBytes %d\n",numBytes)); |
16600 } |
16731 |
16601 BMDPRINTF(("numBytes %d\n",numBytes)); |
16732 bitmap.bmiHeader.biHeight = -height; |
16602 |
16733 if (GetDIBits(bDC,hBitmap,0,height,__ByteArrayInstPtr(imageBits)->ba_element,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16603 bitmap.bmiHeader.biHeight = -height; |
16734 { |
16604 if (GetDIBits(bDC,hBitmap,0,height,__ByteArrayInstPtr(imageBits)->ba_element,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16735 INFOFPRINTF((stderr, "WinWorkstation [warning]: zero bits returned in primGetBits\n")); |
16605 { |
16736 goto fail; |
16606 error = __MKSTRING("zero bits returned in primGetBits"); |
16737 } |
16607 goto out; |
16738 |
16608 } |
16739 /* swap red and blue (windows delivers BGR) */ |
16609 |
16740 { |
16610 /* swap red and blue (windows delivers BGR) */ |
16741 char *cp = __ByteArrayInstPtr(imageBits)->ba_element; |
16611 { |
16742 #ifdef PRE_18_FEB_05 |
16612 char *cp = __ByteArrayInstPtr(imageBits)->ba_element; |
16743 int n = numBytes; |
16613 int _h; |
16744 for ( ;n > 0; n -= 3, cp += 3) { |
16614 char *rowp = cp; |
16745 char b = cp[0]; |
16615 |
16746 cp[0] = cp[2]; |
16616 for (_h=height; _h>0; _h--) { |
16747 cp[2] = b; |
16617 int _w; |
16748 } |
16618 char *pixel = rowp; |
16749 #else |
16619 |
16750 int _h; |
16620 for (_w=width; _w>0; _w--) { |
16751 char *rowp = cp; |
16621 char b; |
16752 |
16622 |
16753 for (_h=height; _h>0; _h--) { |
16623 b = pixel[0]; |
16754 int _w; |
16624 pixel[0] = pixel[2]; |
16755 char *pixel = rowp; |
16625 pixel[2] = b; |
16756 |
16626 pixel += 3; |
16757 for (_w=width; _w>0; _w--) { |
16627 }; |
16758 char b; |
16628 rowp += bytesPerRow; |
16759 |
16629 }; |
16760 b = pixel[0]; |
16630 } |
16761 pixel[0] = pixel[2]; |
16631 } else { |
16762 pixel[2] = b; |
16632 error = __MKSTRING("unacceptable bitmap in primGetBits"); |
16763 pixel += 3; |
16633 goto out; |
16764 }; |
16634 } |
16765 rowp += bytesPerRow; |
16635 } else { |
16766 }; |
16636 error = __MKSTRING("unacceptable HWND in primGetBits"); |
16767 #endif |
16637 goto out; |
16768 } |
16638 } |
16769 } else { |
16639 |
16770 INFOFPRINTF((stderr, "WinWorkstation [warning]: unacceptable bitmap in primGetBits\n")); |
16640 bytesPerLine = __MKSMALLINT(bytesPerRow); |
16771 goto fail; |
16641 bitmapPad = __MKSMALLINT(WIN32PADDING); |
16772 } |
16642 bitsPerPixel = __MKSMALLINT(bitmap.bmiHeader.biBitCount); |
16773 } else { |
16643 } |
16774 INFOFPRINTF((stderr, "WinWorkstation [warning]: unacceptable HWND in primGetBits\n")); |
16644 |
16775 goto fail; |
16645 out: |
16776 } |
|
16777 |
|
16778 __ArrayInstPtr(info)->a_element[0] = @symbol(msbFirst); // bitOrder |
|
16779 __ArrayInstPtr(info)->a_element[1] = __MKSMALLINT(1); // depth |
|
16780 __ArrayInstPtr(info)->a_element[2] = __MKSMALLINT(bytesPerRow); // bytesPerLine |
|
16781 __ArrayInstPtr(info)->a_element[3] = @symbol(msbFirst); // byteOrder |
|
16782 __ArrayInstPtr(info)->a_element[4] = @symbol(XYPixmap); // format |
|
16783 __ArrayInstPtr(info)->a_element[5] = __MKSMALLINT(0); // bitmapUnit |
|
16784 __ArrayInstPtr(info)->a_element[6] = __MKSMALLINT(WIN32PADDING); // bitmapPad |
|
16785 __ArrayInstPtr(info)->a_element[7] = __MKSMALLINT(bitmap.bmiHeader.biBitCount); // bitsPerPixel |
|
16786 __ArrayInstPtr(info)->a_element[8] = __MKSMALLINT(0x0000FF); // redMask |
|
16787 __ArrayInstPtr(info)->a_element[9] = __MKSMALLINT(0x00FF00); // greenMask |
|
16788 __ArrayInstPtr(info)->a_element[10] = __MKSMALLINT(0xFF0000); // blueMask |
|
16789 if ((hPrevious != NULL) && (bDC != NULL)) |
|
16790 SelectObject(bDC, hPrevious); |
|
16791 if (bDC) |
|
16792 DeleteDC(bDC); |
|
16793 if (hBitmap) |
|
16794 _DeleteObject(hBitmap, __LINE__); |
|
16795 RETURN ( true ); |
|
16796 } |
|
16797 fail: ; |
|
16798 if ((hPrevious != NULL) && (bDC != NULL)) |
16646 if ((hPrevious != NULL) && (bDC != NULL)) |
16799 SelectObject(bDC, hPrevious); |
16647 SelectObject(bDC, hPrevious); |
16800 if (bDC) |
16648 if (bDC) |
16801 DeleteDC(bDC); |
16649 DeleteDC(bDC); |
16802 if (hBitmap) |
16650 if (hBitmap) |
16803 _DeleteObject(hBitmap, __LINE__); |
16651 _DeleteObject(hBitmap, __LINE__); |
16804 %}. |
16652 %}. |
16805 ^ false |
16653 |
16806 ! |
16654 error notNil ifTrue:[ |
16807 |
16655 ^ self primitiveFailed:error. |
16808 primGetBitsFromPixmap:aDrawableId x:srcX y:srcY width:w height:h into:imageBits infoInto:info |
16656 ]. |
|
16657 |
|
16658 |
|
16659 ^ IdentityDictionary new |
|
16660 at:#bitOrder put:#msbFirst; |
|
16661 at:#depth put:1; |
|
16662 at:#bytesPerLine put:bytesPerLine; |
|
16663 at:#byteOrder put:#lsbFirst; |
|
16664 at:#format put:#XYPixmap; |
|
16665 at:#bitmapUnit put:0; |
|
16666 at:#bitmapPad put:bitmapPad; |
|
16667 at:#bitsPerPixel put:bitsPerPixel; |
|
16668 at:#redMask put:16rFF0000; |
|
16669 at:#greenMask put:16r00FF00; |
|
16670 at:#blueMask put:16r0000FF; |
|
16671 yourself. |
|
16672 |
|
16673 "Modified (comment): / 28-03-2017 / 14:28:39 / stefan" |
|
16674 ! |
|
16675 |
|
16676 getBitsFromPixmapId:aDrawableId x:srcX y:srcY width:w height:h into:imageBits |
|
16677 "get bits from a drawable into the imageBits. The storage for the bits |
|
16678 must be big enough for the data to fit. If ok, returns an array with some |
|
16679 info and the bits in imageBits. The info contains the depth, bitOrder and |
|
16680 number of bytes per scanline. The number of bytes per scanline is not known |
|
16681 in advance, since the Workstation is free to return whatever it thinks is a good padding." |
|
16682 |
|
16683 |rawInfo error bytesPerLine format bitmapPad bitsPerPixel| |
|
16684 |
|
16685 ((w <= 0) or:[h <= 0]) ifTrue:[ |
|
16686 self primitiveFailed:'zero width or height'. |
|
16687 ^ nil |
|
16688 ]. |
|
16689 |
|
16690 rawInfo := Array new:11. |
16809 |
16691 |
16810 %{ |
16692 %{ |
16811 int height, width; |
16693 int height, width; |
16812 unsigned int numBytes; |
16694 unsigned int numBytes; |
16813 unsigned char* ep = 0; |
16695 unsigned char* ep = 0; |
16815 HBITMAP hBitmap = 0; |
16697 HBITMAP hBitmap = 0; |
16816 HDC bDC = 0; |
16698 HDC bDC = 0; |
16817 HDC xDC = 0; |
16699 HDC xDC = 0; |
16818 struct |
16700 struct |
16819 { |
16701 { |
16820 BITMAPINFOHEADER bmiHeader; |
16702 BITMAPINFOHEADER bmiHeader; |
16821 DWORD rgb[2]; |
16703 DWORD rgb[2]; |
16822 } bitmap; |
16704 } bitmap; |
16823 BITMAP bitmapInfo; |
16705 BITMAP bitmapInfo; |
16824 |
16706 |
16825 if (__isExternalAddress(aDrawableId) |
16707 if (__isExternalAddress(aDrawableId) |
16826 && __bothSmallInteger(srcX, srcY) |
16708 && __bothSmallInteger(srcX, srcY) |
16827 && __bothSmallInteger(w, h) |
16709 && __bothSmallInteger(w, h) |
16828 && __isArray(info) |
16710 && __isArray(rawInfo) && __arraySize(rawInfo) >= 11 |
16829 && __isByteArray(imageBits)) |
16711 && __isByteArray(imageBits)) |
16830 { |
16712 { |
16831 xBitmap = _HBITMAPVAL( aDrawableId ); |
16713 xBitmap = _HBITMAPVAL( aDrawableId ); |
16832 BMDPRINTF(("primGetBitsFromPixmap %x\n",xBitmap)); |
16714 BMDPRINTF(("primGetBitsFromPixmap %x\n",xBitmap)); |
16833 if (xBitmap != 0) { |
16715 if (xBitmap != 0) { |
16834 xDC = GetDC(0); |
16716 xDC = GetDC(0); |
16835 SelectObject(xDC, xBitmap); |
16717 SelectObject(xDC, xBitmap); |
16836 GetObject(xBitmap,sizeof(bitmapInfo),&bitmapInfo); |
16718 GetObject(xBitmap,sizeof(bitmapInfo),&bitmapInfo); |
16837 |
16719 |
16838 bDC = CreateCompatibleDC(__rootDC); |
16720 bDC = CreateCompatibleDC(__rootDC); |
16839 BMDPRINTF(("srcX %d srcY %d w %d h %d\n",__intVal(srcX),__intVal(srcY),__intVal(w),__intVal(h))); |
16721 BMDPRINTF(("srcX %d srcY %d w %d h %d\n",__intVal(srcX),__intVal(srcY),__intVal(w),__intVal(h))); |
16840 height = __intVal(h); |
16722 height = __intVal(h); |
16841 width = __intVal(w); |
16723 width = __intVal(w); |
16842 BMDPRINTF(("width %d height %d\n",width,height)); |
16724 BMDPRINTF(("width %d height %d\n",width,height)); |
16843 |
16725 |
16844 hBitmap = CreateCompatibleBitmap(xDC, width, height); |
16726 hBitmap = CreateCompatibleBitmap(xDC, width, height); |
16845 if (!hBitmap) |
16727 if (!hBitmap) { |
16846 goto fail; |
16728 error = __MKSTRING("create bitmap failed"); |
16847 |
16729 goto out; |
16848 SelectObject(bDC,hBitmap); |
16730 } |
16849 if (BitBlt(bDC, |
16731 |
16850 0,0, |
16732 SelectObject(bDC,hBitmap); |
16851 width,height, |
16733 if (BitBlt(bDC, |
16852 xDC, |
16734 0,0, |
16853 __intVal(srcX), __intVal(srcY), |
16735 width,height, |
16854 SRCCOPY) |
16736 xDC, |
16855 == 0 |
16737 __intVal(srcX), __intVal(srcY), |
16856 ) |
16738 SRCCOPY) |
16857 { |
16739 == 0 |
16858 BMDPRINTF(("ERROR in primGetBitsFromPixmap: BitBlt\n")); |
16740 ) |
16859 goto fail; |
16741 { |
16860 } |
16742 error = __MKSTRING("BitBlt failed"); |
16861 bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
16743 goto out; |
16862 bitmap.bmiHeader.biPlanes = 1; |
16744 } |
|
16745 bitmap.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
|
16746 bitmap.bmiHeader.biPlanes = 1; |
16863 #ifdef ALWAYSTRUECOLOR |
16747 #ifdef ALWAYSTRUECOLOR |
16864 bitmap.bmiHeader.biCompression = BI_RGB; |
16748 bitmap.bmiHeader.biCompression = BI_RGB; |
16865 #else |
16749 #else |
16866 if (__depth == 24) { |
16750 if (__depth == 24) { |
16867 /*bitmap.bmiHeader.biCompression = BI_BITFIELDS; |
16751 /*bitmap.bmiHeader.biCompression = BI_BITFIELDS; |
16868 bitmap.r = 0xff0000; |
16752 bitmap.r = 0xff0000; |
16869 bitmap.g = 0x00ff00; |
16753 bitmap.g = 0x00ff00; |
16870 bitmap.b = 0x0000ff;*/ |
16754 bitmap.b = 0x0000ff;*/ |
16871 bitmap.bmiHeader.biCompression = BI_RGB; |
16755 bitmap.bmiHeader.biCompression = BI_RGB; |
16872 } else if (__depth == 16) { |
16756 } else if (__depth == 16) { |
16873 /*bitmap.bmiHeader.biCompression = BI_RGB; |
16757 bitmap.b = 0x001f; |
16874 bitmap.bmiHeader.biCompression = BI_BITFIELDS; |
16758 bitmap.g = 0x07e0; |
16875 bitmap.b = 0x001f; |
16759 bitmap.r = 0xf800;*/ |
16876 bitmap.g = 0x07e0; |
16760 bitmap.bmiHeader.biCompression = BI_RGB; |
16877 bitmap.r = 0xf800;*/ |
16761 } else { |
16878 bitmap.bmiHeader.biCompression = BI_RGB; |
16762 error = __MKSTRING("primGetBitsFromPixmap: unsupported depth"); |
16879 } else { |
16763 got fail; |
16880 BMDPRINTF(("primGetBitsFromPixmap: unsupported depth\n")); |
16764 } |
16881 got fail; |
|
16882 } |
|
16883 #endif /* ALWAYSTRUECOLOR */ |
16765 #endif /* ALWAYSTRUECOLOR */ |
16884 bitmap.bmiHeader.biSizeImage = 0; |
16766 bitmap.bmiHeader.biSizeImage = 0; |
16885 bitmap.bmiHeader.biXPelsPerMeter = 0; |
16767 bitmap.bmiHeader.biXPelsPerMeter = 0; |
16886 bitmap.bmiHeader.biYPelsPerMeter = 0; |
16768 bitmap.bmiHeader.biYPelsPerMeter = 0; |
16887 bitmap.bmiHeader.biClrUsed = 0; |
16769 bitmap.bmiHeader.biClrUsed = 0; |
16888 bitmap.bmiHeader.biClrImportant = 0; |
16770 bitmap.bmiHeader.biClrImportant = 0; |
16889 |
16771 |
16890 bitmap.bmiHeader.biWidth = width; |
16772 bitmap.bmiHeader.biWidth = width; |
16891 bitmap.bmiHeader.biHeight = -height; |
16773 bitmap.bmiHeader.biHeight = -height; |
16892 bitmap.bmiHeader.biBitCount = bitmapInfo.bmBitsPixel; |
16774 bitmap.bmiHeader.biBitCount = bitmapInfo.bmBitsPixel; |
16893 |
16775 |
16894 if (GetDIBits(bDC,hBitmap,0,height,0,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16776 if (GetDIBits(bDC,hBitmap,0,height,0,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16895 { |
16777 { |
16896 BMDPRINTF(("noinfo returned\n")); |
16778 error = __MKSTRING("GetDIBits failed"); |
16897 goto fail; |
16779 goto out; |
16898 } |
16780 } |
16899 BMDPRINTF(("bitmap info:%d %d %d %d\n",bitmap.bmiHeader.biWidth,bitmap.bmiHeader.biHeight,bitmap.bmiHeader.biBitCount,bitmap.bmiHeader.biSizeImage)); |
16781 BMDPRINTF(("bitmap info:%d %d %d %d\n",bitmap.bmiHeader.biWidth,bitmap.bmiHeader.biHeight,bitmap.bmiHeader.biBitCount,bitmap.bmiHeader.biSizeImage)); |
16900 numBytes = bitmap.bmiHeader.biSizeImage; |
16782 numBytes = bitmap.bmiHeader.biSizeImage; |
16901 if ( numBytes != 0 ) { |
16783 if ( numBytes != 0 ) { |
16902 if (numBytes > __byteArraySize(imageBits)) { |
16784 if (numBytes > __byteArraySize(imageBits)) { |
16903 /* imageBits too small */ |
16785 /* imageBits too small */ |
16904 BMDPRINTF(("provided byteArray too small\n")); |
16786 error = __MKSTRING("provided byteArray too small"); |
16905 goto fail; |
16787 goto out; |
16906 } |
16788 } |
16907 BMDPRINTF(("numBytes %d\n",numBytes)); |
16789 BMDPRINTF(("numBytes %d\n",numBytes)); |
16908 |
16790 |
16909 bitmap.bmiHeader.biHeight = -height; |
16791 bitmap.bmiHeader.biHeight = -height; |
16910 bitmap.bmiHeader.biBitCount = bitmapInfo.bmBitsPixel; /*__depth;*/ |
16792 bitmap.bmiHeader.biBitCount = bitmapInfo.bmBitsPixel; /*__depth;*/ |
16911 bitmap.rgb[0] = 0; |
16793 bitmap.rgb[0] = 0; |
16912 bitmap.rgb[1] = 0xffffff; |
16794 bitmap.rgb[1] = 0xffffff; |
16913 if (GetDIBits(xDC,xBitmap,0,height,__ByteArrayInstPtr(imageBits)->ba_element,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16795 if (GetDIBits(xDC,xBitmap,0,height,__ByteArrayInstPtr(imageBits)->ba_element,(struct tagBITMAPINFO *)&bitmap,DIB_RGB_COLORS) == 0) |
16914 { |
16796 { |
16915 BMDPRINTF(("zero bits returned\n")); |
16797 BMDPRINTF(("zero bits returned\n")); |
16916 goto fail; |
16798 error = __MKSTRING("zero bits returned"); |
16917 } |
16799 goto out; |
|
16800 } |
16918 |
16801 |
16919 #if 0 |
16802 #if 0 |
16920 { |
16803 { |
16921 /* swap red and blue (windows delivers BGR) */ |
16804 /* swap red and blue (windows delivers BGR) */ |
16922 char *cp = __ByteArrayInstPtr(imageBits)->ba_element; |
16805 char *cp = __ByteArrayInstPtr(imageBits)->ba_element; |
16923 int n = numBytes; |
16806 int n = numBytes; |
16924 |
16807 |
16925 for ( ;n > 0; n -= 3, cp += 3) { |
16808 for ( ;n > 0; n -= 3, cp += 3) { |
16926 char b = cp[0]; |
16809 char b = cp[0]; |
16927 cp[0] = cp[2]; |
16810 cp[0] = cp[2]; |
16928 cp[2] = b; |
16811 cp[2] = b; |
16929 } |
16812 } |
16930 } |
16813 } |
16931 #endif |
16814 #endif |
16932 } else { |
16815 } else { |
16933 BMDPRINTF(("unacceptable bitmap\n")); |
16816 error = __MKSTRING("unacceptable bitmap (size is 0 bytes)"); |
16934 goto fail; |
16817 goto out; |
16935 } |
16818 } |
16936 } else { |
16819 } else { |
16937 BMDPRINTF(("unacceptable bitmap\n")); |
16820 error = __MKSTRING("unacceptable bitmap (null xBitmap)"); |
16938 goto fail; |
16821 goto out; |
16939 } |
16822 } |
16940 __ArrayInstPtr(info)->a_element[0] = @symbol(msbFirst); |
16823 bytesPerLine = __MKSMALLINT(numBytes/height); |
16941 __ArrayInstPtr(info)->a_element[1] = __MKSMALLINT(1); |
16824 format = (bitmap.bmiHeader.biBitCount == 1) ? @symbol(ZPixmap) : @symbol(XYPixmap); |
16942 __ArrayInstPtr(info)->a_element[2] = __MKSMALLINT(numBytes/height); |
16825 bitmapPad = __MKSMALLINT(WIN32PADDING); |
16943 __ArrayInstPtr(info)->a_element[3] = @symbol(lsbFirst); |
16826 bitsPerPixel = __MKSMALLINT(bitmap.bmiHeader.biBitCount); |
16944 __ArrayInstPtr(info)->a_element[4] = (bitmap.bmiHeader.biBitCount == 1) ? @symbol(ZPixmap) : @symbol(XYPixmap); |
16827 } |
16945 __ArrayInstPtr(info)->a_element[5] = __MKSMALLINT(0); |
16828 out: |
16946 __ArrayInstPtr(info)->a_element[6] = __MKSMALLINT(WIN32PADDING); |
|
16947 __ArrayInstPtr(info)->a_element[7] = __MKSMALLINT(bitmap.bmiHeader.biBitCount); |
|
16948 __ArrayInstPtr(info)->a_element[8] = __MKSMALLINT(0xFF0000); // redMask |
|
16949 __ArrayInstPtr(info)->a_element[9] = __MKSMALLINT(0x00FF00); // greenMask |
|
16950 __ArrayInstPtr(info)->a_element[10] = __MKSMALLINT(0x0000FF); // blueMask |
|
16951 if (bDC) |
|
16952 DeleteDC(bDC); |
|
16953 if (xDC) |
|
16954 ReleaseDC(0, xDC); //DeleteDC(xDC); |
|
16955 if (hBitmap) |
|
16956 DeleteObject(hBitmap); |
|
16957 RETURN ( true ); |
|
16958 } |
|
16959 fail: |
|
16960 if (bDC) |
16829 if (bDC) |
16961 DeleteDC(bDC); |
16830 DeleteDC(bDC); |
16962 if (xDC) |
16831 if (xDC) |
16963 ReleaseDC(0, xDC); //DeleteDC(xDC); |
16832 ReleaseDC(0, xDC); //DeleteDC(xDC); |
16964 if (hBitmap) |
16833 if (hBitmap) |
16965 DeleteObject(hBitmap); |
16834 DeleteObject(hBitmap); |
16966 |
|
16967 %}. |
16835 %}. |
16968 ^ false |
16836 |
|
16837 error notNil ifTrue:[ |
|
16838 self primitiveFailed:error. |
|
16839 ]. |
|
16840 |
|
16841 ^ IdentityDictionary new |
|
16842 at:#bitOrder put:#msbFirst; |
|
16843 at:#depth put:1; |
|
16844 at:#bytesPerLine put:bytesPerLine; |
|
16845 at:#byteOrder put:#lsbFirst; |
|
16846 at:#format put:format; |
|
16847 at:#bitmapUnit put:0; |
|
16848 at:#bitmapPad put:bitmapPad; |
|
16849 at:#bitsPerPixel put:bitsPerPixel; |
|
16850 at:#redMask put:16rFF0000; |
|
16851 at:#greenMask put:16r00FF00; |
|
16852 at:#blueMask put:16r0000FF; |
|
16853 yourself. |
|
16854 |
|
16855 "Modified (comment): / 28-03-2017 / 14:28:46 / stefan" |
|
16856 ! |
|
16857 |
|
16858 getPixelX:px y:py from:ignoredDrawableId with:aGCId |
|
16859 "return the pixel value at x/y; coordinates start at 0/0 for the upper left. |
|
16860 Nil is returned for invalid coordinates or if any other problem arises." |
|
16861 |
|
16862 %{ /* NOCONTEXT */ |
|
16863 if (__isExternalAddress(aGCId) |
|
16864 && __bothSmallInteger(px, py)) { |
|
16865 struct gcData *gcData = _GCDATA(aGCId); |
|
16866 HDC hDC; |
|
16867 int __x = __intVal(px), __y = __intVal(py); |
|
16868 int pixel; |
|
16869 |
|
16870 hDC = _getDC(gcData); |
|
16871 pixel = GetPixel(hDC, __x, __y); |
|
16872 #ifndef CACHE_LAST_DC |
|
16873 _releaseDC(gcData); |
|
16874 #endif |
|
16875 /* |
|
16876 * for compatibility, returns the pixelValue |
|
16877 * from a monochrome bitmap |
|
16878 */ |
|
16879 if (gcData->hBitmap) { |
|
16880 if (gcData->bitmapColorBitCount == 1) { |
|
16881 pixel = (pixel == 0) ? 0 : 1; |
|
16882 } |
|
16883 } |
|
16884 |
|
16885 RETURN ( __MKSMALLINT(pixel & 0xFFFFFF) ); |
|
16886 } |
|
16887 %}. |
|
16888 ^ nil |
16969 ! ! |
16889 ! ! |
16970 |
16890 |
16971 !WinWorkstation methodsFor:'style defaults'! |
16891 !WinWorkstation methodsFor:'style defaults'! |
16972 |
16892 |
16973 defaultStyleValueFor:aKey |
16893 defaultStyleValueFor:aKey |