2
* Copyright (C) 2012 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
27
#include "RenderSnapshottedPlugIn.h"
30
#include "FrameLoaderClient.h"
31
#include "FrameView.h"
33
#include "HTMLPlugInImageElement.h"
34
#include "MouseEvent.h"
35
#include "PaintInfo.h"
40
static const int autoStartPlugInSizeThresholdWidth = 1;
41
static const int autoStartPlugInSizeThresholdHeight = 1;
42
static const int startButtonPadding = 10;
44
RenderSnapshottedPlugIn::RenderSnapshottedPlugIn(HTMLPlugInImageElement* element)
45
: RenderEmbeddedObject(element)
46
, m_snapshotResource(RenderImageResource::create())
47
, m_isMouseInButtonRect(false)
49
m_snapshotResource->initialize(this);
52
RenderSnapshottedPlugIn::~RenderSnapshottedPlugIn()
54
ASSERT(m_snapshotResource);
55
m_snapshotResource->shutdown();
58
HTMLPlugInImageElement* RenderSnapshottedPlugIn::plugInImageElement() const
60
return static_cast<HTMLPlugInImageElement*>(node());
63
void RenderSnapshottedPlugIn::updateSnapshot(PassRefPtr<Image> image)
65
// Zero-size plugins will have no image.
69
m_snapshotResource->setCachedImage(new CachedImage(image.get()));
73
void RenderSnapshottedPlugIn::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
75
if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
76
RenderReplaced::paint(paintInfo, paintOffset);
80
RenderEmbeddedObject::paint(paintInfo, paintOffset);
83
void RenderSnapshottedPlugIn::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
85
if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
86
paintReplacedSnapshot(paintInfo, paintOffset);
87
paintButton(paintInfo, paintOffset);
91
RenderEmbeddedObject::paintReplaced(paintInfo, paintOffset);
94
void RenderSnapshottedPlugIn::paintReplacedSnapshot(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
96
// This code should be similar to RenderImage::paintReplaced() and RenderImage::paintIntoRect().
97
LayoutUnit cWidth = contentWidth();
98
LayoutUnit cHeight = contentHeight();
99
if (!cWidth || !cHeight)
102
RefPtr<Image> image = m_snapshotResource->image();
103
if (!image || image->isNull())
106
GraphicsContext* context = paintInfo.context;
108
if (style()->highlight() != nullAtom && !context->paintingDisabled())
109
paintCustomHighlight(toPoint(paintOffset - location()), style()->highlight(), true);
112
LayoutSize contentSize(cWidth, cHeight);
113
LayoutPoint contentLocation = paintOffset;
114
contentLocation.move(borderLeft() + paddingLeft(), borderTop() + paddingTop());
116
LayoutRect rect(contentLocation, contentSize);
117
IntRect alignedRect = pixelSnappedIntRect(rect);
118
if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
121
bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), image.get(), alignedRect.size());
122
context->drawImage(image.get(), style()->colorSpace(), alignedRect, CompositeSourceOver, shouldRespectImageOrientation(), useLowQualityScaling);
125
static Image* startButtonImage()
127
static Image* buttonImage = Image::loadPlatformResource("startButton").leakRef();
131
static Image* startButtonPressedImage()
133
static Image* buttonImage = Image::loadPlatformResource("startButtonPressed").leakRef();
137
void RenderSnapshottedPlugIn::paintButton(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
139
LayoutRect contentRect = contentBoxRect();
140
if (contentRect.isEmpty())
143
Image* buttonImage = startButtonImage();
144
if (plugInImageElement()->active()) {
145
if (m_isMouseInButtonRect)
146
buttonImage = startButtonPressedImage();
147
} else if (!plugInImageElement()->hovered())
150
LayoutPoint contentLocation = paintOffset + contentRect.maxXMaxYCorner() - buttonImage->size() - LayoutSize(startButtonPadding, startButtonPadding);
151
paintInfo.context->drawImage(buttonImage, ColorSpaceDeviceRGB, roundedIntPoint(contentLocation), buttonImage->rect());
154
void RenderSnapshottedPlugIn::repaintButton()
156
// FIXME: This is unfortunate. We should just repaint the button.
160
CursorDirective RenderSnapshottedPlugIn::getCursor(const LayoutPoint& point, Cursor& overrideCursor) const
162
if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
163
overrideCursor = handCursor();
166
return RenderEmbeddedObject::getCursor(point, overrideCursor);
169
void RenderSnapshottedPlugIn::handleEvent(Event* event)
171
if (!event->isMouseEvent())
174
MouseEvent* mouseEvent = static_cast<MouseEvent*>(event);
176
if (event->type() == eventNames().clickEvent && mouseEvent->button() == LeftButton) {
177
if (m_isMouseInButtonRect)
178
plugInImageElement()->setDisplayState(HTMLPlugInElement::Playing);
180
plugInImageElement()->setDisplayState(HTMLPlugInElement::PlayingWithPendingMouseClick);
181
plugInImageElement()->setPendingClickEvent(mouseEvent);
184
if (Frame* frame = document()->frame())
185
frame->loader()->client()->recreatePlugin(widget());
188
event->setDefaultHandled();
189
} else if (event->type() == eventNames().mouseoverEvent || event->type() == eventNames().mouseoutEvent)
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;
200
void RenderSnapshottedPlugIn::layout()
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);
211
LayoutSize buttonSize = startButtonImage()->size();
212
m_buttonRect = LayoutRect(contentBoxRect().maxXMaxYCorner() - LayoutSize(startButtonPadding, startButtonPadding) - buttonSize, buttonSize);
215
} // namespace WebCore