[squeak-dev] ImageForm color with alpha

Stéphane Rollandin lecteur at zogotounga.net
Tue Dec 11 08:00:30 UTC 2018


> 
>     Why is it that
> 
>              (Morph new color: (Color blue alpha: 0.5))
> 
>     and
> 
>              (Morph new color: (Color blue alpha: 0.5)) imageForm asMorph
> 
>     do not have the same color?
> 
> 
> Because ImageMorph is using "Form blend" rule instead of "Form 
> blendAlphaScaled".


Where does this happen? Using SketchMorph instead of ImageMorph shows 
the same behavior.

The only way I found so far to fix the issue is to subclass FormCanvas 
as FormCanvas2, with the single method #setFillColor: where I changed 
the #blend send to #blendAlpha, and then to redefine 
#imageForm:forRectangle: in Rectangle as

imageForm: depth forRectangle: rect
	| canvas |
	canvas := FormCanvas2 extent: rect extent depth: depth.
	canvas translateBy: rect topLeft negated
		during:[:tempCanvas| tempCanvas fullDrawMorph: self].
	^ canvas form offset: rect topLeft

(see attached code)

Is there another way to have a Form exactly faithful to the displayed 
morph? And shouldn't that be the defaut behavior of #imageForm (in other 
words, isn't the current behavior a bug)?

Best,

Stef
-------------- next part --------------
'From Squeak5.1 of 23 August 2016 [latest update: #16548] on 11 December 2018 at 8:58:43 am'!

!Morph methodsFor: '*Sprite-override' stamp: 'spfa 12/10/2018 13:21'!
imageForm: depth forRectangle: rect
	| canvas |
	canvas := FormCanvas2 extent: rect extent depth: depth.
	canvas translateBy: rect topLeft negated
		during:[:tempCanvas| tempCanvas fullDrawMorph: self].
	^ canvas form offset: rect topLeft! !
-------------- next part --------------
'From Squeak5.1 of 23 August 2016 [latest update: #16548] on 11 December 2018 at 8:58:37 am'!
FormCanvas subclass: #FormCanvas2
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Sprite-Ancillary'!

!FormCanvas2 methodsFor: 'as yet unclassified' stamp: 'spfa 12/10/2018 13:15'!
setFillColor: aColor
	"Install a new color used for filling."
	| screen patternWord fillColor |
	fillColor := self shadowColor ifNil:[aColor].
	fillColor ifNil:[fillColor := Color transparent].
	fillColor isColor ifFalse:[
		(fillColor isKindOf: InfiniteForm) ifFalse:[^self error:'Cannot install color'].
		^port fillPattern: fillColor; combinationRule: Form over].
	"Okay, so fillColor really *is* a color"
	port sourceForm: nil.
	fillColor isTranslucent ifFalse:[
		port combinationRule: Form over.
		port fillPattern: fillColor.
		self depth = 8 ifTrue:[
			"In 8 bit depth it's usually a good idea to use a stipple pattern"
			port fillColor: (form balancedPatternFor: fillColor)].
		^self].
	"fillColor is some translucent color"

	self depth > 8 ifTrue:[
		"BitBlt setup for alpha masked transfer"
		port fillPattern: fillColor.
		self depth = 16
			ifTrue:[port alphaBits: fillColor privateAlpha; combinationRule: 30]
			ifFalse:[port combinationRule: Form blendAlpha].
		^self].
	"Can't represent actual transparency -- use stipple pattern"
	screen := Color translucentMaskFor: fillColor alpha depth: self depth.
	patternWord := form pixelWordFor: fillColor.
	port fillPattern: (screen collect: [:maskWord | maskWord bitAnd: patternWord]).
	port combinationRule: Form paint.
! !


More information about the Squeak-dev mailing list