[svg] Cleanup text content model rules
Per spec (and empirically) <text> elements are not nestable (neither directly or indirectly): https://www.w3.org/TR/SVG11/intro.html#TermTextContentChildElement Update the implementation to - only bridge onRender -> onRenderText in the root SkSVGText implementation - disallow <text> elements as text container descendants Change-Id: I07b3abaf943b820e01c88f78bddf7ce5970ee508 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/358220 Commit-Queue: Florin Malita <fmalita@google.com> Reviewed-by: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
parent
fe8a4faa4b
commit
302ea2e03c
@ -26,6 +26,9 @@ protected:
|
|||||||
virtual void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*,
|
virtual void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*,
|
||||||
SkSVGXmlSpace) const = 0;
|
SkSVGXmlSpace) const = 0;
|
||||||
|
|
||||||
|
// Text nodes other than the root <text> element are not rendered directly.
|
||||||
|
void onRender(const SkSVGRenderContext&) const override {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SkPath onAsPath(const SkSVGRenderContext&) const final;
|
SkPath onAsPath(const SkSVGRenderContext&) const final;
|
||||||
|
|
||||||
@ -53,8 +56,6 @@ protected:
|
|||||||
bool parseAndSetAttribute(const char*, const char*) override;
|
bool parseAndSetAttribute(const char*, const char*) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onRender(const SkSVGRenderContext&) const final;
|
|
||||||
|
|
||||||
std::vector<sk_sp<SkSVGTextFragment>> fChildren;
|
std::vector<sk_sp<SkSVGTextFragment>> fChildren;
|
||||||
|
|
||||||
using INHERITED = SkSVGTextFragment;
|
using INHERITED = SkSVGTextFragment;
|
||||||
@ -67,7 +68,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
SkSVGText() : INHERITED(SkSVGTag::kText) {}
|
SkSVGText() : INHERITED(SkSVGTag::kText) {}
|
||||||
|
|
||||||
void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*, SkSVGXmlSpace) const override;
|
void onRender(const SkSVGRenderContext&) const override;
|
||||||
|
|
||||||
using INHERITED = SkSVGTextContainer;
|
using INHERITED = SkSVGTextContainer;
|
||||||
};
|
};
|
||||||
@ -93,7 +94,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
SkSVGTextLiteral() : INHERITED(SkSVGTag::kTextLiteral) {}
|
SkSVGTextLiteral() : INHERITED(SkSVGTag::kTextLiteral) {}
|
||||||
|
|
||||||
void onRender(const SkSVGRenderContext&) const override {}
|
|
||||||
void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*, SkSVGXmlSpace) const override;
|
void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*, SkSVGXmlSpace) const override;
|
||||||
|
|
||||||
void appendChild(sk_sp<SkSVGNode>) override {}
|
void appendChild(sk_sp<SkSVGNode>) override {}
|
||||||
|
@ -490,9 +490,8 @@ SkPath SkSVGTextFragment::onAsPath(const SkSVGRenderContext&) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkSVGTextContainer::appendChild(sk_sp<SkSVGNode> child) {
|
void SkSVGTextContainer::appendChild(sk_sp<SkSVGNode> child) {
|
||||||
// Only allow text nodes.
|
// Only allow text content child nodes.
|
||||||
switch (child->tag()) {
|
switch (child->tag()) {
|
||||||
case SkSVGTag::kText:
|
|
||||||
case SkSVGTag::kTextLiteral:
|
case SkSVGTag::kTextLiteral:
|
||||||
case SkSVGTag::kTextPath:
|
case SkSVGTag::kTextPath:
|
||||||
case SkSVGTag::kTSpan:
|
case SkSVGTag::kTSpan:
|
||||||
@ -506,10 +505,7 @@ void SkSVGTextContainer::appendChild(sk_sp<SkSVGNode> child) {
|
|||||||
|
|
||||||
void SkSVGTextContainer::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext* tctx,
|
void SkSVGTextContainer::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext* tctx,
|
||||||
SkSVGXmlSpace) const {
|
SkSVGXmlSpace) const {
|
||||||
if (!tctx) {
|
SkASSERT(tctx);
|
||||||
// No text context => missing top-level <text> node.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SkSVGTextContext::ScopedPosResolver resolver(*this, ctx.lengthContext(), tctx);
|
const SkSVGTextContext::ScopedPosResolver resolver(*this, ctx.lengthContext(), tctx);
|
||||||
|
|
||||||
@ -542,10 +538,6 @@ bool SkSVGTextContainer::parseAndSetAttribute(const char* name, const char* valu
|
|||||||
this->setXmlSpace(SkSVGAttributeParser::parse<SkSVGXmlSpace>("xml:space", name, value));
|
this->setXmlSpace(SkSVGAttributeParser::parse<SkSVGXmlSpace>("xml:space", name, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkSVGTextContainer::onRender(const SkSVGRenderContext& ctx) const {
|
|
||||||
this->onRenderText(ctx, nullptr, this->getXmlSpace());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkSVGTextLiteral::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext* tctx,
|
void SkSVGTextLiteral::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext* tctx,
|
||||||
SkSVGXmlSpace xs) const {
|
SkSVGXmlSpace xs) const {
|
||||||
SkASSERT(tctx);
|
SkASSERT(tctx);
|
||||||
@ -553,17 +545,16 @@ void SkSVGTextLiteral::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextCont
|
|||||||
tctx->appendFragment(this->getText(), ctx, xs);
|
tctx->appendFragment(this->getText(), ctx, xs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkSVGText::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext*,
|
void SkSVGText::onRender(const SkSVGRenderContext& ctx) const {
|
||||||
SkSVGXmlSpace xs) const {
|
// Root <text> nodes establish a text layout context.
|
||||||
// Root text nodes establish a new text layout context.
|
|
||||||
SkSVGTextContext tctx(ctx);
|
SkSVGTextContext tctx(ctx);
|
||||||
|
|
||||||
this->INHERITED::onRenderText(ctx, &tctx, xs);
|
this->onRenderText(ctx, &tctx, this->getXmlSpace());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkSVGTextPath::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext*,
|
void SkSVGTextPath::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext*,
|
||||||
SkSVGXmlSpace xs) const {
|
SkSVGXmlSpace xs) const {
|
||||||
// Root text nodes establish a new text layout context.
|
// textPath nodes establish a new text layout context.
|
||||||
SkSVGTextContext tctx(ctx, this);
|
SkSVGTextContext tctx(ctx, this);
|
||||||
|
|
||||||
this->INHERITED::onRenderText(ctx, &tctx, xs);
|
this->INHERITED::onRenderText(ctx, &tctx, xs);
|
||||||
|
Loading…
Reference in New Issue
Block a user