~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/platform/graphics/cairo/BitmapImageCairo.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include "ImageObserver.h"
 
32
#include "NativeImageCairo.h"
 
33
#include "PlatformContextCairo.h"
 
34
#include <cairo.h>
 
35
 
 
36
namespace WebCore {
 
37
 
 
38
PassRefPtr<BitmapImage> BitmapImage::create(cairo_surface_t* surface)
 
39
{
 
40
    return BitmapImage::create(new NativeImageCairo(surface));
 
41
}
 
42
 
 
43
BitmapImage::BitmapImage(NativeImageCairo* nativeImage, ImageObserver* observer)
 
44
    : Image(observer)
 
45
    , m_currentFrame(0)
 
46
    , m_frames(0)
 
47
    , m_frameTimer(0)
 
48
    , m_repetitionCount(cAnimationNone)
 
49
    , m_repetitionCountStatus(Unknown)
 
50
    , m_repetitionsComplete(0)
 
51
    , m_decodedSize(0)
 
52
    , m_frameCount(1)
 
53
    , m_isSolidColor(false)
 
54
    , m_checkedForSolidColor(false)
 
55
    , m_animationFinished(true)
 
56
    , m_allDataReceived(true)
 
57
    , m_haveSize(true)
 
58
    , m_sizeAvailable(true)
 
59
    , m_haveFrameCount(true)
 
60
{
 
61
    cairo_surface_t* surface = nativeImage->surface();
 
62
    int width = cairo_image_surface_get_width(surface);
 
63
    int height = cairo_image_surface_get_height(surface);
 
64
    m_decodedSize = width * height * 4;
 
65
    m_size = IntSize(width, height);
 
66
 
 
67
    m_frames.grow(1);
 
68
    m_frames[0].m_frame = nativeImage;
 
69
    m_frames[0].m_hasAlpha = cairo_surface_get_content(surface) != CAIRO_CONTENT_COLOR;
 
70
    m_frames[0].m_haveMetadata = true;
 
71
    checkForSolidColor();
 
72
}
 
73
 
 
74
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
 
75
{
 
76
    draw(context, dst, src, styleColorSpace, op, DoNotRespectImageOrientation);
 
77
}
 
78
 
 
79
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op, RespectImageOrientationEnum shouldRespectImageOrientation)
 
80
{
 
81
    if (!dst.width() || !dst.height() || !src.width() || !src.height())
 
82
        return;
 
83
 
 
84
    startAnimation();
 
85
 
 
86
    NativeImageCairo* nativeImage = frameAtIndex(m_currentFrame);
 
87
    if (!nativeImage) // If it's too early we won't have an image yet.
 
88
        return;
 
89
 
 
90
    if (mayFillWithSolidColor()) {
 
91
        fillWithSolidColor(context, dst, solidColor(), styleColorSpace, op);
 
92
        return;
 
93
    }
 
94
 
 
95
    context->save();
 
96
 
 
97
    // Set the compositing operation.
 
98
    if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
 
99
        context->setCompositeOperation(CompositeCopy);
 
100
    else
 
101
        context->setCompositeOperation(op);
 
102
 
 
103
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
 
104
    cairo_surface_t* surface = nativeImage->surface();
 
105
    IntSize scaledSize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
 
106
    FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(src, scaledSize);
 
107
#else
 
108
    FloatRect adjustedSrcRect(src);
 
109
#endif
 
110
 
 
111
    ImageOrientation orientation = DefaultImageOrientation;
 
112
    if (shouldRespectImageOrientation == RespectImageOrientation)
 
113
        orientation = frameOrientationAtIndex(m_currentFrame);
 
114
 
 
115
    FloatRect dstRect = dst;
 
116
 
 
117
    if (orientation != DefaultImageOrientation) {
 
118
        // ImageOrientation expects the origin to be at (0, 0).
 
119
        context->translate(dstRect.x(), dstRect.y());
 
120
        dstRect.setLocation(FloatPoint());
 
121
        context->concatCTM(orientation.transformFromDefault(dstRect.size()));
 
122
        if (orientation.usesWidthAsHeight()) {
 
123
            // The destination rectangle will have it's width and height already reversed for the orientation of
 
124
            // the image, as it was needed for page layout, so we need to reverse it back here.
 
125
            dstRect = FloatRect(dstRect.x(), dstRect.y(), dstRect.height(), dstRect.width());
 
126
        }
 
127
    }
 
128
 
 
129
    context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, adjustedSrcRect, context);
 
130
 
 
131
    context->restore();
 
132
 
 
133
    if (imageObserver())
 
134
        imageObserver()->didDraw(this);
 
135
}
 
136
 
 
137
void BitmapImage::checkForSolidColor()
 
138
{
 
139
    m_isSolidColor = false;
 
140
    m_checkedForSolidColor = true;
 
141
 
 
142
    if (frameCount() > 1)
 
143
        return;
 
144
 
 
145
    NativeImageCairo* nativeImage = frameAtIndex(m_currentFrame);
 
146
    if (!nativeImage) // If it's too early we won't have an image yet.
 
147
        return;
 
148
 
 
149
    cairo_surface_t* surface = nativeImage->surface();
 
150
    ASSERT(cairo_surface_get_type(surface) == CAIRO_SURFACE_TYPE_IMAGE);
 
151
 
 
152
    int width = cairo_image_surface_get_width(surface);
 
153
    int height = cairo_image_surface_get_height(surface);
 
154
 
 
155
    if (width != 1 || height != 1)
 
156
        return;
 
157
 
 
158
    unsigned* pixelColor = reinterpret_cast<unsigned*>(cairo_image_surface_get_data(surface));
 
159
    m_solidColor = colorFromPremultipliedARGB(*pixelColor);
 
160
 
 
161
    m_isSolidColor = true;
 
162
}
 
163
 
 
164
bool FrameData::clear(bool clearMetadata)
 
165
{
 
166
    if (clearMetadata)
 
167
        m_haveMetadata = false;
 
168
 
 
169
    if (m_frame) {
 
170
        delete m_frame;
 
171
        m_frame = 0;
 
172
        return true;
 
173
    }
 
174
    return false;
 
175
}
 
176
 
 
177
} // namespace WebCore
 
178