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

Side by Side Diff: Source/core/svg/SVGSVGElement.cpp

Issue 185333004: [SVG] Refactor getIntersectionList() and getEnclosureList() (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Copyright notice update. Created 6 years, 9 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
« no previous file with comments | « Source/core/svg/SVGSVGElement.h ('k') | 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, 2006 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org>
4 * Copyright (C) 2007 Apple Inc. All rights reserved. 4 * Copyright (C) 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2014 Google, Inc.
5 * 6 *
6 * This library is free software; you can redistribute it and/or 7 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 8 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 9 * License as published by the Free Software Foundation; either
9 * 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.
10 * 11 *
11 * 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,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details. 15 * Library General Public License for more details.
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 if (updateRelativeLengthsOrViewBox 323 if (updateRelativeLengthsOrViewBox
323 || SVGZoomAndPan::isKnownAttribute(attrName)) { 324 || SVGZoomAndPan::isKnownAttribute(attrName)) {
324 if (renderer()) 325 if (renderer())
325 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render er()); 326 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render er());
326 return; 327 return;
327 } 328 }
328 329
329 SVGGraphicsElement::svgAttributeChanged(attrName); 330 SVGGraphicsElement::svgAttributeChanged(attrName);
330 } 331 }
331 332
332 PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const Flo atRect& rect, SVGElement* referenceElement, CollectIntersectionOrEnclosure colle ct) const 333 // FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
334 static bool intersectsAllowingEmpty(const FloatRect& r1, const FloatRect& r2)
335 {
336 if (r1.width() < 0 || r1.height() < 0 || r2.width() < 0 || r2.height() < 0)
337 return false;
338
339 return r1.x() < r2.maxX() && r2.x() < r1.maxX()
340 && r1.y() < r2.maxY() && r2.y() < r1.maxY();
341 }
342
343 // One of the element types that can cause graphics to be drawn onto the target canvas.
344 // Specifically: circle, ellipse, image, line, path, polygon, polyline, rect, te xt and use.
345 static bool isIntersectionOrEnclosureTarget(RenderObject* renderer)
346 {
347 return renderer->isSVGShape()
348 || renderer->isSVGText()
349 || renderer->isSVGImage()
350 || renderer->node()->hasTagName(SVGNames::useTag);
351 }
352
353 bool SVGSVGElement::checkIntersectionOrEnclosure(const SVGElement& element, cons t FloatRect& rect,
354 CheckIntersectionOrEnclosure mode) const
355 {
356 RenderObject* renderer = element.renderer();
357 ASSERT(!renderer || renderer->style());
358 if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
359 return false;
360
361 if (!isIntersectionOrEnclosureTarget(renderer))
362 return false;
363
364 AffineTransform ctm = toSVGGraphicsElement(element).computeCTM(AncestorScope , DisallowStyleUpdate, this);
365 FloatRect mappedRepaintRect = ctm.mapRect(renderer->repaintRectInLocalCoordi nates());
366
367 bool result = false;
368 switch (mode) {
369 case CheckIntersection:
370 result = intersectsAllowingEmpty(rect, mappedRepaintRect);
371 break;
372 case CheckEnclosure:
373 result = rect.contains(mappedRepaintRect);
374 break;
375 default:
376 ASSERT_NOT_REACHED();
377 break;
378 }
379
380 return result;
381 }
382
383 PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const Flo atRect& rect,
384 SVGElement* referenceElement, CheckIntersectionOrEnclosure mode) const
333 { 385 {
334 Vector<RefPtr<Node> > nodes; 386 Vector<RefPtr<Node> > nodes;
335 Element* element = ElementTraversal::next(*(referenceElement ? referenceElem ent : this)); 387
336 while (element) { 388 const SVGElement* root = this;
337 if (element->isSVGElement()) { 389 if (referenceElement) {
338 SVGElement* svgElement = toSVGElement(element); 390 // Only the common subtree needs to be traversed.
339 if (collect == CollectIntersectionList) { 391 if (contains(referenceElement)) {
340 if (RenderSVGModelObject::checkIntersection(svgElement->renderer (), rect)) 392 root = referenceElement;
341 nodes.append(element); 393 } else if (!isDescendantOf(referenceElement)) {
342 } else { 394 // No common subtree.
343 if (RenderSVGModelObject::checkEnclosure(svgElement->renderer(), rect)) 395 return StaticNodeList::adopt(nodes);
344 nodes.append(element);
345 }
346 } 396 }
397 }
347 398
348 element = ElementTraversal::next(*element, referenceElement ? referenceE lement : this); 399 for (Element* element = ElementTraversal::firstWithin(*root); element;
400 element = ElementTraversal::next(*element, root)) {
401
402 if (!WebCore::isSVGGraphicsElement(*element))
403 continue;
404
405 SVGElement* svgElement = toSVGElement(element);
406 if (checkIntersectionOrEnclosure(*svgElement, rect, mode))
407 nodes.append(element);
349 } 408 }
409
350 return StaticNodeList::adopt(nodes); 410 return StaticNodeList::adopt(nodes);
351 } 411 }
352 412
353 PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOf f> passRect, SVGElement* referenceElement) const 413 PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOf f> rect, SVGElement* referenceElement) const
354 { 414 {
355 RefPtr<SVGRectTearOff> rect = passRect; 415 document().updateLayoutIgnorePendingStylesheets();
356 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CollectIntersectionList); 416
417 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CheckIntersection);
357 } 418 }
358 419
359 PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> passRect, SVGElement* referenceElement) const 420 PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> rect, SVGElement* referenceElement) const
360 { 421 {
361 RefPtr<SVGRectTearOff> rect = passRect; 422 document().updateLayoutIgnorePendingStylesheets();
362 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CollectEnclosureList); 423
424 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CheckEnclosure);
363 } 425 }
364 426
365 bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTea rOff> passRect) const 427 bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTea rOff> rect) const
366 { 428 {
367 RefPtr<SVGRectTearOff> rect = passRect; 429 ASSERT(element);
368 return RenderSVGModelObject::checkIntersection(element->renderer(), rect->ta rget()->value()); 430 document().updateLayoutIgnorePendingStylesheets();
431
432 return checkIntersectionOrEnclosure(*element, rect->target()->value(), Check Intersection);
369 } 433 }
370 434
371 bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOf f> passRect) const 435 bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOf f> rect) const
372 { 436 {
373 RefPtr<SVGRectTearOff> rect = passRect; 437 ASSERT(element);
374 return RenderSVGModelObject::checkEnclosure(element->renderer(), rect->targe t()->value()); 438 document().updateLayoutIgnorePendingStylesheets();
439
440 return checkIntersectionOrEnclosure(*element, rect->target()->value(), Check Enclosure);
375 } 441 }
376 442
377 void SVGSVGElement::deselectAll() 443 void SVGSVGElement::deselectAll()
378 { 444 {
379 if (LocalFrame* frame = document().frame()) 445 if (LocalFrame* frame = document().frame())
380 frame->selection().clear(); 446 frame->selection().clear();
381 } 447 }
382 448
383 PassRefPtr<SVGNumberTearOff> SVGSVGElement::createSVGNumber() 449 PassRefPtr<SVGNumberTearOff> SVGSVGElement::createSVGNumber()
384 { 450 {
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 Vector<Element*>::const_iterator end = elements.end(); 846 Vector<Element*>::const_iterator end = elements.end();
781 for (Vector<Element*>::const_iterator it = elements.begin(); it != end; ++it ) { 847 for (Vector<Element*>::const_iterator it = elements.begin(); it != end; ++it ) {
782 if ((*it)->isDescendantOf(this)) 848 if ((*it)->isDescendantOf(this))
783 return *it; 849 return *it;
784 } 850 }
785 851
786 return 0; 852 return 0;
787 } 853 }
788 854
789 } 855 }
OLDNEW
« no previous file with comments | « Source/core/svg/SVGSVGElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698