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

KHTML

SVGLinearGradientElement.cpp

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
00003                   2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
00004 
00005     This file is part of the KDE project
00006 
00007     This library is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU Library General Public
00009     License as published by the Free Software Foundation; either
00010     version 2 of the License, or (at your option) any later version.
00011 
00012     This library is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     Library General Public License for more details.
00016 
00017     You should have received a copy of the GNU Library General Public License
00018     along with this library; see the file COPYING.LIB.  If not, write to
00019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020     Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "config.h"
00024 #include "wtf/Platform.h"
00025 
00026 #if ENABLE(SVG)
00027 #include "SVGLinearGradientElement.h"
00028 
00029 #include "FloatPoint.h"
00030 #include "LinearGradientAttributes.h"
00031 #include "SVGLength.h"
00032 #include "SVGNames.h"
00033 #include "SVGPaintServerLinearGradient.h"
00034 #include "SVGTransform.h"
00035 #include "SVGTransformList.h"
00036 #include "SVGUnitTypes.h"
00037 
00038 namespace WebCore {
00039 
00040 SVGLinearGradientElement::SVGLinearGradientElement(const QualifiedName& tagName, Document* doc)
00041     : SVGGradientElement(tagName, doc)
00042     , m_x1(this, LengthModeWidth)
00043     , m_y1(this, LengthModeHeight)
00044     , m_x2(this, LengthModeWidth)
00045     , m_y2(this, LengthModeHeight)
00046 {
00047     // Spec: If the attribute is not specified, the effect is as if a value of "100%" were specified.
00048     setX2BaseValue(SVGLength(this, LengthModeWidth, "100%"));
00049 }
00050 
00051 SVGLinearGradientElement::~SVGLinearGradientElement()
00052 {
00053 }
00054 
00055 ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, X1, x1, SVGNames::x1Attr, m_x1)
00056 ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, Y1, y1, SVGNames::y1Attr, m_y1)
00057 ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, X2, x2, SVGNames::x2Attr, m_x2)
00058 ANIMATED_PROPERTY_DEFINITIONS(SVGLinearGradientElement, SVGLength, Length, length, Y2, y2, SVGNames::y2Attr, m_y2)
00059 
00060 void SVGLinearGradientElement::parseMappedAttribute(MappedAttribute* attr)
00061 {
00062     if (attr->name() == SVGNames::x1Attr)
00063         setX1BaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00064     else if (attr->name() == SVGNames::y1Attr)
00065         setY1BaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00066     else if (attr->name() == SVGNames::x2Attr)
00067         setX2BaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00068     else if (attr->name() == SVGNames::y2Attr)
00069         setY2BaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00070     else
00071         SVGGradientElement::parseMappedAttribute(attr);
00072 }
00073 
00074 void SVGLinearGradientElement::svgAttributeChanged(const QualifiedName& attrName)
00075 {
00076     SVGGradientElement::svgAttributeChanged(attrName);
00077 
00078     if (!m_resource)
00079         return;
00080 
00081     if (attrName == SVGNames::x1Attr || attrName == SVGNames::y1Attr ||
00082         attrName == SVGNames::x2Attr || attrName == SVGNames::y2Attr)
00083         m_resource->invalidate();
00084 }
00085 
00086 void SVGLinearGradientElement::buildGradient() const
00087 {
00088     LinearGradientAttributes attributes = collectGradientProperties();
00089 
00090     // If we didn't find any gradient containing stop elements, ignore the request.
00091     if (attributes.stops().isEmpty())
00092         return;
00093 
00094     RefPtr<SVGPaintServerLinearGradient> linearGradient = WTF::static_pointer_cast<SVGPaintServerLinearGradient>(m_resource);
00095 
00096     linearGradient->setGradientStops(attributes.stops());
00097     linearGradient->setBoundingBoxMode(attributes.boundingBoxMode());
00098     linearGradient->setGradientSpreadMethod(attributes.spreadMethod());
00099     linearGradient->setGradientTransform(attributes.gradientTransform());
00100     linearGradient->setGradientStart(FloatPoint::narrowPrecision(attributes.x1(), attributes.y1()));
00101     linearGradient->setGradientEnd(FloatPoint::narrowPrecision(attributes.x2(), attributes.y2()));
00102 }
00103 
00104 LinearGradientAttributes SVGLinearGradientElement::collectGradientProperties() const
00105 {
00106     LinearGradientAttributes attributes;
00107     HashSet<const SVGGradientElement*> processedGradients;
00108 
00109     bool isLinear = true;
00110     const SVGGradientElement* current = this;
00111 
00112     while (current) {
00113         if (!attributes.hasSpreadMethod() && current->hasAttribute(SVGNames::spreadMethodAttr))
00114             attributes.setSpreadMethod((SVGGradientSpreadMethod) current->spreadMethod());
00115 
00116         if (!attributes.hasBoundingBoxMode() && current->hasAttribute(SVGNames::gradientUnitsAttr))
00117             attributes.setBoundingBoxMode(current->getAttribute(SVGNames::gradientUnitsAttr) == "objectBoundingBox");
00118 
00119         if (!attributes.hasGradientTransform() && current->hasAttribute(SVGNames::gradientTransformAttr))
00120             attributes.setGradientTransform(current->gradientTransform()->consolidate().matrix());
00121 
00122         if (!attributes.hasStops()) {
00123             const Vector<SVGGradientStop>& stops(current->buildStops());
00124             kDebug() << "stops.isEmpty()" << stops.isEmpty() << endl;
00125             if (!stops.isEmpty())
00126                 attributes.setStops(stops);
00127         }
00128 
00129         if (isLinear) {
00130             const SVGLinearGradientElement* linear = static_cast<const SVGLinearGradientElement*>(current);
00131 
00132             if (!attributes.hasX1() && current->hasAttribute(SVGNames::x1Attr))
00133                 attributes.setX1(linear->x1().valueAsPercentage());
00134 
00135             if (!attributes.hasY1() && current->hasAttribute(SVGNames::y1Attr))
00136                 attributes.setY1(linear->y1().valueAsPercentage());
00137 
00138             if (!attributes.hasX2() && current->hasAttribute(SVGNames::x2Attr))
00139                 attributes.setX2(linear->x2().valueAsPercentage());
00140 
00141             if (!attributes.hasY2() && current->hasAttribute(SVGNames::y2Attr))
00142                 attributes.setY2(linear->y2().valueAsPercentage());
00143         }
00144 
00145         processedGradients.add(current);
00146 
00147         // Respect xlink:href, take attributes from referenced element
00148         Node* refNode = ownerDocument()->getElementById(SVGURIReference::getTarget(current->href()));
00149         if (refNode && (refNode->hasTagName(SVGNames::linearGradientTag) || refNode->hasTagName(SVGNames::radialGradientTag))) {
00150             current = static_cast<const SVGGradientElement*>(const_cast<const Node*>(refNode));
00151             int ec;
00152             kDebug() << "take attributes from" << current->getAttributeNS("", "id", ec) << endl;
00153 
00154             // Cycle detection
00155             if (processedGradients.contains(current))
00156                 return LinearGradientAttributes();
00157 
00158             isLinear = current->gradientType() == LinearGradientPaintServer;
00159         } else
00160             current = 0;
00161     }
00162 
00163     return attributes;
00164 }
00165 
00166 // KHTML ElementImpl pure virtual method
00167 quint32 SVGLinearGradientElement::id() const
00168 {
00169     return SVGNames::linearGradientTag.id();
00170 }
00171 
00172 DOMString SVGLinearGradientElement::tagName() const
00173 {
00174     return SVGNames::linearGradientTag.tagName();
00175 }
00176 
00177 }
00178 
00179 #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
  • 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