to do #displayDeviceForm:aForm x:x y:y
authorfm
Wed, 25 Apr 2007 14:17:13 +0200
changeset 2329 f5a1833995a1
parent 2328 90f481d446bc
child 2330 5f3b78d00a18
to do #displayDeviceForm:aForm x:x y:y
WinPrinterContext.st
--- 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 $'
 ! !