--- a/DeviceGraphicsContext.st Wed Jan 31 13:15:13 2018 +0100
+++ b/DeviceGraphicsContext.st Wed Jan 31 14:44:39 2018 +0100
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
@@ -1136,7 +1138,7 @@
"Modified: 4.6.1996 / 17:59:28 / cg"
!
-displayForm:formToDraw x:x y:y
+displayForm:formOrImageToDraw x:x y:y
"draw a form or image non opaque;
if it's a 1-plane bitmap, 1-bits are drawn in the
current paint-color, leaving pixels with 0-bits unchanged
@@ -1149,9 +1151,9 @@
certain, that the colors are real colors (actually, only for
noColor or allColor)."
- |realForm pX pY w h nW nH pO pC|
-
- realForm := formToDraw.
+ |realFormOrImage pX pY w h nW nH pO pC|
+
+ realFormOrImage := formOrImageToDraw.
transformation notNil ifTrue:[
pO := transformation transformPoint:x@y.
@@ -1159,8 +1161,8 @@
pY := pO y.
transformation isNoScale ifFalse:[
- w := formToDraw width.
- h := formToDraw height.
+ w := formOrImageToDraw width.
+ h := formOrImageToDraw height.
pC := transformation applyTo:(x+w-1)@(y+h-1).
nW := pC x - pX + 1.
nH := pC y - pY + 1.
@@ -1172,23 +1174,23 @@
"/ hard case - someone is drawing forms with scaling in effect
"/ look if we have a scaled version in our pocket ...
"/
- realForm := nil.
+ realFormOrImage := nil.
CachedScaledForms notNil ifTrue:[
- (CachedScales at:formToDraw ifAbsent:nil) = transformation scale ifTrue:[
- realForm := CachedScaledForms at:formToDraw ifAbsent:nil.
+ (CachedScales at:formOrImageToDraw ifAbsent:nil) = transformation scale ifTrue:[
+ realFormOrImage := CachedScaledForms at:formOrImageToDraw ifAbsent:nil.
]
].
- realForm isNil ifTrue:[
+ realFormOrImage isNil ifTrue:[
"/
"/ nope - must do the work ...
"/
- realForm := formToDraw magnifiedBy:(nW / w) @ (nH / h).
+ realFormOrImage := formOrImageToDraw magnifiedBy:(nW / w) @ (nH / h).
CachedScaledForms isNil ifTrue:[
CachedScaledForms := WeakIdentityDictionary new.
CachedScales := WeakIdentityDictionary new.
].
- CachedScaledForms at:formToDraw put:realForm.
- CachedScales at:formToDraw put:transformation scale.
+ CachedScaledForms at:formOrImageToDraw put:realFormOrImage.
+ CachedScales at:formOrImageToDraw put:transformation scale.
]
]
]
@@ -1197,7 +1199,7 @@
pY := y.
].
- self displayDeviceForm:realForm x:pX y:pY
+ self displayDeviceForm:realFormOrImage x:pX y:pY
"Modified: / 12-04-1997 / 12:47:29 / cg"
"Modified (comment): / 13-02-2017 / 20:00:13 / cg"
@@ -1935,13 +1937,14 @@
certain, that the colors are real colors (actually, only for
noColor or allColor)."
- (aFormOrImage isImage and:[aFormOrImage photometric == #rgba]) ifTrue:[
+ (aFormOrImage isImage and:[aFormOrImage hasAlphaChannel]) ifTrue:[
Error handle:[:ex |
Logger error:'error when drawing alpha: %1' with:ex description.
] do:[
self displayDeviceFormWithAlpha:aFormOrImage x:x y:y.
^ self.
].
+ ^ self.
].
self displayDeviceFormNoAlpha:aFormOrImage x:x y:y.
@@ -2303,7 +2306,8 @@
however, the alpha channel is taken care of.
This is a (slow) fallback helper for displays which do not support alpha blending"
- |bytesPerLine orgDstData dstData imgData info w h pX pY bppDrawable
+ |bytesPerLine orgDstData
+ dstBytes imgBytes info w h pX pY bppDrawable
dstBytesPerRow "{Class: SmallInteger}"
imgBytesPerRow "{Class: SmallInteger}"
dstIndex "{Class: SmallInteger}"
@@ -2312,8 +2316,14 @@
imgRowIndex "{Class: SmallInteger}"
oB "{Class: SmallInteger}"
oR "{Class: SmallInteger}"
- oG "{Class: SmallInteger}"|
-
+ oG "{Class: SmallInteger}"
+ iR "{Class: SmallInteger}"
+ iG "{Class: SmallInteger}"
+ iB "{Class: SmallInteger}"
+ iA "{Class: SmallInteger}"
+ try |
+
+ device flush.
device sync.
w := anImage width.
@@ -2325,19 +2335,51 @@
"/ give it more than enough bytes
bytesPerLine := (w * 32 + 31) // 32 * 4.
- dstData := ByteArray uninitializedNew:(bytesPerLine * h).
- drawableType == #pixmap ifTrue:[
- info := device getBitsFromPixmapId:(self drawableId) x:pX y:pY width:w height:h into:dstData.
- ] ifFalse:[
- info := device getBitsFromViewId:(self drawableId) x:pX y:pY width:w height:h into:dstData.
+ dstBytes := ByteArray uninitializedNew:(bytesPerLine * h).
+
+ "/ OSX XQuartz bug workaround
+ "/ if I do this, the Inspector can read the window's bits
+ "/ (sometimes after a retry)
+ "/ however, the imageEditor stil has problems to show the image
+ "/ in its lower left preview area.
+ "/ This should really really not be required!!!!!!
+ try := 1.
+ Error handle:[:ex |
+ try < 5 ifTrue:[
+ try := try + 1.
+ device flush.
+ device sync.
+ Delay waitForMilliseconds:20.
+ device flush.
+ device sync.
+ ex restart.
+ ].
+ ex reject
+ ] do:[
+ drawableType == #pixmap ifTrue:[
+ info := device getBitsFromPixmapId:(self drawableId) x:pX y:pY width:w height:h into:dstBytes.
+ ] ifFalse:[
+ info := device getBitsFromViewId:(self drawableId) x:pX y:pY width:w height:h into:dstBytes.
+ ].
].
-
dstBytesPerRow := info at:#bytesPerLine.
imgBytesPerRow := anImage bytesPerRow.
- imgData := anImage bits.
- orgDstData := dstData copy.
-
+ imgBytes := anImage bits.
+ orgDstData := dstBytes copy.
+
+ iR := 0.
+ iG := 1.
+ iB := 2.
+ iA := 3.
+ anImage photometric == #argb ifTrue:[
+ iA := 0.
+ iR := 1.
+ iG := 2.
+ iB := 3.
+ ].
+
+ "/ TODO: the following code is a nr1 candidate for inline c-code
bppDrawable := info at:#bitsPerPixel.
bppDrawable == 32 ifTrue:[
"/ data is coming as bytes in r,g,b,a order
@@ -2365,14 +2407,14 @@
nG "{Class: SmallInteger}"
nB "{Class: SmallInteger}"|
- rD := dstData at:(dstIndex+oR).
- gD := dstData at:(dstIndex+oG).
- bD := dstData at:(dstIndex+oB).
-
- rI := imgData at:(imgIndex).
- gI := imgData at:(imgIndex+1).
- bI := imgData at:(imgIndex+2).
- aI := imgData at:(imgIndex+3).
+ rD := dstBytes at:(dstIndex+oR).
+ gD := dstBytes at:(dstIndex+oG).
+ bD := dstBytes at:(dstIndex+oB).
+
+ rI := imgBytes at:(imgIndex+iR).
+ gI := imgBytes at:(imgIndex+iG).
+ bI := imgBytes at:(imgIndex+iB).
+ aI := imgBytes at:(imgIndex+iA).
aI == 255 ifTrue:[
nR := rI.
@@ -2391,9 +2433,10 @@
nB := (((bI * aI)+(bD * aD)) // 255).
].
].
- dstData at:(dstIndex+1) put:nR.
- dstData at:(dstIndex+2) put:nG.
- dstData at:(dstIndex+3) put:nB.
+ "/ dstBytes at:(dstIndex) put:255.
+ dstBytes at:(dstIndex+1) put:nR.
+ dstBytes at:(dstIndex+2) put:nG.
+ dstBytes at:(dstIndex+3) put:nB.
dstIndex := dstIndex + 4.
imgIndex := imgIndex + 4.
@@ -2403,11 +2446,15 @@
].
"/ draw the pixels (always MSB)
device
- drawBits:dstData bitsPerPixel:32 depth:24 padding:32
+ drawBits:dstBytes bitsPerPixel:32 depth:24 padding:32
width:w height:h x:0 y:0
into:(self drawableId) x:pX y:pY width:w height:h with:gcId.
+
+ device flush.
+ device sync.
^ self.
].
+
bppDrawable == 24 ifTrue:[
"/ data is coming as bytes in r,g,b order
dstRowIndex := 1.
@@ -2436,14 +2483,14 @@
nG "{Class: SmallInteger}"
nB "{Class: SmallInteger}"|
- rD := dstData at:(dstIndex+oR).
- gD := dstData at:(dstIndex+oG).
- bD := dstData at:(dstIndex+oB).
-
- rI := imgData at:(imgIndex).
- gI := imgData at:(imgIndex+1).
- bI := imgData at:(imgIndex+2).
- aI := imgData at:(imgIndex+3).
+ rD := dstBytes at:(dstIndex+oR).
+ gD := dstBytes at:(dstIndex+oG).
+ bD := dstBytes at:(dstIndex+oB).
+
+ rI := imgBytes at:(imgIndex+iR).
+ gI := imgBytes at:(imgIndex+iG).
+ bI := imgBytes at:(imgIndex+iB).
+ aI := imgBytes at:(imgIndex+iA).
aI == 255 ifTrue:[
nR := rI.
@@ -2462,9 +2509,9 @@
nB := (((bI * aI)+(bD * aD)) // 255).
].
].
- dstData at:(dstIndex+2) put:nR.
- dstData at:(dstIndex+1) put:nG.
- dstData at:(dstIndex+0) put:nB.
+ dstBytes at:(dstIndex+2) put:nR.
+ dstBytes at:(dstIndex+1) put:nG.
+ dstBytes at:(dstIndex+0) put:nB.
dstIndex := dstIndex + 3.
imgIndex := imgIndex + 4.
@@ -2474,12 +2521,17 @@
].
"/ draw the pixels (always MSB)
device
- drawBits:dstData bitsPerPixel:24 depth:24 padding:32
+ drawBits:dstBytes bitsPerPixel:24 depth:24 padding:32
width:w height:h x:0 y:0
into:(self drawableId) x:pX y:pY width:w height:h with:gcId.
+
+ device flush.
+ device sync.
^ self.
].
- self halt.
+
+ Logger info:'(X11GC): drawing alpha into non24, non-32 displays is currently not supported'.
+ self displayDeviceFormNoAlpha:anImage x:x y:y.
"Created: / 11-04-2017 / 16:45:39 / cg"
"Modified: / 12-04-2017 / 10:38:52 / cg"