Commit 4ffdd673 authored by Christopher Lam's avatar Christopher Lam Committed by Commit Bot

Add rgb and rgba color parsing to extensions image_utils.

This CL is a precursor to Change 680677 which needs to store a color
with transparency. To do this, we plan to store the color as an rgba
string, which is converted back by the function added in this patch.

The RGB parsing here does not handle percentages, for simplicity.

Bug: 762401
Change-Id: I1304f0444be4c80536a26bbb97dd653503d1b9c2
Reviewed-on: https://chromium-review.googlesource.com/711775
Commit-Queue: calamity <calamity@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#508592}
parent 3a0cffce
......@@ -27,8 +27,7 @@ bool ParseCssColorString(const std::string& color_string, SkColor* result) {
if (base::StartsWith(color_string, "hsl", base::CompareCase::SENSITIVE))
return ParseHslColorString(color_string, result);
if (base::StartsWith(color_string, "rgb", base::CompareCase::SENSITIVE)) {
NOTIMPLEMENTED();
return false;
return ParseRgbColorString(color_string, result);
}
if (SkParse::FindNamedColor(color_string.c_str(), color_string.size(),
result) != nullptr) {
......@@ -71,6 +70,49 @@ std::string GenerateHexColorString(SkColor color) {
SkColorGetG(color), SkColorGetB(color));
}
bool ParseRgbColorString(const std::string& color_string, SkColor* result) {
// https://www.w3.org/wiki/CSS/Properties/color/RGB#The_format_of_the_RGB_Value
// The CSS3 specification defines the format of a RGB color as
// rgb(<number>, <number>, <number>) or
// rgb(<percent>, <percent>, <percent>) or
// and with alpha, the format is
// rgb(<number>, <number>, <number>, <alphavalue>) or
// rgba(<percent>, <percent>, <percent>, <alphavalue>)
// Whitespace is arbitrary.
// e.g.: rgb(120, 100, 50), rgba(120, 100, 50, 0.5);
int r = 0;
int g = 0;
int b = 0;
// 'rgb()' has '1' alpha value implicitly.
double alpha = 1.0;
// Percentage rgb values are not supported.
if (color_string.find('%') != std::string::npos) {
NOTIMPLEMENTED();
return false;
}
if (!re2::RE2::FullMatch(color_string,
"rgb\\(([\\d]+),\\s*([\\d]+),\\s*([\\d]+)\\)", &r,
&g, &b) &&
!re2::RE2::FullMatch(
color_string,
"rgba\\(([\\d]+),\\s*([\\d]+),\\s*([\\d]+),\\s*([\\d.]+)\\)", &r, &g,
&b, &alpha)) {
return false;
}
if (alpha < 0 || alpha > 1.0 || r < 0 || r > 255 || g < 0 || g > 255 ||
b < 0 || b > 255) {
return false;
}
SkAlpha sk_alpha = alpha * 255;
*result = SkColorSetARGB(sk_alpha, r, g, b);
return true;
}
bool ParseHslColorString(const std::string& color_string, SkColor* result) {
// http://www.w3.org/wiki/CSS/Properties/color/HSL#The_format_of_the_HSL_Value
// The CSS3 specification defines the format of a HSL color as
......
......@@ -23,6 +23,9 @@ bool ParseHexColorString(const std::string& color_string, SkColor* result);
// Creates a string like #FF9982 from a color.
std::string GenerateHexColorString(SkColor color);
// Parses rgb() or rgba() string to a color. Returns true for success.
bool ParseRgbColorString(const std::string& color_string, SkColor* result);
// Parses hsl() or hsla() string to a SkColor. Returns true for success.
bool ParseHslColorString(const std::string& color_string, SkColor* result);
......
......@@ -33,6 +33,17 @@ void RunFailHslTest(const std::string& hsl_string) {
EXPECT_FALSE(image_util::ParseHslColorString(hsl_string, &color));
}
void RunPassRgbTest(const std::string& rgb_string, SkColor expected) {
SkColor color = 0;
EXPECT_TRUE(image_util::ParseRgbColorString(rgb_string, &color));
EXPECT_EQ(color, expected);
}
void RunFailRgbTest(const std::string& rgb_string) {
SkColor color = 0;
EXPECT_FALSE(image_util::ParseRgbColorString(rgb_string, &color));
}
TEST(ImageUtilTest, ChangeBadgeBackgroundNormalCSS) {
RunPassHexTest("#34006A", SkColorSetARGB(0xFF, 0x34, 0, 0x6A));
}
......@@ -108,6 +119,44 @@ TEST(ImageUtilTest, AcceptHsla) {
RunPassHslTest("hsla(0, 100%, 50%, 1)", SK_ColorRED);
}
TEST(ImageUtilTest, AcceptRgb) {
// Run basic color tests.
RunPassRgbTest("rgb(255,0,0)", SK_ColorRED);
RunPassRgbTest("rgb(0, 255, 0)", SK_ColorGREEN);
RunPassRgbTest("rgb(0, 0, 255)", SK_ColorBLUE);
}
TEST(ImageUtilTest, InvalidRgb) {
RunFailRgbTest("(0,100,50)");
RunFailRgbTest("[0, 100, 50]");
RunFailRgbTest("rg b(0,100,50)");
RunFailRgbTest("rgb(0,-100, 10)");
RunFailRgbTest("rgb(100,50)");
RunFailRgbTest("rgb(120.0, 100.6, 50.3)");
RunFailRgbTest("rgb[120, 100, 50]");
RunFailRgbTest("rgb(120, 100, 50, 1.0)");
RunFailRgbTest("rgba(120, 100, 50)");
RunFailRgbTest("rgb(0, 300, 0)");
// This is valid RGB but we don't support percentages yet.
RunFailRgbTest("rgb(100%, 0%, 100%)");
}
TEST(ImageUtilTest, AcceptRgba) {
// Run basic color tests.
RunPassRgbTest("rgba(255, 0, 0, 1.0)", SK_ColorRED);
RunPassRgbTest("rgba(255, 0, 0, 0.0)",
SkColorSetARGB(0x00, 0xFF, 0x00, 0x00));
RunPassRgbTest("rgba(255, 0, 0, 0.5)",
SkColorSetARGB(0x7F, 0xFF, 0x00, 0x00));
RunPassRgbTest("rgba(255, 0, 0, 0.25)",
SkColorSetARGB(0x3F, 0xFF, 0x00, 0x00));
RunPassRgbTest("rgba(255, 0, 0, 0.75)",
SkColorSetARGB(0xBF, 0xFF, 0x00, 0x00));
// We should able to parse an integer alpha value.
RunPassRgbTest("rgba(255, 0, 0, 1)", SK_ColorRED);
}
TEST(ImageUtilTest, BasicColorKeyword) {
SkColor color = 0;
EXPECT_TRUE(image_util::ParseCssColorString("red", &color));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment