File indexing completed on 2024-04-28 15:24:35

0001 /*
0002     Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
0003                   2004, 2005, 2006 Rob Buis <buis@kde.org>
0004 
0005     This file is part of the KDE project
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #include "wtf/Platform.h"
0024 
0025 #if ENABLE(SVG)
0026 
0027 #include "SVGLocatable.h"
0028 
0029 #include "AffineTransform.h"
0030 #include "RenderPath.h"
0031 #include "SVGException.h"
0032 #include "SVGSVGElement.h"
0033 
0034 namespace WebCore
0035 {
0036 
0037 SVGLocatable::SVGLocatable()
0038 {
0039 }
0040 
0041 SVGLocatable::~SVGLocatable()
0042 {
0043 }
0044 
0045 SVGElement *SVGLocatable::nearestViewportElement(const SVGStyledElement *e)
0046 {
0047     Q_UNUSED(e);
0048     /*
0049     Node* n = e->parentNode();
0050     while (n && !n->isDocumentNode()) {
0051         if (n->hasTagName(SVGNames::svgTag) || n->hasTagName(SVGNames::symbolTag) ||
0052             n->hasTagName(SVGNames::imageTag))
0053             return static_cast<SVGElement*>(n);
0054     #if ENABLE(SVG_FOREIGN_OBJECT)
0055         if (n->hasTagName(SVGNames::foreignObjectTag))
0056             return static_cast<SVGElement*>(n);
0057     #endif
0058 
0059         n = n->parentNode();
0060     }*/
0061 
0062     return nullptr;
0063 }
0064 
0065 SVGElement *SVGLocatable::farthestViewportElement(const SVGStyledElement *e)
0066 {
0067     Q_UNUSED(e);
0068     // FIXME : likely this will be always the <svg> farthest away.
0069     // If we have a different implementation of documentElement(), one
0070     // that give the documentElement() of the svg fragment, it could be
0071     // used instead. This depends on cdf demands though(Rob.)
0072     SVGElement *farthest = nullptr;
0073     /*Node* n = e->parentNode();
0074     while (n && !n->isDocumentNode()) {
0075         if (n->hasTagName(SVGNames::svgTag) || n->hasTagName(SVGNames::symbolTag) ||
0076             n->hasTagName(SVGNames::imageTag))
0077             farthest = static_cast<SVGElement*>(n);
0078     #if ENABLE(SVG_FOREIGN_OBJECT)
0079         if (n->hasTagName(SVGNames::foreignObjectTag))
0080             farthest = static_cast<SVGElement*>(n);
0081     #endif
0082 
0083         n = n->parentNode();
0084     }*/
0085 
0086     return farthest;
0087 }
0088 
0089 // Spec:
0090 // https://www.w3.org/TR/2005/WD-SVGMobile12-20050413/svgudom.html#svg::SVGLocatable
0091 FloatRect SVGLocatable::getBBox(const SVGStyledElement *e)
0092 {
0093     Q_UNUSED(e);
0094     FloatRect bboxRect;
0095 
0096     /*if (e && e->renderer()) {
0097         // Need this to make sure we have render object dimensions.
0098         // See bug 11686.
0099         e->document()->updateLayoutIgnorePendingStylesheets();
0100         bboxRect = e->renderer()->relativeBBox(false);
0101     }*/
0102 
0103     return bboxRect;
0104 }
0105 
0106 AffineTransform SVGLocatable::getCTM(const SVGElement *element)
0107 {
0108     if (!element) {
0109         return AffineTransform();
0110     }
0111 
0112     AffineTransform ctm;
0113 
0114     Node *parent = element->parentNode();
0115     if (parent && parent->isSVGElement()) {
0116         SVGElement *parentElement = static_cast<SVGElement *>(parent);
0117         if (parentElement && parentElement->isStyledLocatable()) {
0118             AffineTransform parentCTM = static_cast<SVGStyledLocatableElement *>(parentElement)->getCTM();
0119             ctm = parentCTM * ctm;
0120         }
0121     }
0122 
0123     return ctm;
0124 }
0125 
0126 AffineTransform SVGLocatable::getScreenCTM(const SVGElement *element)
0127 {
0128     if (!element) {
0129         return AffineTransform();
0130     }
0131 
0132     AffineTransform ctm;
0133 
0134     Node *parent = element->parentNode();
0135     if (parent && parent->isSVGElement()) {
0136         SVGElement *parentElement = static_cast<SVGElement *>(parent);
0137         if (parentElement && parentElement->isStyledLocatable()) {
0138             AffineTransform parentCTM = static_cast<SVGStyledLocatableElement *>(parentElement)->getScreenCTM();
0139             ctm = parentCTM * ctm;
0140         }
0141     }
0142 
0143     return ctm;
0144 }
0145 
0146 AffineTransform SVGLocatable::getTransformToElement(SVGElement *target, ExceptionCode &ec) const
0147 {
0148     Q_UNUSED(ec);
0149     AffineTransform ctm = getCTM();
0150 
0151     if (target && target->isStyledLocatable()) {
0152         AffineTransform targetCTM = static_cast<SVGStyledLocatableElement *>(target)->getCTM();
0153         if (!targetCTM.isInvertible()) {
0154             //ec = SVGException::SVG_MATRIX_NOT_INVERTABLE;
0155             return ctm;
0156         }
0157         ctm *= targetCTM.inverse();
0158     }
0159 
0160     return ctm;
0161 }
0162 
0163 }
0164 
0165 #endif // ENABLE(SVG)
0166