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 "platform/graphics/Image.h"
     33 
     34 namespace blink {
     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     ASSERT(renderer);
     48 #if !ENABLE(OILPAN)
     49     ref();
     50 #else
     51     if (m_clients.isEmpty()) {
     52         ASSERT(!m_keepAlive);
     53         m_keepAlive = adoptPtr(new Persistent<CSSImageGeneratorValue>(this));
     54     }
     55 #endif
     56 
     57     if (!size.isEmpty())
     58         m_sizes.add(size);
     59 
     60     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
     61     if (it == m_clients.end())
     62         m_clients.add(renderer, SizeAndCount(size, 1));
     63     else {
     64         SizeAndCount& sizeCount = it->value;
     65         ++sizeCount.count;
     66     }
     67 }
     68 
     69 void CSSImageGeneratorValue::removeClient(RenderObject* renderer)
     70 {
     71     ASSERT(renderer);
     72     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
     73     ASSERT_WITH_SECURITY_IMPLICATION(it != m_clients.end());
     74 
     75     IntSize removedImageSize;
     76     SizeAndCount& sizeCount = it->value;
     77     IntSize size = sizeCount.size;
     78     if (!size.isEmpty()) {
     79         m_sizes.remove(size);
     80         if (!m_sizes.contains(size))
     81             m_images.remove(size);
     82     }
     83 
     84     if (!--sizeCount.count)
     85         m_clients.remove(renderer);
     86 
     87 #if !ENABLE(OILPAN)
     88     deref();
     89 #else
     90     if (m_clients.isEmpty()) {
     91         ASSERT(m_keepAlive);
     92         m_keepAlive = nullptr;
     93     }
     94 #endif
     95 }
     96 
     97 Image* CSSImageGeneratorValue::getImage(RenderObject* renderer, const IntSize& size)
     98 {
     99     RenderObjectSizeCountMap::iterator it = m_clients.find(renderer);
    100     if (it != m_clients.end()) {
    101         SizeAndCount& sizeCount = it->value;
    102         IntSize oldSize = sizeCount.size;
    103         if (oldSize != size) {
    104 #if !ENABLE_OILPAN
    105             RefPtr<CSSImageGeneratorValue> protect(this);
    106 #endif
    107             removeClient(renderer);
    108             addClient(renderer, size);
    109         }
    110     }
    111 
    112     // Don't generate an image for empty sizes.
    113     if (size.isEmpty())
    114         return 0;
    115 
    116     // Look up the image in our cache.
    117     return m_images.get(size);
    118 }
    119 
    120 void CSSImageGeneratorValue::putImage(const IntSize& size, PassRefPtr<Image> image)
    121 {
    122     m_images.add(size, image);
    123 }
    124 
    125 PassRefPtr<Image> CSSImageGeneratorValue::image(RenderObject* renderer, const IntSize& size)
    126 {
    127     switch (classType()) {
    128     case CanvasClass:
    129         return toCSSCanvasValue(this)->image(renderer, size);
    130     case CrossfadeClass:
    131         return toCSSCrossfadeValue(this)->image(renderer, size);
    132     case LinearGradientClass:
    133         return toCSSLinearGradientValue(this)->image(renderer, size);
    134     case RadialGradientClass:
    135         return toCSSRadialGradientValue(this)->image(renderer, size);
    136     default:
    137         ASSERT_NOT_REACHED();
    138     }
    139     return nullptr;
    140 }
    141 
    142 bool CSSImageGeneratorValue::isFixedSize() const
    143 {
    144     switch (classType()) {
    145     case CanvasClass:
    146         return toCSSCanvasValue(this)->isFixedSize();
    147     case CrossfadeClass:
    148         return toCSSCrossfadeValue(this)->isFixedSize();
    149     case LinearGradientClass:
    150         return toCSSLinearGradientValue(this)->isFixedSize();
    151     case RadialGradientClass:
    152         return toCSSRadialGradientValue(this)->isFixedSize();
    153     default:
    154         ASSERT_NOT_REACHED();
    155     }
    156     return false;
    157 }
    158 
    159 IntSize CSSImageGeneratorValue::fixedSize(const RenderObject* renderer)
    160 {
    161     switch (classType()) {
    162     case CanvasClass:
    163         return toCSSCanvasValue(this)->fixedSize(renderer);
    164     case CrossfadeClass:
    165         return toCSSCrossfadeValue(this)->fixedSize(renderer);
    166     case LinearGradientClass:
    167         return toCSSLinearGradientValue(this)->fixedSize(renderer);
    168     case RadialGradientClass:
    169         return toCSSRadialGradientValue(this)->fixedSize(renderer);
    170     default:
    171         ASSERT_NOT_REACHED();
    172     }
    173     return IntSize();
    174 }
    175 
    176 bool CSSImageGeneratorValue::isPending() const
    177 {
    178     switch (classType()) {
    179     case CrossfadeClass:
    180         return toCSSCrossfadeValue(this)->isPending();
    181     case CanvasClass:
    182         return toCSSCanvasValue(this)->isPending();
    183     case LinearGradientClass:
    184         return toCSSLinearGradientValue(this)->isPending();
    185     case RadialGradientClass:
    186         return toCSSRadialGradientValue(this)->isPending();
    187     default:
    188         ASSERT_NOT_REACHED();
    189     }
    190     return false;
    191 }
    192 
    193 bool CSSImageGeneratorValue::knownToBeOpaque(const RenderObject* renderer) const
    194 {
    195     switch (classType()) {
    196     case CrossfadeClass:
    197         return toCSSCrossfadeValue(this)->knownToBeOpaque(renderer);
    198     case CanvasClass:
    199         return false;
    200     case LinearGradientClass:
    201         return toCSSLinearGradientValue(this)->knownToBeOpaque(renderer);
    202     case RadialGradientClass:
    203         return toCSSRadialGradientValue(this)->knownToBeOpaque(renderer);
    204     default:
    205         ASSERT_NOT_REACHED();
    206     }
    207     return false;
    208 }
    209 
    210 void CSSImageGeneratorValue::loadSubimages(ResourceFetcher* fetcher)
    211 {
    212     switch (classType()) {
    213     case CrossfadeClass:
    214         toCSSCrossfadeValue(this)->loadSubimages(fetcher);
    215         break;
    216     case CanvasClass:
    217         toCSSCanvasValue(this)->loadSubimages(fetcher);
    218         break;
    219     case LinearGradientClass:
    220         toCSSLinearGradientValue(this)->loadSubimages(fetcher);
    221         break;
    222     case RadialGradientClass:
    223         toCSSRadialGradientValue(this)->loadSubimages(fetcher);
    224         break;
    225     default:
    226         ASSERT_NOT_REACHED();
    227     }
    228 }
    229 
    230 } // namespace blink
    231