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

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: Build fix. 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
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 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public 7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either 8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version. 9 * version 2 of the License, or (at your option) any later version.
10 * 10 *
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 if (updateRelativeLengthsOrViewBox 322 if (updateRelativeLengthsOrViewBox
323 || SVGZoomAndPan::isKnownAttribute(attrName)) { 323 || SVGZoomAndPan::isKnownAttribute(attrName)) {
324 if (renderer()) 324 if (renderer())
325 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render er()); 325 RenderSVGResource::markForLayoutAndParentResourceInvalidation(render er());
326 return; 326 return;
327 } 327 }
328 328
329 SVGGraphicsElement::svgAttributeChanged(attrName); 329 SVGGraphicsElement::svgAttributeChanged(attrName);
330 } 330 }
331 331
332 PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const Flo atRect& rect, SVGElement* referenceElement, CollectIntersectionOrEnclosure colle ct) const 332 // FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
333 // So special-case handling of such lines.
334 static bool intersectsAllowingEmpty(const FloatRect& r, const FloatRect& other)
Stephen Chennney 2014/03/03 13:00:22 Either this is much simpler to implement, or I'm n
f(malita) 2014/03/03 14:12:18 TBH I haven't looked beyond the comments when movi
335 {
336 if (r.isEmpty() && other.isEmpty())
fs 2014/03/03 10:44:32 This function had me wondering... Since isEmpty()
337 return false;
338 if (r.isEmpty() && !other.isEmpty()) {
339 return (other.contains(r.x(), r.y()) && !other.contains(r.maxX(), r.maxY ()))
340 || (!other.contains(r.x(), r.y()) && other.contains(r.maxX(), r.maxY ()));
341 }
342 if (other.isEmpty() && !r.isEmpty())
343 return intersectsAllowingEmpty(other, r);
fs 2014/03/03 10:44:32 Might make sense to just make the code in the abov
344 return r.intersects(other);
345 }
346
347 // One of the element types that can cause graphics to be drawn onto the target canvas.
348 // Specifically: circle, ellipse, image, line, path, polygon, polyline, rect, te xt and use.
349 static bool isIntersectionOrEnclosureTarget(RenderObject* renderer)
350 {
351 return renderer->isSVGShape()
352 || renderer->isSVGText()
353 || renderer->isSVGImage()
354 || renderer->node()->hasTagName(SVGNames::useTag);
355 }
356
357 bool SVGSVGElement::checkIntersectionOrEnclosure(const SVGElement& element, cons t FloatRect& rect,
358 CheckIntersectionOrEnclosure mode) const
359 {
360 RenderObject* renderer = element.renderer();
361 ASSERT(!renderer || renderer->style());
362 if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
363 return false;
364
365 if (!isIntersectionOrEnclosureTarget(renderer))
366 return false;
367
368 ASSERT(WebCore::isSVGGraphicsElement(element));
369 AffineTransform ctm = toSVGGraphicsElement(element).computeCTM(AncestorScope , DisallowStyleUpdate, this);
370 FloatRect mappedRepaintRect = ctm.mapRect(renderer->repaintRectInLocalCoordi nates());
371
372 bool result = false;
373 switch (mode) {
374 case CheckIntersection:
375 result = intersectsAllowingEmpty(rect, mappedRepaintRect);
376 break;
377 case CheckEnclosure:
378 result = rect.contains(mappedRepaintRect);
379 break;
380 default:
381 ASSERT_NOT_REACHED();
382 break;
383 }
384
385 return result;
386 }
387
388 PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const Flo atRect& rect,
389 SVGElement* referenceElement, CheckIntersectionOrEnclosure mode) const
333 { 390 {
334 Vector<RefPtr<Node> > nodes; 391 Vector<RefPtr<Node> > nodes;
335 Element* element = ElementTraversal::next(*(referenceElement ? referenceElem ent : this)); 392
336 while (element) { 393 const SVGElement* root = this;
337 if (element->isSVGElement()) { 394 if (referenceElement) {
fs 2014/03/03 10:44:32 Some test(s) for this case would be nice - but I'm
f(malita) 2014/03/03 14:12:18 I'll add some willingly :)
338 SVGElement* svgElement = toSVGElement(element); 395 // Only the common subtree needs to be traversed.
339 if (collect == CollectIntersectionList) { 396 if (contains(referenceElement)) {
340 if (RenderSVGModelObject::checkIntersection(svgElement->renderer (), rect)) 397 root = referenceElement;
341 nodes.append(element); 398 } else if (!isDescendantOf(referenceElement)) {
342 } else { 399 // No common subtree: the spec is not clear about this case - should we bend over backwards
fs 2014/03/03 10:44:32 I think this is in line with the spec wording, so
f(malita) 2014/03/03 14:12:18 Awesome, I'll remove the comment then.
343 if (RenderSVGModelObject::checkEnclosure(svgElement->renderer(), rect)) 400 // to find a common ancestor and map everything in its space?
344 nodes.append(element); 401 return StaticNodeList::adopt(nodes);
345 }
346 } 402 }
403 }
347 404
348 element = ElementTraversal::next(*element, referenceElement ? referenceE lement : this); 405 for (Element* element = ElementTraversal::firstWithin(*root); element;
406 element = ElementTraversal::next(*element, root)) {
407
408 if (!WebCore::isSVGGraphicsElement(*element))
409 continue;
410
411 SVGElement* svgElement = toSVGElement(element);
412 if (checkIntersectionOrEnclosure(*svgElement, rect, mode))
413 nodes.append(element);
349 } 414 }
415
350 return StaticNodeList::adopt(nodes); 416 return StaticNodeList::adopt(nodes);
351 } 417 }
352 418
353 PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOf f> passRect, SVGElement* referenceElement) const 419 PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOf f> rect, SVGElement* referenceElement) const
354 { 420 {
355 RefPtr<SVGRectTearOff> rect = passRect; 421 document().updateLayoutIgnorePendingStylesheets();
356 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CollectIntersectionList); 422
423 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CheckIntersection);
357 } 424 }
358 425
359 PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> passRect, SVGElement* referenceElement) const 426 PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> rect, SVGElement* referenceElement) const
360 { 427 {
361 RefPtr<SVGRectTearOff> rect = passRect; 428 document().updateLayoutIgnorePendingStylesheets();
362 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CollectEnclosureList); 429
430 return collectIntersectionOrEnclosureList(rect->target()->value(), reference Element, CheckEnclosure);
363 } 431 }
364 432
365 bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTea rOff> passRect) const 433 bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTea rOff> rect) const
366 { 434 {
367 RefPtr<SVGRectTearOff> rect = passRect; 435 ASSERT(element);
368 return RenderSVGModelObject::checkIntersection(element->renderer(), rect->ta rget()->value()); 436 document().updateLayoutIgnorePendingStylesheets();
437
438 return checkIntersectionOrEnclosure(*element, rect->target()->value(), Check Intersection);
369 } 439 }
370 440
371 bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOf f> passRect) const 441 bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOf f> rect) const
372 { 442 {
373 RefPtr<SVGRectTearOff> rect = passRect; 443 ASSERT(element);
374 return RenderSVGModelObject::checkEnclosure(element->renderer(), rect->targe t()->value()); 444 document().updateLayoutIgnorePendingStylesheets();
445
446 return checkIntersectionOrEnclosure(*element, rect->target()->value(), Check Enclosure);
375 } 447 }
376 448
377 void SVGSVGElement::deselectAll() 449 void SVGSVGElement::deselectAll()
378 { 450 {
379 if (LocalFrame* frame = document().frame()) 451 if (LocalFrame* frame = document().frame())
380 frame->selection().clear(); 452 frame->selection().clear();
381 } 453 }
382 454
383 PassRefPtr<SVGNumberTearOff> SVGSVGElement::createSVGNumber() 455 PassRefPtr<SVGNumberTearOff> SVGSVGElement::createSVGNumber()
384 { 456 {
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 Vector<Element*>::const_iterator end = elements.end(); 852 Vector<Element*>::const_iterator end = elements.end();
781 for (Vector<Element*>::const_iterator it = elements.begin(); it != end; ++it ) { 853 for (Vector<Element*>::const_iterator it = elements.begin(); it != end; ++it ) {
782 if ((*it)->isDescendantOf(this)) 854 if ((*it)->isDescendantOf(this))
783 return *it; 855 return *it;
784 } 856 }
785 857
786 return 0; 858 return 0;
787 } 859 }
788 860
789 } 861 }
OLDNEW
« Source/core/svg/SVGElement.h ('K') | « Source/core/svg/SVGSVGElement.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698