Add svg parsing to CanvasKit viewer.html
Also enables ccpr and makes flags parsing more robust.
Change-Id: Ia98467403de87423a63167681b2ee635b0fa593a
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/292690
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/modules/canvaskit/BUILD.gn b/modules/canvaskit/BUILD.gn
index be152b2..861db54 100644
--- a/modules/canvaskit/BUILD.gn
+++ b/modules/canvaskit/BUILD.gn
@@ -9,6 +9,7 @@
sources = [
"../../tools/viewer/SKPSlide.cpp",
"../../tools/viewer/SampleSlide.cpp",
+ "../../tools/viewer/SvgSlide.cpp",
]
deps = [ "../..:samples" ]
}
diff --git a/modules/canvaskit/canvaskit/viewer.html b/modules/canvaskit/canvaskit/viewer.html
index e890554..c5c46d1 100644
--- a/modules/canvaskit/canvaskit/viewer.html
+++ b/modules/canvaskit/canvaskit/viewer.html
@@ -17,8 +17,9 @@
<script type="text/javascript" charset="utf-8">
const flags = {};
for (pair of location.hash.substring(1).split(',')) {
- const [key, value] = pair.split(':', 2);
- flags[key] = value;
+ // Parse "values" as an array in case the value has a colon (e.g., "slide:http://...").
+ const [key, ...values] = pair.split(':');
+ flags[key] = values.join(':');
}
window.onhashchange = function() {
location.reload();
@@ -35,22 +36,22 @@
});
function LoadSlide(CanvasKit) {
- if (!CanvasKit.MakeSlide || !CanvasKit.MakeSkpSlide) {
+ if (!CanvasKit.MakeSlide || !CanvasKit.MakeSkpSlide || !CanvasKit.MakeSvgSlide) {
throw 'Not compiled with Viewer.';
}
const slideName = flags.slide || 'WavyPathText';
- if (slideName.endsWith('.skp')) {
+ if (slideName.endsWith('.skp') || slideName.endsWith('.svg')) {
fetch(slideName).then(function(response) {
if (response.status != 200) {
throw 'Error fetching ' + slideName;
}
- response.arrayBuffer().then(function(data) {
- let slide = CanvasKit.MakeSkpSlide(slideName, data);
- if (!slide) {
- throw 'Could not parse skp data for slide ' + slideName;
- }
- ViewerMain(CanvasKit, slide);
- });
+ if (slideName.endsWith('.skp')) {
+ response.arrayBuffer().then((data) => ViewerMain(
+ CanvasKit, CanvasKit.MakeSkpSlide(slideName, data)));
+ } else {
+ response.text().then((text) => ViewerMain(
+ CanvasKit, CanvasKit.MakeSvgSlide(slideName, text)));
+ }
});
} else {
let slide = CanvasKit.MakeSlide(slideName);
diff --git a/modules/canvaskit/compile.sh b/modules/canvaskit/compile.sh
index e2eb513..6fcf1b0 100755
--- a/modules/canvaskit/compile.sh
+++ b/modules/canvaskit/compile.sh
@@ -90,11 +90,13 @@
SKOTTIE_BINDINGS=""
fi
+GN_VIEWER="skia_use_expat=false skia_enable_ccpr=false"
VIEWER_BINDINGS=""
VIEWER_LIB=""
if [[ $@ == *viewer* ]]; then
echo "Including viewer"
+ GN_VIEWER="skia_use_expat=true skia_enable_ccpr=true"
VIEWER_BINDINGS="$BASE_DIR/viewer_bindings.cpp"
VIEWER_LIB="$BUILD_DIR/libviewer_wasm.a"
IS_OFFICIAL_BUILD="false"
@@ -268,7 +270,6 @@
skia_use_angle=false \
skia_use_dng_sdk=false \
skia_use_egl=true \
- skia_use_expat=false \
skia_use_fontconfig=false \
skia_use_freetype=true \
skia_use_libheif=false \
@@ -293,9 +294,9 @@
${GN_GPU} \
${GN_FONT} \
${GN_PARTICLES} \
+ ${GN_VIEWER} \
\
skia_enable_skshaper=true \
- skia_enable_ccpr=false \
skia_enable_nvpr=false \
skia_enable_skparagraph=true \
skia_enable_pdf=false"
diff --git a/modules/canvaskit/viewer_bindings.cpp b/modules/canvaskit/viewer_bindings.cpp
index 9f34ee5..6a6e4bc 100644
--- a/modules/canvaskit/viewer_bindings.cpp
+++ b/modules/canvaskit/viewer_bindings.cpp
@@ -12,6 +12,7 @@
#include "include/gpu/GrContext.h"
#include "tools/viewer/SKPSlide.h"
#include "tools/viewer/SampleSlide.h"
+#include "tools/viewer/SvgSlide.h"
#include <GLES3/gl3.h>
#include <string>
@@ -31,6 +32,12 @@
return sk_make_sp<SKPSlide>(SkString(name.c_str()), std::move(stream));
}
+sk_sp<Slide> MakeSvgSlide(std::string name, std::string svgText) {
+ auto stream = std::make_unique<SkMemoryStream>(svgText.data(), svgText.size(),
+ /*copyData=*/true);
+ return sk_make_sp<SvgSlide>(SkString(name.c_str()), std::move(stream));
+}
+
static void delete_wrapped_framebuffer(SkSurface::ReleaseContext context) {
GLuint framebuffer = (GLuint)context;
glDeleteFramebuffers(1, &framebuffer);
@@ -96,6 +103,7 @@
EMSCRIPTEN_BINDINGS(Viewer) {
function("MakeSlide", &MakeSlide);
function("MakeSkpSlide", &MakeSkpSlide);
+ function("MakeSvgSlide", &MakeSvgSlide);
function("MakeOffscreenFramebuffer", &MakeOffscreenFramebuffer);
function("BlitOffscreenFramebuffer", &BlitOffscreenFramebuffer);
class_<Slide>("Slide")
diff --git a/tools/viewer/SvgSlide.cpp b/tools/viewer/SvgSlide.cpp
index 3779ffd..c420843 100644
--- a/tools/viewer/SvgSlide.cpp
+++ b/tools/viewer/SvgSlide.cpp
@@ -14,18 +14,26 @@
#include "include/core/SkStream.h"
SvgSlide::SvgSlide(const SkString& name, const SkString& path)
- : fPath(path) {
+ : SvgSlide(name, SkStream::MakeFromFile(path.c_str())) {
+}
+
+SvgSlide::SvgSlide(const SkString& name, std::unique_ptr<SkStream> stream)
+ : fStream(std::move(stream)) {
fName = name;
}
void SvgSlide::load(SkScalar w, SkScalar h) {
- fWinSize = SkSize::Make(w, h);
+ if (!fStream) {
+ SkDebugf("No svg stream for slide %s.\n", fName.c_str());
+ return;
+ }
- if (const auto svgStream = SkStream::MakeFromFile(fPath.c_str())) {
- fDom = SkSVGDOM::MakeFromStream(*svgStream);
- if (fDom) {
- fDom->setContainerSize(fWinSize);
- }
+ fWinSize = SkSize::Make(w, h);
+
+ fStream->rewind();
+ fDom = SkSVGDOM::MakeFromStream(*fStream);
+ if (fDom) {
+ fDom->setContainerSize(fWinSize);
}
}
diff --git a/tools/viewer/SvgSlide.h b/tools/viewer/SvgSlide.h
index ccc840e..6a15a30 100644
--- a/tools/viewer/SvgSlide.h
+++ b/tools/viewer/SvgSlide.h
@@ -15,6 +15,7 @@
class SvgSlide final : public Slide {
public:
SvgSlide(const SkString& name, const SkString& path);
+ SvgSlide(const SkString& name, std::unique_ptr<SkStream>);
void load(SkScalar winWidth, SkScalar winHeight) override;
void unload() override;
@@ -24,9 +25,8 @@
void draw(SkCanvas*) override;
private:
- const SkString fPath;
-
- SkSize fWinSize = SkSize::MakeEmpty();
+ std::unique_ptr<SkStream> fStream;
+ SkSize fWinSize = SkSize::MakeEmpty();
sk_sp<SkSVGDOM> fDom;
typedef Slide INHERITED;