• Skip to content
  • Skip to link menu
KDE 4.3 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 #include "khtml_part.h"
00056 
00057 namespace WebCore {
00058 
00059 /*using namespace HTMLNames;
00060 using namespace EventNames;*/
00061 using namespace SVGNames;
00062 
00063 SVGSVGElement::SVGSVGElement(const QualifiedName& tagName, Document* doc)
00064     : SVGStyledLocatableElement(tagName, doc)
00065     , SVGTests()
00066     , SVGLangSpace()
00067     , SVGExternalResourcesRequired()
00068     , SVGFitToViewBox()
00069     , SVGZoomAndPan()
00070     , m_x(this, LengthModeWidth)
00071     , m_y(this, LengthModeHeight)
00072     , m_width(this, LengthModeWidth)
00073     , m_height(this, LengthModeHeight)
00074     , m_useCurrentView(false)
00075     /*, m_timeContainer(SMILTimeContainer::create(this))
00076     , m_viewSpec(0)*/
00077 {
00078     setWidthBaseValue(SVGLength(this, LengthModeWidth, "100%"));
00079     setHeightBaseValue(SVGLength(this, LengthModeHeight, "100%"));
00080     //doc->registerForCacheCallbacks(this);
00081 }
00082 
00083 SVGSVGElement::~SVGSVGElement()
00084 {
00085     /*document()->unregisterForCacheCallbacks(this);
00086     // There are cases where removedFromDocument() is not called.
00087     // see ContainerNode::removeAllChildren, called by it's destructor.
00088     document()->accessSVGExtensions()->removeTimeContainer(this);*/
00089 }
00090 
00091 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x)
00092 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y)
00093 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width)
00094 ANIMATED_PROPERTY_DEFINITIONS(SVGSVGElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height)
00095 
00096 const AtomicString& SVGSVGElement::contentScriptType() const
00097 {
00098     /*static const AtomicString defaultValue("text/ecmascript");
00099     const AtomicString& n = getAttribute(contentScriptTypeAttr);
00100     return n.isNull() ? defaultValue : n;*/
00101     ASSERT(false);
00102     return "";
00103 }
00104 
00105 void SVGSVGElement::setContentScriptType(const AtomicString& type)
00106 {
00107     setAttribute(SVGNames::contentScriptTypeAttr, type);
00108 }
00109 
00110 const AtomicString& SVGSVGElement::contentStyleType() const
00111 {
00112     /*static const AtomicString defaultValue("text/css");
00113     const AtomicString& n = getAttribute(contentStyleTypeAttr);
00114     return n.isNull() ? defaultValue : n;*/
00115     ASSERT(false);
00116     return "";
00117 }
00118 
00119 void SVGSVGElement::setContentStyleType(const AtomicString& type)
00120 {
00121     setAttribute(SVGNames::contentStyleTypeAttr, type);
00122 }
00123 
00124 bool SVGSVGElement::hasSetContainerSize() const
00125 {
00126     // For now, we interpret % dimensions only if we're a top-level SVG element nested inside
00127     // an another part. ### might even want to check if we're the documentElement; this
00128     // will also need changes with <img> handling
00129     return isOutermostSVG() && document()->part()->parentPart();
00130 }
00131 
00132 IntSize SVGSVGElement::containerSize() const
00133 {
00134     if (KHTMLView* v = document()->view())
00135         return IntSize(v->visibleWidth(), v->visibleHeight());
00136     else
00137         return IntSize(300, 150);
00138 }
00139 
00140 FloatRect SVGSVGElement::viewport() const
00141 {
00142     double _x = 0.0;
00143     double _y = 0.0;
00144     if (!isOutermostSVG()) {
00145         _x = x().value();
00146         _y = y().value();
00147     }
00148     float w = width().value();
00149     float h = height().value();
00150     AffineTransform viewBox = viewBoxToViewTransform(w, h);
00151     double wDouble = w;
00152     double hDouble = h;
00153     viewBox.map(_x, _y, &_x, &_y);
00154     viewBox.map(w, h, &wDouble, &hDouble);
00155     return FloatRect::narrowPrecision(_x, _y, wDouble, hDouble);
00156 }
00157 
00158 int SVGSVGElement::relativeWidthValue() const
00159 {
00160     SVGLength w = width();
00161     if (w.unitType() != LengthTypePercentage)
00162         return 0;
00163 
00164     return static_cast<int>(w.valueAsPercentage() * containerSize().width());
00165 }
00166 
00167 int SVGSVGElement::relativeHeightValue() const
00168 {
00169     SVGLength h = height();
00170     if (h.unitType() != LengthTypePercentage)
00171         return 0;
00172 
00173     return static_cast<int>(h.valueAsPercentage() * containerSize().height());
00174 }
00175 
00176 float SVGSVGElement::pixelUnitToMillimeterX() const
00177 {
00178     // 2.54 / cssPixelsPerInch gives CM.
00179     return (2.54f / cssPixelsPerInch) * 10.0f;
00180 }
00181 
00182 float SVGSVGElement::pixelUnitToMillimeterY() const
00183 {
00184     // 2.54 / cssPixelsPerInch gives CM.
00185     return (2.54f / cssPixelsPerInch) * 10.0f;
00186 }
00187 
00188 float SVGSVGElement::screenPixelToMillimeterX() const
00189 {
00190     return pixelUnitToMillimeterX();
00191 }
00192 
00193 float SVGSVGElement::screenPixelToMillimeterY() const
00194 {
00195     return pixelUnitToMillimeterY();
00196 }
00197 
00198 bool SVGSVGElement::useCurrentView() const
00199 {
00200     return m_useCurrentView;
00201 }
00202 
00203 void SVGSVGElement::setUseCurrentView(bool currentView)
00204 {
00205     m_useCurrentView = currentView;
00206 }
00207 
00208 SVGViewSpec* SVGSVGElement::currentView() const
00209 {
00210     if (!m_viewSpec)
00211         m_viewSpec.set(new SVGViewSpec(this));
00212 
00213     return m_viewSpec.get();
00214 }
00215 
00216 float SVGSVGElement::currentScale() const
00217 {
00218     /*if (document() && document()->frame())
00219         return document()->frame()->zoomFactor();*/
00220     return 1.0f;
00221 }
00222 
00223 void SVGSVGElement::setCurrentScale(float scale)
00224 {
00225     /*if (document() && document()->frame())
00226         document()->frame()->setZoomFactor(scale, true);*/
00227 }
00228 
00229 FloatPoint SVGSVGElement::currentTranslate() const
00230 {
00231     return m_translation;
00232 }
00233 
00234 void SVGSVGElement::setCurrentTranslate(const FloatPoint &translation)
00235 {
00236     m_translation = translation;
00237     if (parentNode() == document() && document()->renderer())
00238         document()->renderer()->repaint();
00239 }
00240 
00241 void SVGSVGElement::addSVGWindowEventListener(const AtomicString& eventType, const Attribute* attr)
00242 {
00243     // FIXME: None of these should be window events long term.
00244     // Once we propertly support SVGLoad, etc.
00245     RefPtr<EventListener> listener = document()->accessSVGExtensions()->
00246         createSVGEventListener(attr->localName().string(), attr->value(), this);
00247     //document()->setHTMLWindowEventListener(eventType, listener.release());
00248 }
00249 
00250 void SVGSVGElement::parseMappedAttribute(MappedAttribute* attr)
00251 {
00252     kDebug() << "parse attribute: " << attr->localName() << attr->value() << endl;
00253     if (!nearestViewportElement()) {
00254         // Only handle events if we're the outermost <svg> element
00255         /*if (attr->name() == onunloadAttr)
00256             addSVGWindowEventListener(unloadEvent, attr);
00257         else if (attr->name() == onabortAttr)
00258             addSVGWindowEventListener(abortEvent, attr);
00259         else if (attr->name() == onerrorAttr)
00260             addSVGWindowEventListener(errorEvent, attr);
00261         else if (attr->name() == onresizeAttr)
00262             addSVGWindowEventListener(resizeEvent, attr);
00263         else if (attr->name() == onscrollAttr)
00264             addSVGWindowEventListener(scrollEvent, attr);
00265         else if (attr->name() == SVGNames::onzoomAttr)
00266             addSVGWindowEventListener(zoomEvent, attr);*/
00267     }
00268     if (attr->name() == SVGNames::xAttr)
00269         setXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00270     else if (attr->name() == SVGNames::yAttr)
00271         setYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00272     else if (attr->name() == SVGNames::widthAttr) {
00273         kDebug() << "set width" << attr->value() << endl;
00274         setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00275         addCSSProperty(attr, CSSPropertyWidth, attr->value());
00276         /*if (width().value() < 0.0)
00277             document()->accessSVGExtensions()->reportError("A negative value for svg attribute <width> is not allowed");*/
00278     } else if (attr->name() == SVGNames::heightAttr) {
00279         kDebug() << "set height" << attr->value() << endl;
00280         setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00281         addCSSProperty(attr, CSSPropertyHeight, attr->value());
00282         /*if (height().value() < 0.0)
00283             document()->accessSVGExtensions()->reportError("A negative value for svg attribute <height> is not allowed");*/
00284     } else {
00285         /*if (SVGTests::parseMappedAttribute(attr))
00286             return;
00287         if (SVGLangSpace::parseMappedAttribute(attr))
00288             return;
00289         if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
00290             return;
00291         if (SVGFitToViewBox::parseMappedAttribute(attr))
00292             return;
00293         if (SVGZoomAndPan::parseMappedAttribute(attr))
00294             return;*/
00295 
00296         SVGStyledLocatableElement::parseMappedAttribute(attr);
00297     }
00298 }
00299 
00300 void SVGSVGElement::svgAttributeChanged(const QualifiedName& attrName)
00301 {
00302     SVGStyledElement::svgAttributeChanged(attrName);
00303 
00304     if (!renderer())
00305         return;
00306 
00307     /*if (attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
00308         attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
00309         SVGTests::isKnownAttribute(attrName) ||
00310         SVGLangSpace::isKnownAttribute(attrName) ||
00311         SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
00312         SVGFitToViewBox::isKnownAttribute(attrName) ||
00313         SVGZoomAndPan::isKnownAttribute(attrName) ||
00314         SVGStyledLocatableElement::isKnownAttribute(attrName))
00315         renderer()->setNeedsLayout(true);*/
00316 }
00317 
00318 unsigned long SVGSVGElement::suspendRedraw(unsigned long /* max_wait_milliseconds */)
00319 {
00320     // FIXME: Implement me (see bug 11275)
00321     return 0;
00322 }
00323 
00324 void SVGSVGElement::unsuspendRedraw(unsigned long /* suspend_handle_id */, ExceptionCode& ec)
00325 {
00326     // if suspend_handle_id is not found, throw exception
00327     // FIXME: Implement me (see bug 11275)
00328 }
00329 
00330 void SVGSVGElement::unsuspendRedrawAll()
00331 {
00332     // FIXME: Implement me (see bug 11275)
00333 }
00334 
00335 void SVGSVGElement::forceRedraw()
00336 {
00337     // FIXME: Implement me (see bug 11275)
00338 }
00339 
00340 DOM::NodeListImpl* SVGSVGElement::getIntersectionList(const FloatRect& rect, SVGElement*)
00341 {
00342     // FIXME: Implement me (see bug 11274)
00343     return 0;
00344 }
00345 
00346 DOM::NodeListImpl* SVGSVGElement::getEnclosureList(const FloatRect& rect, SVGElement*)
00347 {
00348     // FIXME: Implement me (see bug 11274)
00349     return 0;
00350 }
00351 
00352 bool SVGSVGElement::checkIntersection(SVGElement* element, const FloatRect& rect)
00353 {
00354     // TODO : take into account pointer-events?
00355     // FIXME: Why is element ignored??
00356     // FIXME: Implement me (see bug 11274)
00357     return rect.intersects(getBBox());
00358 }
00359 
00360 bool SVGSVGElement::checkEnclosure(SVGElement* element, const FloatRect& rect)
00361 {
00362     // TODO : take into account pointer-events?
00363     // FIXME: Why is element ignored??
00364     // FIXME: Implement me (see bug 11274)
00365     return rect.contains(getBBox());
00366 }
00367 
00368 void SVGSVGElement::deselectAll()
00369 {
00370     //document()->frame()->selectionController()->clear();
00371 }
00372 
00373 float SVGSVGElement::createSVGNumber()
00374 {
00375     return 0.0f;
00376 }
00377 
00378 SVGLength SVGSVGElement::createSVGLength()
00379 {
00380     return SVGLength();
00381 }
00382 
00383 SVGAngle* SVGSVGElement::createSVGAngle()
00384 {
00385     return new SVGAngle();
00386 }
00387 
00388 FloatPoint SVGSVGElement::createSVGPoint()
00389 {
00390     return FloatPoint();
00391 }
00392 
00393 AffineTransform SVGSVGElement::createSVGMatrix()
00394 {
00395     return AffineTransform();
00396 }
00397 
00398 FloatRect SVGSVGElement::createSVGRect()
00399 {
00400     return FloatRect();
00401 }
00402 
00403 SVGTransform SVGSVGElement::createSVGTransform()
00404 {
00405     return SVGTransform();
00406 }
00407 
00408 SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const AffineTransform& matrix)
00409 {
00410     return SVGTransform(matrix);
00411 }
00412 
00413 AffineTransform SVGSVGElement::getCTM() const
00414 {
00415     AffineTransform mat;
00416     if (!isOutermostSVG())
00417         mat.translate(x().value(), y().value());
00418 
00419     if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
00420         AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value());
00421         mat = viewBox * mat;
00422     }
00423 
00424     return mat;
00425 }
00426 
00427 AffineTransform SVGSVGElement::getScreenCTM() const
00428 {
00429     /*document()->updateLayoutIgnorePendingStylesheets();
00430     float rootX = 0.0f;
00431     float rootY = 0.0f;
00432     
00433     if (RenderObject* renderer = this->renderer()) {
00434         renderer = renderer->parent();
00435         if (isOutermostSVG()) {
00436             int tx = 0;
00437             int ty = 0;
00438             if (renderer)
00439                 renderer->absolutePosition(tx, ty, true);
00440             rootX += tx;
00441             rootY += ty;
00442         } else {
00443             rootX += x().value();
00444             rootY += y().value();
00445         }
00446     }
00447     
00448     AffineTransform mat = SVGStyledLocatableElement::getScreenCTM();
00449     mat.translate(rootX, rootY);
00450 
00451     if (attributes()->getNamedItem(SVGNames::viewBoxAttr)) {
00452         AffineTransform viewBox = viewBoxToViewTransform(width().value(), height().value());
00453         mat = viewBox * mat;
00454     }
00455 
00456     return mat;*/
00457     ASSERT(false);
00458     return AffineTransform();
00459 }
00460 
00461 RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*)
00462 {
00463     kDebug() << "create RenderSVGRoot from <svg> element" << endl;
00464     return new (arena) RenderSVGRoot(this);
00465     /*if (isOutermostSVG())
00466         return new (arena) RenderSVGRoot(this);
00467     else
00468         return new (arena) RenderSVGViewportContainer(this);*/
00469 }
00470 
00471 void SVGSVGElement::insertedIntoDocument()
00472 {
00473     document()->accessSVGExtensions()->addTimeContainer(this);
00474     SVGStyledLocatableElement::insertedIntoDocument();
00475 }
00476 
00477 void SVGSVGElement::removedFromDocument()
00478 {
00479     document()->accessSVGExtensions()->removeTimeContainer(this);
00480     SVGStyledLocatableElement::removedFromDocument();
00481 }
00482 
00483 void SVGSVGElement::pauseAnimations()
00484 {
00485     /*if (!m_timeContainer->isPaused())
00486         m_timeContainer->pause();*/
00487 }
00488 
00489 void SVGSVGElement::unpauseAnimations()
00490 {
00491     /*if (m_timeContainer->isPaused())
00492         m_timeContainer->resume();*/
00493 }
00494 
00495 bool SVGSVGElement::animationsPaused() const
00496 {
00497     //return m_timeContainer->isPaused();
00498     ASSERT(false);
00499     return false;
00500 }
00501 
00502 float SVGSVGElement::getCurrentTime() const
00503 {
00504     //return narrowPrecisionToFloat(m_timeContainer->elapsed().value());
00505     ASSERT(false);
00506     return 0.0;
00507 }
00508 
00509 void SVGSVGElement::setCurrentTime(float /* seconds */)
00510 {
00511     // FIXME: Implement me, bug 12073
00512 }
00513 
00514 bool SVGSVGElement::hasRelativeValues() const
00515 {
00516     return (x().isRelative() || width().isRelative() ||
00517             y().isRelative() || height().isRelative());
00518 }
00519 
00520 bool SVGSVGElement::isOutermostSVG() const
00521 {
00522     // This is true whenever this is the outermost SVG, even if there are HTML elements outside it
00523     return !parentNode()->isSVGElement();
00524 }
00525 
00526 AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
00527 {
00528     FloatRect viewBoxRect;
00529     if (useCurrentView()) {
00530         if (currentView()) // what if we should use it but it is not set?
00531             viewBoxRect = currentView()->viewBox();
00532     } else
00533         viewBoxRect = viewBox();
00534     if (!viewBoxRect.width() || !viewBoxRect.height())
00535         return AffineTransform();
00536 
00537     AffineTransform ctm = preserveAspectRatio()->getCTM(viewBoxRect.x(),
00538             viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(),
00539             0, 0, viewWidth, viewHeight);
00540 
00541     if (useCurrentView() && currentView())
00542         return currentView()->transform()->concatenate().matrix() * ctm;
00543 
00544     return ctm;
00545 }
00546 
00547 /*void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement)
00548 {
00549     setUseCurrentView(true);
00550     if (viewElement->hasAttribute(SVGNames::viewBoxAttr))
00551         currentView()->setViewBox(viewElement->viewBox());
00552     else
00553         currentView()->setViewBox(viewBox());
00554     if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) {
00555         currentView()->preserveAspectRatio()->setAlign(viewElement->preserveAspectRatio()->align());
00556         currentView()->preserveAspectRatio()->setMeetOrSlice(viewElement->preserveAspectRatio()->meetOrSlice());
00557     } else {
00558         currentView()->preserveAspectRatio()->setAlign(preserveAspectRatio()->align());
00559         currentView()->preserveAspectRatio()->setMeetOrSlice(preserveAspectRatio()->meetOrSlice());
00560     }
00561     if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr))
00562         currentView()->setZoomAndPan(viewElement->zoomAndPan());
00563     renderer()->setNeedsLayout(true);
00564 }*/
00565     
00566 void SVGSVGElement::willSaveToCache()
00567 {
00568     //pauseAnimations();
00569 }
00570 
00571 void SVGSVGElement::willRestoreFromCache()
00572 {
00573     //unpauseAnimations();
00574 }
00575 
00576 // KHTML stuff
00577 quint32 SVGSVGElement::id() const { return SVGNames::svgTag.id(); }
00578 
00579 }
00580 
00581 #endif // ENABLE(SVG)
00582 
00583 // 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
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
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