4d5e848f0e4d466daf5240191c0d337253240bf8
[WebKit-https.git] / WebCore / platform / Image.h
1 /*
2  * Copyright (C) 2004, 2005, 2006 Apple Computer, 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 #ifndef IMAGE_H_
27 #define IMAGE_H_
28
29 #include "DeprecatedArray.h"
30 #include "ImageSource.h"
31 #include "IntSize.h"
32 #include "FloatSize.h"
33 #include <kxmlcore/Vector.h>
34
35 #if __APPLE__
36 #if __OBJC__
37 @class NSImage;
38 #else
39 class NSImage;
40 #endif
41 #endif
42
43 namespace WebCore {
44     struct FrameData;
45 };
46
47 // This complicated-looking declaration tells the framedata Vector that it can copy without
48 // having to invoke our copy constructor. This allows us to not have to worry about ref counting
49 // the native frames.
50 namespace KXMLCore { 
51     template<> class VectorTraits<WebCore::FrameData> : public SimpleClassVectorTraits {};
52 }
53
54 namespace WebCore {
55
56 class FloatPoint;
57 class FloatRect;
58 class IntRect;
59 class IntSize;
60 class String;
61
62 template <typename T> class Timer;
63
64 // FIXME: Eventually we will want to have CoreGraphics vs. Cairo ifdefs in this file rather
65 // than Apple vs. non-Apple.
66
67 // This pointer represents the platform-specific image data.
68 #if __APPLE__
69 typedef CGImageRef NativeImagePtr;
70 class PDFDocumentImage;
71 typedef CFDataRef NativeBytePtr;
72 #else
73 typedef cairo_surface_t* NativeImagePtr;
74 typedef const DeprecatedByteArray* NativeBytePtr;
75 #endif
76
77 // This class gets notified when an image advances animation frames.
78 class ImageAnimationObserver;
79
80 // ================================================
81 // FrameData Class
82 // ================================================
83
84 struct FrameData {
85     FrameData()
86       :m_frame(0), m_duration(0), m_hasAlpha(true) 
87     {}
88
89     ~FrameData()
90     { 
91         clear();
92     }
93
94     void clear();
95
96     NativeImagePtr m_frame;
97     float m_duration;
98     bool m_hasAlpha;
99 };
100
101 // =================================================
102 // Image Class
103 // =================================================
104
105 class Image {
106 public:
107     Image();
108     Image(ImageAnimationObserver* observer, bool isPDF = false);
109     ~Image();
110     
111     static Image* loadResource(const char *name);
112     static bool supportsType(const String& type);
113
114     bool isNull() const;
115
116     IntSize size() const;
117     IntRect rect() const;
118     int width() const;
119     int height() const;
120
121     bool setData(const DeprecatedByteArray& bytes, bool allDataReceived);
122     bool setNativeData(NativeBytePtr bytePtr, bool allDataReceived);
123
124     // It may look unusual that there is no start animation call as public API.  This is because
125     // we start and stop animating lazily.  Animation begins whenever someone draws the image.  It will
126     // automatically pause once all observers no longer want to render the image anywhere.
127     void stopAnimation();
128     void resetAnimation();
129     
130     // Frame accessors.
131     size_t currentFrame() const { return m_currentFrame; }
132     size_t frameCount();
133     NativeImagePtr frameAtIndex(size_t index);
134     float frameDurationAtIndex(size_t index);
135     bool frameHasAlphaAtIndex(size_t index);
136
137     // Typically the CachedImage that owns us.
138     ImageAnimationObserver* animationObserver() const { return m_animationObserver; }
139
140     // Note: These constants exactly match the NSCompositeOperator constants of AppKit.
141     enum CompositeOperator {
142         CompositeClear,
143         CompositeCopy,
144         CompositeSourceOver,
145         CompositeSourceIn,
146         CompositeSourceOut,
147         CompositeSourceAtop,
148         CompositeDestinationOver,
149         CompositeDestinationIn,
150         CompositeDestinationOut,
151         CompositeDestinationAtop,
152         CompositeXOR,
153         CompositePlusDarker,
154         CompositeHighlight,
155         CompositePlusLighter
156     };
157
158     enum TileRule { StretchTile, RoundTile, RepeatTile };
159
160     static CompositeOperator compositeOperatorFromString(const String&);
161
162     // Drawing routines.
163     void drawInRect(const FloatRect& dstRect, const FloatRect& srcRect,
164                     CompositeOperator compositeOp, void* context);
165     void tileInRect(const FloatRect& destRect, const FloatPoint& point,
166                     const FloatSize& tileSize, void* context);
167     void scaleAndTileInRect(const FloatRect& dstRect, const FloatRect& srcRect,
168                             TileRule hRule, TileRule vRule, void* context);
169
170 #if __APPLE__
171     // Apple Image accessors for native formats.
172     CGImageRef getCGImageRef();
173     NSImage* getNSImage();
174     CFDataRef getTIFFRepresentation();
175     
176     // PDF
177     void setIsPDF() { m_isPDF = true; }
178     
179 private:
180     void checkForSolidColor(CGImageRef image);
181 #endif
182
183 private:
184     // We do not allow images to be assigned to or copied.
185     Image(const Image&);
186     Image &operator=(const Image&);
187
188     // Decodes and caches a frame. Never accessed except internally.
189     void cacheFrame(size_t index);
190
191     // Called to invalidate all our cached data when more bytes are available.
192     void invalidateData();
193
194     // Whether or not size is available yet.    
195     bool isSizeAvailable();
196
197     // Animation.
198     bool shouldAnimate();
199     void startAnimation();
200     void advanceAnimation(Timer<Image>* timer);
201     
202     // Constructor for native data.
203     void initNativeData();
204
205     // Destructor for native data.
206     void destroyNativeData();
207
208     // Invalidation of native data.
209     void invalidateNativeData();
210
211     // Members
212     DeprecatedByteArray m_data; // The encoded raw data for the image.
213     ImageSource m_source;
214     mutable IntSize m_size; // The size to use for the overall image (will just be the size of the first image).
215     
216     size_t m_currentFrame; // The index of the current frame of animation.
217     Vector<FrameData> m_frames; // An array of the cached frames of the animation. We have to ref frames to pin them in the cache.
218     
219     // Our animation observer.
220     ImageAnimationObserver* m_animationObserver;
221     Timer<Image>* m_frameTimer;
222     int m_repetitionCount; // How many total animation loops we should do.
223     int m_repetitionsComplete;  // How many repetitions we've finished.
224
225 #if __APPLE__
226     mutable NSImage* m_nsImage; // A cached NSImage of frame 0. Only built lazily if someone actually queries for one.
227     mutable CFDataRef m_tiffRep; // Cached TIFF rep for frame 0.  Only built lazily if someone queries for one.
228     PDFDocumentImage* m_PDFDoc;
229     CGColorRef m_solidColor; // Will be 0 if transparent.
230     bool m_isSolidColor : 1; // If the image is 1x1 with no alpha, we can just do a rect fill when painting/tiling.
231     bool m_isPDF : 1;
232 #endif
233
234     bool m_animatingImageType : 1;  // Whether or not we're an image type that is capable of animating (GIF).
235     bool m_animationFinished : 1;  // Whether or not we've completed the entire animation.
236
237     mutable bool m_haveSize : 1; // Whether or not our |m_size| member variable has the final overall image size yet.
238     bool m_sizeAvailable : 1; // Whether or not we can obtain the size of the first image frame yet from ImageIO.
239 };
240
241 }
242
243 #endif