1 /* 2 * Copyright (C) Research In Motion Limited 2011. All rights reserved. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20 #include "config.h" 21 22 #include "core/svg/properties/SVGAttributeToPropertyMap.h" 23 #include "core/svg/properties/SVGAnimatedProperty.h" 24 #include "wtf/PassOwnPtr.h" 25 26 namespace WebCore { 27 28 void SVGAttributeToPropertyMap::addProperties(const SVGAttributeToPropertyMap& map) 29 { 30 AttributeToPropertiesMap::const_iterator end = map.m_map.end(); 31 for (AttributeToPropertiesMap::const_iterator it = map.m_map.begin(); it != end; ++it) { 32 const PropertiesVector* mapVector = it->value.get(); 33 ASSERT(mapVector); 34 35 if (!mapVector->isEmpty()) { 36 const SVGPropertyInfo* firstProperty = mapVector->first(); 37 ASSERT(firstProperty); 38 const QualifiedName& attributeName = firstProperty->attributeName; 39 40 // All of the properties in mapVector are guaranteed to have the same attribute name. 41 // Add them to our properties vector for that attribute name, reserving capacity up 42 // front. 43 PropertiesVector* vector = getOrCreatePropertiesVector(attributeName); 44 ASSERT(vector); 45 vector->reserveCapacity(vector->size() + mapVector->size()); 46 const PropertiesVector::const_iterator mapVectorEnd = mapVector->end(); 47 for (PropertiesVector::const_iterator mapVectorIt = mapVector->begin(); mapVectorIt != mapVectorEnd; ++mapVectorIt) { 48 ASSERT(*mapVectorIt); 49 ASSERT(attributeName == (*mapVectorIt)->attributeName); 50 vector->append(*mapVectorIt); 51 } 52 } 53 } 54 } 55 56 void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo* info) 57 { 58 ASSERT(info); 59 PropertiesVector* vector = getOrCreatePropertiesVector(info->attributeName); 60 ASSERT(vector); 61 vector->append(info); 62 } 63 64 void SVGAttributeToPropertyMap::animatedPropertiesForAttribute(SVGElement* ownerType, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty> >& properties) 65 { 66 ASSERT(ownerType); 67 PropertiesVector* vector = m_map.get(attributeName); 68 if (!vector) 69 return; 70 71 properties.reserveCapacity(properties.size() + vector->size()); 72 const PropertiesVector::iterator vectorEnd = vector->end(); 73 for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) 74 properties.append(animatedProperty(ownerType, attributeName, *vectorIt)); 75 } 76 77 void SVGAttributeToPropertyMap::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes) 78 { 79 PropertiesVector* vector = m_map.get(attributeName); 80 if (!vector) 81 return; 82 83 propertyTypes.reserveCapacity(propertyTypes.size() + vector->size()); 84 const PropertiesVector::iterator vectorEnd = vector->end(); 85 for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) 86 propertyTypes.append((*vectorIt)->animatedPropertyType); 87 } 88 89 void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement* contextElement) 90 { 91 ASSERT(contextElement); 92 const AttributeToPropertiesMap::iterator end = m_map.end(); 93 for (AttributeToPropertiesMap::iterator it = m_map.begin(); it != end; ++it) { 94 PropertiesVector* vector = it->value.get(); 95 ASSERT(vector); 96 97 const PropertiesVector::iterator vectorEnd = vector->end(); 98 for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) 99 synchronizeProperty(contextElement, it->key, *vectorIt); 100 } 101 } 102 103 bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName) 104 { 105 ASSERT(contextElement); 106 PropertiesVector* vector = m_map.get(attributeName); 107 if (!vector) 108 return false; 109 110 const PropertiesVector::iterator vectorEnd = vector->end(); 111 for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt) 112 synchronizeProperty(contextElement, attributeName, *vectorIt); 113 114 return true; 115 } 116 117 SVGAttributeToPropertyMap::PropertiesVector* SVGAttributeToPropertyMap::getOrCreatePropertiesVector(const QualifiedName& attributeName) 118 { 119 ASSERT(attributeName != anyQName()); 120 AttributeToPropertiesMap::AddResult addResult = m_map.add(attributeName, PassOwnPtr<PropertiesVector>()); 121 PropertiesVector* vector = addResult.iterator->value.get(); 122 if (addResult.isNewEntry) { 123 ASSERT(!vector); 124 vector = (addResult.iterator->value = adoptPtr(new PropertiesVector)).get(); 125 } 126 ASSERT(vector); 127 ASSERT(addResult.iterator->value.get() == vector); 128 return vector; 129 } 130 131 void SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info) 132 { 133 ASSERT(info); 134 ASSERT_UNUSED(attributeName, attributeName == info->attributeName); 135 ASSERT(info->synchronizeProperty); 136 (*info->synchronizeProperty)(contextElement); 137 } 138 139 PassRefPtr<SVGAnimatedProperty> SVGAttributeToPropertyMap::animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info) 140 { 141 ASSERT(info); 142 ASSERT_UNUSED(attributeName, attributeName == info->attributeName); 143 ASSERT(info->lookupOrCreateWrapperForAnimatedProperty); 144 return (*info->lookupOrCreateWrapperForAnimatedProperty)(contextElement); 145 } 146 147 } 148