initial import
[vuplus_webkit] / Source / WebCore / platform / graphics / cairo / ImageCairo.cpp
1 /*
2  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4  * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "config.h"
29 #include "BitmapImage.h"
30
31 #if USE(CAIRO)
32
33 #include "AffineTransform.h"
34 #include "CairoUtilities.h"
35 #include "Color.h"
36 #include "FloatRect.h"
37 #include "GraphicsContext.h"
38 #include "PlatformContextCairo.h"
39 #include "ImageBuffer.h"
40 #include "ImageObserver.h"
41 #include "RefPtrCairo.h"
42 #include <cairo.h>
43 #include <math.h>
44 #include <wtf/OwnPtr.h>
45
46 namespace WebCore {
47
48 bool FrameData::clear(bool clearMetadata)
49 {
50     if (clearMetadata)
51         m_haveMetadata = false;
52
53     if (m_frame) {
54         cairo_surface_destroy(m_frame);
55         m_frame = 0;
56         return true;
57     }
58     return false;
59 }
60
61 BitmapImage::BitmapImage(cairo_surface_t* surface, ImageObserver* observer)
62     : Image(observer)
63     , m_currentFrame(0)
64     , m_frames(0)
65     , m_frameTimer(0)
66     , m_repetitionCount(cAnimationNone)
67     , m_repetitionCountStatus(Unknown)
68     , m_repetitionsComplete(0)
69     , m_isSolidColor(false)
70     , m_checkedForSolidColor(false)
71     , m_animationFinished(true)
72     , m_allDataReceived(true)
73     , m_haveSize(true)
74     , m_sizeAvailable(true)
75     , m_decodedSize(0)
76     , m_haveFrameCount(true)
77     , m_frameCount(1)
78 {
79     initPlatformData();
80
81     // TODO: check to be sure this is an image surface
82
83     int width = cairo_image_surface_get_width(surface);
84     int height = cairo_image_surface_get_height(surface);
85     m_decodedSize = width * height * 4;
86     m_size = IntSize(width, height);
87
88     m_frames.grow(1);
89     m_frames[0].m_frame = surface;
90     m_frames[0].m_hasAlpha = cairo_surface_get_content(surface) != CAIRO_CONTENT_COLOR;
91     m_frames[0].m_haveMetadata = true;
92     checkForSolidColor();
93 }
94
95 void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
96 {
97     FloatRect srcRect(src);
98     FloatRect dstRect(dst);
99
100     if (dstRect.width() == 0.0f || dstRect.height() == 0.0f ||
101         srcRect.width() == 0.0f || srcRect.height() == 0.0f)
102         return;
103
104     startAnimation();
105
106     cairo_surface_t* image = frameAtIndex(m_currentFrame);
107     if (!image) // If it's too early we won't have an image yet.
108         return;
109
110     if (mayFillWithSolidColor()) {
111         fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op);
112         return;
113     }
114
115     context->save();
116
117     // Set the compositing operation.
118     if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
119         context->setCompositeOperation(CompositeCopy);
120     else
121         context->setCompositeOperation(op);
122     context->platformContext()->drawSurfaceToContext(image, dstRect, srcRect, context);
123
124     context->restore();
125
126     if (imageObserver())
127         imageObserver()->didDraw(this);
128 }
129
130 void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, const AffineTransform& patternTransform,
131                         const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator op, const FloatRect& destRect)
132 {
133     cairo_surface_t* image = nativeImageForCurrentFrame();
134     if (!image) // If it's too early we won't have an image yet.
135         return;
136
137     cairo_t* cr = context->platformContext()->cr();
138     drawPatternToCairoContext(cr, image, size(), tileRect, patternTransform, phase, toCairoOperator(op), destRect);
139
140     if (imageObserver())
141         imageObserver()->didDraw(this);
142 }
143
144 void BitmapImage::checkForSolidColor()
145 {
146     m_isSolidColor = false;
147     m_checkedForSolidColor = true;
148
149     if (frameCount() > 1)
150         return;
151
152     cairo_surface_t* frameSurface = frameAtIndex(0);
153     if (!frameSurface)
154         return;
155
156     ASSERT(cairo_surface_get_type(frameSurface) == CAIRO_SURFACE_TYPE_IMAGE);
157
158     int width = cairo_image_surface_get_width(frameSurface);
159     int height = cairo_image_surface_get_height(frameSurface);
160
161     if (width != 1 || height != 1)
162         return;
163
164     unsigned* pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(frameSurface));
165     m_solidColor = colorFromPremultipliedARGB(*pixelColor);
166
167     m_isSolidColor = true;
168 }
169
170 }
171
172 #endif // USE(CAIRO)