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

Side by Side Diff: Source/core/rendering/svg/RenderSVGResourceClipper.cpp

Issue 899163003: Move rendering/RenderObject to layout/LayoutObject. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 5 years, 10 months 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 | Annotate | Revision Log
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 { 51 {
52 } 52 }
53 53
54 void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidatio n) 54 void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidatio n)
55 { 55 {
56 m_clipContentPicture.clear(); 56 m_clipContentPicture.clear();
57 m_clipBoundaries = FloatRect(); 57 m_clipBoundaries = FloatRect();
58 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval idation : ParentOnlyInvalidation); 58 markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInval idation : ParentOnlyInvalidation);
59 } 59 }
60 60
61 void RenderSVGResourceClipper::removeClientFromCache(RenderObject* client, bool markForInvalidation) 61 void RenderSVGResourceClipper::removeClientFromCache(LayoutObject* client, bool markForInvalidation)
62 { 62 {
63 ASSERT(client); 63 ASSERT(client);
64 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati on : ParentOnlyInvalidation); 64 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidati on : ParentOnlyInvalidation);
65 } 65 }
66 66
67 bool RenderSVGResourceClipper::applyStatefulResource(RenderObject* object, Graph icsContext*& context, ClipperState& clipperState) 67 bool RenderSVGResourceClipper::applyStatefulResource(LayoutObject* object, Graph icsContext*& context, ClipperState& clipperState)
68 { 68 {
69 ASSERT(object); 69 ASSERT(object);
70 ASSERT(context); 70 ASSERT(context);
71 71
72 clearInvalidationMask(); 72 clearInvalidationMask();
73 73
74 return applyClippingToContext(object, object->objectBoundingBox(), object->p aintInvalidationRectInLocalCoordinates(), context, clipperState); 74 return applyClippingToContext(object, object->objectBoundingBox(), object->p aintInvalidationRectInLocalCoordinates(), context, clipperState);
75 } 75 }
76 76
77 bool RenderSVGResourceClipper::tryPathOnlyClipping(DisplayItemClient client, Gra phicsContext* context, 77 bool RenderSVGResourceClipper::tryPathOnlyClipping(DisplayItemClient client, Gra phicsContext* context,
78 const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundi ngBox) { 78 const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundi ngBox) {
79 // If the current clip-path gets clipped itself, we have to fallback to mask ing. 79 // If the current clip-path gets clipped itself, we have to fallback to mask ing.
80 if (!style()->svgStyle().clipperResource().isEmpty()) 80 if (!style()->svgStyle().clipperResource().isEmpty())
81 return false; 81 return false;
82 WindRule clipRule = RULE_NONZERO; 82 WindRule clipRule = RULE_NONZERO;
83 Path clipPath = Path(); 83 Path clipPath = Path();
84 84
85 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) { 85 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
86 RenderObject* renderer = childElement->renderer(); 86 LayoutObject* renderer = childElement->renderer();
87 if (!renderer) 87 if (!renderer)
88 continue; 88 continue;
89 // Only shapes or paths are supported for direct clipping. We need to fa llback to masking for texts. 89 // Only shapes or paths are supported for direct clipping. We need to fa llback to masking for texts.
90 if (renderer->isSVGText()) 90 if (renderer->isSVGText())
91 return false; 91 return false;
92 if (!childElement->isSVGGraphicsElement()) 92 if (!childElement->isSVGGraphicsElement())
93 continue; 93 continue;
94 SVGGraphicsElement* styled = toSVGGraphicsElement(childElement); 94 SVGGraphicsElement* styled = toSVGGraphicsElement(childElement);
95 RenderStyle* style = renderer->style(); 95 RenderStyle* style = renderer->style();
96 if (!style || style->display() == NONE || style->visibility() != VISIBLE ) 96 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { 137 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
138 context->displayItemList()->add(BeginClipPathDisplayItem::create(client, clipPath, clipRule)); 138 context->displayItemList()->add(BeginClipPathDisplayItem::create(client, clipPath, clipRule));
139 } else { 139 } else {
140 BeginClipPathDisplayItem clipPathDisplayItem(client, clipPath, clipRule) ; 140 BeginClipPathDisplayItem clipPathDisplayItem(client, clipPath, clipRule) ;
141 clipPathDisplayItem.replay(context); 141 clipPathDisplayItem.replay(context);
142 } 142 }
143 143
144 return true; 144 return true;
145 } 145 }
146 146
147 bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* target, cons t FloatRect& targetBoundingBox, 147 bool RenderSVGResourceClipper::applyClippingToContext(LayoutObject* target, cons t FloatRect& targetBoundingBox,
148 const FloatRect& paintInvalidationRect, GraphicsContext* context, ClipperSta te& clipperState) 148 const FloatRect& paintInvalidationRect, GraphicsContext* context, ClipperSta te& clipperState)
149 { 149 {
150 ASSERT(target); 150 ASSERT(target);
151 ASSERT(context); 151 ASSERT(context);
152 ASSERT(clipperState == ClipperNotApplied); 152 ASSERT(clipperState == ClipperNotApplied);
153 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout()); 153 ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
154 154
155 if (paintInvalidationRect.isEmpty() || m_inClipExpansion) 155 if (paintInvalidationRect.isEmpty() || m_inClipExpansion)
156 return false; 156 return false;
157 TemporaryChange<bool> inClipExpansionChange(m_inClipExpansion, true); 157 TemporaryChange<bool> inClipExpansionChange(m_inClipExpansion, true);
(...skipping 16 matching lines...) Expand all
174 // Fall back to masking. 174 // Fall back to masking.
175 clipperState = ClipperAppliedMask; 175 clipperState = ClipperAppliedMask;
176 176
177 // Mask layer start 177 // Mask layer start
178 context->beginTransparencyLayer(1, &paintInvalidationRect); 178 context->beginTransparencyLayer(1, &paintInvalidationRect);
179 { 179 {
180 GraphicsContextStateSaver maskContentSaver(*context); 180 GraphicsContextStateSaver maskContentSaver(*context);
181 context->concatCTM(animatedLocalTransform); 181 context->concatCTM(animatedLocalTransform);
182 182
183 // clipPath can also be clipped by another clipPath. 183 // clipPath can also be clipped by another clipPath.
184 SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObj ect(this); 184 SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObj ect(this);
185 RenderSVGResourceClipper* clipPathClipper = resources ? resources->clipp er() : 0; 185 RenderSVGResourceClipper* clipPathClipper = resources ? resources->clipp er() : 0;
186 ClipperState clipPathClipperState = ClipperNotApplied; 186 ClipperState clipPathClipperState = ClipperNotApplied;
187 if (clipPathClipper && !clipPathClipper->applyClippingToContext(this, ta rgetBoundingBox, paintInvalidationRect, context, clipPathClipperState)) { 187 if (clipPathClipper && !clipPathClipper->applyClippingToContext(this, ta rgetBoundingBox, paintInvalidationRect, context, clipPathClipperState)) {
188 // FIXME: Awkward state micro-management. Ideally, GraphicsContextSt ateSaver should 188 // FIXME: Awkward state micro-management. Ideally, GraphicsContextSt ateSaver should
189 // a) pop saveLayers also 189 // a) pop saveLayers also
190 // b) pop multiple states if needed (similarly to SkCanvas::restor eToCount()) 190 // b) pop multiple states if needed (similarly to SkCanvas::restor eToCount())
191 // Then we should be able to replace this mess with a single, top-le vel GCSS. 191 // Then we should be able to replace this mess with a single, top-le vel GCSS.
192 maskContentSaver.restore(); 192 maskContentSaver.restore();
193 context->endLayer(); 193 context->endLayer();
194 return false; 194 return false;
195 } 195 }
196 196
197 drawClipMaskContent(context, targetBoundingBox); 197 drawClipMaskContent(context, targetBoundingBox);
198 198
199 if (clipPathClipper) 199 if (clipPathClipper)
200 clipPathClipper->postApplyStatefulResource(this, context, clipPathCl ipperState); 200 clipPathClipper->postApplyStatefulResource(this, context, clipPathCl ipperState);
201 } 201 }
202 202
203 // Masked content layer start. 203 // Masked content layer start.
204 context->beginLayer(1, SkXfermode::kSrcIn_Mode, &paintInvalidationRect); 204 context->beginLayer(1, SkXfermode::kSrcIn_Mode, &paintInvalidationRect);
205 205
206 return true; 206 return true;
207 } 207 }
208 208
209 void RenderSVGResourceClipper::postApplyStatefulResource(RenderObject* target, G raphicsContext*& context, ClipperState& clipperState) 209 void RenderSVGResourceClipper::postApplyStatefulResource(LayoutObject* target, G raphicsContext*& context, ClipperState& clipperState)
210 { 210 {
211 switch (clipperState) { 211 switch (clipperState) {
212 case ClipperAppliedPath: 212 case ClipperAppliedPath:
213 // Path-only clipping, no layers to restore but we need to emit an end t o the clip path display item. 213 // Path-only clipping, no layers to restore but we need to emit an end t o the clip path display item.
214 { 214 {
215 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { 215 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
216 context->displayItemList()->add(EndClipPathDisplayItem::create(t arget->displayItemClient())); 216 context->displayItemList()->add(EndClipPathDisplayItem::create(t arget->displayItemClient()));
217 } else { 217 } else {
218 EndClipPathDisplayItem endClipPathDisplayItem(target->displayIte mClient()); 218 EndClipPathDisplayItem endClipPathDisplayItem(target->displayIte mClient());
219 endClipPathDisplayItem.replay(context); 219 endClipPathDisplayItem.replay(context);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 ASSERT(context); 255 ASSERT(context);
256 ASSERT(frame()); 256 ASSERT(frame());
257 257
258 // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinat es) to avoid the intersection 258 // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinat es) to avoid the intersection
259 // with local clips/mask, which may yield incorrect results when mixing obje ctBoundingBox and 259 // with local clips/mask, which may yield incorrect results when mixing obje ctBoundingBox and
260 // userSpaceOnUse units (http://crbug.com/294900). 260 // userSpaceOnUse units (http://crbug.com/294900).
261 FloatRect bounds = strokeBoundingBox(); 261 FloatRect bounds = strokeBoundingBox();
262 context->beginRecording(bounds); 262 context->beginRecording(bounds);
263 263
264 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) { 264 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
265 RenderObject* renderer = childElement->renderer(); 265 LayoutObject* renderer = childElement->renderer();
266 if (!renderer) 266 if (!renderer)
267 continue; 267 continue;
268 268
269 RenderStyle* style = renderer->style(); 269 RenderStyle* style = renderer->style();
270 if (!style || style->display() == NONE || style->visibility() != VISIBLE ) 270 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
271 continue; 271 continue;
272 272
273 WindRule newClipRule = style->svgStyle().clipRule(); 273 WindRule newClipRule = style->svgStyle().clipRule();
274 bool isUseElement = isSVGUseElement(*childElement); 274 bool isUseElement = isSVGUseElement(*childElement);
275 if (isUseElement) { 275 if (isUseElement) {
(...skipping 23 matching lines...) Expand all
299 renderer->paint(info, IntPoint()); 299 renderer->paint(info, IntPoint());
300 } 300 }
301 301
302 m_clipContentPicture = context->endRecording(); 302 m_clipContentPicture = context->endRecording();
303 } 303 }
304 304
305 void RenderSVGResourceClipper::calculateClipContentPaintInvalidationRect() 305 void RenderSVGResourceClipper::calculateClipContentPaintInvalidationRect()
306 { 306 {
307 // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip. 307 // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip.
308 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) { 308 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
309 RenderObject* renderer = childElement->renderer(); 309 LayoutObject* renderer = childElement->renderer();
310 if (!renderer) 310 if (!renderer)
311 continue; 311 continue;
312 if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElemen t(*childElement)) 312 if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElemen t(*childElement))
313 continue; 313 continue;
314 RenderStyle* style = renderer->style(); 314 RenderStyle* style = renderer->style();
315 if (!style || style->display() == NONE || style->visibility() != VISIBLE ) 315 if (!style || style->display() == NONE || style->visibility() != VISIBLE )
316 continue; 316 continue;
317 m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(render er->paintInvalidationRectInLocalCoordinates())); 317 m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(render er->paintInvalidationRectInLocalCoordinates()));
318 } 318 }
319 m_clipBoundaries = toSVGClipPathElement(element())->calculateAnimatedLocalTr ansform().mapRect(m_clipBoundaries); 319 m_clipBoundaries = toSVGClipPathElement(element())->calculateAnimatedLocalTr ansform().mapRect(m_clipBoundaries);
(...skipping 12 matching lines...) Expand all
332 point = transform.inverse().mapPoint(point); 332 point = transform.inverse().mapPoint(point);
333 } 333 }
334 334
335 AffineTransform animatedLocalTransform = toSVGClipPathElement(element())->ca lculateAnimatedLocalTransform(); 335 AffineTransform animatedLocalTransform = toSVGClipPathElement(element())->ca lculateAnimatedLocalTransform();
336 if (!animatedLocalTransform.isInvertible()) 336 if (!animatedLocalTransform.isInvertible())
337 return false; 337 return false;
338 338
339 point = animatedLocalTransform.inverse().mapPoint(point); 339 point = animatedLocalTransform.inverse().mapPoint(point);
340 340
341 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) { 341 for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element() ); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement )) {
342 RenderObject* renderer = childElement->renderer(); 342 LayoutObject* renderer = childElement->renderer();
343 if (!renderer) 343 if (!renderer)
344 continue; 344 continue;
345 if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElemen t(*childElement)) 345 if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElemen t(*childElement))
346 continue; 346 continue;
347 IntPoint hitPoint; 347 IntPoint hitPoint;
348 HitTestResult result(hitPoint); 348 HitTestResult result(hitPoint);
349 if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipCon tent), result, point, HitTestForeground)) 349 if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipCon tent), result, point, HitTestForeground))
350 return true; 350 return true;
351 } 351 }
352 352
353 return false; 353 return false;
354 } 354 }
355 355
356 FloatRect RenderSVGResourceClipper::resourceBoundingBox(const RenderObject* obje ct) 356 FloatRect RenderSVGResourceClipper::resourceBoundingBox(const LayoutObject* obje ct)
357 { 357 {
358 // Resource was not layouted yet. Give back the boundingBox of the object. 358 // Resource was not layouted yet. Give back the boundingBox of the object.
359 if (selfNeedsLayout()) 359 if (selfNeedsLayout())
360 return object->objectBoundingBox(); 360 return object->objectBoundingBox();
361 361
362 if (m_clipBoundaries.isEmpty()) 362 if (m_clipBoundaries.isEmpty())
363 calculateClipContentPaintInvalidationRect(); 363 calculateClipContentPaintInvalidationRect();
364 364
365 if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { 365 if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
366 FloatRect objectBoundingBox = object->objectBoundingBox(); 366 FloatRect objectBoundingBox = object->objectBoundingBox();
367 AffineTransform transform; 367 AffineTransform transform;
368 transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); 368 transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
369 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h eight()); 369 transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.h eight());
370 return transform.mapRect(m_clipBoundaries); 370 return transform.mapRect(m_clipBoundaries);
371 } 371 }
372 372
373 return m_clipBoundaries; 373 return m_clipBoundaries;
374 } 374 }
375 375
376 } 376 }
OLDNEW
« no previous file with comments | « Source/core/rendering/svg/RenderSVGResourceClipper.h ('k') | Source/core/rendering/svg/RenderSVGResourceContainer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698