Commit 41de0ebf authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

[CI] Cleanup SVG <pattern> attribute collection

Move the 'href' lookup to a helper function (as seen in the very similar
SVGGradientElement.) Use a similar setup in SVGGradientElement
equivalent method.
Move attribute synchronization from LayoutSVGResourcePattern into
SVGPatternElement::CollectPatternAttributes.
Change the SetPatternAttributes helper to take a SVGPatternElement
reference.
Remove the element null-check in the LayoutObject.

Bug: 769774
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2
Change-Id: I16901de05437bbeea1981f5340bec1a3e4329b50
Reviewed-on: https://chromium-review.googlesource.com/966221Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Cr-Commit-Position: refs/heads/master@{#543709}
parent c4bbd513
......@@ -136,18 +136,13 @@ SVGPaintServer LayoutSVGResourcePattern::PreparePaintServer(
const FloatRect& object_bounding_box) {
ClearInvalidationMask();
SVGPatternElement* pattern_element = ToSVGPatternElement(GetElement());
if (!pattern_element)
return SVGPaintServer::Invalid();
// Validate pattern DOM state before building the actual
// pattern. This should avoid tearing down the pattern we're
// currently working on. Preferably the state validation should have
// no side-effects though.
if (should_collect_pattern_attributes_) {
pattern_element->SynchronizeAnimatedSVGAttribute(AnyQName());
attributes_wrapper_->Set(PatternAttributes());
SVGPatternElement* pattern_element = ToSVGPatternElement(GetElement());
pattern_element->CollectPatternAttributes(MutableAttributes());
should_collect_pattern_attributes_ = false;
}
......
......@@ -188,11 +188,8 @@ void SVGGradientElement::CollectCommonAttributes(
const SVGGradientElement* SVGGradientElement::ReferencedElement() const {
// Respect xlink:href, take attributes from referenced element.
Element* referenced_element =
TargetElementFromIRIString(HrefString(), GetTreeScope());
if (!referenced_element || !IsSVGGradientElement(*referenced_element))
return nullptr;
return ToSVGGradientElement(referenced_element);
return ToSVGGradientElementOrNull(
TargetElementFromIRIString(HrefString(), GetTreeScope()));
}
Vector<Gradient::ColorStop> SVGGradientElement::BuildStops() const {
......
......@@ -148,46 +148,56 @@ LayoutObject* SVGPatternElement::CreateLayoutObject(const ComputedStyle&) {
return new LayoutSVGResourcePattern(this);
}
static void SetPatternAttributes(const SVGPatternElement* element,
static void SetPatternAttributes(const SVGPatternElement& element,
PatternAttributes& attributes) {
if (!attributes.HasX() && element->x()->IsSpecified())
attributes.SetX(element->x()->CurrentValue());
element.SynchronizeAnimatedSVGAttribute(AnyQName());
if (!attributes.HasY() && element->y()->IsSpecified())
attributes.SetY(element->y()->CurrentValue());
if (!attributes.HasX() && element.x()->IsSpecified())
attributes.SetX(element.x()->CurrentValue());
if (!attributes.HasWidth() && element->width()->IsSpecified())
attributes.SetWidth(element->width()->CurrentValue());
if (!attributes.HasY() && element.y()->IsSpecified())
attributes.SetY(element.y()->CurrentValue());
if (!attributes.HasHeight() && element->height()->IsSpecified())
attributes.SetHeight(element->height()->CurrentValue());
if (!attributes.HasWidth() && element.width()->IsSpecified())
attributes.SetWidth(element.width()->CurrentValue());
if (!attributes.HasViewBox() && element->HasValidViewBox())
attributes.SetViewBox(element->viewBox()->CurrentValue()->Value());
if (!attributes.HasHeight() && element.height()->IsSpecified())
attributes.SetHeight(element.height()->CurrentValue());
if (!attributes.HasViewBox() && element.HasValidViewBox())
attributes.SetViewBox(element.viewBox()->CurrentValue()->Value());
if (!attributes.HasPreserveAspectRatio() &&
element->preserveAspectRatio()->IsSpecified())
element.preserveAspectRatio()->IsSpecified()) {
attributes.SetPreserveAspectRatio(
element->preserveAspectRatio()->CurrentValue());
element.preserveAspectRatio()->CurrentValue());
}
if (!attributes.HasPatternUnits() && element->patternUnits()->IsSpecified())
if (!attributes.HasPatternUnits() && element.patternUnits()->IsSpecified()) {
attributes.SetPatternUnits(
element->patternUnits()->CurrentValue()->EnumValue());
element.patternUnits()->CurrentValue()->EnumValue());
}
if (!attributes.HasPatternContentUnits() &&
element->patternContentUnits()->IsSpecified())
element.patternContentUnits()->IsSpecified()) {
attributes.SetPatternContentUnits(
element->patternContentUnits()->CurrentValue()->EnumValue());
element.patternContentUnits()->CurrentValue()->EnumValue());
}
if (!attributes.HasPatternTransform() &&
element->HasTransform(SVGElement::kExcludeMotionTransform)) {
element.HasTransform(SVGElement::kExcludeMotionTransform)) {
attributes.SetPatternTransform(
element->CalculateTransform(SVGElement::kExcludeMotionTransform));
element.CalculateTransform(SVGElement::kExcludeMotionTransform));
}
if (!attributes.HasPatternContentElement() &&
ElementTraversal::FirstWithin(*element))
attributes.SetPatternContentElement(element);
ElementTraversal::FirstWithin(element))
attributes.SetPatternContentElement(&element);
}
const SVGPatternElement* SVGPatternElement::ReferencedElement() const {
return ToSVGPatternElementOrNull(
TargetElementFromIRIString(HrefString(), GetTreeScope()));
}
void SVGPatternElement::CollectPatternAttributes(
......@@ -196,19 +206,16 @@ void SVGPatternElement::CollectPatternAttributes(
const SVGPatternElement* current = this;
while (true) {
SetPatternAttributes(current, attributes);
SetPatternAttributes(*current, attributes);
processed_patterns.insert(current);
// Respect xlink:href, take attributes from referenced element
Node* ref_node = SVGURIReference::TargetElementFromIRIString(
current->HrefString(), GetTreeScope());
// If (xlink:)href links to another SVGPatternElement, allow attributes
// from that element to override values this pattern didn't set.
current = current->ReferencedElement();
// Only consider attached SVG pattern elements.
if (!IsSVGPatternElement(ref_node) || !ref_node->GetLayoutObject())
if (!current || !current->GetLayoutObject())
break;
current = ToSVGPatternElement(ref_node);
// Cycle detection
if (processed_patterns.Contains(current))
break;
......
......@@ -89,6 +89,8 @@ class SVGPatternElement final : public SVGElement,
void SvgAttributeChanged(const QualifiedName&) override;
void ChildrenChanged(const ChildrenChange&) override;
const SVGPatternElement* ReferencedElement() const;
LayoutObject* CreateLayoutObject(const ComputedStyle&) override;
bool SelfHasRelativeLengths() const override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment