[svg] Plumb a ResourceProvider
... for image loading.
Update the SVG tools to pass local/FS resource providers.
Change-Id: I2c0e446047da87f177fde0f23b7ea1f0a856e808
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/359996
Commit-Queue: Florin Malita <fmalita@google.com>
Reviewed-by: Tyler Denniston <tdenniston@google.com>
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 30645a0..8a8b354 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -1313,13 +1313,17 @@
: fName(SkOSPath::Basename(path.c_str()))
, fScale(1) {
- sk_sp<SkData> data(SkData::MakeFromFileName(path.c_str()));
- if (!data) {
+ auto stream = SkStream::MakeFromFile(path.c_str());
+ if (!stream) {
return;
}
- SkMemoryStream stream(std::move(data));
- fDom = SkSVGDOM::MakeFromStream(stream);
+ auto rp = skresources::DataURIResourceProviderProxy::Make(
+ skresources::FileResourceProvider::Make(SkOSPath::Dirname(path.c_str()),
+ /*predecode=*/true),
+ /*predecode=*/true);
+ fDom = SkSVGDOM::Builder().setResourceProvider(std::move(rp))
+ .make(*stream);
if (!fDom) {
return;
}
diff --git a/modules/svg/BUILD.gn b/modules/svg/BUILD.gn
index 6f5a4d3..e1a6056 100644
--- a/modules/svg/BUILD.gn
+++ b/modules/svg/BUILD.gn
@@ -20,6 +20,7 @@
configs += [ "../../:skia_private" ]
deps = [
"../..:skia",
+ "../skresources",
"../skshaper",
]
}
diff --git a/modules/svg/include/SkSVGDOM.h b/modules/svg/include/SkSVGDOM.h
index 2c0bc27..c9e0b31 100644
--- a/modules/svg/include/SkSVGDOM.h
+++ b/modules/svg/include/SkSVGDOM.h
@@ -12,6 +12,7 @@
#include "include/core/SkRefCnt.h"
#include "include/core/SkSize.h"
#include "include/private/SkTemplates.h"
+#include "modules/skresources/include/SkResources.h"
#include "modules/svg/include/SkSVGIDMapper.h"
class SkCanvas;
@@ -29,10 +30,16 @@
*/
Builder& setFontManager(sk_sp<SkFontMgr>);
+ /**
+ * Specify a resource provider for loading images etc.
+ */
+ Builder& setResourceProvider(sk_sp<skresources::ResourceProvider>);
+
sk_sp<SkSVGDOM> make(SkStream&) const;
private:
- sk_sp<SkFontMgr> fFontMgr;
+ sk_sp<SkFontMgr> fFontMgr;
+ sk_sp<skresources::ResourceProvider> fResourceProvider;
};
static sk_sp<SkSVGDOM> MakeFromStream(SkStream& str) {
@@ -48,11 +55,13 @@
void render(SkCanvas*) const;
private:
- SkSVGDOM(sk_sp<SkSVGSVG>, sk_sp<SkFontMgr>, SkSVGIDMapper&&);
+ SkSVGDOM(sk_sp<SkSVGSVG>, sk_sp<SkFontMgr>, sk_sp<skresources::ResourceProvider>,
+ SkSVGIDMapper&&);
- const sk_sp<SkSVGSVG> fRoot;
- const sk_sp<SkFontMgr> fFontMgr;
- const SkSVGIDMapper fIDMapper;
+ const sk_sp<SkSVGSVG> fRoot;
+ const sk_sp<SkFontMgr> fFontMgr;
+ const sk_sp<skresources::ResourceProvider> fResourceProvider;
+ const SkSVGIDMapper fIDMapper;
SkSize fContainerSize;
};
diff --git a/modules/svg/include/SkSVGRenderContext.h b/modules/svg/include/SkSVGRenderContext.h
index 5be4e37..981756a 100644
--- a/modules/svg/include/SkSVGRenderContext.h
+++ b/modules/svg/include/SkSVGRenderContext.h
@@ -14,6 +14,7 @@
#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/core/SkTypes.h"
+#include "modules/skresources/include/SkResources.h"
#include "modules/svg/include/SkSVGAttribute.h"
#include "modules/svg/include/SkSVGIDMapper.h"
#include "src/core/SkTLazy.h"
@@ -55,7 +56,8 @@
class SkSVGRenderContext {
public:
- SkSVGRenderContext(SkCanvas*, const sk_sp<SkFontMgr>&, const SkSVGIDMapper&,
+ SkSVGRenderContext(SkCanvas*, const sk_sp<SkFontMgr>&,
+ const sk_sp<skresources::ResourceProvider>&, const SkSVGIDMapper&,
const SkSVGLengthContext&, const SkSVGPresentationContext&,
const SkSVGNode*);
SkSVGRenderContext(const SkSVGRenderContext&);
@@ -145,6 +147,7 @@
SkTLazy<SkPaint> commonPaint(const SkSVGPaint&, float opacity) const;
const sk_sp<SkFontMgr>& fFontMgr;
+ const sk_sp<skresources::ResourceProvider>& fResourceProvider;
const SkSVGIDMapper& fIDMapper;
SkTCopyOnFirstWrite<SkSVGLengthContext> fLengthContext;
SkTCopyOnFirstWrite<SkSVGPresentationContext> fPresentationContext;
diff --git a/modules/svg/src/SkSVGDOM.cpp b/modules/svg/src/SkSVGDOM.cpp
index e562b53..08b8c65 100644
--- a/modules/svg/src/SkSVGDOM.cpp
+++ b/modules/svg/src/SkSVGDOM.cpp
@@ -410,6 +410,11 @@
return *this;
}
+SkSVGDOM::Builder& SkSVGDOM::Builder::setResourceProvider(sk_sp<skresources::ResourceProvider> rp) {
+ fResourceProvider = std::move(rp);
+ return *this;
+}
+
sk_sp<SkSVGDOM> SkSVGDOM::Builder::make(SkStream& str) const {
SkDOM xmlDom;
if (!xmlDom.build(str)) {
@@ -424,22 +429,35 @@
return nullptr;
}
+ class NullResourceProvider final : public skresources::ResourceProvider {
+ sk_sp<SkData> load(const char[], const char[]) const override { return nullptr; }
+ };
+
+ auto resource_provider = fResourceProvider ? fResourceProvider
+ : sk_make_sp<NullResourceProvider>();
+
return sk_sp<SkSVGDOM>(new SkSVGDOM(sk_sp<SkSVGSVG>(static_cast<SkSVGSVG*>(root.release())),
- std::move(fFontMgr), std::move(mapper)));
+ std::move(fFontMgr), std::move(resource_provider),
+ std::move(mapper)));
}
-SkSVGDOM::SkSVGDOM(sk_sp<SkSVGSVG> root, sk_sp<SkFontMgr> fmgr, SkSVGIDMapper&& mapper)
+SkSVGDOM::SkSVGDOM(sk_sp<SkSVGSVG> root, sk_sp<SkFontMgr> fmgr,
+ sk_sp<skresources::ResourceProvider> rp, SkSVGIDMapper&& mapper)
: fRoot(std::move(root))
, fFontMgr(std::move(fmgr))
+ , fResourceProvider(std::move(rp))
, fIDMapper(std::move(mapper))
, fContainerSize(fRoot->intrinsicSize(SkSVGLengthContext(SkSize::Make(0, 0))))
-{}
+{
+ SkASSERT(fResourceProvider);
+}
void SkSVGDOM::render(SkCanvas* canvas) const {
if (fRoot) {
SkSVGLengthContext lctx(fContainerSize);
SkSVGPresentationContext pctx;
- fRoot->render(SkSVGRenderContext(canvas, fFontMgr, fIDMapper, lctx, pctx, nullptr));
+ fRoot->render(SkSVGRenderContext(canvas, fFontMgr, fResourceProvider, fIDMapper, lctx, pctx,
+ nullptr));
}
}
diff --git a/modules/svg/src/SkSVGRenderContext.cpp b/modules/svg/src/SkSVGRenderContext.cpp
index 563f8db..db5191a 100644
--- a/modules/svg/src/SkSVGRenderContext.cpp
+++ b/modules/svg/src/SkSVGRenderContext.cpp
@@ -145,11 +145,13 @@
SkSVGRenderContext::SkSVGRenderContext(SkCanvas* canvas,
const sk_sp<SkFontMgr>& fmgr,
+ const sk_sp<skresources::ResourceProvider>& rp,
const SkSVGIDMapper& mapper,
const SkSVGLengthContext& lctx,
const SkSVGPresentationContext& pctx,
const SkSVGNode* node)
: fFontMgr(fmgr)
+ , fResourceProvider(rp)
, fIDMapper(mapper)
, fLengthContext(lctx)
, fPresentationContext(pctx)
@@ -160,6 +162,7 @@
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other)
: SkSVGRenderContext(other.fCanvas,
other.fFontMgr,
+ other.fResourceProvider,
other.fIDMapper,
*other.fLengthContext,
*other.fPresentationContext,
@@ -168,6 +171,7 @@
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other, SkCanvas* canvas)
: SkSVGRenderContext(canvas,
other.fFontMgr,
+ other.fResourceProvider,
other.fIDMapper,
*other.fLengthContext,
*other.fPresentationContext,
@@ -176,6 +180,7 @@
SkSVGRenderContext::SkSVGRenderContext(const SkSVGRenderContext& other, const SkSVGNode* node)
: SkSVGRenderContext(other.fCanvas,
other.fFontMgr,
+ other.fResourceProvider,
other.fIDMapper,
*other.fLengthContext,
*other.fPresentationContext,
@@ -390,6 +395,7 @@
SkSVGPresentationContext pctx;
SkSVGRenderContext local_ctx(fCanvas,
fFontMgr,
+ fResourceProvider,
fIDMapper,
*fLengthContext,
pctx,
diff --git a/modules/svg/tests/Text.cpp b/modules/svg/tests/Text.cpp
index 107395b..7308ac8 100644
--- a/modules/svg/tests/Text.cpp
+++ b/modules/svg/tests/Text.cpp
@@ -162,7 +162,8 @@
const SkSVGPresentationContext pctx;
SkNoDrawCanvas canvas(0, 0);
sk_sp<SkFontMgr> fmgr;
- const SkSVGRenderContext ctx(&canvas, fmgr, mapper, lctx, pctx, nullptr);
+ sk_sp<skresources::ResourceProvider> rp;
+ const SkSVGRenderContext ctx(&canvas, fmgr, rp, mapper, lctx, pctx, nullptr);
SkSVGTextContext tctx(ctx, mock_cb);
SkSVGTextContext::ScopedPosResolver pa(*a, lctx, &tctx, tst.offseta);
diff --git a/modules/svg/utils/SvgTool.cpp b/modules/svg/utils/SvgTool.cpp
index 71ab3c3..7ee49a2 100644
--- a/modules/svg/utils/SvgTool.cpp
+++ b/modules/svg/utils/SvgTool.cpp
@@ -11,7 +11,9 @@
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/encode/SkPngEncoder.h"
+#include "modules/skresources/include/SkResources.h"
#include "modules/svg/include/SkSVGDOM.h"
+#include "src/utils/SkOSPath.h"
#include "tools/flags/CommandLineFlags.h"
static DEFINE_string2(input , i, nullptr, "Input SVG file.");
@@ -39,9 +41,14 @@
return 1;
}
+ auto rp = skresources::DataURIResourceProviderProxy::Make(
+ skresources::FileResourceProvider::Make(SkOSPath::Dirname(FLAGS_input[0]),
+ /*predecode=*/true),
+ /*predecode=*/true);
auto svg_dom = SkSVGDOM::Builder()
.setFontManager(SkFontMgr::RefDefault())
+ .setResourceProvider(std::move(rp))
.make(in);
if (!svg_dom) {
std::cerr << "Could not parse " << FLAGS_input[0] << "\n";
diff --git a/tools/viewer/SvgSlide.cpp b/tools/viewer/SvgSlide.cpp
index 28bdb21..2bab0ae 100644
--- a/tools/viewer/SvgSlide.cpp
+++ b/tools/viewer/SvgSlide.cpp
@@ -11,27 +11,31 @@
#include "include/core/SkCanvas.h"
#include "include/core/SkStream.h"
+#include "modules/skresources/include/SkResources.h"
#include "modules/svg/include/SkSVGDOM.h"
+#include "src/utils/SkOSPath.h"
SvgSlide::SvgSlide(const SkString& name, const SkString& path)
- : SvgSlide(name, SkStream::MakeFromFile(path.c_str())) {
-}
-
-SvgSlide::SvgSlide(const SkString& name, std::unique_ptr<SkStream> stream)
- : fStream(std::move(stream)) {
+ : fPath(path)
+{
fName = name;
}
void SvgSlide::load(SkScalar w, SkScalar h) {
- if (!fStream) {
- SkDebugf("No svg stream for slide %s.\n", fName.c_str());
+ auto stream = SkStream::MakeFromFile(fPath.c_str());
+
+ if (!stream) {
+ SkDebugf("Could not open %s.\n", fPath.c_str());
return;
}
fWinSize = SkSize::Make(w, h);
- fStream->rewind();
- fDom = SkSVGDOM::MakeFromStream(*fStream);
+ auto rp = skresources::DataURIResourceProviderProxy::Make(
+ skresources::FileResourceProvider::Make(SkOSPath::Dirname(fPath.c_str()),
+ /*predecode=*/true),
+ /*predecode=*/true);
+ fDom = SkSVGDOM::Builder().setResourceProvider(std::move(rp)).make(*stream);
if (fDom) {
fDom->setContainerSize(fWinSize);
}
diff --git a/tools/viewer/SvgSlide.h b/tools/viewer/SvgSlide.h
index fa10ffe..895e3fc 100644
--- a/tools/viewer/SvgSlide.h
+++ b/tools/viewer/SvgSlide.h
@@ -15,7 +15,6 @@
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;
@@ -25,8 +24,9 @@
void draw(SkCanvas*) override;
private:
- std::unique_ptr<SkStream> fStream;
- SkSize fWinSize = SkSize::MakeEmpty();
+ const SkString fPath;
+
+ SkSize fWinSize = SkSize::MakeEmpty();
sk_sp<SkSVGDOM> fDom;
using INHERITED = Slide;