From d406b1f1d08ef1c47a717d54e466709434d16684 Mon Sep 17 00:00:00 2001 From: jaseg Date: Wed, 29 Sep 2021 00:24:30 +0200 Subject: Add rgba color support for newer resvg/usvg --- svg-flatten/Makefile | 1 + svg-flatten/src/out_svg.cpp | 8 ++--- svg-flatten/src/svg_color.cpp | 73 ++++++++++++++++++++++++++++++++----------- svg-flatten/src/svg_color.h | 8 ++--- svg-flatten/src/svg_doc.cpp | 6 ++-- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/svg-flatten/Makefile b/svg-flatten/Makefile index 202a14c..902489e 100644 --- a/svg-flatten/Makefile +++ b/svg-flatten/Makefile @@ -92,6 +92,7 @@ $(BUILDDIR)/host/%.o: %.cpp @mkdir -p $(dir $@) $(CXX) -c $(HOST_CXXFLAGS) $(HOST_CXXFLAGS) $(HOST_INCLUDES) -o $@ $< +.PRECIOUS: $(HOST_SOURCES:%.cpp=$(BUILDDIR)/host/%.o) .INTERMEDIATE: $(HOST_SOURCES:%.cpp=$(BUILDDIR)/host/%.o) $(BUILDDIR)/$(BINARY): $(HOST_SOURCES:%.cpp=$(BUILDDIR)/host/%.o) @mkdir -p $(dir $@) diff --git a/svg-flatten/src/out_svg.cpp b/svg-flatten/src/out_svg.cpp index e778d6b..d94edc0 100644 --- a/svg-flatten/src/out_svg.cpp +++ b/svg-flatten/src/out_svg.cpp @@ -37,7 +37,7 @@ SimpleSVGOutput::SimpleSVGOutput(ostream &out, bool only_polys, int digits_frac, } void SimpleSVGOutput::header_impl(d2p origin, d2p size) { - cerr << "svg: header" << endl; + //cerr << "svg: header" << endl; m_offset[0] = origin[0]; m_offset[1] = origin[1]; m_out << "" << endl; } diff --git a/svg-flatten/src/svg_color.cpp b/svg-flatten/src/svg_color.cpp index 62b11bf..ef2336d 100644 --- a/svg-flatten/src/svg_color.cpp +++ b/svg-flatten/src/svg_color.cpp @@ -40,10 +40,6 @@ enum gerber_color gerbolyze::svg_color_to_gerber(string color, string opacity, e assert(*endptr == '\0'); } - if (alpha < 0.5f) { - return GRB_NONE; - } - if (color.empty()) { return default_val; } @@ -56,8 +52,17 @@ enum gerber_color gerbolyze::svg_color_to_gerber(string color, string opacity, e return GRB_PATTERN_FILL; } - if (color.length() == 7 && color[0] == '#') { - HSVColor hsv(color); + if ((color.length() == 7 && color[0] == '#') || color.rfind("rgba", 0) != string::npos) { + RGBAColor rgba(color); + HSVColor hsv(rgba); + + if (alpha == 1.0) + alpha = rgba.a; + + if (alpha < 0.5f) { + return GRB_NONE; + } + if ((hsv.v >= 0.5) != rset.flip_color_interpretation) { return GRB_CLEAR; } else { @@ -68,20 +73,52 @@ enum gerber_color gerbolyze::svg_color_to_gerber(string color, string opacity, e return GRB_DARK; } -gerbolyze::RGBColor::RGBColor(string hex) { - assert(hex[0] == '#'); - char *endptr = nullptr; - const char *c = hex.data(); - int rgb = strtol(c + 1, &endptr, 16); - assert(endptr); - assert(endptr == c + 7); - assert(*endptr == '\0'); - r = ((rgb >> 16) & 0xff) / 255.0f; - g = ((rgb >> 8) & 0xff) / 255.0f; - b = ((rgb >> 0) & 0xff) / 255.0f; +gerbolyze::RGBAColor::RGBAColor(string spec) { + /* resvg/usvg v0.18.0 added support for rgba(...) color specs */ + if (spec.rfind("rgba(", 0) != string::npos) { + /* "rgba(127, 127, 200, 255)" */ + std::regex reg("rgba\\(([0-9]+),([0-9]+),([0-9]+),([0-9]+)\\)"); + std::smatch match; + + assert(std::regex_match(spec, match, reg)); + + int c[4]; + for (size_t i=0; i<4; i++) { + assert (match.size() == 5); + char *endptr = nullptr; + string span = match[i+1].str(); + c[i] = strtoul(span.data(), &endptr, 10); + assert(endptr && endptr != span.data()); + assert(*endptr == '\0'); + } + + assert (0 <= c[0] && c[0] <= 255); + assert (0 <= c[1] && c[1] <= 255); + assert (0 <= c[2] && c[2] <= 255); + assert (0 <= c[3] && c[3] <= 255); + + r = c[0]/255.0f; + g = c[1]/255.0f; + b = c[2]/255.0f; + a = c[3]/255.0f; + + } else { + /* "#FF00E3" */ + assert(spec[0] == '#'); + char *endptr = nullptr; + const char *c = spec.data(); + int rgb = strtol(c + 1, &endptr, 16); + assert(endptr); + assert(endptr == c + 7); + assert(*endptr == '\0'); + r = ((rgb >> 16) & 0xff) / 255.0f; + g = ((rgb >> 8) & 0xff) / 255.0f; + b = ((rgb >> 0) & 0xff) / 255.0f; + a = 1.0; + } }; -gerbolyze::HSVColor::HSVColor(const RGBColor &color) { +gerbolyze::HSVColor::HSVColor(const RGBAColor &color) { float xmax = fmax(color.r, fmax(color.g, color.b)); float xmin = fmin(color.r, fmin(color.g, color.b)); float c = xmax - xmin; diff --git a/svg-flatten/src/svg_color.h b/svg-flatten/src/svg_color.h index 752c2ed..d2cd75e 100644 --- a/svg-flatten/src/svg_color.h +++ b/svg-flatten/src/svg_color.h @@ -31,16 +31,16 @@ enum gerber_color { GRB_PATTERN_FILL, }; -class RGBColor { +class RGBAColor { public: - float r, g, b; - RGBColor(std::string hex); + float r, g, b, a; + RGBAColor(std::string spec); }; class HSVColor { public: float h, s, v; - HSVColor(const RGBColor &color); + HSVColor(const RGBAColor &color); }; enum gerber_color svg_color_to_gerber(std::string color, std::string opacity, enum gerber_color default_val, const RenderSettings &rset); diff --git a/svg-flatten/src/svg_doc.cpp b/svg-flatten/src/svg_doc.cpp index a3186ec..6767b84 100644 --- a/svg-flatten/src/svg_doc.cpp +++ b/svg-flatten/src/svg_doc.cpp @@ -110,7 +110,7 @@ double gerbolyze::SVGDocument::doc_units_to_mm(double px) const { bool IDElementSelector::match(const pugi::xml_node &node, bool is_toplevel, bool parent_include) const { string id = node.attribute("id").value(); - cerr << "match id=" << id << " toplevel=" << is_toplevel << " parent=" << parent_include << endl; + //cerr << "match id=" << id << " toplevel=" << is_toplevel << " parent=" << parent_include << endl; if (is_toplevel && layers) { bool layer_match = std::find(layers->begin(), layers->end(), id) != layers->end(); if (!layer_match) { @@ -124,7 +124,7 @@ bool IDElementSelector::match(const pugi::xml_node &node, bool is_toplevel, bool bool include_match = std::find(include.begin(), include.end(), id) != include.end(); bool exclude_match = std::find(exclude.begin(), exclude.end(), id) != exclude.end(); - cerr << " excl=" << exclude_match << " incl=" << include_match << endl; + //cerr << " excl=" << exclude_match << " incl=" << include_match << endl; if (is_toplevel) { if (!include.empty()) @@ -227,7 +227,7 @@ void gerbolyze::SVGDocument::export_svg_group(RenderContext &ctx, const pugi::xm void gerbolyze::SVGDocument::export_svg_path(RenderContext &ctx, const pugi::xml_node &node) { enum gerber_color fill_color = gerber_fill_color(node, ctx.settings()); enum gerber_color stroke_color = gerber_stroke_color(node, ctx.settings()); - cerr << "path: resolved colors, stroke=" << stroke_color << ", fill=" << fill_color << endl; + //cerr << "path: resolved colors, stroke=" << stroke_color << ", fill=" << fill_color << endl; double stroke_width = usvg_double_attr(node, "stroke-width", /* default */ 1.0); assert(stroke_width > 0.0); -- cgit