[svgcanvas] Named colors support

Use color shorthands instead of rgb(x,y,z).

Change-Id: Id77d466debe74b90f9b35cbe1dfd1d38718e8d29
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/236341
Auto-Submit: Florin Malita <fmalita@chromium.org>
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp
index d8db4e7..7662631 100644
--- a/src/svg/SkSVGDevice.cpp
+++ b/src/svg/SkSVGDevice.cpp
@@ -37,6 +37,35 @@
 namespace {
 
 static SkString svg_color(SkColor color) {
+    // https://www.w3.org/TR/css-color-3/#html4
+    auto named_color = [](SkColor c) -> const char* {
+        switch (c & 0xffffff) {
+        case 0x000000: return "black";
+        case 0x000080: return "navy";
+        case 0x0000ff: return "blue";
+        case 0x008000: return "green";
+        case 0x008080: return "teal";
+        case 0x00ff00: return "lime";
+        case 0x00ffff: return "aqua";
+        case 0x800000: return "maroon";
+        case 0x800080: return "purple";
+        case 0x808000: return "olive";
+        case 0x808080: return "gray";
+        case 0xc0c0c0: return "silver";
+        case 0xff0000: return "red";
+        case 0xff00ff: return "fuchsia";
+        case 0xffff00: return "yellow";
+        case 0xffffff: return "white";
+        default: break;
+        }
+
+        return nullptr;
+    };
+
+    if (const auto* nc = named_color(color)) {
+        return SkString(nc);
+    }
+
     return SkStringPrintf("rgb(%u,%u,%u)",
                           SkColorGetR(color),
                           SkColorGetG(color),
@@ -298,7 +327,7 @@
 void SkSVGDevice::AutoElement::addPaint(const SkPaint& paint, const Resources& resources) {
     SkPaint::Style style = paint.getStyle();
     if (style == SkPaint::kFill_Style || style == SkPaint::kStrokeAndFill_Style) {
-        static constexpr char kDefaultFill[] = "rgb(0,0,0)";
+        static constexpr char kDefaultFill[] = "black";
         if (!resources.fPaintServer.equals(kDefaultFill)) {
             this->addAttribute("fill", resources.fPaintServer);
 
diff --git a/tests/SVGDeviceTest.cpp b/tests/SVGDeviceTest.cpp
index 3518067..71d1fba 100644
--- a/tests/SVGDeviceTest.cpp
+++ b/tests/SVGDeviceTest.cpp
@@ -375,7 +375,7 @@
     REPORTER_ASSERT(reporter, strcmp(dom.findAttr(filterElement, "height"), "100%") == 0);
 
     REPORTER_ASSERT(reporter,
-                    strcmp(dom.findAttr(floodElement, "flood-color"), "rgb(255,0,0)") == 0);
+                    strcmp(dom.findAttr(floodElement, "flood-color"), "red") == 0);
     REPORTER_ASSERT(reporter, atoi(dom.findAttr(floodElement, "flood-opacity")) == 1);
 
     REPORTER_ASSERT(reporter, strcmp(dom.findAttr(compositeElement, "in"), "flood") == 0);
@@ -419,10 +419,10 @@
         const char*    expected_fill;
         const char*    expected_stroke;
     } gTests[] = {
-        { SK_ColorBLACK, SkPaint::kFill_Style  , nullptr       , nullptr        },
-        { SK_ColorBLACK, SkPaint::kStroke_Style, "none"        , "rgb(0,0,0)"   },
-        { SK_ColorRED  , SkPaint::kFill_Style  , "rgb(255,0,0)", nullptr        },
-        { SK_ColorRED  , SkPaint::kStroke_Style, "none"        , "rgb(255,0,0)" },
+        { SK_ColorBLACK, SkPaint::kFill_Style  , nullptr, nullptr },
+        { SK_ColorBLACK, SkPaint::kStroke_Style, "none" , "black" },
+        { SK_ColorRED  , SkPaint::kFill_Style  , "red"  , nullptr },
+        { SK_ColorRED  , SkPaint::kStroke_Style, "none" , "red"   },
     };
 
     for (const auto& tst : gTests) {