--- a/WinPrinterContext.st Fri Oct 19 15:23:40 2007 +0200
+++ b/WinPrinterContext.st Fri Oct 19 15:47:23 2007 +0200
@@ -333,33 +333,6 @@
"Created: / 07-08-2006 / 12:09:48 / fm"
"Modified: / 07-08-2006 / 14:11:17 / fm"
"Modified: / 16-04-2007 / 15:37:41 / cg"
-!
-
-printImage: anImage
- "Opens a print dialog and prints the given image"
-
- | printerInfo printer |
-
- printerInfo := PrintingDialog getPrinterInfo.
- printerInfo isNil ifTrue:[^self].
-
- printer := self fromPrinterInfo: printerInfo.
- [
- printer startPrintJob: 'Image'.
- printer background:Color white.
- anImage displayOn:printer x:1000 y:1000.
- printer endPrintJob.
- ] forkAt: 3
-
- "
- WinPrinterContext printImage: (Image fromFile:'C:\vsw311\pavheadr.gif').
- WinPrinterContext printImage: XPToolbarIconLibrary help32x32Icon.
- WinPrinterContext printImage: XPToolbarIconLibrary eraseXP28x28Icon.
-
- "
-
- "Created: / 07-08-2006 / 11:46:52 / fm"
- "Modified: / 16-04-2007 / 15:37:34 / cg"
! !
!WinPrinterContext class methodsFor:'testing & examples'!
@@ -629,12 +602,12 @@
printer := self fromPrinterInfo: printerInfo.
[
- printer
- print: aString
- font: aFont
- title: aTitle
- wordWrap: wordWrap
- marginsRect: nil
+ printer
+ print: aString
+ font: aFont
+ title: aTitle
+ wordWrap: wordWrap
+ marginsRect: nil
] forkAt: 3
"
@@ -707,6 +680,34 @@
"Modified: / 16-04-2007 / 15:37:38 / cg"
!
+printImage: anImage
+ "Opens a print dialog and prints the given image"
+
+ | printerInfo printer |
+
+ printerInfo := PrintingDialog getPrinterInfo.
+ printerInfo isNil ifTrue:[^self].
+
+ printer := self fromPrinterInfo: printerInfo.
+ [
+ printer startPrintJob: 'Image'.
+ printer background:Color white.
+ anImage displayOn:printer x:1000 y:1000.
+ printer endPrintJob.
+ ] forkAt: 3
+
+ "
+ WinPrinterContext printImage: (Image fromFile:'C:\vsw311\pavheadr.gif').
+ WinPrinterContext printImage: XPToolbarIconLibrary help32x32Icon.
+ WinPrinterContext printImage: XPToolbarIconLibrary eraseXP28x28Icon.
+ WinPrinterContext printImage: XPToolbarIconLibrary saveImageBlack22x22Icon.
+ WinPrinterContext printImage: XPToolbarIconLibrary changesBrowser18x22Icon.
+ "
+
+ "Created: / 07-08-2006 / 11:46:52 / fm"
+ "Modified: / 16-04-2007 / 15:37:34 / cg"
+!
+
printLines: pairOfPointsWithContextArray
"Opens a print dialog and prints the given lines"
@@ -918,6 +919,10 @@
!WinPrinterContext methodsFor:'accessing'!
+bitsPerPixel
+ ^ printerInfo bitsPerPixel ? 8
+!
+
depth
^ 24
!
@@ -2590,8 +2595,87 @@
^Display bitsRed
!
+compressColorMapImage: image
+ "calculates a new color map for the image, using only used colors"
+
+ |depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits|
+
+ oldImage := image.
+ depth := oldImage depth.
+
+ oldImage photometric ~~ #palette ifTrue:[
+ Transcript showCR:'Compress colorMap: Only palette images have colormaps.'.
+ ^ image
+ ].
+
+ usedColors := oldImage realUsedColors.
+ usedColors size == (1 bitShift:depth) ifTrue:[
+ Transcript showCR:'Compress colorMap: All colors are used - no compression.'.
+ ^ image
+ ].
+ usedColors size == oldImage colorMap size ifTrue:[
+ Transcript showCR:'Compress colorMap: Colormap already compressed - no compression.'.
+ ^ image
+ ].
+
+ "/ translation table
+ oldToNew := ByteArray new:(1 bitShift:depth).
+ newColorMap := usedColors asArray.
+ newColorMap sort:self sortBlockForColors.
+
+ oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr |
+ |newPixel|
+
+ (usedColors includes:clr) ifTrue:[
+ newPixel := newColorMap indexOf:clr.
+ oldToNew at:oldIdx put:newPixel-1.
+ ]
+ ].
+
+ oldBits := oldImage bits.
+ newBits := ByteArray new:(oldBits size).
+ depth ~~ 8 ifTrue:[
+ "/ expand/compress can only handle 8bits
+ tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height).
+ oldBits
+ expandPixels:depth
+ width:oldImage width
+ height:oldImage height
+ into:tmpBits
+ mapping:oldToNew.
+ tmpBits
+ compressPixels:depth
+ width:oldImage width
+ height:oldImage height
+ into:newBits
+ mapping:nil
+ ] ifFalse:[
+ oldBits
+ expandPixels:depth
+ width:oldImage width
+ height:oldImage height
+ into:newBits
+ mapping:oldToNew.
+ ].
+
+ newImage := oldImage species new
+ width:oldImage width
+ height:oldImage height
+ depth:depth
+ fromArray:newBits.
+
+ newImage colorMap:newColorMap.
+ newImage fileName:oldImage fileName.
+ newImage mask:(oldImage mask copy).
+
+ ^ newImage
+
+ "Created: / 28.7.1998 / 20:03:11 / cg"
+ "Modified: / 15.9.1998 / 17:53:32 / cg"
+!
+
copyFromId:sourceId x:srcX y:srcY gc:srcGCId to:destId x:dstX y:dstY gc:dstGCId
- width:w height:h
+ width:w height:h
"do a bit-blt; copy bits from the rectangle defined by
srcX/srcY and w/h from the sourceId drawable to the rectangle
below dstX/dstY in the destId drawable. Trigger an error if any
@@ -2604,39 +2688,39 @@
if (! __isExternalAddressLike(srcGCId)
|| ! __isExternalAddressLike(dstGCId)) {
- goto fail;
+ goto fail;
}
if (__bothSmallInteger(w, h)
&& __bothSmallInteger(srcX, srcY)
&& __bothSmallInteger(dstX, dstY)) {
- HANDLE srcDC = (HANDLE)(__externalAddressVal(srcGCId));
- HANDLE dstDC = (HANDLE)(__externalAddressVal(dstGCId));
-
- int fun, aFunctionSymbol;
- int src_fg, src_bg, dst_fg, dst_bg;
- char buf[5];
+ HANDLE srcDC = (HANDLE)(__externalAddressVal(srcGCId));
+ HANDLE dstDC = (HANDLE)(__externalAddressVal(dstGCId));
+
+ int fun, aFunctionSymbol;
+ int src_fg, src_bg, dst_fg, dst_bg;
+ char buf[5];
// fun = dstGcData->bitbltrop2;
- aFunctionSymbol= __INST(function);
-
- if (aFunctionSymbol == @symbol(copy)) {
- fun = SRCCOPY /* R2_COPYPEN */ ;
+ aFunctionSymbol= __INST(function);
+
+ if (aFunctionSymbol == @symbol(copy)) {
+ fun = SRCCOPY /* R2_COPYPEN */ ;
/* bfun = BITBLT_COPY; */
- } else if (aFunctionSymbol == @symbol(copyInverted)) {
- fun = NOTSRCCOPY /* R2_NOTCOPYPEN */;
+ } else if (aFunctionSymbol == @symbol(copyInverted)) {
+ fun = NOTSRCCOPY /* R2_NOTCOPYPEN */;
/* bfun = BITBLT_COPYINVERTED; */
- } else if (aFunctionSymbol == @symbol(xor)) {
- fun = SRCINVERT /* R2_XORPEN */;
+ } else if (aFunctionSymbol == @symbol(xor)) {
+ fun = SRCINVERT /* R2_XORPEN */;
/* bfun = BITBLT_XOR; */
- } else if (aFunctionSymbol == @symbol(and)) {
- fun = SRCAND /* R2_MASKPEN */ ;
+ } else if (aFunctionSymbol == @symbol(and)) {
+ fun = SRCAND /* R2_MASKPEN */ ;
/* bfun = BITBLT_AND; */
- } else if (aFunctionSymbol == @symbol(or)) {
- fun = MERGECOPY /* R2_MERGEPEN */ ;
+ } else if (aFunctionSymbol == @symbol(or)) {
+ fun = MERGECOPY /* R2_MERGEPEN */ ;
/* bfun = BITBLT_OR; */
- }
+ }
// convert 123 to string [buf]
// itoa(fun, buf, 10);
@@ -2645,75 +2729,75 @@
/*
#if 0
- switch (fun) {
- case BITBLT_COPY:
- console_printf("BITBLT_COPY\n");
- break;
- case BITBLT_COPYINVERTED:
- console_printf("BITBLT_COPYINVERTED\n");
- break;
- case BITBLT_XOR:
- console_printf("BITBLT_XOR\n");
- break;
- case BITBLT_AND:
- console_printf("BITBLT_AND\n");
- break;
- case BITBLT_OR:
- console_printf("BITBLT_OR\n");
- break;
- }
+ switch (fun) {
+ case BITBLT_COPY:
+ console_printf("BITBLT_COPY\n");
+ break;
+ case BITBLT_COPYINVERTED:
+ console_printf("BITBLT_COPYINVERTED\n");
+ break;
+ case BITBLT_XOR:
+ console_printf("BITBLT_XOR\n");
+ break;
+ case BITBLT_AND:
+ console_printf("BITBLT_AND\n");
+ break;
+ case BITBLT_OR:
+ console_printf("BITBLT_OR\n");
+ break;
+ }
#endif
*/
// fun = dstGcData->bitbltrop2;
- if (0 /* fun == BITBLT_COPY */) {
- src_fg = dst_fg = 0xFFFFFF;
- src_bg = dst_bg = 0x000000;
- } else {
- src_fg = GetTextColor(srcDC) /* srcGcData->fgColor */;
- src_bg = GetBkColor(dstDC) /* srcGcData->bgColor */;
- dst_fg = GetTextColor(srcDC) /* dstGcData->fgColor */;
- dst_bg = GetBkColor(dstDC) /* dstGcData->bgColor */;
- }
-
- SetBkColor(dstDC, dst_fg);
- SetTextColor(dstDC, dst_bg);
-
- SetBkColor(srcDC, src_fg);
- SetTextColor(srcDC, src_bg);
+ if (0 /* fun == BITBLT_COPY */) {
+ src_fg = dst_fg = 0xFFFFFF;
+ src_bg = dst_bg = 0x000000;
+ } else {
+ src_fg = GetTextColor(srcDC) /* srcGcData->fgColor */;
+ src_bg = GetBkColor(dstDC) /* srcGcData->bgColor */;
+ dst_fg = GetTextColor(srcDC) /* dstGcData->fgColor */;
+ dst_bg = GetBkColor(dstDC) /* dstGcData->bgColor */;
+ }
+
+ SetBkColor(dstDC, dst_fg);
+ SetTextColor(dstDC, dst_bg);
+
+ SetBkColor(srcDC, src_fg);
+ SetTextColor(srcDC, src_bg);
/*
- CPRINTF(("bitblt src f:%x b:%x",GetTextColor(srcDC),GetBkColor(srcDC)));
- CPRINTF(("dst f:%x b:%x\n",GetTextColor(dstDC),GetBkColor(dstDC)));
+ CPRINTF(("bitblt src f:%x b:%x",GetTextColor(srcDC),GetBkColor(srcDC)));
+ CPRINTF(("dst f:%x b:%x\n",GetTextColor(dstDC),GetBkColor(dstDC)));
*/
- if (BitBlt(dstDC,
- __intVal(dstX), __intVal(dstY),
- __intVal(w), __intVal(h),
- srcDC,
- __intVal(srcX), __intVal(srcY),
- fun)
- == 0
- ) {
- console_fprintf(stderr, "WinWorkstation [info]: ERROR in BitBlt\n");
- }
+ if (BitBlt(dstDC,
+ __intVal(dstX), __intVal(dstY),
+ __intVal(w), __intVal(h),
+ srcDC,
+ __intVal(srcX), __intVal(srcY),
+ fun)
+ == 0
+ ) {
+ console_fprintf(stderr, "WinWorkstation [info]: ERROR in BitBlt\n");
+ }
/*
- if (dstGcData != srcGcData) {
- SetBkColor(dstDC, dstGcData->bgColor);
- SetTextColor(dstDC, dstGcData->fgColor);
- }
- SetBkColor(srcDC, srcGcData->bgColor);
- SetTextColor(srcDC, srcGcData->fgColor);
+ if (dstGcData != srcGcData) {
+ SetBkColor(dstDC, dstGcData->bgColor);
+ SetTextColor(dstDC, dstGcData->fgColor);
+ }
+ SetBkColor(srcDC, srcGcData->bgColor);
+ SetTextColor(srcDC, srcGcData->fgColor);
*/
/*
- if (srcGcData != dstGcData) {
- _releaseDC(srcGcData);
- }
- _releaseDC(dstGcData);
+ if (srcGcData != dstGcData) {
+ _releaseDC(srcGcData);
+ }
+ _releaseDC(dstGcData);
*/
- RETURN ( self );
+ RETURN ( self );
}
fail: ;
@@ -2813,450 +2897,48 @@
!
displayDeviceForm:aForm x:x y:y
- "draw a form or image non opaque (i.e. only foreground color is drawn);
- If its a 1-plane bitmap, 1-bits are drawn in the
- current paint-color, leaving pixels with 0-bits unchanged
- (i.e. only 1-bits are drawn from the form).
- If its a deep form (i.e. a pixmap) the current paint
- settings are ignored and the form is drawn as-is;
- however, the mask is applied if present.
-
- The form should must have been allocated on the same device,
- otherwise its converted here, which slows down the draw.
- No transformation or scaling is done.
- Care must be taken, that the paint color is correctly allocated
- (by sending #on: to the color) before doing so.
- Using functions other than #copy only makes sense if you are
- certain, that the colors are real colors (actually, only for
- noColor or allColor)."
-
-"/ |id w h easy paintDither tmpForm tmpId tmpGCId
-"/ fgId noColor allColor allBits pX pY
-"/ mask maskId deviceForm deviceFormGCId deviceMask colorMap|
-"/
-"/ w := aForm width.
-"/ h := aForm height.
-"/
-"/ pX := x rounded.
-"/ pY := y rounded.
-"/
-"/ deviceForm := aForm asFormOn:device.
-"/ deviceForm isNil ifTrue:[
-"/ 'DeviceGraphicsContext [warning]: cannot create device-form' errorPrintCR.
-"/ ^self
-"/ ].
-"/ id := deviceForm id.
-"/
-"/ id isNil ifTrue:[
-"/ 'DeviceGraphicsContext [warning]: invalid form draw - ignored' errorPrintCR.
-"/ ^ self
-"/ ].
-"/ gcId isNil ifTrue:[
-"/ self initGC
-"/ ].
-"/ (deviceFormGCId := deviceForm gcId) isNil ifTrue:[
-"/ "/ device needGCForBitmapSource - i.e. WIN32
-"/ device platformName ~= 'X11' ifTrue:[
-"/ deviceForm initGC.
-"/ deviceFormGCId := deviceForm gcId.
-"/ ]
-"/ ].
-"/
-"/ "
-"/ a deep form ignores paint/bgPaint settings
-"/ "
-"/ mask := aForm mask.
-"/
-"/ ((aForm depth ~~ 1)
-"/ or:[mask notNil]) ifTrue:[
-"/ mask notNil ifTrue:[
-"/ mask depth == 1 ifFalse:[
-"/ 'DEVGC: alpha channel not yet supported' errorPrintCR.
-"/ ] ifTrue:[
-"/ deviceMask := mask asFormOn:device.
-"/ deviceMask isNil ifTrue:[
-"/ 'DeviceGraphicsContext [warning]: cannot create device-mask' errorPrintCR.
-"/ ^self
-"/ ].
-"/ maskId := deviceMask id.
-"/ maskId notNil ifTrue:[
-"/ deviceMask gcId isNil ifTrue:[deviceMask initGC].
-"/ allColor := Color allColor.
-"/ allBits := allColor colorId.
-"/
-"/ (deviceForm depth == device depth
-"/ and:[aForm maskedPixelsAre0]) ifTrue:[
-"/ "/ can do it without a temporary pixmap:
-"/ "/ or-in the form into the inverse stamped-out area
-"/ "/ of the destination.
-"/ "/ Oring is of course only possible if we know that
-"/ "/ masked pixels are already zero in the form.
-"/
-"/ "/ stamp out using mask
-"/ device setForeground:0 background:allBits in:gcId.
-"/ device setFunction:#and in:gcId.
-"/ device
-"/ copyPlaneFromPixmapId:maskId
-"/ x:0
-"/ y:0
-"/ gc:(deviceMask gcId)
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/ "/ or-in the form
-"/ device setFunction:#or in:gcId.
-"/ device
-"/ copyFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/ ] ifFalse:[
-"/ "/ must do it slow, using a temporary form ..
-"/
-"/ "
-"/ create temp-form;
-"/ "
-"/ tmpForm := Form width:w height:h depth:device depth on:device.
-"/ tmpForm isNil ifTrue:[
-"/ 'DeviceGraphicsContext [warning]: cannot create temp form' errorPrintCR.
-"/ ^self
-"/ ].
-"/ tmpForm initGC.
-"/ tmpId := tmpForm id.
-"/ tmpGCId := tmpForm gcId.
-"/
-"/ "
-"/ fill tempform with image
-"/ "
-"/ aForm depth == 1 ifTrue:[
-"/ (colorMap := aForm colorMap) notNil ifTrue:[
-"/ colorMap size < 2 ifTrue:[
-"/ device
-"/ setForegroundColor:(colorMap at:1)
-"/ in:tmpGCId.
-"/ ] ifFalse:[
-"/ device
-"/ setForegroundColor:(colorMap at:2)
-"/ backgroundColor:(colorMap at:1)
-"/ in:tmpGCId.
-"/ ]
-"/ ].
-"/ device
-"/ copyPlaneFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:tmpId
-"/ x:0
-"/ y:0
-"/ gc:tmpGCId
-"/ width:w
-"/ height:h.
-"/ ] ifFalse:[
-"/ device
-"/ copyFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:tmpId
-"/ x:0
-"/ y:0
-"/ gc:tmpGCId
-"/ width:w
-"/ height:h.
-"/ ].
-"/
-"/ "
-"/ stamp out mask in temp form
-"/ "
-"/ device setForeground:allBits background:0 in:tmpGCId.
-"/ device setFunction:#and in:tmpGCId.
-"/ device
-"/ copyPlaneFromPixmapId:maskId
-"/ x:0
-"/ y:0
-"/ gc:(deviceMask gcId)
-"/ to:tmpId
-"/ x:0
-"/ y:0
-"/ gc:tmpGCId
-"/ width:w
-"/ height:h.
-"/
-"/ "
-"/ stamp out mask in destination
-"/ "
-"/ device setForeground:0 background:allBits in:gcId.
-"/ device setFunction:#and in:gcId.
-"/ device
-"/ copyPlaneFromPixmapId:maskId
-"/ x:0
-"/ y:0
-"/ gc:(deviceMask gcId)
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/
-"/ "
-"/ or-in tempform-bits ...
-"/ "
-"/ device setFunction:#or in:gcId.
-"/ device
-"/ copyFromPixmapId:tmpId
-"/ x:0
-"/ y:0
-"/ gc:tmpGCId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/
-"/ "
-"/ release tempForm immediately
-"/ (although GC will eventually do it,
-"/ this creates less stress to the Xserver in the meanwhile ...)
-"/ "
-"/ tmpForm destroy.
-"/ ].
-"/
-"/ "/ restore GC
-"/ foreground notNil ifTrue:[
-"/ device setForegroundColor:foreground in:gcId.
-"/ ].
-"/ background notNil ifTrue:[
-"/ device setBackgroundColor:background in:gcId
-"/ ].
-"/ device setFunction:function in:gcId.
-"/ ^ self
-"/ ]
-"/ ]
-"/ ].
-"/
-"/ device
-"/ copyFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceForm gcId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/ ^ self
-"/ ].
-"/
-"/ "
-"/ the following code is somewhat complicated, since it has to deal
-"/ with dithered paint colors, which cannot be done directly on most
-"/ devices (actually, a test for the devices capabilities has to be added here)
-"/ (just assume drawing a bitmap with dithered paint color ... sigh)
-"/ "
-"/
-"/ easy := (function == #copy).
-"/
-"/ "
-"/ if paint is not a real color, we have to do it the hard way ...
-"/ "
-"/ easy ifTrue:[
-"/ paint isColor ifFalse:[
-"/ paintDither := paint.
-"/ easy := false
-"/ ] ifTrue:[
-"/ paintDither := paint ditherForm.
-"/ paintDither notNil ifTrue:[
-"/ easy := false.
-"/ ]
-"/ ].
-"/ ].
-"/
-"/ allColor := Color allColor.
-"/ allBits := allColor colorId.
-"/
-"/ easy ifTrue:[
-"/ "
-"/ paint is a real color
-"/ "
-"/
-"/ "
-"/ if paint color is all-0 or all-1's, we can do it in one
-"/ operation ...
-"/ "
-"/ fgId := paint colorId.
-"/
-"/ ((fgId ~~ ((1 bitShift:device depth)-1))
-"/ and:[fgId ~~ allBits]) ifTrue:[
-"/ "
-"/ clear fg-bits ...
-"/ "
-"/ device setForeground:0 background:allBits in:gcId.
-"/ device setFunction:#and in:gcId.
-"/ device
-"/ copyPlaneFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/ ].
-"/
-"/ fgId ~~ 0 ifTrue:[
-"/ "
-"/ or-in fg-bits ...
-"/ "
-"/ device setForeground:fgId background:0 in:gcId.
-"/ device setFunction:#or in:gcId.
-"/ device
-"/ copyPlaneFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h
-"/ ].
-"/ "
-"/ flush foreground/background cache
-"/ "
-"/ foreground := nil.
-"/ background := nil.
-"/ device setFunction:function in:gcId.
-"/ ^ self
-"/ ].
-"/
-"/ function == #or ifTrue:[
-"/ easy := paint notNil
-"/ and:[paint isColor
-"/ and:[paint ditherForm isNil]].
-"/ easy ifTrue:[
-"/ easy := bgPaint isNil
-"/ or:[bgPaint isColor
-"/ and:[bgPaint colorId == 0]]
-"/ ].
-"/ easy ifTrue:[
-"/ fgId := paint colorId.
-"/
-"/ fgId ~~ 0 ifTrue:[
-"/ "
-"/ or-in fg-bits ...
-"/ "
-"/ device setForeground:fgId background:0 in:gcId.
-"/ device
-"/ copyPlaneFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h
-"/ ].
-"/ "
-"/ flush foreground/background cache
-"/ "
-"/ foreground := nil.
-"/ background := nil.
-"/ ^ self
-"/ ].
-"/ ].
-"/
-"/ "
-"/ hard case; paint is a dithered color
-"/ "
-"/
-"/ noColor := Color noColor.
-"/
-"/ "
-"/ create temp-form;
-"/ "
-"/ tmpForm := Form width:w height:h depth:device depth on:device.
-"/ tmpForm isNil ifTrue:[
-"/ 'DeviceGraphicsContext [warning]: cannot create temp form' errorPrintCR.
-"/ ^self
-"/ ].
-"/ "
-"/ fill tempform
-"/ "
-"/ tmpForm paint:paint.
-"/ tmpForm fillRectangleX:0 y:0 width:w height:h.
-"/ "
-"/ stamp out background
-"/ "
-"/ tmpForm paint:allColor on:noColor.
-"/ tmpForm function:#and.
-"/ tmpForm displayOpaqueForm:deviceForm x:0 y:0.
-"/ "
-"/ stamp out foreground from destination
-"/ "
-"/ device setForeground:0 background:allBits in:gcId.
-"/ device setFunction:#and in:gcId.
-"/ device
-"/ copyPlaneFromPixmapId:id
-"/ x:0
-"/ y:0
-"/ gc:deviceFormGCId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/ "
-"/ or-in temp into destination
-"/ "
-"/ device setForeground:allBits background:0 in:gcId.
-"/ device setFunction:#or in:gcId.
-"/
-"/ device
-"/ copyFromPixmapId:tmpForm id
-"/ x:0
-"/ y:0
-"/ gc:tmpForm gcId
-"/ to:drawableId
-"/ x:pX
-"/ y:pY
-"/ gc:gcId
-"/ width:w
-"/ height:h.
-"/
-"/ "
-"/ release tempForm immediately
-"/ (although GC will eventually do it,
-"/ this creates less stress to the Xserver in the meanwhile ...)
-"/ "
-"/
-"/ tmpForm destroy.
-"/ "
-"/ flush foreground/background cache
-"/ "
-"/ foreground := nil.
-"/ background := nil.
-"/ device setFunction:function in:gcId.
-
- "Modified: / 27.7.1998 / 20:07:22 / cg"
+
+ |sortedImage formMask bitsWithTransparency|
+
+ sortedImage := aForm.
+"/ sortedImage := self sortColorMapImage: aForm.
+ sortedImage := self compressColorMapImage: sortedImage.
+
+ formMask := sortedImage mask.
+ formMask isNil
+ ifTrue:[bitsWithTransparency := aForm bits ]
+ ifFalse:[
+ |bitsWithTransparencySize|
+ formMask := formMask asImageWithDepth: aForm depth.
+ bitsWithTransparency := sortedImage bits copy.
+ bitsWithTransparencySize := bitsWithTransparency size.
+ formMask bits doWithIndex:[:maskBit :index |
+ bitsWithTransparencySize >= index ifTrue:[
+ maskBit == 0 ifTrue:[bitsWithTransparency at: index put: 255 "60" "bitClearAt: index"].
+"/ maskBit == 1 ifTrue:[bitsWithTransparency at: index put: (bitsWithTransparency at: index)].
+ ].
+ ].
+ ].
+
+"/ sortedImage colorMap redVector at:255 put: 255.
+"/ sortedImage colorMap greenVector at:255 put: 255.
+"/ sortedImage colorMap blueVector at:255 put: 255.
+
+ self
+ drawBits: bitsWithTransparency ? sortedImage bits
+ redVector: sortedImage colorMap redVector
+ greenVector: sortedImage colorMap greenVector
+ blueVector: sortedImage colorMap blueVector
+ bitsPerPixel: sortedImage bitsPerPixel
+ depth: sortedImage depth
+ width: sortedImage width
+ height: sortedImage height
+ into: self id
+ x: x
+ y: y
+ width: sortedImage width
+ height: sortedImage height
+ with: gcId.
!
drawBits:imageBits bitsPerPixel:bitsPerPixel depth:imageDepth padding:padd
@@ -3296,6 +2978,41 @@
].
!
+drawBits:imageBits redVector:redVector greenVector:greenVector blueVector:blueVector bitsPerPixel:bitsPerPixel depth:imageDepth
+ width:imageWidth height:imageHeight
+ 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.
+ 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."
+
+ "
+ sorry; I had to separate it into 2 methods, since XPutImage needs
+ an unlimited stack, and thus cannot send primitiveFailed
+ "
+ (self primDrawBits:imageBits redVector:redVector greenVector:greenVector blueVector:blueVector bitsPerPixel:bitsPerPixel depth:imageDepth
+ width:imageWidth height:imageHeight
+ into:ignoredDrawableId
+ x:dstx y:dsty
+ width:w height:h
+ with:aGCId)
+ ifFalse:[
+ "
+ also happens, if a segmentation violation occurs in the
+ XPutImage ...
+ "
+ self primitiveFailed
+ ].
+!
+
primCreateBitmapFromArray:anArray width:w height:h
%{
@@ -3394,12 +3111,12 @@
!
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
+ with:aGCId
"since XPutImage may allocate huge amount of stack space
(some implementations use alloca), this must run with unlimited stack."
@@ -3411,9 +3128,9 @@
unsigned char *__imageBits = 0;
if (__isByteArray(imageBits)) {
- __imageBits = __ByteArrayInstPtr(imageBits)->ba_element;
+ __imageBits = __ByteArrayInstPtr(imageBits)->ba_element;
} else if (__isExternalBytesLike(imageBits)) {
- __imageBits = (unsigned char *)(__externalBytesAddress(imageBits));
+ __imageBits = (unsigned char *)(__externalBytesAddress(imageBits));
}
if (/* ISCONNECTED
@@ -3426,120 +3143,120 @@
&& __isSmallInteger(padd)
&& __imageBits)
{
- struct
- {
- BITMAPINFOHEADER bmiHeader;
- DWORD r;
- DWORD g;
- DWORD b;
- } bitmap;
-
- HANDLE hDC = (HANDLE)(__externalAddressVal(aGCId));
- HBITMAP hBitmap = _HBITMAPVAL(__INST(drawableId));
+ struct
+ {
+ BITMAPINFOHEADER bmiHeader;
+ DWORD r;
+ DWORD g;
+ DWORD b;
+ } bitmap;
+
+ HANDLE hDC = (HANDLE)(__externalAddressVal(aGCId));
+ HBITMAP hBitmap = _HBITMAPVAL(__INST(drawableId));
/*
- DDPRINTF(("hDC = %x\n", hDC));
+ 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;
- if (__intVal(imageDepth) == 24) {
- /*bitmap.bmiHeader.biCompression = BI_BITFIELDS;
- bitmap.r = 0xff0000;
- bitmap.g = 0x00ff00;
- bitmap.b = 0x0000ff;*/
- bitmap.bmiHeader.biCompression = BI_RGB;
- } else if (__intVal(imageDepth) == 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;
- }
- 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);*/
-
- 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);
+ 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;
+ if (__intVal(imageDepth) == 24) {
+ /*bitmap.bmiHeader.biCompression = BI_BITFIELDS;
+ bitmap.r = 0xff0000;
+ bitmap.g = 0x00ff00;
+ bitmap.b = 0x0000ff;*/
+ bitmap.bmiHeader.biCompression = BI_RGB;
+ } else if (__intVal(imageDepth) == 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;
+ }
+ 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);*/
+
+ 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);
/*
- SetDIBits(hDC,hBitmap,
- 0,__intVal(h),
- (void *)b_bits,
- (BITMAPINFO*)&bitmap,DIB_RGB_COLORS);
+ SetDIBits(hDC,hBitmap,
+ 0,__intVal(h),
+ (void *)b_bits,
+ (BITMAPINFO*)&bitmap,DIB_RGB_COLORS);
*/
/*
- StretchDIBits(hDC,
- __intVal(dstx),(__intVal(dsty)), // x & y coord of destination upper-left corner
- __intVal(w), __intVal(h), // width & height of destination rectangle
- __intVal(srcx), __intVal(srcy), // x & y coord of source upper-left corner
- __intVal(w), __intVal(h), // width & height of source rectangle
- (void *)b_bits, // bitmap bits
- (BITMAPINFO*)&bitmap, // bitmap data
- DIB_RGB_COLORS, // usage options
- SRCCOPY // raster operation code
- );
+ StretchDIBits(hDC,
+ __intVal(dstx),(__intVal(dsty)), // x & y coord of destination upper-left corner
+ __intVal(w), __intVal(h), // width & height of destination rectangle
+ __intVal(srcx), __intVal(srcy), // x & y coord of source upper-left corner
+ __intVal(w), __intVal(h), // width & height of source rectangle
+ (void *)b_bits, // bitmap bits
+ (BITMAPINFO*)&bitmap, // bitmap data
+ DIB_RGB_COLORS, // usage options
+ SRCCOPY // raster operation code
+ );
*/
- if (allocatedBits) {
- free(allocatedBits);
- }
+ if (allocatedBits) {
+ free(allocatedBits);
+ }
/*
#ifndef CACHE_LAST_DC
- _releaseDC(gcData);
+ _releaseDC(gcData);
#endif
*/
- RETURN ( true );
+ RETURN ( true );
}
fail: ;
@@ -3548,14 +3265,211 @@
*/
if (allocatedBits) {
/*
- PRINTF(("freeing up temp bitmap bits ...\n"));
+ PRINTF(("freeing up temp bitmap bits ...\n"));
*/
- free(allocatedBits);
+ free(allocatedBits);
}
/*
#ifndef CACHE_LAST_DC
if (hDC) {
- _releaseDC(gcData);
+ _releaseDC(gcData);
+ }
+#endif
+*/
+%}
+.
+ ^ false
+!
+
+primDrawBits:imageBits redVector:redVector greenVector:greenVector blueVector:blueVector bitsPerPixel:bitsPerPixel depth:imageDepth
+ width:imageWidth height:imageHeight
+ into:ignoredDrawableId
+ x:dstx y:dsty
+ width:w height:h
+ with:aGCId
+
+ "since XPutImage may allocate huge amount of stack space
+ (some implementations use alloca), this must run with unlimited stack."
+
+%{
+ unsigned char fastBits[10000];
+ unsigned char *b_bits = 0;
+ unsigned char *allocatedBits = 0;
+ unsigned char *__imageBits = 0;
+ unsigned char *__redVector = 0;
+ unsigned char *__greenVector = 0;
+ unsigned char *__blueVector = 0;
+ int padd = 8;
+
+ if (__isByteArray(imageBits)) {
+ __imageBits = __ByteArrayInstPtr(imageBits)->ba_element;
+ } else if (__isExternalBytesLike(imageBits)) {
+ __imageBits = (unsigned char *)(__externalBytesAddress(imageBits));
+ }
+
+ if (__isByteArray(redVector)) {
+ __redVector = __ByteArrayInstPtr(redVector)->ba_element;
+ } else if (__isExternalBytesLike(redVector)) {
+ __redVector = (unsigned char *)(__externalBytesAddress(redVector));
+ }
+
+ if (__isByteArray(greenVector)) {
+ __greenVector = __ByteArrayInstPtr(greenVector)->ba_element;
+ } else if (__isExternalBytesLike(greenVector)) {
+ __greenVector = (unsigned char *)(__externalBytesAddress(greenVector));
+ }
+
+ if (__isByteArray(blueVector)) {
+ __blueVector = __ByteArrayInstPtr(blueVector)->ba_element;
+ } else if (__isExternalBytesLike(blueVector)) {
+ __blueVector = (unsigned char *)(__externalBytesAddress(blueVector));
+ }
+
+ if (/* ISCONNECTED
+ && */ __isExternalAddressLike(aGCId)
+// && __bothSmallInteger(srcx, srcy)
+ && __bothSmallInteger(dstx, dsty)
+ && __bothSmallInteger(w, h)
+ && __bothSmallInteger(imageWidth, imageHeight)
+ && __bothSmallInteger(imageDepth, bitsPerPixel)
+ && __imageBits
+ && __redVector
+ && __greenVector
+ && __blueVector)
+ {
+ struct
+ {
+ BITMAPINFOHEADER bmiHeader;
+ RGBQUAD bmiColors[256];
+ } bitmap;
+
+ HANDLE hDC = (HANDLE)(__externalAddressVal(aGCId));
+ HBITMAP hBitmap = _HBITMAPVAL(__INST(drawableId));
+ int col;
+/*
+ DDPRINTF(("hDC = %x\n", hDC));
+*/
+
+ if (padd != WIN32PADDING) {
+
+ int row, col;
+ unsigned char *cp;
+ unsigned char *pBits;
+ int b_width, b_height, bytesPerRowST, bytesPerRowWN, padding, nBytes;
+ int bi = __intVal(bitsPerPixel);
+
+ console_fprintf(stderr, "Non WIN32PADDING");
+
+ b_width = __intVal(w);
+ b_height = __intVal(h);
+ bytesPerRowST = (b_width * bi + (padd - 1 )) / 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;
+ bitmap.bmiHeader.biCompression = BI_RGB;
+ 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 (__intVal(imageDepth) == 8) {
+ for(col=0;col<256;col++)
+ {
+ if (__redVector[col] == 0) {
+ console_fprintf(stderr, "__redVector[col] 0");
+ }
+ bitmap.bmiColors[col].rgbBlue = __blueVector[col]; // Microsoft idea: change rgbBlue to rgbRed
+ bitmap.bmiColors[col].rgbGreen = __greenVector[col];
+ bitmap.bmiColors[col].rgbRed = __redVector[col]; // Microsoft idea: change rgbRed to rgbBlue
+ bitmap.bmiColors[col].rgbReserved = 0;
+
+ }
+ }
+
+ bitmap.bmiColors[255].rgbBlue=255;
+ bitmap.bmiColors[255].rgbGreen=255;
+ bitmap.bmiColors[255].rgbRed =255;
+
+ SetDIBitsToDevice(hDC,__intVal(dstx),__intVal(dsty),
+ __intVal(w), __intVal(h),
+ 0, 0, /* __intVal(srcx), __intVal(srcy), */
+ 0,__intVal(h),
+ (void *)b_bits,
+ (BITMAPINFO*)&bitmap,DIB_RGB_COLORS);
+/*
+ SetDIBits(hDC,hBitmap,
+ 0,__intVal(h),
+ (void *)b_bits,
+ (BITMAPINFO*)&bitmap,DIB_RGB_COLORS);
+*/
+/*
+ StretchDIBits(hDC,
+ __intVal(dstx),(__intVal(dsty)), // x & y coord of destination upper-left corner
+ __intVal(w), __intVal(h), // width & height of destination rectangle
+ __intVal(srcx), __intVal(srcy), // x & y coord of source upper-left corner
+ __intVal(w), __intVal(h), // width & height of source rectangle
+ (void *)b_bits, // bitmap bits
+ (BITMAPINFO*)&bitmap, // bitmap data
+ DIB_RGB_COLORS, // usage options
+ SRCCOPY // raster operation code
+ );
+*/
+ 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
*/
@@ -3635,6 +3549,91 @@
"/ ^ bitsRed
^Display shiftRed
+!
+
+sortBlockForColors
+
+ ^ [:a :b |
+ a redByte == b redByte ifTrue:[
+ a greenByte == b greenByte ifTrue:[
+ a blueByte < b blueByte
+ ] ifFalse:[
+ a greenByte < b greenByte
+ ]
+ ] ifFalse:[
+ a redByte < b redByte
+ ]
+ ].
+!
+
+sortColorMapImage: image
+ "calculates a new color map for the image, sorting colors"
+
+ |sortBlock depth newColorMap newImage oldImage usedColors oldToNew oldBits newBits tmpBits|
+
+ sortBlock := self sortBlockForColors.
+ oldImage := image.
+ depth := oldImage depth.
+
+ oldImage photometric ~~ #palette ifTrue:[
+ Transcript showCR:'Compress colorMap: Only palette images have colormaps.'.
+ ^ image
+ ].
+
+ usedColors := oldImage realColorMap.
+
+
+ "/ translation table
+ oldToNew := ByteArray new:(1 bitShift:depth).
+ newColorMap := usedColors asArray.
+ newColorMap sort:sortBlock.
+
+ oldImage colorMap asArray keysAndValuesDo:[:oldIdx :clr |
+ |newPixel|
+
+ (usedColors includes:clr) ifTrue:[
+ newPixel := newColorMap indexOf:clr.
+ oldToNew at:oldIdx put:newPixel-1.
+ ]
+ ].
+
+ oldBits := oldImage bits.
+ newBits := ByteArray new:(oldBits size).
+ depth ~~ 8 ifTrue:[
+ "/ expand/compress can only handle 8bits
+ tmpBits := ByteArray uninitializedNew:(oldImage width*oldImage height).
+ oldBits
+ expandPixels:depth
+ width:oldImage width
+ height:oldImage height
+ into:tmpBits
+ mapping:oldToNew.
+ tmpBits
+ compressPixels:depth
+ width:oldImage width
+ height:oldImage height
+ into:newBits
+ mapping:nil
+ ] ifFalse:[
+ oldBits
+ expandPixels:depth
+ width:oldImage width
+ height:oldImage height
+ into:newBits
+ mapping:oldToNew.
+ ].
+
+ newImage := oldImage species new
+ width:oldImage width
+ height:oldImage height
+ depth:depth
+ fromArray:newBits.
+
+ newImage colorMap:newColorMap.
+ newImage fileName:oldImage fileName.
+ newImage mask:(oldImage mask copy).
+
+ ^newImage
! !
!WinPrinterContext methodsFor:'font stuff'!
@@ -4542,48 +4541,48 @@
%{ /* NOCONTEXT */
if (__isExternalAddress(aDrawableId)){
- BITMAP bitmap;
- HBITMAP hBitmap = _HBITMAPVAL(aDrawableId);
- HBITMAP memBM;
- HANDLE compatibleDC, rootDC, hdcScreen;
+ BITMAP bitmap;
+ HBITMAP hBitmap = _HBITMAPVAL(aDrawableId);
+ HBITMAP memBM;
+ HANDLE compatibleDC, rootDC, hdcScreen;
// HANDLE printerDC = (HANDLE)(__externalAddressVal(__INST(gcId)));
-
- if (! hBitmap) {
- RETURN (nil);
- }
-
- if (GetObject(hBitmap, sizeof(bitmap), &bitmap)) {
+ if (! hBitmap) {
+ RETURN (nil);
+ }
+
+ if (GetObject(hBitmap, sizeof(bitmap), &bitmap)) {
/*
- DDPRINTF(("bitmap info:%d\n", bitmap.bmBitsPixel));
+ DDPRINTF(("bitmap info:%d\n", bitmap.bmBitsPixel));
*/
- } else {
+ } else {
/*
- DPRINTF(("noinfo returned for bitmap\n"));
+ DPRINTF(("noinfo returned for bitmap\n"));
*/
- /* mhmh - can this happen ? */
- bitmap.bmBitsPixel = 1;
- }
+ /* mhmh - can this happen ? */
+ bitmap.bmBitsPixel = 1;
+ }
/*
- gcData->hBitmap = hBitmap;
- gcData->bitmapColorBitCount = bitmap.bmBitsPixel;
+ gcData->hBitmap = hBitmap;
+ gcData->bitmapColorBitCount = bitmap.bmBitsPixel;
*/
- rootDC = CreateDC("DISPLAY", NULL, NULL, NULL);
- compatibleDC = CreateCompatibleDC(rootDC);
- SelectObject(compatibleDC, hBitmap);
+ rootDC = CreateDC("DISPLAY", NULL, NULL, NULL);
+ compatibleDC = CreateCompatibleDC(rootDC);
+ SelectObject(compatibleDC, hBitmap);
// hdcScreen= CreateDC("NULL", NULL, NULL, NULL);
// compatibleDC = rootDC;
// compatibleDC = CreateCompatibleDC(printerDC);
// compatibleDC = CreateCompatibleDC(0);
+
// memBM = CreateCompatibleBitmap ( compatibleDC, bitmap.bmWidth, bitmap.bmHeight );
// SelectObject ( compatibleDC, memBM );
- RETURN (__MKOBJ(compatibleDC));
+ RETURN (__MKOBJ(compatibleDC));
/*
- RETURN ( __MKOBJ(gcData) );
+ RETURN ( __MKOBJ(gcData) );
*/
}
RETURN (nil);
@@ -4800,58 +4799,6 @@
%}
!
-xgcForBitmap:aDrawableId
-
-%{ /* NOCONTEXT */
-
- if (__isExternalAddress(aDrawableId)){
- BITMAP bitmap;
- HBITMAP hBitmap = _HBITMAPVAL(aDrawableId);
- HBITMAP memBM;
- HANDLE compatibleDC, rootDC, hdcScreen;
- HANDLE hDC = (HANDLE)(__externalAddressVal(__INST(gcId)));
-
- if (! hBitmap) {
- RETURN (nil);
- }
-
- if (GetObject(hBitmap, sizeof(bitmap), &bitmap)) {
-/*
- DDPRINTF(("bitmap info:%d\n", bitmap.bmBitsPixel));
-*/
- } else {
-/*
- DPRINTF(("noinfo returned for bitmap\n"));
-*/
- /* mhmh - can this happen ? */
- bitmap.bmBitsPixel = 1;
- }
-/*
- gcData->hBitmap = hBitmap;
- gcData->bitmapColorBitCount = bitmap.bmBitsPixel;
-*/
-
- rootDC = CreateDC("DISPLAY", NULL, NULL, NULL);
- compatibleDC = CreateCompatibleDC(hDC);
- SelectObject(compatibleDC, hBitmap);
-
- // hdcScreen= CreateDC("NULL", NULL, NULL, NULL);
- // compatibleDC = rootDC;
- // compatibleDC = CreateCompatibleDC(0);
- // compatibleDC = CreateCompatibleDC(hDC);
- // memBM = CreateCompatibleBitmap ( compatibleDC, bitmap.bmWidth, bitmap.bmHeight );
- // SelectObject ( compatibleDC, memBM );
-
- RETURN (__MKOBJ(compatibleDC));
-
-/*
- RETURN ( __MKOBJ(gcData) );
-*/
- }
- RETURN (nil);
-%}
-!
-
xprimDrawBits:imageBits bitsPerPixel:bitsPerPixel depth:imageDepth padding:padd width:imageWidth height:imageHeight
x:srcx y:srcy
into:ignoredDrawableId
@@ -5267,5 +5214,5 @@
!WinPrinterContext class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/WinPrinterContext.st,v 1.15 2007-05-03 13:59:24 fm Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/WinPrinterContext.st,v 1.16 2007-10-19 13:47:23 fm Exp $'
! !