gdiplus: Fix blend_colors when alpha channel differs.
Vincent Povirk
madewokherd at gmail.com
Tue Mar 24 13:17:32 CDT 2015
When picking a color halfway between 100% white (0xffffffff) and fully
transparent (0x00000000), the result was 50% opaque 50% grey
(0x80808080) when it should really be 50% opaque white (0x80ffffff).
This had a tendency to create grey fringes on things. The fix is to
weight the non-alpha components based on how much they contribute to
the final alpha value.
-------------- next part --------------
From 05de5fd798155ed9b273a4ad2b0f7b9ed45ffd5c Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Tue, 24 Mar 2015 12:50:18 -0500
Subject: [PATCH] gdiplus: Fix blend_colors when alpha channel differs.
---
dlls/gdiplus/graphics.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index ae530a9..580390f 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -521,20 +521,22 @@ static GpStatus alpha_blend_pixels(GpGraphics *graphics, INT dst_x, INT dst_y,
static ARGB blend_colors(ARGB start, ARGB end, REAL position)
{
- ARGB result=0;
- ARGB i;
- INT a1, a2, a3;
+ INT start_a, end_a, final_a;
+ INT pos;
- a1 = (start >> 24) & 0xff;
- a2 = (end >> 24) & 0xff;
+ pos = gdip_round(position * 0xff);
- a3 = (int)(a1*(1.0f - position)+a2*(position));
+ start_a = ((start >> 24) & 0xff) * (pos ^ 0xff);
+ end_a = ((end >> 24) & 0xff) * pos;
- result |= a3 << 24;
+ final_a = start_a + end_a;
- for (i=0xff; i<=0xff0000; i = i << 8)
- result |= (int)((start&i)*(1.0f - position)+(end&i)*(position))&i;
- return result;
+ if (final_a < 0xff) return 0;
+
+ return (final_a / 0xff) << 24 |
+ ((((start >> 16) & 0xff) * start_a + (((end >> 16) & 0xff) * end_a)) / final_a) << 16 |
+ ((((start >> 8) & 0xff) * start_a + (((end >> 8) & 0xff) * end_a)) / final_a) << 8 |
+ (((start & 0xff) * start_a + ((end & 0xff) * end_a)) / final_a);
}
static ARGB blend_line_gradient(GpLineGradient* brush, REAL position)
--
2.1.0
More information about the wine-patches
mailing list