| Index: third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
|
| diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
|
| index 3179cad77ebcb183e603311a10c8a7f0e721201b..be03d5aa916ed184fa358b7cc55cf7029ba5287f 100644
|
| --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
|
| +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp
|
| @@ -36,58 +36,58 @@ namespace blink {
|
|
|
| namespace {
|
|
|
| -bool requiresMask(const LayoutObject& layoutObject) {
|
| - // Only basic shapes or paths are supported for direct clipping. We need to
|
| - // fallback to masking for texts.
|
| - if (layoutObject.isSVGText())
|
| - return true;
|
| - // Current shape in clip-path gets clipped too. Fallback to masking.
|
| - return layoutObject.styleRef().clipPath();
|
| -}
|
| -
|
| -bool requiresMask(const SVGElement& element) {
|
| - const LayoutObject* layoutObject = element.layoutObject();
|
| - DCHECK(layoutObject);
|
| - if (isSVGUseElement(element)) {
|
| - if (layoutObject->styleRef().clipPath())
|
| - return true;
|
| - const SVGGraphicsElement* clippingElement =
|
| - toSVGUseElement(element).visibleTargetGraphicsElementForClipping();
|
| - DCHECK(clippingElement);
|
| - layoutObject = clippingElement->layoutObject();
|
| - }
|
| - return requiresMask(*layoutObject);
|
| +enum class ClipStrategy { None, Mask, Path };
|
| +
|
| +ClipStrategy modifyStrategyForClipPath(const ComputedStyle& style,
|
| + ClipStrategy strategy) {
|
| + // If the shape in the clip-path gets clipped too then fallback to masking.
|
| + if (strategy != ClipStrategy::Path || !style.clipPath())
|
| + return strategy;
|
| + return ClipStrategy::Mask;
|
| }
|
|
|
| -bool contributesToClip(const SVGGraphicsElement& element) {
|
| +ClipStrategy determineClipStrategy(const SVGGraphicsElement& element) {
|
| const LayoutObject* layoutObject = element.layoutObject();
|
| if (!layoutObject)
|
| - return false;
|
| + return ClipStrategy::None;
|
| const ComputedStyle& style = layoutObject->styleRef();
|
| if (style.display() == EDisplay::None ||
|
| style.visibility() != EVisibility::Visible)
|
| - return false;
|
| + return ClipStrategy::None;
|
| + ClipStrategy strategy = ClipStrategy::None;
|
| // Only shapes, paths and texts are allowed for clipping.
|
| - return layoutObject->isSVGShape() || layoutObject->isSVGText();
|
| + if (layoutObject->isSVGShape()) {
|
| + strategy = ClipStrategy::Path;
|
| + } else if (layoutObject->isSVGText()) {
|
| + // Text requires masking.
|
| + strategy = ClipStrategy::Mask;
|
| + }
|
| + return modifyStrategyForClipPath(style, strategy);
|
| }
|
|
|
| -bool contributesToClip(const SVGElement& element) {
|
| +ClipStrategy determineClipStrategy(const SVGElement& element) {
|
| // <use> within <clipPath> have a restricted content model.
|
| // (https://drafts.fxtf.org/css-masking-1/#ClipPathElement)
|
| if (isSVGUseElement(element)) {
|
| const LayoutObject* useLayoutObject = element.layoutObject();
|
| if (!useLayoutObject ||
|
| useLayoutObject->styleRef().display() == EDisplay::None)
|
| - return false;
|
| - const SVGGraphicsElement* clippingElement =
|
| + return ClipStrategy::None;
|
| + const SVGGraphicsElement* shapeElement =
|
| toSVGUseElement(element).visibleTargetGraphicsElementForClipping();
|
| - if (!clippingElement)
|
| - return false;
|
| - return contributesToClip(*clippingElement);
|
| + if (!shapeElement)
|
| + return ClipStrategy::None;
|
| + ClipStrategy shapeStrategy = determineClipStrategy(*shapeElement);
|
| + return modifyStrategyForClipPath(useLayoutObject->styleRef(),
|
| + shapeStrategy);
|
| }
|
| if (!element.isSVGGraphicsElement())
|
| - return false;
|
| - return contributesToClip(toSVGGraphicsElement(element));
|
| + return ClipStrategy::None;
|
| + return determineClipStrategy(toSVGGraphicsElement(element));
|
| +}
|
| +
|
| +bool contributesToClip(const SVGElement& element) {
|
| + return determineClipStrategy(element) != ClipStrategy::None;
|
| }
|
|
|
| void pathFromElement(const SVGElement& element, Path& clipPath) {
|
| @@ -137,10 +137,10 @@ bool LayoutSVGResourceClipper::calculateClipContentPathIfNeeded() {
|
|
|
| for (const SVGElement& childElement :
|
| Traversal<SVGElement>::childrenOf(*element())) {
|
| - if (!contributesToClip(childElement))
|
| + ClipStrategy strategy = determineClipStrategy(childElement);
|
| + if (strategy == ClipStrategy::None)
|
| continue;
|
| -
|
| - if (requiresMask(childElement)) {
|
| + if (strategy == ClipStrategy::Mask) {
|
| m_clipContentPath.clear();
|
| return false;
|
| }
|
|
|