Home | History | Annotate | Download | only in css
      1 /*
      2  * Copyright (C) 2008 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 COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "core/css/CSSImageGeneratorValue.h"
     28 
     29 #include "core/css/CSSCanvasValue.h"
     30 #include "core/css/CSSCrossfadeValue.h"
     31 #include "core/css/CSSGradientValue.h"
     32 #include "core/platform/graphics/Image.h"
     33 
     34 namespace WebCore {
     35 
     36 CSSImageGeneratorValue::CSSImageGeneratorValue(ClassType classType)
     37     : CSSValue(classType)
     38 {
     39 }
     40 
     41 CSSImageGeneratorValue::~CSSImageGeneratorValue()
     42 {
     43 }
     44 
     45 void CSSImageGeneratorValue::addClient(RenderObject* renderer, const IntSize& size)
     46 {
     47     ref();
     48 
     49     ASSERT(renderer);
     50     if (!size.isEmpty())
     51         m_sizes.add(size);
     52 
     53     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
     54     if (it == m_clients.end())
     55         m_clients.add(renderer, SizeAndCount(size, 1));
     56     else {
     57         SizeAndCount& sizeCount = it->value;
     58         ++sizeCount.count;
     59     }
     60 }
     61 
     62 void CSSImageGeneratorValue::removeClient(RenderObject* renderer)
     63 {
     64     ASSERT(renderer);
     65     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
     66     ASSERT(it != m_clients.end());
     67 
     68     IntSize removedImageSize;
     69     SizeAndCount& sizeCount = it->value;
     70     IntSize size = sizeCount.size;
     71     if (!size.isEmpty()) {
     72         m_sizes.remove(size);
     73         if (!m_sizes.contains(size))
     74             m_images.remove(size);
     75     }
     76 
     77     if (!--sizeCount.count)
     78         m_clients.remove(renderer);
     79 
     80     deref();
     81 }
     82 
     83 Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& size)
     84 {
     85     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
     86     if (it != m_clients.end()) {
     87         SizeAndCount& sizeCount = it->value;
     88         IntSize oldSize = sizeCount.size;
     89         if (oldSize != size) {
     90             RefPtr<CSSImageGeneratorValue> protect(this);
     91             removeClient(renderer);
     92             addClient(renderer, size);
     93         }
     94     }
     95 
     96     // Don't generate an image for empty sizes.
     97     if (size.isEmpty())
     98         return 0;
     99 
    100     // Look up the image in our cache.
    101     return m_images.get(size);
    102 }
    103 
    104 void CSSImageGeneratorValue::putImage(const IntSize& size, PassRefPtr<Image> image)
    105 {
    106     m_images.add(size, image);
    107 }
    108 
    109 PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size)
    110 {
    111     switch (classType()) {
    112     case CanvasClass:
    113         return static_cast<CSSCanvasValue*>(this)->image(renderer, size);
    114     case CrossfadeClass:
    115         return static_cast<CSSCrossfadeValue*>(this)->image(renderer, size);
    116     case LinearGradientClass:
    117         return static_cast<CSSLinearGradientValue*>(this)->image(renderer, size);
    118     case RadialGradientClass:
    119         return static_cast<CSSRadialGradientValue*>(this)->image(renderer, size);
    120     default:
    121         ASSERT_NOT_REACHED();
    122     }
    123     return 0;
    124 }
    125 
    126 bool CSSImageGeneratorValue::isFixedSize() const
    127 {
    128     switch (classType()) {
    129     case CanvasClass:
    130         return static_cast<const CSSCanvasValue*>(this)->isFixedSize();
    131     case CrossfadeClass:
    132         return static_cast<const CSSCrossfadeValue*>(this)->isFixedSize();
    133     case LinearGradientClass:
    134         return static_cast<const CSSLinearGradientValue*>(this)->isFixedSize();
    135     case RadialGradientClass:
    136         return static_cast<const CSSRadialGradientValue*>(this)->isFixedSize();
    137     default:
    138         ASSERT_NOT_REACHED();
    139     }
    140     return false;
    141 }
    142 
    143 IntSize CSSImageGeneratorValue::fixedSize(const RenderObject* renderer)
    144 {
    145     switch (classType()) {
    146     case CanvasClass:
    147         return static_cast<CSSCanvasValue*>(this)->fixedSize(renderer);
    148     case CrossfadeClass:
    149         return static_cast<CSSCrossfadeValue*>(this)->fixedSize(renderer);
    150     case LinearGradientClass:
    151         return static_cast<CSSLinearGradientValue*>(this)->fixedSize(renderer);
    152     case RadialGradientClass:
    153         return static_cast<CSSRadialGradientValue*>(this)->fixedSize(renderer);
    154     default:
    155         ASSERT_NOT_REACHED();
    156     }
    157     return IntSize();
    158 }
    159 
    160 bool CSSImageGeneratorValue::isPending() const
    161 {
    162     switch (classType()) {
    163     case CrossfadeClass:
    164         return static_cast<const CSSCrossfadeValue*>(this)->isPending();
    165     case CanvasClass:
    166         return static_cast<const CSSCanvasValue*>(this)->isPending();
    167     case LinearGradientClass:
    168         return static_cast<const CSSLinearGradientValue*>(this)->isPending();
    169     case RadialGradientClass:
    170         return static_cast<const CSSRadialGradientValue*>(this)->isPending();
    171     default:
    172         ASSERT_NOT_REACHED();
    173     }
    174     return false;
    175 }
    176 
    177 bool CSSImageGeneratorValue::knownToBeOpaque(const RenderObject* renderer) const
    178 {
    179     switch (classType()) {
    180     case CrossfadeClass:
    181         return static_cast<const CSSCrossfadeValue*>(this)->knownToBeOpaque(renderer);
    182     case CanvasClass:
    183         return false;
    184     case LinearGradientClass:
    185         return static_cast<const CSSLinearGradientValue*>(this)->knownToBeOpaque(renderer);
    186     case RadialGradientClass:
    187         return static_cast<const CSSRadialGradientValue*>(this)->knownToBeOpaque(renderer);
    188     default:
    189         ASSERT_NOT_REACHED();
    190     }
    191     return false;
    192 }
    193 
    194 void CSSImageGeneratorValue::loadSubimages(ResourceFetcher* fetcher)
    195 {
    196     switch (classType()) {
    197     case CrossfadeClass:
    198         static_cast<CSSCrossfadeValue*>(this)->loadSubimages(fetcher);
    199         break;
    200     case CanvasClass:
    201         static_cast<CSSCanvasValue*>(this)->loadSubimages(fetcher);
    202         break;
    203     case LinearGradientClass:
    204         static_cast<CSSLinearGradientValue*>(this)->loadSubimages(fetcher);
    205         break;
    206     case RadialGradientClass:
    207         static_cast<CSSRadialGradientValue*>(this)->loadSubimages(fetcher);
    208         break;
    209     default:
    210         ASSERT_NOT_REACHED();
    211     }
    212 }
    213 
    214 } // namespace WebCore
    215