• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KHTML

SVGSVGElement.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
00003                   2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
00004                   2007 Apple Inc.  All rights reserved.
00005 
00006     This file is part of the KDE project
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include "config.h"
00025 #include <wtf/Platform.h>
00026 
00027 #if ENABLE(SVG)
00028 #include "SVGSVGElement.h"
00029 
00030 #include "AffineTransform.h"
00031 /*#include "CSSHelper.h"*/
00032 #include "css/csshelper.h"
00033 /*#include "CSSPropertyNames.h"*/
00034 #include "Document.h"
00035 //#include "EventListener.h"
00036 #include "dom/dom2_events.h"
00037 /*#include "EventNames.h"*/
00038 #include "FloatConversion.h"
00039 #include "FloatRect.h"
00040 /*#include "Frame.h"
00041 #include "HTMLNames.h"
00042 #include "RenderSVGViewportContainer.h"*/
00043 #include "RenderSVGRoot.h"
00044 #include "SVGAngle.h"
00045 #include "SVGLength.h"
00046 #include "SVGNames.h"
00047 #include "SVGPreserveAspectRatio.h"
00048 #include "SVGTransform.h"
00049 #include "SVGTransformList.h"
00050 /*#include "SVGViewElement.h"*/
00051 #include "SVGViewSpec.h"
00052 /*#include "SVGZoomEvent.h"
00053 #include "SelectionController.h"
00054 #include "SMILTimeContainer.h"*/
00055 
00056 namespace WebCore {
00057 
00058 /*using namespace HTMLNames;
00059 using namespace EventNames;*/
00060 using namespace SVGNames;
00061 
00062 SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document* doc)
00063     : SVGStyledLocatableElement(tagName, doc)
00064     , SVGTests()
00065     , SVGLangSpace()
00066     , SVGExternalResourcesRequired()
00067     , SVGFitToViewBox()
00068     , SVGZoomAndPan()
00069     , m_x(this, LengthModeWidth)
00070     , m_y(this, LengthModeHeight)
00071     , m_width(this, LengthModeWidth)
00072     , m_height(this, LengthModeHeight)
00073     , m_useCurrentView(false)
00074     /*, m_timeContainer(SMILTimeContainer::create(this))
00075     , m_viewSpec(0)*/
00076     , m_containerSize(300, 150)
00077     /*, m_hasSetContainerSize(false)*/
00078 {
00079     setWidthBaseValue(SVGLength(this, LengthModeWidth, "100%"));
00080     setHeightBaseValue(SVGLength(this, LengthModeHeight, "100%"));
00081     //doc->registerForCacheCallbacks(this);
00082 }
00083 
00084 SVGSVGElement::~SVGSVGElement()
00085 {
00086     /*document()->unregisterForCacheCallbacks(this);
00087     // There are cases where removedFromDocument() is not called.
00088     // see ContainerNode::removeAllChildren, called by it's destructor.
00089     document()->accessSVGExtensions()->removeTimeContainer(this);*/
00090 }
00091 
00092 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x)
00093 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y)
00094 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width)
00095 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height)
00096 
00097 const AtomicString& SVGSVGElement::contentScriptType() const
00098 {
00099     /*static const AtomicString defaultValue("text/ecmascript");
00100     const AtomicString& n = getAttribute(contentScriptTypeAttr);
00101     return n.isNull() ? defaultValue : n;*/
00102     ASSERT(false);
00103     return "";
00104 }
00105 
00106 void SVGSVGElement::setContentScriptType(const AtomicString& type)
00107 {
00108     setAttribute(SVGNames::contentScriptTypeAttr, type);
00109 }
00110 
00111 const AtomicString& SVGSVGElement::contentStyleType() const
00112 {
00113     /*static const AtomicString defaultValue("text/css");
00114     const AtomicString& n = getAttribute(contentStyleTypeAttr);
00115     return n.isNull() ? defaultValue : n;*/
00116     ASSERT(false);
00117     return "";
00118 }
00119 
00120 void SVGSVGElement::setContentStyleType(const AtomicString& type)
00121 {
00122     setAttribute(SVGNames::contentStyleTypeAttr, type);
00123 }
00124 
00125 FloatRect SVGSVGElement::viewport() const
00126 {
00127     double _x = 0.0;
00128     double _y = 0.0;
00129     if (!isOutermostSVG()) {
00130         _x = x().value();
00131         _y = y().value();
00132     }
00133     float w = width().value();
00134     float h = height().value();
00135     AffineTransform viewBox = viewBoxToViewTransform(w, h);
00136     double wDouble = w;
00137     double hDouble = h;
00138     viewBox.map(_x, _y, &_x, &_y);
00139     viewBox.map(w, h, &wDouble, &hDouble);
00140     return FloatRect::narrowPrecision(_x, _y, wDouble, hDouble);
00141 }
00142 
00143 int SVGSVGElement::relativeWidthValue() const
00144 {
00145     SVGLength w = width();
00146     if (w.unitType() != LengthTypePercentage)
00147         return 0;
00148 
00149     return static_cast<int>(w.valueAsPercentage() * m_containerSize.width());
00150 }
00151 
00152 int SVGSVGElement::relativeHeightValue() const
00153 {
00154     SVGLength h = height();
00155     if (h.unitType() != LengthTypePercentage)
00156         return 0;
00157 
00158     return static_cast<int>(h.valueAsPercentage() * m_containerSize.height());
00159 }
00160 
00161 float SVGSVGElement::pixelUnitToMillimeterX() const
00162 {
00163     // 2.54 / cssPixelsPerInch gives CM.
00164     return (2.54f / cssPixelsPerInch) * 10.0f;
00165 }
00166 
00167 float SVGSVGElement::pixelUnitToMillimeterY() const
00168 {
00169     // 2.54 / cssPixelsPerInch gives CM.
00170     return (2.54f / cssPixelsPerInch) * 10.0f;
00171 }
00172 
00173 float SVGSVGElement::screenPixelToMillimeterX() const
00174 {
00175     return pixelUnitToMillimeterX();
00176 }
00177 
00178 float SVGSVGElement::screenPixelToMillimeterY() const
00179 {
00180     return pixelUnitToMillimeterY();
00181 }
00182 
00183 bool SVGSVGElement::useCurrentView() const
00184 {
00185     return m_useCurrentView;
00186 }
00187 
00188 void SVGSVGElement::setUseCurrentView(bool currentView)
00189 {
00190     m_useCurrentView = currentView;
00191 }
00192 
00193 SVGViewSpec* SVGSVGElement::currentView() const
00194 {
00195     if (!m_viewSpec)
00196         m_viewSpec.set(new SVGViewSpec(this));
00197 
00198     return m_viewSpec.get();
00199 }
00200 
00201 float SVGSVGElement::currentScale() const
00202 {
00203     /*if (document() && document()->frame())
00204         return document()->frame()->zoomFactor();*/
00205     return 1.0f;
00206 }
00207 
00208 void SVGSVGElement::setCurrentScale(float scale)
00209 {
00210     /*if (document() && document()->frame())
00211         document()->frame()->setZoomFactor(scale, true);*/
00212 }
00213 
00214 FloatPoint SVGSVGElement::currentTranslate() const
00215 {
00216     return m_translation;
00217 }
00218 
00219 void SVGSVGElement::setCurrentTranslate(const FloatPoint &translation)
00220 {
00221     m_translation = translation;
00222     if (parentNode() == document() && document()->renderer())
00223         document()->renderer()->repaint();
00224 }
00225 
00226 void SVGSVGElement::addSVGWindowEventListener(const AtomicString& eventType, const Attribute* attr)
00227 {
00228     // FIXME: None of these should be window events long term.
00229     // Once we propertly support SVGLoad, etc.
00230     RefPtr<EventListener> listener = document()->accessSVGExtensions()->
00231         createSVGEventListener(attr->localName().string(), attr->value(), this);
00232     //document()->setHTMLWindowEventListener(eventType, listener.release());
00233 }
00234 
00235 void SVGSVGElement::parseMappedAttribute(MappedAttribute* attr)
00236 {
00237     kDebug() << "parse attribute: " << attr->localName() << attr->value() << endl;
00238     if (!nearestViewportElement()) {
00239         // Only handle events if we're the outermost <svg> element
00240         /*if (attr->name() == onunloadAttr)
00241             addSVGWindowEventListener(unloadEvent, attr);
00242         else if (attr->name() == onabortAttr)
00243             addSVGWindowEventListener(abortEvent, attr);
00244         else if (attr->name() == onerrorAttr)
00245             addSVGWindowEventListener(errorEvent, attr);
00246         else if (attr->name() == onresizeAttr)
00247             addSVGWindowEventListener(resizeEvent, attr);
00248         else if (attr->name() == onscrollAttr)
00249             addSVGWindowEventListener(scrollEvent, attr);
00250         else if (attr->name() == SVGNames::onzoomAttr)
00251             addSVGWindowEventListener(zoomEvent, attr);*/
00252     }
00253     if (attr->name() == SVGNames::xAttr)
00254         setXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00255     else if (attr->name() == SVGNames::yAttr)
00256         setYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00257     else if (attr->name() == SVGNames::widthAttr) {
00258         kDebug() << "set width" << attr->value() << endl;
00259         setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00260         addCSSProperty(attr, CSSPropertyWidth, attr->value());
00261         /*if (width().value() < 0.0)
00262             document()->accessSVGExtensions()->reportError("A negative value for svg attribute <width> is not allowed");*/
00263     } else if (attr->name() == SVGNames::heightAttr) {
00264         kDebug() << "set height" << attr->value() << endl;
00265         setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00266         addCSSProperty(attr, CSSPropertyHeight, attr->value());
00267         /*if (height().value() < 0.0)
00268             document()->accessSVGExtensions()->reportError("A negative value for svg attribute <height> is not allowed");*/
00269     } else {
00270         /*if (SVGTests::parseMappedAttribute(attr))
00271             return;
00272         if (SVGLangSpace::parseMappedAttribute(attr))
00273             return;
00274         if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
00275             return;
00276         if (SVGFitToViewBox::parseMappedAttribute(attr))
00277             return;
00278         if (SVGZoomAndPan::parseMappedAttribute(attr))
00279             return;*/
00280 
00281         SVGStyledLocatableElement::parseMappedAttribute(attr);
00282     }
00283 }
00284 
00285 void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
00286 {
00287     SVGStyledElement::svgAttributeChanged(attrName);
00288 
00289     if (!renderer())
00290         return;
00291 
00292     /*if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
00293         attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
00294         SVGTests::isKnownAttribute(attrName) ||
00295         SVGLangSpace::isKnownAttribute(attrName) ||
00296         SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
00297         SVGFitToViewBox::isKnownAttribute(attrName) ||
00298         SVGZoomAndPan::isKnownAttribute(attrName) ||
00299         SVGStyledLocatableElement::isKnownAttribute(attrName))
00300         renderer()->setNeedsLayout(true);*/
00301 }
00302 
00303 unsigned long SVGSVGElement::suspendRedraw(unsigned long /* max_wait_milliseconds */)
00304 {
00305     // FIXME: Implement me (see bug 11275)
00306     return 0;
00307 }
00308 
00309 void SVGSVGElement::unsuspendRedraw(unsigned long /* suspend_handle_id */, ExceptionCode& ec)
00310 {
00311     // if suspend_handle_id is not found, throw exception
00312     // FIXME: Implement me (see bug 11275)
00313 }
00314 
00315 void SVGSVGElement::unsuspendRedrawAll()
00316 {
00317     // FIXME: Implement me (see bug 11275)
00318 }
00319 
00320 void SVGSVGElement::forceRedraw()
00321 {
00322     // FIXME: Implement me (see bug 11275)
00323 }
00324 
00325 NodeList* SVGSVGElement::getIntersectionList(const FloatRect& rect, SVGElement*)
00326 {
00327     // FIXME: Implement me (see bug 11274)
00328     return 0;
00329 }
00330 
00331 NodeList* SVGSVGElement::getEnclosureList(const FloatRect& rect, SVGElement*)
00332 {
00333     // FIXME: Implement me (see bug 11274)
00334     return 0;
00335 }
00336 
00337 bool SVGSVGElement::checkIntersection(SVGElement* element, const FloatRect& rect)
00338 {
00339     // TODO : take into account pointer-events?
00340     // FIXME: Why is element ignored??
00341     // FIXME: Implement me (see bug 11274)
00342     return rect.intersects(getBBox());
00343 }
00344 
00345 bool SVGSVGElement::checkEnclosure(SVGElement* element, const FloatRect& rect)
00346 {
00347     // TODO : take into account pointer-events?
00348     // FIXME: Why is element ignored??
00349     // FIXME: Implement me (see bug 11274)
00350     return rect.contains(getBBox());
00351 }
00352 
00353 void SVGSVGElement::deselectAll()
00354 {
00355     //document()->frame()->selectionController()->clear();
00356 }
00357 
00358 float SVGSVGElement::createSVGNumber()
00359 {
00360     return 0.0f;
00361 }
00362 
00363 SVGLength SVGSVGElement::createSVGLength()
00364 {
00365     return SVGLength();
00366 }
00367 
00368 SVGAngle* SVGSVGElement::createSVGAngle()
00369 {
00370     return new SVGAngle();
00371 }
00372 
00373 FloatPoint SVGSVGElement::createSVGPoint()
00374 {
00375     return FloatPoint();
00376 }
00377 
00378 AffineTransform SVGSVGElement::createSVGMatrix()
00379 {
00380     return AffineTransform();
00381 }
00382 
00383 FloatRect SVGSVGElement::createSVGRect()
00384 {
00385     return FloatRect();
00386 }
00387 
00388 SVGTransform SVGSVGElement::createSVGTransform()
00389 {
00390     return SVGTransform();
00391 }
00392 
00393 SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const AffineTransform& matrix)
00394 {
00395     return SVGTransform(matrix);
00396 }
00397 
00398 AffineTransform SVGSVGElement::getCTM() const
00399 {
00400     AffineTransform mat;
00401     if (!isOutermostSVG())
00402         mat.translate(x().value(), y().value());
00403 
00404     if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
00405         AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value());
00406         mat = viewBox * mat;
00407     }
00408 
00409     return mat;
00410 }
00411 
00412 AffineTransform SVGSVGElement::getScreenCTM() const
00413 {
00414     /*document()->updateLayoutIgnorePendingStylesheets();
00415     float rootX = 0.0f;
00416     float rootY = 0.0f;
00417     
00418     if (RenderObject* renderer = this->renderer()) {
00419         renderer = renderer->parent();
00420         if (isOutermostSVG()) {
00421             int tx = 0;
00422             int ty = 0;
00423             if (renderer)
00424                 renderer->absolutePosition(tx, ty, true);
00425             rootX += tx;
00426             rootY += ty;
00427         } else {
00428             rootX += x().value();
00429             rootY += y().value();
00430         }
00431     }
00432     
00433     AffineTransform mat = SVGStyledLocatableElement::getScreenCTM();
00434     mat.translate(rootX, rootY);
00435 
00436     if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
00437         AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value());
00438         mat = viewBox * mat;
00439     }
00440 
00441     return mat;*/
00442     ASSERT(false);
00443     return AffineTransform();
00444 }
00445 
00446 RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
00447 {
00448     kDebug() << "create RenderSVGRoot from <svg> element" << endl;
00449     return new (arena) RenderSVGRoot(this);
00450     /*if (isOutermostSVG())
00451         return new (arena) RenderSVGRoot(this);
00452     else
00453         return new (arena) RenderSVGViewportContainer(this);*/
00454 }
00455 
00456 void SVGSVGElement::insertedIntoDocument()
00457 {
00458     document()->accessSVGExtensions()->addTimeContainer(this);
00459     SVGStyledLocatableElement::insertedIntoDocument();
00460 }
00461 
00462 void SVGSVGElement::removedFromDocument()
00463 {
00464     document()->accessSVGExtensions()->removeTimeContainer(this);
00465     SVGStyledLocatableElement::removedFromDocument();
00466 }
00467 
00468 void SVGSVGElement::pauseAnimations()
00469 {
00470     /*if (!m_timeContainer->isPaused())
00471         m_timeContainer->pause();*/
00472 }
00473 
00474 void SVGSVGElement::unpauseAnimations()
00475 {
00476     /*if (m_timeContainer->isPaused())
00477         m_timeContainer->resume();*/
00478 }
00479 
00480 bool SVGSVGElement::animationsPaused() const
00481 {
00482     //return m_timeContainer->isPaused();
00483     ASSERT(false);
00484     return false;
00485 }
00486 
00487 float SVGSVGElement::getCurrentTime() const
00488 {
00489     //return narrowPrecisionToFloat(m_timeContainer->elapsed().value());
00490     ASSERT(false);
00491     return 0.0;
00492 }
00493 
00494 void SVGSVGElement::setCurrentTime(float /* seconds */)
00495 {
00496     // FIXME: Implement me, bug 12073
00497 }
00498 
00499 bool SVGSVGElement::hasRelativeValues() const
00500 {
00501     return (x().isRelative() || width().isRelative() ||
00502             y().isRelative() || height().isRelative());
00503 }
00504 
00505 bool SVGSVGElement::isOutermostSVG() const
00506 {
00507     // This is true whenever this is the outermost SVG, even if there are HTML elements outside it
00508     return !parentNode()->isSVGElement();
00509 }
00510 
00511 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
00512 {
00513     FloatRect viewBoxRect;
00514     if (useCurrentView()) {
00515         if (currentView()) // what if we should use it but it is not set?
00516             viewBoxRect = currentView()->viewBox();
00517     } else
00518         viewBoxRect = viewBox();
00519     if (!viewBoxRect.width() || !viewBoxRect.height())
00520         return AffineTransform();
00521 
00522     AffineTransform ctm = preserveAspectRatio()->getCTM(viewBoxRect.x(),
00523             viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(),
00524             0, 0, viewWidth, viewHeight);
00525 
00526     if (useCurrentView() && currentView())
00527         return currentView()->transform()->concatenate().matrix() * ctm;
00528 
00529     return ctm;
00530 }
00531 
00532 /*void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement)
00533 {
00534     setUseCurrentView(true);
00535     if (viewElement->hasAttribute(SVGNames::viewBoxAttr))
00536         currentView()->setViewBox(viewElement->viewBox());
00537     else
00538         currentView()->setViewBox(viewBox());
00539     if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) {
00540         currentView()->preserveAspectRatio()->setAlign(viewElement->preserveAspectRatio()->align());
00541         currentView()->preserveAspectRatio()->setMeetOrSlice(viewElement->preserveAspectRatio()->meetOrSlice());
00542     } else {
00543         currentView()->preserveAspectRatio()->setAlign(preserveAspectRatio()->align());
00544         currentView()->preserveAspectRatio()->setMeetOrSlice(preserveAspectRatio()->meetOrSlice());
00545     }
00546     if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr))
00547         currentView()->setZoomAndPan(viewElement->zoomAndPan());
00548     renderer()->setNeedsLayout(true);
00549 }*/
00550     
00551 void SVGSVGElement::willSaveToCache()
00552 {
00553     //pauseAnimations();
00554 }
00555 
00556 void SVGSVGElement::willRestoreFromCache()
00557 {
00558     //unpauseAnimations();
00559 }
00560 
00561 // KHTML stuff
00562 quint32 SVGSVGElement::id() const { return SVGNames::svgTag.id(); }
00563 
00564 }
00565 
00566 #endif // ENABLE(SVG)
00567 
00568 // vim:ts=4:noet

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal