Skip to content

Commit 845c3bc

Browse files
bderodnfield
authored andcommitted
Add color premultiply/unpremultiply (flutter#57)
1 parent 2a1b560 commit 845c3bc

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

impeller/geometry/color.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ struct Color {
4949
alpha == c.alpha;
5050
}
5151

52+
constexpr Color Premultiply() const {
53+
return {red * alpha, green * alpha, blue * alpha, alpha};
54+
}
55+
56+
constexpr Color Unpremultiply() const {
57+
if (ScalarNearlyEqual(alpha, 0.0)) {
58+
return Color::BlackTransparent();
59+
}
60+
return {red / alpha, green / alpha, blue / alpha, alpha};
61+
}
62+
5263
static constexpr Color White() { return {1.0, 1.0, 1.0, 1.0}; }
5364

5465
static constexpr Color Black() { return {0.0, 0.0, 0.0, 1.0}; }

impeller/geometry/geometry_unittests.cc

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
#include <limits>
65
#include "impeller/geometry/geometry_unittests.h"
76
#include <limits>
87
#include "flutter/testing/testing.h"
@@ -568,6 +567,29 @@ TEST(GeometryTest, PointReflect) {
568567
}
569568
}
570569

570+
TEST(GeometryTest, ColorPremultiply) {
571+
{
572+
Color a(1.0, 0.5, 0.2, 0.5);
573+
Color premultiplied = a.Premultiply();
574+
Color expected = Color(0.5, 0.25, 0.1, 0.5);
575+
ASSERT_COLOR_NEAR(premultiplied, expected);
576+
}
577+
578+
{
579+
Color a(0.5, 0.25, 0.1, 0.5);
580+
Color unpremultiplied = a.Unpremultiply();
581+
Color expected = Color(1.0, 0.5, 0.2, 0.5);
582+
ASSERT_COLOR_NEAR(unpremultiplied, expected);
583+
}
584+
585+
{
586+
Color a(0.5, 0.25, 0.1, 0.0);
587+
Color unpremultiplied = a.Unpremultiply();
588+
Color expected = Color(0.0, 0.0, 0.0, 0.0);
589+
ASSERT_COLOR_NEAR(unpremultiplied, expected);
590+
}
591+
}
592+
571593
TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
572594
{
573595
auto deg = Degrees{90.0};

impeller/geometry/geometry_unittests.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b) {
5858
: ::testing::AssertionFailure() << "Rects are not equal.";
5959
}
6060

61+
inline ::testing::AssertionResult ColorNear(impeller::Color a,
62+
impeller::Color b) {
63+
auto equal = NumberNear(a.red, b.red) && NumberNear(a.green, b.green) &&
64+
NumberNear(a.blue, b.blue) && NumberNear(a.alpha, b.alpha);
65+
66+
return equal ? ::testing::AssertionSuccess()
67+
: ::testing::AssertionFailure() << "Colors are not equal.";
68+
}
69+
6170
inline ::testing::AssertionResult PointNear(impeller::Point a,
6271
impeller::Point b) {
6372
auto equal = NumberNear(a.x, b.x) && NumberNear(a.y, b.y);
@@ -76,5 +85,6 @@ inline ::testing::AssertionResult SizeNear(impeller::Size a, impeller::Size b) {
7685
#define ASSERT_MATRIX_NEAR(a, b) ASSERT_PRED2(&::MatrixNear, a, b)
7786
#define ASSERT_QUATERNION_NEAR(a, b) ASSERT_PRED2(&::QuaternionNear, a, b)
7887
#define ASSERT_RECT_NEAR(a, b) ASSERT_PRED2(&::RectNear, a, b)
88+
#define ASSERT_COLOR_NEAR(a, b) ASSERT_PRED2(&::ColorNear, a, b)
7989
#define ASSERT_POINT_NEAR(a, b) ASSERT_PRED2(&::PointNear, a, b)
8090
#define ASSERT_SIZE_NEAR(a, b) ASSERT_PRED2(&::SizeNear, a, b)

0 commit comments

Comments
 (0)