Reland [svg] Add svg_tool

A simple svg -> png converter, to demonstrate basic API usage.

TBR=

Change-Id: Id723946e2c1cbdaf324a24202279cb6a6d7082b6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/325460
Reviewed-by: Florin Malita <fmalita@google.com>
Commit-Queue: Florin Malita <fmalita@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 66b957d..1021b43 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1901,6 +1901,7 @@
     ]
   }
 
+  # TODO(fmalita): componentize & relocate
   test_lib("experimental_svg_model") {
     if (skia_use_expat) {
       sources = [
@@ -1936,6 +1937,16 @@
     }
   }
 
+  if (skia_use_expat && !skia_use_wuffs) {
+    test_app("svg_tool") {
+      sources = [ "experimental/svg/utils/SvgTool.cpp" ]
+      deps = [
+        ":experimental_svg_model",
+        ":flags",
+      ]
+    }
+  }
+
   test_lib("experimental_xform") {
     sources = [
       "experimental/xform/SkShape.cpp",
diff --git a/experimental/svg/utils/SvgTool.cpp b/experimental/svg/utils/SvgTool.cpp
new file mode 100644
index 0000000..34236f6
--- /dev/null
+++ b/experimental/svg/utils/SvgTool.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <iostream>
+
+#include "experimental/svg/model/SkSVGDOM.h"
+#include "include/core/SkMatrix.h"
+#include "include/core/SkStream.h"
+#include "include/core/SkSurface.h"
+#include "include/encode/SkPngEncoder.h"
+#include "tools/flags/CommandLineFlags.h"
+
+static DEFINE_string2(input , i, nullptr, "Input SVG file.");
+static DEFINE_string2(output, o, nullptr, "Output PNG file.");
+
+static DEFINE_int(width , 1024, "Output width.");
+static DEFINE_int(height, 1024, "Output height.");
+
+int main(int argc, char** argv) {
+    CommandLineFlags::Parse(argc, argv);
+
+    if (FLAGS_input.isEmpty() || FLAGS_output.isEmpty()) {
+        std::cerr << "Missing required 'input' and 'output' args.\n";
+        return 1;
+    }
+
+    if (FLAGS_width <= 0 || FLAGS_height <= 0) {
+        std::cerr << "Invalid width/height.\n";
+        return 1;
+    }
+
+    SkFILEStream in(FLAGS_input[0]);
+    if (!in.isValid()) {
+        std::cerr << "Could not open " << FLAGS_input[0] << "\n";
+        return 1;
+    }
+
+    auto svg_dom = SkSVGDOM::MakeFromStream(in);
+    if (!svg_dom) {
+        std::cerr << "Could not parse " << FLAGS_input[0] << "\n";
+        return 1;
+    }
+
+    auto surface = SkSurface::MakeRasterN32Premul(FLAGS_width, FLAGS_height);
+
+    svg_dom->setContainerSize(SkSize::Make(FLAGS_width, FLAGS_height));
+    svg_dom->render(surface->getCanvas());
+
+    SkPixmap pixmap;
+    surface->peekPixels(&pixmap);
+
+    SkFILEWStream out(FLAGS_output[0]);
+    if (!out.isValid()) {
+        std::cerr << "Could not open " << FLAGS_output[0] << " for writing.\n";
+        return 1;
+    }
+
+    // Use default encoding options.
+    SkPngEncoder::Options png_options;
+
+    if (!SkPngEncoder::Encode(&out, pixmap, png_options)) {
+        std::cerr << "PNG encoding failed.\n";
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/public.bzl b/public.bzl
index f67fd40..f6f99c1 100644
--- a/public.bzl
+++ b/public.bzl
@@ -991,3 +991,14 @@
 
 def svg_lib_srcs():
     return native.glob(["experimental/svg/model/*.cpp"])
+
+################################################################################
+## svg_tool
+################################################################################
+
+SVG_TOOL_SRCS = [
+    "experimental/svg/utils/SvgTool.cpp",
+    # TODO(benjaminwagner): Add "flags" target.
+    "tools/flags/CommandLineFlags.cpp",
+    "tools/flags/CommandLineFlags.h",
+]