Rubber-stamped by Brady Eidson.
[webbrowser.git] / WebCore / svg / SVGLocatable.cpp
blob00acc2a0d7cb1b6c9f4be096518802a3326f503a
1 /*
2 Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3 2004, 2005, 2006 Rob Buis <buis@kde.org>
4 Copyright (C) 2009 Google, Inc. All rights reserved.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
22 #include "config.h"
23 #if ENABLE(SVG)
25 #include "SVGLocatable.h"
27 #include "TransformationMatrix.h"
28 #include "RenderPath.h"
29 #include "SVGException.h"
30 #include "SVGSVGElement.h"
32 namespace WebCore {
34 SVGLocatable::SVGLocatable()
38 SVGLocatable::~SVGLocatable()
42 static bool isViewportElement(Node* node)
44 return (node->hasTagName(SVGNames::svgTag)
45 || node->hasTagName(SVGNames::symbolTag)
46 #if ENABLE(SVG_FOREIGN_OBJECT)
47 || node->hasTagName(SVGNames::foreignObjectTag)
48 #endif
49 || node->hasTagName(SVGNames::imageTag));
52 SVGElement* SVGLocatable::nearestViewportElement(const SVGElement* element)
54 ASSERT(element);
55 for (Node* n = element->parentNode(); n && !n->isDocumentNode(); n = n->parentNode()) {
56 if (isViewportElement(n))
57 return static_cast<SVGElement*>(n);
60 return 0;
63 SVGElement* SVGLocatable::farthestViewportElement(const SVGElement* element)
65 ASSERT(element);
66 SVGElement* farthest = 0;
67 for (Node* n = element->parentNode(); n && !n->isDocumentNode(); n = n->parentNode()) {
68 if (isViewportElement(n))
69 farthest = static_cast<SVGElement*>(n);
71 return farthest;
74 FloatRect SVGLocatable::getBBox(const SVGElement* element)
76 element->document()->updateLayoutIgnorePendingStylesheets();
78 // FIXME: Eventually we should support getBBox for detached elements.
79 if (!element->renderer())
80 return FloatRect();
82 return element->renderer()->objectBoundingBox();
85 TransformationMatrix SVGLocatable::getCTM(const SVGElement* element)
87 ASSERT(element);
88 TransformationMatrix ctm;
90 Node* parent = element->parentNode();
91 if (parent && parent->isSVGElement()) {
92 SVGElement* parentElement = static_cast<SVGElement*>(parent);
93 if (parentElement && parentElement->isStyledLocatable()) {
94 TransformationMatrix parentCTM = static_cast<SVGStyledLocatableElement*>(parentElement)->getCTM();
95 ctm = parentCTM * ctm;
99 return ctm;
102 TransformationMatrix SVGLocatable::getScreenCTM(const SVGElement* element)
104 ASSERT(element);
105 TransformationMatrix ctm;
107 Node* parent = element->parentNode();
108 if (parent && parent->isSVGElement()) {
109 SVGElement* parentElement = static_cast<SVGElement*>(parent);
110 if (parentElement && parentElement->isStyledLocatable()) {
111 TransformationMatrix parentCTM = static_cast<SVGStyledLocatableElement*>(parentElement)->getScreenCTM();
112 ctm = parentCTM * ctm;
116 return ctm;
119 TransformationMatrix SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec) const
121 TransformationMatrix ctm = getCTM();
123 if (target && target->isStyledLocatable()) {
124 TransformationMatrix targetCTM = static_cast<SVGStyledLocatableElement*>(target)->getCTM();
125 if (!targetCTM.isInvertible()) {
126 ec = SVGException::SVG_MATRIX_NOT_INVERTABLE;
127 return ctm;
129 ctm *= targetCTM.inverse();
132 return ctm;
137 #endif // ENABLE(SVG)
139 // vim:ts=4:noet