--- a/Image.st Wed Jul 16 12:47:11 2008 +0200
+++ b/Image.st Mon Jul 21 17:14:40 2008 +0200
@@ -15,7 +15,8 @@
instanceVariableNames:'pixelStore bytes width height bitsPerPixel depth colorMap
maxPixelValue rowByteSize bitsPerSample samplesPerPixel
photometric device deviceForm monoDeviceForm fullColorDeviceForm
- mask maskedPixelsAre0 fileName imageSequence'
+ mask maskedPixelsAre0 fileName imageSequence aaBlendWithStart
+ aaDictionary'
classVariableNames:'Lobby DitherAlgorithm NumberOfDitherColors
CollectGarbageWhenRunningOutOfColors ImageErrorSignal
ImageNotFoundQuerySignal BadImageFormatQuerySignal
@@ -769,6 +770,64 @@
^ self width:ext x height:ext y depth:d
!
+extent:ext depth:d antiAliasedPalette:aBasicColorArray bgColor:bgColor
+ ^ self extent:ext depth:d antiAliasedPalette:aBasicColorArray bgColor:bgColor mixedArray:#(1.0 0.8 0.6 0.4 0.2)
+
+ "
+ |colorMap i|
+
+ colorMap := Array with:Color white with:Color blue.
+
+ i := Depth8Image extent:300@400 depth:8 antiAliasedPalette:colorMap bgColor:Color white.
+ i fillAntiAliasedArc:200@200 radius:80 from:0 angle:360 withColor:Color blue.
+ i inspect.
+ "
+!
+
+extent:ext depth:d antiAliasedPalette:aBasicColorArray bgColor:bgColor mixedArray:mixedArray
+ |colors colorMap colorIndex colorDictionary tmpDic newImage emptyBits|
+
+ colors := OrderedCollection new.
+ colorMap := OrderedCollection new.
+ colorIndex := 0.
+ colorDictionary := Dictionary new.
+
+ aBasicColorArray do:[:aColor |
+ colorMap add:aColor.
+ colorIndex := colorIndex + 1.
+
+ tmpDic := Dictionary new.
+
+ mixedArray do:[:aFloat |
+ tmpDic at:aFloat put:colorIndex.
+ colorMap add:(aColor mixed:aFloat with:bgColor).
+ colorIndex := colorIndex + 1.
+ ].
+
+ colorDictionary at:aColor put:tmpDic.
+ ].
+
+ newImage := (self implementorForDepth:d) new.
+ newImage aaDictionary:colorDictionary.
+ newImage aaBlendWithStart:mixedArray first.
+
+ newImage width:ext x height:ext y depth:d palette:colorMap.
+ emptyBits := ByteArray new:(newImage bytesPerRow * ext y).
+ newImage bits:emptyBits.
+
+ ^ newImage
+
+ "
+ |colorMap i|
+
+ colorMap := Array with:Color white with:Color blue.
+
+ i := Depth8Image extent:300@400 depth:8 antiAliasedPalette:colorMap bgColor:Color white.
+ i fillAntiAliasedArc:200@200 radius:80 from:0 angle:360 withColor:Color blue.
+ i inspect.
+ "
+!
+
extent:ext depth:d bits:bits
"ST-80 compatibility; assume 32-bit padding"
@@ -2215,6 +2274,14 @@
!Image methodsFor:'accessing'!
+aaBlendWithStart:something
+ aaBlendWithStart := something.
+!
+
+aaDictionary:something
+ aaDictionary := something.
+!
+
bitsPerSample
"return the number of bits per sample.
The return value is an array of bits-per-plane."
@@ -3228,7 +3295,6 @@
"Created: 20.6.1996 / 17:09:53 / cg"
! !
-
!Image methodsFor:'conversion helpers'!
rgbColormapFor:aDevice
@@ -8649,7 +8715,56 @@
"
!
-fillArc:origin radius:r from:startAngle angle:angle withColor:aColorOrIndex
+fillAntiAliasedArc:origin radius:r from:startAngle angle:angle withColor:aColor
+ "draw a circle with some pixel value.
+ By using a tempForm, we assure that the same pixel algorithm is used as in a window"
+
+ |tempForm wI "{ Class: SmallInteger }"
+ hI "{ Class: SmallInteger }"
+ colorValue|
+
+ self assert:(aaBlendWithStart notNil).
+ self assert:(aaDictionary notNil).
+
+ wI := self width.
+ hI := self height.
+
+ tempForm := Form width:wI height:hI depth:1 onDevice:Screen current.
+ tempForm clear.
+ tempForm paint:(Color colorId:1).
+ tempForm fillArc:origin radius:r from:startAngle angle:angle.
+
+ colorValue := self valueFromColor:aColor.
+
+ 0 to:hI-1 do:[:yRun|
+ 0 to:wI-1 do:[:xRun|
+ (tempForm atX:xRun y:yRun) == 1 ifTrue:[
+ self atImageAndMask:(xRun)@(yRun) putValue:colorValue.
+
+ #(#left right) do:[:aHorizontal |
+ #(#top bottom) do:[:aVertical |
+ self vitualAntiAliasedAlongXvertical:aVertical horizontal:aHorizontal form:tempForm color:aColor xRun:xRun yRun:yRun.
+ self vitualAntiAliasedAlongYhorizontal:aHorizontal vertical:aVertical form:tempForm color:aColor xRun:xRun yRun:yRun.
+ ].
+ ].
+ ].
+ ].
+ ].
+
+ "
+ |cm i|
+
+ cm := Array with:Color white with:Color black with:Color red with:Color blue.
+
+ i := Depth8Image extent:300@400 depth:8 antiAliasedPalette:cm bgColor:Color white.
+ i fillAntiAliasedArc:205@195 radius:80 from:0 angle:90 withColor:Color red.
+ i fillAntiAliasedArc:200@200 radius:80 from:90 angle:270 withColor:Color blue.
+ i inspect.
+
+ "
+!
+
+fillArc:origin radius:r from:startAngle angle:angle withColor:aColorOrIndex
"draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window"
@@ -11167,7 +11282,6 @@
self photometric:(self class defaultPhotometric)
! !
-
!Image methodsFor:'instance release'!
close
@@ -13468,10 +13582,160 @@
"Modified: 11.7.1996 / 11:11:34 / cg"
! !
+!Image methodsFor:'virtual anti-aliased'!
+
+vitualAntiAliasedAlongXvertical:bottomOrTop horizontal:leftOrRight form:tempForm color:aColor xRun:xRun yRun:yRun
+ |isBottom isLeft additionalY workPoint startX endX pixels pixelPos percent distance nearestKey tmp|
+
+ self assert:(aaBlendWithStart notNil).
+ self assert:(aaDictionary notNil).
+
+ isBottom := bottomOrTop sameAs:'bottom'.
+ isBottom ifTrue:[
+ additionalY := -1.
+ ] ifFalse:[
+ additionalY := 1.
+ ].
+
+ isLeft := leftOrRight sameAs:'left'.
+ isLeft ifTrue:[
+ workPoint := (xRun - 1)@yRun.
+ [(
+ (tempForm atX:workPoint x y:workPoint y) == 0 and:[
+ (tempForm atX:workPoint x y:workPoint y + additionalY) == 1]) and:[
+ (tempForm atX:workPoint x - 1 y:workPoint y + additionalY) == 1]
+ ] whileTrue:[
+ startX := workPoint x.
+ endX isNil ifTrue:[endX := workPoint x].
+ workPoint := (workPoint x - 1)@yRun.
+ ].
+ ] ifFalse:[
+ workPoint := (xRun + 1)@yRun.
+ [(
+ (tempForm atX:workPoint x y:workPoint y) == 0 and:[
+ (tempForm atX:workPoint x y:workPoint y + additionalY) == 1]) and:[
+ (tempForm atX:workPoint x + 1 y:workPoint y + additionalY) == 1]
+ ] whileTrue:[
+ endX := workPoint x.
+ startX isNil ifTrue:[startX := workPoint x].
+ workPoint := (workPoint x + 1)@yRun.
+ ].
+ ].
+
+ (startX notNil and:[endX notNil]) ifTrue:[
+ startX = endX ifTrue:[
+ self atImageAndMask:startX@yRun putValue:((aaDictionary at:aColor) at:aaBlendWithStart).
+ ] ifFalse:[
+ pixels := (endX - startX) + 1.
+ startX to:endX do:[:x |
+ isLeft ifTrue:[
+ pixelPos := (x - startX) + 1.
+ ] ifFalse:[
+ pixelPos := (endX - x) + 1.
+ ].
+
+ percent := (100 / (pixels / pixelPos)) asFloat / 100.
+
+ (aaDictionary at:aColor) keys do:[:aKey |
+ nearestKey isNil ifTrue:[
+ distance := percent dist:aKey.
+ nearestKey := aKey.
+ ] ifFalse:[
+ tmp := percent dist:aKey.
+ distance > tmp ifTrue:[
+ distance := tmp.
+ nearestKey := aKey.
+ ].
+ ].
+ ].
+
+ self atImageAndMask:x@yRun putValue:((aaDictionary at:aColor) at:nearestKey).
+
+ distance := nil.
+ nearestKey := nil.
+ ].
+ ].
+ ].
+!
+
+vitualAntiAliasedAlongYhorizontal:leftOrRight vertical:bottomOrTop form:tempForm color:aColor xRun:xRun yRun:yRun
+ |isLeft isBottom additionalX workPoint startY endY pixels pixelPos percent distance nearestKey tmp|
+
+ self assert:(aaBlendWithStart notNil).
+ self assert:(aaDictionary notNil).
+
+ isLeft := leftOrRight sameAs:'left'.
+ isLeft ifTrue:[
+ additionalX := 1.
+ ] ifFalse:[
+ additionalX := -1.
+ ].
+
+ isBottom := bottomOrTop sameAs:'bottom'.
+ isBottom ifTrue:[
+ workPoint := xRun@(yRun + 1).
+ [(
+ (tempForm atX:workPoint x y:workPoint y) == 0 and:[
+ (tempForm atX:workPoint x + additionalX y:workPoint y) == 1]) and:[
+ (tempForm atX:workPoint x + additionalX y:workPoint y + 1) == 1]
+ ] whileTrue:[
+ endY := workPoint y.
+ startY isNil ifTrue:[startY := workPoint y].
+ workPoint := xRun@(workPoint y + 1).
+ ].
+ ] ifFalse:[
+ workPoint := xRun@(yRun - 1).
+ [(
+ (tempForm atX:workPoint x y:workPoint y) == 0 and:[
+ (tempForm atX:workPoint x + additionalX y:workPoint y) == 1]) and:[
+ (tempForm atX:workPoint x + additionalX y:workPoint y - 1) == 1]
+ ] whileTrue:[
+ startY := workPoint y.
+ endY isNil ifTrue:[endY := workPoint y].
+ workPoint := xRun@(workPoint y - 1).
+ ].
+ ].
+
+ (startY notNil and:[endY notNil]) ifTrue:[
+ startY = endY ifTrue:[
+ self atImageAndMask:xRun@startY putValue:((aaDictionary at:aColor) at:aaBlendWithStart).
+ ] ifFalse:[
+ pixels := (endY - startY) + 1.
+ startY to:endY do:[:y |
+ isBottom ifTrue:[
+ pixelPos := (endY - y) + 1.
+ ] ifFalse:[
+ pixelPos := (y - startY) + 1.
+ ].
+
+ percent := (100 / (pixels / pixelPos)) asFloat / 100.
+
+ (aaDictionary at:aColor) keys do:[:aKey |
+ nearestKey isNil ifTrue:[
+ distance := percent dist:aKey.
+ nearestKey := aKey.
+ ] ifFalse:[
+ tmp := percent dist:aKey.
+ distance > tmp ifTrue:[
+ distance := tmp.
+ nearestKey := aKey.
+ ].
+ ].
+ ].
+
+ self atImageAndMask:xRun@y putValue:((aaDictionary at:aColor) at:nearestKey).
+
+ distance := nil.
+ nearestKey := nil.
+ ].
+ ].
+ ].
+! !
+
!Image class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/Image.st,v 1.410 2008-07-16 10:47:11 sr Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/Image.st,v 1.411 2008-07-21 15:14:40 sr Exp $'
! !
Image initialize!