OLD | NEW |
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. |
11 * | 11 * |
12 * This library is distributed in the hope that it will be useful, | 12 * This library is distributed in the hope that it will be useful, |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 * Library General Public License for more details. | 15 * Library General Public License for more details. |
16 * | 16 * |
17 * You should have received a copy of the GNU Library General Public License | 17 * You should have received a copy of the GNU Library General Public License |
18 * along with this library; see the file COPYING.LIB. If not, write to | 18 * along with this library; see the file COPYING.LIB. If not, write to |
19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | 19 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
20 * Boston, MA 02110-1301, USA. | 20 * Boston, MA 02110-1301, USA. |
21 */ | 21 */ |
22 | 22 |
23 #include "config.h" | 23 #include "config.h" |
24 #include "core/layout/svg/LayoutSVGResourceClipper.h" | 24 #include "core/layout/svg/LayoutSVGResourceClipper.h" |
25 | 25 |
26 #include "core/SVGNames.h" | 26 #include "core/SVGNames.h" |
27 #include "core/dom/ElementTraversal.h" | 27 #include "core/dom/ElementTraversal.h" |
28 #include "core/layout/HitTestResult.h" | 28 #include "core/layout/HitTestResult.h" |
29 #include "core/layout/svg/SVGLayoutSupport.h" | 29 #include "core/layout/svg/SVGLayoutSupport.h" |
30 #include "core/layout/svg/SVGResources.h" | |
31 #include "core/layout/svg/SVGResourcesCache.h" | |
32 #include "core/paint/CompositingRecorder.h" | |
33 #include "core/paint/PaintInfo.h" | 30 #include "core/paint/PaintInfo.h" |
34 #include "core/paint/TransformRecorder.h" | |
35 #include "core/svg/SVGGeometryElement.h" | 31 #include "core/svg/SVGGeometryElement.h" |
36 #include "core/svg/SVGUseElement.h" | 32 #include "core/svg/SVGUseElement.h" |
37 #include "platform/RuntimeEnabledFeatures.h" | 33 #include "platform/RuntimeEnabledFeatures.h" |
38 #include "platform/graphics/paint/ClipPathDisplayItem.h" | |
39 #include "platform/graphics/paint/CompositingDisplayItem.h" | |
40 #include "platform/graphics/paint/DisplayItemList.h" | |
41 #include "platform/graphics/paint/DrawingDisplayItem.h" | |
42 #include "platform/graphics/paint/SkPictureBuilder.h" | 34 #include "platform/graphics/paint/SkPictureBuilder.h" |
43 #include "third_party/skia/include/core/SkPicture.h" | 35 #include "third_party/skia/include/core/SkPicture.h" |
44 #include "third_party/skia/include/pathops/SkPathOps.h" | 36 #include "third_party/skia/include/pathops/SkPathOps.h" |
45 | 37 |
46 namespace blink { | 38 namespace blink { |
47 | 39 |
48 LayoutSVGResourceClipper::LayoutSVGResourceClipper(SVGClipPathElement* node) | 40 LayoutSVGResourceClipper::LayoutSVGResourceClipper(SVGClipPathElement* node) |
49 : LayoutSVGResourceContainer(node) | 41 : LayoutSVGResourceContainer(node) |
50 , m_inClipExpansion(false) | 42 , m_inClipExpansion(false) |
51 { | 43 { |
52 } | 44 } |
53 | 45 |
54 LayoutSVGResourceClipper::~LayoutSVGResourceClipper() | 46 LayoutSVGResourceClipper::~LayoutSVGResourceClipper() |
55 { | 47 { |
56 } | 48 } |
57 | 49 |
58 void LayoutSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidatio
n) | 50 void LayoutSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidatio
n) |
59 { | 51 { |
60 m_clipContentPicture.clear(); | 52 m_clipContentPicture.clear(); |
61 m_clipBoundaries = FloatRect(); | 53 m_clipBoundaries = FloatRect(); |
62 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval
idation : ParentOnlyInvalidation); | 54 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval
idation : ParentOnlyInvalidation); |
63 } | 55 } |
64 | 56 |
65 void LayoutSVGResourceClipper::removeClientFromCache(LayoutObject* client, bool
markForInvalidation) | 57 void LayoutSVGResourceClipper::removeClientFromCache(LayoutObject* client, bool
markForInvalidation) |
66 { | 58 { |
67 ASSERT(client); | 59 ASSERT(client); |
68 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati
on : ParentOnlyInvalidation); | 60 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati
on : ParentOnlyInvalidation); |
69 } | 61 } |
70 | 62 |
71 bool LayoutSVGResourceClipper::tryPathOnlyClipping(const LayoutObject& layoutObj
ect, GraphicsContext* context, | 63 bool LayoutSVGResourceClipper::asPath(const AffineTransform& animatedLocalTransf
orm, |
72 const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundi
ngBox) { | 64 const FloatRect& referenceBox, Path& clipPath) { |
73 // If the current clip-path gets clipped itself, we have to fallback to mask
ing. | 65 // If the current clip-path gets clipped itself, we have to fallback to mask
ing. |
74 if (!style()->svgStyle().clipperResource().isEmpty()) | 66 if (style()->svgStyle().hasClipper()) |
75 return false; | 67 return false; |
76 | 68 |
77 Path clipPath; | |
78 bool usingBuilder = false; | 69 bool usingBuilder = false; |
79 SkOpBuilder clipPathBuilder; | 70 SkOpBuilder clipPathBuilder; |
80 | 71 |
81 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()
); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement
)) { | 72 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()
); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement
)) { |
82 LayoutObject* childLayoutObject = childElement->layoutObject(); | 73 LayoutObject* childLayoutObject = childElement->layoutObject(); |
83 if (!childLayoutObject) | 74 if (!childLayoutObject) |
84 continue; | 75 continue; |
85 // Only shapes or paths are supported for direct clipping. We need to fa
llback to masking for texts. | 76 // Only shapes or paths are supported for direct clipping. We need to fa
llback to masking for texts. |
86 if (childLayoutObject->isSVGText()) | 77 if (childLayoutObject->isSVGText()) |
87 return false; | 78 return false; |
88 if (!childElement->isSVGGraphicsElement()) | 79 if (!childElement->isSVGGraphicsElement()) |
89 continue; | 80 continue; |
90 | 81 |
91 const ComputedStyle* style = childLayoutObject->style(); | 82 const ComputedStyle* style = childLayoutObject->style(); |
92 if (!style || style->display() == NONE || style->visibility() != VISIBLE
) | 83 if (!style || style->display() == NONE || style->visibility() != VISIBLE
) |
93 continue; | 84 continue; |
94 const SVGComputedStyle& svgStyle = style->svgStyle(); | 85 const SVGComputedStyle& svgStyle = style->svgStyle(); |
95 // Current shape in clip-path gets clipped too. Fallback to masking. | 86 // Current shape in clip-path gets clipped too. Fallback to masking. |
96 if (!svgStyle.clipperResource().isEmpty()) | 87 if (svgStyle.hasClipper()) |
97 return false; | 88 return false; |
98 | 89 |
99 // First clip shape. | 90 // First clip shape. |
100 if (clipPath.isEmpty()) { | 91 if (clipPath.isEmpty()) { |
101 if (isSVGGeometryElement(childElement)) | 92 if (isSVGGeometryElement(childElement)) |
102 toSVGGeometryElement(childElement)->toClipPath(clipPath); | 93 toSVGGeometryElement(childElement)->toClipPath(clipPath); |
103 else if (isSVGUseElement(childElement)) | 94 else if (isSVGUseElement(childElement)) |
104 toSVGUseElement(childElement)->toClipPath(clipPath); | 95 toSVGUseElement(childElement)->toClipPath(clipPath); |
105 | 96 |
106 continue; | 97 continue; |
(...skipping 21 matching lines...) Expand all Loading... |
128 if (usingBuilder) { | 119 if (usingBuilder) { |
129 SkPath resolvedPath; | 120 SkPath resolvedPath; |
130 clipPathBuilder.resolve(&resolvedPath); | 121 clipPathBuilder.resolve(&resolvedPath); |
131 clipPath = resolvedPath; | 122 clipPath = resolvedPath; |
132 } | 123 } |
133 | 124 |
134 // We are able to represent the clip as a path. Continue with direct clippin
g, | 125 // We are able to represent the clip as a path. Continue with direct clippin
g, |
135 // and transform the content to userspace if necessary. | 126 // and transform the content to userspace if necessary. |
136 if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { | 127 if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { |
137 AffineTransform transform; | 128 AffineTransform transform; |
138 transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); | 129 transform.translate(referenceBox.x(), referenceBox.y()); |
139 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h
eight()); | 130 transform.scaleNonUniform(referenceBox.width(), referenceBox.height()); |
140 clipPath.transform(transform); | 131 clipPath.transform(transform); |
141 } | 132 } |
142 | 133 |
143 // Transform path by animatedLocalTransform. | 134 // Transform path by animatedLocalTransform. |
144 clipPath.transform(animatedLocalTransform); | 135 clipPath.transform(animatedLocalTransform); |
145 | |
146 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { | |
147 if (!context->displayItemList()->displayItemConstructionIsDisabled()) | |
148 context->displayItemList()->createAndAppend<BeginClipPathDisplayItem
>(layoutObject, clipPath); | |
149 } else { | |
150 BeginClipPathDisplayItem clipPathDisplayItem(layoutObject, clipPath); | |
151 clipPathDisplayItem.replay(*context); | |
152 } | |
153 | |
154 return true; | 136 return true; |
155 } | 137 } |
156 | 138 |
157 PassRefPtr<const SkPicture> LayoutSVGResourceClipper::createContentPicture(Affin
eTransform& contentTransformation, const FloatRect& targetBoundingBox, | 139 PassRefPtr<const SkPicture> LayoutSVGResourceClipper::createContentPicture(Affin
eTransform& contentTransformation, const FloatRect& targetBoundingBox, |
158 GraphicsContext* context) | 140 GraphicsContext* context) |
159 { | 141 { |
160 ASSERT(frame()); | 142 ASSERT(frame()); |
161 | 143 |
162 if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { | 144 if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { |
163 contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox
.y()); | 145 contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox
.y()); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 AffineTransform transform; | 263 AffineTransform transform; |
282 transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); | 264 transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); |
283 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h
eight()); | 265 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h
eight()); |
284 return transform.mapRect(m_clipBoundaries); | 266 return transform.mapRect(m_clipBoundaries); |
285 } | 267 } |
286 | 268 |
287 return m_clipBoundaries; | 269 return m_clipBoundaries; |
288 } | 270 } |
289 | 271 |
290 } | 272 } |
OLD | NEW |