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 26namespace WebCore { 27 28void 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 56void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo* info) 57{ 58 ASSERT(info); 59 PropertiesVector* vector = getOrCreatePropertiesVector(info->attributeName); 60 ASSERT(vector); 61 vector->append(info); 62} 63 64void 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 77void 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 89void 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 103bool 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 117SVGAttributeToPropertyMap::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 131void 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 139PassRefPtr<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