--- a/WinPrinterContext.st Wed Apr 25 12:27:22 2007 +0200
+++ b/WinPrinterContext.st Wed Apr 25 14:17:13 2007 +0200
@@ -2549,6 +2549,453 @@
%}
!
+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"
+!
+
drawBits:imageBits bitsPerPixel:bitsPerPixel depth:imageDepth padding:padd
width:imageWidth height:imageHeight
x:srcx y:srcy
@@ -4557,5 +5004,5 @@
!WinPrinterContext class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/WinPrinterContext.st,v 1.13 2007-04-25 10:27:22 fm Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/WinPrinterContext.st,v 1.14 2007-04-25 12:17:13 fm Exp $'
! !