• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KHTML

SVGStyledElement.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
00003                   2004, 2005, 2007 Rob Buis <buis@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "config.h"
00022 #include "wtf/Platform.h"
00023 
00024 #if ENABLE(SVG)
00025 #include "SVGStyledElement.h"
00026 
00027 /*#include "Attr.h"
00028 #include "CSSParser.h"
00029 #include "CSSStyleSelector.h"
00030 #include "CString.h"*/
00031 #include "cssstyleselector.h"
00032 #include "Document.h"
00033 /*#include "HTMLNames.h"*/
00034 #include "PlatformString.h"
00035 #include "SVGElement.h"
00036 /*#include "SVGElementInstance.h"*/
00037 #include "SVGNames.h"
00038 #include "RenderObject.h"
00039 #include "SVGRenderStyle.h"
00040 /*#include "SVGResource.h"*/
00041 #include "SVGSVGElement.h"
00042 #include <wtf/Assertions.h>
00043 
00044 // khtml
00045 #include "css_base.h"
00046 
00047 
00048 namespace WebCore {
00049 
00050 using namespace SVGNames;
00051 using namespace DOM;
00052 
00053 static HashSet<const SVGStyledElement*>* gElementsWithInstanceUpdatesBlocked = 0;
00054 
00055 SVGStyledElement::SVGStyledElement(const QualifiedName& tagName, Document* doc)
00056     : SVGElement(tagName, doc)
00057 {
00058 }
00059 
00060 SVGStyledElement::~SVGStyledElement()
00061 {
00062 //    SVGResource::removeClient(this);
00063 }
00064 
00065 ANIMATED_PROPERTY_DEFINITIONS(SVGStyledElement, String, String, string, ClassName, className, HTMLNames::classAttr, m_className)
00066 
00067 bool SVGStyledElement::rendererIsNeeded(RenderStyle* style)
00068 {
00069     // http://www.w3.org/TR/SVG/extend.html#PrivateData
00070     // Prevent anything other than SVG renderers from appearing in our render tree
00071     // Spec: SVG allows inclusion of elements from foreign namespaces anywhere
00072     // with the SVG content. In general, the SVG user agent will include the unknown
00073     // elements in the DOM but will otherwise ignore unknown elements. 
00074     if (!parentNode() || parentNode()->isSVGElement())
00075         return StyledElement::rendererIsNeeded(style);
00076 
00077     return false;
00078 }
00079 
00080 static void mapAttributeToCSSProperty(HashMap<DOMStringImpl*, int>* propertyNameToIdMap, const QualifiedName& attrName)
00081 {
00082     /*int propertyId = cssPropertyID(attrName.localName());*/
00083     QString propName = attrName.localName().string();
00084     int propertyId = DOM::getPropertyID(propName.toLatin1(), propName.length());
00085     ASSERT(propertyId > 0);
00086     propertyNameToIdMap->set(attrName.localName().implementation(), propertyId);
00087 }
00088 
00089 int SVGStyledElement::cssPropertyIdForSVGAttributeName(const QualifiedName& attrName)
00090 {
00091     if (!attrName.namespaceURI().isEmpty()/*khtml fix, was isNull()*/)
00092         return 0;
00093 
00094     // ### I think this is better redone as a switch.
00095     static HashMap<DOMStringImpl*, int>* propertyNameToIdMap = 0;
00096     if (!propertyNameToIdMap) {
00097         propertyNameToIdMap = new HashMap<DOMStringImpl*, int>;
00098         // This is a list of all base CSS and SVG CSS properties which are exposed as SVG XML attributes
00099         mapAttributeToCSSProperty(propertyNameToIdMap, alignment_baselineAttr);
00100         mapAttributeToCSSProperty(propertyNameToIdMap, baseline_shiftAttr);
00101         mapAttributeToCSSProperty(propertyNameToIdMap, clipAttr);
00102         mapAttributeToCSSProperty(propertyNameToIdMap, clip_pathAttr);
00103         mapAttributeToCSSProperty(propertyNameToIdMap, clip_ruleAttr);
00104         mapAttributeToCSSProperty(propertyNameToIdMap, colorAttr);
00105         mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolationAttr);
00106         mapAttributeToCSSProperty(propertyNameToIdMap, color_interpolation_filtersAttr);
00107         mapAttributeToCSSProperty(propertyNameToIdMap, color_profileAttr);
00108         mapAttributeToCSSProperty(propertyNameToIdMap, color_renderingAttr); 
00109         mapAttributeToCSSProperty(propertyNameToIdMap, cursorAttr);
00110         mapAttributeToCSSProperty(propertyNameToIdMap, directionAttr);
00111         mapAttributeToCSSProperty(propertyNameToIdMap, displayAttr);
00112         mapAttributeToCSSProperty(propertyNameToIdMap, dominant_baselineAttr);
00113         mapAttributeToCSSProperty(propertyNameToIdMap, enable_backgroundAttr);
00114         mapAttributeToCSSProperty(propertyNameToIdMap, fillAttr);
00115         mapAttributeToCSSProperty(propertyNameToIdMap, fill_opacityAttr);
00116         mapAttributeToCSSProperty(propertyNameToIdMap, fill_ruleAttr);
00117         mapAttributeToCSSProperty(propertyNameToIdMap, filterAttr);
00118         mapAttributeToCSSProperty(propertyNameToIdMap, flood_colorAttr);
00119         mapAttributeToCSSProperty(propertyNameToIdMap, flood_opacityAttr);
00120         mapAttributeToCSSProperty(propertyNameToIdMap, font_familyAttr);
00121         mapAttributeToCSSProperty(propertyNameToIdMap, font_sizeAttr);
00122         mapAttributeToCSSProperty(propertyNameToIdMap, font_stretchAttr);
00123         mapAttributeToCSSProperty(propertyNameToIdMap, font_styleAttr);
00124         mapAttributeToCSSProperty(propertyNameToIdMap, font_variantAttr);
00125         mapAttributeToCSSProperty(propertyNameToIdMap, font_weightAttr);
00126         mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_horizontalAttr);
00127         mapAttributeToCSSProperty(propertyNameToIdMap, glyph_orientation_verticalAttr);
00128         mapAttributeToCSSProperty(propertyNameToIdMap, image_renderingAttr);
00129         mapAttributeToCSSProperty(propertyNameToIdMap, kerningAttr);
00130         mapAttributeToCSSProperty(propertyNameToIdMap, letter_spacingAttr);
00131         mapAttributeToCSSProperty(propertyNameToIdMap, lighting_colorAttr);
00132         mapAttributeToCSSProperty(propertyNameToIdMap, marker_endAttr);
00133         mapAttributeToCSSProperty(propertyNameToIdMap, marker_midAttr);
00134         mapAttributeToCSSProperty(propertyNameToIdMap, marker_startAttr);
00135         mapAttributeToCSSProperty(propertyNameToIdMap, maskAttr);
00136         mapAttributeToCSSProperty(propertyNameToIdMap, opacityAttr);
00137         mapAttributeToCSSProperty(propertyNameToIdMap, overflowAttr);
00138         mapAttributeToCSSProperty(propertyNameToIdMap, pointer_eventsAttr);
00139         mapAttributeToCSSProperty(propertyNameToIdMap, shape_renderingAttr);
00140         mapAttributeToCSSProperty(propertyNameToIdMap, stop_colorAttr);
00141         mapAttributeToCSSProperty(propertyNameToIdMap, stop_opacityAttr);
00142         mapAttributeToCSSProperty(propertyNameToIdMap, strokeAttr);
00143         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dasharrayAttr);
00144         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_dashoffsetAttr);
00145         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linecapAttr);
00146         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_linejoinAttr);
00147         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_miterlimitAttr);
00148         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_opacityAttr);
00149         mapAttributeToCSSProperty(propertyNameToIdMap, stroke_widthAttr);
00150         mapAttributeToCSSProperty(propertyNameToIdMap, text_anchorAttr);
00151         mapAttributeToCSSProperty(propertyNameToIdMap, text_decorationAttr);
00152         mapAttributeToCSSProperty(propertyNameToIdMap, text_renderingAttr);
00153         mapAttributeToCSSProperty(propertyNameToIdMap, unicode_bidiAttr);
00154         mapAttributeToCSSProperty(propertyNameToIdMap, visibilityAttr);
00155         mapAttributeToCSSProperty(propertyNameToIdMap, word_spacingAttr);
00156         mapAttributeToCSSProperty(propertyNameToIdMap, writing_modeAttr);
00157     }
00158     return propertyNameToIdMap->get(attrName.localName().implementation());
00159 }
00160 
00161 /*bool SVGStyledElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
00162 {
00163     if (SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName) > 0) {
00164         result = eSVG;
00165         return false;
00166     }
00167     return SVGElement::mapToEntry(attrName, result);
00168 }*/
00169 
00170 void SVGStyledElement::parseMappedAttribute(MappedAttribute* attr)
00171 {
00172     // NOTE: Any subclass which overrides parseMappedAttribute for a property handled by
00173     // cssPropertyIdForSVGAttributeName will also have to override mapToEntry to disable the default eSVG mapping
00174     int id = attr->id();
00175     if (id == ATTR_STYLE) {
00176         if (inlineStyleDecls()) {
00177             inlineStyleDecls()->clear();
00178         } else {
00179             createInlineDecl();
00180         }
00181         inlineStyleDecls()->setProperty(attr->value());
00182         setChanged();
00183         return;
00184     }
00185     int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name());
00186     if (propId > 0) {
00187         addCSSProperty(attr, propId, attr->value());
00188         setChanged();
00189         return;
00190     }
00191     
00192     // id and class are handled by StyledElement
00193     SVGElement::parseMappedAttribute(attr);
00194 }
00195 
00196 bool SVGStyledElement::isKnownAttribute(const QualifiedName& attrName)
00197 {
00198     // Recognize all style related SVG CSS properties
00199     int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attrName);
00200     if (propId > 0)
00201         return true;
00202     return (attrName.id() == ATTR_ID || attrName.id() == ATTR_STYLE);
00203     /*return (attrName == HTMLNames::idAttr || attrName == HTMLNames::styleAttr); */
00204 }
00205 
00206 void SVGStyledElement::svgAttributeChanged(const QualifiedName& attrName)
00207 {
00208     SVGElement::svgAttributeChanged(attrName);
00209 
00210     // If we're the child of a resource element, be sure to invalidate it.
00211     invalidateResourcesInAncestorChain();
00212 
00213     SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
00214     if (!extensions)
00215         return;
00216 
00217     // TODO: Fix bug http://bugs.webkit.org/show_bug.cgi?id=15430 (SVGElementInstances should rebuild themselves lazily)
00218 
00219     // In case we're referenced by a <use> element, we have element instances registered
00220     // to us in the SVGDocumentExtensions. If notifyAttributeChange() is called, we need
00221     // to recursively update all children including ourselves.
00222     updateElementInstance(extensions);
00223 }
00224 
00225 void SVGStyledElement::invalidateResourcesInAncestorChain() const
00226 {
00227     Node* node = parentNode();
00228     while (node) {
00229         if (!node->isSVGElement())
00230             break;
00231 
00232         SVGElement* element = static_cast<SVGElement*>(node);
00233         if (SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element->isStyled() ? element : 0)) {
00234             /*if (SVGResource* resource = styledElement->canvasResource())
00235                 resource->invalidate();*/
00236         }
00237 
00238         node = node->parentNode();
00239     }
00240 }
00241 
00242 void SVGStyledElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
00243 {
00244     Q_UNUSED(changedByParser);
00245     Q_UNUSED(beforeChange);
00246     Q_UNUSED(afterChange);
00247     Q_UNUSED(childCountDelta);
00248     SVGElement::childrenChanged();
00249     /*SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
00250     if (document()->parsing())
00251         return;
00252 
00253     SVGDocumentExtensions* extensions = document()->accessSVGExtensions();
00254     if (!extensions)
00255         return;
00256 
00257     // TODO: Fix bug http://bugs.webkit.org/show_bug.cgi?id=15430 (SVGElementInstances should rebuild themselves lazily)
00258 
00259     // In case we're referenced by a <use> element, we have element instances registered
00260     // to us in the SVGDocumentExtensions. If childrenChanged() is called, we need
00261     // to recursively update all children including ourselves.
00262     updateElementInstance(extensions);*/
00263 }
00264 
00265 void SVGStyledElement::updateElementInstance(SVGDocumentExtensions* extensions) const
00266 {
00267     Q_UNUSED(extensions);
00268     /*if (gElementsWithInstanceUpdatesBlocked && gElementsWithInstanceUpdatesBlocked->contains(this))
00269         return;
00270 
00271     SVGStyledElement* nonConstThis = const_cast<SVGStyledElement*>(this);
00272     HashSet<SVGElementInstance*>* set = extensions->instancesForElement(nonConstThis);
00273     if (!set || set->isEmpty())
00274         return;
00275 
00276     // We need to be careful here, as the instancesForElement
00277     // hash set may be modified after we call updateInstance! 
00278     HashSet<SVGElementInstance*> localCopy;
00279 
00280     // First create a local copy of the hashset
00281     HashSet<SVGElementInstance*>::const_iterator it1 = set->begin();
00282     const HashSet<SVGElementInstance*>::const_iterator end1 = set->end();
00283 
00284     for (; it1 != end1; ++it1)
00285         localCopy.add(*it1);
00286 
00287     // Actually nofify instances to update
00288     HashSet<SVGElementInstance*>::const_iterator it2 = localCopy.begin();
00289     const HashSet<SVGElementInstance*>::const_iterator end2 = localCopy.end();
00290 
00291     for (; it2 != end2; ++it2)
00292         (*it2)->updateInstance(nonConstThis);*/
00293 }
00294 
00295 RenderStyle* SVGStyledElement::resolveStyle(RenderStyle* parentStyle)
00296 {
00297     Q_UNUSED(parentStyle);
00298     if (renderer()) {
00299         RenderStyle* renderStyle = renderer()->style();
00300         renderStyle->ref();
00301         return renderStyle;
00302     }
00303 
00304     return document()->styleSelector()->styleForElement(this/*, parentStyle*/);
00305 }
00306 
00307 PassRefPtr<DOM::CSSValueImpl> SVGStyledElement::getPresentationAttribute(const String& name)
00308 {
00309     Q_UNUSED(name);
00310     /*MappedAttribute* cssSVGAttr = mappedAttributes()->getAttributeItem(name);
00311     if (!cssSVGAttr || !cssSVGAttr->style())
00312         return 0;
00313     return cssSVGAttr->style()->getPropertyCSSValue(name);*/
00314     Q_ASSERT(false);
00315     return new CSSPrimitiveValueImpl(0);
00316 }
00317 
00318 void SVGStyledElement::detach()
00319 {
00320     /*SVGResource::removeClient(this);*/
00321     SVGElement::detach();
00322 }
00323 
00324 void SVGStyledElement::setInstanceUpdatesBlocked(bool blockUpdates)
00325 {
00326     if (blockUpdates) {
00327         if (!gElementsWithInstanceUpdatesBlocked)
00328             gElementsWithInstanceUpdatesBlocked = new HashSet<const SVGStyledElement*>;
00329         gElementsWithInstanceUpdatesBlocked->add(this);
00330     } else {
00331         ASSERT(gElementsWithInstanceUpdatesBlocked);
00332         ASSERT(gElementsWithInstanceUpdatesBlocked->contains(this));
00333         gElementsWithInstanceUpdatesBlocked->remove(this);
00334     }
00335 }
00336 
00337 }
00338 
00339 #endif // ENABLE(SVG)

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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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