File indexing completed on 2024-04-28 15:24:28
0001 /* 0002 Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org> 0003 2004, 2005, 2006, 2007, 2008 Rob Buis <buis@kde.org> 0004 0005 This file is part of the KDE project 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include "wtf/Platform.h" 0024 0025 #if ENABLE(SVG) 0026 #include "SVGClipPathElement.h" 0027 0028 #include "css/cssstyleselector.h" 0029 #include "Document.h" 0030 #include "SVGNames.h" 0031 #include "SVGTransformList.h" 0032 #include "SVGUnitTypes.h" 0033 0034 namespace WebCore 0035 { 0036 0037 SVGClipPathElement::SVGClipPathElement(const QualifiedName &tagName, Document *doc) 0038 : SVGStyledTransformableElement(tagName, doc) 0039 , SVGTests() 0040 , SVGLangSpace() 0041 , SVGExternalResourcesRequired() 0042 , m_clipPathUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) 0043 { 0044 } 0045 0046 SVGClipPathElement::~SVGClipPathElement() 0047 { 0048 } 0049 0050 ANIMATED_PROPERTY_DEFINITIONS(SVGClipPathElement, int, Enumeration, enumeration, ClipPathUnits, clipPathUnits, SVGNames::clipPathUnitsAttr, m_clipPathUnits) 0051 0052 void SVGClipPathElement::parseMappedAttribute(MappedAttribute *attr) 0053 { 0054 if (attr->name() == SVGNames::clipPathUnitsAttr) { 0055 if (attr->value() == "userSpaceOnUse") { 0056 setClipPathUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE); 0057 } else if (attr->value() == "objectBoundingBox") { 0058 setClipPathUnitsBaseValue(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); 0059 } 0060 } else { 0061 if (SVGTests::parseMappedAttribute(attr)) { 0062 return; 0063 } 0064 if (SVGLangSpace::parseMappedAttribute(attr)) { 0065 return; 0066 } 0067 if (SVGExternalResourcesRequired::parseMappedAttribute(attr)) { 0068 return; 0069 } 0070 SVGStyledTransformableElement::parseMappedAttribute(attr); 0071 } 0072 } 0073 0074 void SVGClipPathElement::svgAttributeChanged(const QualifiedName &attrName) 0075 { 0076 SVGStyledTransformableElement::svgAttributeChanged(attrName); 0077 0078 if (!m_clipper) { 0079 return; 0080 } 0081 0082 if (attrName == SVGNames::clipPathUnitsAttr || 0083 SVGTests::isKnownAttribute(attrName) || 0084 SVGLangSpace::isKnownAttribute(attrName) || 0085 SVGExternalResourcesRequired::isKnownAttribute(attrName) || 0086 SVGStyledTransformableElement::isKnownAttribute(attrName)) { 0087 m_clipper->invalidate(); 0088 } 0089 } 0090 0091 void SVGClipPathElement::childrenChanged(bool changedByParser, Node *beforeChange, Node *afterChange, int childCountDelta) 0092 { 0093 SVGStyledTransformableElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 0094 0095 if (!m_clipper) { 0096 return; 0097 } 0098 0099 m_clipper->invalidate(); 0100 } 0101 0102 SVGResource *SVGClipPathElement::canvasResource() 0103 { 0104 if (!m_clipper) { 0105 m_clipper = SVGResourceClipper::create(); 0106 } else { 0107 m_clipper->resetClipData(); 0108 } 0109 0110 bool bbox = clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 0111 0112 //RenderStyle* clipPathStyle = styleForRenderer(parent()->renderer()); // FIXME: Manual style resolution is a hack 0113 for (Node *n = firstChild(); n; n = n->nextSibling()) { 0114 if (n->isSVGElement() && static_cast<SVGElement *>(n)->isStyledTransformable()) { 0115 SVGStyledTransformableElement *styled = static_cast<SVGStyledTransformableElement *>(n); 0116 RenderStyle *pathStyle = document()->styleSelector()->styleForElement(styled/*khtml, clipPathStyle*/); 0117 if (pathStyle->display() != NONE) { 0118 Path pathData = styled->toClipPath(); 0119 // FIXME: How do we know the element has done a layout? 0120 pathData.transform(styled->animatedLocalTransform()); 0121 if (!pathData.isEmpty()) { 0122 m_clipper->addClipData(pathData, pathStyle->svgStyle()->clipRule(), bbox); 0123 } 0124 } 0125 //khtml pathStyle->deref(document()->renderArena()); 0126 } 0127 } 0128 if (m_clipper->clipData().isEmpty()) { 0129 Path pathData; 0130 pathData.addRect(FloatRect()); 0131 m_clipper->addClipData(pathData, RULE_EVENODD, bbox); 0132 } 0133 //khtml clipPathStyle->deref(document()->renderArena()); 0134 return m_clipper.get(); 0135 } 0136 0137 } 0138 0139 #endif // ENABLE(SVG)