summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc85
1 files changed, 34 insertions, 51 deletions
diff --git a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
index 754d3cef50d..6944d125c20 100644
--- a/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
+++ b/chromium/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
@@ -52,13 +52,10 @@ LayoutSVGResourcePattern::LayoutSVGResourcePattern(SVGPatternElement* node)
attributes_wrapper_(MakeGarbageCollected<PatternAttributesWrapper>()),
pattern_map_(MakeGarbageCollected<PatternMap>()) {}
-void LayoutSVGResourcePattern::RemoveAllClientsFromCache(
- bool mark_for_invalidation) {
+void LayoutSVGResourcePattern::RemoveAllClientsFromCache() {
pattern_map_->clear();
should_collect_pattern_attributes_ = true;
- MarkAllClientsForInvalidation(
- mark_for_invalidation ? SVGResourceClient::kPaintInvalidation
- : SVGResourceClient::kParentOnlyInvalidation);
+ MarkAllClientsForInvalidation(SVGResourceClient::kPaintInvalidation);
}
bool LayoutSVGResourcePattern::RemoveClientFromCache(
@@ -70,51 +67,53 @@ bool LayoutSVGResourcePattern::RemoveClientFromCache(
return true;
}
-PatternData* LayoutSVGResourcePattern::PatternForClient(
- const SVGResourceClient& client,
+std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
const FloatRect& object_bounding_box) {
- DCHECK(!should_collect_pattern_attributes_);
+ auto pattern_data = std::make_unique<PatternData>();
- // FIXME: the double hash lookup is needed to guard against paint-time
- // invalidation (painting animated images may trigger layout invals which
- // delete our map entry). Hopefully that will be addressed at some point, and
- // then we can optimize the lookup.
- if (PatternData* current_data = pattern_map_->at(&client))
- return current_data;
-
- return pattern_map_->Set(&client, BuildPatternData(object_bounding_box))
- .stored_value->value.get();
-}
+ DCHECK(GetElement());
+ // 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_) {
+ attributes_wrapper_->Set(PatternAttributes());
+ auto* pattern_element = To<SVGPatternElement>(GetElement());
+ pattern_element->CollectPatternAttributes(MutableAttributes());
+ should_collect_pattern_attributes_ = false;
+ }
-std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
- const FloatRect& object_bounding_box) {
- // If we couldn't determine the pattern content element root, stop here.
const PatternAttributes& attributes = Attributes();
- if (!attributes.PatternContentElement())
- return nullptr;
- // An empty viewBox disables layout.
- if (attributes.HasViewBox() && attributes.ViewBox().IsEmpty())
- return nullptr;
+ // Spec: When the geometry of the applicable element has no width or height
+ // and objectBoundingBox is specified, then the given effect (e.g. a gradient
+ // or a filter) will be ignored.
+ if (attributes.PatternUnits() ==
+ SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
+ object_bounding_box.IsEmpty())
+ return pattern_data;
+
+ // If there's no content disable rendering of the pattern.
+ if (!attributes.PatternContentElement())
+ return pattern_data;
- DCHECK(GetElement());
// Compute tile metrics.
FloatRect tile_bounds = SVGLengthContext::ResolveRectangle(
GetElement(), attributes.PatternUnits(), object_bounding_box,
*attributes.X(), *attributes.Y(), *attributes.Width(),
*attributes.Height());
if (tile_bounds.IsEmpty())
- return nullptr;
+ return pattern_data;
AffineTransform tile_transform;
if (attributes.HasViewBox()) {
+ // An empty viewBox disables rendering of the pattern.
if (attributes.ViewBox().IsEmpty())
- return nullptr;
+ return pattern_data;
tile_transform = SVGFitToViewBox::ViewBoxToViewTransform(
attributes.ViewBox(), attributes.PreserveAspectRatio(),
tile_bounds.Width(), tile_bounds.Height());
} else {
- // A viewbox overrides patternContentUnits, per spec.
+ // A viewBox overrides patternContentUnits, per spec.
if (attributes.PatternContentUnits() ==
SVGUnitTypes::kSvgUnitTypeObjectboundingbox) {
tile_transform.Scale(object_bounding_box.Width(),
@@ -122,7 +121,6 @@ std::unique_ptr<PatternData> LayoutSVGResourcePattern::BuildPatternData(
}
}
- std::unique_ptr<PatternData> pattern_data = base::WrapUnique(new PatternData);
pattern_data->pattern = Pattern::CreatePaintRecordPattern(
AsPaintRecord(tile_bounds.Size(), tile_transform),
FloatRect(FloatPoint(), tile_bounds.Size()));
@@ -139,27 +137,12 @@ SVGPaintServer LayoutSVGResourcePattern::PreparePaintServer(
const FloatRect& object_bounding_box) {
ClearInvalidationMask();
- // 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_) {
- attributes_wrapper_->Set(PatternAttributes());
- auto* pattern_element = To<SVGPatternElement>(GetElement());
- pattern_element->CollectPatternAttributes(MutableAttributes());
- should_collect_pattern_attributes_ = false;
- }
-
- // Spec: When the geometry of the applicable element has no width or height
- // and objectBoundingBox is specified, then the given effect (e.g. a gradient
- // or a filter) will be ignored.
- if (Attributes().PatternUnits() ==
- SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
- object_bounding_box.IsEmpty())
- return SVGPaintServer::Invalid();
+ std::unique_ptr<PatternData>& pattern_data =
+ pattern_map_->insert(&client, nullptr).stored_value->value;
+ if (!pattern_data)
+ pattern_data = BuildPatternData(object_bounding_box);
- PatternData* pattern_data = PatternForClient(client, object_bounding_box);
- if (!pattern_data || !pattern_data->pattern)
+ if (!pattern_data->pattern)
return SVGPaintServer::Invalid();
return SVGPaintServer(pattern_data->pattern, pattern_data->transform);