Modified: trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp (139700 => 139701)
--- trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp 2013-01-15 02:08:38 UTC (rev 139700)
+++ trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.cpp 2013-01-15 02:44:55 UTC (rev 139701)
@@ -29,14 +29,18 @@
#include "Chrome.h"
#include "ChromeClient.h"
#include "Cursor.h"
+#include "FEGaussianBlur.h"
+#include "Filter.h"
#include "FrameLoaderClient.h"
#include "FrameView.h"
#include "Gradient.h"
#include "HTMLPlugInImageElement.h"
+#include "ImageBuffer.h"
#include "MouseEvent.h"
#include "Page.h"
#include "PaintInfo.h"
#include "Path.h"
+#include "SourceGraphic.h"
namespace WebCore {
@@ -46,7 +50,53 @@
static const int startLabelInset = 20; // But the label is inset from its box also. FIXME: This will be removed when we go to a ShadowDOM approach.
static const double showLabelAfterMouseOverDelay = 1;
static const double showLabelAutomaticallyDelay = 3;
+static const int snapshotLabelBlurRadius = 5;
+class RenderSnapshottedPlugInBlurFilter : public Filter {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ static PassRefPtr<RenderSnapshottedPlugInBlurFilter> create(int radius)
+ {
+ return adoptRef(new RenderSnapshottedPlugInBlurFilter(radius));
+ }
+
+ void setSourceImageRect(const FloatRect& r)
+ {
+ m_sourceImageRect = r;
+ m_filterRegion = r;
+ m_sourceGraphic->setMaxEffectRect(r);
+ m_blur->setMaxEffectRect(r);
+ }
+ virtual FloatRect sourceImageRect() const { return m_sourceImageRect; }
+ virtual FloatRect filterRegion() const { return m_filterRegion; }
+
+ void apply();
+ ImageBuffer* output() const { return m_blur->asImageBuffer(); }
+
+private:
+ RenderSnapshottedPlugInBlurFilter(int radius);
+
+ FloatRect m_sourceImageRect;
+ FloatRect m_filterRegion;
+ RefPtr<SourceGraphic> m_sourceGraphic;
+ RefPtr<FEGaussianBlur> m_blur;
+};
+
+RenderSnapshottedPlugInBlurFilter::RenderSnapshottedPlugInBlurFilter(int radius)
+{
+ setFilterResolution(FloatSize(1, 1));
+ m_sourceGraphic = SourceGraphic::create(this);
+ m_blur = FEGaussianBlur::create(this, radius, radius);
+ m_blur->inputEffects().append(m_sourceGraphic);
+}
+
+void RenderSnapshottedPlugInBlurFilter::apply()
+{
+ m_sourceGraphic->clearResult();
+ m_blur->clearResult();
+ m_blur->apply();
+}
+
RenderSnapshottedPlugIn::RenderSnapshottedPlugIn(HTMLPlugInImageElement* element)
: RenderEmbeddedObject(element)
, m_snapshotResource(RenderImageResource::create())
@@ -55,14 +105,18 @@
, m_showedLabelOnce(false)
, m_showReason(UserMousedOver)
, m_showLabelDelayTimer(this, &RenderSnapshottedPlugIn::showLabelDelayTimerFired)
+ , m_snapshotResourceForLabel(RenderImageResource::create())
{
m_snapshotResource->initialize(this);
+ m_snapshotResourceForLabel->initialize(this);
}
RenderSnapshottedPlugIn::~RenderSnapshottedPlugIn()
{
ASSERT(m_snapshotResource);
m_snapshotResource->shutdown();
+ ASSERT(m_snapshotResourceForLabel);
+ m_snapshotResourceForLabel->shutdown();
}
HTMLPlugInImageElement* RenderSnapshottedPlugIn::plugInImageElement() const
@@ -76,6 +130,11 @@
if (!image)
return;
+ // We may have stored a version of this snapshot to use when showing the
+ // label. Invalidate it now and it will be regenerated later.
+ if (m_snapshotResourceForLabel->hasImage())
+ m_snapshotResourceForLabel->setCachedImage(0);
+
m_snapshotResource->setCachedImage(new CachedImage(image.get()));
repaint();
if (m_shouldShowLabelAutomatically)
@@ -95,27 +154,23 @@
void RenderSnapshottedPlugIn::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
if (plugInImageElement()->displayState() < HTMLPlugInElement::PlayingWithPendingMouseClick) {
- paintReplacedSnapshot(paintInfo, paintOffset);
if (m_shouldShowLabel)
- paintLabel(paintInfo, paintOffset);
+ paintReplacedSnapshotWithLabel(paintInfo, paintOffset);
+ else
+ paintReplacedSnapshot(paintInfo, paintOffset);
return;
}
RenderEmbeddedObject::paintReplaced(paintInfo, paintOffset);
}
-void RenderSnapshottedPlugIn::paintReplacedSnapshot(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+void RenderSnapshottedPlugIn::paintSnapshot(Image* image, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
- // This code should be similar to RenderImage::paintReplaced() and RenderImage::paintIntoRect().
LayoutUnit cWidth = contentWidth();
LayoutUnit cHeight = contentHeight();
if (!cWidth || !cHeight)
return;
- RefPtr<Image> image = m_snapshotResource->image();
- if (!image || image->isNull())
- return;
-
GraphicsContext* context = paintInfo.context;
#if PLATFORM(MAC)
if (style()->highlight() != nullAtom && !context->paintingDisabled())
@@ -131,10 +186,19 @@
if (alignedRect.width() <= 0 || alignedRect.height() <= 0)
return;
- bool useLowQualityScaling = shouldPaintAtLowQuality(context, image.get(), image.get(), alignedRect.size());
- context->drawImage(image.get(), style()->colorSpace(), alignedRect, CompositeSourceOver, shouldRespectImageOrientation(), useLowQualityScaling);
+ bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size());
+ context->drawImage(image, style()->colorSpace(), alignedRect, CompositeSourceOver, shouldRespectImageOrientation(), useLowQualityScaling);
}
+void RenderSnapshottedPlugIn::paintReplacedSnapshot(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+ RefPtr<Image> image = m_snapshotResource->image();
+ if (!image || image->isNull())
+ return;
+
+ paintSnapshot(image.get(), paintInfo, paintOffset);
+}
+
Image* RenderSnapshottedPlugIn::startLabelImage(LabelSize size) const
{
static Image* labelImages[2] = { 0, 0 };
@@ -153,8 +217,25 @@
return labelImages[arrayIndex];
}
-void RenderSnapshottedPlugIn::paintLabel(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+static PassRefPtr<Image> snapshottedPluginImageForLabelDisplay(PassRefPtr<Image> snapshot, const LayoutRect& blurRegion)
{
+ OwnPtr<ImageBuffer> snapshotBuffer = ImageBuffer::create(snapshot->size());
+ snapshotBuffer->context()->drawImage(snapshot.get(), ColorSpaceDeviceRGB, IntPoint(0, 0));
+
+ OwnPtr<ImageBuffer> blurBuffer = ImageBuffer::create(roundedIntSize(blurRegion.size()));
+ blurBuffer->context()->drawImage(snapshot.get(), ColorSpaceDeviceRGB, IntPoint(-blurRegion.x(), -blurRegion.y()));
+
+ RefPtr<RenderSnapshottedPlugInBlurFilter> blurFilter = RenderSnapshottedPlugInBlurFilter::create(snapshotLabelBlurRadius);
+ blurFilter->setSourceImage(blurBuffer.release());
+ blurFilter->setSourceImageRect(FloatRect(FloatPoint(), blurRegion.size()));
+ blurFilter->apply();
+
+ snapshotBuffer->context()->drawImageBuffer(blurFilter->output(), ColorSpaceDeviceRGB, roundedIntPoint(blurRegion.location()));
+ return snapshotBuffer->copyImage();
+}
+
+void RenderSnapshottedPlugIn::paintReplacedSnapshotWithLabel(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
if (contentBoxRect().isEmpty())
return;
@@ -179,6 +260,19 @@
if (!labelImage)
return;
+ RefPtr<Image> snapshotImage = m_snapshotResource->image();
+ if (!snapshotImage || snapshotImage->isNull())
+ return;
+
+ RefPtr<Image> blurredSnapshotImage = m_snapshotResourceForLabel->image();
+ if (!blurredSnapshotImage || blurredSnapshotImage->isNull()) {
+ blurredSnapshotImage = snapshottedPluginImageForLabelDisplay(snapshotImage, labelRect);
+ m_snapshotResourceForLabel->setCachedImage(new CachedImage(blurredSnapshotImage.get()));
+ }
+ snapshotImage = blurredSnapshotImage;
+
+ paintSnapshot(snapshotImage.get(), paintInfo, paintOffset);
+
// Remember that the labelRect includes the label inset, so we need to adjust for it.
paintInfo.context->drawImage(labelImage, ColorSpaceDeviceRGB,
IntRect(roundedIntPoint(paintOffset + labelRect.location() - IntSize(startLabelInset, startLabelInset)),
Modified: trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h (139700 => 139701)
--- trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h 2013-01-15 02:08:38 UTC (rev 139700)
+++ trunk/Source/WebCore/rendering/RenderSnapshottedPlugIn.h 2013-01-15 02:44:55 UTC (rev 139701)
@@ -63,7 +63,8 @@
virtual void paintReplaced(PaintInfo&, const LayoutPoint&) OVERRIDE;
void paintReplacedSnapshot(PaintInfo&, const LayoutPoint&);
- void paintLabel(PaintInfo&, const LayoutPoint&);
+ void paintReplacedSnapshotWithLabel(PaintInfo&, const LayoutPoint&);
+ void paintSnapshot(Image*, PaintInfo&, const LayoutPoint&);
void repaintLabel();
LayoutRect tryToFitStartLabel(LabelSize, const LayoutRect& contentBox) const;
@@ -82,6 +83,7 @@
bool m_showedLabelOnce;
ShowReason m_showReason;
Timer<RenderSnapshottedPlugIn> m_showLabelDelayTimer;
+ OwnPtr<RenderImageResource> m_snapshotResourceForLabel;
};
inline RenderSnapshottedPlugIn* toRenderSnapshottedPlugIn(RenderObject* object)