[SVGDom] Clipped clipPath support
ClipPaths can be clipped too, e.g.: <clipPath id="clip1" clip-path="url(#clip2)">...</clipPath> Since we're not really drawing clips but resolving their geometry, asPath() needs to take composed clipping into account (and intersect as needed). R=reed@google.com,robertphillips@google.com,stephana@google.com Change-Id: I25959e22fe50f72042147cfe6b416b6b9ac20cd4 Reviewed-on: https://skia-review.googlesource.com/5720 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
parent
67702f6322
commit
7d529881c4
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkMatrix.h"
|
#include "SkMatrix.h"
|
||||||
|
#include "SkPathOps.h"
|
||||||
#include "SkSVGNode.h"
|
#include "SkSVGNode.h"
|
||||||
#include "SkSVGRenderContext.h"
|
#include "SkSVGRenderContext.h"
|
||||||
#include "SkSVGValue.h"
|
#include "SkSVGValue.h"
|
||||||
@ -32,7 +33,18 @@ bool SkSVGNode::asPaint(const SkSVGRenderContext& ctx, SkPaint* paint) const {
|
|||||||
|
|
||||||
SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const {
|
SkPath SkSVGNode::asPath(const SkSVGRenderContext& ctx) const {
|
||||||
SkSVGRenderContext localContext(ctx);
|
SkSVGRenderContext localContext(ctx);
|
||||||
return this->onPrepareToRender(&localContext) ? this->onAsPath(localContext) : SkPath();
|
if (!this->onPrepareToRender(&localContext)) {
|
||||||
|
return SkPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
SkPath path = this->onAsPath(localContext);
|
||||||
|
|
||||||
|
if (const auto* clipPath = localContext.clipPath()) {
|
||||||
|
// There is a clip-path present on the current node.
|
||||||
|
Op(path, *clipPath, kIntersect_SkPathOp, &path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
|
bool SkSVGNode::onPrepareToRender(SkSVGRenderContext* ctx) const {
|
||||||
|
@ -328,12 +328,20 @@ void SkSVGRenderContext::applyClip(const SkSVGClip& clip) {
|
|||||||
|
|
||||||
const SkPath clipPath = clipNode->asPath(*this);
|
const SkPath clipPath = clipNode->asPath(*this);
|
||||||
|
|
||||||
|
// We use the computed clip path in two ways:
|
||||||
|
//
|
||||||
|
// - apply to the current canvas, for drawing
|
||||||
|
// - track in the presentation context, for asPath() composition
|
||||||
|
//
|
||||||
|
// TODO: the two uses are exclusive, avoid canvas churn when non needed.
|
||||||
|
|
||||||
// Only save if needed
|
// Only save if needed
|
||||||
if (fCanvas->getSaveCount() == fCanvasSaveCount) {
|
if (fCanvas->getSaveCount() == fCanvasSaveCount) {
|
||||||
fCanvas->save();
|
fCanvas->save();
|
||||||
}
|
}
|
||||||
|
|
||||||
fCanvas->clipPath(clipPath, true);
|
fCanvas->clipPath(clipPath, true);
|
||||||
|
fClipPath.set(clipPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const SkPaint* SkSVGRenderContext::fillPaint() const {
|
const SkPaint* SkSVGRenderContext::fillPaint() const {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define SkSVGRenderContext_DEFINED
|
#define SkSVGRenderContext_DEFINED
|
||||||
|
|
||||||
#include "SkPaint.h"
|
#include "SkPaint.h"
|
||||||
|
#include "SkPath.h"
|
||||||
#include "SkRect.h"
|
#include "SkRect.h"
|
||||||
#include "SkSize.h"
|
#include "SkSize.h"
|
||||||
#include "SkSVGAttribute.h"
|
#include "SkSVGAttribute.h"
|
||||||
@ -79,6 +80,9 @@ public:
|
|||||||
const SkPaint* fillPaint() const;
|
const SkPaint* fillPaint() const;
|
||||||
const SkPaint* strokePaint() const;
|
const SkPaint* strokePaint() const;
|
||||||
|
|
||||||
|
// The local computed clip path (not inherited).
|
||||||
|
const SkPath* clipPath() const { return fClipPath.getMaybeNull(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Stack-only
|
// Stack-only
|
||||||
void* operator new(size_t) = delete;
|
void* operator new(size_t) = delete;
|
||||||
@ -95,6 +99,9 @@ private:
|
|||||||
// The save count on 'fCanvas' at construction time.
|
// The save count on 'fCanvas' at construction time.
|
||||||
// A restoreToCount() will be issued on destruction.
|
// A restoreToCount() will be issued on destruction.
|
||||||
int fCanvasSaveCount;
|
int fCanvasSaveCount;
|
||||||
|
|
||||||
|
// clipPath, if present for the current context (not inherited).
|
||||||
|
SkTLazy<SkPath> fClipPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SkSVGRenderContext_DEFINED
|
#endif // SkSVGRenderContext_DEFINED
|
||||||
|
Loading…
Reference in New Issue
Block a user