1 /* 2 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "CSSPrimitiveValueCache.h" 28 29 namespace WebCore { 30 31 CSSPrimitiveValueCache::CSSPrimitiveValueCache() 32 : m_colorTransparent(CSSPrimitiveValue::createColor(Color::transparent)) 33 , m_colorWhite(CSSPrimitiveValue::createColor(Color::white)) 34 , m_colorBlack(CSSPrimitiveValue::createColor(Color::black)) 35 , m_pixelZero(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PX)) 36 , m_percentZero(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_PERCENTAGE)) 37 , m_numberZero(CSSPrimitiveValue::create(0, CSSPrimitiveValue::CSS_NUMBER)) 38 { 39 } 40 41 CSSPrimitiveValueCache::~CSSPrimitiveValueCache() 42 { 43 } 44 45 PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createIdentifierValue(int ident) 46 { 47 if (ident <= 0 || ident >= numCSSValueKeywords) 48 return CSSPrimitiveValue::createIdentifier(ident); 49 50 RefPtr<CSSPrimitiveValue> dummyValue; 51 pair<IdentifierValueCache::iterator, bool> entry = m_identifierValueCache.add(ident, dummyValue); 52 if (entry.second) 53 entry.first->second = CSSPrimitiveValue::createIdentifier(ident); 54 return entry.first->second; 55 } 56 57 PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createColorValue(unsigned rgbValue) 58 { 59 // These are the empty and deleted values of the hash table. 60 if (rgbValue == Color::transparent) 61 return m_colorTransparent; 62 if (rgbValue == Color::white) 63 return m_colorWhite; 64 // Just because it is common. 65 if (rgbValue == Color::black) 66 return m_colorBlack; 67 68 // Just wipe out the cache and start rebuilding if it gets too big. 69 const int maximumColorCacheSize = 512; 70 if (m_colorValueCache.size() > maximumColorCacheSize) 71 m_colorValueCache.clear(); 72 73 RefPtr<CSSPrimitiveValue> dummyValue; 74 pair<ColorValueCache::iterator, bool> entry = m_colorValueCache.add(rgbValue, dummyValue); 75 if (entry.second) 76 entry.first->second = CSSPrimitiveValue::createColor(rgbValue); 77 return entry.first->second; 78 } 79 80 PassRefPtr<CSSPrimitiveValue> CSSPrimitiveValueCache::createValue(double value, CSSPrimitiveValue::UnitTypes type) 81 { 82 // Small positive integers repeat often. 83 static const int maximumCacheableValue = 256; 84 if (value < 0 || value > maximumCacheableValue) 85 return CSSPrimitiveValue::create(value, type); 86 87 int intValue = static_cast<int>(value); 88 if (value != intValue) 89 return CSSPrimitiveValue::create(value, type); 90 91 IntegerValueCache* cache; 92 switch (type) { 93 case CSSPrimitiveValue::CSS_PX: 94 if (intValue == 0) 95 return m_pixelZero; 96 cache = &m_pixelValueCache; 97 break; 98 case CSSPrimitiveValue::CSS_PERCENTAGE: 99 if (intValue == 0) 100 return m_percentZero; 101 cache = &m_percentValueCache; 102 break; 103 case CSSPrimitiveValue::CSS_NUMBER: 104 if (intValue == 0) 105 return m_numberZero; 106 cache = &m_numberValueCache; 107 break; 108 default: 109 return CSSPrimitiveValue::create(value, type); 110 } 111 112 RefPtr<CSSPrimitiveValue> dummyValue; 113 pair<IntegerValueCache::iterator, bool> entry = cache->add(intValue, dummyValue); 114 if (entry.second) 115 entry.first->second = CSSPrimitiveValue::create(value, type); 116 return entry.first->second; 117 } 118 119 } 120