[svg] Refactor SkSVGImage to expose image loading
This is in preparation for reusing the image loading + aspect ratio mapping for <feImage>. Change-Id: I53dcf904476aae386f672488379201524855a703 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/404217 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
parent
86f31f287e
commit
2992fb0d60
@ -11,6 +11,10 @@
|
||||
#include "modules/svg/include/SkSVGTransformableNode.h"
|
||||
#include "modules/svg/include/SkSVGTypes.h"
|
||||
|
||||
namespace skresources {
|
||||
class ResourceProvider;
|
||||
}
|
||||
|
||||
class SkSVGImage final : public SkSVGTransformableNode {
|
||||
public:
|
||||
static sk_sp<SkSVGImage> Make() {
|
||||
@ -26,6 +30,15 @@ public:
|
||||
SkPath onAsPath(const SkSVGRenderContext&) const override;
|
||||
SkRect onObjectBoundingBox(const SkSVGRenderContext&) const override;
|
||||
|
||||
struct ImageInfo {
|
||||
sk_sp<SkImage> fImage;
|
||||
SkRect fDst;
|
||||
};
|
||||
static ImageInfo LoadImage(const sk_sp<skresources::ResourceProvider>&,
|
||||
const SkSVGIRI&,
|
||||
const SkRect&,
|
||||
SkSVGPreserveAspectRatio);
|
||||
|
||||
SVG_ATTR(X , SkSVGLength , SkSVGLength(0))
|
||||
SVG_ATTR(Y , SkSVGLength , SkSVGLength(0))
|
||||
SVG_ATTR(Width , SkSVGLength , SkSVGLength(0))
|
||||
@ -39,8 +52,6 @@ protected:
|
||||
private:
|
||||
SkSVGImage() : INHERITED(SkSVGTag::kImage) {}
|
||||
|
||||
SkRect resolveImageRect(const SkRect&, const SkRect&) const;
|
||||
|
||||
using INHERITED = SkSVGTransformableNode;
|
||||
};
|
||||
|
||||
|
@ -54,32 +54,42 @@ static sk_sp<SkImage> LoadImage(const sk_sp<skresources::ResourceProvider>& rp,
|
||||
return imageAsset ? imageAsset->getFrameData(0).image : nullptr;
|
||||
}
|
||||
|
||||
SkRect SkSVGImage::resolveImageRect(const SkRect& viewBox, const SkRect& viewPort) const {
|
||||
const SkMatrix m = ComputeViewboxMatrix(viewBox, viewPort, fPreserveAspectRatio);
|
||||
// Map and place at x, y specified by image attributes
|
||||
return m.mapRect(viewBox).makeOffset(viewPort.fLeft, viewPort.fTop);
|
||||
}
|
||||
|
||||
void SkSVGImage::onRender(const SkSVGRenderContext& ctx) const {
|
||||
const auto& rp = ctx.resourceProvider();
|
||||
SkSVGImage::ImageInfo SkSVGImage::LoadImage(const sk_sp<skresources::ResourceProvider>& rp,
|
||||
const SkSVGIRI& iri,
|
||||
const SkRect& viewPort,
|
||||
SkSVGPreserveAspectRatio par) {
|
||||
SkASSERT(rp);
|
||||
|
||||
// TODO: svg sources
|
||||
sk_sp<SkImage> image = LoadImage(rp, fHref);
|
||||
sk_sp<SkImage> image = ::LoadImage(rp, iri);
|
||||
if (!image) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// Per spec: raster content has implicit viewbox of '0 0 width height'.
|
||||
const SkRect viewBox = SkRect::Make(image->bounds());
|
||||
|
||||
// Map and place at x, y specified by viewport
|
||||
const SkMatrix m = ComputeViewboxMatrix(viewBox, viewPort, par);
|
||||
const SkRect dst = m.mapRect(viewBox).makeOffset(viewPort.fLeft, viewPort.fTop);
|
||||
|
||||
return {std::move(image), dst};
|
||||
}
|
||||
|
||||
void SkSVGImage::onRender(const SkSVGRenderContext& ctx) const {
|
||||
// Per spec: x, w, width, height attributes establish the new viewport.
|
||||
const SkSVGLengthContext& lctx = ctx.lengthContext();
|
||||
const SkRect viewPort = lctx.resolveRect(fX, fY, fWidth, fHeight);
|
||||
|
||||
const auto imgInfo = LoadImage(ctx.resourceProvider(), fHref, viewPort, fPreserveAspectRatio);
|
||||
if (!imgInfo.fImage) {
|
||||
SkDebugf("can't render image: load image failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Per spec: x, w, width, height attributes establish the new viewport.
|
||||
const SkSVGLengthContext& lctx = ctx.lengthContext();
|
||||
const SkRect viewPort = lctx.resolveRect(fX, fY, fWidth, fHeight);
|
||||
// Per spec: raster content has implicit viewbox of '0 0 width height'.
|
||||
const SkRect viewBox = SkRect::Make(image->bounds());
|
||||
|
||||
ctx.canvas()->drawImageRect(image,
|
||||
this->resolveImageRect(viewBox, viewPort),
|
||||
SkSamplingOptions(SkFilterMode::kLinear));
|
||||
// TODO: image-rendering property
|
||||
ctx.canvas()->drawImageRect(
|
||||
imgInfo.fImage, imgInfo.fDst, SkSamplingOptions(SkFilterMode::kLinear));
|
||||
}
|
||||
|
||||
SkPath SkSVGImage::onAsPath(const SkSVGRenderContext&) const { return {}; }
|
||||
|
Loading…
Reference in New Issue
Block a user