diff options
Diffstat (limited to 'gfx')
-rw-r--r-- | gfx/color_utils.cc | 31 | ||||
-rw-r--r-- | gfx/color_utils.h | 6 | ||||
-rw-r--r-- | gfx/color_utils_unittest.cc | 18 |
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))); +} |