File indexing completed on 2024-04-28 15:24:32
0001 /* 0002 Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 0003 Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org> 0004 Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> 0005 0006 This file is part of the KDE project 0007 0008 This library is free software; you can redistribute it and/or 0009 modify it under the terms of the GNU Library General Public 0010 License as published by the Free Software Foundation; either 0011 version 2 of the License, or (at your option) any later version. 0012 0013 This library is distributed in the hope that it will be useful, 0014 but WITHOUT ANY WARRANTY; without even the implied warranty of 0015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0016 Library General Public License for more details. 0017 0018 You should have received a copy of the GNU Library General Public License 0019 along with this library; see the file COPYING.LIB. If not, write to 0020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0021 Boston, MA 02110-1301, USA. 0022 */ 0023 0024 #if ENABLE(SVG) && ENABLE(SVG_FILTERS) 0025 #include "SVGFilterElement.h" 0026 0027 #include "Attr.h" 0028 #include "SVGFilterPrimitiveStandardAttributes.h" 0029 #include "SVGLength.h" 0030 #include "SVGNames.h" 0031 #include "SVGUnitTypes.h" 0032 0033 namespace WebCore 0034 { 0035 0036 SVGFilterElement::SVGFilterElement(const QualifiedName &tagName, Document *doc) 0037 : SVGStyledElement(tagName, doc) 0038 , SVGURIReference() 0039 , SVGLangSpace() 0040 , SVGExternalResourcesRequired() 0041 , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) 0042 , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) 0043 , m_x(this, LengthModeWidth) 0044 , m_y(this, LengthModeHeight) 0045 , m_width(this, LengthModeWidth) 0046 , m_height(this, LengthModeHeight) 0047 , m_filterResX(0) 0048 , m_filterResY(0) 0049 { 0050 // Spec: If the attribute is not specified, the effect is as if a value of "-10%" were specified. 0051 setXBaseValue(SVGLength(this, LengthModeWidth, "-10%")); 0052 setYBaseValue(SVGLength(this, LengthModeHeight, "-10%")); 0053 0054 // Spec: If the attribute is not specified, the effect is as if a value of "120%" were specified. 0055 setWidthBaseValue(SVGLength(this, LengthModeWidth, "120%")); 0056 setHeightBaseValue(SVGLength(this, LengthModeHeight, "120%")); 0057 } 0058 0059 SVGFilterElement::~SVGFilterElement() 0060 { 0061 } 0062 0063 ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, int, Enumeration, enumeration, FilterUnits, filterUnits, SVGNames::filterUnitsAttr, m_filterUnits) 0064 ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, int, Enumeration, enumeration, PrimitiveUnits, primitiveUnits, SVGNames::primitiveUnitsAttr, m_primitiveUnits) 0065 ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, X, x, SVGNames::xAttr, m_x) 0066 ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, Y, y, SVGNames::yAttr, m_y) 0067 ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, Width, width, SVGNames::widthAttr, m_width) 0068 ANIMATED_PROPERTY_DEFINITIONS(SVGFilterElement, SVGLength, Length, length, Height, height, SVGNames::heightAttr, m_height) 0069 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGFilterElement, long, Integer, integer, FilterResX, filterResX, SVGNames::filterResAttr, "filterResX", m_filterResX) 0070 ANIMATED_PROPERTY_DEFINITIONS_WITH_CUSTOM_IDENTIFIER(SVGFilterElement, long, Integer, integer, FilterResY, filterResY, SVGNames::filterResAttr, "filterResY", m_filterResY) 0071 0072 void SVGFilterElement::setFilterRes(unsigned long, unsigned long) const 0073 { 0074 } 0075 0076 void SVGFilterElement::parseMappedAttribute(MappedAttribute *attr) 0077 { 0078 const String &value = attr->value(); 0079 if (attr->name() == SVGNames::filterUnitsAttr) { 0080 if (value == "userSpaceOnUse") { 0081 setFilterUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE); 0082 } else if (value == "objectBoundingBox") { 0083 setFilterUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); 0084 } 0085 } else if (attr->name() == SVGNames::primitiveUnitsAttr) { 0086 if (value == "userSpaceOnUse") { 0087 setPrimitiveUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE); 0088 } else if (value == "objectBoundingBox") { 0089 setPrimitiveUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); 0090 } 0091 } else if (attr->name() == SVGNames::xAttr) { 0092 setXBaseValue(SVGLength(this, LengthModeWidth, value)); 0093 } else if (attr->name() == SVGNames::yAttr) { 0094 setYBaseValue(SVGLength(this, LengthModeHeight, value)); 0095 } else if (attr->name() == SVGNames::widthAttr) { 0096 setWidthBaseValue(SVGLength(this, LengthModeWidth, value)); 0097 } else if (attr->name() == SVGNames::heightAttr) { 0098 setHeightBaseValue(SVGLength(this, LengthModeHeight, value)); 0099 } else { 0100 if (SVGURIReference::parseMappedAttribute(attr)) { 0101 return; 0102 } 0103 if (SVGLangSpace::parseMappedAttribute(attr)) { 0104 return; 0105 } 0106 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) { 0107 return; 0108 } 0109 0110 SVGStyledElement::parseMappedAttribute(attr); 0111 } 0112 } 0113 0114 SVGResource *SVGFilterElement::canvasResource() 0115 { 0116 if (!attached()) { 0117 return 0; 0118 } 0119 0120 if (!m_filter) { 0121 m_filter = new SVGResourceFilter(); 0122 } 0123 0124 bool filterBBoxMode = filterUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 0125 m_filter->setFilterBoundingBoxMode(filterBBoxMode); 0126 0127 float _x, _y, _width, _height; 0128 0129 if (filterBBoxMode) { 0130 _x = x().valueAsPercentage(); 0131 _y = y().valueAsPercentage(); 0132 _width = width().valueAsPercentage(); 0133 _height = height().valueAsPercentage(); 0134 } else { 0135 m_filter->setXBoundingBoxMode(x().unitType() == LengthTypePercentage); 0136 m_filter->setYBoundingBoxMode(y().unitType() == LengthTypePercentage); 0137 0138 _x = x().value(); 0139 _y = y().value(); 0140 _width = width().value(); 0141 _height = height().value(); 0142 } 0143 0144 m_filter->setFilterRect(FloatRect(_x, _y, _width, _height)); 0145 0146 bool primitiveBBoxMode = primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 0147 m_filter->setEffectBoundingBoxMode(primitiveBBoxMode); 0148 0149 // TODO : use switch/case instead? 0150 m_filter->clearEffects(); 0151 for (Node *n = firstChild(); n != 0; n = n->nextSibling()) { 0152 SVGElement *element = 0; 0153 if (n->isSVGElement()) { 0154 element = static_cast<SVGElement *>(n); 0155 } 0156 if (element && element->isFilterEffect()) { 0157 SVGFilterPrimitiveStandardAttributes *filterAttributes = static_cast<SVGFilterPrimitiveStandardAttributes *>(element); 0158 SVGFilterEffect *filterEffect = filterAttributes->filterEffect(m_filter.get()); 0159 if (!filterEffect) { 0160 continue; 0161 } 0162 0163 m_filter->addFilterEffect(filterEffect); 0164 } 0165 } 0166 0167 return m_filter.get(); 0168 } 0169 0170 } 0171 0172 #endif // ENABLE(SVG) 0173