From 564ab243cc3fa7c0239d71a6dacb4a6c7765e9f5 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 3 Jun 2021 23:45:11 +0200 Subject: [PATCH] Add svg-flatten SVG feature tests --- .gitmodules | 3 + svg-flatten/Makefile | 15 +- svg-flatten/src/{ => test}/nopencv_test.cpp | 2 +- svg-flatten/src/test/svg_tests.py | 75 ++++++++++ svg-flatten/testdata/svg/circles.svg | 78 ++++++++++ svg-flatten/testdata/svg/compound_xform.svg | 102 +++++++++++++ svg-flatten/testdata/svg/empty.svg | 11 ++ svg-flatten/testdata/svg/empty_inkscape.svg | 54 +++++++ svg-flatten/testdata/svg/groups.svg | 96 +++++++++++++ svg-flatten/testdata/svg/pattern_fill.svg | 135 ++++++++++++++++++ svg-flatten/testdata/svg/pattern_stroke.svg | 89 ++++++++++++ .../testdata/svg/pattern_stroke_dashed.svg | 89 ++++++++++++ svg-flatten/testdata/svg/rect.svg | 65 +++++++++ svg-flatten/testdata/svg/rect_occlusion.svg | 79 ++++++++++ svg-flatten/testdata/svg/rotation.svg | 66 +++++++++ svg-flatten/testdata/svg/rotation_90.svg | 66 +++++++++ svg-flatten/testdata/svg/scale.svg | 91 ++++++++++++ svg-flatten/testdata/svg/shear.svg | 59 ++++++++ svg-flatten/testdata/svg/stroke.svg | 67 +++++++++ svg-flatten/testdata/svg/stroke_caps.svg | 68 +++++++++ svg-flatten/testdata/svg/stroke_dashes.svg | 75 ++++++++++ svg-flatten/testdata/svg/stroke_joins.svg | 68 +++++++++ svg-flatten/testdata/svg/text.svg | 108 ++++++++++++++ upstream/filesystem | 1 + 24 files changed, 1552 insertions(+), 10 deletions(-) rename svg-flatten/src/{ => test}/nopencv_test.cpp (99%) create mode 100644 svg-flatten/src/test/svg_tests.py create mode 100644 svg-flatten/testdata/svg/circles.svg create mode 100644 svg-flatten/testdata/svg/compound_xform.svg create mode 100644 svg-flatten/testdata/svg/empty.svg create mode 100644 svg-flatten/testdata/svg/empty_inkscape.svg create mode 100644 svg-flatten/testdata/svg/groups.svg create mode 100644 svg-flatten/testdata/svg/pattern_fill.svg create mode 100644 svg-flatten/testdata/svg/pattern_stroke.svg create mode 100644 svg-flatten/testdata/svg/pattern_stroke_dashed.svg create mode 100644 svg-flatten/testdata/svg/rect.svg create mode 100644 svg-flatten/testdata/svg/rect_occlusion.svg create mode 100644 svg-flatten/testdata/svg/rotation.svg create mode 100644 svg-flatten/testdata/svg/rotation_90.svg create mode 100644 svg-flatten/testdata/svg/scale.svg create mode 100644 svg-flatten/testdata/svg/shear.svg create mode 100644 svg-flatten/testdata/svg/stroke.svg create mode 100644 svg-flatten/testdata/svg/stroke_caps.svg create mode 100644 svg-flatten/testdata/svg/stroke_dashes.svg create mode 100644 svg-flatten/testdata/svg/stroke_joins.svg create mode 100644 svg-flatten/testdata/svg/text.svg create mode 160000 upstream/filesystem diff --git a/.gitmodules b/.gitmodules index deedaea..b3b249b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -22,3 +22,6 @@ [submodule "upstream/stb"] path = upstream/stb url = https://github.com/nothings/stb +[submodule "upstream/filesystem"] + path = upstream/filesystem + url = https://github.com/gulrak/filesystem diff --git a/svg-flatten/Makefile b/svg-flatten/Makefile index a980c05..2c9ff6c 100644 --- a/svg-flatten/Makefile +++ b/svg-flatten/Makefile @@ -1,5 +1,5 @@ -CXX := clang++ +CXX ?= clang++ LD ?= ld INSTALL := install PKG_CONFIG ?= pkg-config @@ -45,7 +45,7 @@ SOURCES += $(CLIPPER_SOURCES) INCLUDES := -Iinclude -Isrc $(CLIPPER_INCLUDES) $(VORONOI_INCLUDES) $(POISSON_INCLUDES) $(BASE64_INCLUDES) $(ARGAGG_INCLUDES) $(CAVC_INCLUDES) $(SUBPROCESS_INCLUDES) $(MINUNIT_INCLUDES) $(STB_INCLUDES) CXXFLAGS := -std=c++2a -g -Wall -Wextra -O0 -LDFLAGS := -lm -lc -lstdc++ +LDFLAGS := -lm PKG_CONFIG_DEPS := ifdef USE_SYSTEM_PUGIXML @@ -71,19 +71,16 @@ $(BUILDDIR)/%.o: %.cpp $(BUILDDIR)/$(TARGET): $(SOURCES:%.cpp=$(BUILDDIR)/%.o) @mkdir -p $(dir $@) - if [ $$(uname -s) = "Darwin" ]; then \ - $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^; \ - else \ - $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ -Wl,--start-group $^ -lstdc++fs -Wl,--end-group; \ - fi + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ -$(BUILDDIR)/nopencv-tests: src/nopencv_test.cpp src/nopencv.cpp +$(BUILDDIR)/nopencv-test: src/test/nopencv_test.cpp src/nopencv.cpp @mkdir -p $(dir $@) $(CXX) $(CXXFLAGS) $(INCLUDES) $(LDFLAGS) -o $@ $^ .PHONY: tests -tests: $(BUILDDIR)/nopencv-tests +tests: $(BUILDDIR)/nopencv-test + $(BUILDDIR)/nopencv-test .PHONY: install install: diff --git a/svg-flatten/src/nopencv_test.cpp b/svg-flatten/src/test/nopencv_test.cpp similarity index 99% rename from svg-flatten/src/nopencv_test.cpp rename to svg-flatten/src/test/nopencv_test.cpp index 17ba71e..2f358b2 100644 --- a/svg-flatten/src/nopencv_test.cpp +++ b/svg-flatten/src/test/nopencv_test.cpp @@ -15,7 +15,7 @@ using namespace gerbolyze; using namespace gerbolyze::nopencv; -char msg[1024]; +char msg[512]; class TempfileHack { public: diff --git a/svg-flatten/src/test/svg_tests.py b/svg-flatten/src/test/svg_tests.py new file mode 100644 index 0000000..a5139ec --- /dev/null +++ b/svg-flatten/src/test/svg_tests.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import tempfile +import unittest +from pathlib import Path +import subprocess +import os + +from PIL import Image +import numpy as np + +def run_svg_flatten(input_file, output_file, **kwargs): + if 'SVG_FLATTEN' in os.environ: + svg_flatten = os.environ.get('SVG_FLATTEN') + elif (Path(__file__) / '../../build/svg-flatten').is_file(): + svg_flatten = '../../build/svg-flatten' + elif Path('./build/svg-flatten').is_file(): + svg_flatten = './build/svg-flatten' + else: + svg_flatten = 'svg-flatten' + + args = [ svg_flatten, + *(arg for (key, value) in kwargs.items() for arg in (f'--{key.replace("_", "-")}', value)), + str(input_file), str(output_file) ] + + try: + proc = subprocess.run(args, capture_output=True, check=True) + except: + print('Subprocess stdout:') + print(proc.stdout) + print('Subprocess stderr:') + print(proc.stderr) + raise + +class SVGRoundTripTests(unittest.TestCase): + + def compare_images(self, reference, output, test_name, mean=0.01): + ref = np.array(Image.open(reference)) + out = np.array(Image.open(output)) + delta = np.abs(out - ref).astype(float) / 255 + + #print(f'{test_name}: mean={delta.mean():.5g}') + + self.assertTrue(delta.mean() < mean, + f'Expected mean pixel difference between images to be <{mean}, was {delta.mean():.5g}') + + def run_svg_round_trip_test(self, test_in_svg): + with tempfile.NamedTemporaryFile(suffix='.svg') as tmp_out_svg,\ + tempfile.NamedTemporaryFile(suffix='.png') as tmp_out_png,\ + tempfile.NamedTemporaryFile(suffix='.png') as tmp_in_png: + + run_svg_flatten(test_in_svg, tmp_out_svg.name, format='svg') + + subprocess.run(['resvg', tmp_out_svg.name, tmp_out_png.name], check=True, stdout=subprocess.DEVNULL) + subprocess.run(['resvg', test_in_svg, tmp_in_png.name], check=True, stdout=subprocess.DEVNULL) + + try: + self.compare_images(tmp_in_png, tmp_out_png, test_in_svg.stem) + except AssertionError as e: + import shutil + shutil.copyfile(tmp_in_png.name, f'/tmp/gerbolyze-fail-{test_in_svg.stem}-in.png') + shutil.copyfile(tmp_out_png.name, f'/tmp/gerbolyze-fail-{test_in_svg.stem}-out.png') + foo = list(e.args) + foo[0] += '\nFailing test renderings copied to:\n' + foo[0] += f' /tmp/gerbolyze-fail-{test_in_svg.stem}-{{in|out}}.png\n' + e.args = tuple(foo) + raise e + +for test_in_svg in Path('testdata/svg').glob('*.svg'): + # We need to make sure we capture the loop variable's current value here. + gen = lambda testcase: lambda self: self.run_svg_round_trip_test(testcase) + setattr(SVGRoundTripTests, f'test_{test_in_svg.stem}', gen(test_in_svg)) + +if __name__ == '__main__': + unittest.main() diff --git a/svg-flatten/testdata/svg/circles.svg b/svg-flatten/testdata/svg/circles.svg new file mode 100644 index 0000000..9be474e --- /dev/null +++ b/svg-flatten/testdata/svg/circles.svg @@ -0,0 +1,78 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/compound_xform.svg b/svg-flatten/testdata/svg/compound_xform.svg new file mode 100644 index 0000000..229e05d --- /dev/null +++ b/svg-flatten/testdata/svg/compound_xform.svg @@ -0,0 +1,102 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/empty.svg b/svg-flatten/testdata/svg/empty.svg new file mode 100644 index 0000000..d2cdc52 --- /dev/null +++ b/svg-flatten/testdata/svg/empty.svg @@ -0,0 +1,11 @@ + + + diff --git a/svg-flatten/testdata/svg/empty_inkscape.svg b/svg-flatten/testdata/svg/empty_inkscape.svg new file mode 100644 index 0000000..716379f --- /dev/null +++ b/svg-flatten/testdata/svg/empty_inkscape.svg @@ -0,0 +1,54 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/svg-flatten/testdata/svg/groups.svg b/svg-flatten/testdata/svg/groups.svg new file mode 100644 index 0000000..d94dad0 --- /dev/null +++ b/svg-flatten/testdata/svg/groups.svg @@ -0,0 +1,96 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/pattern_fill.svg b/svg-flatten/testdata/svg/pattern_fill.svg new file mode 100644 index 0000000..21789e6 --- /dev/null +++ b/svg-flatten/testdata/svg/pattern_fill.svg @@ -0,0 +1,135 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/pattern_stroke.svg b/svg-flatten/testdata/svg/pattern_stroke.svg new file mode 100644 index 0000000..5564df0 --- /dev/null +++ b/svg-flatten/testdata/svg/pattern_stroke.svg @@ -0,0 +1,89 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/pattern_stroke_dashed.svg b/svg-flatten/testdata/svg/pattern_stroke_dashed.svg new file mode 100644 index 0000000..3d8145e --- /dev/null +++ b/svg-flatten/testdata/svg/pattern_stroke_dashed.svg @@ -0,0 +1,89 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/rect.svg b/svg-flatten/testdata/svg/rect.svg new file mode 100644 index 0000000..297ff7e --- /dev/null +++ b/svg-flatten/testdata/svg/rect.svg @@ -0,0 +1,65 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/rect_occlusion.svg b/svg-flatten/testdata/svg/rect_occlusion.svg new file mode 100644 index 0000000..ce0e531 --- /dev/null +++ b/svg-flatten/testdata/svg/rect_occlusion.svg @@ -0,0 +1,79 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/rotation.svg b/svg-flatten/testdata/svg/rotation.svg new file mode 100644 index 0000000..961ef0f --- /dev/null +++ b/svg-flatten/testdata/svg/rotation.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/rotation_90.svg b/svg-flatten/testdata/svg/rotation_90.svg new file mode 100644 index 0000000..dcca867 --- /dev/null +++ b/svg-flatten/testdata/svg/rotation_90.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/scale.svg b/svg-flatten/testdata/svg/scale.svg new file mode 100644 index 0000000..91b28d6 --- /dev/null +++ b/svg-flatten/testdata/svg/scale.svg @@ -0,0 +1,91 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/shear.svg b/svg-flatten/testdata/svg/shear.svg new file mode 100644 index 0000000..ec7875f --- /dev/null +++ b/svg-flatten/testdata/svg/shear.svg @@ -0,0 +1,59 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/svg-flatten/testdata/svg/stroke.svg b/svg-flatten/testdata/svg/stroke.svg new file mode 100644 index 0000000..6a4b334 --- /dev/null +++ b/svg-flatten/testdata/svg/stroke.svg @@ -0,0 +1,67 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/stroke_caps.svg b/svg-flatten/testdata/svg/stroke_caps.svg new file mode 100644 index 0000000..6b89a34 --- /dev/null +++ b/svg-flatten/testdata/svg/stroke_caps.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/stroke_dashes.svg b/svg-flatten/testdata/svg/stroke_dashes.svg new file mode 100644 index 0000000..c1d6f5c --- /dev/null +++ b/svg-flatten/testdata/svg/stroke_dashes.svg @@ -0,0 +1,75 @@ + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/stroke_joins.svg b/svg-flatten/testdata/svg/stroke_joins.svg new file mode 100644 index 0000000..ee3e1ac --- /dev/null +++ b/svg-flatten/testdata/svg/stroke_joins.svg @@ -0,0 +1,68 @@ + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/svg-flatten/testdata/svg/text.svg b/svg-flatten/testdata/svg/text.svg new file mode 100644 index 0000000..bd8c390 --- /dev/null +++ b/svg-flatten/testdata/svg/text.svg @@ -0,0 +1,108 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + Gerbolyze + Gerbolyze + Gerbolyze + diff --git a/upstream/filesystem b/upstream/filesystem new file mode 160000 index 0000000..4e21ab3 --- /dev/null +++ b/upstream/filesystem @@ -0,0 +1 @@ +Subproject commit 4e21ab305794f5309a1454b4ae82ab9a0f5e0d25