diff --git a/include/rvegen/postprocess/svg_writer.h b/include/rvegen/postprocess/svg_writer.h index f1dfe2d..32dba2f 100644 --- a/include/rvegen/postprocess/svg_writer.h +++ b/include/rvegen/postprocess/svg_writer.h @@ -25,6 +25,7 @@ #include "post_process_base.h" #include "../shapes/circle.h" +#include "../shapes/convex_polygon.h" #include "../shapes/ellipse.h" #include "../shapes/rectangle.h" #include "../types.h" @@ -144,6 +145,18 @@ class svg_writer final : public post_process_base { << "transform=\"rotate(" << deg << ' ' << cx << ' ' << cy << ")\" " << "fill=\"" << fill << "\" fill-opacity=\"0.7\" " << "stroke=\"#222\" stroke-width=\"" << stroke_w << "\"/>\n"; + } else if (auto const* p = dynamic_cast const*>(raw); p) { + // SVG takes a space-separated points list. Flip y + // for each vertex to keep SVG's top-down y-axis convention. + out << " vertices()) { + if (!first) out << ' '; + out << v[0] << ',' << (Ly - v[1]); + first = false; + } + out << "\" fill=\"" << fill << "\" fill-opacity=\"0.7\" " + << "stroke=\"#222\" stroke-width=\"" << stroke_w << "\"/>\n"; } else { out << " \n"; } diff --git a/tests/extra_types_smoke.cpp b/tests/extra_types_smoke.cpp index d0df405..8cc5cc2 100644 --- a/tests/extra_types_smoke.cpp +++ b/tests/extra_types_smoke.cpp @@ -2380,6 +2380,27 @@ void test_voronoi_to_shapes_helper_returns_shape_vector() { } } +// svg_writer dispatch for convex_polygon: emit a element with +// SVG-flipped y-coordinates. Mirrors the gmsh dispatch added for the +// Voronoi pipeline. +void test_svg_writer_emits_polygon_element_for_convex_polygon() { + rvegen::svg_writer::shape_vector shapes; + shapes.emplace_back(std::make_unique>( + std::vector>{{0.1, 0.2}, {0.4, 0.2}, + {0.4, 0.6}, {0.1, 0.6}})); + + rvegen::svg_writer writer{}; + std::stringstream out; + writer.write(out, shapes, {1.0, 1.0, 0.0}); + const auto txt = out.str(); + + REQUIRE(txt.find("