[Vm-dev] VM Maker: VMMaker.oscog-nice.1754.mcz

commits at source.squeak.org commits at source.squeak.org
Thu Mar 31 20:07:04 UTC 2016


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1754.mcz

==================== Summary ====================

Name: VMMaker.oscog-nice.1754
Author: nice
Time: 31 March 2016, 10:04:44.274 pm
UUID: a0138c60-3e62-446e-a1d8-b00b7bb6c92b
Ancestors: VMMaker.oscog-eem.1753

BitBltSimulation is operating on bits of 32bits words, therefore it's better to declare its operans as 'unsigned int' rather than sqInt.

On 32bits VM, this should not change anything, but on 64bits spur, it makes this snippet work:

| wideString source pos blt expectedWideString |
source := #[1 64 255 14 1 64 48 251].
expectedWideString := WideString fromByteArray: source.
wideString := WideString new: source size // 4.
pos := 0.
blt := (BitBlt
        toForm: (Form new hackBits: wideString))
        sourceForm: (Form new hackBits: source).
blt
        combinationRule: Form over;
        sourceX: 0;
        sourceY: pos // 4;
        height: wideString byteSize // 4;
        width: 4;
        destX: 0;
        destY: 0;
        copyBits.
wideString restoreEndianness.
self assert: wideString = expectedWideString

Hence it fix loading/diffing MCZ with wide character.

=============== Diff against VMMaker.oscog-eem.1753 ===============

Item was changed:
  ----- Method: BitBltSimulation>>addWord:with: (in category 'combination rules') -----
  addWord: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord + destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>alphaBlend:with: (in category 'combination rules') -----
  alphaBlend: sourceWord with: destinationWord
  	"Blend sourceWord with destinationWord, assuming both are 32-bit pixels.
  	The source is assumed to have 255*alpha in the high 8 bits of each pixel,
  	while the high 8 bits of the destinationWord will be ignored.
  	The blend produced is alpha*source + (1-alpha)*dest, with
  	the computation being performed independently on each color
  	component.  The high byte of the result will be 0."
  	| alpha unAlpha result blendRB blendAG |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
- 	<return: 'unsigned int'>
  	<var: #sourceWord type: 'unsigned int'>
  	<var: #destinationWord type: 'unsigned int'>
  	<var: #blendRB type: 'unsigned int'>
  	<var: #blendAG type: 'unsigned int'>
  	<var: #result type: 'unsigned int'>
  	<var: #alpha type: 'unsigned int'>
  	<var: #unAlpha type: 'unsigned int'>
  	alpha := sourceWord >> 24.  "High 8 bits of source pixel"
  	alpha = 0 ifTrue: [ ^ destinationWord ].
  	alpha = 255 ifTrue: [ ^ sourceWord ].
  	unAlpha := 255 - alpha.
  
  	blendRB := ((sourceWord bitAnd: 16rFF00FF) * alpha) +
  				((destinationWord bitAnd: 16rFF00FF) * unAlpha)
  				+ 16rFF00FF.	"blend red and blue"
  
  	blendAG := (((sourceWord>> 8 bitOr: 16rFF0000) bitAnd: 16rFF00FF) * alpha) +
  				((destinationWord>>8 bitAnd: 16rFF00FF) * unAlpha)
  				+ 16rFF00FF.	"blend alpha and green"
  
  	blendRB := blendRB + (blendRB - 16r10001 >> 8 bitAnd: 16rFF00FF) >> 8 bitAnd: 16rFF00FF.	"divide by 255"
  	blendAG := blendAG + (blendAG - 16r10001 >> 8 bitAnd: 16rFF00FF) >> 8 bitAnd: 16rFF00FF.
  	result := blendRB bitOr: blendAG<<8.
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>alphaBlendConst:with: (in category 'combination rules') -----
  alphaBlendConst: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  
  	^ self alphaBlendConst: sourceWord with: destinationWord paintMode: false!

Item was changed:
  ----- Method: BitBltSimulation>>alphaBlendConst:with:paintMode: (in category 'combination rules') -----
  alphaBlendConst: sourceWord with: destinationWord paintMode: paintMode
  	"Blend sourceWord with destinationWord using a constant alpha.
  	Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.
  	The blend produced is alpha*source + (1.0-alpha)*dest, with the
  	computation being performed independently on each color component.
  	This function could eventually blend into any depth destination,
  	using the same color averaging and mapping as warpBlt.
  	paintMode = true means do nothing if the source pixel value is zero."
  
  	"This first implementation works with dest depths of 16 and 32 bits only.
  	Normal color mapping will allow sources of lower depths in this case,
  	and results can be mapped directly by truncation, so no extra color maps are needed.
  	To allow storing into any depth will require subsequent addition of two other
  	colormaps, as is the case with WarpBlt."
  
  	| pixMask destShifted sourceShifted destPixVal rgbMask sourcePixVal unAlpha result pixBlend shift blend maskShifted bitsPerColor blendAG blendRB |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
- 	<return: 'unsigned int'>
  	<var: #sourceWord type: 'unsigned int'>
  	<var: #destinationWord type: 'unsigned int'>
  	<var: #blendRB type: 'unsigned int'>
  	<var: #blendAG type: 'unsigned int'>
  	<var: #result type: 'unsigned int'>
  	<var: #sourceAlpha type: 'unsigned int'>
  	<var: #unAlpha type: 'unsigned int'>
+ 	<var: #sourceShifted type: 'unsigned int'>
+ 	<var: #destShifted type: 'unsigned int'>
+ 	<var: #maskShifted type: 'unsigned int'>
+ 	<var: #pixMask type: 'unsigned int'>
+ 	<var: #rgbMask type: 'unsigned int'>
+ 	<var: #pixBlend type: 'unsigned int'>
+ 	<var: #blend type: 'unsigned int'>
  	destDepth < 16 ifTrue: [^ destinationWord "no-op"].
  	unAlpha := 255 - sourceAlpha.
  	result := destinationWord.
  	destPPW = 1 ifTrue:["32bpp blends include alpha"
  		paintMode & (sourceWord = 0)  "painting a transparent pixel" ifFalse:[
  
  				blendRB := ((sourceWord bitAnd: 16rFF00FF) * sourceAlpha) +
  						((destinationWord bitAnd: 16rFF00FF) * unAlpha) + 16rFF00FF.	"blendRB red and blue"
  
  				blendAG := ((sourceWord>> 8 bitAnd: 16rFF00FF) * sourceAlpha) +
  						((destinationWord>>8 bitAnd: 16rFF00FF) * unAlpha) + 16rFF00FF.	"blendRB alpha and green"
  
  				blendRB := blendRB + (blendRB - 16r10001 >> 8 bitAnd: 16rFF00FF) >> 8 bitAnd: 16rFF00FF.	"divide by 255"
  				blendAG := blendAG + (blendAG - 16r10001 >> 8 bitAnd: 16rFF00FF) >> 8 bitAnd: 16rFF00FF.
  				result := blendRB bitOr: blendAG<<8.
  		].
  	] ifFalse:[
  		pixMask := maskTable at: destDepth.
  		bitsPerColor := 5.
  		rgbMask := 16r1F.
  		maskShifted := destMask.
  		destShifted := destinationWord.
  		sourceShifted := sourceWord.
  		1 to: destPPW do:[:j |
  			sourcePixVal := sourceShifted bitAnd: pixMask.
  			((maskShifted bitAnd: pixMask) = 0  "no effect if outside of dest rectangle"
  				or: [paintMode & (sourcePixVal = 0)  "or painting a transparent pixel"])
  			ifFalse:
  				[destPixVal := destShifted bitAnd: pixMask.
  				pixBlend := 0.
  				1 to: 3 do:
  					[:i | shift := (i-1)*bitsPerColor.
  					blend := (((sourcePixVal>>shift bitAnd: rgbMask) * sourceAlpha)
  								+ ((destPixVal>>shift bitAnd: rgbMask) * unAlpha))
  						 	+ 254 // 255 bitAnd: rgbMask.
  					pixBlend := pixBlend bitOr: blend<<shift].
  				result := (result bitAnd: (pixMask << (j-1*16)) bitInvert32)
  								bitOr: pixBlend << (j-1*16)].
  			maskShifted := maskShifted >> destDepth.
  			sourceShifted := sourceShifted >> destDepth.
  			destShifted := destShifted >> destDepth].
  	].
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>alphaBlendScaled:with: (in category 'combination rules') -----
  alphaBlendScaled: sourceWord with: destinationWord
  	"Blend sourceWord with destinationWord using the alpha value from sourceWord.
  	Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.
  	In contrast to alphaBlend:with: the color produced is
  
  		srcColor + (1-srcAlpha) * dstColor
  
  	e.g., it is assumed that the source color is already scaled."
  	| unAlpha rb ag |
  	<inline: false>	"Do NOT inline this into optimized loops"
+ 	<returnTypeC: 'unsigned int'>
  	<var: #sourceWord type: 'unsigned int'>
  	<var: #destinationWord type: 'unsigned int'>
  	<var: #rb type: 'unsigned int'>
  	<var: #ag type: 'unsigned int'>
  	<var: #unAlpha type: 'unsigned int'>
  	unAlpha := 255 - (sourceWord >> 24).  "High 8 bits of source pixel is source opacity (ARGB format)"
  	rb := ((destinationWord bitAnd: 16rFF00FF) * unAlpha >> 8 bitAnd: 16rFF00FF) + (sourceWord bitAnd: 16rFF00FF). "blend red and blue components"
  	ag := ((destinationWord>>8 bitAnd: 16rFF00FF) * unAlpha >> 8 bitAnd: 16rFF00FF) + (sourceWord>>8 bitAnd: 16rFF00FF). "blend alpha and green components"
  	rb := (rb bitAnd: 16rFF00FF) bitOr: (rb bitAnd: 16r1000100) * 16rFF >> 8. "saturate red and blue components if there is a carry"
  	ag := (ag bitAnd: 16rFF00FF) << 8 bitOr: (ag bitAnd: 16r1000100) * 16rFF. "saturate alpha and green components if there is a carry"
  	^ag bitOr: rb "recompose"!

Item was changed:
  ----- Method: BitBltSimulation>>alphaPaintConst:with: (in category 'combination rules') -----
  alphaPaintConst: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  
  	sourceWord = 0 ifTrue: [^ destinationWord  "opt for all-transparent source"].
  	^ self alphaBlendConst: sourceWord with: destinationWord paintMode: true!

Item was changed:
  ----- Method: BitBltSimulation>>alphaSourceBlendBits16 (in category 'inner loop') -----
  alphaSourceBlendBits16
  	"This version assumes 
  		combinationRule = 34
  		sourcePixSize = 32
  		destPixSize = 16
  		sourceForm ~= destForm.
  	"
  	| srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY 
  	srcY dstY dstMask srcShift ditherBase ditherIndex ditherThreshold |
  	<inline: false> "This particular method should be optimized in itself"
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	<var: #dstMask type: #'unsigned int'>
  	deltaY := bbH + 1. "So we can pre-decrement"
  	srcY := sy.
  	dstY := dy.
  	srcShift := (dx bitAnd: 1) * 16.
  	destMSB ifTrue:[srcShift := 16 - srcShift].
  	mask1 := 16rFFFF << (16 - srcShift).
  	"This is the outer loop"
  	[(deltaY := deltaY - 1) ~= 0] whileTrue:[
  		srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).
  		dstIndex := destBits + (dstY * destPitch) + (dx // 2 * 4).
  		ditherBase := (dstY bitAnd: 3) * 4.
  		ditherIndex := (sx bitAnd: 3) - 1. "For pre-increment"
  		deltaX := bbW + 1. "So we can pre-decrement"
  		dstMask := mask1.
  		dstMask = 16rFFFF ifTrue:[srcShift := 16] ifFalse:[srcShift := 0].
  
  		"This is the inner loop"
  		[(deltaX := deltaX - 1) ~= 0] whileTrue:[
  			ditherThreshold := ditherMatrix4x4 at: ditherBase + (ditherIndex := ditherIndex + 1 bitAnd: 3).
  			sourceWord := self srcLongAt: srcIndex.
  			srcAlpha := sourceWord >> 24.
  			srcAlpha = 255 ifTrue:[
  				"Dither from 32 to 16 bit"
  				sourceWord := self dither32To16: sourceWord threshold: ditherThreshold.
  				sourceWord = 0 
  					ifTrue:[sourceWord := 1 << srcShift]
  					ifFalse: [sourceWord := sourceWord << srcShift].
  				"Store masked value"
  				self dstLongAt: dstIndex put: sourceWord mask: dstMask.
  			] ifFalse:[ "srcAlpha ~= 255"
  				srcAlpha = 0 ifFalse:[ "0 < srcAlpha < 255"
  					"If we have to mix colors then just copy a single word"
  					destWord := self dstLongAt: dstIndex.
  					destWord := destWord bitAnd: dstMask bitInvert32.
  					destWord := destWord >> srcShift.
  					"Expand from 16 to 32 bit by adding zero bits"
  					destWord := (((destWord bitAnd: 16r7C00) bitShift: 9) bitOr:
  									((destWord bitAnd: 16r3E0) bitShift: 6)) bitOr:
  								(((destWord bitAnd: 16r1F) bitShift: 3) bitOr:
  									16rFF000000).
  					"Mix colors"
  					sourceWord := self alphaBlendScaled: sourceWord with: destWord.
  					"And dither"
  					sourceWord := self dither32To16: sourceWord threshold: ditherThreshold.
  					sourceWord = 0 
  						ifTrue:[sourceWord := 1 << srcShift]
  						ifFalse:[sourceWord := sourceWord << srcShift].
  					"Store back"
  					self dstLongAt: dstIndex put: sourceWord mask: dstMask.
  				].
  			].
  			srcIndex := srcIndex + 4.
  			destMSB
  				ifTrue:[srcShift = 0 ifTrue:[dstIndex := dstIndex + 4]]
  				ifFalse:[srcShift = 0 ifFalse:[dstIndex := dstIndex + 4]].
  			srcShift := srcShift bitXor: 16. "Toggle between 0 and 16"
  			dstMask := dstMask bitInvert32. "Mask other half word"
  		].
  		srcY := srcY + 1.
  		dstY := dstY + 1.
  	].!

Item was changed:
  ----- Method: BitBltSimulation>>alphaSourceBlendBits32 (in category 'inner loop') -----
  alphaSourceBlendBits32
  	"This version assumes 
  		combinationRule = 34
  		sourcePixSize = destPixSize = 32
  		sourceForm ~= destForm.
  	Note: The inner loop has been optimized for dealing
  		with the special cases of srcAlpha = 0.0 and srcAlpha = 1.0 
  	"
  	| srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY srcY dstY |
  	<inline: false> "This particular method should be optimized in itself"
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
  
  	"Give the compile a couple of hints"
  
  	"The following should be declared as pointers so the compiler will
  	notice that they're used for accessing memory locations 
  	(good to know on an Intel architecture) but then the increments
  	would be different between ST code and C code so must hope the
  	compiler notices what happens (MS Visual C does)"
  
  	deltaY := bbH + 1. "So we can pre-decrement"
  	srcY := sy.
  	dstY := dy.
  
  	"This is the outer loop"
  	[(deltaY := deltaY - 1) ~= 0] whileTrue:[
  		srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).
  		dstIndex := destBits + (dstY * destPitch) + (dx * 4).
  		deltaX := bbW + 1. "So we can pre-decrement"
  
  		"This is the inner loop"
  		[(deltaX := deltaX - 1) ~= 0] whileTrue:[
  			sourceWord := self srcLongAt: srcIndex.
  			srcAlpha := sourceWord >> 24.
  			srcAlpha = 255 ifTrue:[
  				self dstLongAt: dstIndex put: sourceWord.
  				srcIndex := srcIndex + 4.
  				dstIndex := dstIndex + 4.
  				"Now copy as many words as possible with alpha = 255"
  				[(deltaX := deltaX - 1) ~= 0 and:[
  					(sourceWord := self srcLongAt: srcIndex) >> 24 = 255]]
  						whileTrue:[
  							self dstLongAt: dstIndex put: sourceWord.
  							srcIndex := srcIndex + 4.
  							dstIndex := dstIndex + 4.
  						].
  				"Adjust deltaX"
  				deltaX := deltaX + 1.
  			] ifFalse:[ "srcAlpha ~= 255"
  				srcAlpha = 0 ifTrue:[
  					srcIndex := srcIndex + 4.
  					dstIndex := dstIndex + 4.
  					"Now skip as many words as possible,"
  					[(deltaX := deltaX - 1) ~= 0 and:[
  						(sourceWord := self srcLongAt: srcIndex) >> 24 = 0]]
  						whileTrue:[
  							srcIndex := srcIndex + 4.
  							dstIndex := dstIndex + 4.
  						].
  					"Adjust deltaX"
  					deltaX := deltaX + 1.
  				] ifFalse:[ "0 < srcAlpha < 255"
  					"If we have to mix colors then just copy a single word"
  					destWord := self dstLongAt: dstIndex.
  					destWord := self alphaBlendScaled: sourceWord with: destWord.
  					self dstLongAt: dstIndex put: destWord.
  					srcIndex := srcIndex + 4.
  					dstIndex := dstIndex + 4.
  				].
  			].
  		].
  		srcY := srcY + 1.
  		dstY := dstY + 1.
  	].!

Item was changed:
  ----- Method: BitBltSimulation>>alphaSourceBlendBits8 (in category 'inner loop') -----
  alphaSourceBlendBits8
  	"This version assumes 
  		combinationRule = 34
  		sourcePixSize = 32
  		destPixSize = 8
  		sourceForm ~= destForm.
  	Note: This is not real blending since we don't have the source colors available.
  	"
  	| srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY 
  	srcY dstY dstMask srcShift adjust mappingTable mapperFlags |
  	<inline: false>
  	<var: #mappingTable type:'unsigned int *'>
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	<var: #dstMask type: #'unsigned int'>
  	mappingTable := self default8To32Table.
  	mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.
  	deltaY := bbH + 1. "So we can pre-decrement"
  	srcY := sy.
  	dstY := dy.
  	mask1 := ((dx bitAnd: 3) * 8).
  	destMSB ifTrue:[mask1 := 24 - mask1].
  	mask2 := AllOnes bitXor:(16rFF << mask1).
  	(dx bitAnd: 1) = 0 
  		ifTrue:[adjust := 0]
  		ifFalse:[adjust := 16r1F1F1F1F].
  	(dy bitAnd: 1) = 0
  		ifTrue:[adjust := adjust bitXor: 16r1F1F1F1F].
  	"This is the outer loop"
  	[(deltaY := deltaY - 1) ~= 0] whileTrue:[
  		adjust := adjust bitXor: 16r1F1F1F1F.
  		srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).
  		dstIndex := destBits + (dstY * destPitch) + (dx // 4 * 4).
  		deltaX := bbW + 1. "So we can pre-decrement"
  		srcShift := mask1.
  		dstMask := mask2.
  
  		"This is the inner loop"
  		[(deltaX := deltaX - 1) ~= 0] whileTrue:[
  			sourceWord := ((self srcLongAt: srcIndex) bitAnd: (adjust bitInvert32)) + adjust.
  			srcAlpha := sourceWord >> 24.
  			srcAlpha > 31 ifTrue:["Everything below 31 is transparent"
  				srcAlpha < 224 ifTrue:["Everything above 224 is opaque"
  					destWord := self dstLongAt: dstIndex.
  					destWord := destWord bitAnd: dstMask bitInvert32.
  					destWord := destWord >> srcShift.
  					destWord := mappingTable at: destWord.
  					sourceWord := self alphaBlendScaled: sourceWord with: destWord.
  				].
  				sourceWord := self mapPixel: sourceWord flags: mapperFlags.
  				sourceWord := sourceWord << srcShift.
  				"Store back"
  				self dstLongAt: dstIndex put: sourceWord mask: dstMask.
  			].
  			srcIndex := srcIndex + 4.
  			destMSB ifTrue:[
  				srcShift = 0 
  					ifTrue:[dstIndex := dstIndex + 4.
  							srcShift := 24.
  							dstMask := 16r00FFFFFF]
  					ifFalse:[srcShift := srcShift - 8.
  							dstMask := (dstMask >> 8) bitOr: 16rFF000000].
  			] ifFalse:[
  				srcShift = 24
  					ifTrue:[dstIndex := dstIndex + 4.
  							srcShift := 0.
  							dstMask := 16rFFFFFF00]
  					ifFalse:[srcShift := srcShift + 8.
  							dstMask := dstMask << 8 bitOr: 255].
  			].
  			adjust := adjust bitXor: 16r1F1F1F1F.
  		].
  		srcY := srcY + 1.
  		dstY := dstY + 1.
  	].!

Item was changed:
  ----- Method: BitBltSimulation>>bitAnd:with: (in category 'combination rules') -----
  bitAnd: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitAnd: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>bitAndInvert:with: (in category 'combination rules') -----
  bitAndInvert: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitAnd: destinationWord bitInvert32!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertAnd:with: (in category 'combination rules') -----
  bitInvertAnd: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitInvert32 bitAnd: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertAndInvert:with: (in category 'combination rules') -----
  bitInvertAndInvert: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitInvert32 bitAnd: destinationWord bitInvert32!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertDestination:with: (in category 'combination rules') -----
  bitInvertDestination: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^destinationWord bitInvert32!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertOr:with: (in category 'combination rules') -----
  bitInvertOr: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitInvert32 bitOr: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertOrInvert:with: (in category 'combination rules') -----
  bitInvertOrInvert: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitInvert32 bitOr: destinationWord bitInvert32!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertSource:with: (in category 'combination rules') -----
  bitInvertSource: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitInvert32!

Item was changed:
  ----- Method: BitBltSimulation>>bitInvertXor:with: (in category 'combination rules') -----
  bitInvertXor: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitInvert32 bitXor: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>bitOr:with: (in category 'combination rules') -----
  bitOr: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitOr: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>bitOrInvert:with: (in category 'combination rules') -----
  bitOrInvert: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitOr: destinationWord bitInvert32!

Item was changed:
  ----- Method: BitBltSimulation>>bitXor:with: (in category 'combination rules') -----
  bitXor: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord bitXor: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>clearWord:with: (in category 'combination rules') -----
+ clearWord: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
- clearWord: source with: destination
  	^ 0!

Item was changed:
  ----- Method: BitBltSimulation>>copyLoop (in category 'inner loop') -----
  copyLoop
  	| prevWord thisWord skewWord halftoneWord mergeWord hInc y unskew skewMask notSkewMask mergeFnwith destWord |
  	"This version of the inner loop assumes noSource = false."
  	<inline: false>
+ 	<var: #mergeFnwith declareC: 'unsigned int (*mergeFnwith)(unsigned int, unsigned int)'>
+ 	<var: #prevWord type: #'unsigned int'>
+ 	<var: #thisWord type: #'unsigned int'>
+ 	<var: #skewWord type: #'unsigned int'>
+ 	<var: #halftoneWord type: #'unsigned int'>
+ 	<var: #mergeWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	<var: #skewMask type: #'unsigned int'>
+ 	<var: #notSkewMask type: #'unsigned int'>
+ 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'unsigned int (*)(unsigned int, unsigned int)'.
- 	<var: #mergeFnwith declareC: 'sqInt (*mergeFnwith)(sqInt, sqInt)'>
- 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'sqInt (*)(sqInt, sqInt)'.
  	mergeFnwith.  "null ref for compiler"
  
  	hInc := hDir*4.  "Byte delta"
  	"degenerate skew fixed for Sparc. 10/20/96 ikp"
  	skew == -32
  		ifTrue: [skew := unskew := skewMask := 0]
  		ifFalse: [skew < 0
  			ifTrue:
  				[unskew := skew+32.
  				skewMask := AllOnes << (0-skew)]
  			ifFalse:
  				[skew = 0
  					ifTrue:
  						[unskew := 0.
  						skewMask := AllOnes]
  					ifFalse:
  						[unskew := skew-32.
  						skewMask := AllOnes >> skew]]].
  	notSkewMask := skewMask bitInvert32.
  	noHalftone
  		ifTrue: [halftoneWord := AllOnes.  halftoneHeight := 0]
  		ifFalse: [halftoneWord := self halftoneAt: 0].
  
  	y := dy.
  	1 to: bbH do: "here is the vertical loop"
  		[ :i |
  		halftoneHeight > 1 ifTrue:  "Otherwise, its always the same"
  			[halftoneWord := self halftoneAt: y.
  			y := y + vDir].
  		preload ifTrue:
  			["load the 64-bit shifter"
  			prevWord := self srcLongAt: sourceIndex.
  			self incSrcIndex: hInc]
  			ifFalse:
  			[prevWord := 0].
  
  	"Note: the horizontal loop has been expanded into three parts for speed:"
  
  			"This first section requires masking of the destination store..."
  			destMask := mask1.
  			thisWord := self srcLongAt: sourceIndex.  "pick up next word"
  			self incSrcIndex: hInc.
  			skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)
  							bitOr:  "32-bit rotate"
  						((thisWord bitAnd: skewMask) bitShift: skew).
  			prevWord := thisWord.
  			destWord := self dstLongAt: destIndex.
  			mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord) with: destWord.
  			destWord := (destMask bitAnd: mergeWord) bitOr:
  							(destWord bitAnd: destMask bitInvert32).
  			self dstLongAt: destIndex put: destWord.
  			self incDestIndex: hInc.
  
  		"This central horizontal loop requires no store masking"
  		destMask := AllOnes.
  combinationRule = 3
  ifTrue: [(skew = 0) & (halftoneWord = AllOnes)
  		ifTrue: 
  		["Very special inner loop for STORE mode with no skew -- just move words"
  		hDir = -1
  		ifTrue: ["Woeful patch: revert to older code for hDir = -1"
  				2 to: nWords-1 do: 
  					[ :word |
  					thisWord := self srcLongAt: sourceIndex.
  					self incSrcIndex: hInc.
  					self dstLongAt: destIndex put: thisWord.
  					self incDestIndex: hInc]]
  		ifFalse: [2 to: nWords-1 do: 
  					[ :word |  "Note loop starts with prevWord loaded (due to preload)"
  					self dstLongAt: destIndex put: prevWord.
  					self incDestIndex: hInc.
  					prevWord := self srcLongAt: sourceIndex.
  					self incSrcIndex: hInc]]]
  		ifFalse:
  		["Special inner loop for STORE mode -- no need to call merge"
  		2 to: nWords-1 do: 
  			[ :word |
  			thisWord := self srcLongAt: sourceIndex.
  			self incSrcIndex: hInc.
  			skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)
  							bitOr:  "32-bit rotate"
  						((thisWord bitAnd: skewMask) bitShift: skew).
  			prevWord := thisWord.
  			self dstLongAt: destIndex put: (skewWord bitAnd: halftoneWord).
  			self incDestIndex: hInc]]
  ] ifFalse: [2 to: nWords-1 do: "Normal inner loop does merge:"
  			[ :word |
  			thisWord := self srcLongAt: sourceIndex.  "pick up next word"
  			self incSrcIndex: hInc.
  			skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)
  							bitOr:  "32-bit rotate"
  						((thisWord bitAnd: skewMask) bitShift: skew).
  			prevWord := thisWord.
  			mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)
  							with: (self dstLongAt: destIndex).
  			self dstLongAt: destIndex put: mergeWord.
  			self incDestIndex: hInc]
  ].
  
  		"This last section, if used, requires masking of the destination store..."
  		nWords > 1 ifTrue:
  			[destMask := mask2.
  			thisWord := self srcLongAt: sourceIndex.  "pick up next word"
  			self incSrcIndex: hInc.
  			skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)
  							bitOr:  "32-bit rotate"
  						((thisWord bitAnd: skewMask) bitShift: skew).
  			destWord := self dstLongAt: destIndex.
  			mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord) with: destWord.
  			destWord := (destMask bitAnd: mergeWord) bitOr:
  							(destWord bitAnd: destMask bitInvert32).
  			self dstLongAt: destIndex put: destWord.
  			self incDestIndex: hInc].
  
  	self incSrcIndex: sourceDelta.
  	self incDestIndex: destDelta]!

Item was changed:
  ----- Method: BitBltSimulation>>copyLoopNoSource (in category 'inner loop') -----
  copyLoopNoSource
  	"Faster copyLoop when source not used.  hDir and vDir are both
  	positive, and perload and skew are unused"
  	| halftoneWord mergeWord mergeFnwith destWord |
  	<inline: false>
+ 	<var: #mergeFnwith declareC: 'unsigned int (*mergeFnwith)(unsigned int, unsigned int)'>
+ 	<var: #halftoneWord type: #'unsigned int'>
+ 	<var: #mergeWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'unsigned int (*)(unsigned int, unsigned int)'.
- 	<var: #mergeFnwith declareC: 'sqInt (*mergeFnwith)(sqInt, sqInt)'>
- 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'sqInt (*)(sqInt, sqInt)'.
  	mergeFnwith.  "null ref for compiler"
  
  	1 to: bbH do: "here is the vertical loop"
  		[ :i |
  		noHalftone
  			ifTrue: [halftoneWord := AllOnes]
  			ifFalse: [halftoneWord := self halftoneAt: dy+i-1].
  
  	"Note: the horizontal loop has been expanded into three parts for speed:"
  
  			"This first section requires masking of the destination store..."
  			destMask := mask1.
  			destWord := self dstLongAt: destIndex.
  			mergeWord := self mergeFn: halftoneWord
  							with: destWord.
  			destWord := (destMask bitAnd: mergeWord) bitOr: 
  							(destWord bitAnd: destMask bitInvert32).
  			self dstLongAt: destIndex put: destWord.
  			self incDestIndex: 4.
  
  		"This central horizontal loop requires no store masking"
  			destMask := AllOnes.
  			combinationRule = 3 ifTrue: ["Special inner loop for STORE"
  				destWord := halftoneWord.
  				2 to: nWords-1 do:[ :word |
  					self dstLongAt: destIndex put: destWord.
  					self incDestIndex: 4].
  			] ifFalse:[ "Normal inner loop does merge"
  				2 to: nWords-1 do:[ :word | "Normal inner loop does merge"
  					destWord := self dstLongAt: destIndex.
  					mergeWord := self mergeFn: halftoneWord with: destWord.
  					self dstLongAt: destIndex put: mergeWord.
  					self incDestIndex: 4].
  			].
  
  		"This last section, if used, requires masking of the destination store..."
  		nWords > 1 ifTrue:
  			[destMask := mask2.
  			destWord := self dstLongAt: destIndex.
  			mergeWord := self mergeFn: halftoneWord with: destWord.
  			destWord := (destMask bitAnd: mergeWord) bitOr:
  							(destWord bitAnd: destMask bitInvert32).
  			self dstLongAt: destIndex put: destWord.
  			self incDestIndex: 4].
  
  	self incDestIndex: destDelta]!

Item was changed:
  ----- Method: BitBltSimulation>>copyLoopPixMap (in category 'inner loop') -----
  copyLoopPixMap
  	"This version of the inner loop maps source pixels
  	to a destination form with different depth.  Because it is already
  	unweildy, the loop is not unrolled as in the other versions.
  	Preload, skew and skewMask are all overlooked, since pickSourcePixels
  	delivers its destination word already properly aligned.
  	Note that pickSourcePixels could be copied in-line at the top of
  	the horizontal loop, and some of its inits moved out of the loop."
  	"ar 12/7/1999:
  	The loop has been rewritten to use only one pickSourcePixels call.
  	The idea is that the call itself could be inlined. If we decide not
  	to inline pickSourcePixels we could optimize the loop instead."
  	| skewWord halftoneWord mergeWord scrStartBits nSourceIncs startBits endBits sourcePixMask destPixMask mergeFnwith nPix srcShift dstShift destWord words srcShiftInc dstShiftInc dstShiftLeft mapperFlags |
  	<inline: false>
+ 	<var: #mergeFnwith declareC: 'unsigned int (*mergeFnwith)(unsigned int, unsigned int)'>
+ 	<var: #skewWord type: #'unsigned int'>
+ 	<var: #halftoneWord type: #'unsigned int'>
+ 	<var: #mergeWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	<var: #sourcePixMask type: #'unsigned int'>
+ 	<var: #destPixMask type: #'unsigned int'>
+ 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'unsigned int (*)(unsigned int, unsigned int)'.
- 	<var: #mergeFnwith declareC: 'sqInt (*mergeFnwith)(sqInt, sqInt)'>
- 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'sqInt (*)(sqInt, sqInt)'.
  	mergeFnwith.  "null ref for compiler"
  
  	"Additional inits peculiar to unequal source and dest pix size..."
  	sourcePPW := 32//sourceDepth.
  	sourcePixMask := maskTable at: sourceDepth.
  	destPixMask := maskTable at: destDepth.
  	mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.
  	sourceIndex := sourceBits +
  					(sy * sourcePitch) + ((sx // sourcePPW) *4).
  	scrStartBits := sourcePPW - (sx bitAnd: sourcePPW-1).
  	bbW < scrStartBits
  		ifTrue: [nSourceIncs := 0]
  		ifFalse: [nSourceIncs := (bbW - scrStartBits)//sourcePPW + 1].
  	sourceDelta := sourcePitch - (nSourceIncs * 4).
  
  	"Note following two items were already calculated in destmask setup!!"
  	startBits := destPPW - (dx bitAnd: destPPW-1).
  	endBits := ((dx + bbW - 1) bitAnd: destPPW-1) + 1.
  
  	bbW < startBits ifTrue:[startBits := bbW].
  
  	"Precomputed shifts for pickSourcePixels"
  	srcShift := ((sx bitAnd: sourcePPW - 1) * sourceDepth).
  	dstShift := ((dx bitAnd: destPPW - 1) * destDepth).
  	srcShiftInc := sourceDepth.
  	dstShiftInc := destDepth.
  	dstShiftLeft := 0.
  	sourceMSB ifTrue:[
  		srcShift := 32 - sourceDepth - srcShift.
  		srcShiftInc := 0 - srcShiftInc].
  	destMSB ifTrue:[
  		dstShift := 32 - destDepth - dstShift.
  		dstShiftInc := 0 - dstShiftInc.
  		dstShiftLeft := 32 - destDepth].
  
  	1 to: bbH do: "here is the vertical loop"
  		[ :i |
  		"*** is it possible at all that noHalftone == false? ***"
  		noHalftone
  			ifTrue:[halftoneWord := AllOnes]
  			ifFalse: [halftoneWord := self halftoneAt: dy+i-1].
  		"setup first load"
  		srcBitShift := srcShift.
  		dstBitShift := dstShift.
  		destMask := mask1.
  		nPix := startBits.
  		"Here is the horizontal loop..."
  		words := nWords.
  			["pick up the word"
  			skewWord := self pickSourcePixels: nPix flags: mapperFlags 
  								srcMask: sourcePixMask destMask: destPixMask
  								srcShiftInc: srcShiftInc dstShiftInc: dstShiftInc.
  			"align next word to leftmost pixel"
  			dstBitShift := dstShiftLeft.
  
  			destMask = AllOnes ifTrue:["avoid read-modify-write"
  				mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)
  								with: (self dstLongAt: destIndex).
  				self dstLongAt: destIndex put: (destMask bitAnd: mergeWord).
  			] ifFalse:[ "General version using dest masking"
  				destWord := self dstLongAt: destIndex.
  				mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)
  								with: (destWord bitAnd: destMask).
  				destWord := (destMask bitAnd: mergeWord) bitOr:
  								(destWord bitAnd: destMask bitInvert32).
  				self dstLongAt: destIndex put: destWord.
  			].
  			self incDestIndex: 4.
  			words = 2 "e.g., is the next word the last word?"
  				ifTrue:["set mask for last word in this row"
  						destMask := mask2.
  						nPix := endBits]
  				ifFalse:["use fullword mask for inner loop"
  						destMask := AllOnes.
  						nPix := destPPW].
  			(words := words - 1) = 0] whileFalse.
  		"--- end of inner loop ---"
  		self incSrcIndex: sourceDelta.
  		self incDestIndex: destDelta]
  !

Item was changed:
  ----- Method: BitBltSimulation>>destinationWord:with: (in category 'combination rules') -----
  destinationWord: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>dither32To16:threshold: (in category 'pixel mapping') -----
  dither32To16: srcWord threshold: ditherValue
  	"Dither the given 32bit word to 16 bit. Ignore alpha."
  	| addThreshold  |
  	<inline: true> "You bet"
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #srcWord type: 'unsigned int'>
  	addThreshold := ditherValue bitShift: 8.
  	^((dither8Lookup at: (addThreshold+((srcWord bitShift: -16) bitAnd: 255))) bitShift: 10) + 
  		((dither8Lookup at: (addThreshold+((srcWord bitShift: -8) bitAnd: 255))) bitShift: 5) + 
  		(dither8Lookup at: (addThreshold+(srcWord bitAnd: 255))).
  !

Item was changed:
  ----- Method: BitBltSimulation>>expensiveDither32To16:threshold: (in category 'pixel mapping') -----
  expensiveDither32To16: srcWord threshold: ditherValue
  	"Dither the given 32bit word to 16 bit. Ignore alpha."
  	| pv threshold value out |
  	<inline: true> "You bet"
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #srcWord type: 'unsigned int'>
  	pv := srcWord bitAnd: 255.
  	threshold := ditherThresholds16 at: (pv bitAnd: 7).
  	value := ditherValues16 at: (pv bitShift: -3).
  	ditherValue < threshold
  		ifTrue:[out := value + 1]
  		ifFalse:[out := value].
  	pv := (srcWord bitShift: -8) bitAnd: 255.
  	threshold := ditherThresholds16 at: (pv bitAnd: 7).
  	value := ditherValues16 at: (pv bitShift: -3).
  	ditherValue < threshold
  		ifTrue:[out := out bitOr: (value+1 bitShift:5)]
  		ifFalse:[out := out bitOr: (value bitShift: 5)].
  	pv := (srcWord bitShift: -16) bitAnd: 255.
  	threshold := ditherThresholds16 at: (pv bitAnd: 7).
  	value := ditherValues16 at: (pv bitShift: -3).
  	ditherValue < threshold
  		ifTrue:[out := out bitOr: (value+1 bitShift:10)]
  		ifFalse:[out := out bitOr: (value bitShift: 10)].
  	^out!

Item was changed:
  ----- Method: BitBltSimulation>>fixAlpha:with: (in category 'combination rules') -----
  fixAlpha: sourceWord with: destinationWord
  	"For any non-zero pixel value in destinationWord with zero alpha channel take the alpha from sourceWord and fill it in. Intended for fixing alpha channels left at zero during 16->32 bpp conversions."
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	destDepth = 32 ifFalse:[^destinationWord]. "no-op for non 32bpp"
  	destinationWord = 0 ifTrue:[^0].
  	(destinationWord bitAnd: 16rFF000000) = 0 ifFalse:[^destinationWord].
  	^destinationWord bitOr: (sourceWord bitAnd: 16rFF000000)
  !

Item was changed:
  ----- Method: BitBltSimulation>>merge:with: (in category 'combination rules') -----
  merge: sourceWord with: destinationWord
  	| mergeFnwith |
  	"Sender warpLoop is too big to include this in-line"
+ 	<var: #mergeFnwith declareC: 'unsigned int (*mergeFnwith)(unsigned int, unsigned int)'>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
+ 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'unsigned int (*)(unsigned int, unsigned int)'.
- 	<var: #mergeFnwith declareC: 'sqInt (*mergeFnwith)(sqInt, sqInt)'>
- 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'sqInt (*)(sqInt, sqInt)'.
  	mergeFnwith.  "null ref for compiler"
  
  	^ self mergeFn: sourceWord with: destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>partitionedAND:to:nBits:nPartitions: (in category 'combination rules') -----
  partitionedAND: word1 to: word2 nBits: nBits nPartitions: nParts
  	"AND word1 to word2 as nParts partitions of nBits each.
  	Any field of word1 not all-ones is treated as all-zeroes.
  	Used for erasing, eg, brush shapes prior to ORing in a color"
  	| mask result |
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #word1 type: 'unsigned int'>
+ 	<var: #word2 type: 'unsigned int'>
+ 	<var: #result type: 'unsigned int'>
  	mask := maskTable at: nBits.  "partition mask starts at the right"
  	result := 0.
  	1 to: nParts do:
  		[:i |
  		(word1 bitAnd: mask) = mask
  			ifTrue: [result := result bitOr: (word2 bitAnd: mask)].
  		mask := mask << nBits  "slide left to next partition"].
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>partitionedAdd:to:nBits:componentMask:carryOverflowMask: (in category 'combination rules') -----
  partitionedAdd: word1 to: word2 nBits: nBits componentMask: componentMask carryOverflowMask: carryOverflowMask
  	"Add word1 to word2 as nParts partitions of nBits each.
  	This is useful for packed pixels, or packed colors"
  	| carryOverflow sum w1 w2 |
  	"Use unsigned int everywhere because it has a well known arithmetic model without undefined behavior w.r.t. overflow and shifts"
+ 	<returnTypeC: 'unsigned int'>
  	 <var: #word1 type: 'unsigned int'>
  	<var: #word2 type: 'unsigned int'>
  	 <var: #w1 type: 'unsigned int'>
  	<var: #w2 type: 'unsigned int'>
  	<var: #componentMask type: 'unsigned int'>
  	<var: #carryOverflowMask type: 'unsigned int'>
  	<var: #carryOverflow type: 'unsigned int'>
  	<var: #sum type: 'unsigned int'>
  	w1 := word1 bitAnd: carryOverflowMask. "mask to remove high bit of each component"
  	w2 := word2 bitAnd: carryOverflowMask.
  	sum := (word1 bitXor: w1)+(word2 bitXor: w2). "sum without high bit to avoid overflowing over next component"
  	carryOverflow := (w1 bitAnd: w2) bitOr: ((w1 bitOr: w2) bitAnd: sum). "detect overflow condition for saturating"
  	^((sum bitXor: w1)bitXor:w2) "sum high bit without overflow"
  		bitOr: carryOverflow>>(nBits-1) * componentMask "saturate in case of overflow"!

Item was changed:
  ----- Method: BitBltSimulation>>partitionedMax:with:nBits:nPartitions: (in category 'combination rules') -----
  partitionedMax: word1 with: word2 nBits: nBits nPartitions: nParts
  	"Max word1 to word2 as nParts partitions of nBits each"
  	| mask result |
  	"In C, most arithmetic operations answer the same bit pattern regardless of the operands being signed or unsigned ints
  	(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
  	words as unsigned int in those cases where comparisions are done (jmv)"
+ 	<returnTypeC: 'unsigned int'>
  	<var: #word1 type: 'unsigned int'>
  	<var: #word2 type: 'unsigned int'>
  	<var: #mask type: 'unsigned int'>
  	<var: #result type: 'unsigned int'>
  	mask := maskTable at: nBits.  "partition mask starts at the right"
  	result := 0.
  	1 to: nParts do:
  		[:i |
  		result := result bitOr: ((word2 bitAnd: mask) max: (word1 bitAnd: mask)).
  		mask := mask << nBits  "slide left to next partition"].
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>partitionedMin:with:nBits:nPartitions: (in category 'combination rules') -----
  partitionedMin: word1 with: word2 nBits: nBits nPartitions: nParts
  	"Min word1 to word2 as nParts partitions of nBits each"
  	| mask result |
  	"In C, most arithmetic operations answer the same bit pattern regardless of the operands being signed or unsigned ints
  	(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
  	words as unsigned int in those cases where comparisions are done (jmv)"
+ 	<returnTypeC: 'unsigned int'>
  	<var: #word1 type: 'unsigned int'>
  	<var: #word2 type: 'unsigned int'>
  	<var: #mask type: 'unsigned int'>
  	<var: #result type: 'unsigned int'>
  	mask := maskTable at: nBits.  "partition mask starts at the right"
  	result := 0.
  	1 to: nParts do:
  		[:i |
  		result := result bitOr: ((word2 bitAnd: mask) min: (word1 bitAnd: mask)).
  		mask := mask << nBits  "slide left to next partition"].
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>partitionedMul:with:nBits:nPartitions: (in category 'combination rules') -----
  partitionedMul: word1 with: word2 nBits: nBits nPartitions: nParts
  	"Multiply word1 with word2 as nParts partitions of nBits each.
  	This is useful for packed pixels, or packed colors.
  	Bug in loop version when non-white background"
  
  	| sMask product result dMask |
  	"In C, integer multiplication might answer a wrong value if the unsigned values are declared as signed.
  	This problem does not affect this method, because the most significant bit (i.e. the sign bit) will
  	always be zero (jmv)"
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #word1 type: 'unsigned int'>
+ 	<var: #word2 type: 'unsigned int'>
+ 	<var: #sMask type: 'unsigned int'>
+ 	<var: #dMask type: 'unsigned int'>
+ 	<var: #result type: 'unsigned int'>
+ 	<var: #product type: 'unsigned int'>
  	sMask := maskTable at: nBits.  "partition mask starts at the right"
  	dMask :=  sMask << nBits.
  	result := (((word1 bitAnd: sMask)+1) * ((word2 bitAnd: sMask)+1) - 1 
  				bitAnd: dMask) >> nBits.	"optimized first step"
  	nParts = 1
  		ifTrue: [ ^result ].
  	product := (((word1>>nBits bitAnd: sMask)+1) * ((word2>>nBits bitAnd: sMask)+1) - 1 bitAnd: dMask).
  	result := result bitOr: product.
  	nParts = 2
  		ifTrue: [ ^result ].
  	product := (((word1>>(2*nBits) bitAnd: sMask)+1) * ((word2>>(2*nBits) bitAnd: sMask)+1) - 1 bitAnd: dMask).
  	result := result bitOr: product << nBits.
  	nParts = 3
  		ifTrue: [ ^result ].
  	product := (((word1>>(3*nBits) bitAnd: sMask)+1) * ((word2>>(3*nBits) bitAnd: sMask)+1) - 1 bitAnd: dMask).
  	result := result bitOr: product << (2*nBits).
  	^ result
  
  "	| sMask product result dMask |
  	sMask := maskTable at: nBits.  'partition mask starts at the right'
  	dMask :=  sMask << nBits.
  	result := (((word1 bitAnd: sMask)+1) * ((word2 bitAnd: sMask)+1) - 1 
  				bitAnd: dMask) >> nBits.	'optimized first step'
  	nBits to: nBits * (nParts-1) by: nBits do: [:ofs |
  		product := (((word1>>ofs bitAnd: sMask)+1) * ((word2>>ofs bitAnd: sMask)+1) - 1 bitAnd: dMask).
  		result := result bitOr: (product bitAnd: dMask) << (ofs-nBits)].
  	^ result"!

Item was changed:
  ----- Method: BitBltSimulation>>partitionedRgbComponentAlpha:dest:nBits:nPartitions: (in category 'combination rules') -----
  partitionedRgbComponentAlpha: sourceWord dest: destWord nBits: nBits nPartitions: nParts
  	| mask result p1 p2 v |
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destWord type: 'unsigned int'>
+ 	<var: #p1 type: 'unsigned int'>
+ 	<var: #p2 type: 'unsigned int'>
+ 	<var: #mask type: 'unsigned int'>
+ 	<var: #result type: 'unsigned int'>
  	mask := maskTable at: nBits.  "partition mask starts at the right"
  	result := 0.
  	1 to: nParts do:
  		[:i |
  		p1 := (sourceWord bitAnd: mask) >> ((i - 1)*nBits).
  		p2 := (destWord bitAnd: mask) >> ((i - 1)*nBits).
  		nBits = 32
  			ifFalse:[
  				nBits = 16
  					ifTrue:[
  						p1 := (self rgbMap16To32: p1) bitOr: 16rFF000000.
  						p2 := (self rgbMap16To32: p2) bitOr: 16rFF000000]
  					ifFalse:[
  						p1 := (self rgbMap: p1 from: nBits to: 32) bitOr: 16rFF000000.
  						p2 := (self rgbMap: p2 from: nBits to: 32) bitOr: 16rFF000000.]].
  		v := self rgbComponentAlpha32: p1 with: p2.
  		nBits = 32
  			ifFalse:[
  				v := self rgbMap: v from: 32 to: nBits].
  		result := result bitOr: (v <<  ((i - 1)*nBits)). 
  		mask := mask << nBits  "slide left to next partition"].
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>partitionedSub:from:nBits:nPartitions: (in category 'combination rules') -----
  partitionedSub: word1 from: word2 nBits: nBits nPartitions: nParts
  	"Subtract word1 from word2 as nParts partitions of nBits each.
  	This is useful for packed pixels, or packed colors"
  	| mask result p1 p2 |
  	"In C, most arithmetic operations answer the same bit pattern regardless of the operands being signed or unsigned ints
  	(this is due to the way 2's complement numbers work). However, comparisions might fail. Add the proper declaration of
  	words as unsigned int in those cases where comparisions are done (jmv)"
+ 	<returnTypeC: 'unsigned int'>
  	<var: #word1 type: 'unsigned int'>
  	<var: #word2 type: 'unsigned int'>
  	<var: #p1 type: 'unsigned int'>
  	<var: #p2 type: 'unsigned int'>
  	<var: #mask type: 'unsigned int'>
  	<var: #result type: 'unsigned int'>
  	mask := maskTable at: nBits.  "partition mask starts at the right"
  	result := 0.
  	1 to: nParts do:
  		[:i |
  		p1 := word1 bitAnd: mask.
  		p2 := word2 bitAnd: mask.
  		p1 < p2  "result is really abs value of thedifference"
  			ifTrue: [result := result bitOr: p2 - p1]
  			ifFalse: [result := result bitOr: p1 - p2].
  		mask := mask << nBits  "slide left to next partition"].
  	^ result
  !

Item was changed:
  ----- Method: BitBltSimulation>>pickSourcePixels:flags:srcMask:destMask:srcShiftInc:dstShiftInc: (in category 'combination rules') -----
  pickSourcePixels: nPixels flags: mapperFlags srcMask: srcMask destMask: dstMask srcShiftInc: srcShiftInc dstShiftInc: dstShiftInc
  	"Pick nPix pixels starting at srcBitIndex from the source, map by the
  	color map, and justify them according to dstBitIndex in the resulting destWord."
  	| sourceWord destWord sourcePix destPix srcShift dstShift nPix |
  	<inline: true> "oh please"
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
  	sourceWord := self srcLongAt: sourceIndex.
  	destWord := 0.
  	srcShift := srcBitShift. "Hint: Keep in register"
  	dstShift := dstBitShift. "Hint: Keep in register"
  	nPix := nPixels. "always > 0 so we can use do { } while(--nPix);"
  	(mapperFlags = (ColorMapPresent bitOr: ColorMapIndexedPart)) ifTrue:[
  		"a little optimization for (pretty crucial) blits using indexed lookups only"
  		[	"grab, colormap and mix in pixel"
  			sourcePix := sourceWord >> srcShift bitAnd: srcMask.
  			destPix := cmLookupTable at: (sourcePix bitAnd: cmMask).
  			destWord := destWord bitOr: (destPix bitAnd: dstMask) << dstShift.
  			"adjust dest pix index"
  			dstShift := dstShift + dstShiftInc.
  			"adjust source pix index"
  			((srcShift := srcShift + srcShiftInc) bitAnd: 16rFFFFFFE0) = 0 ifFalse:[
  				sourceMSB ifTrue:[srcShift := srcShift + 32] ifFalse:[srcShift := srcShift - 32].
  				sourceWord := self srcLongAt: (self incSrcIndex: 4)].
  		(nPix := nPix - 1) = 0] whileFalse.
  	] ifFalse:[
  		[	"grab, colormap and mix in pixel"
  			sourcePix := sourceWord >> srcShift bitAnd: srcMask.
  			destPix := self mapPixel: sourcePix flags: mapperFlags.
  			destWord := destWord bitOr: (destPix bitAnd: dstMask) << dstShift.
  			"adjust dest pix index"
  			dstShift := dstShift + dstShiftInc.
  			"adjust source pix index"
  			((srcShift := srcShift + srcShiftInc) bitAnd: 16rFFFFFFE0) = 0 ifFalse:[
  				sourceMSB ifTrue:[srcShift := srcShift + 32] ifFalse:[srcShift := srcShift - 32].
  				sourceWord := self srcLongAt: (self incSrcIndex: 4)].
  		(nPix := nPix - 1) = 0] whileFalse.
  	].
  	srcBitShift := srcShift. "Store back"
  	^destWord
  !

Item was changed:
  ----- Method: BitBltSimulation>>pickWarpPixelAtX:y: (in category 'pixel mapping') -----
  pickWarpPixelAtX: xx y: yy
  	"Pick a single pixel from the source for WarpBlt.
  	Note: This method is crucial for WarpBlt speed w/o smoothing
  	and still relatively important when smoothing is used."
  	| x y srcIndex sourceWord sourcePix |
  	<inline: true> "*please*"
+ 	<returnTypeC: #'unsigned int'>
+ 	<var: #sourceWord type: #'unsigned int'>
  
  	"note: it would be much faster if we could just
  	avoid these stupid tests for being inside sourceForm."
  	(xx < 0 or:[yy < 0 or:[
  		(x := xx >> BinaryPoint) >= sourceWidth or:[
  			(y := yy >> BinaryPoint) >= sourceHeight]]]) ifTrue:[^0]. "out of bounds"
  
  	"Fetch source word.
  	Note: We should really update srcIndex with sx and sy so that
  	we don't have to do the computation below. We might even be
  	able to simplify the out of bounds test from above."
  	srcIndex := sourceBits + (y * sourcePitch) + (x >> warpAlignShift * 4).
  	sourceWord := self srcLongAt: srcIndex.
  
  	"Extract pixel from word"
  	srcBitShift := warpBitShiftTable at: (x bitAnd: warpAlignMask).
  	sourcePix := sourceWord >> srcBitShift bitAnd: warpSrcMask.
  	^sourcePix!

Item was changed:
  ----- Method: BitBltSimulation>>pixClear:with: (in category 'combination rules') -----
  pixClear: sourceWord with: destinationWord
  	"Clear all pixels in destinationWord for which the pixels of sourceWord have the same values. Used to clear areas of some constant color to zero."
  	| mask result nBits pv |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
+ 	<var: #mask type: 'unsigned int'>
+ 	<var: #pv type: 'unsigned int'>
+ 	<var: #result type: 'unsigned int'>
  	destDepth = 32 ifTrue:[
  		sourceWord = destinationWord ifTrue:[^0] ifFalse:[^destinationWord].
  	].
  	nBits := destDepth.
  	mask := maskTable at: nBits.  "partition mask starts at the right"
  	result := 0.
  	1 to: destPPW do:[:i |
  		pv := destinationWord bitAnd: mask.
  		(sourceWord bitAnd: mask) = pv ifTrue:[pv := 0].
  		result := result bitOr: pv.
  		mask := mask << nBits "slide left to next partition"].
  	^ result!

Item was changed:
  ----- Method: BitBltSimulation>>pixMask:with: (in category 'combination rules') -----
  pixMask: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^ self partitionedAND: sourceWord bitInvert32 to: destinationWord
  					nBits: destDepth nPartitions: destPPW!

Item was changed:
  ----- Method: BitBltSimulation>>pixPaint:with: (in category 'combination rules') -----
  pixPaint: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	sourceWord = 0 ifTrue: [^ destinationWord].
  	^ sourceWord bitOr:
  		(self partitionedAND: sourceWord bitInvert32 to: destinationWord
  						nBits: destDepth nPartitions: destPPW)!

Item was changed:
  ----- Method: BitBltSimulation>>pixSwap:with: (in category 'combination rules') -----
  pixSwap: sourceWord with: destWord
  	"Swap the pixels in destWord"
  	| result shift lowMask highMask |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destWord type: 'unsigned int'>
+ 	<var: #lowMask type: 'unsigned int'>
+ 	<var: #highMask type: 'unsigned int'>
+ 	<var: #result type: 'unsigned int'>
  	destPPW = 1 ifTrue:[^destWord]. "a single pixel per word"
  	result := 0.
  	lowMask := (1 << destDepth) - 1. "mask low pixel"
  	highMask := lowMask << (destPPW-1 * destDepth). "mask high pixel"
  	shift := 32 - destDepth.
  	result := result bitOr: (
  				(destWord bitAnd: lowMask) << shift bitOr:
  					(destWord bitAnd: highMask) >> shift).
  	destPPW <= 2 ifTrue:[^result].
  	2 to: destPPW // 2 do:[:i|
  		lowMask := lowMask << destDepth.
  		highMask := highMask >> destDepth.
  		shift := shift - (destDepth * 2).
  		result := result bitOr: (
  					(destWord bitAnd: lowMask) << shift bitOr:
  						(destWord bitAnd: highMask) >> shift)].
  	^result!

Item was changed:
  ----- Method: BitBltSimulation>>rgbAdd:with: (in category 'combination rules') -----
  rgbAdd: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
  	<var: #sourceWord type: 'unsigned int'>
  	<var: #destinationWord type: 'unsigned int'>
  	<var: #carryOverflowMask type: 'unsigned int'>
  	<var: #componentMask type: 'unsigned int'>
  	| componentMask carryOverflowMask |
  	destDepth < 16 ifTrue:
  		["Add each pixel separately"
  		componentMask := 1<<destDepth-1.
  		carryOverflowMask := 16rFFFFFFFF//componentMask<<(destDepth-1).
  		^ self partitionedAdd: sourceWord to: destinationWord
  						nBits: destDepth componentMask: componentMask carryOverflowMask: carryOverflowMask].
  	destDepth = 16 ifTrue:
  		["Add RGB components of each pixel separately"
  		componentMask := 16r1F.
  		carryOverflowMask := 16r42104210.
  		^ (self partitionedAdd: (sourceWord bitAnd: 16r7FFF7FFF) to: (destinationWord bitAnd: 16r7FFF7FFF) "make sure that the unused bit is at 0"
  						nBits: 5 componentMask: componentMask carryOverflowMask: carryOverflowMask)]
  	ifFalse:
  		["Add RGBA components of the pixel separately"
  		componentMask := 16rFF.
  		carryOverflowMask := 16r80808080.
  		^ self partitionedAdd: sourceWord to: destinationWord
  						nBits: 8 componentMask: componentMask carryOverflowMask: carryOverflowMask]!

Item was changed:
  ----- Method: BitBltSimulation>>rgbComponentAlpha16 (in category 'combination rules') -----
  rgbComponentAlpha16
  	"This version assumes 
  		combinationRule = 41
  		sourcePixSize = 32
  		destPixSize = 16
  		sourceForm ~= destForm.
  	"
  	<inline: false>  "This particular method should be optimized in itself"
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	<var: #dstMask type: #'unsigned int'>
  	
  	| srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY 
  	srcY dstY dstMask srcShift ditherBase ditherIndex ditherThreshold |
  
  	deltaY := bbH + 1. "So we can pre-decrement"
  	srcY := sy.
  	dstY := dy.
  	srcShift := (dx bitAnd: 1) * 16.
  	destMSB ifTrue:[srcShift := 16 - srcShift].
  	mask1 := 16rFFFF << (16 - srcShift).
  	"This is the outer loop"
  	[(deltaY := deltaY - 1) ~= 0] whileTrue:[
  		srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).
  		dstIndex := destBits + (dstY * destPitch) + (dx // 2 * 4).
  		ditherBase := (dstY bitAnd: 3) * 4.
  		ditherIndex := (sx bitAnd: 3) - 1. "For pre-increment"
  		deltaX := bbW + 1. "So we can pre-decrement"
  		dstMask := mask1.
  		dstMask = 16rFFFF ifTrue:[srcShift := 16] ifFalse:[srcShift := 0].
  
  		"This is the inner loop"
  		[(deltaX := deltaX - 1) ~= 0] whileTrue:[
  			ditherThreshold := ditherMatrix4x4 at: ditherBase + (ditherIndex := ditherIndex + 1 bitAnd: 3).
  			sourceWord := self srcLongAt: srcIndex.
  			srcAlpha := sourceWord bitAnd: 16rFFFFFF.
  				srcAlpha = 0 ifFalse:[ "0 < srcAlpha"
  					"If we have to mix colors then just copy a single word"
  					destWord := self dstLongAt: dstIndex.
  					destWord := destWord bitAnd: dstMask bitInvert32.
  					destWord := destWord >> srcShift.
  					"Expand from 16 to 32 bit by adding zero bits"
  					destWord := (((destWord bitAnd: 16r7C00) bitShift: 9) bitOr:
  									((destWord bitAnd: 16r3E0) bitShift: 6)) bitOr:
  								(((destWord bitAnd: 16r1F) bitShift: 3) bitOr:
  									16rFF000000).
  					"Mix colors"
  					sourceWord := self rgbComponentAlpha32: sourceWord with: destWord.
  					"And dither"
  					sourceWord := self dither32To16: sourceWord threshold: ditherThreshold.
  					sourceWord = 0 
  						ifTrue:[sourceWord := 1 << srcShift]
  						ifFalse:[sourceWord := sourceWord << srcShift].
  					"Store back"
  					self dstLongAt: dstIndex put: sourceWord mask: dstMask.
  				].
  			srcIndex := srcIndex + 4.
  			destMSB
  				ifTrue:[srcShift = 0 ifTrue:[dstIndex := dstIndex + 4]]
  				ifFalse:[srcShift = 0 ifFalse:[dstIndex := dstIndex + 4]].
  			srcShift := srcShift bitXor: 16. "Toggle between 0 and 16"
  			dstMask := dstMask bitInvert32. "Mask other half word"
  		].
  		srcY := srcY + 1.
  		dstY := dstY + 1.
  	].
  !

Item was changed:
  ----- Method: BitBltSimulation>>rgbComponentAlpha32 (in category 'combination rules') -----
  rgbComponentAlpha32
  	"This version assumes 
  		combinationRule = 41
  		sourcePixSize = destPixSize = 32
  		sourceForm ~= destForm.
  	Note: The inner loop has been optimized for dealing
  		with the special case of aR = aG = aB = 0 
  	"
  	| srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY srcY dstY |
  
  	<inline: false> "This particular method should be optimized in itself"
  
  	"Give the compile a couple of hints"
- 	<var: #sourceWord type: 'register long'>
  	<var: #deltaX type: 'register long'>
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
  
  	"The following should be declared as pointers so the compiler will
  	notice that they're used for accessing memory locations 
  	(good to know on an Intel architecture) but then the increments
  	would be different between ST code and C code so must hope the
  	compiler notices what happens (MS Visual C does)"
  	<var: #srcIndex type: 'register long'>
  	<var: #dstIndex type: 'register long'>
  	
  	deltaY := bbH + 1. "So we can pre-decrement"
  	srcY := sy.
  	dstY := dy.
  
  	"This is the outer loop"
  	[(deltaY := deltaY - 1) ~= 0] whileTrue:[
  		srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).
  		dstIndex := destBits + (dstY * destPitch) + (dx * 4).
  		deltaX := bbW + 1. "So we can pre-decrement"
  
  		"This is the inner loop"
  		[(deltaX := deltaX - 1) ~= 0] whileTrue:[
  			sourceWord := self srcLongAt: srcIndex.
  			srcAlpha := sourceWord bitAnd:16rFFFFFF.
  				srcAlpha = 0 ifTrue:[
  					srcIndex := srcIndex + 4.
  					dstIndex := dstIndex + 4.
  					"Now skip as many words as possible,"
  					[(deltaX := deltaX - 1) ~= 0 and:[
  						((sourceWord := self srcLongAt: srcIndex) bitAnd:16rFFFFFF) = 0]]
  						whileTrue:[
  							srcIndex := srcIndex + 4.
  							dstIndex := dstIndex + 4.
  						].
  					"Adjust deltaX"
  					deltaX := deltaX + 1.
  				] ifFalse:[ "0 < srcAlpha"
  					"If we have to mix colors then just copy a single word"
  					destWord := self dstLongAt: dstIndex.
  					destWord := self rgbComponentAlpha32: sourceWord with: destWord.
  					self dstLongAt: dstIndex put: destWord.
  					srcIndex := srcIndex + 4.
  					dstIndex := dstIndex + 4.
  				].
  		].
  		srcY := srcY + 1.
  		dstY := dstY + 1.
  	].!

Item was changed:
  ----- Method: BitBltSimulation>>rgbComponentAlpha8 (in category 'combination rules') -----
  rgbComponentAlpha8
  	"This version assumes 
  		combinationRule = 41
  		sourcePixSize = 32
  		destPixSize = 8
  		sourceForm ~= destForm.
  	Note: This is not real blending since we don't have the source colors available.
  	"
  	
  	| srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY 
  	srcY dstY dstMask srcShift adjust mappingTable mapperFlags |
  	
  	<inline: false>  "This particular method should be optimized in itself"
  	<var: #mappingTable declareC:'unsigned int *mappingTable'>
+ 	<var: #sourceWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	<var: #dstMask type: #'unsigned int'>
  	
  	mappingTable := self default8To32Table.
  	mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.
  	deltaY := bbH + 1. "So we can pre-decrement"
  	srcY := sy.
  	dstY := dy.
  	mask1 := ((dx bitAnd: 3) * 8).
  	destMSB ifTrue:[mask1 := 24 - mask1].
  	mask2 := AllOnes bitXor:(16rFF << mask1).
  	(dx bitAnd: 1) = 0 
  		ifTrue:[adjust := 0]
  		ifFalse:[adjust := 16r1F1F1F1F].
  	(dy bitAnd: 1) = 0
  		ifTrue:[adjust := adjust bitXor: 16r1F1F1F1F].
  	"This is the outer loop"
  	[(deltaY := deltaY - 1) ~= 0] whileTrue:[
  		adjust := adjust bitXor: 16r1F1F1F1F.
  		srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).
  		dstIndex := destBits + (dstY * destPitch) + (dx // 4 * 4).
  		deltaX := bbW + 1. "So we can pre-decrement"
  		srcShift := mask1.
  		dstMask := mask2.
  
  		"This is the inner loop"
  		[(deltaX := deltaX - 1) ~= 0] whileTrue:[
  			sourceWord := ((self srcLongAt: srcIndex) bitAnd: (adjust bitInvert32)) + adjust.
  			srcAlpha := sourceWord bitAnd: 16rFFFFFF.
  			"set srcAlpha to the average of the 3 separate aR,Ag,AB values"
  			srcAlpha := ((srcAlpha >> 16) + (srcAlpha >> 8 bitAnd: 16rFF) + (srcAlpha bitAnd: 16rFF)) // 3.
  			srcAlpha > 31 ifTrue:["Everything below 31 is transparent"
  				srcAlpha > 224 
  					ifTrue: ["treat everything above 224 as opaque"
  						sourceWord := 16rFFFFFFFF].
  				destWord := self dstLongAt: dstIndex.
  				destWord := destWord bitAnd: dstMask bitInvert32.
  				destWord := destWord >> srcShift.
  				destWord := mappingTable at: destWord.
  				sourceWord := self rgbComponentAlpha32: sourceWord with: destWord.
  				sourceWord := self mapPixel: sourceWord flags: mapperFlags.
  				sourceWord := sourceWord << srcShift.
  				"Store back"
  				self dstLongAt: dstIndex put: sourceWord mask: dstMask.
  			].
  			srcIndex := srcIndex + 4.
  			destMSB ifTrue:[
  				srcShift = 0 
  					ifTrue:[dstIndex := dstIndex + 4.
  							srcShift := 24.
  							dstMask := 16r00FFFFFF]
  					ifFalse:[srcShift := srcShift - 8.
  							dstMask := (dstMask >> 8) bitOr: 16rFF000000].
  			] ifFalse:[
  				srcShift = 32
  					ifTrue:[dstIndex := dstIndex + 4.
  							srcShift := 0.
  							dstMask := 16rFFFFFF00]
  					ifFalse:[srcShift := srcShift + 8.
  							dstMask := dstMask << 8 bitOr: 255].
  			].
  			adjust := adjust bitXor: 16r1F1F1F1F.
  		].
  		srcY := srcY + 1.
  		dstY := dstY + 1.
  	].
  !

Item was changed:
  ----- Method: BitBltSimulation>>rgbDiff:with: (in category 'combination rules') -----
  rgbDiff: sourceWord with: destinationWord
  	"Subract the pixels in the source and destination, color by color,
  	and return the sum of the absolute value of all the differences.
  	For non-rgb, return the number of differing pixels."
  	| pixMask destShifted sourceShifted destPixVal bitsPerColor rgbMask sourcePixVal diff maskShifted |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
+ 	<var: #sourceShifted type: 'unsigned int'>
+ 	<var: #destShifted type: 'unsigned int'>
+ 	<var: #maskShifted type: 'unsigned int'>
+ 	<var: #pixMask type: 'unsigned int'>
+ 	<var: #rgbMask type: 'unsigned int'>
  	pixMask := maskTable at: destDepth.
  	destDepth = 16
  		ifTrue: [bitsPerColor := 5.  rgbMask := 16r1F]
  		ifFalse: [bitsPerColor := 8.  rgbMask := 16rFF].
  	maskShifted := destMask.
  	destShifted := destinationWord.
  	sourceShifted := sourceWord.
  	1 to: destPPW do:
  		[:i |
  		(maskShifted bitAnd: pixMask) > 0 ifTrue:
  			["Only tally pixels within the destination rectangle"
  			destPixVal := destShifted bitAnd: pixMask.
  			sourcePixVal := sourceShifted bitAnd: pixMask.
  			destDepth < 16
  				ifTrue: [sourcePixVal = destPixVal
  							ifTrue: [diff := 0]
  							ifFalse: [diff := 1]]
  				ifFalse: [diff := (self partitionedSub: sourcePixVal from: destPixVal
  								nBits: bitsPerColor nPartitions: 3).
  						diff := (diff bitAnd: rgbMask)
  							+ (diff>>bitsPerColor bitAnd: rgbMask)
  							+ ((diff>>bitsPerColor)>>bitsPerColor bitAnd: rgbMask)].
  			bitCount := bitCount + diff].
  		maskShifted := maskShifted >> destDepth.
  		sourceShifted := sourceShifted >> destDepth.
  		destShifted := destShifted >> destDepth].
  	^ destinationWord  "For no effect on dest"
  !

Item was changed:
  ----- Method: BitBltSimulation>>rgbMax:with: (in category 'combination rules') -----
  rgbMax: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	destDepth < 16 ifTrue:
  		["Max each pixel separately"
  		^ self partitionedMax: sourceWord with: destinationWord
  						nBits: destDepth nPartitions: destPPW].
  	destDepth = 16 ifTrue:
  		["Max RGB components of each pixel separately"
  		^ (self partitionedMax: sourceWord with: destinationWord
  						nBits: 5 nPartitions: 3)
  		+ ((self partitionedMax: sourceWord>>16 with: destinationWord>>16
  						nBits: 5 nPartitions: 3) << 16)]
  	ifFalse:
  		["Max RGBA components of the pixel separately"
  		^ self partitionedMax: sourceWord with: destinationWord
  						nBits: 8 nPartitions: 4]!

Item was changed:
  ----- Method: BitBltSimulation>>rgbMin:with: (in category 'combination rules') -----
  rgbMin: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	destDepth < 16 ifTrue:
  		["Min each pixel separately"
  		^ self partitionedMin: sourceWord with: destinationWord
  						nBits: destDepth nPartitions: destPPW].
  	destDepth = 16 ifTrue:
  		["Min RGB components of each pixel separately"
  		^ (self partitionedMin: sourceWord with: destinationWord
  						nBits: 5 nPartitions: 3)
  		+ ((self partitionedMin: sourceWord>>16 with: destinationWord>>16
  						nBits: 5 nPartitions: 3) << 16)]
  	ifFalse:
  		["Min RGBA components of the pixel separately"
  		^ self partitionedMin: sourceWord with: destinationWord
  						nBits: 8 nPartitions: 4]!

Item was changed:
  ----- Method: BitBltSimulation>>rgbMinInvert:with: (in category 'combination rules') -----
  rgbMinInvert: wordToInvert with: destinationWord
  	| sourceWord |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #wordToInvert type: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	sourceWord := wordToInvert bitInvert32.
  	destDepth < 16 ifTrue:
  		["Min each pixel separately"
  		^ self partitionedMin: sourceWord with: destinationWord
  						nBits: destDepth nPartitions: destPPW].
  	destDepth = 16 ifTrue:
  		["Min RGB components of each pixel separately"
  		^ (self partitionedMin: sourceWord with: destinationWord
  						nBits: 5 nPartitions: 3)
  		+ ((self partitionedMin: sourceWord>>16 with: destinationWord>>16
  						nBits: 5 nPartitions: 3) << 16)]
  	ifFalse:
  		["Min RGBA components of the pixel separately"
  		^ self partitionedMin: sourceWord with: destinationWord
  						nBits: 8 nPartitions: 4]!

Item was changed:
  ----- Method: BitBltSimulation>>rgbMul:with: (in category 'combination rules') -----
  rgbMul: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	destDepth < 16 ifTrue:
  		["Mul each pixel separately"
  		^ self partitionedMul: sourceWord with: destinationWord
  						nBits: destDepth nPartitions: destPPW].
  	destDepth = 16 ifTrue:
  		["Mul RGB components of each pixel separately"
  		^ (self partitionedMul: sourceWord with: destinationWord
  						nBits: 5 nPartitions: 3)
  		+ ((self partitionedMul: sourceWord>>16 with: destinationWord>>16
  						nBits: 5 nPartitions: 3) << 16)]
  	ifFalse:
  		["Mul RGBA components of the pixel separately"
  		^ self partitionedMul: sourceWord with: destinationWord
  						nBits: 8 nPartitions: 4]
  
  "	| scanner |
  	Display repaintMorphicDisplay.
  	scanner := DisplayScanner quickPrintOn: Display.
  	MessageTally time: [0 to: 760 by: 4 do:  [:y |scanner drawString: 'qwrepoiuasfd=)(/&()=#!!lkjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,Mqwrepoiuasfd=)(/&()=#!!lkjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,M1234124356785678' at: 0 at y]]. "!

Item was changed:
  ----- Method: BitBltSimulation>>rgbSub:with: (in category 'combination rules') -----
  rgbSub: sourceWord with: destinationWord
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	destDepth < 16 ifTrue:
  		["Sub each pixel separately"
  		^ self partitionedSub: sourceWord from: destinationWord
  						nBits: destDepth nPartitions: destPPW].
  	destDepth = 16 ifTrue:
  		["Sub RGB components of each pixel separately"
  		^ (self partitionedSub: sourceWord from: destinationWord
  						nBits: 5 nPartitions: 3)
  		+ ((self partitionedSub: sourceWord>>16 from: destinationWord>>16
  						nBits: 5 nPartitions: 3) << 16)]
  	ifFalse:
  		["Sub RGBA components of the pixel separately"
  		^ self partitionedSub: sourceWord from: destinationWord
  						nBits: 8 nPartitions: 4]!

Item was changed:
  ----- Method: BitBltSimulation>>sourceWord:with: (in category 'combination rules') -----
  sourceWord: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord!

Item was changed:
  ----- Method: BitBltSimulation>>subWord:with: (in category 'combination rules') -----
  subWord: sourceWord with: destinationWord
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
  	^sourceWord - destinationWord!

Item was changed:
  ----- Method: BitBltSimulation>>tallyIntoMap:with: (in category 'combination rules') -----
  tallyIntoMap: sourceWord with: destinationWord
  	"Tally pixels into the color map.  Those tallied are exactly those
  	in the destination rectangle.  Note that the source should be 
  	specified == destination, in order for the proper color map checks 
  	to be performed at setup."
  	| mapIndex pixMask destShifted maskShifted pixVal |
  	<inline: false>
+ 	<returnTypeC: 'unsigned int'>
+ 	<var: #sourceWord type: 'unsigned int'>
+ 	<var: #destinationWord type: 'unsigned int'>
+ 	<var: #pixMask type: 'unsigned int'>
+ 	<var: #destShifted type: 'unsigned int'>
+ 	<var: #maskShifted type: 'unsigned int'>
  	(cmFlags bitAnd: (ColorMapPresent bitOr: ColorMapIndexedPart)) = 
  		(ColorMapPresent bitOr: ColorMapIndexedPart)
  			ifFalse: [^ destinationWord "no op"].
  	pixMask := maskTable at: destDepth.
  	destShifted := destinationWord.
  	maskShifted := destMask.
  	1 to: destPPW do:
  		[:i |
  		(maskShifted bitAnd: pixMask) = 0 ifFalse:
  			["Only tally pixels within the destination rectangle"
  			pixVal := destShifted bitAnd: pixMask.
  			destDepth < 16
  				ifTrue: [mapIndex := pixVal]
  				ifFalse: [destDepth = 16
  					ifTrue: [mapIndex := self rgbMap: pixVal from: 5 to: cmBitsPerColor]
  					ifFalse: [mapIndex := self rgbMap: pixVal from: 8 to: cmBitsPerColor]].
  			self tallyMapAt: mapIndex put: (self tallyMapAt: mapIndex) + 1].
  		maskShifted := maskShifted >> destDepth.
  		destShifted := destShifted >> destDepth].
  	^ destinationWord  "For no effect on dest"!

Item was changed:
  ----- Method: BitBltSimulation>>warpLoop (in category 'inner loop') -----
  warpLoop
  	"This version of the inner loop traverses an arbirary quadrilateral
  	source, thus producing a general affine transformation."
  	| skewWord halftoneWord mergeWord startBits
  	  deltaP12x deltaP12y deltaP43x deltaP43y pAx pAy pBx pBy
  	  xDelta yDelta smoothingCount sourceMapOop
  	  nSteps nPix words destWord endBits mergeFnwith dstShiftInc dstShiftLeft mapperFlags |
+ 	<inline: false>	
+ 	<var: #mergeFnwith declareC: 'unsigned int (*mergeFnwith)(unsigned int, unsigned int)'>
+ 	<var: #skewWord type: #'unsigned int'>
+ 	<var: #halftoneWord type: #'unsigned int'>
+ 	<var: #mergeWord type: #'unsigned int'>
+ 	<var: #destWord type: #'unsigned int'>
+ 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'unsigned int (*)(unsigned int, unsigned int)'.
- 	<inline: false>
- 	<var: #mergeFnwith declareC: 'sqInt (*mergeFnwith)(sqInt, sqInt)'>
- 	mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: 'sqInt (*)(sqInt, sqInt)'.
  	mergeFnwith.  "null ref for compiler"
  
  	(interpreterProxy slotSizeOf: bitBltOop) >= (BBWarpBase+12)
  		ifFalse: [^ interpreterProxy primitiveFail].
  	nSteps := height-1.  nSteps <= 0 ifTrue: [nSteps := 1].
  
  	pAx := self fetchIntOrFloat: BBWarpBase ofObject: bitBltOop.
  	words := self fetchIntOrFloat: BBWarpBase+3 ofObject: bitBltOop.
  	deltaP12x := self deltaFrom: pAx to: words nSteps: nSteps.
  	deltaP12x < 0 ifTrue: [pAx := words - (nSteps*deltaP12x)].
  
  	pAy := self fetchIntOrFloat: BBWarpBase+1 ofObject: bitBltOop.
  	words := self fetchIntOrFloat: BBWarpBase+4 ofObject: bitBltOop.
  	deltaP12y := self deltaFrom: pAy to: words nSteps: nSteps.
  	deltaP12y < 0 ifTrue: [pAy := words - (nSteps*deltaP12y)].
  
  	pBx := self fetchIntOrFloat: BBWarpBase+9 ofObject: bitBltOop.
  	words := self fetchIntOrFloat: BBWarpBase+6 ofObject: bitBltOop.
  	deltaP43x := self deltaFrom: pBx to: words nSteps: nSteps.
  	deltaP43x < 0 ifTrue: [pBx := words - (nSteps*deltaP43x)].
  
  	pBy := self fetchIntOrFloat: BBWarpBase+10 ofObject: bitBltOop.
  	words := self fetchIntOrFloat: BBWarpBase+7 ofObject: bitBltOop.
  	deltaP43y := self deltaFrom: pBy to: words nSteps: nSteps.
  	deltaP43y < 0 ifTrue: [pBy := words - (nSteps*deltaP43y)].
  
  	interpreterProxy failed ifTrue: [^ false].  "ie if non-integers above"
  	interpreterProxy methodArgumentCount = 2
  		ifTrue: [smoothingCount := interpreterProxy stackIntegerValue: 1.
  				sourceMapOop := interpreterProxy stackValue: 0.
  				sourceMapOop = interpreterProxy nilObject
  				ifTrue: [sourceDepth < 16 ifTrue:
  					["color map is required to smooth non-RGB dest"
  					^ interpreterProxy primitiveFail]]
  				ifFalse: [(interpreterProxy slotSizeOf: sourceMapOop)
  							< (1 << sourceDepth) ifTrue:
  					["sourceMap must be long enough for sourceDepth"
  					^ interpreterProxy primitiveFail].
  					sourceMapOop := self oopForPointer: (interpreterProxy firstIndexableField: sourceMapOop)]]
  		ifFalse: [smoothingCount := 1.
  				sourceMapOop := interpreterProxy nilObject].
  	nSteps := width-1.  nSteps <= 0 ifTrue: [nSteps := 1].
  	startBits := destPPW - (dx bitAnd: destPPW-1).
  	endBits := ((dx + bbW - 1) bitAnd: destPPW-1) + 1.
   	bbW < startBits ifTrue:[startBits := bbW].
  
  	destY < clipY ifTrue:[
  		"Advance increments if there was clipping in y"
  		pAx := pAx + (clipY - destY * deltaP12x).
  		pAy := pAy + (clipY - destY * deltaP12y).
  		pBx := pBx + (clipY - destY * deltaP43x).
  		pBy := pBy + (clipY - destY * deltaP43y)].
  
  	"Setup values for faster pixel fetching."
  	self warpLoopSetup.
  	"Setup color mapping if not provided"
  	(smoothingCount > 1 and:[(cmFlags bitAnd: ColorMapNewStyle) = 0]) ifTrue:[
  		cmLookupTable == nil ifTrue:[
  			destDepth = 16 ifTrue:[self setupColorMasksFrom: 8 to: 5].
  		] ifFalse:[
  			self setupColorMasksFrom: 8 to: cmBitsPerColor.
  		].
  	].
  	mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.
  
  	destMSB
  		ifTrue:[	dstShiftInc := 0 - destDepth.
  				dstShiftLeft := 32 - destDepth]
  		ifFalse:[	dstShiftInc := destDepth.
  				dstShiftLeft := 0].
  	1 to: bbH do:
  		[ :i | "here is the vertical loop..."
  		xDelta := self deltaFrom: pAx to: pBx nSteps: nSteps.
   		xDelta >= 0 ifTrue: [sx := pAx] ifFalse: [sx := pBx - (nSteps*xDelta)].
  		yDelta := self deltaFrom: pAy to: pBy nSteps: nSteps.
   		yDelta >= 0 ifTrue: [sy := pAy] ifFalse: [sy := pBy - (nSteps*yDelta)].
  
  		destMSB
  			ifTrue:[dstBitShift := 32 - ((dx bitAnd: destPPW - 1) + 1 * destDepth)]
  			ifFalse:[dstBitShift := (dx bitAnd: destPPW - 1) * destDepth].
  
  		(destX < clipX) ifTrue:[
  			"Advance increments if there was clipping in x"
  			sx := sx + (clipX - destX * xDelta).
  			sy := sy + (clipX - destX * yDelta).
  		].
  
  		noHalftone
  			ifTrue: [halftoneWord := AllOnes]
  			ifFalse: [halftoneWord := self halftoneAt: dy+i-1].
  		destMask := mask1.
  		nPix := startBits.
  		"Here is the inner loop..."
  		words := nWords.
  			["pick up word"
  			smoothingCount = 1 ifTrue:["Faster if not smoothing"
  				skewWord := self warpPickSourcePixels: nPix
  								xDeltah: xDelta yDeltah: yDelta
  								xDeltav: deltaP12x yDeltav: deltaP12y
  								dstShiftInc: dstShiftInc flags: mapperFlags.
  			] ifFalse:["more difficult with smoothing"
  				skewWord := self warpPickSmoothPixels: nPix
  						xDeltah: xDelta yDeltah: yDelta
  						xDeltav: deltaP12x yDeltav: deltaP12y
  						sourceMap: sourceMapOop
  						smoothing: smoothingCount
  						dstShiftInc: dstShiftInc.
  			].
  			"align next word access to left most pixel"
  			dstBitShift := dstShiftLeft.
  			destMask = AllOnes ifTrue:["avoid read-modify-write"
  				mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)
  								with: (self dstLongAt: destIndex).
  				self dstLongAt: destIndex put: (destMask bitAnd: mergeWord).
  			] ifFalse:[ "General version using dest masking"
  				destWord := self dstLongAt: destIndex.
  				mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)
  								with: (destWord bitAnd: destMask).
  				destWord := (destMask bitAnd: mergeWord) bitOr:
  								(destWord bitAnd: destMask bitInvert32).
  				self dstLongAt: destIndex put: destWord.
  			].
  			self incDestIndex: 4.
  			words = 2 "e.g., is the next word the last word?"
  				ifTrue:["set mask for last word in this row"
  						destMask := mask2.
  						nPix := endBits]
  				ifFalse:["use fullword mask for inner loop"
  						destMask := AllOnes.
  						nPix := destPPW].
  			(words := words - 1) = 0] whileFalse.
  		"--- end of inner loop ---"
  		pAx := pAx + deltaP12x.
  		pAy := pAy + deltaP12y.
  		pBx := pBx + deltaP43x.
  		pBy := pBy + deltaP43y.
  		self incDestIndex: destDelta]!

Item was changed:
  ----- Method: BitBltSimulation>>warpPickSmoothPixels:xDeltah:yDeltah:xDeltav:yDeltav:sourceMap:smoothing:dstShiftInc: (in category 'pixel mapping') -----
  warpPickSmoothPixels: nPixels
  	xDeltah: xDeltah yDeltah: yDeltah
  	xDeltav: xDeltav yDeltav: yDeltav
  	sourceMap: sourceMap
  	smoothing: n
  	dstShiftInc: dstShiftInc
  	"Pick n (sub-) pixels from the source form, mapped by sourceMap,
  	average the RGB values, map by colorMap and return the new word.
  	This version is only called from WarpBlt with smoothingCount > 1"
  	| rgb x y a r g b xx yy xdh ydh xdv ydv dstMask destWord i j k nPix |
  	<inline: false> "nope - too much stuff in here"
+ 	<var: #rgb type: #'unsigned int'>
  	dstMask := maskTable at: destDepth.
  	destWord := 0.
  	n = 2 "Try avoiding divides for most common n (divide by 2 is generated as shift)"
  		ifTrue:[xdh := xDeltah // 2. ydh := yDeltah // 2. 
  				xdv := xDeltav // 2. ydv := yDeltav // 2]
  		ifFalse:[xdh := xDeltah // n. ydh := yDeltah // n. 
  				xdv := xDeltav // n. ydv := yDeltav // n].
  	i := nPixels.
  	[
  		x := sx. y := sy.
  		a := r := g := b := 0.
  		"Pick and average n*n subpixels"
  		nPix := 0.  "actual number of pixels (not clipped and not transparent)"
  		j := n.
  		[
  			xx := x. yy := y.
  			k := n.
  			[
  				"get a single subpixel"
  				rgb := self pickWarpPixelAtX: xx y: yy.
  				(combinationRule=25 "PAINT" and: [rgb = 0]) ifFalse:[
  					"If not clipped and not transparent, then tally rgb values"
  					nPix := nPix + 1.
  					sourceDepth < 16 ifTrue:[
  						"Get RGBA values from sourcemap table"
  						rgb := self long32At: sourceMap + (rgb << 2).
  					] ifFalse:["Already in RGB format"
  						sourceDepth = 16 
  								ifTrue:[rgb := self rgbMap16To32: rgb]
  								ifFalse:[rgb := self rgbMap32To32: rgb]].
  					b := b + (rgb bitAnd: 255).
  					g := g + (rgb >> 8 bitAnd: 255).
  					r := r + (rgb >> 16 bitAnd: 255).
  					a := a + (rgb >> 24)].
  				xx := xx + xdh.
  				yy := yy + ydh.
  			(k := k - 1) = 0] whileFalse.
  			x := x + xdv.
  			y := y + ydv.
  		(j := j - 1) = 0] whileFalse.
  
  		(nPix = 0 or: [combinationRule=25 "PAINT" and: [nPix < (n * n // 2)]]) ifTrue:[
  			rgb := 0  "All pixels were 0, or most were transparent"
  		] ifFalse:[
  			"normalize rgba sums"
  			nPix = 4 "Try to avoid divides for most common n"
  				ifTrue:[r := r >> 2.	g := g >> 2.	b := b >> 2.	a := a >> 2]
  				ifFalse:[	r := r // nPix.	g := g // nPix.	b := b // nPix.	a := a // nPix].
  			rgb := (a << 24) + (r << 16) + (g << 8) + b.
  
  			"map the pixel"
  			rgb = 0 ifTrue: [
  				"only generate zero if pixel is really transparent"
  				(r + g + b + a) > 0 ifTrue: [rgb := 1]].
  			rgb := self mapPixel: rgb flags: cmFlags.
  		].
  		"Mix it in"
  		destWord := destWord bitOr: (rgb bitAnd: dstMask) << dstBitShift.
  		dstBitShift := dstBitShift + dstShiftInc.
  		sx := sx + xDeltah.
  		sy := sy + yDeltah.
  	(i := i - 1) = 0] whileFalse.
  
  	^destWord
  !



More information about the Vm-dev mailing list