summaryrefslogtreecommitdiffstats
path: root/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'gfx')
-rw-r--r--gfx/color_utils.cc31
-rw-r--r--gfx/color_utils.h6
-rw-r--r--gfx/color_utils_unittest.cc18
3 files changed, 45 insertions, 10 deletions
diff --git a/gfx/color_utils.cc b/gfx/color_utils.cc
index 268f556..73c585b 100644
--- a/gfx/color_utils.cc
+++ b/gfx/color_utils.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -256,13 +256,28 @@ SkColor AlphaBlend(SkColor foreground, SkColor background, SkAlpha alpha) {
return background;
if (alpha == 255)
return foreground;
- return SkColorSetRGB(
- ((SkColorGetR(foreground) * alpha) +
- (SkColorGetR(background) * (255 - alpha))) / 255,
- ((SkColorGetG(foreground) * alpha) +
- (SkColorGetG(background) * (255 - alpha))) / 255,
- ((SkColorGetB(foreground) * alpha) +
- (SkColorGetB(background) * (255 - alpha))) / 255);
+
+ int f_alpha = SkColorGetA(foreground);
+ int b_alpha = SkColorGetA(background);
+
+ double normalizer = (f_alpha * alpha + b_alpha * (255 - alpha)) / 255.0;
+ if (normalizer == 0.0)
+ return SkColorSetARGB(0, 0, 0, 0);
+
+ double f_weight = f_alpha * alpha / normalizer;
+ double b_weight = b_alpha * (255 - alpha) / normalizer;
+
+ double r = (SkColorGetR(foreground) * f_weight +
+ SkColorGetR(background) * b_weight) / 255.0;
+ double g = (SkColorGetG(foreground) * f_weight +
+ SkColorGetG(background) * b_weight) / 255.0;
+ double b = (SkColorGetB(foreground) * f_weight +
+ SkColorGetB(background) * b_weight) / 255.0;
+
+ return SkColorSetARGB(static_cast<int>(normalizer),
+ static_cast<int>(r),
+ static_cast<int>(g),
+ static_cast<int>(b));
}
SkColor GetReadableColor(SkColor foreground, SkColor background) {
diff --git a/gfx/color_utils.h b/gfx/color_utils.h
index f511168..b6eb2da 100644
--- a/gfx/color_utils.h
+++ b/gfx/color_utils.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -58,7 +58,9 @@ SkColor GetAverageColorOfFavicon(SkBitmap* bitmap, SkAlpha alpha);
void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]);
// Returns a blend of the supplied colors, ranging from |background| (for
-// |alpha| == 0) to |foreground| (for |alpha| == 255).
+// |alpha| == 0) to |foreground| (for |alpha| == 255). The alpha channels of
+// the supplied colors are also taken into account, so the returned color may
+// be partially transparent.
SkColor AlphaBlend(SkColor foreground, SkColor background, SkAlpha alpha);
// Given a foreground and background color, try to return a foreground color
diff --git a/gfx/color_utils_unittest.cc b/gfx/color_utils_unittest.cc
index 363d700..30cf514 100644
--- a/gfx/color_utils_unittest.cc
+++ b/gfx/color_utils_unittest.cc
@@ -47,3 +47,21 @@ TEST(ColorUtils, ColorToHSLRegisterSpill) {
EXPECT_EQ(153U, SkColorGetG(result));
EXPECT_EQ(88U, SkColorGetB(result));
}
+
+TEST(ColorUtils, AlphaBlend) {
+ SkColor fore = SkColorSetARGB(255, 200, 200, 200);
+ SkColor back = SkColorSetARGB(255, 100, 100, 100);
+
+ EXPECT_TRUE(color_utils::AlphaBlend(fore, back, 255) ==
+ fore);
+ EXPECT_TRUE(color_utils::AlphaBlend(fore, back, 0) ==
+ back);
+
+ // One is fully transparent, result is partially transparent.
+ back = SkColorSetA(back, 0);
+ EXPECT_EQ(136U, SkColorGetA(color_utils::AlphaBlend(fore, back, 136)));
+
+ // Both are fully transparent, result is fully transparent.
+ fore = SkColorSetA(fore, 0);
+ EXPECT_EQ(0U, SkColorGetA(color_utils::AlphaBlend(fore, back, 255)));
+}