1/*
2    Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3    Copyright (C) 2001 Dirk Mueller <mueller@kde.org>
4    Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
5    Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public
9    License as published by the Free Software Foundation; either
10    version 2 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16
17    You should have received a copy of the GNU Library General Public License
18    along with this library; see the file COPYING.LIB.  If not, write to
19    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.
21*/
22
23#ifndef CachedImage_h
24#define CachedImage_h
25
26#include "CachedResource.h"
27#include "ImageObserver.h"
28#include "IntRect.h"
29#include "IntSizeHash.h"
30#include "LayoutSize.h"
31#include "SVGImageCache.h"
32#include <wtf/HashMap.h>
33#include <wtf/Vector.h>
34
35namespace WebCore {
36
37class CachedImageClient;
38class CachedResourceLoader;
39class FloatSize;
40class MemoryCache;
41class RenderObject;
42struct Length;
43
44class CachedImage FINAL : public CachedResource, public ImageObserver {
45    friend class MemoryCache;
46
47public:
48    CachedImage(const ResourceRequest&);
49    CachedImage(Image*);
50    virtual ~CachedImage();
51
52    Image* image(); // Returns the nullImage() if the image is not available yet.
53    Image* imageForRenderer(const RenderObject*); // Returns the nullImage() if the image is not available yet.
54    bool hasImage() const { return m_image.get(); }
55    bool currentFrameKnownToBeOpaque(const RenderObject*); // Side effect: ensures decoded image is in cache, therefore should only be called when about to draw the image.
56
57    std::pair<Image*, float> brokenImage(float deviceScaleFactor) const; // Returns an image and the image's resolution scale factor.
58    bool willPaintBrokenImage() const;
59
60    bool canRender(const RenderObject* renderer, float multiplier) { return !errorOccurred() && !imageSizeForRenderer(renderer, multiplier).isEmpty(); }
61
62    void setContainerSizeForRenderer(const CachedImageClient*, const IntSize&, float);
63    bool usesImageContainerSize() const;
64    bool imageHasRelativeWidth() const;
65    bool imageHasRelativeHeight() const;
66
67    virtual void addDataBuffer(ResourceBuffer*) OVERRIDE;
68    virtual void finishLoading(ResourceBuffer*) OVERRIDE;
69
70    // This method takes a zoom multiplier that can be used to increase the natural size of the image by the zoom.
71    LayoutSize imageSizeForRenderer(const RenderObject*, float multiplier); // returns the size of the complete image.
72    void computeIntrinsicDimensions(Length& intrinsicWidth, Length& intrinsicHeight, FloatSize& intrinsicRatio);
73
74    static void resumeAnimatingImagesForLoader(CachedResourceLoader*);
75
76private:
77    virtual void load(CachedResourceLoader*, const ResourceLoaderOptions&) OVERRIDE;
78
79    void clear();
80
81    void createImage();
82    void clearImage();
83    bool canBeDrawn() const;
84    // If not null, changeRect is the changed part of the image.
85    void notifyObservers(const IntRect* changeRect = 0);
86    virtual PurgePriority purgePriority() const OVERRIDE { return PurgeFirst; }
87    void checkShouldPaintBrokenImage();
88
89    virtual void switchClientsToRevalidatedResource() OVERRIDE;
90    virtual bool mayTryReplaceEncodedData() const OVERRIDE { return true; }
91
92    virtual void didAddClient(CachedResourceClient*) OVERRIDE;
93    virtual void didRemoveClient(CachedResourceClient*) OVERRIDE;
94
95    virtual void allClientsRemoved() OVERRIDE;
96    virtual void destroyDecodedData() OVERRIDE;
97
98    virtual void addData(const char* data, unsigned length) OVERRIDE;
99    virtual void error(CachedResource::Status) OVERRIDE;
100    virtual void responseReceived(const ResourceResponse&) OVERRIDE;
101
102    // For compatibility, images keep loading even if there are HTTP errors.
103    virtual bool shouldIgnoreHTTPStatusCodeErrors() const OVERRIDE { return true; }
104
105    virtual bool isImage() const OVERRIDE { return true; }
106    virtual bool stillNeedsLoad() const OVERRIDE { return !errorOccurred() && status() == Unknown && !isLoading(); }
107
108    // ImageObserver
109    virtual void decodedSizeChanged(const Image*, int delta) OVERRIDE;
110    virtual void didDraw(const Image*) OVERRIDE;
111
112    virtual bool shouldPauseAnimation(const Image*) OVERRIDE;
113    virtual void animationAdvanced(const Image*) OVERRIDE;
114    virtual void changedInRect(const Image*, const IntRect&) OVERRIDE;
115
116    void addIncrementalDataBuffer(ResourceBuffer*);
117
118    typedef pair<IntSize, float> SizeAndZoom;
119    typedef HashMap<const CachedImageClient*, SizeAndZoom> ContainerSizeRequests;
120    ContainerSizeRequests m_pendingContainerSizeRequests;
121
122    RefPtr<Image> m_image;
123#if ENABLE(SVG)
124    OwnPtr<SVGImageCache> m_svgImageCache;
125#endif
126    bool m_shouldPaintBrokenImage;
127};
128
129}
130
131#endif
132