Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1136)

Side by Side Diff: third_party/WebKit/Source/core/layout/svg/LayoutSVGResourceClipper.cpp

Issue 2563613002: Unify "contributes to" and "requires mask" for clip-path child iteration (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org>
4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. 4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
5 * Copyright (C) 2011 Dirk Schulze <krit@webkit.org> 5 * Copyright (C) 2011 Dirk Schulze <krit@webkit.org>
6 * 6 *
7 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version. 10 * version 2 of the License, or (at your option) any later version.
(...skipping 18 matching lines...) Expand all
29 #include "core/svg/SVGGeometryElement.h" 29 #include "core/svg/SVGGeometryElement.h"
30 #include "core/svg/SVGUseElement.h" 30 #include "core/svg/SVGUseElement.h"
31 #include "platform/graphics/paint/SkPictureBuilder.h" 31 #include "platform/graphics/paint/SkPictureBuilder.h"
32 #include "third_party/skia/include/core/SkPicture.h" 32 #include "third_party/skia/include/core/SkPicture.h"
33 #include "third_party/skia/include/pathops/SkPathOps.h" 33 #include "third_party/skia/include/pathops/SkPathOps.h"
34 34
35 namespace blink { 35 namespace blink {
36 36
37 namespace { 37 namespace {
38 38
39 bool requiresMask(const LayoutObject& layoutObject) { 39 enum class ClipStrategy { None, Mask, Path };
40 // Only basic shapes or paths are supported for direct clipping. We need to 40
41 // fallback to masking for texts. 41 ClipStrategy modifyStrategyForClipPath(const ComputedStyle& style,
42 if (layoutObject.isSVGText()) 42 ClipStrategy strategy) {
43 return true; 43 // If the shape in the clip-path gets clipped too then fallback to masking.
44 // Current shape in clip-path gets clipped too. Fallback to masking. 44 if (strategy != ClipStrategy::Path || !style.clipPath())
45 return layoutObject.styleRef().clipPath(); 45 return strategy;
46 return ClipStrategy::Mask;
46 } 47 }
47 48
48 bool requiresMask(const SVGElement& element) { 49 ClipStrategy determineClipStrategy(const SVGGraphicsElement& element) {
49 const LayoutObject* layoutObject = element.layoutObject();
50 DCHECK(layoutObject);
51 if (isSVGUseElement(element)) {
52 if (layoutObject->styleRef().clipPath())
53 return true;
54 const SVGGraphicsElement* clippingElement =
55 toSVGUseElement(element).visibleTargetGraphicsElementForClipping();
56 DCHECK(clippingElement);
57 layoutObject = clippingElement->layoutObject();
58 }
59 return requiresMask(*layoutObject);
60 }
61
62 bool contributesToClip(const SVGGraphicsElement& element) {
63 const LayoutObject* layoutObject = element.layoutObject(); 50 const LayoutObject* layoutObject = element.layoutObject();
64 if (!layoutObject) 51 if (!layoutObject)
65 return false; 52 return ClipStrategy::None;
66 const ComputedStyle& style = layoutObject->styleRef(); 53 const ComputedStyle& style = layoutObject->styleRef();
67 if (style.display() == EDisplay::None || 54 if (style.display() == EDisplay::None ||
68 style.visibility() != EVisibility::Visible) 55 style.visibility() != EVisibility::Visible)
69 return false; 56 return ClipStrategy::None;
57 ClipStrategy strategy = ClipStrategy::None;
70 // Only shapes, paths and texts are allowed for clipping. 58 // Only shapes, paths and texts are allowed for clipping.
71 return layoutObject->isSVGShape() || layoutObject->isSVGText(); 59 if (layoutObject->isSVGShape()) {
60 strategy = ClipStrategy::Path;
61 } else if (layoutObject->isSVGText()) {
62 // Text requires masking.
63 strategy = ClipStrategy::Mask;
64 }
65 return modifyStrategyForClipPath(style, strategy);
72 } 66 }
73 67
74 bool contributesToClip(const SVGElement& element) { 68 ClipStrategy determineClipStrategy(const SVGElement& element) {
75 // <use> within <clipPath> have a restricted content model. 69 // <use> within <clipPath> have a restricted content model.
76 // (https://drafts.fxtf.org/css-masking-1/#ClipPathElement) 70 // (https://drafts.fxtf.org/css-masking-1/#ClipPathElement)
77 if (isSVGUseElement(element)) { 71 if (isSVGUseElement(element)) {
78 const LayoutObject* useLayoutObject = element.layoutObject(); 72 const LayoutObject* useLayoutObject = element.layoutObject();
79 if (!useLayoutObject || 73 if (!useLayoutObject ||
80 useLayoutObject->styleRef().display() == EDisplay::None) 74 useLayoutObject->styleRef().display() == EDisplay::None)
81 return false; 75 return ClipStrategy::None;
82 const SVGGraphicsElement* clippingElement = 76 const SVGGraphicsElement* shapeElement =
83 toSVGUseElement(element).visibleTargetGraphicsElementForClipping(); 77 toSVGUseElement(element).visibleTargetGraphicsElementForClipping();
84 if (!clippingElement) 78 if (!shapeElement)
85 return false; 79 return ClipStrategy::None;
86 return contributesToClip(*clippingElement); 80 ClipStrategy shapeStrategy = determineClipStrategy(*shapeElement);
81 return modifyStrategyForClipPath(useLayoutObject->styleRef(),
82 shapeStrategy);
87 } 83 }
88 if (!element.isSVGGraphicsElement()) 84 if (!element.isSVGGraphicsElement())
89 return false; 85 return ClipStrategy::None;
90 return contributesToClip(toSVGGraphicsElement(element)); 86 return determineClipStrategy(toSVGGraphicsElement(element));
87 }
88
89 bool contributesToClip(const SVGElement& element) {
90 return determineClipStrategy(element) != ClipStrategy::None;
91 } 91 }
92 92
93 void pathFromElement(const SVGElement& element, Path& clipPath) { 93 void pathFromElement(const SVGElement& element, Path& clipPath) {
94 if (isSVGGeometryElement(element)) 94 if (isSVGGeometryElement(element))
95 toSVGGeometryElement(element).toClipPath(clipPath); 95 toSVGGeometryElement(element).toClipPath(clipPath);
96 else if (isSVGUseElement(element)) 96 else if (isSVGUseElement(element))
97 toSVGUseElement(element).toClipPath(clipPath); 97 toSVGUseElement(element).toClipPath(clipPath);
98 } 98 }
99 99
100 } // namespace 100 } // namespace
(...skipping 29 matching lines...) Expand all
130 // masking. 130 // masking.
131 if (styleRef().clipPath()) 131 if (styleRef().clipPath())
132 return false; 132 return false;
133 133
134 unsigned opCount = 0; 134 unsigned opCount = 0;
135 bool usingBuilder = false; 135 bool usingBuilder = false;
136 SkOpBuilder clipPathBuilder; 136 SkOpBuilder clipPathBuilder;
137 137
138 for (const SVGElement& childElement : 138 for (const SVGElement& childElement :
139 Traversal<SVGElement>::childrenOf(*element())) { 139 Traversal<SVGElement>::childrenOf(*element())) {
140 if (!contributesToClip(childElement)) 140 ClipStrategy strategy = determineClipStrategy(childElement);
141 if (strategy == ClipStrategy::None)
141 continue; 142 continue;
142 143 if (strategy == ClipStrategy::Mask) {
143 if (requiresMask(childElement)) {
144 m_clipContentPath.clear(); 144 m_clipContentPath.clear();
145 return false; 145 return false;
146 } 146 }
147 147
148 // First clip shape. 148 // First clip shape.
149 if (m_clipContentPath.isEmpty()) { 149 if (m_clipContentPath.isEmpty()) {
150 pathFromElement(childElement, m_clipContentPath); 150 pathFromElement(childElement, m_clipContentPath);
151 continue; 151 continue;
152 } 152 }
153 153
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 toSVGClipPathElement(element())->calculateTransform( 302 toSVGClipPathElement(element())->calculateTransform(
303 SVGElement::IncludeMotionTransform); 303 SVGElement::IncludeMotionTransform);
304 if (clipPathUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox) { 304 if (clipPathUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox) {
305 transform.translate(referenceBox.x(), referenceBox.y()); 305 transform.translate(referenceBox.x(), referenceBox.y());
306 transform.scaleNonUniform(referenceBox.width(), referenceBox.height()); 306 transform.scaleNonUniform(referenceBox.width(), referenceBox.height());
307 } 307 }
308 return transform.mapRect(m_localClipBounds); 308 return transform.mapRect(m_localClipBounds);
309 } 309 }
310 310
311 } // namespace blink 311 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698