Fix calculations

This commit is contained in:
Melissa LeBlanc-Williams 2023-08-08 18:33:09 -07:00
parent ea39d7089f
commit 78d1ebb529

View File

@ -881,17 +881,17 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma
blend_source2 = skip_source2_index_none || *sptr2 != (uint8_t)skip_source2_index; blend_source2 = skip_source2_index_none || *sptr2 != (uint8_t)skip_source2_index;
if (blend_source1 && blend_source2) { if (blend_source1 && blend_source2) {
// Premultiply by the alpha factor // Premultiply by the alpha factor
int sca1 = *sptr1++ *ifactor1; int sda = *sptr1++ *ifactor1;
int sca2 = *sptr2++ *ifactor2; int sca = *sptr2++ *ifactor2;
// Blend // Blend
int blend; int blend;
if (blendmode == BITMAPTOOLS_BLENDMODE_SCREEN) { if (blendmode == BITMAPTOOLS_BLENDMODE_SCREEN) {
blend = sca2 + sca1 - sca2 * sca1; blend = sca + sda - (sca * sda / 65536);
} else { } else {
blend = sca2 + sca1 * (256 - ifactor2); blend = sca + sda * (256 - ifactor2) / 256;
} }
// Divide by the alpha factor // Divide by the alpha factor
pixel = (blend / (256 * ifactor1 + 256 * ifactor2 - ifactor1 * ifactor2)); pixel = (blend / (ifactor1 + ifactor2 - ifactor1 * ifactor2 / 256));
} else if (blend_source1) { } else if (blend_source1) {
// Apply iFactor1 to source1 only // Apply iFactor1 to source1 only
pixel = *sptr1++ *ifactor1 / 256; pixel = *sptr1++ *ifactor1 / 256;
@ -934,31 +934,31 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma
int ifactor_blend = ifactor1 + ifactor2 - ifactor1 * ifactor2 / 256; int ifactor_blend = ifactor1 + ifactor2 - ifactor1 * ifactor2 / 256;
// Premultiply the colors by the alpha factor // Premultiply the colors by the alpha factor
int red_sca1 = ((spix1 & r_mask) >> 11) * ifactor1; int red_dca = ((spix1 & r_mask) >> 8) * ifactor1;
int green_sca1 = ((spix1 & g_mask) >> 5) * ifactor1; int grn_dca = ((spix1 & g_mask) >> 3) * ifactor1;
int blue_sca1 = (spix1 & b_mask) * ifactor1; int blu_dca = ((spix1 & b_mask) << 3) * ifactor1;
int red_sca2 = ((spix2 & r_mask) >> 11) * ifactor2; int red_sca = ((spix2 & r_mask) >> 8) * ifactor2;
int green_sca2 = ((spix2 & g_mask) >> 5) * ifactor2; int grn_sca = ((spix2 & g_mask) >> 3) * ifactor2;
int blue_sca2 = (spix2 & b_mask) * ifactor2; int blu_sca = ((spix2 & b_mask) << 3) * ifactor2;
int red_blend, green_blend, blue_blend; int red_blend, grn_blend, blu_blend;
if (blendmode == BITMAPTOOLS_BLENDMODE_SCREEN) { if (blendmode == BITMAPTOOLS_BLENDMODE_SCREEN) {
// Perform a screen blend // Perform a screen blend Sca + Dca - Sca × Dca
red_blend = red_sca2 + red_sca1 - (red_sca2 * red_sca1); red_blend = red_sca + red_dca - (red_sca * red_dca / 65536);
green_blend = green_sca2 + green_sca1 - (green_sca2 * green_sca1); grn_blend = grn_sca + grn_dca - (grn_sca * grn_dca / 65536);
blue_blend = blue_sca2 + blue_sca1 - (blue_sca2 * blue_sca1); blu_blend = blu_sca + blu_dca - (blu_sca * blu_dca / 65536);
} else { } else {
// Perform a normal blend // Perform a normal (src-over) blend
red_blend = red_sca2 + red_sca1 * (256 - ifactor2) / 256; red_blend = red_sca + red_dca * (256 - ifactor2) / 256;
green_blend = green_sca2 + green_sca1 * (256 - ifactor2) / 256; grn_blend = grn_sca + grn_dca * (256 - ifactor2) / 256;
blue_blend = blue_sca2 + blue_sca1 * (256 - ifactor2) / 256; blu_blend = blu_sca + blu_dca * (256 - ifactor2) / 256;
} }
// Divide by the alpha factor // Divide by the alpha factor
int r = ((red_blend / ifactor_blend) << 11) & r_mask; int r = ((red_blend / ifactor_blend) << 8) & r_mask;
int g = ((green_blend / ifactor_blend) << 5) & g_mask; int g = ((grn_blend / ifactor_blend) << 3) & g_mask;
int b = (blue_blend / ifactor_blend) & b_mask; int b = ((blu_blend / ifactor_blend) >> 3) & b_mask;
// Clamp to the appropriate range // Clamp to the appropriate range
r = MIN(r_mask, MAX(0, r)) & r_mask; r = MIN(r_mask, MAX(0, r)) & r_mask;