Commit 321d124a authored by Fredrik Söderquist's avatar Fredrik Söderquist Committed by Commit Bot

Add GetSVGResourceAsType helpers

This adds helper functions for going from an SVGResource or
StyleSVGResource to the associated LayoutSVGResourceContainer type.
This reduces the amount of boilplate needed for this a little bit. These
types of access is expected to be little more common when the
SVGResources object has been phased out.

Add a special overload for ReferenceClipPathOperation that maps to a
LayoutSVGResourceClipper, and GetFilterResourceForSVG to capture the
current "single url(...)" restriction.

Bug: 1028063
Change-Id: I7d408a4d25d024162ace818a088b25be1205cedb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2072218
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: default avatarStephen Chenney <schenney@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#745090}
parent 10ccf570
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_CLIPPER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_CLIPPER_H_
#include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_container.h"
#include "third_party/blink/renderer/core/style/reference_clip_path_operation.h"
#include "third_party/blink/renderer/core/svg/svg_unit_types.h" #include "third_party/blink/renderer/core/svg/svg_unit_types.h"
#include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkRefCnt.h"
...@@ -88,6 +89,16 @@ class LayoutSVGResourceClipper final : public LayoutSVGResourceContainer { ...@@ -88,6 +89,16 @@ class LayoutSVGResourceClipper final : public LayoutSVGResourceContainer {
DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceClipper, DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceClipper,
kClipperResourceType); kClipperResourceType);
inline LayoutSVGResourceClipper* GetSVGResourceAsType(
const ClipPathOperation* clip_path_operation) {
const auto* reference_clip =
DynamicTo<ReferenceClipPathOperation>(clip_path_operation);
if (!reference_clip)
return nullptr;
return GetSVGResourceAsType<LayoutSVGResourceClipper>(
reference_clip->Resource());
}
} // namespace blink } // namespace blink
#endif #endif
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_CONTAINER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_SVG_LAYOUT_SVG_RESOURCE_CONTAINER_H_
#include "third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_hidden_container.h"
#include "third_party/blink/renderer/core/style/style_svg_resource.h"
#include "third_party/blink/renderer/core/svg/svg_resource.h"
#include "third_party/blink/renderer/core/svg/svg_resource_client.h" #include "third_party/blink/renderer/core/svg/svg_resource_client.h"
namespace blink { namespace blink {
...@@ -106,6 +108,29 @@ DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceContainer, ...@@ -106,6 +108,29 @@ DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceContainer,
resource->ResourceType() == typeName, \ resource->ResourceType() == typeName, \
resource.ResourceType() == typeName) resource.ResourceType() == typeName)
template <typename ContainerType>
inline bool IsResourceOfType(LayoutSVGResourceContainer* container) {
return container->ResourceType() == ContainerType::kResourceType;
}
template <typename ContainerType>
inline ContainerType* GetSVGResourceAsType(SVGResource* resource) {
if (!resource)
return nullptr;
if (LayoutSVGResourceContainer* container = resource->ResourceContainer()) {
if (IsResourceOfType<ContainerType>(container))
return static_cast<ContainerType*>(container);
}
return nullptr;
}
template <typename ContainerType>
inline ContainerType* GetSVGResourceAsType(StyleSVGResource* style_resource) {
if (!style_resource)
return nullptr;
return GetSVGResourceAsType<ContainerType>(style_resource->Resource());
}
} // namespace blink } // namespace blink
#endif #endif
...@@ -130,4 +130,18 @@ void LayoutSVGResourceFilter::PrimitiveAttributeChanged( ...@@ -130,4 +130,18 @@ void LayoutSVGResourceFilter::PrimitiveAttributeChanged(
} }
} }
LayoutSVGResourceFilter* GetFilterResourceForSVG(const ComputedStyle& style) {
if (!style.HasFilter())
return nullptr;
const FilterOperations& operations = style.Filter();
if (operations.size() != 1)
return nullptr;
const auto* reference_filter =
DynamicTo<ReferenceFilterOperation>(*operations.at(0));
if (!reference_filter)
return nullptr;
return GetSVGResourceAsType<LayoutSVGResourceFilter>(
reference_filter->Resource());
}
} // namespace blink } // namespace blink
...@@ -108,6 +108,10 @@ class LayoutSVGResourceFilter final : public LayoutSVGResourceContainer { ...@@ -108,6 +108,10 @@ class LayoutSVGResourceFilter final : public LayoutSVGResourceContainer {
Persistent<FilterMap> filter_; Persistent<FilterMap> filter_;
}; };
// Get the LayoutSVGResourceFilter from the 'filter' property iff the 'filter'
// is a single url(...) reference.
LayoutSVGResourceFilter* GetFilterResourceForSVG(const ComputedStyle&);
DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceFilter, IsSVGResourceFilter()); DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceFilter, IsSVGResourceFilter());
} // namespace blink } // namespace blink
......
...@@ -114,6 +114,12 @@ class LayoutSVGResourcePaintServer : public LayoutSVGResourceContainer { ...@@ -114,6 +114,12 @@ class LayoutSVGResourcePaintServer : public LayoutSVGResourceContainer {
LayoutSVGResourceMode); LayoutSVGResourceMode);
}; };
template <>
inline bool IsResourceOfType<LayoutSVGResourcePaintServer>(
LayoutSVGResourceContainer* container) {
return container->IsSVGPaintServer();
}
} // namespace blink } // namespace blink
#endif #endif
...@@ -740,7 +740,7 @@ void WriteResources(WTF::TextStream& ts, ...@@ -740,7 +740,7 @@ void WriteResources(WTF::TextStream& ts,
WriteStandardPrefix(ts, *clipper, 0); WriteStandardPrefix(ts, *clipper, 0);
ts << " " << clipper->ResourceBoundingBox(reference_box) << "\n"; ts << " " << clipper->ResourceBoundingBox(reference_box) << "\n";
} }
if (LayoutSVGResourceFilter* filter = resources->Filter()) { if (LayoutSVGResourceFilter* filter = GetFilterResourceForSVG(style)) {
DCHECK(style.HasFilter()); DCHECK(style.HasFilter());
DCHECK_EQ(style.Filter().size(), 1u); DCHECK_EQ(style.Filter().size(), 1u);
const FilterOperation& filter_operation = *style.Filter().at(0); const FilterOperation& filter_operation = *style.Filter().at(0);
......
...@@ -115,37 +115,6 @@ static HashSet<AtomicString>& FillAndStrokeTags() { ...@@ -115,37 +115,6 @@ static HashSet<AtomicString>& FillAndStrokeTags() {
return tag_list; return tag_list;
} }
namespace {
template <typename ContainerType>
bool IsResourceOfType(LayoutSVGResourceContainer* container) {
return container->ResourceType() == ContainerType::kResourceType;
}
template <>
bool IsResourceOfType<LayoutSVGResourcePaintServer>(
LayoutSVGResourceContainer* container) {
return container->IsSVGPaintServer();
}
template <typename ContainerType>
ContainerType* CastResource(SVGResource* resource) {
if (!resource)
return nullptr;
if (LayoutSVGResourceContainer* container = resource->ResourceContainer()) {
if (IsResourceOfType<ContainerType>(container))
return static_cast<ContainerType*>(container);
}
return nullptr;
}
template <typename ContainerType>
ContainerType* CastResource(StyleSVGResource& style_resource) {
return CastResource<ContainerType>(style_resource.Resource());
}
} // namespace
bool SVGResources::HasResourceData() const { bool SVGResources::HasResourceData() const {
return clipper_filter_masker_data_ || marker_data_ || fill_stroke_data_ || return clipper_filter_masker_data_ || marker_data_ || fill_stroke_data_ ||
linked_resource_; linked_resource_;
...@@ -176,59 +145,51 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources( ...@@ -176,59 +145,51 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources(
std::unique_ptr<SVGResources> resources; std::unique_ptr<SVGResources> resources;
if (ClipperFilterMaskerTags().Contains(tag_name)) { if (ClipperFilterMaskerTags().Contains(tag_name)) {
if (computed_style.ClipPath() && !object.IsSVGRoot()) { if (computed_style.ClipPath() && !object.IsSVGRoot()) {
ClipPathOperation* clip_path_operation = computed_style.ClipPath(); if (LayoutSVGResourceClipper* clipper =
if (clip_path_operation->GetType() == ClipPathOperation::REFERENCE) { GetSVGResourceAsType(computed_style.ClipPath())) {
const ReferenceClipPathOperation& clip_path_reference = EnsureResources(resources).SetClipper(clipper);
To<ReferenceClipPathOperation>(*clip_path_operation);
EnsureResources(resources).SetClipper(
CastResource<LayoutSVGResourceClipper>(
clip_path_reference.Resource()));
} }
} }
if (computed_style.HasFilter() && !object.IsSVGRoot()) { if (computed_style.HasFilter() && !object.IsSVGRoot()) {
const FilterOperations& filter_operations = computed_style.Filter(); if (LayoutSVGResourceFilter* filter =
if (filter_operations.size() == 1) { GetFilterResourceForSVG(computed_style)) {
const FilterOperation& filter_operation = *filter_operations.at(0); EnsureResources(resources).SetFilter(filter);
if (const auto* reference_filter_operation =
DynamicTo<ReferenceFilterOperation>(filter_operation)) {
EnsureResources(resources).SetFilter(
CastResource<LayoutSVGResourceFilter>(
reference_filter_operation->Resource()));
}
} }
} }
if (StyleSVGResource* masker_resource = style.MaskerResource()) { if (auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
EnsureResources(resources).SetMasker( style.MaskerResource())) {
CastResource<LayoutSVGResourceMasker>(*masker_resource)); EnsureResources(resources).SetMasker(masker);
} }
} }
if (style.HasMarkers() && SupportsMarkers(element)) { if (style.HasMarkers() && SupportsMarkers(element)) {
if (StyleSVGResource* marker_start_resource = style.MarkerStartResource()) { if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
EnsureResources(resources).SetMarkerStart( style.MarkerStartResource())) {
CastResource<LayoutSVGResourceMarker>(*marker_start_resource)); EnsureResources(resources).SetMarkerStart(marker);
} }
if (StyleSVGResource* marker_mid_resource = style.MarkerMidResource()) { if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
EnsureResources(resources).SetMarkerMid( style.MarkerMidResource())) {
CastResource<LayoutSVGResourceMarker>(*marker_mid_resource)); EnsureResources(resources).SetMarkerMid(marker);
} }
if (StyleSVGResource* marker_end_resource = style.MarkerEndResource()) { if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
EnsureResources(resources).SetMarkerEnd( style.MarkerEndResource())) {
CastResource<LayoutSVGResourceMarker>(*marker_end_resource)); EnsureResources(resources).SetMarkerEnd(marker);
} }
} }
if (FillAndStrokeTags().Contains(tag_name)) { if (FillAndStrokeTags().Contains(tag_name)) {
if (StyleSVGResource* fill_resource = style.FillPaint().Resource()) { if (auto* paint_resource =
EnsureResources(resources).SetFill( GetSVGResourceAsType<LayoutSVGResourcePaintServer>(
CastResource<LayoutSVGResourcePaintServer>(*fill_resource)); style.FillPaint().Resource())) {
EnsureResources(resources).SetFill(paint_resource);
} }
if (StyleSVGResource* stroke_resource = style.StrokePaint().Resource()) { if (auto* paint_resource =
EnsureResources(resources).SetStroke( GetSVGResourceAsType<LayoutSVGResourcePaintServer>(
CastResource<LayoutSVGResourcePaintServer>(*stroke_resource)); style.StrokePaint().Resource())) {
EnsureResources(resources).SetStroke(paint_resource);
} }
} }
......
...@@ -2606,13 +2606,9 @@ bool PaintLayer::HitTestClippedOutByClipPath( ...@@ -2606,13 +2606,9 @@ bool PaintLayer::HitTestClippedOutByClipPath(
return !clip_path->GetPath(reference_box).Contains(point); return !clip_path->GetPath(reference_box).Contains(point);
} }
DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE); DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
SVGResource* resource = LayoutSVGResourceClipper* clipper = GetSVGResourceAsType(clip_path_operation);
To<ReferenceClipPathOperation>(*clip_path_operation).Resource(); if (!clipper)
LayoutSVGResourceContainer* container =
resource ? resource->ResourceContainer() : nullptr;
if (!container || container->ResourceType() != kClipperResourceType)
return false; return false;
auto* clipper = ToLayoutSVGResourceClipper(container);
// If the clipPath is using "userspace on use" units, then the origin of // If the clipPath is using "userspace on use" units, then the origin of
// the coordinate system is the top-left of the reference box, so adjust // the coordinate system is the top-left of the reference box, so adjust
// the point accordingly. // the point accordingly.
......
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