From 2616cf46ff2005d36ff0481f602d7cb1bfebc8ea Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 30 Sep 2021 20:37:32 +0200 Subject: svg-flatten: Add forwarding logic for usvg font options --- svg-flatten/src/main.cpp | 53 ++++++++++++++++++++++++++------ svg-flatten/src/test/nopencv_test.cpp | 2 +- svg-flatten/src/util.cpp | 41 ++++++++++++++---------- svg-flatten/src/util.h | 5 ++- svg-flatten/svg_flatten_wasi/__init__.py | 36 +++++++++++++++++++--- 5 files changed, 104 insertions(+), 33 deletions(-) diff --git a/svg-flatten/src/main.cpp b/svg-flatten/src/main.cpp index e259881..817ba67 100644 --- a/svg-flatten/src/main.cpp +++ b/svg-flatten/src/main.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -120,16 +121,26 @@ int main(int argc, char **argv) { {"skip_usvg", {"--no-usvg"}, "Do not preprocess input using usvg (do not use unless you know *exactly* what you're doing)", 0}, - {"usvg_dpi", {"--usvg-dpi"}, - "Passed through to usvg's --dpi, in case the input file has different ideas of DPI than usvg has.", - 1}, {"scale", {"--scale"}, "Scale input svg lengths by this factor (-o gerber only).", 1}, {"exclude_groups", {"-e", "--exclude-groups"}, "Comma-separated list of group IDs to exclude from export. Takes precedence over --only-groups.", 1}, - + /* Forwarded USVG options */ + {"usvg-dpi", {"--usvg-dpi"}, + "Passed through to usvg's --dpi, in case the input file has different ideas of DPI than usvg has.", + 1}, + {"usvg-font-family", {"--usvg-font-family"}, "", 1}, + {"usvg-font-size", {"--usvg-font-size"}, "", 1}, + {"usvg-serif-family", {"--usvg-serif-family"}, "", 1}, + {"usvg-sans-serif-family", {"--usvg-sans-serif-family"}, "", 1}, + {"usvg-cursive-family", {"--usvg-cursive-family"}, "", 1}, + {"usvg-fantasy-family", {"--usvg-fantasy-family"}, "", 1}, + {"usvg-monospace-family", {"--usvg-monospace-family"}, "", 1}, + {"usvg-use-font-file", {"--usvg-use-font-file"}, "", 1}, + {"usvg-use-fonts-dir", {"--usvg-use-fonts-dir"}, "", 1}, + {"usvg-skip-system-fonts", {"--usvg-skip-system-fonts"}, "", 0}, }}; @@ -366,15 +377,37 @@ int main(int argc, char **argv) { frob = barf; } else { +#ifndef NOFORK //cerr << "calling usvg on " << barf << " and " << frob << endl; - int dpi = 96; - if (args["usvg_dpi"]) { - dpi = args["usvg_dpi"].as(); + vector command_line = {"--keep-named-groups"}; + + string options[] = { + "usvg-dpi", + "usvg-font-family", + "usvg-font-size", + "usvg-serif-family", + "usvg-sans-serif-family", + "usvg-cursive-family", + "usvg-fantasy-family", + "usvg-monospace-family", + "usvg-use-font-file", + "usvg-use-fonts-dir", + }; + + for (string &opt : options) { + if (args[opt.c_str()]) { + command_line.push_back("--" + opt.substr(5)); + command_line.push_back(args[opt.c_str()]); + } + } + + if (args["usvg-skip-system-fonts"]) { + command_line.push_back("--skip-system-fonts"); } - string dpi_str = to_string(dpi); + + command_line.push_back(barf); + command_line.push_back(frob); -#ifndef NOFORK - const char *command_line[] = {nullptr, "--keep-named-groups", "--dpi", dpi_str.c_str(), barf.c_str(), frob.c_str(), nullptr}; if (run_cargo_command("usvg", command_line, "USVG")) { return EXIT_FAILURE; } diff --git a/svg-flatten/src/test/nopencv_test.cpp b/svg-flatten/src/test/nopencv_test.cpp index 13be6f8..204ee59 100644 --- a/svg-flatten/src/test/nopencv_test.cpp +++ b/svg-flatten/src/test/nopencv_test.cpp @@ -159,7 +159,7 @@ MU_TEST(test_complex_example_from_paper) { } int render_svg(const char *in_svg, const char *out_png) { - const char *command_line[] = {nullptr, in_svg, out_png, nullptr}; + vector command_line = {in_svg, out_png}; return run_cargo_command("resvg", command_line, "RESVG"); } diff --git a/svg-flatten/src/util.cpp b/svg-flatten/src/util.cpp index d9a5a09..0597360 100644 --- a/svg-flatten/src/util.cpp +++ b/svg-flatten/src/util.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #ifndef NOFORK #include @@ -11,16 +12,24 @@ #include "util.h" -using namespace std; - #ifndef NOFORK -int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar) { +int gerbolyze::run_cargo_command(const char *cmd_name, std::vector &cmdline, const char *envvar) { + + //std::cerr << "Running command: " << cmd_name << " "; + std::vector cmdline_c = {nullptr}; + for (std::string &s : cmdline) { + //std::cerr << s << " "; + cmdline_c.push_back(s.c_str()); + } + cmdline_c.push_back(nullptr); + //std::cerr << std::endl; + const char *homedir; if ((homedir = getenv("HOME")) == NULL) { homedir = getpwuid(getuid())->pw_dir; } - string homedir_s(homedir); - string cargo_bin_dir = homedir_s + "/.cargo/bin/" + cmd_name; + std::string homedir_s(homedir); + std::string cargo_bin_dir = homedir_s + "/.cargo/bin/" + cmd_name; bool found = false; int proc_rc = -1; @@ -31,36 +40,36 @@ int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], co if ((envvar_val = getenv(envvar)) == NULL) { continue; } else { - cmdline[0] = envvar_val; + cmdline_c[0] = envvar_val; } break; case 1: - cmdline[0] = cmd_name; + cmdline_c[0] = cmd_name; break; case 2: - cmdline[0] = cargo_bin_dir.c_str(); + cmdline_c[0] = cargo_bin_dir.c_str(); break; } struct subprocess_s subprocess; - int rc = subprocess_create(cmdline, subprocess_option_inherit_environment, &subprocess); + int rc = subprocess_create(cmdline_c.data(), subprocess_option_inherit_environment, &subprocess); if (rc) { - cerr << "Error calling " << cmd_name << endl; + std::cerr << "Error calling " << cmd_name << std::endl; return EXIT_FAILURE; } proc_rc = -1; rc = subprocess_join(&subprocess, &proc_rc); if (rc) { - cerr << "Error calling " << cmd_name << endl; + std::cerr << "Error calling " << cmd_name << std::endl; return EXIT_FAILURE; } rc = subprocess_destroy(&subprocess); if (rc) { - cerr << "Error calling " << cmd_name << endl; + std::cerr << "Error calling " << cmd_name << std::endl; return EXIT_FAILURE; } @@ -73,21 +82,21 @@ int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], co } if (!found) { - cerr << "Error: Cannot find " << cmd_name << ". Is it installed and in $PATH?" << endl; + std::cerr << "Error: Cannot find " << cmd_name << ". Is it installed and in $PATH?" << std::endl; return EXIT_FAILURE; } if (proc_rc) { - cerr << cmd_name << " returned an error code: " << proc_rc << endl; + std::cerr << cmd_name << " returned an error code: " << proc_rc << std::endl; return EXIT_FAILURE; } return 0; } #else -int gerbolyze::run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar) { +int gerbolyze::run_cargo_command(const char *cmd_name, std::vector &cmdline, const char *envvar) { (void) cmd_name, (void) cmdline, (void) envvar; - cerr << "Error: Cannot spawn " << cmd_name << " subprocess since binary was built with fork/exec disabled (-DNOFORK=1)" << endl; + std::cerr << "Error: Cannot spawn " << cmd_name << " subprocess since binary was built with fork/exec disabled (-DNOFORK=1)" << std::endl; return EXIT_FAILURE; } #endif diff --git a/svg-flatten/src/util.h b/svg-flatten/src/util.h index f3fbe32..bed915b 100644 --- a/svg-flatten/src/util.h +++ b/svg-flatten/src/util.h @@ -18,7 +18,10 @@ #pragma once +#include +#include + namespace gerbolyze { -int run_cargo_command(const char *cmd_name, const char *cmdline[], const char *envvar); +int run_cargo_command(const char *cmd_name, std::vector &cmdline, const char *envvar); } diff --git a/svg-flatten/svg_flatten_wasi/__init__.py b/svg-flatten/svg_flatten_wasi/__init__.py index 3b35b1f..be57cba 100644 --- a/svg-flatten/svg_flatten_wasi/__init__.py +++ b/svg-flatten/svg_flatten_wasi/__init__.py @@ -73,8 +73,21 @@ def _run_wasm_app(wasm_filename, argv, cachedir="svg-flatten-wasi"): return trap.code -def run_usvg(input_file, output_file, dpi=96): - args = ['--keep-named-groups', '--dpi', str(dpi), input_file, output_file] +def run_usvg(input_file, output_file, **usvg_args): + + args = ['--keep-named-groups'] + for key, value in usvg_args.items(): + if value is not None: + if value is False: + continue + + args.append(f'--{key.replace("_", "-")[5:]}') + + if value is not True: + args.append(value) + + args += [input_file, output_file] + print(args) # By default, try a number of options: candidates = [ @@ -106,15 +119,28 @@ def run_usvg(input_file, output_file, dpi=96): @click.command(context_settings={'ignore_unknown_options': True}) @click.option('--no-usvg', is_flag=True) -@click.option('--usvg-dpi', type=int, default=96) +# Options forwarded to USVG +@click.option('--usvg-dpi') +@click.option('--usvg-font-family') +@click.option('--usvg-font-size') +@click.option('--usvg-serif-family') +@click.option('--usvg-sans-serif-family') +@click.option('--usvg-cursive-family') +@click.option('--usvg-fantasy-family') +@click.option('--usvg-monospace-family') +@click.option('--usvg-use-font-file') +@click.option('--usvg-use-fonts-dir') +@click.option('--usvg-skip-system-fonts', is_flag=True) +# Catch-all argument to forward options to svg-flatten @click.argument('other_args', nargs=-1, type=click.UNPROCESSED) +# Input/output file @click.argument('input_file', type=click.Path(resolve_path=True, dir_okay=False)) @click.argument('output_file', type=click.Path(resolve_path=True, dir_okay=False, writable=True)) -def run_svg_flatten(input_file, output_file, other_args, usvg_dpi, no_usvg): +def run_svg_flatten(input_file, output_file, other_args, no_usvg, **usvg_args): with tempfile.NamedTemporaryFile() as f: if not no_usvg: - run_usvg(input_file, f.name, dpi=usvg_dpi) + run_usvg(input_file, f.name, **usvg_args) input_file = f.name cmdline = ['svg-flatten', '--force-svg', '--no-usvg', *other_args, input_file, output_file] -- cgit