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

« back to all changes in this revision

Viewing changes to Source/WebCore/rendering/RenderSnapshottedPlugIn.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) 2012 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 INC. AND ITS CONTRIBUTORS ``AS IS''
 
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
23
 * THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "RenderSnapshottedPlugIn.h"
 
28
 
 
29
#include "Cursor.h"
 
30
#include "FrameLoaderClient.h"
 
31
#include "FrameView.h"
 
32
#include "Gradient.h"
 
33
#include "HTMLPlugInImageElement.h"
 
34
#include "MouseEvent.h"
 
35
#include "PaintInfo.h"
 
36
#include "Path.h"
 
37
 
 
38
namespace WebCore {
 
39
 
 
40
static const int autoStartPlugInSizeThresholdWidth = 1;
 
41
static const int autoStartPlugInSizeThresholdHeight = 1;
 
42
static const int startButtonPadding = 10;
 
43
 
 
44
RenderSnapshottedPlugIn::RenderSnapshottedPlugIn(HTMLPlugInImageElement* element)
 
45
    : RenderEmbeddedObject(element)
 
46
    , m_snapshotResource(RenderImageResource::create())
 
47
    , m_isMouseInButtonRect(false)
 
48
{
 
49
    m_snapshotResource->initialize(this);
 
50
}
 
51
 
 
52
RenderSnapshottedPlugIn::~RenderSnapshottedPlugIn()
 
53
{
 
54
    ASSERT(m_snapshotResource);
 
55
    m_snapshotResource->shutdown();
 
56
}
 
57
 
 
58
HTMLPlugInImageElement* RenderSnapshottedPlugIn::plugInImageElement() const
 
59
{
 
60
    return static_cast<HTMLPlugInImageElement*>(node());
 
61
}
 
62
 
 
63
void RenderSnapshottedPlugIn::updateSnapshot(PassRefPtr<Image> image)
 
64
{
 
65
    // Zero-size plugins will have no image.
 
66
    if (!image)
 
67
        return;
 
68
 
 
69
    m_snapshotResource->setCachedImage(new CachedImage(image.get()));
 
70
    repaint();
 
71
}
 
72
 
 
73
void RenderSnapshottedPlugIn::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 
74
{
 
75
    if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
 
76
        RenderReplaced::paint(paintInfo, paintOffset);
 
77
        return;
 
78
    }
 
79
 
 
80
    RenderEmbeddedObject::paint(paintInfo, paintOffset);
 
81
}
 
82
 
 
83
void RenderSnapshottedPlugIn::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 
84
{
 
85
    if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
 
86
        paintReplacedSnapshot(paintInfo, paintOffset);
 
87
        paintButton(paintInfo, paintOffset);
 
88
        return;
 
89
    }
 
90
 
 
91
    RenderEmbeddedObject::paintReplaced(paintInfo, paintOffset);
 
92
}
 
93
 
 
94
void RenderSnapshottedPlugIn::paintReplacedSnapshot(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 
95
{
 
96
    // This code should be similar to RenderImage::paintReplaced() and RenderImage::paintIntoRect().
 
97
    LayoutUnit cWidth = contentWidth();
 
98
    LayoutUnit cHeight = contentHeight();
 
99
    if (!cWidth || !cHeight)
 
100
        return;
 
101
 
 
102
    RefPtr<Image> image = m_snapshotResource->image();
 
103
    if (!image || image->isNull())
 
104
        return;
 
105
 
 
106
    GraphicsContext* context = paintInfo.context;
 
107
#if PLATFORM(MAC)
 
108
    if (style()->highlight() != nullAtom && !context->paintingDisabled())
 
109
        paintCustomHighlight(toPoint(paintOffset - location()), style()->highlight(), true);
 
110
#endif
 
111
 
 
112
    LayoutSize contentSize(cWidth, cHeight);
 
113
    LayoutPoint contentLocation = paintOffset;
 
114
    contentLocation.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
 
115
 
 
116
    LayoutRect rect(contentLocation, contentSize);
 
117
    IntRect alignedRect = pixelSnappedIntRect(rect);
 
118
    if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
 
119
        return;
 
120
 
 
121
    bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), image.get(), alignedRect.size());
 
122
    context->drawImage(image.get(), style()->colorSpace(), alignedRect, CompositeSourceOver, shouldRespectImageOrientation(), useLowQualityScaling);
 
123
}
 
124
 
 
125
static Image* startButtonImage()
 
126
{
 
127
    static Image* buttonImage = Image::loadPlatformResource("startButton").leakRef();
 
128
    return buttonImage;
 
129
}
 
130
 
 
131
static Image* startButtonPressedImage()
 
132
{
 
133
    static Image* buttonImage = Image::loadPlatformResource("startButtonPressed").leakRef();
 
134
    return buttonImage;
 
135
}
 
136
 
 
137
void RenderSnapshottedPlugIn::paintButton(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 
138
{
 
139
    LayoutRect contentRect = contentBoxRect();
 
140
    if (contentRect.isEmpty())
 
141
        return;
 
142
 
 
143
    Image* buttonImage = startButtonImage();
 
144
    if (plugInImageElement()->active()) {
 
145
        if (m_isMouseInButtonRect)
 
146
            buttonImage = startButtonPressedImage();
 
147
    } else if (!plugInImageElement()->hovered())
 
148
        return;
 
149
 
 
150
    LayoutPoint contentLocation = paintOffset + contentRect.maxXMaxYCorner() - buttonImage->size() - LayoutSize(startButtonPadding, startButtonPadding);
 
151
    paintInfo.context->drawImage(buttonImage, ColorSpaceDeviceRGB, roundedIntPoint(contentLocation), buttonImage->rect());
 
152
}
 
153
 
 
154
void RenderSnapshottedPlugIn::repaintButton()
 
155
{
 
156
    // FIXME: This is unfortunate. We should just repaint the button.
 
157
    repaint();
 
158
}
 
159
 
 
160
CursorDirective RenderSnapshottedPlugIn::getCursor(const LayoutPoint& point, Cursor& overrideCursor) const
 
161
{
 
162
    if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
 
163
        overrideCursor = handCursor();
 
164
        return SetCursor;
 
165
    }
 
166
    return RenderEmbeddedObject::getCursor(point, overrideCursor);
 
167
}
 
168
 
 
169
void RenderSnapshottedPlugIn::handleEvent(Event* event)
 
170
{
 
171
    if (!event->isMouseEvent())
 
172
        return;
 
173
 
 
174
    MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
 
175
 
 
176
    if (event->type() == eventNames().clickEvent && mouseEvent->button() == LeftButton) {
 
177
        if (m_isMouseInButtonRect)
 
178
            plugInImageElement()->setDisplayState(HTMLPlugInElement::Playing);
 
179
        else {
 
180
            plugInImageElement()->setDisplayState(HTMLPlugInElement::PlayingWithPendingMouseClick);
 
181
            plugInImageElement()->setPendingClickEvent(mouseEvent);
 
182
        }
 
183
        if (widget()) {
 
184
            if (Frame* frame = document()->frame())
 
185
                frame->loader()->client()->recreatePlugin(widget());
 
186
            repaint();
 
187
        }
 
188
        event->setDefaultHandled();
 
189
    } else if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent)
 
190
        repaintButton();
 
191
    else if (event->type() == eventNames().mousedownEvent) {
 
192
        bool isMouseInButtonRect = m_buttonRect.contains(IntPoint(mouseEvent->offsetX(), mouseEvent->offsetY()));
 
193
        if (isMouseInButtonRect != m_isMouseInButtonRect) {
 
194
            m_isMouseInButtonRect = isMouseInButtonRect;
 
195
            repaintButton();
 
196
        }
 
197
    }
 
198
}
 
199
 
 
200
void RenderSnapshottedPlugIn::layout()
 
201
{
 
202
    RenderEmbeddedObject::layout();
 
203
    if (plugInImageElement()->displayState() < HTMLPlugInElement::Playing) {
 
204
        LayoutRect rect = contentBoxRect();
 
205
        int width = rect.width();
 
206
        int height = rect.height();
 
207
        if (!width || !height || (width <= autoStartPlugInSizeThresholdWidth && height <= autoStartPlugInSizeThresholdHeight))
 
208
            plugInImageElement()->setDisplayState(HTMLPlugInElement::Playing);
 
209
    }
 
210
 
 
211
    LayoutSize buttonSize = startButtonImage()->size();
 
212
    m_buttonRect = LayoutRect(contentBoxRect().maxXMaxYCorner() - LayoutSize(startButtonPadding, startButtonPadding) - buttonSize, buttonSize);
 
213
}
 
214
 
 
215
} // namespace WebCore