<div dir="ltr"><div>Note that I have these &quot;changes&quot; working for 5 months now, so they should be reasonnably stable<br></div>I&#39;m not particularly happy with the proliferation of type hint and some of them might well be unecessary, but I don&#39;t believe in chirurgical patch: too fragile, I prefer uniformity.<br></div><div class="gmail_extra"><br><div class="gmail_quote">2016-03-31 22:06 GMT+02:00  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1754.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-nice.1754.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-nice.1754<br>
Author: nice<br>
Time: 31 March 2016, 10:04:44.274 pm<br>
UUID: a0138c60-3e62-446e-a1d8-b00b7bb6c92b<br>
Ancestors: VMMaker.oscog-eem.1753<br>
<br>
BitBltSimulation is operating on bits of 32bits words, therefore it&#39;s better to declare its operans as &#39;unsigned int&#39; rather than sqInt.<br>
<br>
On 32bits VM, this should not change anything, but on 64bits spur, it makes this snippet work:<br>
<br>
| wideString source pos blt expectedWideString |<br>
source := #[1 64 255 14 1 64 48 251].<br>
expectedWideString := WideString fromByteArray: source.<br>
wideString := WideString new: source size // 4.<br>
pos := 0.<br>
blt := (BitBlt<br>
        toForm: (Form new hackBits: wideString))<br>
        sourceForm: (Form new hackBits: source).<br>
blt<br>
        combinationRule: Form over;<br>
        sourceX: 0;<br>
        sourceY: pos // 4;<br>
        height: wideString byteSize // 4;<br>
        width: 4;<br>
        destX: 0;<br>
        destY: 0;<br>
        copyBits.<br>
wideString restoreEndianness.<br>
self assert: wideString = expectedWideString<br>
<br>
Hence it fix loading/diffing MCZ with wide character.<br>
<br>
=============== Diff against VMMaker.oscog-eem.1753 ===============<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;addWord:with: (in category &#39;combination rules&#39;) -----<br>
  addWord: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord + destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaBlend:with: (in category &#39;combination rules&#39;) -----<br>
  alphaBlend: sourceWord with: destinationWord<br>
        &quot;Blend sourceWord with destinationWord, assuming both are 32-bit pixels.<br>
        The source is assumed to have 255*alpha in the high 8 bits of each pixel,<br>
        while the high 8 bits of the destinationWord will be ignored.<br>
        The blend produced is alpha*source + (1-alpha)*dest, with<br>
        the computation being performed independently on each color<br>
        component.  The high byte of the result will be 0.&quot;<br>
        | alpha unAlpha result blendRB blendAG |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
-       &lt;return: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #blendRB type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #blendAG type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #alpha type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #unAlpha type: &#39;unsigned int&#39;&gt;<br>
        alpha := sourceWord &gt;&gt; 24.  &quot;High 8 bits of source pixel&quot;<br>
        alpha = 0 ifTrue: [ ^ destinationWord ].<br>
        alpha = 255 ifTrue: [ ^ sourceWord ].<br>
        unAlpha := 255 - alpha.<br>
<br>
        blendRB := ((sourceWord bitAnd: 16rFF00FF) * alpha) +<br>
                                ((destinationWord bitAnd: 16rFF00FF) * unAlpha)<br>
                                + 16rFF00FF.    &quot;blend red and blue&quot;<br>
<br>
        blendAG := (((sourceWord&gt;&gt; 8 bitOr: 16rFF0000) bitAnd: 16rFF00FF) * alpha) +<br>
                                ((destinationWord&gt;&gt;8 bitAnd: 16rFF00FF) * unAlpha)<br>
                                + 16rFF00FF.    &quot;blend alpha and green&quot;<br>
<br>
        blendRB := blendRB + (blendRB - 16r10001 &gt;&gt; 8 bitAnd: 16rFF00FF) &gt;&gt; 8 bitAnd: 16rFF00FF.        &quot;divide by 255&quot;<br>
        blendAG := blendAG + (blendAG - 16r10001 &gt;&gt; 8 bitAnd: 16rFF00FF) &gt;&gt; 8 bitAnd: 16rFF00FF.<br>
        result := blendRB bitOr: blendAG&lt;&lt;8.<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaBlendConst:with: (in category &#39;combination rules&#39;) -----<br>
  alphaBlendConst: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
<br>
        ^ self alphaBlendConst: sourceWord with: destinationWord paintMode: false!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaBlendConst:with:paintMode: (in category &#39;combination rules&#39;) -----<br>
  alphaBlendConst: sourceWord with: destinationWord paintMode: paintMode<br>
        &quot;Blend sourceWord with destinationWord using a constant alpha.<br>
        Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.<br>
        The blend produced is alpha*source + (1.0-alpha)*dest, with the<br>
        computation being performed independently on each color component.<br>
        This function could eventually blend into any depth destination,<br>
        using the same color averaging and mapping as warpBlt.<br>
        paintMode = true means do nothing if the source pixel value is zero.&quot;<br>
<br>
        &quot;This first implementation works with dest depths of 16 and 32 bits only.<br>
        Normal color mapping will allow sources of lower depths in this case,<br>
        and results can be mapped directly by truncation, so no extra color maps are needed.<br>
        To allow storing into any depth will require subsequent addition of two other<br>
        colormaps, as is the case with WarpBlt.&quot;<br>
<br>
        | pixMask destShifted sourceShifted destPixVal rgbMask sourcePixVal unAlpha result pixBlend shift blend maskShifted bitsPerColor blendAG blendRB |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
-       &lt;return: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #blendRB type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #blendAG type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #sourceAlpha type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #unAlpha type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #maskShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #pixMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #rgbMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #pixBlend type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #blend type: &#39;unsigned int&#39;&gt;<br>
        destDepth &lt; 16 ifTrue: [^ destinationWord &quot;no-op&quot;].<br>
        unAlpha := 255 - sourceAlpha.<br>
        result := destinationWord.<br>
        destPPW = 1 ifTrue:[&quot;32bpp blends include alpha&quot;<br>
                paintMode &amp; (sourceWord = 0)  &quot;painting a transparent pixel&quot; ifFalse:[<br>
<br>
                                blendRB := ((sourceWord bitAnd: 16rFF00FF) * sourceAlpha) +<br>
                                                ((destinationWord bitAnd: 16rFF00FF) * unAlpha) + 16rFF00FF.    &quot;blendRB red and blue&quot;<br>
<br>
                                blendAG := ((sourceWord&gt;&gt; 8 bitAnd: 16rFF00FF) * sourceAlpha) +<br>
                                                ((destinationWord&gt;&gt;8 bitAnd: 16rFF00FF) * unAlpha) + 16rFF00FF. &quot;blendRB alpha and green&quot;<br>
<br>
                                blendRB := blendRB + (blendRB - 16r10001 &gt;&gt; 8 bitAnd: 16rFF00FF) &gt;&gt; 8 bitAnd: 16rFF00FF.        &quot;divide by 255&quot;<br>
                                blendAG := blendAG + (blendAG - 16r10001 &gt;&gt; 8 bitAnd: 16rFF00FF) &gt;&gt; 8 bitAnd: 16rFF00FF.<br>
                                result := blendRB bitOr: blendAG&lt;&lt;8.<br>
                ].<br>
        ] ifFalse:[<br>
                pixMask := maskTable at: destDepth.<br>
                bitsPerColor := 5.<br>
                rgbMask := 16r1F.<br>
                maskShifted := destMask.<br>
                destShifted := destinationWord.<br>
                sourceShifted := sourceWord.<br>
                1 to: destPPW do:[:j |<br>
                        sourcePixVal := sourceShifted bitAnd: pixMask.<br>
                        ((maskShifted bitAnd: pixMask) = 0  &quot;no effect if outside of dest rectangle&quot;<br>
                                or: [paintMode &amp; (sourcePixVal = 0)  &quot;or painting a transparent pixel&quot;])<br>
                        ifFalse:<br>
                                [destPixVal := destShifted bitAnd: pixMask.<br>
                                pixBlend := 0.<br>
                                1 to: 3 do:<br>
                                        [:i | shift := (i-1)*bitsPerColor.<br>
                                        blend := (((sourcePixVal&gt;&gt;shift bitAnd: rgbMask) * sourceAlpha)<br>
                                                                + ((destPixVal&gt;&gt;shift bitAnd: rgbMask) * unAlpha))<br>
                                                        + 254 // 255 bitAnd: rgbMask.<br>
                                        pixBlend := pixBlend bitOr: blend&lt;&lt;shift].<br>
                                result := (result bitAnd: (pixMask &lt;&lt; (j-1*16)) bitInvert32)<br>
                                                                bitOr: pixBlend &lt;&lt; (j-1*16)].<br>
                        maskShifted := maskShifted &gt;&gt; destDepth.<br>
                        sourceShifted := sourceShifted &gt;&gt; destDepth.<br>
                        destShifted := destShifted &gt;&gt; destDepth].<br>
        ].<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaBlendScaled:with: (in category &#39;combination rules&#39;) -----<br>
  alphaBlendScaled: sourceWord with: destinationWord<br>
        &quot;Blend sourceWord with destinationWord using the alpha value from sourceWord.<br>
        Alpha is encoded as 0 meaning 0.0, and 255 meaning 1.0.<br>
        In contrast to alphaBlend:with: the color produced is<br>
<br>
                srcColor + (1-srcAlpha) * dstColor<br>
<br>
        e.g., it is assumed that the source color is already scaled.&quot;<br>
        | unAlpha rb ag |<br>
        &lt;inline: false&gt; &quot;Do NOT inline this into optimized loops&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #rb type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #ag type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #unAlpha type: &#39;unsigned int&#39;&gt;<br>
        unAlpha := 255 - (sourceWord &gt;&gt; 24).  &quot;High 8 bits of source pixel is source opacity (ARGB format)&quot;<br>
        rb := ((destinationWord bitAnd: 16rFF00FF) * unAlpha &gt;&gt; 8 bitAnd: 16rFF00FF) + (sourceWord bitAnd: 16rFF00FF). &quot;blend red and blue components&quot;<br>
        ag := ((destinationWord&gt;&gt;8 bitAnd: 16rFF00FF) * unAlpha &gt;&gt; 8 bitAnd: 16rFF00FF) + (sourceWord&gt;&gt;8 bitAnd: 16rFF00FF). &quot;blend alpha and green components&quot;<br>
        rb := (rb bitAnd: 16rFF00FF) bitOr: (rb bitAnd: 16r1000100) * 16rFF &gt;&gt; 8. &quot;saturate red and blue components if there is a carry&quot;<br>
        ag := (ag bitAnd: 16rFF00FF) &lt;&lt; 8 bitOr: (ag bitAnd: 16r1000100) * 16rFF. &quot;saturate alpha and green components if there is a carry&quot;<br>
        ^ag bitOr: rb &quot;recompose&quot;!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaPaintConst:with: (in category &#39;combination rules&#39;) -----<br>
  alphaPaintConst: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
<br>
        sourceWord = 0 ifTrue: [^ destinationWord  &quot;opt for all-transparent source&quot;].<br>
        ^ self alphaBlendConst: sourceWord with: destinationWord paintMode: true!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaSourceBlendBits16 (in category &#39;inner loop&#39;) -----<br>
  alphaSourceBlendBits16<br>
        &quot;This version assumes<br>
                combinationRule = 34<br>
                sourcePixSize = 32<br>
                destPixSize = 16<br>
                sourceForm ~= destForm.<br>
        &quot;<br>
        | srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY<br>
        srcY dstY dstMask srcShift ditherBase ditherIndex ditherThreshold |<br>
        &lt;inline: false&gt; &quot;This particular method should be optimized in itself&quot;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #dstMask type: #&#39;unsigned int&#39;&gt;<br>
        deltaY := bbH + 1. &quot;So we can pre-decrement&quot;<br>
        srcY := sy.<br>
        dstY := dy.<br>
        srcShift := (dx bitAnd: 1) * 16.<br>
        destMSB ifTrue:[srcShift := 16 - srcShift].<br>
        mask1 := 16rFFFF &lt;&lt; (16 - srcShift).<br>
        &quot;This is the outer loop&quot;<br>
        [(deltaY := deltaY - 1) ~= 0] whileTrue:[<br>
                srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).<br>
                dstIndex := destBits + (dstY * destPitch) + (dx // 2 * 4).<br>
                ditherBase := (dstY bitAnd: 3) * 4.<br>
                ditherIndex := (sx bitAnd: 3) - 1. &quot;For pre-increment&quot;<br>
                deltaX := bbW + 1. &quot;So we can pre-decrement&quot;<br>
                dstMask := mask1.<br>
                dstMask = 16rFFFF ifTrue:[srcShift := 16] ifFalse:[srcShift := 0].<br>
<br>
                &quot;This is the inner loop&quot;<br>
                [(deltaX := deltaX - 1) ~= 0] whileTrue:[<br>
                        ditherThreshold := ditherMatrix4x4 at: ditherBase + (ditherIndex := ditherIndex + 1 bitAnd: 3).<br>
                        sourceWord := self srcLongAt: srcIndex.<br>
                        srcAlpha := sourceWord &gt;&gt; 24.<br>
                        srcAlpha = 255 ifTrue:[<br>
                                &quot;Dither from 32 to 16 bit&quot;<br>
                                sourceWord := self dither32To16: sourceWord threshold: ditherThreshold.<br>
                                sourceWord = 0<br>
                                        ifTrue:[sourceWord := 1 &lt;&lt; srcShift]<br>
                                        ifFalse: [sourceWord := sourceWord &lt;&lt; srcShift].<br>
                                &quot;Store masked value&quot;<br>
                                self dstLongAt: dstIndex put: sourceWord mask: dstMask.<br>
                        ] ifFalse:[ &quot;srcAlpha ~= 255&quot;<br>
                                srcAlpha = 0 ifFalse:[ &quot;0 &lt; srcAlpha &lt; 255&quot;<br>
                                        &quot;If we have to mix colors then just copy a single word&quot;<br>
                                        destWord := self dstLongAt: dstIndex.<br>
                                        destWord := destWord bitAnd: dstMask bitInvert32.<br>
                                        destWord := destWord &gt;&gt; srcShift.<br>
                                        &quot;Expand from 16 to 32 bit by adding zero bits&quot;<br>
                                        destWord := (((destWord bitAnd: 16r7C00) bitShift: 9) bitOr:<br>
                                                                        ((destWord bitAnd: 16r3E0) bitShift: 6)) bitOr:<br>
                                                                (((destWord bitAnd: 16r1F) bitShift: 3) bitOr:<br>
                                                                        16rFF000000).<br>
                                        &quot;Mix colors&quot;<br>
                                        sourceWord := self alphaBlendScaled: sourceWord with: destWord.<br>
                                        &quot;And dither&quot;<br>
                                        sourceWord := self dither32To16: sourceWord threshold: ditherThreshold.<br>
                                        sourceWord = 0<br>
                                                ifTrue:[sourceWord := 1 &lt;&lt; srcShift]<br>
                                                ifFalse:[sourceWord := sourceWord &lt;&lt; srcShift].<br>
                                        &quot;Store back&quot;<br>
                                        self dstLongAt: dstIndex put: sourceWord mask: dstMask.<br>
                                ].<br>
                        ].<br>
                        srcIndex := srcIndex + 4.<br>
                        destMSB<br>
                                ifTrue:[srcShift = 0 ifTrue:[dstIndex := dstIndex + 4]]<br>
                                ifFalse:[srcShift = 0 ifFalse:[dstIndex := dstIndex + 4]].<br>
                        srcShift := srcShift bitXor: 16. &quot;Toggle between 0 and 16&quot;<br>
                        dstMask := dstMask bitInvert32. &quot;Mask other half word&quot;<br>
                ].<br>
                srcY := srcY + 1.<br>
                dstY := dstY + 1.<br>
        ].!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaSourceBlendBits32 (in category &#39;inner loop&#39;) -----<br>
  alphaSourceBlendBits32<br>
        &quot;This version assumes<br>
                combinationRule = 34<br>
                sourcePixSize = destPixSize = 32<br>
                sourceForm ~= destForm.<br>
        Note: The inner loop has been optimized for dealing<br>
                with the special cases of srcAlpha = 0.0 and srcAlpha = 1.0<br>
        &quot;<br>
        | srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY srcY dstY |<br>
        &lt;inline: false&gt; &quot;This particular method should be optimized in itself&quot;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
<br>
        &quot;Give the compile a couple of hints&quot;<br>
<br>
        &quot;The following should be declared as pointers so the compiler will<br>
        notice that they&#39;re used for accessing memory locations<br>
        (good to know on an Intel architecture) but then the increments<br>
        would be different between ST code and C code so must hope the<br>
        compiler notices what happens (MS Visual C does)&quot;<br>
<br>
        deltaY := bbH + 1. &quot;So we can pre-decrement&quot;<br>
        srcY := sy.<br>
        dstY := dy.<br>
<br>
        &quot;This is the outer loop&quot;<br>
        [(deltaY := deltaY - 1) ~= 0] whileTrue:[<br>
                srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).<br>
                dstIndex := destBits + (dstY * destPitch) + (dx * 4).<br>
                deltaX := bbW + 1. &quot;So we can pre-decrement&quot;<br>
<br>
                &quot;This is the inner loop&quot;<br>
                [(deltaX := deltaX - 1) ~= 0] whileTrue:[<br>
                        sourceWord := self srcLongAt: srcIndex.<br>
                        srcAlpha := sourceWord &gt;&gt; 24.<br>
                        srcAlpha = 255 ifTrue:[<br>
                                self dstLongAt: dstIndex put: sourceWord.<br>
                                srcIndex := srcIndex + 4.<br>
                                dstIndex := dstIndex + 4.<br>
                                &quot;Now copy as many words as possible with alpha = 255&quot;<br>
                                [(deltaX := deltaX - 1) ~= 0 and:[<br>
                                        (sourceWord := self srcLongAt: srcIndex) &gt;&gt; 24 = 255]]<br>
                                                whileTrue:[<br>
                                                        self dstLongAt: dstIndex put: sourceWord.<br>
                                                        srcIndex := srcIndex + 4.<br>
                                                        dstIndex := dstIndex + 4.<br>
                                                ].<br>
                                &quot;Adjust deltaX&quot;<br>
                                deltaX := deltaX + 1.<br>
                        ] ifFalse:[ &quot;srcAlpha ~= 255&quot;<br>
                                srcAlpha = 0 ifTrue:[<br>
                                        srcIndex := srcIndex + 4.<br>
                                        dstIndex := dstIndex + 4.<br>
                                        &quot;Now skip as many words as possible,&quot;<br>
                                        [(deltaX := deltaX - 1) ~= 0 and:[<br>
                                                (sourceWord := self srcLongAt: srcIndex) &gt;&gt; 24 = 0]]<br>
                                                whileTrue:[<br>
                                                        srcIndex := srcIndex + 4.<br>
                                                        dstIndex := dstIndex + 4.<br>
                                                ].<br>
                                        &quot;Adjust deltaX&quot;<br>
                                        deltaX := deltaX + 1.<br>
                                ] ifFalse:[ &quot;0 &lt; srcAlpha &lt; 255&quot;<br>
                                        &quot;If we have to mix colors then just copy a single word&quot;<br>
                                        destWord := self dstLongAt: dstIndex.<br>
                                        destWord := self alphaBlendScaled: sourceWord with: destWord.<br>
                                        self dstLongAt: dstIndex put: destWord.<br>
                                        srcIndex := srcIndex + 4.<br>
                                        dstIndex := dstIndex + 4.<br>
                                ].<br>
                        ].<br>
                ].<br>
                srcY := srcY + 1.<br>
                dstY := dstY + 1.<br>
        ].!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;alphaSourceBlendBits8 (in category &#39;inner loop&#39;) -----<br>
  alphaSourceBlendBits8<br>
        &quot;This version assumes<br>
                combinationRule = 34<br>
                sourcePixSize = 32<br>
                destPixSize = 8<br>
                sourceForm ~= destForm.<br>
        Note: This is not real blending since we don&#39;t have the source colors available.<br>
        &quot;<br>
        | srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY<br>
        srcY dstY dstMask srcShift adjust mappingTable mapperFlags |<br>
        &lt;inline: false&gt;<br>
        &lt;var: #mappingTable type:&#39;unsigned int *&#39;&gt;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #dstMask type: #&#39;unsigned int&#39;&gt;<br>
        mappingTable := self default8To32Table.<br>
        mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.<br>
        deltaY := bbH + 1. &quot;So we can pre-decrement&quot;<br>
        srcY := sy.<br>
        dstY := dy.<br>
        mask1 := ((dx bitAnd: 3) * 8).<br>
        destMSB ifTrue:[mask1 := 24 - mask1].<br>
        mask2 := AllOnes bitXor:(16rFF &lt;&lt; mask1).<br>
        (dx bitAnd: 1) = 0<br>
                ifTrue:[adjust := 0]<br>
                ifFalse:[adjust := 16r1F1F1F1F].<br>
        (dy bitAnd: 1) = 0<br>
                ifTrue:[adjust := adjust bitXor: 16r1F1F1F1F].<br>
        &quot;This is the outer loop&quot;<br>
        [(deltaY := deltaY - 1) ~= 0] whileTrue:[<br>
                adjust := adjust bitXor: 16r1F1F1F1F.<br>
                srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).<br>
                dstIndex := destBits + (dstY * destPitch) + (dx // 4 * 4).<br>
                deltaX := bbW + 1. &quot;So we can pre-decrement&quot;<br>
                srcShift := mask1.<br>
                dstMask := mask2.<br>
<br>
                &quot;This is the inner loop&quot;<br>
                [(deltaX := deltaX - 1) ~= 0] whileTrue:[<br>
                        sourceWord := ((self srcLongAt: srcIndex) bitAnd: (adjust bitInvert32)) + adjust.<br>
                        srcAlpha := sourceWord &gt;&gt; 24.<br>
                        srcAlpha &gt; 31 ifTrue:[&quot;Everything below 31 is transparent&quot;<br>
                                srcAlpha &lt; 224 ifTrue:[&quot;Everything above 224 is opaque&quot;<br>
                                        destWord := self dstLongAt: dstIndex.<br>
                                        destWord := destWord bitAnd: dstMask bitInvert32.<br>
                                        destWord := destWord &gt;&gt; srcShift.<br>
                                        destWord := mappingTable at: destWord.<br>
                                        sourceWord := self alphaBlendScaled: sourceWord with: destWord.<br>
                                ].<br>
                                sourceWord := self mapPixel: sourceWord flags: mapperFlags.<br>
                                sourceWord := sourceWord &lt;&lt; srcShift.<br>
                                &quot;Store back&quot;<br>
                                self dstLongAt: dstIndex put: sourceWord mask: dstMask.<br>
                        ].<br>
                        srcIndex := srcIndex + 4.<br>
                        destMSB ifTrue:[<br>
                                srcShift = 0<br>
                                        ifTrue:[dstIndex := dstIndex + 4.<br>
                                                        srcShift := 24.<br>
                                                        dstMask := 16r00FFFFFF]<br>
                                        ifFalse:[srcShift := srcShift - 8.<br>
                                                        dstMask := (dstMask &gt;&gt; 8) bitOr: 16rFF000000].<br>
                        ] ifFalse:[<br>
                                srcShift = 24<br>
                                        ifTrue:[dstIndex := dstIndex + 4.<br>
                                                        srcShift := 0.<br>
                                                        dstMask := 16rFFFFFF00]<br>
                                        ifFalse:[srcShift := srcShift + 8.<br>
                                                        dstMask := dstMask &lt;&lt; 8 bitOr: 255].<br>
                        ].<br>
                        adjust := adjust bitXor: 16r1F1F1F1F.<br>
                ].<br>
                srcY := srcY + 1.<br>
                dstY := dstY + 1.<br>
        ].!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitAnd:with: (in category &#39;combination rules&#39;) -----<br>
  bitAnd: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitAnd: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitAndInvert:with: (in category &#39;combination rules&#39;) -----<br>
  bitAndInvert: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitAnd: destinationWord bitInvert32!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertAnd:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertAnd: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitInvert32 bitAnd: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertAndInvert:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertAndInvert: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitInvert32 bitAnd: destinationWord bitInvert32!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertDestination:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertDestination: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^destinationWord bitInvert32!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertOr:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertOr: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitInvert32 bitOr: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertOrInvert:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertOrInvert: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitInvert32 bitOr: destinationWord bitInvert32!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertSource:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertSource: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitInvert32!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitInvertXor:with: (in category &#39;combination rules&#39;) -----<br>
  bitInvertXor: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitInvert32 bitXor: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitOr:with: (in category &#39;combination rules&#39;) -----<br>
  bitOr: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitOr: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitOrInvert:with: (in category &#39;combination rules&#39;) -----<br>
  bitOrInvert: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitOr: destinationWord bitInvert32!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;bitXor:with: (in category &#39;combination rules&#39;) -----<br>
  bitXor: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord bitXor: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;clearWord:with: (in category &#39;combination rules&#39;) -----<br>
+ clearWord: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
- clearWord: source with: destination<br>
        ^ 0!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;copyLoop (in category &#39;inner loop&#39;) -----<br>
  copyLoop<br>
        | prevWord thisWord skewWord halftoneWord mergeWord hInc y unskew skewMask notSkewMask mergeFnwith destWord |<br>
        &quot;This version of the inner loop assumes noSource = false.&quot;<br>
        &lt;inline: false&gt;<br>
+       &lt;var: #mergeFnwith declareC: &#39;unsigned int (*mergeFnwith)(unsigned int, unsigned int)&#39;&gt;<br>
+       &lt;var: #prevWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #thisWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #skewWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #halftoneWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #mergeWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #skewMask type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #notSkewMask type: #&#39;unsigned int&#39;&gt;<br>
+       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;unsigned int (*)(unsigned int, unsigned int)&#39;.<br>
-       &lt;var: #mergeFnwith declareC: &#39;sqInt (*mergeFnwith)(sqInt, sqInt)&#39;&gt;<br>
-       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;sqInt (*)(sqInt, sqInt)&#39;.<br>
        mergeFnwith.  &quot;null ref for compiler&quot;<br>
<br>
        hInc := hDir*4.  &quot;Byte delta&quot;<br>
        &quot;degenerate skew fixed for Sparc. 10/20/96 ikp&quot;<br>
        skew == -32<br>
                ifTrue: [skew := unskew := skewMask := 0]<br>
                ifFalse: [skew &lt; 0<br>
                        ifTrue:<br>
                                [unskew := skew+32.<br>
                                skewMask := AllOnes &lt;&lt; (0-skew)]<br>
                        ifFalse:<br>
                                [skew = 0<br>
                                        ifTrue:<br>
                                                [unskew := 0.<br>
                                                skewMask := AllOnes]<br>
                                        ifFalse:<br>
                                                [unskew := skew-32.<br>
                                                skewMask := AllOnes &gt;&gt; skew]]].<br>
        notSkewMask := skewMask bitInvert32.<br>
        noHalftone<br>
                ifTrue: [halftoneWord := AllOnes.  halftoneHeight := 0]<br>
                ifFalse: [halftoneWord := self halftoneAt: 0].<br>
<br>
        y := dy.<br>
        1 to: bbH do: &quot;here is the vertical loop&quot;<br>
                [ :i |<br>
                halftoneHeight &gt; 1 ifTrue:  &quot;Otherwise, its always the same&quot;<br>
                        [halftoneWord := self halftoneAt: y.<br>
                        y := y + vDir].<br>
                preload ifTrue:<br>
                        [&quot;load the 64-bit shifter&quot;<br>
                        prevWord := self srcLongAt: sourceIndex.<br>
                        self incSrcIndex: hInc]<br>
                        ifFalse:<br>
                        [prevWord := 0].<br>
<br>
        &quot;Note: the horizontal loop has been expanded into three parts for speed:&quot;<br>
<br>
                        &quot;This first section requires masking of the destination store...&quot;<br>
                        destMask := mask1.<br>
                        thisWord := self srcLongAt: sourceIndex.  &quot;pick up next word&quot;<br>
                        self incSrcIndex: hInc.<br>
                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                        bitOr:  &quot;32-bit rotate&quot;<br>
                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                        prevWord := thisWord.<br>
                        destWord := self dstLongAt: destIndex.<br>
                        mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord) with: destWord.<br>
                        destWord := (destMask bitAnd: mergeWord) bitOr:<br>
                                                        (destWord bitAnd: destMask bitInvert32).<br>
                        self dstLongAt: destIndex put: destWord.<br>
                        self incDestIndex: hInc.<br>
<br>
                &quot;This central horizontal loop requires no store masking&quot;<br>
                destMask := AllOnes.<br>
  combinationRule = 3<br>
  ifTrue: [(skew = 0) &amp; (halftoneWord = AllOnes)<br>
                ifTrue:<br>
                [&quot;Very special inner loop for STORE mode with no skew -- just move words&quot;<br>
                hDir = -1<br>
                ifTrue: [&quot;Woeful patch: revert to older code for hDir = -1&quot;<br>
                                2 to: nWords-1 do:<br>
                                        [ :word |<br>
                                        thisWord := self srcLongAt: sourceIndex.<br>
                                        self incSrcIndex: hInc.<br>
                                        self dstLongAt: destIndex put: thisWord.<br>
                                        self incDestIndex: hInc]]<br>
                ifFalse: [2 to: nWords-1 do:<br>
                                        [ :word |  &quot;Note loop starts with prevWord loaded (due to preload)&quot;<br>
                                        self dstLongAt: destIndex put: prevWord.<br>
                                        self incDestIndex: hInc.<br>
                                        prevWord := self srcLongAt: sourceIndex.<br>
                                        self incSrcIndex: hInc]]]<br>
                ifFalse:<br>
                [&quot;Special inner loop for STORE mode -- no need to call merge&quot;<br>
                2 to: nWords-1 do:<br>
                        [ :word |<br>
                        thisWord := self srcLongAt: sourceIndex.<br>
                        self incSrcIndex: hInc.<br>
                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                        bitOr:  &quot;32-bit rotate&quot;<br>
                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                        prevWord := thisWord.<br>
                        self dstLongAt: destIndex put: (skewWord bitAnd: halftoneWord).<br>
                        self incDestIndex: hInc]]<br>
  ] ifFalse: [2 to: nWords-1 do: &quot;Normal inner loop does merge:&quot;<br>
                        [ :word |<br>
                        thisWord := self srcLongAt: sourceIndex.  &quot;pick up next word&quot;<br>
                        self incSrcIndex: hInc.<br>
                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                        bitOr:  &quot;32-bit rotate&quot;<br>
                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                        prevWord := thisWord.<br>
                        mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)<br>
                                                        with: (self dstLongAt: destIndex).<br>
                        self dstLongAt: destIndex put: mergeWord.<br>
                        self incDestIndex: hInc]<br>
  ].<br>
<br>
                &quot;This last section, if used, requires masking of the destination store...&quot;<br>
                nWords &gt; 1 ifTrue:<br>
                        [destMask := mask2.<br>
                        thisWord := self srcLongAt: sourceIndex.  &quot;pick up next word&quot;<br>
                        self incSrcIndex: hInc.<br>
                        skewWord := ((prevWord bitAnd: notSkewMask) bitShift: unskew)<br>
                                                        bitOr:  &quot;32-bit rotate&quot;<br>
                                                ((thisWord bitAnd: skewMask) bitShift: skew).<br>
                        destWord := self dstLongAt: destIndex.<br>
                        mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord) with: destWord.<br>
                        destWord := (destMask bitAnd: mergeWord) bitOr:<br>
                                                        (destWord bitAnd: destMask bitInvert32).<br>
                        self dstLongAt: destIndex put: destWord.<br>
                        self incDestIndex: hInc].<br>
<br>
        self incSrcIndex: sourceDelta.<br>
        self incDestIndex: destDelta]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;copyLoopNoSource (in category &#39;inner loop&#39;) -----<br>
  copyLoopNoSource<br>
        &quot;Faster copyLoop when source not used.  hDir and vDir are both<br>
        positive, and perload and skew are unused&quot;<br>
        | halftoneWord mergeWord mergeFnwith destWord |<br>
        &lt;inline: false&gt;<br>
+       &lt;var: #mergeFnwith declareC: &#39;unsigned int (*mergeFnwith)(unsigned int, unsigned int)&#39;&gt;<br>
+       &lt;var: #halftoneWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #mergeWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;unsigned int (*)(unsigned int, unsigned int)&#39;.<br>
-       &lt;var: #mergeFnwith declareC: &#39;sqInt (*mergeFnwith)(sqInt, sqInt)&#39;&gt;<br>
-       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;sqInt (*)(sqInt, sqInt)&#39;.<br>
        mergeFnwith.  &quot;null ref for compiler&quot;<br>
<br>
        1 to: bbH do: &quot;here is the vertical loop&quot;<br>
                [ :i |<br>
                noHalftone<br>
                        ifTrue: [halftoneWord := AllOnes]<br>
                        ifFalse: [halftoneWord := self halftoneAt: dy+i-1].<br>
<br>
        &quot;Note: the horizontal loop has been expanded into three parts for speed:&quot;<br>
<br>
                        &quot;This first section requires masking of the destination store...&quot;<br>
                        destMask := mask1.<br>
                        destWord := self dstLongAt: destIndex.<br>
                        mergeWord := self mergeFn: halftoneWord<br>
                                                        with: destWord.<br>
                        destWord := (destMask bitAnd: mergeWord) bitOr:<br>
                                                        (destWord bitAnd: destMask bitInvert32).<br>
                        self dstLongAt: destIndex put: destWord.<br>
                        self incDestIndex: 4.<br>
<br>
                &quot;This central horizontal loop requires no store masking&quot;<br>
                        destMask := AllOnes.<br>
                        combinationRule = 3 ifTrue: [&quot;Special inner loop for STORE&quot;<br>
                                destWord := halftoneWord.<br>
                                2 to: nWords-1 do:[ :word |<br>
                                        self dstLongAt: destIndex put: destWord.<br>
                                        self incDestIndex: 4].<br>
                        ] ifFalse:[ &quot;Normal inner loop does merge&quot;<br>
                                2 to: nWords-1 do:[ :word | &quot;Normal inner loop does merge&quot;<br>
                                        destWord := self dstLongAt: destIndex.<br>
                                        mergeWord := self mergeFn: halftoneWord with: destWord.<br>
                                        self dstLongAt: destIndex put: mergeWord.<br>
                                        self incDestIndex: 4].<br>
                        ].<br>
<br>
                &quot;This last section, if used, requires masking of the destination store...&quot;<br>
                nWords &gt; 1 ifTrue:<br>
                        [destMask := mask2.<br>
                        destWord := self dstLongAt: destIndex.<br>
                        mergeWord := self mergeFn: halftoneWord with: destWord.<br>
                        destWord := (destMask bitAnd: mergeWord) bitOr:<br>
                                                        (destWord bitAnd: destMask bitInvert32).<br>
                        self dstLongAt: destIndex put: destWord.<br>
                        self incDestIndex: 4].<br>
<br>
        self incDestIndex: destDelta]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;copyLoopPixMap (in category &#39;inner loop&#39;) -----<br>
  copyLoopPixMap<br>
        &quot;This version of the inner loop maps source pixels<br>
        to a destination form with different depth.  Because it is already<br>
        unweildy, the loop is not unrolled as in the other versions.<br>
        Preload, skew and skewMask are all overlooked, since pickSourcePixels<br>
        delivers its destination word already properly aligned.<br>
        Note that pickSourcePixels could be copied in-line at the top of<br>
        the horizontal loop, and some of its inits moved out of the loop.&quot;<br>
        &quot;ar 12/7/1999:<br>
        The loop has been rewritten to use only one pickSourcePixels call.<br>
        The idea is that the call itself could be inlined. If we decide not<br>
        to inline pickSourcePixels we could optimize the loop instead.&quot;<br>
        | skewWord halftoneWord mergeWord scrStartBits nSourceIncs startBits endBits sourcePixMask destPixMask mergeFnwith nPix srcShift dstShift destWord words srcShiftInc dstShiftInc dstShiftLeft mapperFlags |<br>
        &lt;inline: false&gt;<br>
+       &lt;var: #mergeFnwith declareC: &#39;unsigned int (*mergeFnwith)(unsigned int, unsigned int)&#39;&gt;<br>
+       &lt;var: #skewWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #halftoneWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #mergeWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourcePixMask type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destPixMask type: #&#39;unsigned int&#39;&gt;<br>
+       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;unsigned int (*)(unsigned int, unsigned int)&#39;.<br>
-       &lt;var: #mergeFnwith declareC: &#39;sqInt (*mergeFnwith)(sqInt, sqInt)&#39;&gt;<br>
-       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;sqInt (*)(sqInt, sqInt)&#39;.<br>
        mergeFnwith.  &quot;null ref for compiler&quot;<br>
<br>
        &quot;Additional inits peculiar to unequal source and dest pix size...&quot;<br>
        sourcePPW := 32//sourceDepth.<br>
        sourcePixMask := maskTable at: sourceDepth.<br>
        destPixMask := maskTable at: destDepth.<br>
        mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.<br>
        sourceIndex := sourceBits +<br>
                                        (sy * sourcePitch) + ((sx // sourcePPW) *4).<br>
        scrStartBits := sourcePPW - (sx bitAnd: sourcePPW-1).<br>
        bbW &lt; scrStartBits<br>
                ifTrue: [nSourceIncs := 0]<br>
                ifFalse: [nSourceIncs := (bbW - scrStartBits)//sourcePPW + 1].<br>
        sourceDelta := sourcePitch - (nSourceIncs * 4).<br>
<br>
        &quot;Note following two items were already calculated in destmask setup!!&quot;<br>
        startBits := destPPW - (dx bitAnd: destPPW-1).<br>
        endBits := ((dx + bbW - 1) bitAnd: destPPW-1) + 1.<br>
<br>
        bbW &lt; startBits ifTrue:[startBits := bbW].<br>
<br>
        &quot;Precomputed shifts for pickSourcePixels&quot;<br>
        srcShift := ((sx bitAnd: sourcePPW - 1) * sourceDepth).<br>
        dstShift := ((dx bitAnd: destPPW - 1) * destDepth).<br>
        srcShiftInc := sourceDepth.<br>
        dstShiftInc := destDepth.<br>
        dstShiftLeft := 0.<br>
        sourceMSB ifTrue:[<br>
                srcShift := 32 - sourceDepth - srcShift.<br>
                srcShiftInc := 0 - srcShiftInc].<br>
        destMSB ifTrue:[<br>
                dstShift := 32 - destDepth - dstShift.<br>
                dstShiftInc := 0 - dstShiftInc.<br>
                dstShiftLeft := 32 - destDepth].<br>
<br>
        1 to: bbH do: &quot;here is the vertical loop&quot;<br>
                [ :i |<br>
                &quot;*** is it possible at all that noHalftone == false? ***&quot;<br>
                noHalftone<br>
                        ifTrue:[halftoneWord := AllOnes]<br>
                        ifFalse: [halftoneWord := self halftoneAt: dy+i-1].<br>
                &quot;setup first load&quot;<br>
                srcBitShift := srcShift.<br>
                dstBitShift := dstShift.<br>
                destMask := mask1.<br>
                nPix := startBits.<br>
                &quot;Here is the horizontal loop...&quot;<br>
                words := nWords.<br>
                        [&quot;pick up the word&quot;<br>
                        skewWord := self pickSourcePixels: nPix flags: mapperFlags<br>
                                                                srcMask: sourcePixMask destMask: destPixMask<br>
                                                                srcShiftInc: srcShiftInc dstShiftInc: dstShiftInc.<br>
                        &quot;align next word to leftmost pixel&quot;<br>
                        dstBitShift := dstShiftLeft.<br>
<br>
                        destMask = AllOnes ifTrue:[&quot;avoid read-modify-write&quot;<br>
                                mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)<br>
                                                                with: (self dstLongAt: destIndex).<br>
                                self dstLongAt: destIndex put: (destMask bitAnd: mergeWord).<br>
                        ] ifFalse:[ &quot;General version using dest masking&quot;<br>
                                destWord := self dstLongAt: destIndex.<br>
                                mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)<br>
                                                                with: (destWord bitAnd: destMask).<br>
                                destWord := (destMask bitAnd: mergeWord) bitOr:<br>
                                                                (destWord bitAnd: destMask bitInvert32).<br>
                                self dstLongAt: destIndex put: destWord.<br>
                        ].<br>
                        self incDestIndex: 4.<br>
                        words = 2 &quot;e.g., is the next word the last word?&quot;<br>
                                ifTrue:[&quot;set mask for last word in this row&quot;<br>
                                                destMask := mask2.<br>
                                                nPix := endBits]<br>
                                ifFalse:[&quot;use fullword mask for inner loop&quot;<br>
                                                destMask := AllOnes.<br>
                                                nPix := destPPW].<br>
                        (words := words - 1) = 0] whileFalse.<br>
                &quot;--- end of inner loop ---&quot;<br>
                self incSrcIndex: sourceDelta.<br>
                self incDestIndex: destDelta]<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;destinationWord:with: (in category &#39;combination rules&#39;) -----<br>
  destinationWord: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;dither32To16:threshold: (in category &#39;pixel mapping&#39;) -----<br>
  dither32To16: srcWord threshold: ditherValue<br>
        &quot;Dither the given 32bit word to 16 bit. Ignore alpha.&quot;<br>
        | addThreshold  |<br>
        &lt;inline: true&gt; &quot;You bet&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #srcWord type: &#39;unsigned int&#39;&gt;<br>
        addThreshold := ditherValue bitShift: 8.<br>
        ^((dither8Lookup at: (addThreshold+((srcWord bitShift: -16) bitAnd: 255))) bitShift: 10) +<br>
                ((dither8Lookup at: (addThreshold+((srcWord bitShift: -8) bitAnd: 255))) bitShift: 5) +<br>
                (dither8Lookup at: (addThreshold+(srcWord bitAnd: 255))).<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;expensiveDither32To16:threshold: (in category &#39;pixel mapping&#39;) -----<br>
  expensiveDither32To16: srcWord threshold: ditherValue<br>
        &quot;Dither the given 32bit word to 16 bit. Ignore alpha.&quot;<br>
        | pv threshold value out |<br>
        &lt;inline: true&gt; &quot;You bet&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #srcWord type: &#39;unsigned int&#39;&gt;<br>
        pv := srcWord bitAnd: 255.<br>
        threshold := ditherThresholds16 at: (pv bitAnd: 7).<br>
        value := ditherValues16 at: (pv bitShift: -3).<br>
        ditherValue &lt; threshold<br>
                ifTrue:[out := value + 1]<br>
                ifFalse:[out := value].<br>
        pv := (srcWord bitShift: -8) bitAnd: 255.<br>
        threshold := ditherThresholds16 at: (pv bitAnd: 7).<br>
        value := ditherValues16 at: (pv bitShift: -3).<br>
        ditherValue &lt; threshold<br>
                ifTrue:[out := out bitOr: (value+1 bitShift:5)]<br>
                ifFalse:[out := out bitOr: (value bitShift: 5)].<br>
        pv := (srcWord bitShift: -16) bitAnd: 255.<br>
        threshold := ditherThresholds16 at: (pv bitAnd: 7).<br>
        value := ditherValues16 at: (pv bitShift: -3).<br>
        ditherValue &lt; threshold<br>
                ifTrue:[out := out bitOr: (value+1 bitShift:10)]<br>
                ifFalse:[out := out bitOr: (value bitShift: 10)].<br>
        ^out!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;fixAlpha:with: (in category &#39;combination rules&#39;) -----<br>
  fixAlpha: sourceWord with: destinationWord<br>
        &quot;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-&gt;32 bpp conversions.&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        destDepth = 32 ifFalse:[^destinationWord]. &quot;no-op for non 32bpp&quot;<br>
        destinationWord = 0 ifTrue:[^0].<br>
        (destinationWord bitAnd: 16rFF000000) = 0 ifFalse:[^destinationWord].<br>
        ^destinationWord bitOr: (sourceWord bitAnd: 16rFF000000)<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;merge:with: (in category &#39;combination rules&#39;) -----<br>
  merge: sourceWord with: destinationWord<br>
        | mergeFnwith |<br>
        &quot;Sender warpLoop is too big to include this in-line&quot;<br>
+       &lt;var: #mergeFnwith declareC: &#39;unsigned int (*mergeFnwith)(unsigned int, unsigned int)&#39;&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
+       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;unsigned int (*)(unsigned int, unsigned int)&#39;.<br>
-       &lt;var: #mergeFnwith declareC: &#39;sqInt (*mergeFnwith)(sqInt, sqInt)&#39;&gt;<br>
-       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;sqInt (*)(sqInt, sqInt)&#39;.<br>
        mergeFnwith.  &quot;null ref for compiler&quot;<br>
<br>
        ^ self mergeFn: sourceWord with: destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedAND:to:nBits:nPartitions: (in category &#39;combination rules&#39;) -----<br>
  partitionedAND: word1 to: word2 nBits: nBits nPartitions: nParts<br>
        &quot;AND word1 to word2 as nParts partitions of nBits each.<br>
        Any field of word1 not all-ones is treated as all-zeroes.<br>
        Used for erasing, eg, brush shapes prior to ORing in a color&quot;<br>
        | mask result |<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #word1 type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #word2 type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        mask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        result := 0.<br>
        1 to: nParts do:<br>
                [:i |<br>
                (word1 bitAnd: mask) = mask<br>
                        ifTrue: [result := result bitOr: (word2 bitAnd: mask)].<br>
                mask := mask &lt;&lt; nBits  &quot;slide left to next partition&quot;].<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedAdd:to:nBits:componentMask:carryOverflowMask: (in category &#39;combination rules&#39;) -----<br>
  partitionedAdd: word1 to: word2 nBits: nBits componentMask: componentMask carryOverflowMask: carryOverflowMask<br>
        &quot;Add word1 to word2 as nParts partitions of nBits each.<br>
        This is useful for packed pixels, or packed colors&quot;<br>
        | carryOverflow sum w1 w2 |<br>
        &quot;Use unsigned int everywhere because it has a well known arithmetic model without undefined behavior w.r.t. overflow and shifts&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
         &lt;var: #word1 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word2 type: &#39;unsigned int&#39;&gt;<br>
         &lt;var: #w1 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #w2 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #componentMask type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #carryOverflowMask type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #carryOverflow type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #sum type: &#39;unsigned int&#39;&gt;<br>
        w1 := word1 bitAnd: carryOverflowMask. &quot;mask to remove high bit of each component&quot;<br>
        w2 := word2 bitAnd: carryOverflowMask.<br>
        sum := (word1 bitXor: w1)+(word2 bitXor: w2). &quot;sum without high bit to avoid overflowing over next component&quot;<br>
        carryOverflow := (w1 bitAnd: w2) bitOr: ((w1 bitOr: w2) bitAnd: sum). &quot;detect overflow condition for saturating&quot;<br>
        ^((sum bitXor: w1)bitXor:w2) &quot;sum high bit without overflow&quot;<br>
                bitOr: carryOverflow&gt;&gt;(nBits-1) * componentMask &quot;saturate in case of overflow&quot;!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedMax:with:nBits:nPartitions: (in category &#39;combination rules&#39;) -----<br>
  partitionedMax: word1 with: word2 nBits: nBits nPartitions: nParts<br>
        &quot;Max word1 to word2 as nParts partitions of nBits each&quot;<br>
        | mask result |<br>
        &quot;In C, most arithmetic operations answer the same bit pattern regardless of the operands being signed or unsigned ints<br>
        (this is due to the way 2&#39;s complement numbers work). However, comparisions might fail. Add the proper declaration of<br>
        words as unsigned int in those cases where comparisions are done (jmv)&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word1 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word2 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #mask type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        mask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        result := 0.<br>
        1 to: nParts do:<br>
                [:i |<br>
                result := result bitOr: ((word2 bitAnd: mask) max: (word1 bitAnd: mask)).<br>
                mask := mask &lt;&lt; nBits  &quot;slide left to next partition&quot;].<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedMin:with:nBits:nPartitions: (in category &#39;combination rules&#39;) -----<br>
  partitionedMin: word1 with: word2 nBits: nBits nPartitions: nParts<br>
        &quot;Min word1 to word2 as nParts partitions of nBits each&quot;<br>
        | mask result |<br>
        &quot;In C, most arithmetic operations answer the same bit pattern regardless of the operands being signed or unsigned ints<br>
        (this is due to the way 2&#39;s complement numbers work). However, comparisions might fail. Add the proper declaration of<br>
        words as unsigned int in those cases where comparisions are done (jmv)&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word1 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word2 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #mask type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        mask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        result := 0.<br>
        1 to: nParts do:<br>
                [:i |<br>
                result := result bitOr: ((word2 bitAnd: mask) min: (word1 bitAnd: mask)).<br>
                mask := mask &lt;&lt; nBits  &quot;slide left to next partition&quot;].<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedMul:with:nBits:nPartitions: (in category &#39;combination rules&#39;) -----<br>
  partitionedMul: word1 with: word2 nBits: nBits nPartitions: nParts<br>
        &quot;Multiply word1 with word2 as nParts partitions of nBits each.<br>
        This is useful for packed pixels, or packed colors.<br>
        Bug in loop version when non-white background&quot;<br>
<br>
        | sMask product result dMask |<br>
        &quot;In C, integer multiplication might answer a wrong value if the unsigned values are declared as signed.<br>
        This problem does not affect this method, because the most significant bit (i.e. the sign bit) will<br>
        always be zero (jmv)&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #word1 type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #word2 type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #dMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #product type: &#39;unsigned int&#39;&gt;<br>
        sMask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        dMask :=  sMask &lt;&lt; nBits.<br>
        result := (((word1 bitAnd: sMask)+1) * ((word2 bitAnd: sMask)+1) - 1<br>
                                bitAnd: dMask) &gt;&gt; nBits.        &quot;optimized first step&quot;<br>
        nParts = 1<br>
                ifTrue: [ ^result ].<br>
        product := (((word1&gt;&gt;nBits bitAnd: sMask)+1) * ((word2&gt;&gt;nBits bitAnd: sMask)+1) - 1 bitAnd: dMask).<br>
        result := result bitOr: product.<br>
        nParts = 2<br>
                ifTrue: [ ^result ].<br>
        product := (((word1&gt;&gt;(2*nBits) bitAnd: sMask)+1) * ((word2&gt;&gt;(2*nBits) bitAnd: sMask)+1) - 1 bitAnd: dMask).<br>
        result := result bitOr: product &lt;&lt; nBits.<br>
        nParts = 3<br>
                ifTrue: [ ^result ].<br>
        product := (((word1&gt;&gt;(3*nBits) bitAnd: sMask)+1) * ((word2&gt;&gt;(3*nBits) bitAnd: sMask)+1) - 1 bitAnd: dMask).<br>
        result := result bitOr: product &lt;&lt; (2*nBits).<br>
        ^ result<br>
<br>
  &quot;     | sMask product result dMask |<br>
        sMask := maskTable at: nBits.  &#39;partition mask starts at the right&#39;<br>
        dMask :=  sMask &lt;&lt; nBits.<br>
        result := (((word1 bitAnd: sMask)+1) * ((word2 bitAnd: sMask)+1) - 1<br>
                                bitAnd: dMask) &gt;&gt; nBits.        &#39;optimized first step&#39;<br>
        nBits to: nBits * (nParts-1) by: nBits do: [:ofs |<br>
                product := (((word1&gt;&gt;ofs bitAnd: sMask)+1) * ((word2&gt;&gt;ofs bitAnd: sMask)+1) - 1 bitAnd: dMask).<br>
                result := result bitOr: (product bitAnd: dMask) &lt;&lt; (ofs-nBits)].<br>
        ^ result&quot;!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedRgbComponentAlpha:dest:nBits:nPartitions: (in category &#39;combination rules&#39;) -----<br>
  partitionedRgbComponentAlpha: sourceWord dest: destWord nBits: nBits nPartitions: nParts<br>
        | mask result p1 p2 v |<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #p1 type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #p2 type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #mask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        mask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        result := 0.<br>
        1 to: nParts do:<br>
                [:i |<br>
                p1 := (sourceWord bitAnd: mask) &gt;&gt; ((i - 1)*nBits).<br>
                p2 := (destWord bitAnd: mask) &gt;&gt; ((i - 1)*nBits).<br>
                nBits = 32<br>
                        ifFalse:[<br>
                                nBits = 16<br>
                                        ifTrue:[<br>
                                                p1 := (self rgbMap16To32: p1) bitOr: 16rFF000000.<br>
                                                p2 := (self rgbMap16To32: p2) bitOr: 16rFF000000]<br>
                                        ifFalse:[<br>
                                                p1 := (self rgbMap: p1 from: nBits to: 32) bitOr: 16rFF000000.<br>
                                                p2 := (self rgbMap: p2 from: nBits to: 32) bitOr: 16rFF000000.]].<br>
                v := self rgbComponentAlpha32: p1 with: p2.<br>
                nBits = 32<br>
                        ifFalse:[<br>
                                v := self rgbMap: v from: 32 to: nBits].<br>
                result := result bitOr: (v &lt;&lt;  ((i - 1)*nBits)).<br>
                mask := mask &lt;&lt; nBits  &quot;slide left to next partition&quot;].<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;partitionedSub:from:nBits:nPartitions: (in category &#39;combination rules&#39;) -----<br>
  partitionedSub: word1 from: word2 nBits: nBits nPartitions: nParts<br>
        &quot;Subtract word1 from word2 as nParts partitions of nBits each.<br>
        This is useful for packed pixels, or packed colors&quot;<br>
        | mask result p1 p2 |<br>
        &quot;In C, most arithmetic operations answer the same bit pattern regardless of the operands being signed or unsigned ints<br>
        (this is due to the way 2&#39;s complement numbers work). However, comparisions might fail. Add the proper declaration of<br>
        words as unsigned int in those cases where comparisions are done (jmv)&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word1 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #word2 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #p1 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #p2 type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #mask type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        mask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        result := 0.<br>
        1 to: nParts do:<br>
                [:i |<br>
                p1 := word1 bitAnd: mask.<br>
                p2 := word2 bitAnd: mask.<br>
                p1 &lt; p2  &quot;result is really abs value of thedifference&quot;<br>
                        ifTrue: [result := result bitOr: p2 - p1]<br>
                        ifFalse: [result := result bitOr: p1 - p2].<br>
                mask := mask &lt;&lt; nBits  &quot;slide left to next partition&quot;].<br>
        ^ result<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;pickSourcePixels:flags:srcMask:destMask:srcShiftInc:dstShiftInc: (in category &#39;combination rules&#39;) -----<br>
  pickSourcePixels: nPixels flags: mapperFlags srcMask: srcMask destMask: dstMask srcShiftInc: srcShiftInc dstShiftInc: dstShiftInc<br>
        &quot;Pick nPix pixels starting at srcBitIndex from the source, map by the<br>
        color map, and justify them according to dstBitIndex in the resulting destWord.&quot;<br>
        | sourceWord destWord sourcePix destPix srcShift dstShift nPix |<br>
        &lt;inline: true&gt; &quot;oh please&quot;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
        sourceWord := self srcLongAt: sourceIndex.<br>
        destWord := 0.<br>
        srcShift := srcBitShift. &quot;Hint: Keep in register&quot;<br>
        dstShift := dstBitShift. &quot;Hint: Keep in register&quot;<br>
        nPix := nPixels. &quot;always &gt; 0 so we can use do { } while(--nPix);&quot;<br>
        (mapperFlags = (ColorMapPresent bitOr: ColorMapIndexedPart)) ifTrue:[<br>
                &quot;a little optimization for (pretty crucial) blits using indexed lookups only&quot;<br>
                [       &quot;grab, colormap and mix in pixel&quot;<br>
                        sourcePix := sourceWord &gt;&gt; srcShift bitAnd: srcMask.<br>
                        destPix := cmLookupTable at: (sourcePix bitAnd: cmMask).<br>
                        destWord := destWord bitOr: (destPix bitAnd: dstMask) &lt;&lt; dstShift.<br>
                        &quot;adjust dest pix index&quot;<br>
                        dstShift := dstShift + dstShiftInc.<br>
                        &quot;adjust source pix index&quot;<br>
                        ((srcShift := srcShift + srcShiftInc) bitAnd: 16rFFFFFFE0) = 0 ifFalse:[<br>
                                sourceMSB ifTrue:[srcShift := srcShift + 32] ifFalse:[srcShift := srcShift - 32].<br>
                                sourceWord := self srcLongAt: (self incSrcIndex: 4)].<br>
                (nPix := nPix - 1) = 0] whileFalse.<br>
        ] ifFalse:[<br>
                [       &quot;grab, colormap and mix in pixel&quot;<br>
                        sourcePix := sourceWord &gt;&gt; srcShift bitAnd: srcMask.<br>
                        destPix := self mapPixel: sourcePix flags: mapperFlags.<br>
                        destWord := destWord bitOr: (destPix bitAnd: dstMask) &lt;&lt; dstShift.<br>
                        &quot;adjust dest pix index&quot;<br>
                        dstShift := dstShift + dstShiftInc.<br>
                        &quot;adjust source pix index&quot;<br>
                        ((srcShift := srcShift + srcShiftInc) bitAnd: 16rFFFFFFE0) = 0 ifFalse:[<br>
                                sourceMSB ifTrue:[srcShift := srcShift + 32] ifFalse:[srcShift := srcShift - 32].<br>
                                sourceWord := self srcLongAt: (self incSrcIndex: 4)].<br>
                (nPix := nPix - 1) = 0] whileFalse.<br>
        ].<br>
        srcBitShift := srcShift. &quot;Store back&quot;<br>
        ^destWord<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;pickWarpPixelAtX:y: (in category &#39;pixel mapping&#39;) -----<br>
  pickWarpPixelAtX: xx y: yy<br>
        &quot;Pick a single pixel from the source for WarpBlt.<br>
        Note: This method is crucial for WarpBlt speed w/o smoothing<br>
        and still relatively important when smoothing is used.&quot;<br>
        | x y srcIndex sourceWord sourcePix |<br>
        &lt;inline: true&gt; &quot;*please*&quot;<br>
+       &lt;returnTypeC: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
<br>
        &quot;note: it would be much faster if we could just<br>
        avoid these stupid tests for being inside sourceForm.&quot;<br>
        (xx &lt; 0 or:[yy &lt; 0 or:[<br>
                (x := xx &gt;&gt; BinaryPoint) &gt;= sourceWidth or:[<br>
                        (y := yy &gt;&gt; BinaryPoint) &gt;= sourceHeight]]]) ifTrue:[^0]. &quot;out of bounds&quot;<br>
<br>
        &quot;Fetch source word.<br>
        Note: We should really update srcIndex with sx and sy so that<br>
        we don&#39;t have to do the computation below. We might even be<br>
        able to simplify the out of bounds test from above.&quot;<br>
        srcIndex := sourceBits + (y * sourcePitch) + (x &gt;&gt; warpAlignShift * 4).<br>
        sourceWord := self srcLongAt: srcIndex.<br>
<br>
        &quot;Extract pixel from word&quot;<br>
        srcBitShift := warpBitShiftTable at: (x bitAnd: warpAlignMask).<br>
        sourcePix := sourceWord &gt;&gt; srcBitShift bitAnd: warpSrcMask.<br>
        ^sourcePix!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;pixClear:with: (in category &#39;combination rules&#39;) -----<br>
  pixClear: sourceWord with: destinationWord<br>
        &quot;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.&quot;<br>
        | mask result nBits pv |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #mask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #pv type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        destDepth = 32 ifTrue:[<br>
                sourceWord = destinationWord ifTrue:[^0] ifFalse:[^destinationWord].<br>
        ].<br>
        nBits := destDepth.<br>
        mask := maskTable at: nBits.  &quot;partition mask starts at the right&quot;<br>
        result := 0.<br>
        1 to: destPPW do:[:i |<br>
                pv := destinationWord bitAnd: mask.<br>
                (sourceWord bitAnd: mask) = pv ifTrue:[pv := 0].<br>
                result := result bitOr: pv.<br>
                mask := mask &lt;&lt; nBits &quot;slide left to next partition&quot;].<br>
        ^ result!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;pixMask:with: (in category &#39;combination rules&#39;) -----<br>
  pixMask: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^ self partitionedAND: sourceWord bitInvert32 to: destinationWord<br>
                                        nBits: destDepth nPartitions: destPPW!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;pixPaint:with: (in category &#39;combination rules&#39;) -----<br>
  pixPaint: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        sourceWord = 0 ifTrue: [^ destinationWord].<br>
        ^ sourceWord bitOr:<br>
                (self partitionedAND: sourceWord bitInvert32 to: destinationWord<br>
                                                nBits: destDepth nPartitions: destPPW)!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;pixSwap:with: (in category &#39;combination rules&#39;) -----<br>
  pixSwap: sourceWord with: destWord<br>
        &quot;Swap the pixels in destWord&quot;<br>
        | result shift lowMask highMask |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #lowMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #highMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #result type: &#39;unsigned int&#39;&gt;<br>
        destPPW = 1 ifTrue:[^destWord]. &quot;a single pixel per word&quot;<br>
        result := 0.<br>
        lowMask := (1 &lt;&lt; destDepth) - 1. &quot;mask low pixel&quot;<br>
        highMask := lowMask &lt;&lt; (destPPW-1 * destDepth). &quot;mask high pixel&quot;<br>
        shift := 32 - destDepth.<br>
        result := result bitOr: (<br>
                                (destWord bitAnd: lowMask) &lt;&lt; shift bitOr:<br>
                                        (destWord bitAnd: highMask) &gt;&gt; shift).<br>
        destPPW &lt;= 2 ifTrue:[^result].<br>
        2 to: destPPW // 2 do:[:i|<br>
                lowMask := lowMask &lt;&lt; destDepth.<br>
                highMask := highMask &gt;&gt; destDepth.<br>
                shift := shift - (destDepth * 2).<br>
                result := result bitOr: (<br>
                                        (destWord bitAnd: lowMask) &lt;&lt; shift bitOr:<br>
                                                (destWord bitAnd: highMask) &gt;&gt; shift)].<br>
        ^result!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbAdd:with: (in category &#39;combination rules&#39;) -----<br>
  rgbAdd: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #carryOverflowMask type: &#39;unsigned int&#39;&gt;<br>
        &lt;var: #componentMask type: &#39;unsigned int&#39;&gt;<br>
        | componentMask carryOverflowMask |<br>
        destDepth &lt; 16 ifTrue:<br>
                [&quot;Add each pixel separately&quot;<br>
                componentMask := 1&lt;&lt;destDepth-1.<br>
                carryOverflowMask := 16rFFFFFFFF//componentMask&lt;&lt;(destDepth-1).<br>
                ^ self partitionedAdd: sourceWord to: destinationWord<br>
                                                nBits: destDepth componentMask: componentMask carryOverflowMask: carryOverflowMask].<br>
        destDepth = 16 ifTrue:<br>
                [&quot;Add RGB components of each pixel separately&quot;<br>
                componentMask := 16r1F.<br>
                carryOverflowMask := 16r42104210.<br>
                ^ (self partitionedAdd: (sourceWord bitAnd: 16r7FFF7FFF) to: (destinationWord bitAnd: 16r7FFF7FFF) &quot;make sure that the unused bit is at 0&quot;<br>
                                                nBits: 5 componentMask: componentMask carryOverflowMask: carryOverflowMask)]<br>
        ifFalse:<br>
                [&quot;Add RGBA components of the pixel separately&quot;<br>
                componentMask := 16rFF.<br>
                carryOverflowMask := 16r80808080.<br>
                ^ self partitionedAdd: sourceWord to: destinationWord<br>
                                                nBits: 8 componentMask: componentMask carryOverflowMask: carryOverflowMask]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbComponentAlpha16 (in category &#39;combination rules&#39;) -----<br>
  rgbComponentAlpha16<br>
        &quot;This version assumes<br>
                combinationRule = 41<br>
                sourcePixSize = 32<br>
                destPixSize = 16<br>
                sourceForm ~= destForm.<br>
        &quot;<br>
        &lt;inline: false&gt;  &quot;This particular method should be optimized in itself&quot;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #dstMask type: #&#39;unsigned int&#39;&gt;<br>
<br>
        | srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY<br>
        srcY dstY dstMask srcShift ditherBase ditherIndex ditherThreshold |<br>
<br>
        deltaY := bbH + 1. &quot;So we can pre-decrement&quot;<br>
        srcY := sy.<br>
        dstY := dy.<br>
        srcShift := (dx bitAnd: 1) * 16.<br>
        destMSB ifTrue:[srcShift := 16 - srcShift].<br>
        mask1 := 16rFFFF &lt;&lt; (16 - srcShift).<br>
        &quot;This is the outer loop&quot;<br>
        [(deltaY := deltaY - 1) ~= 0] whileTrue:[<br>
                srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).<br>
                dstIndex := destBits + (dstY * destPitch) + (dx // 2 * 4).<br>
                ditherBase := (dstY bitAnd: 3) * 4.<br>
                ditherIndex := (sx bitAnd: 3) - 1. &quot;For pre-increment&quot;<br>
                deltaX := bbW + 1. &quot;So we can pre-decrement&quot;<br>
                dstMask := mask1.<br>
                dstMask = 16rFFFF ifTrue:[srcShift := 16] ifFalse:[srcShift := 0].<br>
<br>
                &quot;This is the inner loop&quot;<br>
                [(deltaX := deltaX - 1) ~= 0] whileTrue:[<br>
                        ditherThreshold := ditherMatrix4x4 at: ditherBase + (ditherIndex := ditherIndex + 1 bitAnd: 3).<br>
                        sourceWord := self srcLongAt: srcIndex.<br>
                        srcAlpha := sourceWord bitAnd: 16rFFFFFF.<br>
                                srcAlpha = 0 ifFalse:[ &quot;0 &lt; srcAlpha&quot;<br>
                                        &quot;If we have to mix colors then just copy a single word&quot;<br>
                                        destWord := self dstLongAt: dstIndex.<br>
                                        destWord := destWord bitAnd: dstMask bitInvert32.<br>
                                        destWord := destWord &gt;&gt; srcShift.<br>
                                        &quot;Expand from 16 to 32 bit by adding zero bits&quot;<br>
                                        destWord := (((destWord bitAnd: 16r7C00) bitShift: 9) bitOr:<br>
                                                                        ((destWord bitAnd: 16r3E0) bitShift: 6)) bitOr:<br>
                                                                (((destWord bitAnd: 16r1F) bitShift: 3) bitOr:<br>
                                                                        16rFF000000).<br>
                                        &quot;Mix colors&quot;<br>
                                        sourceWord := self rgbComponentAlpha32: sourceWord with: destWord.<br>
                                        &quot;And dither&quot;<br>
                                        sourceWord := self dither32To16: sourceWord threshold: ditherThreshold.<br>
                                        sourceWord = 0<br>
                                                ifTrue:[sourceWord := 1 &lt;&lt; srcShift]<br>
                                                ifFalse:[sourceWord := sourceWord &lt;&lt; srcShift].<br>
                                        &quot;Store back&quot;<br>
                                        self dstLongAt: dstIndex put: sourceWord mask: dstMask.<br>
                                ].<br>
                        srcIndex := srcIndex + 4.<br>
                        destMSB<br>
                                ifTrue:[srcShift = 0 ifTrue:[dstIndex := dstIndex + 4]]<br>
                                ifFalse:[srcShift = 0 ifFalse:[dstIndex := dstIndex + 4]].<br>
                        srcShift := srcShift bitXor: 16. &quot;Toggle between 0 and 16&quot;<br>
                        dstMask := dstMask bitInvert32. &quot;Mask other half word&quot;<br>
                ].<br>
                srcY := srcY + 1.<br>
                dstY := dstY + 1.<br>
        ].<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbComponentAlpha32 (in category &#39;combination rules&#39;) -----<br>
  rgbComponentAlpha32<br>
        &quot;This version assumes<br>
                combinationRule = 41<br>
                sourcePixSize = destPixSize = 32<br>
                sourceForm ~= destForm.<br>
        Note: The inner loop has been optimized for dealing<br>
                with the special case of aR = aG = aB = 0<br>
        &quot;<br>
        | srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY srcY dstY |<br>
<br>
        &lt;inline: false&gt; &quot;This particular method should be optimized in itself&quot;<br>
<br>
        &quot;Give the compile a couple of hints&quot;<br>
-       &lt;var: #sourceWord type: &#39;register long&#39;&gt;<br>
        &lt;var: #deltaX type: &#39;register long&#39;&gt;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
<br>
        &quot;The following should be declared as pointers so the compiler will<br>
        notice that they&#39;re used for accessing memory locations<br>
        (good to know on an Intel architecture) but then the increments<br>
        would be different between ST code and C code so must hope the<br>
        compiler notices what happens (MS Visual C does)&quot;<br>
        &lt;var: #srcIndex type: &#39;register long&#39;&gt;<br>
        &lt;var: #dstIndex type: &#39;register long&#39;&gt;<br>
<br>
        deltaY := bbH + 1. &quot;So we can pre-decrement&quot;<br>
        srcY := sy.<br>
        dstY := dy.<br>
<br>
        &quot;This is the outer loop&quot;<br>
        [(deltaY := deltaY - 1) ~= 0] whileTrue:[<br>
                srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).<br>
                dstIndex := destBits + (dstY * destPitch) + (dx * 4).<br>
                deltaX := bbW + 1. &quot;So we can pre-decrement&quot;<br>
<br>
                &quot;This is the inner loop&quot;<br>
                [(deltaX := deltaX - 1) ~= 0] whileTrue:[<br>
                        sourceWord := self srcLongAt: srcIndex.<br>
                        srcAlpha := sourceWord bitAnd:16rFFFFFF.<br>
                                srcAlpha = 0 ifTrue:[<br>
                                        srcIndex := srcIndex + 4.<br>
                                        dstIndex := dstIndex + 4.<br>
                                        &quot;Now skip as many words as possible,&quot;<br>
                                        [(deltaX := deltaX - 1) ~= 0 and:[<br>
                                                ((sourceWord := self srcLongAt: srcIndex) bitAnd:16rFFFFFF) = 0]]<br>
                                                whileTrue:[<br>
                                                        srcIndex := srcIndex + 4.<br>
                                                        dstIndex := dstIndex + 4.<br>
                                                ].<br>
                                        &quot;Adjust deltaX&quot;<br>
                                        deltaX := deltaX + 1.<br>
                                ] ifFalse:[ &quot;0 &lt; srcAlpha&quot;<br>
                                        &quot;If we have to mix colors then just copy a single word&quot;<br>
                                        destWord := self dstLongAt: dstIndex.<br>
                                        destWord := self rgbComponentAlpha32: sourceWord with: destWord.<br>
                                        self dstLongAt: dstIndex put: destWord.<br>
                                        srcIndex := srcIndex + 4.<br>
                                        dstIndex := dstIndex + 4.<br>
                                ].<br>
                ].<br>
                srcY := srcY + 1.<br>
                dstY := dstY + 1.<br>
        ].!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbComponentAlpha8 (in category &#39;combination rules&#39;) -----<br>
  rgbComponentAlpha8<br>
        &quot;This version assumes<br>
                combinationRule = 41<br>
                sourcePixSize = 32<br>
                destPixSize = 8<br>
                sourceForm ~= destForm.<br>
        Note: This is not real blending since we don&#39;t have the source colors available.<br>
        &quot;<br>
<br>
        | srcIndex dstIndex sourceWord srcAlpha destWord deltaX deltaY<br>
        srcY dstY dstMask srcShift adjust mappingTable mapperFlags |<br>
<br>
        &lt;inline: false&gt;  &quot;This particular method should be optimized in itself&quot;<br>
        &lt;var: #mappingTable declareC:&#39;unsigned int *mappingTable&#39;&gt;<br>
+       &lt;var: #sourceWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #dstMask type: #&#39;unsigned int&#39;&gt;<br>
<br>
        mappingTable := self default8To32Table.<br>
        mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.<br>
        deltaY := bbH + 1. &quot;So we can pre-decrement&quot;<br>
        srcY := sy.<br>
        dstY := dy.<br>
        mask1 := ((dx bitAnd: 3) * 8).<br>
        destMSB ifTrue:[mask1 := 24 - mask1].<br>
        mask2 := AllOnes bitXor:(16rFF &lt;&lt; mask1).<br>
        (dx bitAnd: 1) = 0<br>
                ifTrue:[adjust := 0]<br>
                ifFalse:[adjust := 16r1F1F1F1F].<br>
        (dy bitAnd: 1) = 0<br>
                ifTrue:[adjust := adjust bitXor: 16r1F1F1F1F].<br>
        &quot;This is the outer loop&quot;<br>
        [(deltaY := deltaY - 1) ~= 0] whileTrue:[<br>
                adjust := adjust bitXor: 16r1F1F1F1F.<br>
                srcIndex := sourceBits + (srcY * sourcePitch) + (sx * 4).<br>
                dstIndex := destBits + (dstY * destPitch) + (dx // 4 * 4).<br>
                deltaX := bbW + 1. &quot;So we can pre-decrement&quot;<br>
                srcShift := mask1.<br>
                dstMask := mask2.<br>
<br>
                &quot;This is the inner loop&quot;<br>
                [(deltaX := deltaX - 1) ~= 0] whileTrue:[<br>
                        sourceWord := ((self srcLongAt: srcIndex) bitAnd: (adjust bitInvert32)) + adjust.<br>
                        srcAlpha := sourceWord bitAnd: 16rFFFFFF.<br>
                        &quot;set srcAlpha to the average of the 3 separate aR,Ag,AB values&quot;<br>
                        srcAlpha := ((srcAlpha &gt;&gt; 16) + (srcAlpha &gt;&gt; 8 bitAnd: 16rFF) + (srcAlpha bitAnd: 16rFF)) // 3.<br>
                        srcAlpha &gt; 31 ifTrue:[&quot;Everything below 31 is transparent&quot;<br>
                                srcAlpha &gt; 224<br>
                                        ifTrue: [&quot;treat everything above 224 as opaque&quot;<br>
                                                sourceWord := 16rFFFFFFFF].<br>
                                destWord := self dstLongAt: dstIndex.<br>
                                destWord := destWord bitAnd: dstMask bitInvert32.<br>
                                destWord := destWord &gt;&gt; srcShift.<br>
                                destWord := mappingTable at: destWord.<br>
                                sourceWord := self rgbComponentAlpha32: sourceWord with: destWord.<br>
                                sourceWord := self mapPixel: sourceWord flags: mapperFlags.<br>
                                sourceWord := sourceWord &lt;&lt; srcShift.<br>
                                &quot;Store back&quot;<br>
                                self dstLongAt: dstIndex put: sourceWord mask: dstMask.<br>
                        ].<br>
                        srcIndex := srcIndex + 4.<br>
                        destMSB ifTrue:[<br>
                                srcShift = 0<br>
                                        ifTrue:[dstIndex := dstIndex + 4.<br>
                                                        srcShift := 24.<br>
                                                        dstMask := 16r00FFFFFF]<br>
                                        ifFalse:[srcShift := srcShift - 8.<br>
                                                        dstMask := (dstMask &gt;&gt; 8) bitOr: 16rFF000000].<br>
                        ] ifFalse:[<br>
                                srcShift = 32<br>
                                        ifTrue:[dstIndex := dstIndex + 4.<br>
                                                        srcShift := 0.<br>
                                                        dstMask := 16rFFFFFF00]<br>
                                        ifFalse:[srcShift := srcShift + 8.<br>
                                                        dstMask := dstMask &lt;&lt; 8 bitOr: 255].<br>
                        ].<br>
                        adjust := adjust bitXor: 16r1F1F1F1F.<br>
                ].<br>
                srcY := srcY + 1.<br>
                dstY := dstY + 1.<br>
        ].<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbDiff:with: (in category &#39;combination rules&#39;) -----<br>
  rgbDiff: sourceWord with: destinationWord<br>
        &quot;Subract the pixels in the source and destination, color by color,<br>
        and return the sum of the absolute value of all the differences.<br>
        For non-rgb, return the number of differing pixels.&quot;<br>
        | pixMask destShifted sourceShifted destPixVal bitsPerColor rgbMask sourcePixVal diff maskShifted |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #maskShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #pixMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #rgbMask type: &#39;unsigned int&#39;&gt;<br>
        pixMask := maskTable at: destDepth.<br>
        destDepth = 16<br>
                ifTrue: [bitsPerColor := 5.  rgbMask := 16r1F]<br>
                ifFalse: [bitsPerColor := 8.  rgbMask := 16rFF].<br>
        maskShifted := destMask.<br>
        destShifted := destinationWord.<br>
        sourceShifted := sourceWord.<br>
        1 to: destPPW do:<br>
                [:i |<br>
                (maskShifted bitAnd: pixMask) &gt; 0 ifTrue:<br>
                        [&quot;Only tally pixels within the destination rectangle&quot;<br>
                        destPixVal := destShifted bitAnd: pixMask.<br>
                        sourcePixVal := sourceShifted bitAnd: pixMask.<br>
                        destDepth &lt; 16<br>
                                ifTrue: [sourcePixVal = destPixVal<br>
                                                        ifTrue: [diff := 0]<br>
                                                        ifFalse: [diff := 1]]<br>
                                ifFalse: [diff := (self partitionedSub: sourcePixVal from: destPixVal<br>
                                                                nBits: bitsPerColor nPartitions: 3).<br>
                                                diff := (diff bitAnd: rgbMask)<br>
                                                        + (diff&gt;&gt;bitsPerColor bitAnd: rgbMask)<br>
                                                        + ((diff&gt;&gt;bitsPerColor)&gt;&gt;bitsPerColor bitAnd: rgbMask)].<br>
                        bitCount := bitCount + diff].<br>
                maskShifted := maskShifted &gt;&gt; destDepth.<br>
                sourceShifted := sourceShifted &gt;&gt; destDepth.<br>
                destShifted := destShifted &gt;&gt; destDepth].<br>
        ^ destinationWord  &quot;For no effect on dest&quot;<br>
  !<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbMax:with: (in category &#39;combination rules&#39;) -----<br>
  rgbMax: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        destDepth &lt; 16 ifTrue:<br>
                [&quot;Max each pixel separately&quot;<br>
                ^ self partitionedMax: sourceWord with: destinationWord<br>
                                                nBits: destDepth nPartitions: destPPW].<br>
        destDepth = 16 ifTrue:<br>
                [&quot;Max RGB components of each pixel separately&quot;<br>
                ^ (self partitionedMax: sourceWord with: destinationWord<br>
                                                nBits: 5 nPartitions: 3)<br>
                + ((self partitionedMax: sourceWord&gt;&gt;16 with: destinationWord&gt;&gt;16<br>
                                                nBits: 5 nPartitions: 3) &lt;&lt; 16)]<br>
        ifFalse:<br>
                [&quot;Max RGBA components of the pixel separately&quot;<br>
                ^ self partitionedMax: sourceWord with: destinationWord<br>
                                                nBits: 8 nPartitions: 4]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbMin:with: (in category &#39;combination rules&#39;) -----<br>
  rgbMin: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        destDepth &lt; 16 ifTrue:<br>
                [&quot;Min each pixel separately&quot;<br>
                ^ self partitionedMin: sourceWord with: destinationWord<br>
                                                nBits: destDepth nPartitions: destPPW].<br>
        destDepth = 16 ifTrue:<br>
                [&quot;Min RGB components of each pixel separately&quot;<br>
                ^ (self partitionedMin: sourceWord with: destinationWord<br>
                                                nBits: 5 nPartitions: 3)<br>
                + ((self partitionedMin: sourceWord&gt;&gt;16 with: destinationWord&gt;&gt;16<br>
                                                nBits: 5 nPartitions: 3) &lt;&lt; 16)]<br>
        ifFalse:<br>
                [&quot;Min RGBA components of the pixel separately&quot;<br>
                ^ self partitionedMin: sourceWord with: destinationWord<br>
                                                nBits: 8 nPartitions: 4]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbMinInvert:with: (in category &#39;combination rules&#39;) -----<br>
  rgbMinInvert: wordToInvert with: destinationWord<br>
        | sourceWord |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #wordToInvert type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        sourceWord := wordToInvert bitInvert32.<br>
        destDepth &lt; 16 ifTrue:<br>
                [&quot;Min each pixel separately&quot;<br>
                ^ self partitionedMin: sourceWord with: destinationWord<br>
                                                nBits: destDepth nPartitions: destPPW].<br>
        destDepth = 16 ifTrue:<br>
                [&quot;Min RGB components of each pixel separately&quot;<br>
                ^ (self partitionedMin: sourceWord with: destinationWord<br>
                                                nBits: 5 nPartitions: 3)<br>
                + ((self partitionedMin: sourceWord&gt;&gt;16 with: destinationWord&gt;&gt;16<br>
                                                nBits: 5 nPartitions: 3) &lt;&lt; 16)]<br>
        ifFalse:<br>
                [&quot;Min RGBA components of the pixel separately&quot;<br>
                ^ self partitionedMin: sourceWord with: destinationWord<br>
                                                nBits: 8 nPartitions: 4]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbMul:with: (in category &#39;combination rules&#39;) -----<br>
  rgbMul: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        destDepth &lt; 16 ifTrue:<br>
                [&quot;Mul each pixel separately&quot;<br>
                ^ self partitionedMul: sourceWord with: destinationWord<br>
                                                nBits: destDepth nPartitions: destPPW].<br>
        destDepth = 16 ifTrue:<br>
                [&quot;Mul RGB components of each pixel separately&quot;<br>
                ^ (self partitionedMul: sourceWord with: destinationWord<br>
                                                nBits: 5 nPartitions: 3)<br>
                + ((self partitionedMul: sourceWord&gt;&gt;16 with: destinationWord&gt;&gt;16<br>
                                                nBits: 5 nPartitions: 3) &lt;&lt; 16)]<br>
        ifFalse:<br>
                [&quot;Mul RGBA components of the pixel separately&quot;<br>
                ^ self partitionedMul: sourceWord with: destinationWord<br>
                                                nBits: 8 nPartitions: 4]<br>
<br>
  &quot;     | scanner |<br>
        Display repaintMorphicDisplay.<br>
        scanner := DisplayScanner quickPrintOn: Display.<br>
        MessageTally time: [0 to: 760 by: 4 do:  [:y |scanner drawString: &#39;qwrepoiuasfd=)(/&amp;()=#!!〕kjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,Mqwrepoiuasfd=)(/&amp;()=#!!〕kjzxv.,mn124+09857907QROIYTOAFDJZXNBNB,M-.,M1234124356785678&#39; at: 0@y]]. &quot;!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;rgbSub:with: (in category &#39;combination rules&#39;) -----<br>
  rgbSub: sourceWord with: destinationWord<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        destDepth &lt; 16 ifTrue:<br>
                [&quot;Sub each pixel separately&quot;<br>
                ^ self partitionedSub: sourceWord from: destinationWord<br>
                                                nBits: destDepth nPartitions: destPPW].<br>
        destDepth = 16 ifTrue:<br>
                [&quot;Sub RGB components of each pixel separately&quot;<br>
                ^ (self partitionedSub: sourceWord from: destinationWord<br>
                                                nBits: 5 nPartitions: 3)<br>
                + ((self partitionedSub: sourceWord&gt;&gt;16 from: destinationWord&gt;&gt;16<br>
                                                nBits: 5 nPartitions: 3) &lt;&lt; 16)]<br>
        ifFalse:<br>
                [&quot;Sub RGBA components of the pixel separately&quot;<br>
                ^ self partitionedSub: sourceWord from: destinationWord<br>
                                                nBits: 8 nPartitions: 4]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;sourceWord:with: (in category &#39;combination rules&#39;) -----<br>
  sourceWord: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;subWord:with: (in category &#39;combination rules&#39;) -----<br>
  subWord: sourceWord with: destinationWord<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
        ^sourceWord - destinationWord!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;tallyIntoMap:with: (in category &#39;combination rules&#39;) -----<br>
  tallyIntoMap: sourceWord with: destinationWord<br>
        &quot;Tally pixels into the color map.  Those tallied are exactly those<br>
        in the destination rectangle.  Note that the source should be<br>
        specified == destination, in order for the proper color map checks<br>
        to be performed at setup.&quot;<br>
        | mapIndex pixMask destShifted maskShifted pixVal |<br>
        &lt;inline: false&gt;<br>
+       &lt;returnTypeC: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #sourceWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destinationWord type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #pixMask type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destShifted type: &#39;unsigned int&#39;&gt;<br>
+       &lt;var: #maskShifted type: &#39;unsigned int&#39;&gt;<br>
        (cmFlags bitAnd: (ColorMapPresent bitOr: ColorMapIndexedPart)) =<br>
                (ColorMapPresent bitOr: ColorMapIndexedPart)<br>
                        ifFalse: [^ destinationWord &quot;no op&quot;].<br>
        pixMask := maskTable at: destDepth.<br>
        destShifted := destinationWord.<br>
        maskShifted := destMask.<br>
        1 to: destPPW do:<br>
                [:i |<br>
                (maskShifted bitAnd: pixMask) = 0 ifFalse:<br>
                        [&quot;Only tally pixels within the destination rectangle&quot;<br>
                        pixVal := destShifted bitAnd: pixMask.<br>
                        destDepth &lt; 16<br>
                                ifTrue: [mapIndex := pixVal]<br>
                                ifFalse: [destDepth = 16<br>
                                        ifTrue: [mapIndex := self rgbMap: pixVal from: 5 to: cmBitsPerColor]<br>
                                        ifFalse: [mapIndex := self rgbMap: pixVal from: 8 to: cmBitsPerColor]].<br>
                        self tallyMapAt: mapIndex put: (self tallyMapAt: mapIndex) + 1].<br>
                maskShifted := maskShifted &gt;&gt; destDepth.<br>
                destShifted := destShifted &gt;&gt; destDepth].<br>
        ^ destinationWord  &quot;For no effect on dest&quot;!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;warpLoop (in category &#39;inner loop&#39;) -----<br>
  warpLoop<br>
        &quot;This version of the inner loop traverses an arbirary quadrilateral<br>
        source, thus producing a general affine transformation.&quot;<br>
        | skewWord halftoneWord mergeWord startBits<br>
          deltaP12x deltaP12y deltaP43x deltaP43y pAx pAy pBx pBy<br>
          xDelta yDelta smoothingCount sourceMapOop<br>
          nSteps nPix words destWord endBits mergeFnwith dstShiftInc dstShiftLeft mapperFlags |<br>
+       &lt;inline: false&gt;<br>
+       &lt;var: #mergeFnwith declareC: &#39;unsigned int (*mergeFnwith)(unsigned int, unsigned int)&#39;&gt;<br>
+       &lt;var: #skewWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #halftoneWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #mergeWord type: #&#39;unsigned int&#39;&gt;<br>
+       &lt;var: #destWord type: #&#39;unsigned int&#39;&gt;<br>
+       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;unsigned int (*)(unsigned int, unsigned int)&#39;.<br>
-       &lt;inline: false&gt;<br>
-       &lt;var: #mergeFnwith declareC: &#39;sqInt (*mergeFnwith)(sqInt, sqInt)&#39;&gt;<br>
-       mergeFnwith := self cCoerce: (opTable at: combinationRule+1) to: &#39;sqInt (*)(sqInt, sqInt)&#39;.<br>
        mergeFnwith.  &quot;null ref for compiler&quot;<br>
<br>
        (interpreterProxy slotSizeOf: bitBltOop) &gt;= (BBWarpBase+12)<br>
                ifFalse: [^ interpreterProxy primitiveFail].<br>
        nSteps := height-1.  nSteps &lt;= 0 ifTrue: [nSteps := 1].<br>
<br>
        pAx := self fetchIntOrFloat: BBWarpBase ofObject: bitBltOop.<br>
        words := self fetchIntOrFloat: BBWarpBase+3 ofObject: bitBltOop.<br>
        deltaP12x := self deltaFrom: pAx to: words nSteps: nSteps.<br>
        deltaP12x &lt; 0 ifTrue: [pAx := words - (nSteps*deltaP12x)].<br>
<br>
        pAy := self fetchIntOrFloat: BBWarpBase+1 ofObject: bitBltOop.<br>
        words := self fetchIntOrFloat: BBWarpBase+4 ofObject: bitBltOop.<br>
        deltaP12y := self deltaFrom: pAy to: words nSteps: nSteps.<br>
        deltaP12y &lt; 0 ifTrue: [pAy := words - (nSteps*deltaP12y)].<br>
<br>
        pBx := self fetchIntOrFloat: BBWarpBase+9 ofObject: bitBltOop.<br>
        words := self fetchIntOrFloat: BBWarpBase+6 ofObject: bitBltOop.<br>
        deltaP43x := self deltaFrom: pBx to: words nSteps: nSteps.<br>
        deltaP43x &lt; 0 ifTrue: [pBx := words - (nSteps*deltaP43x)].<br>
<br>
        pBy := self fetchIntOrFloat: BBWarpBase+10 ofObject: bitBltOop.<br>
        words := self fetchIntOrFloat: BBWarpBase+7 ofObject: bitBltOop.<br>
        deltaP43y := self deltaFrom: pBy to: words nSteps: nSteps.<br>
        deltaP43y &lt; 0 ifTrue: [pBy := words - (nSteps*deltaP43y)].<br>
<br>
        interpreterProxy failed ifTrue: [^ false].  &quot;ie if non-integers above&quot;<br>
        interpreterProxy methodArgumentCount = 2<br>
                ifTrue: [smoothingCount := interpreterProxy stackIntegerValue: 1.<br>
                                sourceMapOop := interpreterProxy stackValue: 0.<br>
                                sourceMapOop = interpreterProxy nilObject<br>
                                ifTrue: [sourceDepth &lt; 16 ifTrue:<br>
                                        [&quot;color map is required to smooth non-RGB dest&quot;<br>
                                        ^ interpreterProxy primitiveFail]]<br>
                                ifFalse: [(interpreterProxy slotSizeOf: sourceMapOop)<br>
                                                        &lt; (1 &lt;&lt; sourceDepth) ifTrue:<br>
                                        [&quot;sourceMap must be long enough for sourceDepth&quot;<br>
                                        ^ interpreterProxy primitiveFail].<br>
                                        sourceMapOop := self oopForPointer: (interpreterProxy firstIndexableField: sourceMapOop)]]<br>
                ifFalse: [smoothingCount := 1.<br>
                                sourceMapOop := interpreterProxy nilObject].<br>
        nSteps := width-1.  nSteps &lt;= 0 ifTrue: [nSteps := 1].<br>
        startBits := destPPW - (dx bitAnd: destPPW-1).<br>
        endBits := ((dx + bbW - 1) bitAnd: destPPW-1) + 1.<br>
        bbW &lt; startBits ifTrue:[startBits := bbW].<br>
<br>
        destY &lt; clipY ifTrue:[<br>
                &quot;Advance increments if there was clipping in y&quot;<br>
                pAx := pAx + (clipY - destY * deltaP12x).<br>
                pAy := pAy + (clipY - destY * deltaP12y).<br>
                pBx := pBx + (clipY - destY * deltaP43x).<br>
                pBy := pBy + (clipY - destY * deltaP43y)].<br>
<br>
        &quot;Setup values for faster pixel fetching.&quot;<br>
        self warpLoopSetup.<br>
        &quot;Setup color mapping if not provided&quot;<br>
        (smoothingCount &gt; 1 and:[(cmFlags bitAnd: ColorMapNewStyle) = 0]) ifTrue:[<br>
                cmLookupTable == nil ifTrue:[<br>
                        destDepth = 16 ifTrue:[self setupColorMasksFrom: 8 to: 5].<br>
                ] ifFalse:[<br>
                        self setupColorMasksFrom: 8 to: cmBitsPerColor.<br>
                ].<br>
        ].<br>
        mapperFlags := cmFlags bitAnd: ColorMapNewStyle bitInvert32.<br>
<br>
        destMSB<br>
                ifTrue:[        dstShiftInc := 0 - destDepth.<br>
                                dstShiftLeft := 32 - destDepth]<br>
                ifFalse:[       dstShiftInc := destDepth.<br>
                                dstShiftLeft := 0].<br>
        1 to: bbH do:<br>
                [ :i | &quot;here is the vertical loop...&quot;<br>
                xDelta := self deltaFrom: pAx to: pBx nSteps: nSteps.<br>
                xDelta &gt;= 0 ifTrue: [sx := pAx] ifFalse: [sx := pBx - (nSteps*xDelta)].<br>
                yDelta := self deltaFrom: pAy to: pBy nSteps: nSteps.<br>
                yDelta &gt;= 0 ifTrue: [sy := pAy] ifFalse: [sy := pBy - (nSteps*yDelta)].<br>
<br>
                destMSB<br>
                        ifTrue:[dstBitShift := 32 - ((dx bitAnd: destPPW - 1) + 1 * destDepth)]<br>
                        ifFalse:[dstBitShift := (dx bitAnd: destPPW - 1) * destDepth].<br>
<br>
                (destX &lt; clipX) ifTrue:[<br>
                        &quot;Advance increments if there was clipping in x&quot;<br>
                        sx := sx + (clipX - destX * xDelta).<br>
                        sy := sy + (clipX - destX * yDelta).<br>
                ].<br>
<br>
                noHalftone<br>
                        ifTrue: [halftoneWord := AllOnes]<br>
                        ifFalse: [halftoneWord := self halftoneAt: dy+i-1].<br>
                destMask := mask1.<br>
                nPix := startBits.<br>
                &quot;Here is the inner loop...&quot;<br>
                words := nWords.<br>
                        [&quot;pick up word&quot;<br>
                        smoothingCount = 1 ifTrue:[&quot;Faster if not smoothing&quot;<br>
                                skewWord := self warpPickSourcePixels: nPix<br>
                                                                xDeltah: xDelta yDeltah: yDelta<br>
                                                                xDeltav: deltaP12x yDeltav: deltaP12y<br>
                                                                dstShiftInc: dstShiftInc flags: mapperFlags.<br>
                        ] ifFalse:[&quot;more difficult with smoothing&quot;<br>
                                skewWord := self warpPickSmoothPixels: nPix<br>
                                                xDeltah: xDelta yDeltah: yDelta<br>
                                                xDeltav: deltaP12x yDeltav: deltaP12y<br>
                                                sourceMap: sourceMapOop<br>
                                                smoothing: smoothingCount<br>
                                                dstShiftInc: dstShiftInc.<br>
                        ].<br>
                        &quot;align next word access to left most pixel&quot;<br>
                        dstBitShift := dstShiftLeft.<br>
                        destMask = AllOnes ifTrue:[&quot;avoid read-modify-write&quot;<br>
                                mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)<br>
                                                                with: (self dstLongAt: destIndex).<br>
                                self dstLongAt: destIndex put: (destMask bitAnd: mergeWord).<br>
                        ] ifFalse:[ &quot;General version using dest masking&quot;<br>
                                destWord := self dstLongAt: destIndex.<br>
                                mergeWord := self mergeFn: (skewWord bitAnd: halftoneWord)<br>
                                                                with: (destWord bitAnd: destMask).<br>
                                destWord := (destMask bitAnd: mergeWord) bitOr:<br>
                                                                (destWord bitAnd: destMask bitInvert32).<br>
                                self dstLongAt: destIndex put: destWord.<br>
                        ].<br>
                        self incDestIndex: 4.<br>
                        words = 2 &quot;e.g., is the next word the last word?&quot;<br>
                                ifTrue:[&quot;set mask for last word in this row&quot;<br>
                                                destMask := mask2.<br>
                                                nPix := endBits]<br>
                                ifFalse:[&quot;use fullword mask for inner loop&quot;<br>
                                                destMask := AllOnes.<br>
                                                nPix := destPPW].<br>
                        (words := words - 1) = 0] whileFalse.<br>
                &quot;--- end of inner loop ---&quot;<br>
                pAx := pAx + deltaP12x.<br>
                pAy := pAy + deltaP12y.<br>
                pBx := pBx + deltaP43x.<br>
                pBy := pBy + deltaP43y.<br>
                self incDestIndex: destDelta]!<br>
<br>
Item was changed:<br>
  ----- Method: BitBltSimulation&gt;&gt;warpPickSmoothPixels:xDeltah:yDeltah:xDeltav:yDeltav:sourceMap:smoothing:dstShiftInc: (in category &#39;pixel mapping&#39;) -----<br>
  warpPickSmoothPixels: nPixels<br>
        xDeltah: xDeltah yDeltah: yDeltah<br>
        xDeltav: xDeltav yDeltav: yDeltav<br>
        sourceMap: sourceMap<br>
        smoothing: n<br>
        dstShiftInc: dstShiftInc<br>
        &quot;Pick n (sub-) pixels from the source form, mapped by sourceMap,<br>
        average the RGB values, map by colorMap and return the new word.<br>
        This version is only called from WarpBlt with smoothingCount &gt; 1&quot;<br>
        | rgb x y a r g b xx yy xdh ydh xdv ydv dstMask destWord i j k nPix |<br>
        &lt;inline: false&gt; &quot;nope - too much stuff in here&quot;<br>
+       &lt;var: #rgb type: #&#39;unsigned int&#39;&gt;<br>
        dstMask := maskTable at: destDepth.<br>
        destWord := 0.<br>
        n = 2 &quot;Try avoiding divides for most common n (divide by 2 is generated as shift)&quot;<br>
                ifTrue:[xdh := xDeltah // 2. ydh := yDeltah // 2.<br>
                                xdv := xDeltav // 2. ydv := yDeltav // 2]<br>
                ifFalse:[xdh := xDeltah // n. ydh := yDeltah // n.<br>
                                xdv := xDeltav // n. ydv := yDeltav // n].<br>
        i := nPixels.<br>
        [<br>
                x := sx. y := sy.<br>
                a := r := g := b := 0.<br>
                &quot;Pick and average n*n subpixels&quot;<br>
                nPix := 0.  &quot;actual number of pixels (not clipped and not transparent)&quot;<br>
                j := n.<br>
                [<br>
                        xx := x. yy := y.<br>
                        k := n.<br>
                        [<br>
                                &quot;get a single subpixel&quot;<br>
                                rgb := self pickWarpPixelAtX: xx y: yy.<br>
                                (combinationRule=25 &quot;PAINT&quot; and: [rgb = 0]) ifFalse:[<br>
                                        &quot;If not clipped and not transparent, then tally rgb values&quot;<br>
                                        nPix := nPix + 1.<br>
                                        sourceDepth &lt; 16 ifTrue:[<br>
                                                &quot;Get RGBA values from sourcemap table&quot;<br>
                                                rgb := self long32At: sourceMap + (rgb &lt;&lt; 2).<br>
                                        ] ifFalse:[&quot;Already in RGB format&quot;<br>
                                                sourceDepth = 16<br>
                                                                ifTrue:[rgb := self rgbMap16To32: rgb]<br>
                                                                ifFalse:[rgb := self rgbMap32To32: rgb]].<br>
                                        b := b + (rgb bitAnd: 255).<br>
                                        g := g + (rgb &gt;&gt; 8 bitAnd: 255).<br>
                                        r := r + (rgb &gt;&gt; 16 bitAnd: 255).<br>
                                        a := a + (rgb &gt;&gt; 24)].<br>
                                xx := xx + xdh.<br>
                                yy := yy + ydh.<br>
                        (k := k - 1) = 0] whileFalse.<br>
                        x := x + xdv.<br>
                        y := y + ydv.<br>
                (j := j - 1) = 0] whileFalse.<br>
<br>
                (nPix = 0 or: [combinationRule=25 &quot;PAINT&quot; and: [nPix &lt; (n * n // 2)]]) ifTrue:[<br>
                        rgb := 0  &quot;All pixels were 0, or most were transparent&quot;<br>
                ] ifFalse:[<br>
                        &quot;normalize rgba sums&quot;<br>
                        nPix = 4 &quot;Try to avoid divides for most common n&quot;<br>
                                ifTrue:[r := r &gt;&gt; 2.    g := g &gt;&gt; 2.    b := b &gt;&gt; 2.    a := a &gt;&gt; 2]<br>
                                ifFalse:[       r := r // nPix. g := g // nPix. b := b // nPix. a := a // nPix].<br>
                        rgb := (a &lt;&lt; 24) + (r &lt;&lt; 16) + (g &lt;&lt; 8) + b.<br>
<br>
                        &quot;map the pixel&quot;<br>
                        rgb = 0 ifTrue: [<br>
                                &quot;only generate zero if pixel is really transparent&quot;<br>
                                (r + g + b + a) &gt; 0 ifTrue: [rgb := 1]].<br>
                        rgb := self mapPixel: rgb flags: cmFlags.<br>
                ].<br>
                &quot;Mix it in&quot;<br>
                destWord := destWord bitOr: (rgb bitAnd: dstMask) &lt;&lt; dstBitShift.<br>
                dstBitShift := dstBitShift + dstShiftInc.<br>
                sx := sx + xDeltah.<br>
                sy := sy + yDeltah.<br>
        (i := i - 1) = 0] whileFalse.<br>
<br>
        ^destWord<br>
  !<br>
<br>
</blockquote></div><br></div>