*** empty log message ***
authorsr
Mon, 21 Jul 2008 17:14:40 +0200
changeset 4998 2ed2f4e7931e
parent 4997 15d53562d4e8
child 4999 b56e53c1b4d4
*** empty log message ***
Image.st
--- 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!