Home | History | Annotate | Download | only in css
      1 /*
      2  * Copyright (C) 2011, 2012 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 "core/css/CSSValuePool.h"
     28 
     29 #include "core/css/parser/BisonCSSParser.h"
     30 #include "core/css/CSSValueList.h"
     31 #include "core/rendering/style/RenderStyle.h"
     32 
     33 namespace WebCore {
     34 
     35 CSSValuePool& cssValuePool()
     36 {
     37 #if ENABLE(OILPAN)
     38     DEFINE_STATIC_LOCAL(Persistent<CSSValuePool>, pool, (new CSSValuePool()));
     39     return *pool;
     40 #else
     41     DEFINE_STATIC_LOCAL(CSSValuePool, pool, ());
     42     return pool;
     43 #endif // ENABLE(OILPAN)
     44 }
     45 
     46 CSSValuePool::CSSValuePool()
     47     : m_inheritedValue(CSSInheritedValue::create())
     48     , m_implicitInitialValue(CSSInitialValue::createImplicit())
     49     , m_explicitInitialValue(CSSInitialValue::createExplicit())
     50     , m_colorTransparent(CSSPrimitiveValue::createColor(Color::transparent))
     51     , m_colorWhite(CSSPrimitiveValue::createColor(Color::white))
     52     , m_colorBlack(CSSPrimitiveValue::createColor(Color::black))
     53 {
     54     m_identifierValueCache.resize(numCSSValueKeywords);
     55     m_pixelValueCache.resize(maximumCacheableIntegerValue + 1);
     56     m_percentValueCache.resize(maximumCacheableIntegerValue + 1);
     57     m_numberValueCache.resize(maximumCacheableIntegerValue + 1);
     58 }
     59 
     60 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSValueID ident)
     61 {
     62     if (ident <= 0)
     63         return CSSPrimitiveValue::createIdentifier(ident);
     64 
     65     if (!m_identifierValueCache[ident])
     66         m_identifierValueCache[ident] = CSSPrimitiveValue::createIdentifier(ident);
     67     return m_identifierValueCache[ident];
     68 }
     69 
     70 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createIdentifierValue(CSSPropertyID ident)
     71 {
     72     return CSSPrimitiveValue::createIdentifier(ident);
     73 }
     74 
     75 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createColorValue(unsigned rgbValue)
     76 {
     77     // These are the empty and deleted values of the hash table.
     78     if (rgbValue == Color::transparent)
     79         return m_colorTransparent;
     80     if (rgbValue == Color::white)
     81         return m_colorWhite;
     82     // Just because it is common.
     83     if (rgbValue == Color::black)
     84         return m_colorBlack;
     85 
     86     // Just wipe out the cache and start rebuilding if it gets too big.
     87     const unsigned maximumColorCacheSize = 512;
     88     if (m_colorValueCache.size() > maximumColorCacheSize)
     89         m_colorValueCache.clear();
     90 
     91     RefPtrWillBeRawPtr<CSSPrimitiveValue> dummyValue = nullptr;
     92     ColorValueCache::AddResult entry = m_colorValueCache.add(rgbValue, dummyValue);
     93     if (entry.isNewEntry)
     94         entry.storedValue->value = CSSPrimitiveValue::createColor(rgbValue);
     95     return entry.storedValue->value;
     96 }
     97 
     98 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createValue(double value, CSSPrimitiveValue::UnitType type)
     99 {
    100     if (std::isinf(value))
    101         value = 0;
    102 
    103     if (value < 0 || value > maximumCacheableIntegerValue)
    104         return CSSPrimitiveValue::create(value, type);
    105 
    106     int intValue = static_cast<int>(value);
    107     if (value != intValue)
    108         return CSSPrimitiveValue::create(value, type);
    109 
    110     switch (type) {
    111     case CSSPrimitiveValue::CSS_PX:
    112         if (!m_pixelValueCache[intValue])
    113             m_pixelValueCache[intValue] = CSSPrimitiveValue::create(value, type);
    114         return m_pixelValueCache[intValue];
    115     case CSSPrimitiveValue::CSS_PERCENTAGE:
    116         if (!m_percentValueCache[intValue])
    117             m_percentValueCache[intValue] = CSSPrimitiveValue::create(value, type);
    118         return m_percentValueCache[intValue];
    119     case CSSPrimitiveValue::CSS_NUMBER:
    120         if (!m_numberValueCache[intValue])
    121             m_numberValueCache[intValue] = CSSPrimitiveValue::create(value, type);
    122         return m_numberValueCache[intValue];
    123     default:
    124         return CSSPrimitiveValue::create(value, type);
    125     }
    126 }
    127 
    128 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createValue(const Length& value, const RenderStyle& style)
    129 {
    130     return CSSPrimitiveValue::create(value, style.effectiveZoom());
    131 }
    132 
    133 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName)
    134 {
    135     RefPtrWillBeMember<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, nullptr).storedValue->value;
    136     if (!value)
    137         value = CSSPrimitiveValue::create(familyName, CSSPrimitiveValue::CSS_STRING);
    138     return value;
    139 }
    140 
    141 PassRefPtrWillBeRawPtr<CSSValueList> CSSValuePool::createFontFaceValue(const AtomicString& string)
    142 {
    143     // Just wipe out the cache and start rebuilding if it gets too big.
    144     const unsigned maximumFontFaceCacheSize = 128;
    145     if (m_fontFaceValueCache.size() > maximumFontFaceCacheSize)
    146         m_fontFaceValueCache.clear();
    147 
    148     RefPtrWillBeMember<CSSValueList>& value = m_fontFaceValueCache.add(string, nullptr).storedValue->value;
    149     if (!value)
    150         value = BisonCSSParser::parseFontFaceValue(string);
    151     return value;
    152 }
    153 
    154 void CSSValuePool::trace(Visitor* visitor)
    155 {
    156     visitor->trace(m_inheritedValue);
    157     visitor->trace(m_implicitInitialValue);
    158     visitor->trace(m_explicitInitialValue);
    159     visitor->trace(m_identifierValueCache);
    160     visitor->trace(m_colorValueCache);
    161     visitor->trace(m_colorTransparent);
    162     visitor->trace(m_colorWhite);
    163     visitor->trace(m_colorBlack);
    164     visitor->trace(m_pixelValueCache);
    165     visitor->trace(m_percentValueCache);
    166     visitor->trace(m_numberValueCache);
    167     visitor->trace(m_fontFaceValueCache);
    168     visitor->trace(m_fontFamilyValueCache);
    169 }
    170 
    171 }
    172