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 @@
#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/style/reference_clip_path_operation.h"
#include "third_party/blink/renderer/core/svg/svg_unit_types.h"
#include "third_party/skia/include/core/SkRefCnt.h"
......@@ -88,6 +89,16 @@ class LayoutSVGResourceClipper final : public LayoutSVGResourceContainer {
DEFINE_LAYOUT_SVG_RESOURCE_TYPE_CASTS(LayoutSVGResourceClipper,
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
#endif
......@@ -21,6 +21,8 @@
#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/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"
namespace blink {
......@@ -106,6 +108,29 @@ DEFINE_LAYOUT_OBJECT_TYPE_CASTS(LayoutSVGResourceContainer,
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
#endif
......@@ -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
......@@ -108,6 +108,10 @@ class LayoutSVGResourceFilter final : public LayoutSVGResourceContainer {
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());
} // namespace blink
......
......@@ -114,6 +114,12 @@ class LayoutSVGResourcePaintServer : public LayoutSVGResourceContainer {
LayoutSVGResourceMode);
};
template <>
inline bool IsResourceOfType<LayoutSVGResourcePaintServer>(
LayoutSVGResourceContainer* container) {
return container->IsSVGPaintServer();
}
} // namespace blink
#endif
......@@ -740,7 +740,7 @@ void WriteResources(WTF::TextStream& ts,
WriteStandardPrefix(ts, *clipper, 0);
ts << " " << clipper->ResourceBoundingBox(reference_box) << "\n";
}
if (LayoutSVGResourceFilter* filter = resources->Filter()) {
if (LayoutSVGResourceFilter* filter = GetFilterResourceForSVG(style)) {
DCHECK(style.HasFilter());
DCHECK_EQ(style.Filter().size(), 1u);
const FilterOperation& filter_operation = *style.Filter().at(0);
......
......@@ -115,37 +115,6 @@ static HashSet<AtomicString>& FillAndStrokeTags() {
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 {
return clipper_filter_masker_data_ || marker_data_ || fill_stroke_data_ ||
linked_resource_;
......@@ -176,59 +145,51 @@ std::unique_ptr<SVGResources> SVGResources::BuildResources(
std::unique_ptr<SVGResources> resources;
if (ClipperFilterMaskerTags().Contains(tag_name)) {
if (computed_style.ClipPath() && !object.IsSVGRoot()) {
ClipPathOperation* clip_path_operation = computed_style.ClipPath();
if (clip_path_operation->GetType() == ClipPathOperation::REFERENCE) {
const ReferenceClipPathOperation& clip_path_reference =
To<ReferenceClipPathOperation>(*clip_path_operation);
EnsureResources(resources).SetClipper(
CastResource<LayoutSVGResourceClipper>(
clip_path_reference.Resource()));
if (LayoutSVGResourceClipper* clipper =
GetSVGResourceAsType(computed_style.ClipPath())) {
EnsureResources(resources).SetClipper(clipper);
}
}
if (computed_style.HasFilter() && !object.IsSVGRoot()) {
const FilterOperations& filter_operations = computed_style.Filter();
if (filter_operations.size() == 1) {
const FilterOperation& filter_operation = *filter_operations.at(0);
if (const auto* reference_filter_operation =
DynamicTo<ReferenceFilterOperation>(filter_operation)) {
EnsureResources(resources).SetFilter(
CastResource<LayoutSVGResourceFilter>(
reference_filter_operation->Resource()));
}
if (LayoutSVGResourceFilter* filter =
GetFilterResourceForSVG(computed_style)) {
EnsureResources(resources).SetFilter(filter);
}
}
if (StyleSVGResource* masker_resource = style.MaskerResource()) {
EnsureResources(resources).SetMasker(
CastResource<LayoutSVGResourceMasker>(*masker_resource));
if (auto* masker = GetSVGResourceAsType<LayoutSVGResourceMasker>(
style.MaskerResource())) {
EnsureResources(resources).SetMasker(masker);
}
}
if (style.HasMarkers() && SupportsMarkers(element)) {
if (StyleSVGResource* marker_start_resource = style.MarkerStartResource()) {
EnsureResources(resources).SetMarkerStart(
CastResource<LayoutSVGResourceMarker>(*marker_start_resource));
if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
style.MarkerStartResource())) {
EnsureResources(resources).SetMarkerStart(marker);
}
if (StyleSVGResource* marker_mid_resource = style.MarkerMidResource()) {
EnsureResources(resources).SetMarkerMid(
CastResource<LayoutSVGResourceMarker>(*marker_mid_resource));
if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
style.MarkerMidResource())) {
EnsureResources(resources).SetMarkerMid(marker);
}
if (StyleSVGResource* marker_end_resource = style.MarkerEndResource()) {
EnsureResources(resources).SetMarkerEnd(
CastResource<LayoutSVGResourceMarker>(*marker_end_resource));
if (auto* marker = GetSVGResourceAsType<LayoutSVGResourceMarker>(
style.MarkerEndResource())) {
EnsureResources(resources).SetMarkerEnd(marker);
}
}
if (FillAndStrokeTags().Contains(tag_name)) {
if (StyleSVGResource* fill_resource = style.FillPaint().Resource()) {
EnsureResources(resources).SetFill(
CastResource<LayoutSVGResourcePaintServer>(*fill_resource));
if (auto* paint_resource =
GetSVGResourceAsType<LayoutSVGResourcePaintServer>(
style.FillPaint().Resource())) {
EnsureResources(resources).SetFill(paint_resource);
}
if (StyleSVGResource* stroke_resource = style.StrokePaint().Resource()) {
EnsureResources(resources).SetStroke(
CastResource<LayoutSVGResourcePaintServer>(*stroke_resource));
if (auto* paint_resource =
GetSVGResourceAsType<LayoutSVGResourcePaintServer>(
style.StrokePaint().Resource())) {
EnsureResources(resources).SetStroke(paint_resource);
}
}
......
......@@ -2606,13 +2606,9 @@ bool PaintLayer::HitTestClippedOutByClipPath(
return !clip_path->GetPath(reference_box).Contains(point);
}
DCHECK_EQ(clip_path_operation->GetType(), ClipPathOperation::REFERENCE);
SVGResource* resource =
To<ReferenceClipPathOperation>(*clip_path_operation).Resource();
LayoutSVGResourceContainer* container =
resource ? resource->ResourceContainer() : nullptr;
if (!container || container->ResourceType() != kClipperResourceType)
LayoutSVGResourceClipper* clipper = GetSVGResourceAsType(clip_path_operation);
if (!clipper)
return false;
auto* clipper = ToLayoutSVGResourceClipper(container);
// 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 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