[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*,
|
||||
SkSVGXmlSpace) const = 0;
|
||||
|
||||
// Text nodes other than the root <text> element are not rendered directly.
|
||||
void onRender(const SkSVGRenderContext&) const override {}
|
||||
|
||||
private:
|
||||
SkPath onAsPath(const SkSVGRenderContext&) const final;
|
||||
|
||||
@ -53,8 +56,6 @@ protected:
|
||||
bool parseAndSetAttribute(const char*, const char*) override;
|
||||
|
||||
private:
|
||||
void onRender(const SkSVGRenderContext&) const final;
|
||||
|
||||
std::vector<sk_sp<SkSVGTextFragment>> fChildren;
|
||||
|
||||
using INHERITED = SkSVGTextFragment;
|
||||
@ -67,7 +68,7 @@ public:
|
||||
private:
|
||||
SkSVGText() : INHERITED(SkSVGTag::kText) {}
|
||||
|
||||
void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*, SkSVGXmlSpace) const override;
|
||||
void onRender(const SkSVGRenderContext&) const override;
|
||||
|
||||
using INHERITED = SkSVGTextContainer;
|
||||
};
|
||||
@ -93,7 +94,6 @@ public:
|
||||
private:
|
||||
SkSVGTextLiteral() : INHERITED(SkSVGTag::kTextLiteral) {}
|
||||
|
||||
void onRender(const SkSVGRenderContext&) const override {}
|
||||
void onRenderText(const SkSVGRenderContext&, SkSVGTextContext*, SkSVGXmlSpace) const override;
|
||||
|
||||
void appendChild(sk_sp<SkSVGNode>) override {}
|
||||
|
@ -490,9 +490,8 @@ SkPath SkSVGTextFragment::onAsPath(const SkSVGRenderContext&) const {
|
||||
}
|
||||
|
||||
void SkSVGTextContainer::appendChild(sk_sp<SkSVGNode> child) {
|
||||
// Only allow text nodes.
|
||||
// Only allow text content child nodes.
|
||||
switch (child->tag()) {
|
||||
case SkSVGTag::kText:
|
||||
case SkSVGTag::kTextLiteral:
|
||||
case SkSVGTag::kTextPath:
|
||||
case SkSVGTag::kTSpan:
|
||||
@ -506,10 +505,7 @@ void SkSVGTextContainer::appendChild(sk_sp<SkSVGNode> child) {
|
||||
|
||||
void SkSVGTextContainer::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext* tctx,
|
||||
SkSVGXmlSpace) const {
|
||||
if (!tctx) {
|
||||
// No text context => missing top-level <text> node.
|
||||
return;
|
||||
}
|
||||
SkASSERT(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));
|
||||
}
|
||||
|
||||
void SkSVGTextContainer::onRender(const SkSVGRenderContext& ctx) const {
|
||||
this->onRenderText(ctx, nullptr, this->getXmlSpace());
|
||||
}
|
||||
|
||||
void SkSVGTextLiteral::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext* tctx,
|
||||
SkSVGXmlSpace xs) const {
|
||||
SkASSERT(tctx);
|
||||
@ -553,17 +545,16 @@ void SkSVGTextLiteral::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextCont
|
||||
tctx->appendFragment(this->getText(), ctx, xs);
|
||||
}
|
||||
|
||||
void SkSVGText::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext*,
|
||||
SkSVGXmlSpace xs) const {
|
||||
// Root text nodes establish a new text layout context.
|
||||
void SkSVGText::onRender(const SkSVGRenderContext& ctx) const {
|
||||
// Root <text> nodes establish a text layout context.
|
||||
SkSVGTextContext tctx(ctx);
|
||||
|
||||
this->INHERITED::onRenderText(ctx, &tctx, xs);
|
||||
this->onRenderText(ctx, &tctx, this->getXmlSpace());
|
||||
}
|
||||
|
||||
void SkSVGTextPath::onRenderText(const SkSVGRenderContext& ctx, SkSVGTextContext*,
|
||||
SkSVGXmlSpace xs) const {
|
||||
// Root text nodes establish a new text layout context.
|
||||
// textPath nodes establish a new text layout context.
|
||||
SkSVGTextContext tctx(ctx, this);
|
||||
|
||||
this->INHERITED::onRenderText(ctx, &tctx, xs);
|
||||
|
Loading…
Reference in New Issue
Block a user