diff options
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.cc | 85 |
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); |