diff options
author | fmalita <fmalita@chromium.org> | 2016-08-08 11:38:55 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-08-08 11:38:55 -0700 |
commit | 397a517d1a5774653fcdd08172f9a6b5eea67621 (patch) | |
tree | ab9c9aaa4121a8033a29f259401bcecf7d178203 /experimental/svg/model/SkSVGSVG.cpp | |
parent | f621ff49a288978c272d5ae069a6a1c04c74642b (diff) |
[SVGDom] Add viewBox support
The main feature is <svg> viewBox and proper viewport support, but the CL
touches a few other things:
* refactor SkSVGRenderContext to auto-restore canvas state, and split the
presentation bits into a separate CoW SkSVGPresentationContext
* introduce SkSVGNode::onPrepareToRender(), as a way for nodes to push their
custom state before the actual onRender() call (instead of relying on
non-virtual SkSVGNode to know about all possible state bits)
* add a "Type" suffix to SVG types, to disambiguate (e.g. SkSVGRectType vs.
SkSVGRect)
R=robertphillips@google.com,stephana@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2222793002
Review-Url: https://codereview.chromium.org/2222793002
Diffstat (limited to 'experimental/svg/model/SkSVGSVG.cpp')
-rw-r--r-- | experimental/svg/model/SkSVGSVG.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/experimental/svg/model/SkSVGSVG.cpp b/experimental/svg/model/SkSVGSVG.cpp index 42bd280a5e..13f18043c0 100644 --- a/experimental/svg/model/SkSVGSVG.cpp +++ b/experimental/svg/model/SkSVGSVG.cpp @@ -5,11 +5,45 @@ * found in the LICENSE file. */ +#include "SkCanvas.h" +#include "SkSVGRenderContext.h" #include "SkSVGSVG.h" #include "SkSVGValue.h" SkSVGSVG::SkSVGSVG() : INHERITED(SkSVGTag::kSvg) { } +bool SkSVGSVG::onPrepareToRender(SkSVGRenderContext* ctx) const { + auto viewPortRect = ctx->lengthContext().resolveRect(fX, fY, fWidth, fHeight); + auto contentMatrix = SkMatrix::MakeTrans(viewPortRect.x(), viewPortRect.y()); + auto viewPort = SkSize::Make(viewPortRect.width(), viewPortRect.height()); + + if (fViewBox.isValid()) { + const SkRect& viewBox = *fViewBox.get(); + + // An empty viewbox disables rendering. + if (viewBox.isEmpty()) { + return false; + } + + // A viewBox overrides the intrinsic viewport. + viewPort = SkSize::Make(viewBox.width(), viewBox.height()); + + contentMatrix.preConcat( + SkMatrix::MakeRectToRect(viewBox, viewPortRect, SkMatrix::kFill_ScaleToFit)); + } + + if (!contentMatrix.isIdentity()) { + ctx->canvas()->save(); + ctx->canvas()->concat(contentMatrix); + } + + if (viewPort != ctx->lengthContext().viewPort()) { + ctx->writableLengthContext()->setViewPort(viewPort); + } + + return this->INHERITED::onPrepareToRender(ctx); +} + void SkSVGSVG::setX(const SkSVGLength& x) { fX = x; } @@ -26,6 +60,10 @@ void SkSVGSVG::setHeight(const SkSVGLength& h) { fHeight = h; } +void SkSVGSVG::setViewBox(const SkSVGViewBoxType& vb) { + fViewBox.set(vb); +} + void SkSVGSVG::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { switch (attr) { case SkSVGAttribute::kX: @@ -48,6 +86,11 @@ void SkSVGSVG::onSetAttribute(SkSVGAttribute attr, const SkSVGValue& v) { this->setHeight(*h); } break; + case SkSVGAttribute::kViewBox: + if (const auto* vb = v.as<SkSVGViewBoxValue>()) { + this->setViewBox(*vb); + } + break; default: this->INHERITED::onSetAttribute(attr, v); } |