#FEATURE by cg
authorClaus Gittinger <cg@exept.de>
Wed, 07 Mar 2018 20:56:13 +0100
changeset 8301 d4ba3e39cae1
parent 8300 d79edf82e072
child 8302 509a01db4028
#FEATURE by cg class: Image added: #bitBltFrom:function:x:y:toX:y:width:height: #fillRectangle:color: changed: #copyFrom:x:y:toX:y:width:height: #valueFromColor:
Image.st
--- a/Image.st	Wed Mar 07 18:30:08 2018 +0100
+++ b/Image.st	Wed Mar 07 20:56:13 2018 +0100
@@ -2740,6 +2740,12 @@
     "
 !
 
+fillRectangle:aRectangle color:aColor
+    "fill the rectangular area specified by aRectangle with the given color"
+
+    self fillRectangle:aRectangle withColor:aColor
+!
+
 fillWhite:aRectangle
     "fill the rectangular area specified by aRectangle with the white color"
 
@@ -13649,6 +13655,61 @@
 
 !Image methodsFor:'pixel copying'!
 
+bitBltFrom:anImage function:function x:srcX y:srcY toX:dstX y:dstY width:w height:h
+    "operates on pixel values.
+     Any mask is left unchanged.
+
+     WARNING:
+       This is a q@d hack to support the minimum needed for the QRCode generator.
+
+       This implementation is a very slow fallback general algorithm
+       (the loop over the source pixels is very slow).
+       If this method is used heavily, you may want to redefine it in
+       concrete subclasses for the common case of of copying from an Image
+       with the same depth & palette.
+       If you do heavy image processing, specialized versions are even req'd
+       for other cases, rewriting the inner loops as inline C-code."
+
+    |dX dY op|
+
+    dX := srcX-dstX.
+    dY := srcY-dstY.
+
+    function == #copy ifTrue:[
+        anImage 
+            valuesFromX:srcX  y:srcY
+            toX:srcX+w-1 y:srcY+h-1
+            do:[:x :y :pixelValue |
+                self pixelAtX:x-dX y:y-dY put:pixelValue.
+            ].
+        ^ self.
+    ].
+
+    function == #xor ifTrue:[
+        op := [:a :b | a bitXor:b]
+    ] ifFalse:[
+        function == #and ifTrue:[
+            op := [:a :b | a bitAnd:b]
+        ] ifFalse:[
+            function == #or ifTrue:[
+                op := [:a :b | a bitOr:b]
+            ] ifFalse:[
+                self halt
+            ].
+        ].
+    ].
+
+    anImage 
+        valuesFromX:srcX  y:srcY
+        toX:srcX+w-1 y:srcY+h-1
+        do:[:x :y :pixelValue1 |
+            |pixelValue2|
+
+            pixelValue2 := self pixelAtX:x-dX y:y-dY.
+            self pixelAtX:x-dX y:y-dY put:(op value:pixelValue1 value:pixelValue2).
+        ]
+!
+
 copyFrom:anImage x:srcX y:srcY toX:dstX y:dstY width:w height:h
     "replace a rectangular area by pixels from another image.
      The source's colors must be present in the destination's
@@ -13673,18 +13734,36 @@
      and:[self bitsPerPixel == anImage bitsPerPixel
      and:[colorMap = anImage colorMap]]) ifTrue:[
         "/ can loop over values
-        anImage valuesFromX:srcX  y:srcY
-                        toX:srcX+w-1 y:srcY+h-1
-                         do:[:x :y :pixelValue |
-            self pixelAtX:x-dX y:y-dY put:pixelValue.
-        ]
+        anImage 
+            valuesFromX:srcX  y:srcY
+            toX:srcX+w-1 y:srcY+h-1
+            do:[:x :y :pixelValue |
+                |dstX dstY|
+
+                dstX := x-dX.
+                (dstX >= 0 and:[dstX < width]) ifTrue:[
+                    dstY := y-dY.
+                    (dstY >= 0 and:[dstY < height]) ifTrue:[
+                        self pixelAtX:dstX y:dstY put:pixelValue.
+                    ]
+                ]
+            ]
     ] ifFalse:[
         "/ must loop over colors - horribly slow
-        anImage colorsFromX:srcX  y:srcY
-                        toX:srcX+w-1 y:srcY+h-1
-                         do:[:x :y :clr |
-            self colorAtX:x-dX y:y-dY put:clr.
-        ]
+        anImage 
+            colorsFromX:srcX  y:srcY
+            toX:srcX+w-1 y:srcY+h-1
+            do:[:x :y :clr |
+                |dstX dstY|
+
+                dstX := x-dX.
+                (dstX >= 0 and:[dstX < width]) ifTrue:[
+                    dstY := y-dY.
+                    (dstY >= 0 and:[dstY < height]) ifTrue:[
+                        self colorAtX:x-dX y:y-dY put:clr.
+                    ]
+                ]
+            ]
     ].
 
     (mask isNil and:[anImage mask notNil]) ifTrue:[
@@ -15565,6 +15644,11 @@
 
     |pixel maxPixel redBits greenBits blueBits alphaBits r g b a|
 
+    color isInteger ifTrue:[
+        self halt.
+        ^ color
+    ].
+
     color colorId notNil ifTrue:[
         color == Color noColor ifTrue:[
             ^ nil "/ mask