From 63ac1d3e8d48bdfd5ed81c07408aa9ce23090a65 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 11 Apr 2024 06:49:03 +0700 Subject: [PATCH] Implement partial support for rgba() color --- src/svg/svg-color.cpp | 94 +++++++++++++++++++------------- testfiles/src/svg-color-test.cpp | 2 +- 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/svg/svg-color.cpp b/src/svg/svg-color.cpp index 66ae587c12..698c5a46b8 100644 --- a/src/svg/svg-color.cpp +++ b/src/svg/svg-color.cpp @@ -243,54 +243,75 @@ static guint32 internal_sp_svg_read_color(gchar const *str, gchar const **end_pt if (end_ptr) { *end_ptr = str + i; } - } else if (strneq(str, "rgb(", 4)) { + } else if (strneq(str, "rgb(", 4) || strneq(str, "rgba(", 5)) { bool hasp, hasd; gchar *s, *e; - gdouble r, g, b; + gdouble r, g, b, a; s = (gchar *) str + 4; + if (strneq(str, "rgba(", 5)) + s++; hasp = false; hasd = false; - r = g_ascii_strtod(s, &e); - if (s == e) return def; - s = e; - if (*s == '%') { - hasp = true; - s += 1; +#define read_double(x) \ + do { \ + x = g_ascii_strtod(s, &e); \ + if (s == e) \ + return def; \ + s = e; \ + } while (0) + +#define read_double_or_percentage(x) \ + do { \ + read_double(x); \ + if (*s == '%') { \ + hasp = true; \ + s += 1; \ + } else { \ + hasd = true; \ + } \ + } while (0) + +#define read_spaces() \ + do { \ + while (*s && g_ascii_isspace(*s)) \ + s += 1; \ + } while (0) + +#define read_comma() \ + do { \ + read_spaces(); \ + if (*s != ',') \ + return def; \ + s += 1; \ + read_spaces(); \ + } while (0) + + read_double_or_percentage(r); + read_comma(); + read_double_or_percentage(g); + read_comma(); + read_double_or_percentage(b); + if (strneq(str, "rgba(", 5)) { + read_comma(); + read_double(a); } else { - hasd = true; + a = 1.0; } - while (*s && g_ascii_isspace(*s)) s += 1; - if (*s != ',') return def; - s += 1; - while (*s && g_ascii_isspace(*s)) s += 1; - g = g_ascii_strtod(s, &e); - if (s == e) return def; - s = e; - if (*s == '%') { - hasp = true; - s += 1; - } else { - hasd = true; - } - while (*s && g_ascii_isspace(*s)) s += 1; - if (*s != ',') return def; - s += 1; - while (*s && g_ascii_isspace(*s)) s += 1; - b = g_ascii_strtod(s, &e); - if (s == e) return def; - s = e; - if (*s == '%') { - hasp = true; - s += 1; - } else { - hasd = true; - } - while(*s && g_ascii_isspace(*s)) s += 1; + read_spaces(); + +#undef read_double +#undef read_double_or_percentage +#undef read_spaces +#undef read_comma + if (*s != ')') { return def; } + if (a != 1.0) { + return def; // TODO: https://gitlab.com/inkscape/inbox/-/issues/1195 + } ++s; if (hasp && hasd) return def; if (hasp) { @@ -307,7 +328,6 @@ static guint32 internal_sp_svg_read_color(gchar const *str, gchar const **end_pt } return val; } else if (strneq(str, "hsl(", 4)) { - gchar *ptr = (gchar *) str + 4; gchar *e; // ptr after read diff --git a/testfiles/src/svg-color-test.cpp b/testfiles/src/svg-color-test.cpp index c4e937928d..af9f756e6d 100644 --- a/testfiles/src/svg-color-test.cpp +++ b/testfiles/src/svg-color-test.cpp @@ -54,7 +54,7 @@ TEST(SvgColorTest, testWrite) TEST(SvgColorTest, testReadColor) { - gchar const *val[] = {"#f0f", "#ff00ff", "rgb(255,0,255)", "fuchsia"}; + gchar const *val[] = {"#f0f", "#ff00ff", "rgb(255,0,255)", "rgba(255,0,255,1)", "fuchsia"}; size_t const n = sizeof(val) / sizeof(*val); for (size_t i = 0; i < n; i++) { gchar const *end = 0; -- GitLab