-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BitBlt rule blendAlphaScaled may not be correct #643
Comments
Would you elaborate on your scenario? How do those lower-depth forms come to be these days? |
We use A workaround for us might be to use Pens with 32 bit sourceForms, if that is possible. I only noticed the different behavior of 32 bit forms while trying to create a code snippet to reproduce the problem, so I haven't tried this workaround yet. Also, I think that the problem still occurs when using alpha values between |
An example of how to efficiently divide by 255 in very similar context: |
Oups, see https://source.squeak.org/VMMaker/VMMaker.oscog-nice.3249.diff For some reason, I often forget a bitAnd: operation necessary for safely multiplexing the division... |
Should be fixed by 085c500 |
The
BitBlt
blending ruleForm blendAlphaScaled
(34
) doesn't blend the colors0x00000000
(source; fully transparent) and0xFFFFFFFF
(destination; white) correctly. The output is0xFEFEFEFE
(slightly transparent white), whereas it should be0xFFFFFFFF
(fully opaque white).I think the problem lies in the implementation of
BitBltSimulation>>#alphaBlendScaled:with:
. When calculating the summand containing thedestinationWord
, a right bit shift by8
is performed to normalize the result after multiplying withunAlpha
(semantically a division by256
). However,unAlpha
is in the range0x00
-0xFF
and thus a division by0xFF = 255
should be used instead. I think that the other bit shifts by8
in the function are ok, as they are only used to extract or compose certain bytes and not to (semantically) divide a value by256
.This problem causes the described behavior, because the following computation is performed in each channel:
((0xFF * 0xFF) >> 8) + 0x00 = 0xFE01 >> 8 = 0xFE
A division by
0xFF
produces the expected result:((0xFF * 0xFF) / 0xFF) + 0x00 = 0xFE01 / 0xFF = 0xFF
Code to reproduce:
Notes:
+
,*
and>>
to increase performance. A quick search on the internet shows some possible alternatives.Form
s. I think this is due toalphaSourceBlendBits32
being called in this case, which is optimized for edge cases with full or zero transparency and handles those correctly (it doesn't callalphaBlendScaledwith
).The text was updated successfully, but these errors were encountered: