Add color premultiply/unpremultiply (flutter/engine#57)

This commit is contained in:
Brandon DeRosier 2022-03-07 12:53:05 -08:00 committed by Dan Field
parent d27968af0a
commit 7b08462a43
3 changed files with 44 additions and 1 deletions

View File

@ -49,6 +49,17 @@ struct Color {
alpha == c.alpha;
}
constexpr Color Premultiply() const {
return {red * alpha, green * alpha, blue * alpha, alpha};
}
constexpr Color Unpremultiply() const {
if (ScalarNearlyEqual(alpha, 0.0)) {
return Color::BlackTransparent();
}
return {red / alpha, green / alpha, blue / alpha, alpha};
}
static constexpr Color White() { return {1.0, 1.0, 1.0, 1.0}; }
static constexpr Color Black() { return {0.0, 0.0, 0.0, 1.0}; }

View File

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <limits>
#include "impeller/geometry/geometry_unittests.h"
#include <limits>
#include "flutter/testing/testing.h"
@ -568,6 +567,29 @@ TEST(GeometryTest, PointReflect) {
}
}
TEST(GeometryTest, ColorPremultiply) {
{
Color a(1.0, 0.5, 0.2, 0.5);
Color premultiplied = a.Premultiply();
Color expected = Color(0.5, 0.25, 0.1, 0.5);
ASSERT_COLOR_NEAR(premultiplied, expected);
}
{
Color a(0.5, 0.25, 0.1, 0.5);
Color unpremultiplied = a.Unpremultiply();
Color expected = Color(1.0, 0.5, 0.2, 0.5);
ASSERT_COLOR_NEAR(unpremultiplied, expected);
}
{
Color a(0.5, 0.25, 0.1, 0.0);
Color unpremultiplied = a.Unpremultiply();
Color expected = Color(0.0, 0.0, 0.0, 0.0);
ASSERT_COLOR_NEAR(unpremultiplied, expected);
}
}
TEST(GeometryTest, CanConvertBetweenDegressAndRadians) {
{
auto deg = Degrees{90.0};

View File

@ -58,6 +58,15 @@ inline ::testing::AssertionResult RectNear(impeller::Rect a, impeller::Rect b) {
: ::testing::AssertionFailure() << "Rects are not equal.";
}
inline ::testing::AssertionResult ColorNear(impeller::Color a,
impeller::Color b) {
auto equal = NumberNear(a.red, b.red) && NumberNear(a.green, b.green) &&
NumberNear(a.blue, b.blue) && NumberNear(a.alpha, b.alpha);
return equal ? ::testing::AssertionSuccess()
: ::testing::AssertionFailure() << "Colors are not equal.";
}
inline ::testing::AssertionResult PointNear(impeller::Point a,
impeller::Point b) {
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) {
#define ASSERT_MATRIX_NEAR(a, b) ASSERT_PRED2(&::MatrixNear, a, b)
#define ASSERT_QUATERNION_NEAR(a, b) ASSERT_PRED2(&::QuaternionNear, a, b)
#define ASSERT_RECT_NEAR(a, b) ASSERT_PRED2(&::RectNear, a, b)
#define ASSERT_COLOR_NEAR(a, b) ASSERT_PRED2(&::ColorNear, a, b)
#define ASSERT_POINT_NEAR(a, b) ASSERT_PRED2(&::PointNear, a, b)
#define ASSERT_SIZE_NEAR(a, b) ASSERT_PRED2(&::SizeNear, a, b)