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

KHTML

SVGMaskElement.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                   2005 Alexander Kellett <lypanov@kde.org>
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 
00026 #if ENABLE(SVG)
00027 #include "SVGMaskElement.h"
00028 
00029 #include "CSSStyleSelector.h"
00030 #include "GraphicsContext.h"
00031 #include "ImageBuffer.h"
00032 #include "RenderSVGContainer.h"
00033 #include "SVGLength.h"
00034 #include "SVGNames.h"
00035 #include "SVGRenderSupport.h"
00036 #include "SVGUnitTypes.h"
00037 #include <math.h>
00038 #include <wtf/MathExtras.h>
00039 #include <wtf/OwnPtr.h>
00040 
00041 using namespace std;
00042 
00043 namespace WebCore {
00044 
00045 SVGMaskElement::SVGMaskElement(const QualifiedName& tagName, Document* doc)
00046     : SVGStyledLocatableElement(tagName, doc)
00047     , SVGURIReference()
00048     , SVGTests()
00049     , SVGLangSpace()
00050     , SVGExternalResourcesRequired()
00051     , m_maskUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
00052     , m_maskContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
00053     , m_x(this, LengthModeWidth)
00054     , m_y(this, LengthModeHeight)
00055     , m_width(this, LengthModeWidth)
00056     , m_height(this, LengthModeHeight)
00057 {
00058     // Spec: If the attribute is not specified, the effect is as if a value of "-10%" were specified.
00059     setXBaseValue(SVGLength(this, LengthModeWidth, "-10%"));
00060     setYBaseValue(SVGLength(this, LengthModeHeight, "-10%"));
00061   
00062     // Spec: If the attribute is not specified, the effect is as if a value of "120%" were specified.
00063     setWidthBaseValue(SVGLength(this, LengthModeWidth, "120%"));
00064     setHeightBaseValue(SVGLength(this, LengthModeHeight, "120%"));
00065 }
00066 
00067 SVGMaskElement::~SVGMaskElement()
00068 {
00069 }
00070 
00071 ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, int, Enumeration, enumeration, MaskUnits, maskUnits, SVGNames::maskUnitsAttr, m_maskUnits)
00072 ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, int, Enumeration, enumeration, MaskContentUnits, maskContentUnits, SVGNames::maskContentUnitsAttr, m_maskContentUnits)
00073 ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x)
00074 ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y)
00075 ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width)
00076 ANIMATED_PROPERTY_DEFINITIONS(SVGMaskElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height)
00077 
00078 void SVGMaskElement::parseMappedAttribute(MappedAttribute* attr)
00079 {
00080     if (attr->name() == SVGNames::maskUnitsAttr) {
00081         if (attr->value() == "userSpaceOnUse")
00082             setMaskUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE);
00083         else if (attr->value() == "objectBoundingBox")
00084             setMaskUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX);
00085     } else if (attr->name() == SVGNames::maskContentUnitsAttr) {
00086         if (attr->value() == "userSpaceOnUse")
00087             setMaskContentUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE);
00088         else if (attr->value() == "objectBoundingBox")
00089             setMaskContentUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX);
00090     } else if (attr->name() == SVGNames::xAttr)
00091         setXBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00092     else if (attr->name() == SVGNames::yAttr)
00093         setYBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00094     else if (attr->name() == SVGNames::widthAttr)
00095         setWidthBaseValue(SVGLength(this, LengthModeWidth, attr->value()));
00096     else if (attr->name() == SVGNames::heightAttr)
00097         setHeightBaseValue(SVGLength(this, LengthModeHeight, attr->value()));
00098     else {
00099         if (SVGURIReference::parseMappedAttribute(attr))
00100             return;
00101         if (SVGTests::parseMappedAttribute(attr))
00102             return;
00103         if (SVGLangSpace::parseMappedAttribute(attr))
00104             return;
00105         if (SVGExternalResourcesRequired::parseMappedAttribute(attr))
00106             return;
00107         SVGStyledElement::parseMappedAttribute(attr);
00108     }
00109 }
00110 
00111 void SVGMaskElement::svgAttributeChanged(const QualifiedName& attrName)
00112 {
00113     SVGStyledElement::svgAttributeChanged(attrName);
00114 
00115     if (!m_masker)
00116         return;
00117 
00118     if (attrName == SVGNames::maskUnitsAttr || attrName == SVGNames::maskContentUnitsAttr ||
00119         attrName == SVGNames::xAttr || attrName == SVGNames::yAttr ||
00120         attrName == SVGNames::widthAttr || attrName == SVGNames::heightAttr ||
00121         SVGURIReference::isKnownAttribute(attrName) ||
00122         SVGTests::isKnownAttribute(attrName) ||
00123         SVGLangSpace::isKnownAttribute(attrName) ||
00124         SVGExternalResourcesRequired::isKnownAttribute(attrName) ||
00125         SVGStyledElement::isKnownAttribute(attrName))
00126         m_masker->invalidate();
00127 }
00128 
00129 void SVGMaskElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
00130 {
00131     SVGStyledElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
00132 
00133     if (!m_masker)
00134         return;
00135 
00136     m_masker->invalidate();
00137 }
00138 
00139 auto_ptr<ImageBuffer> SVGMaskElement::drawMaskerContent(const FloatRect& targetRect, FloatRect& maskDestRect) const
00140 {    
00141     // Determine specified mask size
00142     float xValue;
00143     float yValue;
00144     float widthValue;
00145     float heightValue;
00146 
00147     if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
00148         xValue = x().valueAsPercentage() * targetRect.width();
00149         yValue = y().valueAsPercentage() * targetRect.height();
00150         widthValue = width().valueAsPercentage() * targetRect.width();
00151         heightValue = height().valueAsPercentage() * targetRect.height();
00152     } else {
00153         xValue = x().value();
00154         yValue = y().value();
00155         widthValue = width().value();
00156         heightValue = height().value();
00157     } 
00158 
00159     IntSize imageSize(lroundf(widthValue), lroundf(heightValue));
00160     clampImageBufferSizeToViewport(document()->renderer(), imageSize);
00161 
00162     if (imageSize.width() < static_cast<int>(widthValue))
00163         widthValue = imageSize.width();
00164 
00165     if (imageSize.height() < static_cast<int>(heightValue))
00166         heightValue = imageSize.height();
00167 
00168     auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(imageSize, false);
00169     if (!maskImage.get())
00170         return maskImage;
00171 
00172     maskDestRect = FloatRect(xValue, yValue, widthValue, heightValue);
00173     if (maskUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
00174         maskDestRect.move(targetRect.x(), targetRect.y());
00175 
00176     GraphicsContext* maskImageContext = maskImage->context();
00177     ASSERT(maskImageContext);
00178 
00179     maskImageContext->save();
00180     maskImageContext->translate(-xValue, -yValue);
00181 
00182     if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
00183         maskImageContext->save();
00184         maskImageContext->scale(FloatSize(targetRect.width(), targetRect.height()));
00185     }
00186 
00187     // Render subtree into ImageBuffer
00188     for (Node* n = firstChild(); n; n = n->nextSibling()) {
00189         SVGElement* elem = 0;
00190         if (n->isSVGElement())
00191             elem = static_cast<SVGElement*>(n);
00192         if (!elem || !elem->isStyled())
00193             continue;
00194 
00195         SVGStyledElement* e = static_cast<SVGStyledElement*>(elem);
00196         RenderObject* item = e->renderer();
00197         if (!item)
00198             continue;
00199 
00200         renderSubtreeToImage(maskImage.get(), item);
00201     }
00202 
00203     if (maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
00204         maskImageContext->restore();
00205 
00206     maskImageContext->restore();
00207     return maskImage;
00208 }
00209  
00210 RenderObject* SVGMaskElement::createRenderer(RenderArena* arena, RenderStyle*)
00211 {
00212     RenderSVGContainer* maskContainer = new (arena) RenderSVGContainer(this);
00213     maskContainer->setDrawsContents(false);
00214     return maskContainer;
00215 }
00216 
00217 SVGResource* SVGMaskElement::canvasResource()
00218 {
00219     if (!m_masker)
00220         m_masker = SVGResourceMasker::create(this);
00221     return m_masker.get();
00222 }
00223 
00224 }
00225 
00226 #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