#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:
--- 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