• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
5 
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.
10 
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.
15 
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.
20 */
21 
22 #include "config.h"
23 #if ENABLE(SVG)
24 
25 #include "SVGLocatable.h"
26 
27 #include "AffineTransform.h"
28 #include "RenderPath.h"
29 #include "SVGException.h"
30 #include "SVGSVGElement.h"
31 
32 namespace WebCore {
33 
SVGLocatable()34 SVGLocatable::SVGLocatable()
35 {
36 }
37 
~SVGLocatable()38 SVGLocatable::~SVGLocatable()
39 {
40 }
41 
isViewportElement(Node * node)42 static bool isViewportElement(Node* node)
43 {
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));
50 }
51 
nearestViewportElement(const SVGElement * element)52 SVGElement* SVGLocatable::nearestViewportElement(const SVGElement* element)
53 {
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);
58     }
59 
60     return 0;
61 }
62 
farthestViewportElement(const SVGElement * element)63 SVGElement* SVGLocatable::farthestViewportElement(const SVGElement* element)
64 {
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);
70     }
71     return farthest;
72 }
73 
getBBox(const SVGElement * element)74 FloatRect SVGLocatable::getBBox(const SVGElement* element)
75 {
76     element->document()->updateLayoutIgnorePendingStylesheets();
77 
78     // FIXME: Eventually we should support getBBox for detached elements.
79     if (!element->renderer())
80         return FloatRect();
81 
82     return element->renderer()->objectBoundingBox();
83 }
84 
getCTM(const SVGElement * element)85 AffineTransform SVGLocatable::getCTM(const SVGElement* element)
86 {
87     ASSERT(element);
88     AffineTransform ctm;
89 
90     Node* parent = element->parentNode();
91     if (parent && parent->isSVGElement()) {
92         SVGElement* parentElement = static_cast<SVGElement*>(parent);
93         if (parentElement && parentElement->isStyledLocatable()) {
94             AffineTransform parentCTM = static_cast<SVGStyledLocatableElement*>(parentElement)->getCTM();
95             ctm = parentCTM * ctm;
96         }
97     }
98 
99     return ctm;
100 }
101 
getScreenCTM(const SVGElement * element)102 AffineTransform SVGLocatable::getScreenCTM(const SVGElement* element)
103 {
104     ASSERT(element);
105     AffineTransform ctm;
106 
107     Node* parent = element->parentNode();
108     if (parent && parent->isSVGElement()) {
109         SVGElement* parentElement = static_cast<SVGElement*>(parent);
110         if (parentElement && parentElement->isStyledLocatable()) {
111             AffineTransform parentCTM = static_cast<SVGStyledLocatableElement*>(parentElement)->getScreenCTM();
112             ctm = parentCTM * ctm;
113         }
114     }
115 
116     return ctm;
117 }
118 
getTransformToElement(SVGElement * target,ExceptionCode & ec) const119 AffineTransform SVGLocatable::getTransformToElement(SVGElement* target, ExceptionCode& ec) const
120 {
121     AffineTransform ctm = getCTM();
122 
123     if (target && target->isStyledLocatable()) {
124         AffineTransform targetCTM = static_cast<SVGStyledLocatableElement*>(target)->getCTM();
125         if (!targetCTM.isInvertible()) {
126             ec = SVGException::SVG_MATRIX_NOT_INVERTABLE;
127             return ctm;
128         }
129         ctm *= targetCTM.inverse();
130     }
131 
132     return ctm;
133 }
134 
135 }
136 
137 #endif // ENABLE(SVG)
138 
139 // vim:ts=4:noet
140