[svg] Property inheritance workaround
Property inheritance is supposed to follow the tree hierarchy, but we implement it based on the render path. One nasty side effect is when resolving IRI paint servers (gradients, patterns), the referencing node properties get inherited (leak) into the paint server fragment. E.g. <pattern id="pat"> <rect fill="green"/> </pattern> <rect stroke="blue" fill="url(#pat)" stroke="blue"/> The pattern subtree incorrectly inherits a blue stroke property from the referencing node when we resolve the fill. As a temporary (and imperfect) workaround, we can reset the presentation context when resolving IRI paint servers. Change-Id: Ia4a8a6199222820661f805c43340b5e16902feff Reviewed-on: https://skia-review.googlesource.com/c/skia/+/354668 Reviewed-by: Tyler Denniston <tdenniston@google.com> Commit-Queue: Florin Malita <fmalita@google.com>
This commit is contained in:
parent
4f2bcff08e
commit
d414e600b2
@ -135,6 +135,8 @@ public:
|
||||
const SkSVGLength& w, const SkSVGLength& h,
|
||||
SkSVGObjectBoundingBoxUnits) const;
|
||||
|
||||
const SkSVGIDMapper& idMapper() const { return fIDMapper; }
|
||||
|
||||
private:
|
||||
// Stack-only
|
||||
void* operator new(size_t) = delete;
|
||||
|
@ -111,8 +111,18 @@ void applySvgPaint(const SkSVGRenderContext& ctx, const SkSVGPaint& svgPaint, Sk
|
||||
p->setColor(SkColorSetA(ctx.resolveSvgColor(svgPaint.color()), p->getAlpha()));
|
||||
break;
|
||||
case SkSVGPaint::Type::kIRI: {
|
||||
// Out property inheritance is borked as it follows the render path and not the tree
|
||||
// hierarchy. To avoid gross transgressions like leaf node presentation attributes leaking
|
||||
// into the paint server context, use a pristine presentation context when following hrefs.
|
||||
SkSVGPresentationContext pctx;
|
||||
SkSVGRenderContext local_context(ctx.canvas(),
|
||||
ctx.fontMgr(),
|
||||
ctx.idMapper(),
|
||||
ctx.lengthContext(),
|
||||
pctx, ctx.node());
|
||||
|
||||
const auto node = ctx.findNodeById(svgPaint.iri());
|
||||
if (!node || !node->asPaint(ctx, p)) {
|
||||
if (!node || !node->asPaint(local_context, p)) {
|
||||
p->setColor(SK_ColorTRANSPARENT);
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user