summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/graphics
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-09-30 15:42:16 +0100
committerSteve Block <steveblock@google.com>2010-10-07 10:59:29 +0100
commitbec39347bb3bb5bf1187ccaf471d26247f28b585 (patch)
tree56bdc4c2978fbfd3d79d0d36d5d6c640ecc09cc8 /WebCore/platform/graphics
parent90b7966e7815b262cd19ac25f03aaad9b21fdc06 (diff)
downloadexternal_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.zip
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.gz
external_webkit-bec39347bb3bb5bf1187ccaf471d26247f28b585.tar.bz2
Merge WebKit at r68651 : Initial merge by git.
Change-Id: I3d6bff59f17eedd6722723354f386fec9be8ad12
Diffstat (limited to 'WebCore/platform/graphics')
-rw-r--r--WebCore/platform/graphics/Color.cpp3
-rw-r--r--WebCore/platform/graphics/ContextShadow.cpp (renamed from WebCore/platform/graphics/qt/ContextShadow.cpp)208
-rw-r--r--WebCore/platform/graphics/ContextShadow.h (renamed from WebCore/platform/graphics/qt/ContextShadow.h)82
-rw-r--r--WebCore/platform/graphics/Font.h4
-rw-r--r--WebCore/platform/graphics/GlyphPageTreeNode.cpp1
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h6
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.cpp28
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h10
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.cpp6
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h13
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp6
-rw-r--r--WebCore/platform/graphics/WidthIterator.cpp33
-rw-r--r--WebCore/platform/graphics/brew/ImageBrew.cpp56
-rw-r--r--WebCore/platform/graphics/cairo/CairoUtilities.cpp59
-rw-r--r--WebCore/platform/graphics/cairo/CairoUtilities.h39
-rw-r--r--WebCore/platform/graphics/cairo/ContextShadowCairo.cpp122
-rw-r--r--WebCore/platform/graphics/cairo/FontCacheFreeType.cpp133
-rw-r--r--WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp57
-rw-r--r--WebCore/platform/graphics/cairo/FontCustomPlatformData.h12
-rw-r--r--WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp157
-rw-r--r--WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h9
-rw-r--r--WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp3
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp33
-rw-r--r--WebCore/platform/graphics/cairo/PathCairo.cpp18
-rw-r--r--WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp13
-rw-r--r--WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h4
-rw-r--r--WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp14
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp47
-rw-r--r--WebCore/platform/graphics/chromium/ContentLayerChromium.cpp22
-rw-r--r--WebCore/platform/graphics/chromium/ContentLayerChromium.h3
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp18
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp8
-rw-r--r--WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp2
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp11
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.h8
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp71
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.h13
-rw-r--r--WebCore/platform/graphics/chromium/VDMXParser.cpp1
-rw-r--r--WebCore/platform/graphics/chromium/VideoFrameChromium.cpp47
-rw-r--r--WebCore/platform/graphics/chromium/VideoFrameChromium.h17
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.cpp399
-rw-r--r--WebCore/platform/graphics/chromium/VideoLayerChromium.h67
-rw-r--r--WebCore/platform/graphics/filters/DistantLightSource.h62
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.cpp46
-rw-r--r--WebCore/platform/graphics/filters/FEBlend.h79
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.cpp44
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.h83
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.cpp50
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.h161
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.cpp68
-rw-r--r--WebCore/platform/graphics/filters/FEComposite.h45
-rw-r--r--WebCore/platform/graphics/filters/FEConvolveMatrix.cpp471
-rw-r--r--WebCore/platform/graphics/filters/FEConvolveMatrix.h118
-rw-r--r--WebCore/platform/graphics/filters/FEDiffuseLighting.cpp126
-rw-r--r--WebCore/platform/graphics/filters/FEDiffuseLighting.h68
-rw-r--r--WebCore/platform/graphics/filters/FEDisplacementMap.cpp171
-rw-r--r--WebCore/platform/graphics/filters/FEDisplacementMap.h70
-rw-r--r--WebCore/platform/graphics/filters/FEFlood.cpp91
-rw-r--r--WebCore/platform/graphics/filters/FEFlood.h58
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.cpp46
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.h47
-rw-r--r--WebCore/platform/graphics/filters/FELighting.cpp270
-rw-r--r--WebCore/platform/graphics/filters/FELighting.h96
-rw-r--r--WebCore/platform/graphics/filters/FEMerge.cpp82
-rw-r--r--WebCore/platform/graphics/filters/FEMerge.h49
-rw-r--r--WebCore/platform/graphics/filters/FEMorphology.cpp188
-rw-r--r--WebCore/platform/graphics/filters/FEMorphology.h66
-rw-r--r--WebCore/platform/graphics/filters/FEOffset.cpp112
-rw-r--r--WebCore/platform/graphics/filters/FEOffset.h57
-rw-r--r--WebCore/platform/graphics/filters/FESpecularLighting.cpp138
-rw-r--r--WebCore/platform/graphics/filters/FESpecularLighting.h69
-rw-r--r--WebCore/platform/graphics/filters/FETile.cpp106
-rw-r--r--WebCore/platform/graphics/filters/FETile.h50
-rw-r--r--WebCore/platform/graphics/filters/FETurbulence.cpp386
-rw-r--r--WebCore/platform/graphics/filters/FETurbulence.h103
-rw-r--r--WebCore/platform/graphics/filters/Filter.h26
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.cpp6
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.h6
-rw-r--r--WebCore/platform/graphics/filters/ImageBufferFilter.cpp28
-rw-r--r--WebCore/platform/graphics/filters/ImageBufferFilter.h28
-rw-r--r--WebCore/platform/graphics/filters/LightSource.cpp169
-rw-r--r--WebCore/platform/graphics/filters/LightSource.h84
-rw-r--r--WebCore/platform/graphics/filters/PointLightSource.h59
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.cpp28
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.h63
-rw-r--r--WebCore/platform/graphics/filters/SourceGraphic.cpp28
-rw-r--r--WebCore/platform/graphics/filters/SourceGraphic.h63
-rw-r--r--WebCore/platform/graphics/filters/SpotLightSource.h72
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.cpp275
-rw-r--r--WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h268
-rw-r--r--WebCore/platform/graphics/gpu/Texture.cpp2
-rw-r--r--WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm4
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp4
-rw-r--r--WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h4
-rw-r--r--WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp (renamed from WebCore/platform/graphics/gtk/CairoUtilities.cpp)2
-rw-r--r--WebCore/platform/graphics/gtk/GdkCairoUtilities.h (renamed from WebCore/platform/graphics/gtk/CairoUtilities.h)6
-rw-r--r--WebCore/platform/graphics/gtk/ImageBufferGtk.cpp2
-rw-r--r--WebCore/platform/graphics/gtk/ImageGtk.cpp2
-rw-r--r--WebCore/platform/graphics/mac/ComplexTextController.cpp22
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h67
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm243
-rw-r--r--WebCore/platform/graphics/mac/ImageMac.mm1
-rw-r--r--WebCore/platform/graphics/qt/ContextShadowQt.cpp159
-rw-r--r--WebCore/platform/graphics/qt/FontQt.cpp42
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp52
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp88
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h6
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp135
-rw-r--r--WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h8
-rw-r--r--WebCore/platform/graphics/skia/FontCustomPlatformData.cpp12
-rw-r--r--WebCore/platform/graphics/skia/FontCustomPlatformData.h6
-rw-r--r--WebCore/platform/graphics/skia/GradientSkia.cpp2
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp6
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp18
-rw-r--r--WebCore/platform/graphics/skia/PatternSkia.cpp2
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp39
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h1
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.cpp2
-rw-r--r--WebCore/platform/graphics/wince/PlatformPathWinCE.cpp1
135 files changed, 6227 insertions, 1515 deletions
diff --git a/WebCore/platform/graphics/Color.cpp b/WebCore/platform/graphics/Color.cpp
index 80c8286..f28d51c 100644
--- a/WebCore/platform/graphics/Color.cpp
+++ b/WebCore/platform/graphics/Color.cpp
@@ -26,13 +26,12 @@
#include "config.h"
#include "Color.h"
+#include "HashTools.h"
#include "PlatformString.h"
#include <math.h>
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
-#include "ColorData.cpp"
-
using namespace std;
using namespace WTF;
diff --git a/WebCore/platform/graphics/qt/ContextShadow.cpp b/WebCore/platform/graphics/ContextShadow.cpp
index 4609923..1007962 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.cpp
+++ b/WebCore/platform/graphics/ContextShadow.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Sencha, Inc.
+ * Copyright (C) 2010 Igalia S.L.
*
* All rights reserved.
*
@@ -28,115 +29,50 @@
#include "config.h"
#include "ContextShadow.h"
-#include <QTimerEvent>
+#include <wtf/MathExtras.h>
#include <wtf/Noncopyable.h>
-namespace WebCore {
-
-// ContextShadow needs a scratch image as the buffer for the blur filter.
-// Instead of creating and destroying the buffer for every operation,
-// we create a buffer which will be automatically purged via a timer.
-
-class ShadowBuffer: public QObject {
-public:
- ShadowBuffer(QObject* parent = 0);
-
- QImage* scratchImage(const QSize& size);
-
- void schedulePurge();
-
-protected:
- void timerEvent(QTimerEvent* event);
-
-private:
- QImage image;
- int timerId;
-};
-
-ShadowBuffer::ShadowBuffer(QObject* parent)
- : QObject(parent)
- , timerId(0)
-{
-}
-
-QImage* ShadowBuffer::scratchImage(const QSize& size)
-{
- int width = size.width();
- int height = size.height();
-
- // We do not need to recreate the buffer if the buffer is reasonably
- // larger than the requested size. However, if the requested size is
- // much smaller than our buffer, reduce our buffer so that we will not
- // keep too many allocated pixels for too long.
- if (!image.isNull() && (image.width() > width) && (image.height() > height))
- if (((2 * width) > image.width()) && ((2 * height) > image.height())) {
- image.fill(Qt::transparent);
- return &image;
- }
-
- // Round to the nearest 32 pixels so we do not grow the buffer everytime
- // there is larger request by 1 pixel.
- width = (1 + (width >> 5)) << 5;
- height = (1 + (height >> 5)) << 5;
-
- image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
- image.fill(Qt::transparent);
- return &image;
-}
-
-void ShadowBuffer::schedulePurge()
-{
- static const double BufferPurgeDelay = 2; // seconds
- killTimer(timerId);
- timerId = startTimer(BufferPurgeDelay * 1000);
-}
-
-void ShadowBuffer::timerEvent(QTimerEvent* event)
-{
- if (event->timerId() == timerId) {
- killTimer(timerId);
- image = QImage();
- }
- QObject::timerEvent(event);
-}
+using WTF::min;
+using WTF::max;
-Q_GLOBAL_STATIC(ShadowBuffer, scratchShadowBuffer)
+namespace WebCore {
ContextShadow::ContextShadow()
- : type(NoShadow)
- , blurRadius(0)
+ : m_type(NoShadow)
+ , m_blurRadius(0)
{
}
-ContextShadow::ContextShadow(const QColor& c, float r, qreal dx, qreal dy)
- : color(c)
- , blurRadius(qRound(r))
- , offset(dx, dy)
+ContextShadow::ContextShadow(const Color& color, float radius, const FloatSize& offset)
+ : m_color(color)
+ , m_blurRadius(round(radius))
+ , m_offset(offset)
{
+ // See comments in http://webkit.org/b/40793, it seems sensible
+ // to follow Skia's limit of 128 pixels of blur radius
+ m_blurRadius = min(m_blurRadius, 128);
+
// The type of shadow is decided by the blur radius, shadow offset, and shadow color.
- if (!color.isValid() || !color.alpha()) {
+ if (!m_color.isValid() || !color.alpha()) {
// Can't paint the shadow with invalid or invisible color.
- type = NoShadow;
- } else if (r > 0) {
+ m_type = NoShadow;
+ } else if (radius > 0) {
// Shadow is always blurred, even the offset is zero.
- type = BlurShadow;
- } else if (offset.isNull()) {
+ m_type = BlurShadow;
+ } else if (!m_offset.width() && !m_offset.height()) {
// Without blur and zero offset means the shadow is fully hidden.
- type = NoShadow;
+ m_type = NoShadow;
} else {
- if (color.alpha() > 0)
- type = AlphaSolidShadow;
- else
- type = OpaqueSolidShadow;
+ m_type = SolidShadow;
}
}
void ContextShadow::clear()
{
- type = NoShadow;
- color = QColor();
- blurRadius = 0;
- offset = QPointF(0, 0);
+ m_type = NoShadow;
+ m_color = Color();
+ m_blurRadius = 0;
+ m_offset = FloatSize();
}
// Instead of integer division, we use 17.15 for fixed-point division.
@@ -146,27 +82,22 @@ static const int BlurSumShift = 15;
// As noted in the SVG filter specification, running box blur 3x
// approximates a real gaussian blur nicely.
-void shadowBlur(QImage& image, int radius, const QColor& shadowColor)
+void ContextShadow::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride)
{
- // See comments in http://webkit.org/b/40793, it seems sensible
- // to follow Skia's limit of 128 pixels for the blur radius.
- if (radius > 128)
- radius = 128;
-
int channels[4] = { 3, 0, 1, 3 };
- int dmax = radius >> 1;
- int dmin = dmax - 1 + (radius & 1);
+ int dmax = m_blurRadius >> 1;
+ int dmin = dmax - 1 + (m_blurRadius & 1);
if (dmin < 0)
dmin = 0;
// Two stages: horizontal and vertical
for (int k = 0; k < 2; ++k) {
- unsigned char* pixels = image.bits();
- int stride = (!k) ? 4 : image.bytesPerLine();
- int delta = (!k) ? image.bytesPerLine() : 4;
- int jfinal = (!k) ? image.height() : image.width();
- int dim = (!k) ? image.width() : image.height();
+ unsigned char* pixels = imageData;
+ int stride = (!k) ? 4 : rowStride;
+ int delta = (!k) ? rowStride : 4;
+ int jfinal = (!k) ? size.height() : size.width();
+ int dim = (!k) ? size.width() : size.height();
for (int j = 0; j < jfinal; ++j, pixels += delta) {
@@ -213,74 +144,31 @@ void shadowBlur(QImage& image, int radius, const QColor& shadowColor)
}
}
}
-
- // "Colorize" with the right shadow color.
- QPainter p(&image);
- p.setCompositionMode(QPainter::CompositionMode_SourceIn);
- p.fillRect(image.rect(), shadowColor.rgb());
- p.end();
}
-QPainter* ContextShadow::beginShadowLayer(QPainter* p, const QRectF &rect)
+void ContextShadow::calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect)
{
- // We expand the area by the blur radius * 2 to give extra space
- // for the blur transition.
- int extra = (type == BlurShadow) ? blurRadius * 2 : 0;
-
- QRectF shadowRect = rect.translated(offset);
- QRectF bufferRect = shadowRect.adjusted(-extra, -extra, extra, extra);
- m_layerRect = bufferRect.toAlignedRect();
+ // Calculate the destination of the blurred layer.
+ FloatRect destinationRect(layerArea);
+ destinationRect.move(m_offset);
+ m_layerRect = enclosingIntRect(destinationRect);
- QRect clipRect;
- if (p->hasClipping())
-#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
- clipRect = p->clipBoundingRect();
-#else
- clipRect = p->clipRegion().boundingRect();
-#endif
- else
- clipRect = p->transform().inverted().mapRect(p->window());
+ // We expand the area by the blur radius * 2 to give extra space for the blur transition.
+ m_layerRect.inflate((m_type == BlurShadow) ? ceil(m_blurRadius * 2) : 0);
if (!clipRect.contains(m_layerRect)) {
-
// No need to have the buffer larger than the clip.
- m_layerRect = m_layerRect.intersected(clipRect);
+ m_layerRect.intersect(clipRect);
+
+ // If we are totally outside the clip region, we aren't painting at all.
if (m_layerRect.isEmpty())
- return 0;
+ return;
// We adjust again because the pixels at the borders are still
// potentially affected by the pixels outside the buffer.
- if (type == BlurShadow)
- m_layerRect.adjust(-extra, -extra, extra, extra);
+ if (m_type == BlurShadow)
+ m_layerRect.inflate((m_type == BlurShadow) ? ceil(m_blurRadius * 2) : 0);
}
-
- ShadowBuffer* shadowBuffer = scratchShadowBuffer();
- QImage* shadowImage = shadowBuffer->scratchImage(m_layerRect.size());
- m_layerImage = QImage(*shadowImage);
-
- m_layerPainter = new QPainter;
- m_layerPainter->begin(&m_layerImage);
- m_layerPainter->setFont(p->font());
- m_layerPainter->translate(offset);
-
- // The origin is now the top left corner of the scratch image.
- m_layerPainter->translate(-m_layerRect.topLeft());
-
- return m_layerPainter;
}
-void ContextShadow::endShadowLayer(QPainter* p)
-{
- m_layerPainter->end();
- delete m_layerPainter;
- m_layerPainter = 0;
-
- if (type == BlurShadow)
- shadowBlur(m_layerImage, blurRadius, color);
-
- p->drawImage(m_layerRect.topLeft(), m_layerImage);
-
- scratchShadowBuffer()->schedulePurge();
-}
-
-}
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/qt/ContextShadow.h b/WebCore/platform/graphics/ContextShadow.h
index 7140340..ede9336 100644
--- a/WebCore/platform/graphics/qt/ContextShadow.h
+++ b/WebCore/platform/graphics/ContextShadow.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Sencha, Inc.
+ * Copyright (C) 2010 Igalia S.L.
*
* All rights reserved.
*
@@ -28,7 +29,22 @@
#ifndef ContextShadow_h
#define ContextShadow_h
-#include <QPainter>
+#include "Color.h"
+#include "FloatRect.h"
+#include "IntRect.h"
+#include "RefCounted.h"
+
+#if PLATFORM(CAIRO)
+typedef struct _cairo cairo_t;
+typedef struct _cairo_surface cairo_surface_t;
+typedef cairo_surface_t* PlatformImage;
+typedef cairo_t* PlatformContext;
+#elif PLATFORM(QT)
+#include <QImage>
+class QPainter;
+typedef QImage PlatformImage;
+typedef QPainter* PlatformContext;
+#endif
namespace WebCore {
@@ -44,49 +60,57 @@ class ContextShadow {
public:
enum {
NoShadow,
- OpaqueSolidShadow,
- AlphaSolidShadow,
+ SolidShadow,
BlurShadow
- } type;
+ } m_type;
- QColor color;
- int blurRadius;
- QPointF offset;
+ Color m_color;
+ int m_blurRadius;
+ FloatSize m_offset;
ContextShadow();
- ContextShadow(const QColor& c, float r, qreal dx, qreal dy);
+ ContextShadow(const Color&, float radius, const FloatSize& offset);
void clear();
// The pair beginShadowLayer and endShadowLayer creates a temporary image
- // where the caller can draw onto, using the returned QPainter. This
- // QPainter instance must be used only to draw between the call to
- // beginShadowLayer and endShadowLayer.
+ // where the caller can draw onto, using the returned context. This context
+ // must be used only to draw between the call to beginShadowLayer and
+ // endShadowLayer.
//
- // Note: multiple/nested shadow layer is NOT allowed.
+ // Note: multiple/nested shadow layers are NOT allowed.
//
// The current clip region will be used to optimize the size of the
- // temporary image. Thus, the original painter should not change any
- // clipping until endShadowLayer.
- // If the shadow will be completely outside the clipping region,
- // beginShadowLayer will return 0.
+ // temporary image. Thus, the original context should not change any
+ // clipping until endShadowLayer. If the shadow will be completely outside
+ // the clipping region, beginShadowLayer will return 0.
//
- // The returned QPainter will have the transformation matrix and clipping
- // properly initialized to start doing the painting (no need to account
- // for the shadow offset), however it will not have the same render hints,
- // pen, brush, etc as the passed QPainter. This is intentional, usually
- // shadow has different properties than the shape which casts the shadow.
+ // The returned context will have the transformation matrix and clipping
+ // properly initialized to start doing the painting (no need to account for
+ // the shadow offset), however it will not have the same render hints, pen,
+ // brush, etc as the passed context. This is intentional, usually shadows
+ // have different properties than the shapes which cast them.
//
- // Once endShadowLayer is called, the temporary image will be drawn
- // with the original painter. If blur radius is specified, the shadow
- // will be filtered first.
- QPainter* beginShadowLayer(QPainter* p, const QRectF& rect);
- void endShadowLayer(QPainter* p);
+ // Once endShadowLayer is called, the temporary image will be drawn with the
+ // original context. If blur radius is specified, the shadow will be
+ // filtered first.
+
+ PlatformContext beginShadowLayer(PlatformContext, const FloatRect& layerArea);
+ void endShadowLayer(PlatformContext);
+ static void purgeScratchBuffer();
+
+#if PLATFORM(QT)
+ QPointF offset() { return QPointF(m_offset.width(), m_offset.height()); }
+#endif
+
private:
- QRect m_layerRect;
- QImage m_layerImage;
- QPainter* m_layerPainter;
+ IntRect m_layerRect;
+ PlatformImage m_layerImage;
+ PlatformContext m_layerContext;
+
+ void blurLayerImage(unsigned char*, const IntSize& imageSize, int stride);
+ void calculateLayerBoundingRect(const FloatRect& layerArea, const IntRect& clipRect);
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/Font.h b/WebCore/platform/graphics/Font.h
index d6cf140..1a321bd 100644
--- a/WebCore/platform/graphics/Font.h
+++ b/WebCore/platform/graphics/Font.h
@@ -191,8 +191,8 @@ public:
}
FontSelector* fontSelector() const;
- static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == 0x00A0; }
- static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == 0xFFFC; }
+ static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; }
+ static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; }
static inline UChar normalizeSpaces(UChar character)
{
diff --git a/WebCore/platform/graphics/GlyphPageTreeNode.cpp b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
index dac26b3..3df14b9 100644
--- a/WebCore/platform/graphics/GlyphPageTreeNode.cpp
+++ b/WebCore/platform/graphics/GlyphPageTreeNode.cpp
@@ -171,6 +171,7 @@ void GlyphPageTreeNode::initializePage(const FontData* fontData, unsigned pageNu
buffer[i] = zeroWidthSpace;
for (i = 0x7F; i < 0xA0; i++)
buffer[i] = zeroWidthSpace;
+ buffer[softHyphen] = zeroWidthSpace;
// \n, \t, and nonbreaking space must render as a space.
buffer[(int)'\n'] = ' ';
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 7863b95..fd3bf2c 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -108,12 +108,6 @@ typedef unsigned char UInt8;
#endif
#endif
-#if PLATFORM(CHROMIUM)
-#define CanvasInterpolationQuality InterpolationMedium
-#else
-#define CanvasInterpolationQuality InterpolationDefault
-#endif
-
#if PLATFORM(QT) && defined(Q_WS_WIN)
#include <windows.h>
#endif
diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp
index 2da5862..86e9569 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -255,6 +255,14 @@ void unpackRGB8ToRGBA8(const uint8_t* source, uint8_t* destination)
destination[3] = 0xFF;
}
+void unpackARGB8ToRGBA8(const uint8_t* source, uint8_t* destination)
+{
+ destination[0] = source[1];
+ destination[1] = source[2];
+ destination[2] = source[3];
+ destination[3] = source[0];
+}
+
void unpackBGRA8ToRGBA8(const uint8_t* source, uint8_t* destination)
{
destination[0] = source[2];
@@ -316,6 +324,14 @@ void unpackRA8ToRGBA8(const uint8_t* source, uint8_t* destination)
destination[3] = source[1];
}
+void unpackAR8ToRGBA8(const uint8_t* source, uint8_t* destination)
+{
+ destination[0] = source[1];
+ destination[1] = source[1];
+ destination[2] = source[1];
+ destination[3] = source[0];
+}
+
void unpackA8ToRGBA8(const uint8_t* source, uint8_t* destination)
{
destination[0] = 0x0;
@@ -634,6 +650,12 @@ static void doPacking(const void* sourceData,
doUnpackingAndPacking<uint8_t, DestType, unpackRGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
+ case GraphicsContext3D::kSourceFormatARGB8: {
+ unsigned int sourceElementsPerPixel, sourceElementsPerRow;
+ computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
+ doUnpackingAndPacking<uint8_t, DestType, unpackARGB8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
+ break;
+ }
case GraphicsContext3D::kSourceFormatBGRA8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 4, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
@@ -670,6 +692,12 @@ static void doPacking(const void* sourceData,
doUnpackingAndPacking<uint8_t, DestType, unpackRA8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
break;
}
+ case GraphicsContext3D::kSourceFormatAR8: {
+ unsigned int sourceElementsPerPixel, sourceElementsPerRow;
+ computeIncrementParameters<uint8_t>(width, 2, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
+ doUnpackingAndPacking<uint8_t, DestType, unpackAR8ToRGBA8, packingFunc>(static_cast<const uint8_t*>(sourceData), width, height, sourceElementsPerPixel, sourceElementsPerRow, destinationData, destinationElementsPerPixel);
+ break;
+ }
case GraphicsContext3D::kSourceFormatA8: {
unsigned int sourceElementsPerPixel, sourceElementsPerRow;
computeIncrementParameters<uint8_t>(width, 1, sourceUnpackAlignment, &sourceElementsPerPixel, &sourceElementsPerRow);
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index bcb7997..a12b1c4 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -537,11 +537,13 @@ public:
kSourceFormatRGBA8,
kSourceFormatRGB8,
kSourceFormatBGRA8,
+ kSourceFormatARGB8,
kSourceFormatRGBA5551,
kSourceFormatRGBA4444,
kSourceFormatRGB565,
kSourceFormatR8,
kSourceFormatRA8,
+ kSourceFormatAR8,
kSourceFormatA8
};
@@ -834,14 +836,14 @@ public:
int m_currentWidth, m_currentHeight;
- typedef struct {
- String source;
- String log;
+#if PLATFORM(MAC)
+ typedef struct {
+ String source;
+ String log;
bool isValid;
} ShaderSourceEntry;
HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap;
-#if PLATFORM(MAC)
ANGLEWebKitBridge m_compiler;
Attributes m_attrs;
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
index b0f529b..412f06d 100644
--- a/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -246,6 +246,12 @@ void GraphicsLayer::paintGraphicsLayerContents(GraphicsContext& context, const I
m_client->paintContents(this, context, m_paintingPhase, clip);
}
+String GraphicsLayer::animationNameForTransition(AnimatedPropertyID property)
+{
+ // | is not a valid identifier character in CSS, so this can never conflict with a keyframe identifier.
+ return String::format("-|transition%c-", property);
+}
+
void GraphicsLayer::suspendAnimations(double)
{
}
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 04899f2..ad4d056 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -284,13 +284,16 @@ public:
IntRect contentsRect() const { return m_contentsRect; }
virtual void setContentsRect(const IntRect& r) { m_contentsRect = r; }
+ // Transitions are identified by a special animation name that cannot clash with a keyframe identifier.
+ static String animationNameForTransition(AnimatedPropertyID);
+
// Return true if the animation is handled by the compositing system. If this returns
// false, the animation will be run by AnimationController.
- virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*keyframesName*/, double /*timeOffset*/) { return false; }
- virtual void removeAnimationsForProperty(AnimatedPropertyID) { }
- virtual void removeAnimationsForKeyframes(const String& /* keyframesName */) { }
- virtual void pauseAnimation(const String& /* keyframesName */, double /*timeOffset*/) { }
-
+ // These methods handle both transitions and keyframe animations.
+ virtual bool addAnimation(const KeyframeValueList&, const IntSize& /*boxSize*/, const Animation*, const String& /*animationName*/, double /*timeOffset*/) { return false; }
+ virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { }
+ virtual void removeAnimation(const String& /*animationName*/) { }
+
virtual void suspendAnimations(double time);
virtual void resumeAnimations();
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index b4a669c..79c33e0 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -173,6 +173,12 @@ static Vector<MediaPlayerFactory*>& installedMediaEngines()
#if PLATFORM(WIN)
MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(addMediaEngine);
+#elif PLATFORM(QT)
+#if USE(QT_MULTIMEDIA)
+ MediaPlayerPrivateQt::registerMediaEngine(addMediaEngine);
+#else
+ MediaPlayerPrivatePhonon::registerMediaEngine(addMediaEngine);
+#endif
#elif !PLATFORM(GTK) && !PLATFORM(EFL)
// FIXME: currently all the MediaEngines are named
// MediaPlayerPrivate. This code will need an update when bug
diff --git a/WebCore/platform/graphics/WidthIterator.cpp b/WebCore/platform/graphics/WidthIterator.cpp
index ef047e8..ae58918 100644
--- a/WebCore/platform/graphics/WidthIterator.cpp
+++ b/WebCore/platform/graphics/WidthIterator.cpp
@@ -212,20 +212,29 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer)
// Force characters that are used to determine word boundaries for the rounding hack
// to be integer width, so following words will start on an integer boundary.
- if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c))
+ if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c)) {
width = ceilf(width);
- // Check to see if the next character is a "rounding hack character", if so, adjust
- // width so that the total run width will be on an integer boundary.
- if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp))
- || (m_run.applyRunRounding() && currentCharacter >= m_end)) {
- float totalWidth = widthSinceLastRounding + width;
- widthSinceLastRounding = ceilf(totalWidth);
- width += widthSinceLastRounding - totalWidth;
- m_runWidthSoFar += widthSinceLastRounding;
- widthSinceLastRounding = 0;
- } else
- widthSinceLastRounding += width;
+ // Since widthSinceLastRounding can lose precision if we include measurements for
+ // preceding whitespace, we bypass it here.
+ m_runWidthSoFar += width;
+
+ // Since this is a rounding hack character, we should have reset this sum on the previous
+ // iteration.
+ ASSERT(!widthSinceLastRounding);
+ } else {
+ // Check to see if the next character is a "rounding hack character", if so, adjust
+ // width so that the total run width will be on an integer boundary.
+ if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp))
+ || (m_run.applyRunRounding() && currentCharacter >= m_end)) {
+ float totalWidth = widthSinceLastRounding + width;
+ widthSinceLastRounding = ceilf(totalWidth);
+ width += widthSinceLastRounding - totalWidth;
+ m_runWidthSoFar += widthSinceLastRounding;
+ widthSinceLastRounding = 0;
+ } else
+ widthSinceLastRounding += width;
+ }
if (glyphBuffer)
glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width));
diff --git a/WebCore/platform/graphics/brew/ImageBrew.cpp b/WebCore/platform/graphics/brew/ImageBrew.cpp
new file mode 100644
index 0000000..f5c855d
--- /dev/null
+++ b/WebCore/platform/graphics/brew/ImageBrew.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, Company 100, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Image.h"
+
+#include "BitmapImage.h"
+#include "FileSystem.h"
+#include "SharedBuffer.h"
+
+#include <wtf/text/CString.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+PassRefPtr<Image> Image::loadPlatformResource(const char *name)
+{
+ String resourcePath = homeDirectoryPath() + String::format("res/%s.png", name);
+
+ RefPtr<SharedBuffer> buffer = SharedBuffer::createWithContentsOfFile(resourcePath.utf8().data());
+ if (!buffer)
+ return Image::nullImage();
+
+ RefPtr<Image> image = BitmapImage::create();
+ image->setData(buffer, true);
+ return image.release();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/cairo/CairoUtilities.cpp b/WebCore/platform/graphics/cairo/CairoUtilities.cpp
new file mode 100644
index 0000000..8c2049f
--- /dev/null
+++ b/WebCore/platform/graphics/cairo/CairoUtilities.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CairoUtilities.h"
+
+#include "Color.h"
+#include <cairo.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+void copyContextProperties(cairo_t* srcCr, cairo_t* dstCr)
+{
+ cairo_set_antialias(dstCr, cairo_get_antialias(srcCr));
+
+ size_t dashCount = cairo_get_dash_count(srcCr);
+ Vector<double> dashes(dashCount);
+
+ double offset;
+ cairo_get_dash(srcCr, dashes.data(), &offset);
+ cairo_set_dash(dstCr, dashes.data(), dashCount, offset);
+ cairo_set_line_cap(dstCr, cairo_get_line_cap(srcCr));
+ cairo_set_line_join(dstCr, cairo_get_line_join(srcCr));
+ cairo_set_line_width(dstCr, cairo_get_line_width(srcCr));
+ cairo_set_miter_limit(dstCr, cairo_get_miter_limit(srcCr));
+ cairo_set_fill_rule(dstCr, cairo_get_fill_rule(srcCr));
+}
+
+void setSourceRGBAFromColor(cairo_t* context, const Color& color)
+{
+ float red, green, blue, alpha;
+ color.getRGBA(red, green, blue, alpha);
+ cairo_set_source_rgba(context, red, green, blue, alpha);
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/cairo/CairoUtilities.h b/WebCore/platform/graphics/cairo/CairoUtilities.h
new file mode 100644
index 0000000..0675b90
--- /dev/null
+++ b/WebCore/platform/graphics/cairo/CairoUtilities.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CairoUtilities_h
+#define CairoUtilities_h
+
+typedef struct _cairo cairo_t;
+
+namespace WebCore {
+class Color;
+
+void copyContextProperties(cairo_t* srcCr, cairo_t* dstCr);
+void setSourceRGBAFromColor(cairo_t*, const Color&);
+
+} // namespace WebCore
+
+#endif // CairoUtilities_h
diff --git a/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp b/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
new file mode 100644
index 0000000..4b94cb3
--- /dev/null
+++ b/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010 Sencha, Inc.
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ContextShadow.h"
+
+#include "CairoUtilities.h"
+#include "Timer.h"
+#include <cairo.h>
+
+namespace WebCore {
+
+static cairo_surface_t* scratchBuffer = 0;
+static void purgeScratchBuffer()
+{
+ cairo_surface_destroy(scratchBuffer);
+ scratchBuffer = 0;
+}
+
+// ContextShadow needs a scratch image as the buffer for the blur filter.
+// Instead of creating and destroying the buffer for every operation,
+// we create a buffer which will be automatically purged via a timer.
+class PurgeScratchBufferTimer : public TimerBase {
+private:
+ virtual void fired() { purgeScratchBuffer(); }
+};
+static PurgeScratchBufferTimer purgeScratchBufferTimer;
+static void scheduleScratchBufferPurge()
+{
+ if (purgeScratchBufferTimer.isActive())
+ purgeScratchBufferTimer.stop();
+ purgeScratchBufferTimer.startOneShot(2);
+}
+
+static cairo_surface_t* getScratchBuffer(const IntSize& size)
+{
+ int width = size.width();
+ int height = size.height();
+ int scratchWidth = scratchBuffer ? cairo_image_surface_get_width(scratchBuffer) : 0;
+ int scratchHeight = scratchBuffer ? cairo_image_surface_get_height(scratchBuffer) : 0;
+
+ // We do not need to recreate the buffer if the current buffer is large enough.
+ if (scratchBuffer && scratchWidth >= width && scratchHeight >= height)
+ return scratchBuffer;
+
+ purgeScratchBuffer();
+
+ // Round to the nearest 32 pixels so we do not grow the buffer for similar sized requests.
+ width = (1 + (width >> 5)) << 5;
+ height = (1 + (height >> 5)) << 5;
+ scratchBuffer = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ return scratchBuffer;
+}
+
+PlatformContext ContextShadow::beginShadowLayer(PlatformContext context, const FloatRect& layerArea)
+{
+ double x1, x2, y1, y2;
+ cairo_clip_extents(context, &x1, &y1, &x2, &y2);
+ calculateLayerBoundingRect(layerArea, IntRect(x1, y1, x2 - x1, y2 - y1));
+
+ // Don't paint if we are totally outside the clip region.
+ if (m_layerRect.isEmpty())
+ return 0;
+
+ m_layerImage = getScratchBuffer(m_layerRect.size());
+ m_layerContext = cairo_create(m_layerImage);
+
+ // Always clear the surface first.
+ cairo_set_operator(m_layerContext, CAIRO_OPERATOR_CLEAR);
+ cairo_paint(m_layerContext);
+ cairo_set_operator(m_layerContext, CAIRO_OPERATOR_OVER);
+
+ cairo_translate(m_layerContext, m_offset.width(), m_offset.height());
+ cairo_translate(m_layerContext, -m_layerRect.x(), -m_layerRect.y());
+ return m_layerContext;
+}
+
+void ContextShadow::endShadowLayer(cairo_t* cr)
+{
+ cairo_destroy(m_layerContext);
+ m_layerContext = 0;
+
+ if (m_type == BlurShadow)
+ blurLayerImage(cairo_image_surface_get_data(m_layerImage),
+ IntSize(cairo_image_surface_get_width(m_layerImage), cairo_image_surface_get_height(m_layerImage)),
+ cairo_image_surface_get_stride(m_layerImage));
+
+ cairo_save(cr);
+ setSourceRGBAFromColor(cr, m_color);
+ cairo_mask_surface(cr, m_layerImage, m_layerRect.x(), m_layerRect.y());
+ cairo_restore(cr);
+
+ // Schedule a purge of the scratch buffer. We do not need to destroy the surface.
+ scheduleScratchBufferPurge();
+}
+
+}
diff --git a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp
index c09dd49..febad12 100644
--- a/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp
+++ b/WebCore/platform/graphics/cairo/FontCacheFreeType.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2010 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -26,13 +27,17 @@
#include "OwnPtrCairo.h"
#include "PlatformRefPtrCairo.h"
#include "SimpleFontData.h"
+#include <cairo-ft.h>
+#include <cairo.h>
+#include <fontconfig/fcfreetype.h>
#include <wtf/Assertions.h>
namespace WebCore {
void FontCache::platformInit()
{
- if (!FontPlatformData::init())
+ // It's fine to call FcInit multiple times per the documentation.
+ if (!FcInit())
ASSERT_NOT_REACHED();
}
@@ -72,9 +77,9 @@ SimpleFontData* FontCache::getSimilarFontPlatformData(const Font& font)
SimpleFontData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription)
{
- // FIXME: Would be even better to somehow get the user's default font here.
- // For now we'll pick the default that the user would get without changing any prefs.
- static AtomicString timesStr("Times New Roman");
+ // We want to return a fallback font here, otherwise the logic preventing FontConfig
+ // matches for non-fallback fonts might return 0. See isFallbackFontAllowed.
+ static AtomicString timesStr("serif");
return getCachedFontData(fontDescription, timesStr);
}
@@ -82,54 +87,106 @@ void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne
{
}
-static bool isWellKnownFontName(const AtomicString family)
+static CString getFamilyNameStringFromFontDescriptionAndFamily(const FontDescription& fontDescription, const AtomicString& family)
{
- // Fonts that are used by layout tests included. The fact that
- // they are used in Layout Tests indicate web compatibility issues
- // if we do not handle them correctly.
- if (equalIgnoringCase(family, "sans-serif") || equalIgnoringCase(family, "sans")
- || equalIgnoringCase(family, "serif") || equalIgnoringCase(family, "mono")
- || equalIgnoringCase(family, "monospace") || equalIgnoringCase(family, "cursive")
- || equalIgnoringCase(family, "fantasy") || equalIgnoringCase(family, "Times")
- || equalIgnoringCase(family, "Courier") || equalIgnoringCase(family, "Helvetica")
- || equalIgnoringCase(family, "Arial") || equalIgnoringCase(family, "Lucida Grande")
- || equalIgnoringCase(family, "Ahem") || equalIgnoringCase(family, "Georgia")
- || equalIgnoringCase(family, "Times New Roman"))
- return true;
-
- return false;
+ // If we're creating a fallback font (e.g. "-webkit-monospace"), convert the name into
+ // the fallback name (like "monospace") that fontconfig understands.
+ if (family.length() && !family.startsWith("-webkit-"))
+ return family.string().utf8();
+
+ switch (fontDescription.genericFamily()) {
+ case FontDescription::StandardFamily:
+ case FontDescription::SerifFamily:
+ return "serif";
+ case FontDescription::SansSerifFamily:
+ return "sans-serif";
+ case FontDescription::MonospaceFamily:
+ return "monospace";
+ case FontDescription::CursiveFamily:
+ return "cursive";
+ case FontDescription::FantasyFamily:
+ return "fantasy";
+ case FontDescription::NoFamily:
+ default:
+ return "";
+ }
}
-FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
-{
- // Handle generic family types specially, because fontconfig does not know them, but we have
- // code to fallback correctly in our platform data implementation.
- if (!family.length() || family.startsWith("-webkit-")
- || (fontDescription.genericFamily() != FontDescription::NoFamily)
- || isWellKnownFontName(family))
- return new FontPlatformData(fontDescription, family);
- // First check the font exists.
- CString familyNameString = family.string().utf8();
- const char* fcfamily = familyNameString.data();
+static bool isFallbackFontAllowed(const CString& familyName)
+{
+ return !strcasecmp(familyName.data(), "sans")
+ || !strcasecmp(familyName.data(), "sans-serif")
+ || !strcasecmp(familyName.data(), "serif")
+ || !strcasecmp(familyName.data(), "monospace");
+}
+FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)
+{
+ // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
+ // says that we must find an exact match for font family, slant (italic or oblique can be used)
+ // and font weight (we only match bold/non-bold here).
PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(FcPatternCreate());
- if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
+ CString familyNameString = getFamilyNameStringFromFontDescriptionAndFamily(fontDescription, family);
+ if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(familyNameString.data())))
return 0;
- OwnPtr<FcObjectSet> objectSet(FcObjectSetCreate());
- if (!FcObjectSetAdd(objectSet.get(), FC_FAMILY))
+ bool italic = fontDescription.italic();
+ if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN))
+ return 0;
+ bool bold = fontDescription.weight() >= FontWeightBold;
+ if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL))
+ return 0;
+ if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize()))
return 0;
- OwnPtr<FcFontSet> fontSet(FcFontList(0, pattern.get(), objectSet.get()));
-
- if (!fontSet)
+ // The following comment and strategy are originally from Skia (src/ports/SkFontHost_fontconfig.cpp):
+ // Font matching:
+ // CSS often specifies a fallback list of families:
+ // font-family: a, b, c, serif;
+ // However, fontconfig will always do its best to find *a* font when asked
+ // for something so we need a way to tell if the match which it has found is
+ // "good enough" for us. Otherwise, we can return null which gets piped up
+ // and lets WebKit know to try the next CSS family name. However, fontconfig
+ // configs allow substitutions (mapping "Arial -> Helvetica" etc) and we
+ // wish to support that.
+ //
+ // Thus, if a specific family is requested we set @family_requested. Then we
+ // record two strings: the family name after config processing and the
+ // family name after resolving. If the two are equal, it's a good match.
+ //
+ // So consider the case where a user has mapped Arial to Helvetica in their
+ // config.
+ // requested family: "Arial"
+ // post_config_family: "Helvetica"
+ // post_match_family: "Helvetica"
+ // -> good match
+ //
+ // and for a missing font:
+ // requested family: "Monaco"
+ // post_config_family: "Monaco"
+ // post_match_family: "Times New Roman"
+ // -> BAD match
+ //
+ FcConfigSubstitute(0, pattern.get(), FcMatchPattern);
+ FcDefaultSubstitute(pattern.get());
+
+ FcChar8* familyNameAfterConfiguration;
+ FcPatternGetString(pattern.get(), FC_FAMILY, 0, &familyNameAfterConfiguration);
+
+ FcResult fontConfigResult;
+ PlatformRefPtr<FcPattern> resultPattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fontConfigResult));
+ if (!resultPattern) // No match.
return 0;
- if (!fontSet->fonts)
+ // Properly handle the situation where Fontconfig gives us a font that has a different family than we requested.
+ FcChar8* familyNameAfterMatching;
+ FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &familyNameAfterMatching);
+ if (strcasecmp(reinterpret_cast<char*>(familyNameAfterConfiguration),
+ reinterpret_cast<char*>(familyNameAfterMatching)) && !isFallbackFontAllowed(familyNameString))
return 0;
- return new FontPlatformData(fontDescription, family);
+ return new FontPlatformData(resultPattern.get(), fontDescription);
}
}
diff --git a/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp b/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp
index 6b76c2a..0d195cb 100644
--- a/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/cairo/FontCustomPlatformData.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2010 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,11 +24,37 @@
#include "FontPlatformData.h"
#include "SharedBuffer.h"
+#include <cairo-ft.h>
+#include <cairo.h>
namespace WebCore {
+static void releaseCustomFontData(void* data)
+{
+ static_cast<SharedBuffer*>(data)->deref();
+}
+
+FontCustomPlatformData::FontCustomPlatformData(FT_Face freeTypeFace, SharedBuffer* buffer)
+ : m_freeTypeFace(freeTypeFace)
+ , m_fontFace(cairo_ft_font_face_create_for_ft_face(freeTypeFace, 0))
+{
+ // FIXME Should we be setting some hinting options here?
+
+ buffer->ref(); // This is balanced by the buffer->deref() in releaseCustomFontData.
+ static cairo_user_data_key_t bufferKey;
+ cairo_font_face_set_user_data(m_fontFace, &bufferKey, buffer,
+ static_cast<cairo_destroy_func_t>(releaseCustomFontData));
+
+ // Cairo doesn't do FreeType reference counting, so we need to ensure that when
+ // this cairo_font_face_t is destroyed, it cleans up the FreeType face as well.
+ static cairo_user_data_key_t freeTypeFaceKey;
+ cairo_font_face_set_user_data(m_fontFace, &freeTypeFaceKey, freeTypeFace,
+ reinterpret_cast<cairo_destroy_func_t>(FT_Done_Face));
+}
+
FontCustomPlatformData::~FontCustomPlatformData()
{
+ // m_freeTypeFace will be destroyed along with m_fontFace. See the constructor.
cairo_font_face_destroy(m_fontFace);
}
@@ -36,38 +63,20 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
return FontPlatformData(m_fontFace, size, bold, italic);
}
-static void releaseData(void* data)
-{
- static_cast<SharedBuffer*>(data)->deref();
-}
-
FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
{
ASSERT_ARG(buffer, buffer);
- int error;
-
static FT_Library library = 0;
- if (!library) {
- error = FT_Init_FreeType(&library);
- if (error) {
- library = 0;
- return 0;
- }
+ if (!library && FT_Init_FreeType(&library)) {
+ library = 0;
+ return 0;
}
- FT_Face face;
- error = FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(buffer->data()), buffer->size(), 0, &face);
- if (error)
+ FT_Face freeTypeFace;
+ if (FT_New_Memory_Face(library, reinterpret_cast<const FT_Byte*>(buffer->data()), buffer->size(), 0, &freeTypeFace))
return 0;
-
- buffer->ref();
- cairo_font_face_t* fontFace = cairo_ft_font_face_create_for_ft_face(face, 0);
-
- static cairo_user_data_key_t bufferKey;
- cairo_font_face_set_user_data(fontFace, &bufferKey, buffer, releaseData);
-
- return new FontCustomPlatformData(fontFace);
+ return new FontCustomPlatformData(freeTypeFace, buffer);
}
bool FontCustomPlatformData::supportsFormat(const String& format)
diff --git a/WebCore/platform/graphics/cairo/FontCustomPlatformData.h b/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
index a72a6a4..c48d110 100644
--- a/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
+++ b/WebCore/platform/graphics/cairo/FontCustomPlatformData.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Alp Toker <alp@atoker.com>
+ * Copyright (C) 2010 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -25,6 +26,7 @@
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
+typedef struct FT_FaceRec_* FT_Face;
typedef struct _cairo_font_face cairo_font_face_t;
namespace WebCore {
@@ -33,16 +35,14 @@ class FontPlatformData;
class SharedBuffer;
struct FontCustomPlatformData : Noncopyable {
- FontCustomPlatformData(cairo_font_face_t* fontFace)
- : m_fontFace(fontFace)
- {}
-
+public:
+ FontCustomPlatformData(FT_Face, SharedBuffer*);
~FontCustomPlatformData();
-
FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode);
-
static bool supportsFormat(const String&);
+private:
+ FT_Face m_freeTypeFace;
cairo_font_face_t* m_fontFace;
};
diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp
index 7968966..0617e6c 100644
--- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp
+++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.cpp
@@ -3,7 +3,7 @@
* Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
* Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
* Copyright (C) 2007 Holger Hans Peter Freyther
- * Copyright (C) 2009 Igalia S.L.
+ * Copyright (C) 2009, 2010 Igalia S.L.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -27,100 +27,88 @@
#include "PlatformString.h"
#include "FontDescription.h"
-#include <wtf/text/CString.h>
-
#include <cairo-ft.h>
#include <cairo.h>
#include <fontconfig/fcfreetype.h>
+
#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT)
#include <gdk/gdk.h>
#endif
namespace WebCore {
-FontPlatformData::FontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName)
- : m_fallbacks(0)
+cairo_subpixel_order_t convertFontConfigSubpixelOrder(int fontConfigOrder)
+{
+ switch (fontConfigOrder) {
+ case FC_RGBA_RGB:
+ return CAIRO_SUBPIXEL_ORDER_RGB;
+ case FC_RGBA_BGR:
+ return CAIRO_SUBPIXEL_ORDER_BGR;
+ case FC_RGBA_VRGB:
+ return CAIRO_SUBPIXEL_ORDER_VRGB;
+ case FC_RGBA_VBGR:
+ return CAIRO_SUBPIXEL_ORDER_VBGR;
+ case FC_RGBA_NONE:
+ case FC_RGBA_UNKNOWN:
+ return CAIRO_SUBPIXEL_ORDER_DEFAULT;
+ }
+ return CAIRO_SUBPIXEL_ORDER_DEFAULT;
+}
+
+cairo_hint_style_t convertFontConfigHintStyle(int fontConfigStyle)
+{
+ switch (fontConfigStyle) {
+ case FC_HINT_NONE:
+ return CAIRO_HINT_STYLE_NONE;
+ case FC_HINT_SLIGHT:
+ return CAIRO_HINT_STYLE_SLIGHT;
+ case FC_HINT_MEDIUM:
+ return CAIRO_HINT_STYLE_MEDIUM;
+ case FC_HINT_FULL:
+ return CAIRO_HINT_STYLE_FULL;
+ }
+ return CAIRO_HINT_STYLE_NONE;
+}
+
+void setCairoFontOptionsFromFontConfigPattern(cairo_font_options_t* options, FcPattern* pattern)
+{
+ FcBool booleanResult;
+ int integerResult;
+
+ // We will determine if subpixel anti-aliasing is enabled via the FC_RGBA setting.
+ if (FcPatternGetBool(pattern, FC_ANTIALIAS, 0, &booleanResult) == FcResultMatch && booleanResult)
+ cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY);
+
+ if (FcPatternGetInteger(pattern, FC_RGBA, 0, &integerResult) == FcResultMatch) {
+ if (integerResult != FC_RGBA_NONE)
+ cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
+ cairo_font_options_set_subpixel_order(options, convertFontConfigSubpixelOrder(integerResult));
+ }
+
+ if (FcPatternGetInteger(pattern, FC_HINT_STYLE, 0, &integerResult) == FcResultMatch)
+ cairo_font_options_set_hint_style(options, convertFontConfigHintStyle(integerResult));
+
+ if (FcPatternGetBool(pattern, FC_HINTING, 0, &booleanResult) == FcResultMatch && !booleanResult)
+ cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE);
+}
+
+FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription)
+ : m_pattern(pattern)
+ , m_fallbacks(0)
, m_size(fontDescription.computedPixelSize())
, m_syntheticBold(false)
, m_syntheticOblique(false)
{
- FontPlatformData::init();
-
- CString familyNameString = familyName.string().utf8();
- const char* fcfamily = familyNameString.data();
- int fcslant = FC_SLANT_ROMAN;
- // FIXME: Map all FontWeight values to fontconfig weights.
- int fcweight = FC_WEIGHT_NORMAL;
- double fcsize = fontDescription.computedPixelSize();
- if (fontDescription.italic())
- fcslant = FC_SLANT_ITALIC;
- if (fontDescription.weight() >= FontWeight600)
- fcweight = FC_WEIGHT_BOLD;
-
- int type = fontDescription.genericFamily();
-
- PlatformRefPtr<FcPattern> pattern = adoptPlatformRef(FcPatternCreate());
- cairo_font_face_t* fontFace;
- static const cairo_font_options_t* defaultOptions = cairo_font_options_create();
- const cairo_font_options_t* options = NULL;
- cairo_matrix_t fontMatrix;
-
- if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
- return;
-
- switch (type) {
- case FontDescription::SerifFamily:
- fcfamily = "serif";
- break;
- case FontDescription::SansSerifFamily:
- fcfamily = "sans-serif";
- break;
- case FontDescription::MonospaceFamily:
- fcfamily = "monospace";
- break;
- case FontDescription::StandardFamily:
- fcfamily = "sans-serif";
- break;
- case FontDescription::NoFamily:
- default:
- fcfamily = NULL;
- break;
- }
+ cairo_font_options_t* options = cairo_font_options_create();
+ setCairoFontOptionsFromFontConfigPattern(options, pattern);
- if (fcfamily && !FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast<const FcChar8*>(fcfamily)))
- return;
- if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fcweight))
- return;
- if (!FcPatternAddInteger(pattern.get(), FC_SLANT, fcslant))
- return;
- if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fcsize))
- return;
-
- FcConfigSubstitute(0, pattern.get(), FcMatchPattern);
- FcDefaultSubstitute(pattern.get());
-
- FcResult fcresult;
- m_pattern = adoptPlatformRef(FcFontMatch(0, pattern.get(), &fcresult));
- // FIXME: should we set some default font?
- if (!m_pattern)
- return;
- fontFace = cairo_ft_font_face_create_for_pattern(m_pattern.get());
+ cairo_matrix_t fontMatrix;
+ cairo_matrix_init_scale(&fontMatrix, m_size, m_size);
cairo_matrix_t ctm;
- cairo_matrix_init_scale(&fontMatrix, fontDescription.computedPixelSize(), fontDescription.computedPixelSize());
cairo_matrix_init_identity(&ctm);
-#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT)
- if (GdkScreen* screen = gdk_screen_get_default())
-gdk_screen_get_font_options(screen);
-#endif
-
- // gdk_screen_get_font_options() returns NULL if no default options are
- // set, so we always have to check.
- if (!options)
- options = defaultOptions;
-
- m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options));
- cairo_font_face_destroy(fontFace);
+ PlatformRefPtr<cairo_font_face_t> fontFace = adoptPlatformRef(cairo_ft_font_face_create_for_pattern(m_pattern.get()));
+ m_scaledFont = adoptPlatformRef(cairo_scaled_font_create(fontFace.get(), &fontMatrix, &ctm, options));
}
FontPlatformData::FontPlatformData(float size, bool bold, bool italic)
@@ -184,19 +172,6 @@ FontPlatformData::FontPlatformData(const FontPlatformData& other)
*this = other;
}
-bool FontPlatformData::init()
-{
- static bool initialized = false;
- if (initialized)
- return true;
- if (!FcInit()) {
- fprintf(stderr, "Can't init font config library\n");
- return false;
- }
- initialized = true;
- return true;
-}
-
FontPlatformData::~FontPlatformData()
{
if (m_fallbacks) {
diff --git a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h
index 987a684..f3488ef 100644
--- a/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h
+++ b/WebCore/platform/graphics/cairo/FontPlatformDataFreeType.h
@@ -3,6 +3,7 @@
* Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com
* Copyright (C) 2007 Holger Hans Peter Freyther
* Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2010 Igalia S.L.
* All rights reserved.
*
* This library is free software; you can redistribute it and/or
@@ -29,11 +30,10 @@
#include "GlyphBuffer.h"
#include "HashFunctions.h"
#include "PlatformRefPtrCairo.h"
-#include <cairo-ft.h>
-#include <cairo.h>
-#include <fontconfig/fcfreetype.h>
#include <wtf/Forward.h>
+typedef struct _FcFontSet FcFontSet;
+
namespace WebCore {
class FontPlatformData {
@@ -53,14 +53,13 @@ public:
, m_syntheticOblique(false)
{ }
- FontPlatformData(const FontDescription&, const AtomicString& family);
+ FontPlatformData(FcPattern*, const FontDescription&);
FontPlatformData(cairo_font_face_t* fontFace, float size, bool bold, bool italic);
FontPlatformData(float size, bool bold, bool italic);
FontPlatformData(const FontPlatformData&);
~FontPlatformData();
- static bool init();
bool isFixedPitch();
float size() const { return m_size; }
void setSize(float size) { m_size = size; }
diff --git a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
index 26da68d..66e9c16 100644
--- a/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GlyphPageTreeNodeCairo.cpp
@@ -32,6 +32,9 @@
#include "GlyphPageTreeNode.h"
#include "SimpleFontData.h"
+#include <cairo-ft.h>
+#include <cairo.h>
+#include <fontconfig/fcfreetype.h>
namespace WebCore {
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 5de7e1f..05096a9 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -35,6 +35,7 @@
#include "AffineTransform.h"
#include "CairoPath.h"
+#include "CairoUtilities.h"
#include "FEGaussianBlur.h"
#include "FloatRect.h"
#include "Font.h"
@@ -131,28 +132,10 @@ static inline void fillRectSourceOver(cairo_t* cr, const FloatRect& rect, const
cairo_fill(cr);
}
-static inline void copyContextProperties(cairo_t* srcCr, cairo_t* dstCr)
-{
- cairo_set_antialias(dstCr, cairo_get_antialias(srcCr));
-
- size_t dashCount = cairo_get_dash_count(srcCr);
- Vector<double> dashes(dashCount);
-
- double offset;
- cairo_get_dash(srcCr, dashes.data(), &offset);
- cairo_set_dash(dstCr, dashes.data(), dashCount, offset);
- cairo_set_line_cap(dstCr, cairo_get_line_cap(srcCr));
- cairo_set_line_join(dstCr, cairo_get_line_join(srcCr));
- cairo_set_line_width(dstCr, cairo_get_line_width(srcCr));
- cairo_set_miter_limit(dstCr, cairo_get_miter_limit(srcCr));
- cairo_set_fill_rule(dstCr, cairo_get_fill_rule(srcCr));
-}
-
static void appendPathToCairoContext(cairo_t* to, cairo_t* from)
{
- cairo_path_t* cairoPath = cairo_copy_path(from);
- cairo_append_path(to, cairoPath);
- cairo_path_destroy(cairoPath);
+ OwnPtr<cairo_path_t> cairoPath(cairo_copy_path(from));
+ cairo_append_path(to, cairoPath.get());
}
// We apply the pending path built via addPath to the Cairo context
@@ -1182,9 +1165,8 @@ void GraphicsContext::clip(const Path& path)
return;
cairo_t* cr = m_data->cr;
- cairo_path_t* p = cairo_copy_path(path.platformPath()->context());
- cairo_append_path(cr, p);
- cairo_path_destroy(p);
+ OwnPtr<cairo_path_t> p(cairo_copy_path(path.platformPath()->context()));
+ cairo_append_path(cr, p.get());
cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
cairo_clip(cr);
@@ -1341,9 +1323,8 @@ void GraphicsContext::drawTiledShadow(const IntRect& rect, const FloatSize& topL
copyContextProperties(cr, shadowContext);
cairo_translate(shadowContext, -rect.x() + blurRadius, -rect.y() + blurRadius);
cairo_new_path(shadowContext);
- cairo_path_t* path = cairo_copy_path(cr);
- cairo_append_path(shadowContext, path);
- cairo_path_destroy(path);
+ OwnPtr<cairo_path_t> path(cairo_copy_path(cr));
+ cairo_append_path(shadowContext, path.get());
setPlatformFill(this, shadowContext, m_common);
diff --git a/WebCore/platform/graphics/cairo/PathCairo.cpp b/WebCore/platform/graphics/cairo/PathCairo.cpp
index 05c6952..776bceb 100644
--- a/WebCore/platform/graphics/cairo/PathCairo.cpp
+++ b/WebCore/platform/graphics/cairo/PathCairo.cpp
@@ -29,9 +29,9 @@
#include "CairoPath.h"
#include "FloatRect.h"
#include "GraphicsContext.h"
+#include "OwnPtrCairo.h"
#include "PlatformString.h"
#include "StrokeStyleApplier.h"
-
#include <cairo.h>
#include <math.h>
#include <wtf/MathExtras.h>
@@ -52,9 +52,8 @@ Path::Path(const Path& other)
: m_path(new CairoPath())
{
cairo_t* cr = platformPath()->context();
- cairo_path_t* p = cairo_copy_path(other.platformPath()->context());
- cairo_append_path(cr, p);
- cairo_path_destroy(p);
+ OwnPtr<cairo_path_t> p(cairo_copy_path(other.platformPath()->context()));
+ cairo_append_path(cr, p.get());
}
Path& Path::operator=(const Path& other)
@@ -64,9 +63,8 @@ Path& Path::operator=(const Path& other)
clear();
cairo_t* cr = platformPath()->context();
- cairo_path_t* p = cairo_copy_path(other.platformPath()->context());
- cairo_append_path(cr, p);
- cairo_path_destroy(p);
+ OwnPtr<cairo_path_t> p(cairo_copy_path(other.platformPath()->context()));
+ cairo_append_path(cr, p.get());
return *this;
}
@@ -297,7 +295,7 @@ bool Path::strokeContains(StrokeStyleApplier* applier, const FloatPoint& point)
void Path::apply(void* info, PathApplierFunction function) const
{
cairo_t* cr = platformPath()->context();
- cairo_path_t* path = cairo_copy_path(cr);
+ OwnPtr<cairo_path_t> path(cairo_copy_path(cr));
cairo_path_data_t* data;
PathElement pelement;
FloatPoint points[3];
@@ -329,7 +327,6 @@ void Path::apply(void* info, PathApplierFunction function) const
break;
}
}
- cairo_path_destroy(path);
}
void Path::transform(const AffineTransform& trans)
@@ -346,7 +343,7 @@ String Path::debugString() const
return String();
String pathString;
- cairo_path_t* path = cairo_copy_path(platformPath()->context());
+ OwnPtr<cairo_path_t> path(cairo_copy_path(platformPath()->context()));
cairo_path_data_t* data;
for (int i = 0; i < path->num_data; i += path->data[i].header.length) {
@@ -373,7 +370,6 @@ String Path::debugString() const
}
}
- cairo_path_destroy(path);
return pathString.simplifyWhiteSpace();
}
diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp
index aa466f9..d289585 100644
--- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp
+++ b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.cpp
@@ -54,6 +54,19 @@ template <> void derefPlatformPtr(cairo_surface_t* ptr)
cairo_surface_destroy(ptr);
}
+template <> cairo_font_face_t* refPlatformPtr(cairo_font_face_t* ptr)
+{
+ if (ptr)
+ cairo_font_face_reference(ptr);
+ return ptr;
+}
+
+template <> void derefPlatformPtr(cairo_font_face_t* ptr)
+{
+ if (ptr)
+ cairo_font_face_destroy(ptr);
+}
+
template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t* ptr)
{
if (ptr)
diff --git a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h
index 4b45c1b..3b720c6 100644
--- a/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h
+++ b/WebCore/platform/graphics/cairo/PlatformRefPtrCairo.h
@@ -24,6 +24,7 @@
typedef struct _cairo cairo_t;
typedef struct _cairo_surface cairo_surface_t;
+typedef struct _cairo_font_face cairo_font_face_t;
typedef struct _cairo_scaled_font cairo_scaled_font_t;
#if defined(USE_FREETYPE)
@@ -38,6 +39,9 @@ template <> void derefPlatformPtr(cairo_t* ptr);
template <> cairo_surface_t* refPlatformPtr(cairo_surface_t* ptr);
template <> void derefPlatformPtr(cairo_surface_t* ptr);
+template <> cairo_font_face_t* refPlatformPtr(cairo_font_face_t*);
+template <> void derefPlatformPtr(cairo_font_face_t*);
+
template <> cairo_scaled_font_t* refPlatformPtr(cairo_scaled_font_t*);
template <> void derefPlatformPtr(cairo_scaled_font_t*);
diff --git a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
index fd85d6f..3d7c34b 100644
--- a/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
+++ b/WebCore/platform/graphics/cairo/SimpleFontDataCairo.cpp
@@ -38,7 +38,9 @@
#include "FontCache.h"
#include "FontDescription.h"
#include "GlyphBuffer.h"
+#include <cairo-ft.h>
#include <cairo.h>
+#include <fontconfig/fcfreetype.h>
#include <wtf/MathExtras.h>
namespace WebCore {
@@ -81,12 +83,12 @@ void SimpleFontData::platformDestroy()
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
- if (!m_smallCapsFontData) {
- FontDescription desc = FontDescription(fontDescription);
- desc.setComputedSize(0.70f * fontDescription.computedSize());
- FontPlatformData platformData(desc, desc.family().family());
- m_smallCapsFontData = new SimpleFontData(platformData);
- }
+ // FIXME: I think we want to ask FontConfig for the right font again.
+ if (!m_smallCapsFontData)
+ m_smallCapsFontData = new SimpleFontData(
+ FontPlatformData(cairo_scaled_font_get_font_face(m_platformData.scaledFont()),
+ 0.70f * fontDescription.computedSize(), m_platformData.syntheticBold(), m_platformData.syntheticOblique()));
+
return m_smallCapsFontData;
}
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index fadc385..2a81fd2 100644
--- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -71,9 +71,54 @@ bool GraphicsContext3D::getImageData(Image* image,
AlphaOp neededAlphaOp = kAlphaDoNothing;
switch (CGImageGetAlphaInfo(cgImage)) {
case kCGImageAlphaPremultipliedFirst:
+ // This path is only accessible for MacOS earlier than 10.6.4.
+ // This is a special case for texImage2D with HTMLCanvasElement input,
+ // in which case image->data() should be null.
+ ASSERT(!image->data());
+ if (!premultiplyAlpha)
+ neededAlphaOp = kAlphaDoUnmultiply;
+ switch (componentsPerPixel) {
+ case 2:
+ srcDataFormat = kSourceFormatAR8;
+ break;
+ case 4:
+ srcDataFormat = kSourceFormatARGB8;
+ break;
+ default:
+ return false;
+ }
+ break;
case kCGImageAlphaFirst:
+ // This path is only accessible for MacOS earlier than 10.6.4.
+ if (premultiplyAlpha)
+ neededAlphaOp = kAlphaDoPremultiply;
+ switch (componentsPerPixel) {
+ case 1:
+ srcDataFormat = kSourceFormatA8;
+ break;
+ case 2:
+ srcDataFormat = kSourceFormatAR8;
+ break;
+ case 4:
+ srcDataFormat = kSourceFormatARGB8;
+ break;
+ default:
+ return false;
+ }
+ break;
case kCGImageAlphaNoneSkipFirst:
- return false;
+ // This path is only accessible for MacOS earlier than 10.6.4.
+ switch (componentsPerPixel) {
+ case 2:
+ srcDataFormat = kSourceFormatAR8;
+ break;
+ case 4:
+ srcDataFormat = kSourceFormatARGB8;
+ break;
+ default:
+ return false;
+ }
+ break;
case kCGImageAlphaPremultipliedLast:
// This is a special case for texImage2D with HTMLCanvasElement input,
// in which case image->data() should be null.
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
index 86be8da..8dda4d6 100644
--- a/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
@@ -126,10 +126,28 @@ ContentLayerChromium::ContentLayerChromium(GraphicsLayerChromium* owner)
ContentLayerChromium::~ContentLayerChromium()
{
- if (m_contentsTexture)
- GLC(layerRendererContext(), layerRendererContext()->deleteTexture(m_contentsTexture));
+ cleanupResources();
}
+void ContentLayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
+{
+ // If we're changing layer renderers then we need to free up any resources
+ // allocated by the old renderer.
+ if (layerRenderer() && layerRenderer() != renderer)
+ cleanupResources();
+
+ LayerChromium::setLayerRenderer(renderer);
+}
+
+void ContentLayerChromium::cleanupResources()
+{
+ if (layerRenderer()) {
+ if (m_contentsTexture) {
+ layerRenderer()->deleteLayerTexture(m_contentsTexture);
+ m_contentsTexture = 0;
+ }
+ }
+}
void ContentLayerChromium::updateContents()
{
diff --git a/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
index 42a77c7..412ba06 100644
--- a/WebCore/platform/graphics/chromium/ContentLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/ContentLayerChromium.h
@@ -49,6 +49,7 @@ public:
virtual void updateContents();
virtual void draw();
virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); }
+ virtual void setLayerRenderer(LayerRendererChromium*);
// Stores values that are shared between instances of this class that are
// associated with the same LayerRendererChromium (and hence the same GL
@@ -79,6 +80,8 @@ protected:
void updateTextureRect(void* pixels, const IntSize& bitmapSize, const IntSize& requiredTextureSize,
const IntRect& updateRect, unsigned textureId);
+ void cleanupResources();
+
unsigned m_contentsTexture;
IntSize m_allocatedTextureSize;
bool m_skipsDraw;
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index 696cd9c..a242523 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -130,7 +130,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
if (textMode & cTextFill) {
// If we also filled, we don't want to draw shadows twice.
// See comment in FontChromiumWin.cpp::paintSkiaText() for more details.
- paint.setLooper(0)->safeUnref();
+ SkSafeUnref(paint.setLooper(0));
}
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
@@ -313,7 +313,7 @@ public:
// So we allow that to run first, then do a second pass over the range it
// found and take the largest subregion that stays within a single font.
const FontData* glyphData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false, false).fontData;
- int endOfRun;
+ unsigned endOfRun;
for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) {
const FontData* nextGlyphData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false, false).fontData;
if (nextGlyphData != glyphData)
@@ -406,7 +406,7 @@ private:
// Harfbuzz will do the same thing for us using the GSUB table.
// 2) Convert spacing characters into plain spaces, as some fonts will provide glyphs
// for characters like '\n' otherwise.
- for (unsigned i = 0; i < originalRun.length(); ++i) {
+ for (int i = 0; i < originalRun.length(); ++i) {
UChar ch = originalRun[i];
UBlockCode block = ::ublock_getCode(ch);
if (block == UBLOCK_COMBINING_DIACRITICAL_MARKS || (Font::treatAsSpace(ch) && ch != ' ')) {
@@ -428,7 +428,7 @@ private:
normalizedString.extract(m_normalizedBuffer.get(), normalizedString.length() + 1, error);
ASSERT(U_SUCCESS(error));
- for (unsigned i = 0; i < normalizedString.length(); ++i) {
+ for (int i = 0; i < normalizedString.length(); ++i) {
if (Font::treatAsSpace(m_normalizedBuffer[i]))
m_normalizedBuffer[i] = ' ';
}
@@ -517,7 +517,7 @@ private:
// glyph.
unsigned logClustersIndex = isRTL ? m_item.num_glyphs - 1 : 0;
- for (int iter = 0; iter < m_item.num_glyphs; ++iter) {
+ for (unsigned iter = 0; iter < m_item.num_glyphs; ++iter) {
// Glyphs are stored in logical order, but for layout purposes we
// always go left to right.
int i = isRTL ? m_item.num_glyphs - iter - 1 : iter;
@@ -683,7 +683,7 @@ static int glyphIndexForXPositionInScriptRun(const TextRunWalker& walker, int x)
x -= truncateFixedPointToInteger(advances[glyphIndex]);
}
} else {
- for (glyphIndex = 0; glyphIndex < walker.length(); ++glyphIndex) {
+ for (glyphIndex = 0; static_cast<unsigned>(glyphIndex) < walker.length(); ++glyphIndex) {
if (x < truncateFixedPointToInteger(advances[glyphIndex]))
break;
x -= truncateFixedPointToInteger(advances[glyphIndex]);
@@ -741,7 +741,7 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat,
if (walker.rtl())
basePosition -= walker.numCodePoints();
- if (x >= 0 && x < walker.width()) {
+ if (x >= 0 && static_cast<unsigned>(x) < walker.width()) {
// The x value in question is within this script run. We consider
// each glyph in presentation order and stop when we find the one
// covering this position.
@@ -803,7 +803,7 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run,
if (walker.rtl())
base -= walker.width();
- if (fromX == -1 && from < walker.numCodePoints()) {
+ if (fromX == -1 && from >= 0 && static_cast<unsigned>(from) < walker.numCodePoints()) {
// |from| is within this script run. So we index the clusters log to
// find which glyph this code-point contributed to and find its x
// position.
@@ -813,7 +813,7 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run,
} else
from -= walker.numCodePoints();
- if (toX == -1 && to < walker.numCodePoints()) {
+ if (toX == -1 && to >= 0 && static_cast<unsigned>(to) < walker.numCodePoints()) {
int glyph = walker.logClusters()[to];
toX = base + walker.xPositions()[glyph];
toAdvance = walker.advances()[glyph];
diff --git a/WebCore/platform/graphics/chromium/FontPlatformData.h b/WebCore/platform/graphics/chromium/FontPlatformData.h
index 871fec8..d8ce3e2 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformData.h
+++ b/WebCore/platform/graphics/chromium/FontPlatformData.h
@@ -33,7 +33,7 @@
#if OS(WINDOWS)
#include "FontPlatformDataChromiumWin.h"
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
#include "FontPlatformDataLinux.h"
#endif
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
index b51eb8c..0da873b 100644
--- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp
@@ -76,7 +76,7 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src)
, m_style(src.m_style)
, m_harfbuzzFace(src.m_harfbuzzFace)
{
- m_typeface->safeRef();
+ SkSafeRef(m_typeface);
}
FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float textSize, bool fakeBold, bool fakeItalic)
@@ -86,7 +86,7 @@ FontPlatformData::FontPlatformData(SkTypeface* tf, const char* family, float tex
, m_fakeBold(fakeBold)
, m_fakeItalic(fakeItalic)
{
- m_typeface->safeRef();
+ SkSafeRef(m_typeface);
querySystemForRenderStyle();
}
@@ -98,13 +98,13 @@ FontPlatformData::FontPlatformData(const FontPlatformData& src, float textSize)
, m_fakeItalic(src.m_fakeItalic)
, m_harfbuzzFace(src.m_harfbuzzFace)
{
- m_typeface->safeRef();
+ SkSafeRef(m_typeface);
querySystemForRenderStyle();
}
FontPlatformData::~FontPlatformData()
{
- m_typeface->safeUnref();
+ SkSafeUnref(m_typeface);
}
FontPlatformData& FontPlatformData::operator=(const FontPlatformData& src)
diff --git a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
index 59e8122..056d8eb 100644
--- a/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
+++ b/WebCore/platform/graphics/chromium/HarfbuzzSkia.cpp
@@ -150,7 +150,7 @@ static HB_Error getOutlinePoint(HB_Font hbFont, HB_Glyph glyph, int flags, hb_ui
SkPath path;
paint.getTextPath(&glyph16, sizeof(glyph16), 0, 0, &path);
int numPoints = path.getPoints(0, 0);
- if (point >= numPoints)
+ if (point >= static_cast<unsigned>(numPoints))
return HB_Err_Invalid_SubTable;
SkPoint* points = reinterpret_cast<SkPoint*>(fastMalloc(sizeof(SkPoint) * (point + 1)));
if (!points)
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index e36c69d..5dba58d 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -174,9 +174,6 @@ LayerChromium::~LayerChromium()
void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer)
{
- // It's not expected that layers will ever switch renderers.
- ASSERT(!renderer || !m_layerRenderer || renderer == m_layerRenderer);
-
m_layerRenderer = renderer;
}
@@ -224,9 +221,10 @@ unsigned LayerChromium::createShaderProgram(GraphicsContext3D* context, const ch
void LayerChromium::setNeedsCommit()
{
- // Call notifySyncRequired(), which in this implementation plumbs through to
+ // Call notifySyncRequired(), which for non-root layers plumbs through to
// call setRootLayerNeedsDisplay() on the WebView, which will cause LayerRendererChromium
// to render a frame.
+ // This function has no effect on root layers.
if (m_owner)
m_owner->notifySyncRequired();
}
@@ -352,8 +350,9 @@ LayerChromium* LayerChromium::superlayer() const
void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect)
{
- // Simply mark the contents as dirty. The actual redraw will
- // happen when it's time to do the compositing.
+ // Simply mark the contents as dirty. For non-root layers, the call to
+ // setNeedsCommit will schedule a fresh compositing pass.
+ // For the root layer, setNeedsCommit has no effect.
m_contentsDirty = true;
m_dirtyRect.unite(dirtyRect);
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 30d35d1..0a66318 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -147,7 +147,9 @@ public:
bool preserves3D() { return m_owner && m_owner->preserves3D(); }
- void setLayerRenderer(LayerRendererChromium*);
+ // Derived types must override this method if they need to react to a change
+ // in the LayerRendererChromium.
+ virtual void setLayerRenderer(LayerRendererChromium*);
void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; }
@@ -200,7 +202,7 @@ protected:
GraphicsLayerChromium* m_owner;
LayerChromium(GraphicsLayerChromium* owner);
- LayerRendererChromium* layerRenderer() const { return m_layerRenderer; }
+ LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); }
GraphicsContext3D* layerRendererContext() const;
static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix,
@@ -260,7 +262,7 @@ private:
bool m_needsDisplayOnBoundsChange;
// Points to the layer renderer that updates and draws this layer.
- LayerRendererChromium* m_layerRenderer;
+ RefPtr<LayerRendererChromium> m_layerRenderer;
FloatRect m_frame;
TransformationMatrix m_transform;
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 116a15d..c4031e5 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -73,12 +73,12 @@ static inline bool compareLayerZ(const LayerChromium* a, const LayerChromium* b)
return transformA.m43() < transformB.m43();
}
-PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GraphicsContext3D> context)
+PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassOwnPtr<GraphicsContext3D> context)
{
if (!context)
return 0;
- OwnPtr<LayerRendererChromium> layerRenderer(new LayerRendererChromium(context));
+ RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(context)));
if (!layerRenderer->hardwareCompositing())
return 0;
@@ -91,7 +91,6 @@ LayerRendererChromium::LayerRendererChromium(PassOwnPtr<GraphicsContext3D> conte
, m_rootLayerTextureHeight(0)
, m_scrollShaderProgram(0)
, m_rootLayer(0)
- , m_needsDisplay(false)
, m_scrollPosition(IntPoint(-1, -1))
, m_currentShader(0)
, m_context(context)
@@ -159,8 +158,10 @@ void LayerRendererChromium::useShader(unsigned programId)
}
}
-// Updates the contents of the root layer texture that fall inside the updateRect
-// and re-composits all sublayers.
+// This method must be called before any other updates are made to the
+// root layer texture. It resizes the root layer texture and scrolls its
+// contents as needed. It also sets up common GL state used by the rest
+// of the layer drawing code.
void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, const IntRect& contentRect,
const IntPoint& scrollPosition)
{
@@ -172,6 +173,8 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
makeContextCurrent();
GLC(m_context, m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_rootLayerTextureId));
+
+ bool skipScroll = false;
// If the size of the visible area has changed then allocate a new texture
// to store the contents of the root layer and adjust the projection matrix
@@ -184,6 +187,10 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
m_projectionMatrix = orthoMatrix(0, visibleRectWidth, visibleRectHeight, 0, -1000, 1000);
GLC(m_context, m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0));
+
+ // The root layer texture was just resized so its contents are not
+ // useful for scrolling.
+ skipScroll = true;
}
// The GL viewport covers the entire visible area, including the scrollbars.
@@ -198,12 +205,20 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
GLC(m_context, m_context->depthFunc(GraphicsContext3D::LEQUAL));
GLC(m_context, m_context->clearStencil(0));
- if (m_scrollPosition == IntPoint(-1, -1))
+ if (m_scrollPosition == IntPoint(-1, -1)) {
m_scrollPosition = scrollPosition;
+ skipScroll = true;
+ }
IntPoint scrollDelta = toPoint(scrollPosition - m_scrollPosition);
+
+ // Scrolling larger than the contentRect size does not preserve any of the pixels, so there is
+ // no need to copy framebuffer pixels back into the texture.
+ if (abs(scrollDelta.y()) > contentRect.height() || abs(scrollDelta.x()) > contentRect.width())
+ skipScroll = true;
+
// Scroll the backbuffer
- if (scrollDelta.x() || scrollDelta.y()) {
+ if (!skipScroll && (scrollDelta.x() || scrollDelta.y())) {
// Scrolling works as follows: We render a quad with the current root layer contents
// translated by the amount the page has scrolled since the last update and then read the
// pixels of the content area (visible area excluding the scroll bars) back into the
@@ -221,23 +236,9 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
m_scrollShaderMatrixLocation, -1);
GLC(m_context, m_context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, contentRect.width(), contentRect.height()));
- m_scrollPosition = scrollPosition;
- } else if (abs(scrollDelta.y()) > contentRect.height() || abs(scrollDelta.x()) > contentRect.width()) {
- // Scrolling larger than the contentRect size does not preserve any of the pixels, so there is
- // no need to copy framebuffer pixels back into the texture.
- m_scrollPosition = scrollPosition;
}
- // Translate all the composited layers by the scroll position.
- TransformationMatrix matrix;
- matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
-
- // Traverse the layer tree and update the layer transforms.
- float opacity = 1;
- const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers();
- size_t i;
- for (i = 0; i < sublayers.size(); i++)
- updateLayersRecursive(sublayers[i].get(), matrix, opacity);
+ m_scrollPosition = scrollPosition;
}
void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect)
@@ -256,9 +257,7 @@ void LayerRendererChromium::updateRootLayerTextureRect(const IntRect& updateRect
#if PLATFORM(SKIA)
// Get the contents of the updated rect.
const SkBitmap bitmap = m_rootLayerCanvas->getDevice()->accessBitmap(false);
- int bitmapWidth = bitmap.width();
- int bitmapHeight = bitmap.height();
- ASSERT(bitmapWidth == updateRect.width() && bitmapHeight == updateRect.height());
+ ASSERT(bitmap.width() == updateRect.width() && bitmap.height() == updateRect.height());
void* pixels = bitmap.getPixels();
#elif PLATFORM(CG)
// Get the contents of the updated rect.
@@ -306,16 +305,13 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect
// Set the rootVisibleRect --- used by subsequent drawLayers calls
m_rootVisibleRect = visibleRect;
- // Translate all the composited layers by the scroll position.
- TransformationMatrix matrix;
- matrix.translate3d(-m_scrollPosition.x(), -m_scrollPosition.y(), 0);
-
// Traverse the layer tree and update the layer transforms.
float opacity = 1;
const Vector<RefPtr<LayerChromium> >& sublayers = m_rootLayer->getSublayers();
size_t i;
+ TransformationMatrix identityMatrix;
for (i = 0; i < sublayers.size(); i++)
- updateLayersRecursive(sublayers[i].get(), matrix, opacity);
+ updateLayersRecursive(sublayers[i].get(), identityMatrix, opacity);
// Enable scissoring to avoid rendering composited layers over the scrollbars.
GLC(m_context, m_context->enable(GraphicsContext3D::SCISSOR_TEST));
@@ -349,7 +345,6 @@ void LayerRendererChromium::present()
// Note that currently this has the same effect as swapBuffers; we should
// consider exposing a different entry point on GraphicsContext3D.
m_context->prepareTexture();
- m_needsDisplay = false;
}
void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
@@ -381,6 +376,14 @@ unsigned LayerRendererChromium::createLayerTexture()
return textureId;
}
+void LayerRendererChromium::deleteLayerTexture(unsigned textureId)
+{
+ if (!textureId)
+ return;
+
+ GLC(m_context, m_context->deleteTexture(textureId));
+}
+
// Returns true if any part of the layer falls within the visibleRect
bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
{
@@ -717,7 +720,8 @@ bool LayerRendererChromium::initializeSharedObjects()
m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get()));
m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get()));
m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get()));
- if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized()) {
+ m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get()));
+ if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() || !m_videoLayerSharedValues->initialized()) {
cleanupSharedObjects();
return false;
}
@@ -732,6 +736,7 @@ void LayerRendererChromium::cleanupSharedObjects()
m_layerSharedValues.clear();
m_contentLayerSharedValues.clear();
m_canvasLayerSharedValues.clear();
+ m_videoLayerSharedValues.clear();
if (m_scrollShaderProgram) {
GLC(m_context, m_context->deleteProgram(m_scrollShaderProgram));
@@ -739,7 +744,7 @@ void LayerRendererChromium::cleanupSharedObjects()
}
if (m_rootLayerTextureId) {
- GLC(m_context, m_context->deleteTexture(m_rootLayerTextureId));
+ deleteLayerTexture(m_rootLayerTextureId);
m_rootLayerTextureId = 0;
}
}
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index c733228..b714584 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -39,9 +39,12 @@
#include "IntRect.h"
#include "LayerChromium.h"
#include "SkBitmap.h"
+#include "VideoLayerChromium.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
#include <wtf/PassOwnPtr.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#if PLATFORM(CG)
@@ -54,9 +57,9 @@ namespace WebCore {
class GraphicsContext3D;
// Class that handles drawing of composited render layers using GL.
-class LayerRendererChromium : public Noncopyable {
+class LayerRendererChromium : public RefCounted<LayerRendererChromium> {
public:
- static PassOwnPtr<LayerRendererChromium> create(PassOwnPtr<GraphicsContext3D> graphicsContext3D);
+ static PassRefPtr<LayerRendererChromium> create(PassOwnPtr<GraphicsContext3D> graphicsContext3D);
LayerRendererChromium(PassOwnPtr<GraphicsContext3D> graphicsContext3D);
~LayerRendererChromium();
@@ -81,8 +84,6 @@ public:
void setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; }
LayerChromium* rootLayer() { return m_rootLayer.get(); }
- void setNeedsDisplay() { m_needsDisplay = true; }
-
bool hardwareCompositing() const { return m_hardwareCompositing; }
void setRootLayerCanvasSize(const IntSize&);
@@ -90,6 +91,7 @@ public:
GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); }
unsigned createLayerTexture();
+ void deleteLayerTexture(unsigned);
static void debugGLCall(GraphicsContext3D*, const char* command, const char* file, int line);
@@ -102,6 +104,7 @@ public:
const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); }
const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); }
const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); }
+ const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); }
void resizeOnscreenContent(const IntSize&);
@@ -139,7 +142,6 @@ private:
RefPtr<LayerChromium> m_rootLayer;
- bool m_needsDisplay;
IntPoint m_scrollPosition;
bool m_hardwareCompositing;
@@ -170,6 +172,7 @@ private:
OwnPtr<LayerChromium::SharedValues> m_layerSharedValues;
OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues;
OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues;
+ OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues;
OwnPtr<GraphicsContext3D> m_context;
};
diff --git a/WebCore/platform/graphics/chromium/VDMXParser.cpp b/WebCore/platform/graphics/chromium/VDMXParser.cpp
index 3347226..bd30a97 100644
--- a/WebCore/platform/graphics/chromium/VDMXParser.cpp
+++ b/WebCore/platform/graphics/chromium/VDMXParser.cpp
@@ -31,7 +31,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/types.h>
// For htons/ntohs
#include <arpa/inet.h>
diff --git a/WebCore/platform/graphics/chromium/VideoFrameChromium.cpp b/WebCore/platform/graphics/chromium/VideoFrameChromium.cpp
new file mode 100644
index 0000000..43b40e2
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/VideoFrameChromium.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "VideoFrameChromium.h"
+
+namespace WebCore {
+
+const unsigned VideoFrameChromium::maxPlanes = 3;
+const unsigned VideoFrameChromium::numRGBPlanes = 1;
+const unsigned VideoFrameChromium::rgbPlane = 0;
+const unsigned VideoFrameChromium::numYUVPlanes = 3;
+const unsigned VideoFrameChromium::yPlane = 0;
+const unsigned VideoFrameChromium::uPlane = 1;
+const unsigned VideoFrameChromium::vPlane = 2;
+
+} // namespace WebCore
+
+
diff --git a/WebCore/platform/graphics/chromium/VideoFrameChromium.h b/WebCore/platform/graphics/chromium/VideoFrameChromium.h
index bbd677e..34e922b 100644
--- a/WebCore/platform/graphics/chromium/VideoFrameChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoFrameChromium.h
@@ -31,18 +31,20 @@
#ifndef VideoFrameChromium_h
#define VideoFrameChromium_h
+#include "IntSize.h"
+
namespace WebCore {
// A class that represents a video frame in chromium.
class VideoFrameChromium {
public:
- static const unsigned cMaxPlanes;
- static const unsigned cNumRGBPlanes;
- static const unsigned cRGBPlane;
- static const unsigned cNumYUVPlanes;
- static const unsigned cYPlane;
- static const unsigned cUPlane;
- static const unsigned cVPlane;
+ static const unsigned maxPlanes;
+ static const unsigned numRGBPlanes;
+ static const unsigned rgbPlane;
+ static const unsigned numYUVPlanes;
+ static const unsigned yPlane;
+ static const unsigned uPlane;
+ static const unsigned vPlane;
// These enums must be kept in sync with WebKit::WebVideoFrame.
enum Format {
@@ -74,6 +76,7 @@ public:
virtual unsigned planes() const = 0;
virtual int stride(unsigned plane) const = 0;
virtual const void* data(unsigned plane) const = 0;
+ virtual const IntSize requiredTextureSize(unsigned plane) const = 0;
};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index 0fb1bb4..26641a9 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -36,15 +36,134 @@
#include "GraphicsContext3D.h"
#include "LayerRendererChromium.h"
#include "RenderLayerBacking.h"
-#include "skia/ext/platform_canvas.h"
-
-#if PLATFORM(SKIA)
-#include "NativeImageSkia.h"
-#include "PlatformContextSkia.h"
-#endif
+#include "VideoFrameChromium.h"
+#include "VideoFrameProvider.h"
namespace WebCore {
+// These values are magic numbers that are used in the transformation
+// from YUV to RGB color values.
+const float VideoLayerChromium::yuv2RGB[9] = {
+ 1.f, 1.f, 1.f,
+ 0.f, -.344f, 1.772f,
+ 1.403f, -.714f, 0.f,
+};
+
+VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context)
+ : m_context(context)
+ , m_yuvShaderProgram(0)
+ , m_rgbaShaderProgram(0)
+ , m_yuvShaderMatrixLocation(0)
+ , m_yuvWidthScaleFactorLocation(0)
+ , m_rgbaShaderMatrixLocation(0)
+ , m_rgbaWidthScaleFactorLocation(0)
+ , m_ccMatrixLocation(0)
+ , m_yTextureLocation(0)
+ , m_uTextureLocation(0)
+ , m_vTextureLocation(0)
+ , m_rgbaTextureLocation(0)
+ , m_yuvAlphaLocation(0)
+ , m_rgbaAlphaLocation(0)
+ , m_initialized(false)
+{
+ // Frame textures are allocated based on stride width, not visible frame
+ // width, such that there is a guarantee that the frame rows line up
+ // properly and are not shifted by (stride - width) pixels. To hide the
+ // "padding" pixels between the edge of the visible frame width and the end
+ // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much
+ // of the width of the texture should be shown when drawing the texture onto
+ // the vertices.
+ char vertexShaderString[] =
+ "precision mediump float; \n"
+ "attribute vec4 a_position; \n"
+ "attribute vec2 a_texCoord; \n"
+ "uniform mat4 matrix; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform float widthScaleFactor; \n"
+ "void main() \n"
+ "{ \n"
+ " gl_Position = matrix * a_position; \n"
+ " v_texCoord = vec2(widthScaleFactor * a_texCoord.x, a_texCoord.y); \n"
+ "} \n";
+
+ char yuvFragmentShaderString[] =
+ "precision mediump float; \n"
+ "precision mediump int; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D y_texture; \n"
+ "uniform sampler2D u_texture; \n"
+ "uniform sampler2D v_texture; \n"
+ "uniform float alpha; \n"
+ "uniform mat3 cc_matrix; \n"
+ "void main() \n"
+ "{ \n"
+ " float y = texture2D(y_texture, v_texCoord).x; \n"
+ " float u = texture2D(u_texture, v_texCoord).r - .5; \n"
+ " float v = texture2D(v_texture, v_texCoord).r - .5; \n"
+ " vec3 rgb = cc_matrix * vec3(y, u, v); \n"
+ " gl_FragColor = vec4(rgb.x, rgb.y, rgb.z, 1.0) * alpha; \n"
+ "} \n";
+
+ char rgbaFragmentShaderString[] =
+ "precision mediump float; \n"
+ "varying vec2 v_texCoord; \n"
+ "uniform sampler2D rgba_texture; \n"
+ "uniform float alpha; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n"
+ " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n"
+ "} \n";
+
+ m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgbaFragmentShaderString);
+ if (!m_rgbaShaderProgram) {
+ LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program");
+ return;
+ }
+
+ m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvFragmentShaderString);
+ if (!m_yuvShaderProgram) {
+ LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program");
+ return;
+ }
+
+ m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "matrix");
+ m_yuvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProgram, "widthScaleFactor");
+ m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_texture");
+ m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_texture");
+ m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_texture");
+ m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_matrix");
+ m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alpha");
+
+ ASSERT(m_yuvShaderMatrixLocation != -1);
+ ASSERT(m_yuvWidthScaleFactorLocation != -1);
+ ASSERT(m_yTextureLocation != -1);
+ ASSERT(m_uTextureLocation != -1);
+ ASSERT(m_vTextureLocation != -1);
+ ASSERT(m_ccMatrixLocation != -1);
+ ASSERT(m_yuvAlphaLocation != -1);
+
+ m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "matrix");
+ m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "rgba_texture");
+ m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "widthScaleFactor");
+ m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "alpha");
+
+ ASSERT(m_rgbaShaderMatrixLocation != -1);
+ ASSERT(m_rgbaTextureLocation != -1);
+ ASSERT(m_rgbaWidthScaleFactorLocation != -1);
+ ASSERT(m_rgbaAlphaLocation != -1);
+
+ m_initialized = true;
+}
+
+VideoLayerChromium::SharedValues::~SharedValues()
+{
+ if (m_yuvShaderProgram)
+ GLC(m_context, m_context->deleteProgram(m_yuvShaderProgram));
+ if (m_rgbaShaderProgram)
+ GLC(m_context, m_context->deleteProgram(m_rgbaShaderProgram));
+}
+
PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner,
VideoFrameProvider* provider)
{
@@ -52,14 +171,25 @@ PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium*
}
VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider* provider)
- : ContentLayerChromium(owner)
-#if PLATFORM(SKIA)
- , m_canvas(0)
- , m_skiaContext(0)
-#endif
- , m_graphicsContext(0)
+ : LayerChromium(owner)
+ , m_skipsDraw(true)
+ , m_frameFormat(VideoFrameChromium::Invalid)
, m_provider(provider)
{
+ for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
+ m_textures[plane] = 0;
+ m_textureSizes[plane] = IntSize();
+ m_frameSizes[plane] = IntSize();
+ }
+}
+
+VideoLayerChromium::~VideoLayerChromium()
+{
+ GraphicsContext3D* context = layerRendererContext();
+ for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
+ if (m_textures[plane])
+ GLC(context, context->deleteTexture(m_textures[plane]));
+ }
}
void VideoLayerChromium::updateContents()
@@ -70,129 +200,176 @@ void VideoLayerChromium::updateContents()
ASSERT(drawsContent());
- IntRect dirtyRect(m_dirtyRect);
- IntSize requiredTextureSize;
-
-#if PLATFORM(SKIA)
- requiredTextureSize = m_bounds;
- IntRect boundsRect(IntPoint(0, 0), m_bounds);
-
- // If the texture needs to be reallocated, then we must redraw the entire
- // contents of the layer.
- if (requiredTextureSize != m_allocatedTextureSize)
- dirtyRect = boundsRect;
- else {
- // Clip the dirtyRect to the size of the layer to avoid drawing outside
- // the bounds of the backing texture.
- dirtyRect.intersect(boundsRect);
+ m_skipsDraw = false;
+ VideoFrameChromium* frame = m_provider->getCurrentFrame();
+ if (!frame) {
+ m_skipsDraw = true;
+ m_provider->putCurrentFrame(frame);
+ return;
}
- if (!m_canvas.get()
- || dirtyRect.width() != m_canvas->getDevice()->width()
- || dirtyRect.height() != m_canvas->getDevice()->height()) {
- m_canvas = new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), true);
- m_skiaContext = new PlatformContextSkia(m_canvas.get());
-
- // This is needed to get text to show up correctly.
- // FIXME: Does this take us down a very slow text rendering path?
- m_skiaContext->setDrawingToImageBuffer(true);
- m_graphicsContext = new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get()));
+ m_frameFormat = frame->format();
+ unsigned textureFormat = determineTextureFormat(frame);
+ if (textureFormat == GraphicsContext3D::INVALID_VALUE) {
+ // FIXME: Implement other paths.
+ notImplemented();
+ m_skipsDraw = true;
+ m_provider->putCurrentFrame(frame);
+ return;
}
- // Bring the canvas into the coordinate system of the paint rect.
- m_canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));
-
- // FIXME: Remove this test when tiled layers are implemented.
- m_skipsDraw = false;
- if (!layerRenderer()->checkTextureSize(requiredTextureSize)) {
+ // Allocate textures for planes if they are not allocated already, or
+ // reallocate textures that are the wrong size for the frame.
+ GraphicsContext3D* context = layerRendererContext();
+ bool texturesAllocated = allocateTexturesIfNeeded(context, frame, textureFormat);
+ if (!texturesAllocated) {
m_skipsDraw = true;
+ m_provider->putCurrentFrame(frame);
return;
}
- unsigned textureId = m_contentsTexture;
- if (!textureId)
- textureId = layerRenderer()->createLayerTexture();
-
- // If the texture id or size changed since last time, then we need to tell GL
- // to re-allocate a texture.
- if (m_contentsTexture != textureId || requiredTextureSize != m_allocatedTextureSize)
- createTextureRect(requiredTextureSize, dirtyRect, textureId);
- else
- updateTextureRect(dirtyRect, textureId);
-#else
- // FIXME: Implement non-skia path
- notImplemented();
-#endif
+ // Update texture planes.
+ for (unsigned plane = 0; plane < frame->planes(); plane++) {
+ ASSERT(frame->requiredTextureSize(plane) == m_textureSizes[plane]);
+ updateTexture(context, m_textures[plane], frame->requiredTextureSize(plane), textureFormat, frame->data(plane));
+ }
+
+ m_dirtyRect.setSize(FloatSize());
+ m_contentsDirty = false;
+ m_provider->putCurrentFrame(frame);
}
-void VideoLayerChromium::createTextureRect(const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId)
+unsigned VideoLayerChromium::determineTextureFormat(VideoFrameChromium* frame)
{
- // Paint into graphics context and get bitmap.
- m_owner->paintGraphicsLayerContents(*m_graphicsContext, updateRect);
- void* pixels = 0;
- IntSize bitmapSize = IntSize();
-#if PLATFORM(SKIA)
- const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false);
- const SkBitmap* skiaBitmap = &bitmap;
- ASSERT(skiaBitmap);
-
- SkAutoLockPixels lock(*skiaBitmap);
- SkBitmap::Config skiaConfig = skiaBitmap->config();
- // FIXME: Do we need to support more image configurations?
- if (skiaConfig == SkBitmap::kARGB_8888_Config) {
- pixels = skiaBitmap->getPixels();
- bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
+ switch (frame->format()) {
+ case VideoFrameChromium::YV12:
+ return GraphicsContext3D::LUMINANCE;
+ case VideoFrameChromium::RGBA:
+ return GraphicsContext3D::RGBA;
+ default:
+ break;
}
-#else
- // FIXME: Implement non-skia path
- notImplemented();
-#endif
- if (!pixels)
- return;
+ return GraphicsContext3D::INVALID_VALUE;
+}
- GraphicsContext3D* context = layerRendererContext();
- context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
- ASSERT(bitmapSize == requiredTextureSize);
- context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, requiredTextureSize.width(), requiredTextureSize.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels);
+bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, VideoFrameChromium* frame, unsigned textureFormat)
+{
+ ASSERT(context);
+ ASSERT(frame);
+
+ for (unsigned plane = 0; plane < frame->planes(); plane++) {
+ IntSize planeTextureSize = frame->requiredTextureSize(plane);
- m_contentsTexture = textureId;
- m_allocatedTextureSize = requiredTextureSize;
+ // If the renderer cannot handle this large of a texture, return false.
+ // FIXME: Remove this test when tiled layers are implemented.
+ if (!layerRenderer()->checkTextureSize(planeTextureSize))
+ return false;
- updateCompleted();
+ if (!m_textures[plane])
+ m_textures[plane] = layerRenderer()->createLayerTexture();
+
+ if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) {
+ allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat);
+ m_textureSizes[plane] = planeTextureSize;
+ m_frameSizes[plane] = IntSize(frame->width(), frame->height());
+ }
+ }
+ return true;
+}
+
+void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat)
+{
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+ GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE, 0));
}
-void VideoLayerChromium::updateTextureRect(const IntRect& updateRect, unsigned textureId)
+void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data)
{
-#if PLATFORM(SKIA)
- const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(true);
- SkBitmap* skiaBitmap = const_cast<SkBitmap*>(&bitmap);
- ASSERT(skiaBitmap);
-
- SkAutoLockPixels lock(*skiaBitmap);
- SkBitmap::Config skiaConfig = skiaBitmap->config();
-
- if (skiaConfig == SkBitmap::kARGB_8888_Config) {
- GraphicsContext3D* context = layerRendererContext();
- context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
- ASSERT(context->supportsMapSubCHROMIUM());
- void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY);
- skiaBitmap->setPixels(mem);
- m_owner->paintGraphicsLayerContents(*m_graphicsContext, updateRect);
- context->unmapTexSubImage2DCHROMIUM(mem);
+ ASSERT(context);
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
+ void* mem = context->mapTexSubImage2DCHROMIUM(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, GraphicsContext3D::WRITE_ONLY);
+ if (mem) {
+ memcpy(mem, data, dimensions.width() * dimensions.height());
+ GLC(context, context->unmapTexSubImage2DCHROMIUM(mem));
+ } else {
+ // FIXME: We should have some sort of code to handle the case when
+ // mapTexSubImage2D fails.
+ m_skipsDraw = true;
}
+}
+
+void VideoLayerChromium::draw()
+{
+ if (m_skipsDraw)
+ return;
+
+ ASSERT(layerRenderer());
+ const VideoLayerChromium::SharedValues* sv = layerRenderer()->videoLayerSharedValues();
+ ASSERT(sv && sv->initialized());
- updateCompleted();
-#else
- // FIXME: Implement non-skia path
- notImplemented();
-#endif
+ switch (m_frameFormat) {
+ case VideoFrameChromium::YV12:
+ drawYUV(sv);
+ break;
+ case VideoFrameChromium::RGBA:
+ drawRGBA(sv);
+ break;
+ default:
+ // FIXME: Implement other paths.
+ notImplemented();
+ break;
+ }
}
-void VideoLayerChromium::updateCompleted()
+void VideoLayerChromium::drawYUV(const SharedValues* sv)
{
- m_dirtyRect.setSize(FloatSize());
- m_contentsDirty = false;
+ GraphicsContext3D* context = layerRendererContext();
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::yPlane]));
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::uPlane]));
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane]));
+
+ layerRenderer()->useShader(sv->yuvShaderProgram());
+ unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width();
+ unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width();
+ float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
+ GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor));
+
+ GLC(context, context->uniform1i(sv->yTextureLocation(), 1));
+ GLC(context, context->uniform1i(sv->uTextureLocation(), 2));
+ GLC(context, context->uniform1i(sv->vTextureLocation(), 3));
+
+ GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1));
+
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation());
+
+ // Reset active texture back to texture 0.
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
}
+void VideoLayerChromium::drawRGBA(const SharedValues* sv)
+{
+ GraphicsContext3D* context = layerRendererContext();
+ GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0));
+ GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane]));
+
+ layerRenderer()->useShader(sv->rgbaShaderProgram());
+ unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width();
+ unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width();
+ float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth;
+ GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor));
+
+ GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0));
+
+ drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation());
}
+
+} // namespace WebCore
+
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
index 3507cb2..620d1a7 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.h
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.h
@@ -34,31 +34,76 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "ContentLayerChromium.h"
+#include "LayerChromium.h"
#include "VideoFrameProvider.h"
namespace WebCore {
// A Layer that contains a Video element.
-class VideoLayerChromium : public ContentLayerChromium {
+class VideoLayerChromium : public LayerChromium {
public:
static PassRefPtr<VideoLayerChromium> create(GraphicsLayerChromium* owner = 0,
VideoFrameProvider* = 0);
- virtual bool drawsContent() { return true; }
+ virtual ~VideoLayerChromium();
virtual void updateContents();
+ virtual bool drawsContent() { return true; }
+ virtual void draw();
+
+ class SharedValues {
+ public:
+ explicit SharedValues(GraphicsContext3D*);
+ ~SharedValues();
+ unsigned yuvShaderProgram() const { return m_yuvShaderProgram; }
+ unsigned rgbaShaderProgram() const { return m_rgbaShaderProgram; }
+ int yuvShaderMatrixLocation() const { return m_yuvShaderMatrixLocation; }
+ int rgbaShaderMatrixLocation() const { return m_rgbaShaderMatrixLocation; }
+ int yuvWidthScaleFactorLocation() const { return m_yuvWidthScaleFactorLocation; }
+ int rgbaWidthScaleFactorLocation() const { return m_rgbaWidthScaleFactorLocation; }
+ int yTextureLocation() const { return m_yTextureLocation; }
+ int uTextureLocation() const { return m_uTextureLocation; }
+ int vTextureLocation() const { return m_vTextureLocation; }
+ int yuvAlphaLocation() const { return m_yuvAlphaLocation; }
+ int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; }
+ int rgbaTextureLocation() const { return m_rgbaTextureLocation; }
+ int ccMatrixLocation() const { return m_ccMatrixLocation; }
+ bool initialized() const { return m_initialized; };
+ private:
+ GraphicsContext3D* m_context;
+ unsigned m_yuvShaderProgram;
+ unsigned m_rgbaShaderProgram;
+ int m_yuvShaderMatrixLocation;
+ int m_yuvWidthScaleFactorLocation;
+ int m_rgbaShaderMatrixLocation;
+ int m_rgbaWidthScaleFactorLocation;
+ int m_ccMatrixLocation;
+ int m_yTextureLocation;
+ int m_uTextureLocation;
+ int m_vTextureLocation;
+ int m_rgbaTextureLocation;
+ int m_yuvAlphaLocation;
+ int m_rgbaAlphaLocation;
+ bool m_initialized;
+ };
private:
VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*);
- void createTextureRect(const IntSize& requiredTextureSize, const IntRect& updateRect, unsigned textureId);
- void updateTextureRect(const IntRect& updateRect, unsigned textureId);
- void updateCompleted();
+ static unsigned determineTextureFormat(VideoFrameChromium*);
+ bool allocateTexturesIfNeeded(GraphicsContext3D*, VideoFrameChromium*, unsigned textureFormat);
+ void updateYUVContents(GraphicsContext3D*, const VideoFrameChromium*);
+ void updateRGBAContents(GraphicsContext3D*, const VideoFrameChromium*);
+ void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat);
+ void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data);
+ void drawYUV(const SharedValues*);
+ void drawRGBA(const SharedValues*);
-#if PLATFORM(SKIA)
- OwnPtr<skia::PlatformCanvas> m_canvas;
- OwnPtr<PlatformContextSkia> m_skiaContext;
-#endif
- OwnPtr<GraphicsContext> m_graphicsContext;
+ static const float yuv2RGB[9];
+
+ bool m_skipsDraw;
+ VideoFrameChromium::Format m_frameFormat;
OwnPtr<VideoFrameProvider> m_provider;
+ unsigned m_textures[3];
+ IntSize m_textureSizes[3];
+ IntSize m_frameSizes[3];
};
}
diff --git a/WebCore/platform/graphics/filters/DistantLightSource.h b/WebCore/platform/graphics/filters/DistantLightSource.h
new file mode 100644
index 0000000..d5d474f
--- /dev/null
+++ b/WebCore/platform/graphics/filters/DistantLightSource.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef DistantLightSource_h
+#define DistantLightSource_h
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+namespace WebCore {
+
+class DistantLightSource : public LightSource {
+public:
+ static PassRefPtr<DistantLightSource> create(float azimuth, float elevation)
+ {
+ return adoptRef(new DistantLightSource(azimuth, elevation));
+ }
+
+ float azimuth() const { return m_azimuth; }
+ float elevation() const { return m_elevation; }
+
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+
+private:
+ DistantLightSource(float azimuth, float elevation)
+ : LightSource(LS_DISTANT)
+ , m_azimuth(azimuth)
+ , m_elevation(elevation)
+ {
+ }
+
+ float m_azimuth;
+ float m_elevation;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // DistantLightSource_h
diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp
index acd6545..4185f61 100644
--- a/WebCore/platform/graphics/filters/FEBlend.cpp
+++ b/WebCore/platform/graphics/filters/FEBlend.cpp
@@ -1,24 +1,24 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
- 2009 Dirk Schulze <krit@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#include "config.h"
@@ -98,13 +98,13 @@ void FEBlend::apply(Filter* filter)
if (m_mode == FEBLEND_MODE_UNKNOWN)
return;
- if (!getEffectContext())
+ if (!effectContext())
return;
- IntRect effectADrawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates());
+ IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
- IntRect effectBDrawingRect = calculateDrawingIntRect(in2->repaintRectInLocalCoordinates());
+ IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());
IntRect imageRect(IntPoint(), resultImage()->size());
diff --git a/WebCore/platform/graphics/filters/FEBlend.h b/WebCore/platform/graphics/filters/FEBlend.h
index 2e67588..a6569e2 100644
--- a/WebCore/platform/graphics/filters/FEBlend.h
+++ b/WebCore/platform/graphics/filters/FEBlend.h
@@ -1,23 +1,23 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef FEBlend_h
#define FEBlend_h
@@ -29,31 +29,32 @@
namespace WebCore {
- enum BlendModeType {
- FEBLEND_MODE_UNKNOWN = 0,
- FEBLEND_MODE_NORMAL = 1,
- FEBLEND_MODE_MULTIPLY = 2,
- FEBLEND_MODE_SCREEN = 3,
- FEBLEND_MODE_DARKEN = 4,
- FEBLEND_MODE_LIGHTEN = 5
- };
+enum BlendModeType {
+ FEBLEND_MODE_UNKNOWN = 0,
+ FEBLEND_MODE_NORMAL = 1,
+ FEBLEND_MODE_MULTIPLY = 2,
+ FEBLEND_MODE_SCREEN = 3,
+ FEBLEND_MODE_DARKEN = 4,
+ FEBLEND_MODE_LIGHTEN = 5
+};
- class FEBlend : public FilterEffect {
- public:
- static PassRefPtr<FEBlend> create(BlendModeType);
+class FEBlend : public FilterEffect {
+public:
+ static PassRefPtr<FEBlend> create(BlendModeType);
- BlendModeType blendMode() const;
- void setBlendMode(BlendModeType);
+ BlendModeType blendMode() const;
+ void setBlendMode(BlendModeType);
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
+ virtual void apply(Filter*);
+ virtual void dump();
- private:
- FEBlend(BlendModeType);
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- BlendModeType m_mode;
- };
+private:
+ FEBlend(BlendModeType);
+
+ BlendModeType m_mode;
+};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index 1d9c66b..86c37c2 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -1,24 +1,24 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
- 2009 Dirk Schulze <krit@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#include "config.h"
@@ -160,11 +160,11 @@ void FEColorMatrix::apply(Filter* filter)
if (!in->resultImage())
return;
- GraphicsContext* filterContext = getEffectContext();
+ GraphicsContext* filterContext = effectContext();
if (!filterContext)
return;
- filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
IntRect imageRect(IntPoint(), resultImage()->size());
PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect));
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.h b/WebCore/platform/graphics/filters/FEColorMatrix.h
index 9b9084c..b898b17 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.h
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.h
@@ -1,23 +1,23 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef FEColorMatrix_h
#define FEColorMatrix_h
@@ -30,34 +30,35 @@
namespace WebCore {
- enum ColorMatrixType {
- FECOLORMATRIX_TYPE_UNKNOWN = 0,
- FECOLORMATRIX_TYPE_MATRIX = 1,
- FECOLORMATRIX_TYPE_SATURATE = 2,
- FECOLORMATRIX_TYPE_HUEROTATE = 3,
- FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4
- };
+enum ColorMatrixType {
+ FECOLORMATRIX_TYPE_UNKNOWN = 0,
+ FECOLORMATRIX_TYPE_MATRIX = 1,
+ FECOLORMATRIX_TYPE_SATURATE = 2,
+ FECOLORMATRIX_TYPE_HUEROTATE = 3,
+ FECOLORMATRIX_TYPE_LUMINANCETOALPHA = 4
+};
+
+class FEColorMatrix : public FilterEffect {
+public:
+ static PassRefPtr<FEColorMatrix> create(ColorMatrixType, const Vector<float>&);
- class FEColorMatrix : public FilterEffect {
- public:
- static PassRefPtr<FEColorMatrix> create(ColorMatrixType, const Vector<float>&);
+ ColorMatrixType type() const;
+ void setType(ColorMatrixType);
- ColorMatrixType type() const;
- void setType(ColorMatrixType);
+ const Vector<float>& values() const;
+ void setValues(const Vector<float>&);
- const Vector<float>& values() const;
- void setValues(const Vector<float>&);
+ virtual void apply(Filter*);
+ virtual void dump();
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- private:
- FEColorMatrix(ColorMatrixType, const Vector<float>&);
+private:
+ FEColorMatrix(ColorMatrixType, const Vector<float>&);
- ColorMatrixType m_type;
- Vector<float> m_values;
- };
+ ColorMatrixType m_type;
+ Vector<float> m_values;
+};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index 471fec8..6fe38e4 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -1,25 +1,25 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
- 2009 Dirk Schulze <krit@webkit.org>
- Copyright (C) Research In Motion Limited 2010. All rights reserved.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#include "config.h"
@@ -36,8 +36,8 @@ namespace WebCore {
typedef void (*TransferType)(unsigned char*, const ComponentTransferFunction&);
-FEComponentTransfer::FEComponentTransfer(const ComponentTransferFunction& redFunc,
- const ComponentTransferFunction& greenFunc, const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc)
+FEComponentTransfer::FEComponentTransfer(const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc,
+ const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc)
: FilterEffect()
, m_redFunc(redFunc)
, m_greenFunc(greenFunc)
@@ -154,7 +154,7 @@ void FEComponentTransfer::apply(Filter* filter)
if (!in->resultImage())
return;
- if (!getEffectContext())
+ if (!effectContext())
return;
unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
@@ -167,7 +167,7 @@ void FEComponentTransfer::apply(Filter* filter)
for (unsigned channel = 0; channel < 4; channel++)
(*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
- IntRect drawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates());
+ IntRect drawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect));
CanvasPixelArray* srcPixelArray(imageData->data());
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.h b/WebCore/platform/graphics/filters/FEComponentTransfer.h
index 55724db..d3145d4 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.h
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.h
@@ -1,23 +1,23 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef FEComponentTransfer_h
#define FEComponentTransfer_h
@@ -30,67 +30,68 @@
namespace WebCore {
- enum ComponentTransferType {
- FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0,
- FECOMPONENTTRANSFER_TYPE_IDENTITY = 1,
- FECOMPONENTTRANSFER_TYPE_TABLE = 2,
- FECOMPONENTTRANSFER_TYPE_DISCRETE = 3,
- FECOMPONENTTRANSFER_TYPE_LINEAR = 4,
- FECOMPONENTTRANSFER_TYPE_GAMMA = 5
- };
-
- struct ComponentTransferFunction {
- ComponentTransferFunction()
- : type(FECOMPONENTTRANSFER_TYPE_UNKNOWN)
- , slope(0.0f)
- , intercept(0.0f)
- , amplitude(0.0f)
- , exponent(0.0f)
- , offset(0.0f)
- {
- }
-
- ComponentTransferType type;
-
- float slope;
- float intercept;
- float amplitude;
- float exponent;
- float offset;
-
- Vector<float> tableValues;
- };
-
- class FEComponentTransfer : public FilterEffect {
- public:
- static PassRefPtr<FEComponentTransfer> create(const ComponentTransferFunction&,
- const ComponentTransferFunction&, const ComponentTransferFunction&, const ComponentTransferFunction&);
-
- ComponentTransferFunction redFunction() const;
- void setRedFunction(const ComponentTransferFunction&);
-
- ComponentTransferFunction greenFunction() const;
- void setGreenFunction(const ComponentTransferFunction&);
-
- ComponentTransferFunction blueFunction() const;
- void setBlueFunction(const ComponentTransferFunction&);
-
- ComponentTransferFunction alphaFunction() const;
- void setAlphaFunction(const ComponentTransferFunction&);
-
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
-
- private:
- FEComponentTransfer(const ComponentTransferFunction&, const ComponentTransferFunction&,
- const ComponentTransferFunction&, const ComponentTransferFunction&);
-
- ComponentTransferFunction m_redFunc;
- ComponentTransferFunction m_greenFunc;
- ComponentTransferFunction m_blueFunc;
- ComponentTransferFunction m_alphaFunc;
- };
+enum ComponentTransferType {
+ FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0,
+ FECOMPONENTTRANSFER_TYPE_IDENTITY = 1,
+ FECOMPONENTTRANSFER_TYPE_TABLE = 2,
+ FECOMPONENTTRANSFER_TYPE_DISCRETE = 3,
+ FECOMPONENTTRANSFER_TYPE_LINEAR = 4,
+ FECOMPONENTTRANSFER_TYPE_GAMMA = 5
+};
+
+struct ComponentTransferFunction {
+ ComponentTransferFunction()
+ : type(FECOMPONENTTRANSFER_TYPE_UNKNOWN)
+ , slope(0)
+ , intercept(0)
+ , amplitude(0)
+ , exponent(0)
+ , offset(0)
+ {
+ }
+
+ ComponentTransferType type;
+
+ float slope;
+ float intercept;
+ float amplitude;
+ float exponent;
+ float offset;
+
+ Vector<float> tableValues;
+};
+
+class FEComponentTransfer : public FilterEffect {
+public:
+ static PassRefPtr<FEComponentTransfer> create(const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc,
+ const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc);
+
+ ComponentTransferFunction redFunction() const;
+ void setRedFunction(const ComponentTransferFunction&);
+
+ ComponentTransferFunction greenFunction() const;
+ void setGreenFunction(const ComponentTransferFunction&);
+
+ ComponentTransferFunction blueFunction() const;
+ void setBlueFunction(const ComponentTransferFunction&);
+
+ ComponentTransferFunction alphaFunction() const;
+ void setAlphaFunction(const ComponentTransferFunction&);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEComponentTransfer(const ComponentTransferFunction& redFunc, const ComponentTransferFunction& greenFunc,
+ const ComponentTransferFunction& blueFunc, const ComponentTransferFunction& alphaFunc);
+
+ ComponentTransferFunction m_redFunc;
+ ComponentTransferFunction m_greenFunc;
+ ComponentTransferFunction m_blueFunc;
+ ComponentTransferFunction m_alphaFunc;
+};
} // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index c10a0f2..94e2524 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -1,24 +1,24 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
- 2009 Dirk Schulze <krit@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#include "config.h"
@@ -122,39 +122,39 @@ void FEComposite::apply(Filter* filter)
if (!in->resultImage() || !in2->resultImage())
return;
- GraphicsContext* filterContext = getEffectContext();
+ GraphicsContext* filterContext = effectContext();
if (!filterContext)
return;
- FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f);
+ FloatRect srcRect = FloatRect(0, 0, -1, -1);
switch (m_type) {
case FECOMPOSITE_OPERATOR_OVER:
- filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates()));
- filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
break;
case FECOMPOSITE_OPERATOR_IN:
filterContext->save();
- filterContext->clipToImageBuffer(in2->resultImage(), calculateDrawingRect(in2->repaintRectInLocalCoordinates()));
- filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()));
+ filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
filterContext->restore();
break;
case FECOMPOSITE_OPERATOR_OUT:
- filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()));
- filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut);
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut);
break;
case FECOMPOSITE_OPERATOR_ATOP:
- filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates()));
- filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop);
+ filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop);
break;
case FECOMPOSITE_OPERATOR_XOR:
- filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, calculateDrawingRect(in2->repaintRectInLocalCoordinates()));
- filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, calculateDrawingRect(in->repaintRectInLocalCoordinates()), srcRect, CompositeXOR);
+ filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeXOR);
break;
case FECOMPOSITE_OPERATOR_ARITHMETIC: {
- IntRect effectADrawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates());
+ IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
- IntRect effectBDrawingRect = calculateDrawingIntRect(in2->repaintRectInLocalCoordinates());
+ IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect));
CanvasPixelArray* srcPixelArrayB(imageData->data());
diff --git a/WebCore/platform/graphics/filters/FEComposite.h b/WebCore/platform/graphics/filters/FEComposite.h
index 448d036..82a3b06 100644
--- a/WebCore/platform/graphics/filters/FEComposite.h
+++ b/WebCore/platform/graphics/filters/FEComposite.h
@@ -1,23 +1,23 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef FEComposite_h
#define FEComposite_h
@@ -59,9 +59,10 @@ public:
float k4() const;
void setK4(float);
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
private:
FEComposite(const CompositeOperationType&, float, float, float, float);
diff --git a/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
new file mode 100644
index 0000000..dd66c6a
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
@@ -0,0 +1,471 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEConvolveMatrix.h"
+
+#include "CanvasPixelArray.h"
+#include "Filter.h"
+#include "ImageData.h"
+
+namespace WebCore {
+
+FEConvolveMatrix::FEConvolveMatrix(const IntSize& kernelSize,
+ float divisor, float bias, const IntPoint& targetOffset, EdgeModeType edgeMode,
+ const FloatPoint& kernelUnitLength, bool preserveAlpha, const Vector<float>& kernelMatrix)
+ : FilterEffect()
+ , m_kernelSize(kernelSize)
+ , m_divisor(divisor)
+ , m_bias(bias)
+ , m_targetOffset(targetOffset)
+ , m_edgeMode(edgeMode)
+ , m_kernelUnitLength(kernelUnitLength)
+ , m_preserveAlpha(preserveAlpha)
+ , m_kernelMatrix(kernelMatrix)
+{
+}
+
+PassRefPtr<FEConvolveMatrix> FEConvolveMatrix::create(const IntSize& kernelSize,
+ float divisor, float bias, const IntPoint& targetOffset, EdgeModeType edgeMode,
+ const FloatPoint& kernelUnitLength, bool preserveAlpha, const Vector<float>& kernelMatrix)
+{
+ return adoptRef(new FEConvolveMatrix(kernelSize, divisor, bias, targetOffset, edgeMode, kernelUnitLength,
+ preserveAlpha, kernelMatrix));
+}
+
+
+IntSize FEConvolveMatrix::kernelSize() const
+{
+ return m_kernelSize;
+}
+
+void FEConvolveMatrix::setKernelSize(IntSize kernelSize)
+{
+ m_kernelSize = kernelSize;
+}
+
+const Vector<float>& FEConvolveMatrix::kernel() const
+{
+ return m_kernelMatrix;
+}
+
+void FEConvolveMatrix::setKernel(const Vector<float>& kernel)
+{
+ m_kernelMatrix = kernel;
+}
+
+float FEConvolveMatrix::divisor() const
+{
+ return m_divisor;
+}
+
+void FEConvolveMatrix::setDivisor(float divisor)
+{
+ m_divisor = divisor;
+}
+
+float FEConvolveMatrix::bias() const
+{
+ return m_bias;
+}
+
+void FEConvolveMatrix::setBias(float bias)
+{
+ m_bias = bias;
+}
+
+IntPoint FEConvolveMatrix::targetOffset() const
+{
+ return m_targetOffset;
+}
+
+void FEConvolveMatrix::setTargetOffset(IntPoint targetOffset)
+{
+ m_targetOffset = targetOffset;
+}
+
+EdgeModeType FEConvolveMatrix::edgeMode() const
+{
+ return m_edgeMode;
+}
+
+void FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode)
+{
+ m_edgeMode = edgeMode;
+}
+
+FloatPoint FEConvolveMatrix::kernelUnitLength() const
+{
+ return m_kernelUnitLength;
+}
+
+void FEConvolveMatrix::setKernelUnitLength(FloatPoint kernelUnitLength)
+{
+ m_kernelUnitLength = kernelUnitLength;
+}
+
+bool FEConvolveMatrix::preserveAlpha() const
+{
+ return m_preserveAlpha;
+}
+
+void FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha)
+{
+ m_preserveAlpha = preserveAlpha;
+}
+
+/*
+ -----------------------------------
+ ConvolveMatrix implementation
+ -----------------------------------
+
+ The image rectangle is split in the following way:
+
+ +---------------------+
+ | A |
+ +---------------------+
+ | | | |
+ | B | C | D |
+ | | | |
+ +---------------------+
+ | E |
+ +---------------------+
+
+ Where region C contains those pixels, whose values
+ can be calculated without crossing the edge of the rectangle.
+
+ Example:
+ Image size: width: 10, height: 10
+
+ Order (kernel matrix size): width: 3, height 4
+ Target: x:1, y:3
+
+ The following figure shows the target inside the kernel matrix:
+
+ ...
+ ...
+ ...
+ .X.
+
+ The regions in this case are the following:
+ Note: (x1, y1) top-left and (x2, y2) is the bottom-right corner
+ Note: row x2 and column y2 is not part of the region
+ only those (x, y) pixels, where x1 <= x < x2 and y1 <= y < y2
+
+ Region A: x1: 0, y1: 0, x2: 10, y2: 3
+ Region B: x1: 0, y1: 3, x2: 1, y2: 10
+ Region C: x1: 1, y1: 3, x2: 9, y2: 10
+ Region D: x1: 9, y1: 3, x2: 10, y2: 10
+ Region E: x1: 0, y1: 10, x2: 10, y2: 10 (empty region)
+
+ Since region C (often) contains most of the pixels, we implemented
+ a fast algoritm to calculate these values, called fastSetInteriorPixels.
+ For other regions, fastSetOuterPixels is used, which calls getPixelValue,
+ to handle pixels outside of the image. In a rare situations, when
+ kernel matrix is bigger than the image, all pixels are calculated by this
+ function.
+
+ Although these two functions have lot in common, I decided not to make
+ common a template for them, since there are key differences as well,
+ and would make it really hard to understand.
+*/
+
+static ALWAYS_INLINE unsigned char clampRGBAValue(float channel, unsigned char max = 255)
+{
+ if (channel <= 0)
+ return 0;
+ if (channel >= max)
+ return max;
+ return channel;
+}
+
+template<bool preserveAlphaValues>
+ALWAYS_INLINE void setDestinationPixels(CanvasPixelArray* image, int& pixel, float* totals, float divisor, float bias, CanvasPixelArray* src)
+{
+ unsigned char maxAlpha = preserveAlphaValues ? 255 : clampRGBAValue(totals[3] / divisor + bias);
+ for (int i = 0; i < 3; ++i)
+ image->set(pixel++, clampRGBAValue(totals[i] / divisor + bias, maxAlpha));
+
+ if (preserveAlphaValues) {
+ image->set(pixel, src->get(pixel));
+ ++pixel;
+ } else
+ image->set(pixel++, maxAlpha);
+}
+
+// Only for region C
+template<bool preserveAlphaValues>
+ALWAYS_INLINE void FEConvolveMatrix::fastSetInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom)
+{
+ // edge mode does not affect these pixels
+ int pixel = (m_targetOffset.y() * paintingData.width + m_targetOffset.x()) * 4;
+ int startKernelPixel = 0;
+ int kernelIncrease = clipRight * 4;
+ int xIncrease = (m_kernelSize.width() - 1) * 4;
+ // Contains the sum of rgb(a) components
+ float totals[3 + (preserveAlphaValues ? 0 : 1)];
+
+ // m_divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
+ ASSERT(m_divisor);
+
+ for (int y = clipBottom + 1; y > 0; --y) {
+ for (int x = clipRight + 1; x > 0; --x) {
+ int kernelValue = m_kernelMatrix.size() - 1;
+ int kernelPixel = startKernelPixel;
+ int width = m_kernelSize.width();
+
+ totals[0] = 0;
+ totals[1] = 0;
+ totals[2] = 0;
+ if (!preserveAlphaValues)
+ totals[3] = 0;
+
+ while (kernelValue >= 0) {
+ totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel++));
+ totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel++));
+ totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel++));
+ if (!preserveAlphaValues)
+ totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(kernelPixel));
+ ++kernelPixel;
+ --kernelValue;
+ if (!--width) {
+ kernelPixel += kernelIncrease;
+ width = m_kernelSize.width();
+ }
+ }
+
+ setDestinationPixels<preserveAlphaValues>(paintingData.dstPixelArray, pixel, totals, m_divisor, paintingData.bias, paintingData.srcPixelArray);
+ startKernelPixel += 4;
+ }
+ pixel += xIncrease;
+ startKernelPixel += xIncrease;
+ }
+}
+
+ALWAYS_INLINE int FEConvolveMatrix::getPixelValue(PaintingData& paintingData, int x, int y)
+{
+ if (x >= 0 && x < paintingData.width && x >= 0 && y < paintingData.height)
+ return (y * paintingData.width + x) << 2;
+
+ switch (m_edgeMode) {
+ default: // EDGEMODE_NONE
+ return -1;
+ case EDGEMODE_DUPLICATE:
+ if (x < 0)
+ x = 0;
+ else if (x >= paintingData.width)
+ x = paintingData.width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= paintingData.height)
+ y = paintingData.height - 1;
+ return (y * paintingData.width + x) << 2;
+ case EDGEMODE_WRAP:
+ while (x < 0)
+ x += paintingData.width;
+ x %= paintingData.width;
+ while (y < 0)
+ y += paintingData.height;
+ y %= paintingData.height;
+ return (y * paintingData.width + x) << 2;
+ }
+}
+
+// For other regions than C
+template<bool preserveAlphaValues>
+void FEConvolveMatrix::fastSetOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
+{
+ int pixel = (y1 * paintingData.width + x1) * 4;
+ int height = y2 - y1;
+ int width = x2 - x1;
+ int beginKernelPixelX = x1 - m_targetOffset.x();
+ int startKernelPixelX = beginKernelPixelX;
+ int startKernelPixelY = y1 - m_targetOffset.y();
+ int xIncrease = (paintingData.width - width) * 4;
+ // Contains the sum of rgb(a) components
+ float totals[3 + (preserveAlphaValues ? 0 : 1)];
+
+ // m_divisor cannot be 0, SVGFEConvolveMatrixElement ensures this
+ ASSERT(m_divisor);
+
+ for (int y = height; y > 0; --y) {
+ for (int x = width; x > 0; --x) {
+ int kernelValue = m_kernelMatrix.size() - 1;
+ int kernelPixelX = startKernelPixelX;
+ int kernelPixelY = startKernelPixelY;
+ int width = m_kernelSize.width();
+
+ totals[0] = 0;
+ totals[1] = 0;
+ totals[2] = 0;
+ if (!preserveAlphaValues)
+ totals[3] = 0;
+
+ while (kernelValue >= 0) {
+ int pixelIndex = getPixelValue(paintingData, kernelPixelX, kernelPixelY);
+ if (pixelIndex >= 0) {
+ totals[0] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex));
+ totals[1] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex + 1));
+ totals[2] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex + 2));
+ }
+ if (!preserveAlphaValues && pixelIndex >= 0)
+ totals[3] += m_kernelMatrix[kernelValue] * static_cast<float>(paintingData.srcPixelArray->get(pixelIndex + 3));
+ ++kernelPixelX;
+ --kernelValue;
+ if (!--width) {
+ kernelPixelX = startKernelPixelX;
+ ++kernelPixelY;
+ width = m_kernelSize.width();
+ }
+ }
+
+ setDestinationPixels<preserveAlphaValues>(paintingData.dstPixelArray, pixel, totals, m_divisor, paintingData.bias, paintingData.srcPixelArray);
+ ++startKernelPixelX;
+ }
+ pixel += xIncrease;
+ startKernelPixelX = beginKernelPixelX;
+ ++startKernelPixelY;
+ }
+}
+
+ALWAYS_INLINE void FEConvolveMatrix::setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom)
+{
+ // Must be implemented here, since it refers another ALWAYS_INLINE
+ // function, which defined in this C++ source file as well
+ if (m_preserveAlpha)
+ fastSetInteriorPixels<true>(paintingData, clipRight, clipBottom);
+ else
+ fastSetInteriorPixels<false>(paintingData, clipRight, clipBottom);
+}
+
+ALWAYS_INLINE void FEConvolveMatrix::setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2)
+{
+ // Although this function can be moved to the header, it is implemented here
+ // because setInteriorPixels is also implemented here
+ if (m_preserveAlpha)
+ fastSetOuterPixels<true>(paintingData, x1, y1, x2, y2);
+ else
+ fastSetOuterPixels<false>(paintingData, x1, y1, x2, y2);
+}
+
+void FEConvolveMatrix::apply(Filter* filter)
+{
+ FilterEffect* in = inputEffect(0);
+ in->apply(filter);
+ if (!in->resultImage())
+ return;
+
+ if (!effectContext())
+ return;
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->filterPrimitiveSubregion());
+
+ RefPtr<CanvasPixelArray> srcPixelArray;
+ if (m_preserveAlpha)
+ srcPixelArray = in->resultImage()->getUnmultipliedImageData(effectDrawingRect)->data();
+ else
+ srcPixelArray = in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data();
+
+ RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
+
+ PaintingData paintingData;
+ paintingData.srcPixelArray = srcPixelArray.get();
+ paintingData.dstPixelArray = imageData->data();
+ paintingData.width = imageRect.width();
+ paintingData.height = imageRect.height();
+ paintingData.bias = m_bias * 255;
+
+ // Drawing fully covered pixels
+ int clipRight = imageRect.width() - m_kernelSize.width();
+ int clipBottom = imageRect.height() - m_kernelSize.height();
+
+ if (clipRight >= 0 && clipBottom >= 0) {
+ setInteriorPixels(paintingData, clipRight, clipBottom);
+
+ clipRight += m_targetOffset.x() + 1;
+ clipBottom += m_targetOffset.y() + 1;
+ if (m_targetOffset.y() > 0)
+ setOuterPixels(paintingData, 0, 0, imageRect.width(), m_targetOffset.y());
+ if (clipBottom < imageRect.height())
+ setOuterPixels(paintingData, 0, clipBottom, imageRect.width(), imageRect.height());
+ if (m_targetOffset.x() > 0)
+ setOuterPixels(paintingData, 0, m_targetOffset.y(), m_targetOffset.x(), clipBottom);
+ if (clipRight < imageRect.width())
+ setOuterPixels(paintingData, clipRight, m_targetOffset.y(), imageRect.width(), clipBottom);
+ } else {
+ // Rare situation, not optimizied for speed
+ setOuterPixels(paintingData, 0, 0, imageRect.width(), imageRect.height());
+ }
+
+ if (m_preserveAlpha)
+ resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
+ else
+ resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
+}
+
+void FEConvolveMatrix::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const EdgeModeType& type)
+{
+ switch (type) {
+ case EDGEMODE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case EDGEMODE_DUPLICATE:
+ ts << "DUPLICATE";
+ break;
+ case EDGEMODE_WRAP:
+ ts << "WRAP";
+ break;
+ case EDGEMODE_NONE:
+ ts << "NONE";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEConvolveMatrix::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feConvolveMatrix";
+ FilterEffect::externalRepresentation(ts);
+ ts << " order=\"" << m_kernelSize << "\" "
+ << "kernelMatrix=\"" << m_kernelMatrix << "\" "
+ << "divisor=\"" << m_divisor << "\" "
+ << "bias=\"" << m_bias << "\" "
+ << "target=\"" << m_targetOffset << "\" "
+ << "edgeMode=\"" << m_edgeMode << "\" "
+ << "kernelUnitLength=\"" << m_kernelUnitLength << "\" "
+ << "preserveAlpha=\"" << m_preserveAlpha << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+}; // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEConvolveMatrix.h b/WebCore/platform/graphics/filters/FEConvolveMatrix.h
new file mode 100644
index 0000000..2fe634f
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEConvolveMatrix.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEConvolveMatrix_h
+#define FEConvolveMatrix_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "FloatPoint.h"
+#include "FloatSize.h"
+#include "Filter.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+enum EdgeModeType {
+ EDGEMODE_UNKNOWN = 0,
+ EDGEMODE_DUPLICATE = 1,
+ EDGEMODE_WRAP = 2,
+ EDGEMODE_NONE = 3
+};
+
+class CanvasPixelArray;
+
+class FEConvolveMatrix : public FilterEffect {
+public:
+ static PassRefPtr<FEConvolveMatrix> create(const IntSize&,
+ float, float, const IntPoint&, EdgeModeType, const FloatPoint&,
+ bool, const Vector<float>&);
+
+ IntSize kernelSize() const;
+ void setKernelSize(IntSize);
+
+ const Vector<float>& kernel() const;
+ void setKernel(const Vector<float>&);
+
+ float divisor() const;
+ void setDivisor(float);
+
+ float bias() const;
+ void setBias(float);
+
+ IntPoint targetOffset() const;
+ void setTargetOffset(IntPoint);
+
+ EdgeModeType edgeMode() const;
+ void setEdgeMode(EdgeModeType);
+
+ FloatPoint kernelUnitLength() const;
+ void setKernelUnitLength(FloatPoint);
+
+ bool preserveAlpha() const;
+ void setPreserveAlpha(bool);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEConvolveMatrix(const IntSize&, float, float,
+ const IntPoint&, EdgeModeType, const FloatPoint&, bool, const Vector<float>&);
+
+ struct PaintingData {
+ CanvasPixelArray* srcPixelArray;
+ CanvasPixelArray* dstPixelArray;
+ int width;
+ int height;
+ float bias;
+ };
+
+ template<bool preserveAlphaValues>
+ ALWAYS_INLINE void fastSetInteriorPixels(PaintingData&, int clipRight, int clipBottom);
+
+ ALWAYS_INLINE int getPixelValue(PaintingData&, int x, int y);
+
+ template<bool preserveAlphaValues>
+ void fastSetOuterPixels(PaintingData&, int x1, int y1, int x2, int y2);
+
+ // Wrapper functions
+ ALWAYS_INLINE void setInteriorPixels(PaintingData& paintingData, int clipRight, int clipBottom);
+ ALWAYS_INLINE void setOuterPixels(PaintingData& paintingData, int x1, int y1, int x2, int y2);
+
+ IntSize m_kernelSize;
+ float m_divisor;
+ float m_bias;
+ IntPoint m_targetOffset;
+ EdgeModeType m_edgeMode;
+ FloatPoint m_kernelUnitLength;
+ bool m_preserveAlpha;
+ Vector<float> m_kernelMatrix;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEConvolveMatrix_h
diff --git a/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp b/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
new file mode 100644
index 0000000..98b5adf
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEDiffuseLighting.h"
+
+#include "LightSource.h"
+
+namespace WebCore {
+
+FEDiffuseLighting::FEDiffuseLighting(const Color& lightingColor, float surfaceScale,
+ float diffuseConstant, float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FELighting(DiffuseLighting, lightingColor, surfaceScale, diffuseConstant, 0, 0, kernelUnitLengthX, kernelUnitLengthY, lightSource)
+{
+}
+
+PassRefPtr<FEDiffuseLighting> FEDiffuseLighting::create(const Color& lightingColor,
+ float surfaceScale, float diffuseConstant, float kernelUnitLengthX,
+ float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+{
+ return adoptRef(new FEDiffuseLighting(lightingColor, surfaceScale, diffuseConstant, kernelUnitLengthX, kernelUnitLengthY, lightSource));
+}
+
+FEDiffuseLighting::~FEDiffuseLighting()
+{
+}
+
+Color FEDiffuseLighting::lightingColor() const
+{
+ return m_lightingColor;
+}
+
+void FEDiffuseLighting::setLightingColor(const Color& lightingColor)
+{
+ m_lightingColor = lightingColor;
+}
+
+float FEDiffuseLighting::surfaceScale() const
+{
+ return m_surfaceScale;
+}
+
+void FEDiffuseLighting::setSurfaceScale(float surfaceScale)
+{
+ m_surfaceScale = surfaceScale;
+}
+
+float FEDiffuseLighting::diffuseConstant() const
+{
+ return m_diffuseConstant;
+}
+
+void FEDiffuseLighting::setDiffuseConstant(float diffuseConstant)
+{
+ m_diffuseConstant = diffuseConstant;
+}
+
+float FEDiffuseLighting::kernelUnitLengthX() const
+{
+ return m_kernelUnitLengthX;
+}
+
+void FEDiffuseLighting::setKernelUnitLengthX(float kernelUnitLengthX)
+{
+ m_kernelUnitLengthX = kernelUnitLengthX;
+}
+
+float FEDiffuseLighting::kernelUnitLengthY() const
+{
+ return m_kernelUnitLengthY;
+}
+
+void FEDiffuseLighting::setKernelUnitLengthY(float kernelUnitLengthY)
+{
+ m_kernelUnitLengthY = kernelUnitLengthY;
+}
+
+const LightSource* FEDiffuseLighting::lightSource() const
+{
+ return m_lightSource.get();
+}
+
+void FEDiffuseLighting::setLightSource(PassRefPtr<LightSource> lightSource)
+{
+ m_lightSource = lightSource;
+}
+
+void FEDiffuseLighting::dump()
+{
+}
+
+TextStream& FEDiffuseLighting::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feDiffuseLighting";
+ FilterEffect::externalRepresentation(ts);
+ ts << " surfaceScale=\"" << m_surfaceScale << "\" "
+ << "diffuseConstant=\"" << m_diffuseConstant << "\" "
+ << "kernelUnitLength=\"" << m_kernelUnitLengthX << ", " << m_kernelUnitLengthY << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEDiffuseLighting.h b/WebCore/platform/graphics/filters/FEDiffuseLighting.h
new file mode 100644
index 0000000..5273144
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEDiffuseLighting.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEDiffuseLighting_h
+#define FEDiffuseLighting_h
+
+#if ENABLE(FILTERS)
+#include "FELighting.h"
+
+namespace WebCore {
+
+class LightSource;
+
+class FEDiffuseLighting : public FELighting {
+public:
+ static PassRefPtr<FEDiffuseLighting> create(const Color&, float, float,
+ float, float, PassRefPtr<LightSource>);
+ virtual ~FEDiffuseLighting();
+
+ Color lightingColor() const;
+ void setLightingColor(const Color&);
+
+ float surfaceScale() const;
+ void setSurfaceScale(float);
+
+ float diffuseConstant() const;
+ void setDiffuseConstant(float);
+
+ float kernelUnitLengthX() const;
+ void setKernelUnitLengthX(float);
+
+ float kernelUnitLengthY() const;
+ void setKernelUnitLengthY(float);
+
+ const LightSource* lightSource() const;
+ void setLightSource(PassRefPtr<LightSource>);
+
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEDiffuseLighting(const Color&, float, float, float, float, PassRefPtr<LightSource>);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEDiffuseLighting_h
diff --git a/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/WebCore/platform/graphics/filters/FEDisplacementMap.cpp
new file mode 100644
index 0000000..6b5dbaa
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEDisplacementMap.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEDisplacementMap.h"
+
+#include "CanvasPixelArray.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "ImageData.h"
+
+namespace WebCore {
+
+FEDisplacementMap::FEDisplacementMap(ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float scale)
+ : FilterEffect()
+ , m_xChannelSelector(xChannelSelector)
+ , m_yChannelSelector(yChannelSelector)
+ , m_scale(scale)
+{
+}
+
+PassRefPtr<FEDisplacementMap> FEDisplacementMap::create(ChannelSelectorType xChannelSelector,
+ ChannelSelectorType yChannelSelector, float scale)
+{
+ return adoptRef(new FEDisplacementMap(xChannelSelector, yChannelSelector, scale));
+}
+
+ChannelSelectorType FEDisplacementMap::xChannelSelector() const
+{
+ return m_xChannelSelector;
+}
+
+void FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector)
+{
+ m_xChannelSelector = xChannelSelector;
+}
+
+ChannelSelectorType FEDisplacementMap::yChannelSelector() const
+{
+ return m_yChannelSelector;
+}
+
+void FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector)
+{
+ m_yChannelSelector = yChannelSelector;
+}
+
+float FEDisplacementMap::scale() const
+{
+ return m_scale;
+}
+
+void FEDisplacementMap::setScale(float scale)
+{
+ m_scale = scale;
+}
+
+void FEDisplacementMap::apply(Filter* filter)
+{
+ FilterEffect* in = inputEffect(0);
+ FilterEffect* in2 = inputEffect(1);
+ in->apply(filter);
+ in2->apply(filter);
+ if (!in->resultImage() || !in2->resultImage())
+ return;
+
+ if (m_xChannelSelector == CHANNEL_UNKNOWN || m_yChannelSelector == CHANNEL_UNKNOWN)
+ return;
+
+ if (!effectContext())
+ return;
+
+ IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
+ RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
+
+ IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
+ RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data());
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
+
+ ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
+
+ float scaleX = m_scale / 255.f * filter->filterResolution().width();
+ float scaleY = m_scale / 255.f * filter->filterResolution().height();
+ float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width();
+ float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height();
+ int stride = imageRect.width() * 4;
+ for (int y = 0; y < imageRect.height(); ++y) {
+ int line = y * stride;
+ for (int x = 0; x < imageRect.width(); ++x) {
+ int dstIndex = line + x * 4;
+ int srcX = x + static_cast<int>(scaleX * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustmentX);
+ int srcY = y + static_cast<int>(scaleY * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustmentY);
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ if (srcX < 0 || srcX >= imageRect.width() || srcY < 0 || srcY >= imageRect.height())
+ imageData->data()->set(dstIndex + channel, static_cast<unsigned char>(0));
+ else {
+ unsigned char pixelValue = srcPixelArrayA->get(srcY * stride + srcX * 4 + channel);
+ imageData->data()->set(dstIndex + channel, pixelValue);
+ }
+ }
+
+ }
+ }
+ resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
+}
+
+void FEDisplacementMap::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const ChannelSelectorType& type)
+{
+ switch (type) {
+ case CHANNEL_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case CHANNEL_R:
+ ts << "RED";
+ break;
+ case CHANNEL_G:
+ ts << "GREEN";
+ break;
+ case CHANNEL_B:
+ ts << "BLUE";
+ break;
+ case CHANNEL_A:
+ ts << "ALPHA";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEDisplacementMap::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feDisplacementMap";
+ FilterEffect::externalRepresentation(ts);
+ ts << " scale=\"" << m_scale << "\" "
+ << "xChannelSelector=\"" << m_xChannelSelector << "\" "
+ << "yChannelSelector=\"" << m_yChannelSelector << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ inputEffect(1)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEDisplacementMap.h b/WebCore/platform/graphics/filters/FEDisplacementMap.h
new file mode 100644
index 0000000..dc87b90
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEDisplacementMap.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEDisplacementMap_h
+#define FEDisplacementMap_h
+
+#if ENABLE(FILTERS)
+#include "PlatformString.h"
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum ChannelSelectorType {
+ CHANNEL_UNKNOWN = 0,
+ CHANNEL_R = 1,
+ CHANNEL_G = 2,
+ CHANNEL_B = 3,
+ CHANNEL_A = 4
+};
+
+class FEDisplacementMap : public FilterEffect {
+public:
+ static PassRefPtr<FEDisplacementMap> create(ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float);
+
+ ChannelSelectorType xChannelSelector() const;
+ void setXChannelSelector(const ChannelSelectorType);
+
+ ChannelSelectorType yChannelSelector() const;
+ void setYChannelSelector(const ChannelSelectorType);
+
+ float scale() const;
+ void setScale(float scale);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEDisplacementMap(ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float);
+
+ ChannelSelectorType m_xChannelSelector;
+ ChannelSelectorType m_yChannelSelector;
+ float m_scale;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEDisplacementMap_h
diff --git a/WebCore/platform/graphics/filters/FEFlood.cpp b/WebCore/platform/graphics/filters/FEFlood.cpp
new file mode 100644
index 0000000..7804d89
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEFlood.cpp
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEFlood.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+FEFlood::FEFlood(const Color& floodColor, float floodOpacity)
+ : FilterEffect()
+ , m_floodColor(floodColor)
+ , m_floodOpacity(floodOpacity)
+{
+}
+
+PassRefPtr<FEFlood> FEFlood::create(const Color& floodColor, float floodOpacity)
+{
+ return adoptRef(new FEFlood(floodColor, floodOpacity));
+}
+
+Color FEFlood::floodColor() const
+{
+ return m_floodColor;
+}
+
+void FEFlood::setFloodColor(const Color& color)
+{
+ m_floodColor = color;
+}
+
+float FEFlood::floodOpacity() const
+{
+ return m_floodOpacity;
+}
+
+void FEFlood::setFloodOpacity(float floodOpacity)
+{
+ m_floodOpacity = floodOpacity;
+}
+
+void FEFlood::apply(Filter*)
+{
+ GraphicsContext* filterContext = effectContext();
+ if (!filterContext)
+ return;
+
+ Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
+ filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()), color, DeviceColorSpace);
+}
+
+void FEFlood::dump()
+{
+}
+
+TextStream& FEFlood::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feFlood";
+ FilterEffect::externalRepresentation(ts);
+ ts << " flood-color=\"" << floodColor().name() << "\" "
+ << "flood-opacity=\"" << floodOpacity() << "\"]\n";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEFlood.h b/WebCore/platform/graphics/filters/FEFlood.h
new file mode 100644
index 0000000..b615531
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEFlood.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEFlood_h
+#define FEFlood_h
+
+#if ENABLE(FILTERS)
+#include "Color.h"
+#include "Filter.h"
+#include "FilterEffect.h"
+
+namespace WebCore {
+
+class FEFlood : public FilterEffect {
+public:
+ static PassRefPtr<FEFlood> create(const Color&, float);
+
+ Color floodColor() const;
+ void setFloodColor(const Color &);
+
+ float floodOpacity() const;
+ void setFloodOpacity(float);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEFlood(const Color&, float);
+
+ Color m_floodColor;
+ float m_floodOpacity;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEFlood_h
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
index 72a5a04..fd9a3d8 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -1,25 +1,25 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
- 2009 Dirk Schulze <krit@webkit.org>
- 2010 Igalia, S.L.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Igalia, S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#include "config.h"
@@ -132,12 +132,12 @@ void FEGaussianBlur::apply(Filter* filter)
if (!in->resultImage())
return;
- if (!getEffectContext())
+ if (!effectContext())
return;
setIsAlphaImage(in->isAlphaImage());
- IntRect effectDrawingRect = calculateDrawingIntRect(in->repaintRectInLocalCoordinates());
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect));
IntRect imageRect(IntPoint(), resultImage()->size());
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h
index 63d763e..745bcc8 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.h
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h
@@ -1,23 +1,23 @@
/*
- Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005 Rob Buis <buis@kde.org>
- 2005 Eric Seidel <eric@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef FEGaussianBlur_h
#define FEGaussianBlur_h
@@ -38,12 +38,13 @@ public:
float stdDeviationY() const;
void setStdDeviationY(float);
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
-
static float calculateStdDeviation(float);
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
private:
FEGaussianBlur(float, float);
static void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight);
diff --git a/WebCore/platform/graphics/filters/FELighting.cpp b/WebCore/platform/graphics/filters/FELighting.cpp
new file mode 100644
index 0000000..f49b67d
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FELighting.cpp
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FELighting.h"
+
+#include "CanvasPixelArray.h"
+#include "ImageData.h"
+#include "LightSource.h"
+
+namespace WebCore {
+
+FELighting::FELighting(LightingType lightingType, const Color& lightingColor, float surfaceScale,
+ float diffuseConstant, float specularConstant, float specularExponent,
+ float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FilterEffect()
+ , m_lightingType(lightingType)
+ , m_lightSource(lightSource)
+ , m_lightingColor(lightingColor)
+ , m_surfaceScale(surfaceScale)
+ , m_diffuseConstant(diffuseConstant)
+ , m_specularConstant(specularConstant)
+ , m_specularExponent(specularExponent)
+ , m_kernelUnitLengthX(kernelUnitLengthX)
+ , m_kernelUnitLengthY(kernelUnitLengthY)
+{
+}
+
+const static int cPixelSize = 4;
+const static int cAlphaChannelOffset = 3;
+const static unsigned char cOpaqueAlpha = static_cast<unsigned char>(0xff);
+
+ALWAYS_INLINE int FELighting::LightingData::upLeftPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::upPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::upRightPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::leftPixelValue()
+{
+ return static_cast<int>(pixels->get(offset - cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::centerPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::rightPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::downLeftPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize - cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::downPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE int FELighting::LightingData::downRightPixelValue()
+{
+ return static_cast<int>(pixels->get(offset + widthMultipliedByPixelSize + cPixelSize + cAlphaChannelOffset));
+}
+
+ALWAYS_INLINE void FELighting::setPixel(LightingData& data, LightSource::PaintingData& paintingData,
+ int lightX, int lightY, float factorX, int normalX, float factorY, int normalY)
+{
+ m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->get(data.offset + 3)) * data.surfaceScale);
+
+ data.normalVector.setX(factorX * static_cast<float>(normalX) * data.surfaceScale);
+ data.normalVector.setY(factorY * static_cast<float>(normalY) * data.surfaceScale);
+ data.normalVector.setZ(1.0f);
+ data.normalVector.normalize();
+
+ if (m_lightingType == FELighting::DiffuseLighting)
+ data.lightStrength = m_diffuseConstant * (data.normalVector * paintingData.lightVector);
+ else {
+ FloatPoint3D halfwayVector = paintingData.lightVector;
+ halfwayVector.setZ(halfwayVector.z() + 1.0f);
+ halfwayVector.normalize();
+ if (m_specularExponent == 1.0f)
+ data.lightStrength = m_specularConstant * (data.normalVector * halfwayVector);
+ else
+ data.lightStrength = m_specularConstant * powf(data.normalVector * halfwayVector, m_specularExponent);
+ }
+
+ if (data.lightStrength > 1.0f)
+ data.lightStrength = 1.0f;
+ if (data.lightStrength < 0.0f)
+ data.lightStrength = 0.0f;
+
+ data.pixels->set(data.offset, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.x()));
+ data.pixels->set(data.offset + 1, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.y()));
+ data.pixels->set(data.offset + 2, static_cast<unsigned char>(data.lightStrength * paintingData.colorVector.z()));
+}
+
+bool FELighting::drawLighting(CanvasPixelArray* pixels, int width, int height)
+{
+ LightSource::PaintingData paintingData;
+ LightingData data;
+
+ if (!m_lightSource)
+ return false;
+
+ // FIXME: do something if width or height (or both) is 1 pixel.
+ // The W3 spec does not define this case. Now the filter just returns.
+ if (width <= 2 || height <= 2)
+ return false;
+
+ data.pixels = pixels;
+ data.surfaceScale = m_surfaceScale / 255.0f;
+ data.widthMultipliedByPixelSize = width * cPixelSize;
+ data.widthDecreasedByOne = width - 1;
+ data.heightDecreasedByOne = height - 1;
+ paintingData.colorVector = FloatPoint3D(m_lightingColor.red(), m_lightingColor.green(), m_lightingColor.blue());
+ m_lightSource->initPaintingData(paintingData);
+
+ // Top/Left corner
+ data.offset = 0;
+ setPixel(data, paintingData, 0, 0,
+ -2.0f / 3.0f, -2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(),
+ -2.0f / 3.0f, -2 * data.centerPixelValue() - data.rightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+
+ // Top/Right pixel
+ data.offset = data.widthMultipliedByPixelSize - cPixelSize;
+ setPixel(data, paintingData, data.widthDecreasedByOne, 0,
+ -2.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(),
+ -2.0f / 3.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue());
+
+ // Bottom/Left pixel
+ data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize;
+ setPixel(data, paintingData, 0, data.heightDecreasedByOne,
+ -2.0f / 3.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue(),
+ -2.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue());
+
+ // Bottom/Right pixel
+ data.offset = height * data.widthMultipliedByPixelSize - cPixelSize;
+ setPixel(data, paintingData, data.widthDecreasedByOne, data.heightDecreasedByOne,
+ -2.0f / 3.0f, -data.upLeftPixelValue() + data.upPixelValue() - 2 * data.leftPixelValue() + 2 * data.centerPixelValue(),
+ -2.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue());
+
+ if (width >= 3) {
+ // Top line
+ data.offset = cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
+ setPixel(data, paintingData, x, 0,
+ -1.0f / 3.0f, -2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(),
+ -1.0f / 2.0f, -data.leftPixelValue() - 2 * data.centerPixelValue() - data.rightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ }
+ // Bottom line
+ data.offset = data.heightDecreasedByOne * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
+ setPixel(data, paintingData, x, data.heightDecreasedByOne,
+ -1.0f / 3.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue(),
+ -1.0f / 2.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.leftPixelValue() + 2 * data.centerPixelValue() + data.rightPixelValue());
+ }
+ }
+
+ if (height >= 3) {
+ // Left line
+ data.offset = data.widthMultipliedByPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) {
+ setPixel(data, paintingData, 0, y,
+ -1.0f / 2.0f, -data.upPixelValue() + data.upRightPixelValue() - 2 * data.centerPixelValue() + 2 * data.rightPixelValue() - data.downPixelValue() + data.downRightPixelValue(),
+ -1.0f / 3.0f, -2 * data.upPixelValue() - data.upRightPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ }
+ // Right line
+ data.offset = data.widthMultipliedByPixelSize + data.widthMultipliedByPixelSize - cPixelSize;
+ for (int y = 1; y < data.heightDecreasedByOne; ++y, data.offset += data.widthMultipliedByPixelSize) {
+ setPixel(data, paintingData, data.widthDecreasedByOne, y,
+ -1.0f / 2.0f, -data.upLeftPixelValue() + data.upPixelValue() -2 * data.leftPixelValue() + 2 * data.centerPixelValue() - data.downLeftPixelValue() + data.downPixelValue(),
+ -1.0f / 3.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue());
+ }
+ }
+
+ if (width >= 3 && height >= 3) {
+ // Interior pixels
+ for (int y = 1; y < data.heightDecreasedByOne; ++y) {
+ data.offset = y * data.widthMultipliedByPixelSize + cPixelSize;
+ for (int x = 1; x < data.widthDecreasedByOne; ++x, data.offset += cPixelSize) {
+ setPixel(data, paintingData, x, y,
+ -1.0f / 4.0f, -data.upLeftPixelValue() + data.upRightPixelValue() - 2 * data.leftPixelValue() + 2 * data.rightPixelValue() - data.downLeftPixelValue() + data.downRightPixelValue(),
+ -1.0f / 4.0f, -data.upLeftPixelValue() - 2 * data.upPixelValue() - data.upRightPixelValue() + data.downLeftPixelValue() + 2 * data.downPixelValue() + data.downRightPixelValue());
+ }
+ }
+ }
+
+ int totalSize = data.widthMultipliedByPixelSize * height;
+ if (m_lightingType == DiffuseLighting) {
+ for (int i = 3; i < totalSize; i += 4)
+ data.pixels->set(i, cOpaqueAlpha);
+ } else {
+ for (int i = 0; i < totalSize; i += 4) {
+ unsigned char a1 = data.pixels->get(i);
+ unsigned char a2 = data.pixels->get(i + 1);
+ unsigned char a3 = data.pixels->get(i + 2);
+ // alpha set to set to max(a1, a2, a3)
+ data.pixels->set(i + 3, a1 >= a2 ? (a1 >= a3 ? a1 : a3) : (a2 >= a3 ? a2 : a3));
+ }
+ }
+
+ return true;
+}
+
+void FELighting::apply(Filter* filter)
+{
+ FilterEffect* in = inputEffect(0);
+ in->apply(filter);
+ if (!in->resultImage())
+ return;
+
+ if (!effectContext())
+ return;
+
+ setIsAlphaImage(false);
+
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
+ RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect));
+ CanvasPixelArray* srcPixelArray(srcImageData->data());
+
+ // FIXME: support kernelUnitLengths other than (1,1). The issue here is that the W3
+ // standard has no test case for them, and other browsers (like Firefox) has strange
+ // output for various kernelUnitLengths, and I am not sure they are reliable.
+ // Anyway, feConvolveMatrix should also use the implementation
+
+ if (drawLighting(srcPixelArray, effectDrawingRect.width(), effectDrawingRect.height()))
+ resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FELighting.h b/WebCore/platform/graphics/filters/FELighting.h
new file mode 100644
index 0000000..28c00c4
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FELighting.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Zoltan Herczeg
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FELighting_h
+#define FELighting_h
+
+#if ENABLE(FILTERS)
+#include "Color.h"
+#include "Filter.h"
+#include "FilterEffect.h"
+#include "LightSource.h"
+#include <wtf/AlwaysInline.h>
+
+// Common base class for FEDiffuseLighting and FESpecularLighting
+
+namespace WebCore {
+
+class CanvasPixelArray;
+
+class FELighting : public FilterEffect {
+public:
+ virtual void apply(Filter*);
+
+protected:
+ enum LightingType {
+ DiffuseLighting,
+ SpecularLighting
+ };
+
+ struct LightingData {
+ FloatPoint3D normalVector;
+ CanvasPixelArray* pixels;
+ float lightStrength;
+ float surfaceScale;
+ int offset;
+ int widthMultipliedByPixelSize;
+ int widthDecreasedByOne;
+ int heightDecreasedByOne;
+
+ ALWAYS_INLINE int upLeftPixelValue();
+ ALWAYS_INLINE int upPixelValue();
+ ALWAYS_INLINE int upRightPixelValue();
+ ALWAYS_INLINE int leftPixelValue();
+ ALWAYS_INLINE int centerPixelValue();
+ ALWAYS_INLINE int rightPixelValue();
+ ALWAYS_INLINE int downLeftPixelValue();
+ ALWAYS_INLINE int downPixelValue();
+ ALWAYS_INLINE int downRightPixelValue();
+ };
+
+ FELighting(LightingType, const Color&, float, float, float, float, float, float, PassRefPtr<LightSource>);
+
+ bool drawLighting(CanvasPixelArray*, int, int);
+ ALWAYS_INLINE void setPixel(LightingData&, LightSource::PaintingData&,
+ int lightX, int lightY, float factorX, int normalX, float factorY, int normalY);
+
+ LightingType m_lightingType;
+ RefPtr<LightSource> m_lightSource;
+
+ Color m_lightingColor;
+ float m_surfaceScale;
+ float m_diffuseConstant;
+ float m_specularConstant;
+ float m_specularExponent;
+ float m_kernelUnitLengthX;
+ float m_kernelUnitLengthY;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FELighting_h
diff --git a/WebCore/platform/graphics/filters/FEMerge.cpp b/WebCore/platform/graphics/filters/FEMerge.cpp
new file mode 100644
index 0000000..19c832a
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEMerge.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEMerge.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+FEMerge::FEMerge()
+ : FilterEffect()
+{
+}
+
+PassRefPtr<FEMerge> FEMerge::create()
+{
+ return adoptRef(new FEMerge);
+}
+
+void FEMerge::apply(Filter* filter)
+{
+ unsigned size = numberOfEffectInputs();
+ ASSERT(size > 0);
+ for (unsigned i = 0; i < size; ++i) {
+ FilterEffect* in = inputEffect(i);
+ in->apply(filter);
+ if (!in->resultImage())
+ return;
+ }
+
+ GraphicsContext* filterContext = effectContext();
+ if (!filterContext)
+ return;
+
+ for (unsigned i = 0; i < size; ++i) {
+ FilterEffect* in = inputEffect(i);
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
+ }
+}
+
+void FEMerge::dump()
+{
+}
+
+TextStream& FEMerge::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feMerge";
+ FilterEffect::externalRepresentation(ts);
+ unsigned size = numberOfEffectInputs();
+ ASSERT(size > 0);
+ ts << " mergeNodes=\"" << size << "\"]\n";
+ for (unsigned i = 0; i < size; ++i)
+ inputEffect(i)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEMerge.h b/WebCore/platform/graphics/filters/FEMerge.h
new file mode 100644
index 0000000..46b882f
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEMerge.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEMerge_h
+#define EMerge_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class FEMerge : public FilterEffect {
+public:
+ static PassRefPtr<FEMerge> create();
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEMerge();
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEMerge_h
diff --git a/WebCore/platform/graphics/filters/FEMorphology.cpp b/WebCore/platform/graphics/filters/FEMorphology.cpp
new file mode 100644
index 0000000..7329e1e
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEMorphology.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEMorphology.h"
+
+#include "CanvasPixelArray.h"
+#include "Filter.h"
+#include "ImageData.h"
+
+#include <wtf/Vector.h>
+
+using std::min;
+using std::max;
+
+namespace WebCore {
+
+FEMorphology::FEMorphology(MorphologyOperatorType type, float radiusX, float radiusY)
+ : FilterEffect()
+ , m_type(type)
+ , m_radiusX(radiusX)
+ , m_radiusY(radiusY)
+{
+}
+
+PassRefPtr<FEMorphology> FEMorphology::create(MorphologyOperatorType type, float radiusX, float radiusY)
+{
+ return adoptRef(new FEMorphology(type, radiusX, radiusY));
+}
+
+MorphologyOperatorType FEMorphology::morphologyOperator() const
+{
+ return m_type;
+}
+
+void FEMorphology::setMorphologyOperator(MorphologyOperatorType type)
+{
+ m_type = type;
+}
+
+float FEMorphology::radiusX() const
+{
+ return m_radiusX;
+}
+
+void FEMorphology::setRadiusX(float radiusX)
+{
+ m_radiusX = radiusX;
+}
+
+float FEMorphology::radiusY() const
+{
+ return m_radiusY;
+}
+
+void FEMorphology::setRadiusY(float radiusY)
+{
+ m_radiusY = radiusY;
+}
+
+void FEMorphology::apply(Filter* filter)
+{
+ FilterEffect* in = inputEffect(0);
+ in->apply(filter);
+ if (!in->resultImage())
+ return;
+
+ if (!effectContext())
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ int radiusX = static_cast<int>(m_radiusX * filter->filterResolution().width());
+ int radiusY = static_cast<int>(m_radiusY * filter->filterResolution().height());
+ if (radiusX <= 0 || radiusY <= 0)
+ return;
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
+ RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data());
+ RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
+
+ int effectWidth = effectDrawingRect.width() * 4;
+
+ // Limit the radius size to effect dimensions
+ radiusX = min(effectDrawingRect.width() - 1, radiusX);
+ radiusY = min(effectDrawingRect.height() - 1, radiusY);
+
+ Vector<unsigned char> extrema;
+ for (int y = 0; y < effectDrawingRect.height(); ++y) {
+ int startY = max(0, y - radiusY);
+ int endY = min(effectDrawingRect.height() - 1, y + radiusY);
+ for (unsigned channel = 0; channel < 4; ++channel) {
+ // Fill the kernel
+ extrema.clear();
+ for (int j = 0; j <= radiusX; ++j) {
+ unsigned char columnExtrema = srcPixelArray->get(startY * effectWidth + 4 * j + channel);
+ for (int i = startY; i <= endY; ++i) {
+ unsigned char pixel = srcPixelArray->get(i * effectWidth + 4 * j + channel);
+ if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema) ||
+ (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
+ columnExtrema = pixel;
+ }
+ extrema.append(columnExtrema);
+ }
+
+ // Kernel is filled, get extrema of next column
+ for (int x = 0; x < effectDrawingRect.width(); ++x) {
+ unsigned endX = min(x + radiusX, effectDrawingRect.width() - 1);
+ unsigned char columnExtrema = srcPixelArray->get(startY * effectWidth + endX * 4 + channel);
+ for (int i = startY; i <= endY; ++i) {
+ unsigned char pixel = srcPixelArray->get(i * effectWidth + endX * 4 + channel);
+ if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && pixel <= columnExtrema) ||
+ (m_type == FEMORPHOLOGY_OPERATOR_DILATE && pixel >= columnExtrema))
+ columnExtrema = pixel;
+ }
+ if (x - radiusX >= 0)
+ extrema.remove(0);
+ if (x + radiusX <= effectDrawingRect.width())
+ extrema.append(columnExtrema);
+ unsigned char entireExtrema = extrema[0];
+ for (unsigned kernelIndex = 0; kernelIndex < extrema.size(); ++kernelIndex) {
+ if ((m_type == FEMORPHOLOGY_OPERATOR_ERODE && extrema[kernelIndex] <= entireExtrema) ||
+ (m_type == FEMORPHOLOGY_OPERATOR_DILATE && extrema[kernelIndex] >= entireExtrema))
+ entireExtrema = extrema[kernelIndex];
+ }
+ imageData->data()->set(y * effectWidth + 4 * x + channel, entireExtrema);
+ }
+ }
+ }
+ resultImage()->putPremultipliedImageData(imageData.get(), imageRect, IntPoint());
+}
+
+void FEMorphology::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const MorphologyOperatorType& type)
+{
+ switch (type) {
+ case FEMORPHOLOGY_OPERATOR_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FEMORPHOLOGY_OPERATOR_ERODE:
+ ts << "ERODE";
+ break;
+ case FEMORPHOLOGY_OPERATOR_DILATE:
+ ts << "DILATE";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FEMorphology::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feMorphology";
+ FilterEffect::externalRepresentation(ts);
+ ts << " operator=\"" << morphologyOperator() << "\" "
+ << "radius=\"" << radiusX() << ", " << radiusY() << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEMorphology.h b/WebCore/platform/graphics/filters/FEMorphology.h
new file mode 100644
index 0000000..c8ce058
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEMorphology.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEMorphology_h
+#define FEMorphology_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum MorphologyOperatorType {
+ FEMORPHOLOGY_OPERATOR_UNKNOWN = 0,
+ FEMORPHOLOGY_OPERATOR_ERODE = 1,
+ FEMORPHOLOGY_OPERATOR_DILATE = 2
+};
+
+class FEMorphology : public FilterEffect {
+public:
+ static PassRefPtr<FEMorphology> create(MorphologyOperatorType, float radiusX, float radiusY);
+ MorphologyOperatorType morphologyOperator() const;
+ void setMorphologyOperator(MorphologyOperatorType);
+
+ float radiusX() const;
+ void setRadiusX(float);
+
+ float radiusY() const;
+ void setRadiusY(float);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEMorphology(MorphologyOperatorType, float radiusX, float radiusY);
+
+ MorphologyOperatorType m_type;
+ float m_radiusX;
+ float m_radiusY;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEMorphology_h
diff --git a/WebCore/platform/graphics/filters/FEOffset.cpp b/WebCore/platform/graphics/filters/FEOffset.cpp
new file mode 100644
index 0000000..ea84cf0
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEOffset.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEOffset.h"
+
+#include "Filter.h"
+#include "GraphicsContext.h"
+
+namespace WebCore {
+
+FEOffset::FEOffset(float dx, float dy)
+ : FilterEffect()
+ , m_dx(dx)
+ , m_dy(dy)
+{
+}
+
+PassRefPtr<FEOffset> FEOffset::create(float dx, float dy)
+{
+ return adoptRef(new FEOffset(dx, dy));
+}
+
+float FEOffset::dx() const
+{
+ return m_dx;
+}
+
+void FEOffset::setDx(float dx)
+{
+ m_dx = dx;
+}
+
+float FEOffset::dy() const
+{
+ return m_dy;
+}
+
+void FEOffset::setDy(float dy)
+{
+ m_dy = dy;
+}
+
+void FEOffset::apply(Filter* filter)
+{
+ FilterEffect* in = inputEffect(0);
+ in->apply(filter);
+ if (!in->resultImage())
+ return;
+
+ GraphicsContext* filterContext = effectContext();
+ if (!filterContext)
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ FloatRect sourceImageRect = filter->sourceImageRect();
+ sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+
+ if (filter->effectBoundingBoxMode()) {
+ m_dx *= sourceImageRect.width();
+ m_dy *= sourceImageRect.height();
+ }
+ m_dx *= filter->filterResolution().width();
+ m_dy *= filter->filterResolution().height();
+
+ FloatRect dstRect = FloatRect(m_dx + in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(),
+ m_dy + in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y(),
+ in->repaintRectInLocalCoordinates().width(),
+ in->repaintRectInLocalCoordinates().height());
+
+ filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, dstRect);
+}
+
+void FEOffset::dump()
+{
+}
+
+TextStream& FEOffset::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feOffset";
+ FilterEffect::externalRepresentation(ts);
+ ts << " dx=\"" << dx() << "\" dy=\"" << dy() << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEOffset.h b/WebCore/platform/graphics/filters/FEOffset.h
new file mode 100644
index 0000000..052ba74
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEOffset.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FEOffset_h
+#define FEOffset_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+class FEOffset : public FilterEffect {
+public:
+ static PassRefPtr<FEOffset> create(float dx, float dy);
+
+ float dx() const;
+ void setDx(float);
+
+ float dy() const;
+ void setDy(float);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FEOffset(float dx, float dy);
+
+ float m_dx;
+ float m_dy;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEOffset_h
diff --git a/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/WebCore/platform/graphics/filters/FESpecularLighting.cpp
new file mode 100644
index 0000000..2606600
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FESpecularLighting.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FESpecularLighting.h"
+
+#include "LightSource.h"
+
+namespace WebCore {
+
+FESpecularLighting::FESpecularLighting(const Color& lightingColor, float surfaceScale,
+ float specularConstant, float specularExponent, float kernelUnitLengthX,
+ float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+ : FELighting(SpecularLighting, lightingColor, surfaceScale, 0, specularConstant, specularExponent, kernelUnitLengthX, kernelUnitLengthY, lightSource)
+{
+}
+
+PassRefPtr<FESpecularLighting> FESpecularLighting::create(const Color& lightingColor,
+ float surfaceScale, float specularConstant, float specularExponent,
+ float kernelUnitLengthX, float kernelUnitLengthY, PassRefPtr<LightSource> lightSource)
+{
+ return adoptRef(new FESpecularLighting(lightingColor, surfaceScale, specularConstant, specularExponent,
+ kernelUnitLengthX, kernelUnitLengthY, lightSource));
+}
+
+FESpecularLighting::~FESpecularLighting()
+{
+}
+
+Color FESpecularLighting::lightingColor() const
+{
+ return m_lightingColor;
+}
+
+void FESpecularLighting::setLightingColor(const Color& lightingColor)
+{
+ m_lightingColor = lightingColor;
+}
+
+float FESpecularLighting::surfaceScale() const
+{
+ return m_surfaceScale;
+}
+
+void FESpecularLighting::setSurfaceScale(float surfaceScale)
+{
+ m_surfaceScale = surfaceScale;
+}
+
+float FESpecularLighting::specularConstant() const
+{
+ return m_specularConstant;
+}
+
+void FESpecularLighting::setSpecularConstant(float specularConstant)
+{
+ m_specularConstant = specularConstant;
+}
+
+float FESpecularLighting::specularExponent() const
+{
+ return m_specularExponent;
+}
+
+void FESpecularLighting::setSpecularExponent(float specularExponent)
+{
+ m_specularExponent = specularExponent;
+}
+
+float FESpecularLighting::kernelUnitLengthX() const
+{
+ return m_kernelUnitLengthX;
+}
+
+void FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX)
+{
+ m_kernelUnitLengthX = kernelUnitLengthX;
+}
+
+float FESpecularLighting::kernelUnitLengthY() const
+{
+ return m_kernelUnitLengthY;
+}
+
+void FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY)
+{
+ m_kernelUnitLengthY = kernelUnitLengthY;
+}
+
+const LightSource* FESpecularLighting::lightSource() const
+{
+ return m_lightSource.get();
+}
+
+void FESpecularLighting::setLightSource(PassRefPtr<LightSource> lightSource)
+{
+ m_lightSource = lightSource;
+}
+
+void FESpecularLighting::dump()
+{
+}
+
+TextStream& FESpecularLighting::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feSpecularLighting";
+ FilterEffect::externalRepresentation(ts);
+ ts << " surfaceScale=\"" << m_surfaceScale << "\" "
+ << "specualConstant=\"" << m_specularConstant << "\" "
+ << "specularExponent=\"" << m_specularExponent << "\"]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FESpecularLighting.h b/WebCore/platform/graphics/filters/FESpecularLighting.h
new file mode 100644
index 0000000..f6e7b66
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FESpecularLighting.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FESpecularLighting_h
+#define FESpecularLighting_h
+
+#if ENABLE(FILTERS)
+#include "FELighting.h"
+
+namespace WebCore {
+
+class FESpecularLighting : public FELighting {
+public:
+ static PassRefPtr<FESpecularLighting> create(const Color&, float, float,
+ float, float, float, PassRefPtr<LightSource>);
+ virtual ~FESpecularLighting();
+
+ Color lightingColor() const;
+ void setLightingColor(const Color&);
+
+ float surfaceScale() const;
+ void setSurfaceScale(float);
+
+ float specularConstant() const;
+ void setSpecularConstant(float);
+
+ float specularExponent() const;
+ void setSpecularExponent(float);
+
+ float kernelUnitLengthX() const;
+ void setKernelUnitLengthX(float);
+
+ float kernelUnitLengthY() const;
+ void setKernelUnitLengthY(float);
+
+ const LightSource* lightSource() const;
+ void setLightSource(PassRefPtr<LightSource>);
+
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ FESpecularLighting(const Color&, float, float, float, float, float, PassRefPtr<LightSource>);
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FESpecularLighting_h
diff --git a/WebCore/platform/graphics/filters/FETile.cpp b/WebCore/platform/graphics/filters/FETile.cpp
new file mode 100644
index 0000000..41abd34
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FETile.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FETile.h"
+
+#include "AffineTransform.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "Pattern.h"
+
+namespace WebCore {
+
+FETile::FETile()
+ : FilterEffect()
+{
+}
+
+PassRefPtr<FETile> FETile::create()
+{
+ return adoptRef(new FETile);
+}
+
+FloatRect FETile::determineFilterPrimitiveSubregion(Filter* filter)
+{
+ inputEffect(0)->determineFilterPrimitiveSubregion(filter);
+
+ filter->determineFilterPrimitiveSubregion(this, filter->filterRegion());
+ return filterPrimitiveSubregion();
+}
+
+void FETile::apply(Filter* filter)
+{
+ FilterEffect* in = inputEffect(0);
+ in->apply(filter);
+ if (!in->resultImage())
+ return;
+
+ GraphicsContext* filterContext = effectContext();
+ if (!filterContext)
+ return;
+
+ setIsAlphaImage(in->isAlphaImage());
+
+ IntRect tileRect = enclosingIntRect(in->repaintRectInLocalCoordinates());
+
+ // Source input needs more attention. It has the size of the filterRegion but gives the
+ // size of the cutted sourceImage back. This is part of the specification and optimization.
+ if (in->isSourceInput()) {
+ FloatRect filterRegion = filter->filterRegion();
+ filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height());
+ tileRect = enclosingIntRect(filterRegion);
+ }
+
+ OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size());
+ GraphicsContext* tileImageContext = tileImage->context();
+ tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, IntPoint());
+ RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
+
+ AffineTransform matrix;
+ matrix.translate(in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(),
+ in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y());
+ pattern.get()->setPatternSpaceTransform(matrix);
+
+ filterContext->setFillPattern(pattern);
+ filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()));
+}
+
+void FETile::dump()
+{
+}
+
+TextStream& FETile::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feTile";
+ FilterEffect::externalRepresentation(ts);
+ ts << "]\n";
+ inputEffect(0)->externalRepresentation(ts, indent + 1);
+
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
diff --git a/WebCore/platform/graphics/filters/FETile.h b/WebCore/platform/graphics/filters/FETile.h
new file mode 100644
index 0000000..20efbcd
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FETile.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FETile_h
+#define FETile_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+class FETile : public FilterEffect {
+public:
+ static PassRefPtr<FETile> create();
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+ virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
+
+private:
+ FETile();
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FETile_h
diff --git a/WebCore/platform/graphics/filters/FETurbulence.cpp b/WebCore/platform/graphics/filters/FETurbulence.cpp
new file mode 100644
index 0000000..bb24362
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FETurbulence.cpp
@@ -0,0 +1,386 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FETurbulence.h"
+
+#include "CanvasPixelArray.h"
+#include "Filter.h"
+#include "ImageData.h"
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+/*
+ Produces results in the range [1, 2**31 - 2]. Algorithm is:
+ r = (a * r) mod m where a = randAmplitude = 16807 and
+ m = randMaximum = 2**31 - 1 = 2147483647, r = seed.
+ See [Park & Miller], CACM vol. 31 no. 10 p. 1195, Oct. 1988
+ To test: the algorithm should produce the result 1043618065
+ as the 10,000th generated number if the original seed is 1.
+*/
+static const int s_perlinNoise = 4096;
+static const long s_randMaximum = 2147483647; // 2**31 - 1
+static const int s_randAmplitude = 16807; // 7**5; primitive root of m
+static const int s_randQ = 127773; // m / a
+static const int s_randR = 2836; // m % a
+
+FETurbulence::FETurbulence(TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
+ : FilterEffect()
+ , m_type(type)
+ , m_baseFrequencyX(baseFrequencyX)
+ , m_baseFrequencyY(baseFrequencyY)
+ , m_numOctaves(numOctaves)
+ , m_seed(seed)
+ , m_stitchTiles(stitchTiles)
+{
+}
+
+PassRefPtr<FETurbulence> FETurbulence::create(TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles)
+{
+ return adoptRef(new FETurbulence(type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles));
+}
+
+TurbulanceType FETurbulence::type() const
+{
+ return m_type;
+}
+
+void FETurbulence::setType(TurbulanceType type)
+{
+ m_type = type;
+}
+
+float FETurbulence::baseFrequencyY() const
+{
+ return m_baseFrequencyY;
+}
+
+void FETurbulence::setBaseFrequencyY(float baseFrequencyY)
+{
+ m_baseFrequencyY = baseFrequencyY;
+}
+
+float FETurbulence::baseFrequencyX() const
+{
+ return m_baseFrequencyX;
+}
+
+void FETurbulence::setBaseFrequencyX(float baseFrequencyX)
+{
+ m_baseFrequencyX = baseFrequencyX;
+}
+
+float FETurbulence::seed() const
+{
+ return m_seed;
+}
+
+void FETurbulence::setSeed(float seed)
+{
+ m_seed = seed;
+}
+
+int FETurbulence::numOctaves() const
+{
+ return m_numOctaves;
+}
+
+void FETurbulence::setNumOctaves(bool numOctaves)
+{
+ m_numOctaves = numOctaves;
+}
+
+bool FETurbulence::stitchTiles() const
+{
+ return m_stitchTiles;
+}
+
+void FETurbulence::setStitchTiles(bool stitch)
+{
+ m_stitchTiles = stitch;
+}
+
+// The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification:
+// http://www.w3.org/TR/SVG11/filters.html#feTurbulence
+
+FETurbulence::PaintingData::PaintingData(long paintingSeed, const IntSize& paintingSize)
+ : seed(paintingSeed)
+ , width(0)
+ , height(0)
+ , wrapX(0)
+ , wrapY(0)
+ , channel(0)
+ , filterSize(paintingSize)
+{
+}
+
+// Compute pseudo random number.
+inline long FETurbulence::PaintingData::random()
+{
+ long result = s_randAmplitude * (seed % s_randQ) - s_randR * (seed / s_randQ);
+ if (result <= 0)
+ result += s_randMaximum;
+ seed = result;
+ return result;
+}
+
+inline float smoothCurve(float t)
+{
+ return t * t * (3 - 2 * t);
+}
+
+inline float linearInterpolation(float t, float a, float b)
+{
+ return a + t * (b - a);
+}
+
+inline void FETurbulence::initPaint(PaintingData& paintingData)
+{
+ float normalizationFactor;
+
+ // The seed value clamp to the range [1, s_randMaximum - 1].
+ if (paintingData.seed <= 0)
+ paintingData.seed = -(paintingData.seed % (s_randMaximum - 1)) + 1;
+ if (paintingData.seed > s_randMaximum - 1)
+ paintingData.seed = s_randMaximum - 1;
+
+ float* gradient;
+ for (int channel = 0; channel < 4; ++channel) {
+ for (int i = 0; i < s_blockSize; ++i) {
+ paintingData.latticeSelector[i] = i;
+ gradient = paintingData.gradient[channel][i];
+ gradient[0] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+ gradient[1] = static_cast<float>((paintingData.random() % (2 * s_blockSize)) - s_blockSize) / s_blockSize;
+ normalizationFactor = sqrtf(gradient[0] * gradient[0] + gradient[1] * gradient[1]);
+ gradient[0] /= normalizationFactor;
+ gradient[1] /= normalizationFactor;
+ }
+ }
+ for (int i = s_blockSize - 1; i > 0; --i) {
+ int k = paintingData.latticeSelector[i];
+ int j = paintingData.random() % s_blockSize;
+ ASSERT(j >= 0);
+ ASSERT(j < 2 * s_blockSize + 2);
+ paintingData.latticeSelector[i] = paintingData.latticeSelector[j];
+ paintingData.latticeSelector[j] = k;
+ }
+ for (int i = 0; i < s_blockSize + 2; ++i) {
+ paintingData.latticeSelector[s_blockSize + i] = paintingData.latticeSelector[i];
+ for (int channel = 0; channel < 4; ++channel) {
+ paintingData.gradient[channel][s_blockSize + i][0] = paintingData.gradient[channel][i][0];
+ paintingData.gradient[channel][s_blockSize + i][1] = paintingData.gradient[channel][i][1];
+ }
+ }
+}
+
+inline void checkNoise(int& noiseValue, int limitValue, int newValue)
+{
+ if (noiseValue >= limitValue)
+ noiseValue -= newValue;
+ if (noiseValue >= limitValue - 1)
+ noiseValue -= newValue - 1;
+}
+
+float FETurbulence::noise2D(PaintingData& paintingData, const FloatPoint& noiseVector)
+{
+ struct Noise {
+ int noisePositionIntegerValue;
+ float noisePositionFractionValue;
+
+ Noise(float component)
+ {
+ float position = component + s_perlinNoise;
+ noisePositionIntegerValue = static_cast<int>(position);
+ noisePositionFractionValue = position - noisePositionIntegerValue;
+ }
+ };
+
+ Noise noiseX(noiseVector.x());
+ Noise noiseY(noiseVector.y());
+ float* q;
+ float sx, sy, a, b, u, v;
+
+ // If stitching, adjust lattice points accordingly.
+ if (m_stitchTiles) {
+ checkNoise(noiseX.noisePositionIntegerValue, paintingData.wrapX, paintingData.width);
+ checkNoise(noiseY.noisePositionIntegerValue, paintingData.wrapY, paintingData.height);
+ }
+
+ noiseX.noisePositionIntegerValue &= s_blockMask;
+ noiseY.noisePositionIntegerValue &= s_blockMask;
+ int latticeIndex = paintingData.latticeSelector[noiseX.noisePositionIntegerValue];
+ int nextLatticeIndex = paintingData.latticeSelector[(noiseX.noisePositionIntegerValue + 1) & s_blockMask];
+
+ sx = smoothCurve(noiseX.noisePositionFractionValue);
+ sy = smoothCurve(noiseY.noisePositionFractionValue);
+
+ // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
+ int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
+ q = paintingData.gradient[paintingData.channel][temp];
+ u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
+ temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
+ q = paintingData.gradient[paintingData.channel][temp];
+ v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
+ a = linearInterpolation(sx, u, v);
+ temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
+ q = paintingData.gradient[paintingData.channel][temp];
+ u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+ temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
+ q = paintingData.gradient[paintingData.channel][temp];
+ v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
+ b = linearInterpolation(sx, u, v);
+ return linearInterpolation(sy, a, b);
+}
+
+unsigned char FETurbulence::calculateTurbulenceValueForPoint(PaintingData& paintingData, const FloatPoint& point)
+{
+ float tileWidth = paintingData.filterSize.width();
+ ASSERT(tileWidth > 0);
+ float tileHeight = paintingData.filterSize.height();
+ ASSERT(tileHeight > 0);
+ // Adjust the base frequencies if necessary for stitching.
+ if (m_stitchTiles) {
+ // When stitching tiled turbulence, the frequencies must be adjusted
+ // so that the tile borders will be continuous.
+ if (m_baseFrequencyX) {
+ float lowFrequency = floorf(tileWidth * m_baseFrequencyX) / tileWidth;
+ float highFrequency = ceilf(tileWidth * m_baseFrequencyX) / tileWidth;
+ // BaseFrequency should be non-negative according to the standard.
+ if (m_baseFrequencyX / lowFrequency < highFrequency / m_baseFrequencyX)
+ m_baseFrequencyX = lowFrequency;
+ else
+ m_baseFrequencyX = highFrequency;
+ }
+ if (m_baseFrequencyY) {
+ float lowFrequency = floorf(tileHeight * m_baseFrequencyY) / tileHeight;
+ float highFrequency = ceilf(tileHeight * m_baseFrequencyY) / tileHeight;
+ if (m_baseFrequencyY / lowFrequency < highFrequency / m_baseFrequencyY)
+ m_baseFrequencyY = lowFrequency;
+ else
+ m_baseFrequencyY = highFrequency;
+ }
+ // Set up TurbulenceInitial stitch values.
+ paintingData.width = roundf(tileWidth * m_baseFrequencyX);
+ paintingData.wrapX = s_perlinNoise + paintingData.width;
+ paintingData.height = roundf(tileHeight * m_baseFrequencyY);
+ paintingData.wrapY = s_perlinNoise + paintingData.height;
+ }
+ float turbulenceFunctionResult = 0;
+ FloatPoint noiseVector(point.x() * m_baseFrequencyX, point.y() * m_baseFrequencyY);
+ float ratio = 1;
+ for (int octave = 0; octave < m_numOctaves; ++octave) {
+ if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
+ turbulenceFunctionResult += noise2D(paintingData, noiseVector) / ratio;
+ else
+ turbulenceFunctionResult += fabsf(noise2D(paintingData, noiseVector)) / ratio;
+ noiseVector.setX(noiseVector.x() * 2);
+ noiseVector.setY(noiseVector.y() * 2);
+ ratio *= 2;
+ if (m_stitchTiles) {
+ // Update stitch values. Subtracting s_perlinNoiseoise before the multiplication and
+ // adding it afterward simplifies to subtracting it once.
+ paintingData.width *= 2;
+ paintingData.wrapX = 2 * paintingData.wrapX - s_perlinNoise;
+ paintingData.height *= 2;
+ paintingData.wrapY = 2 * paintingData.wrapY - s_perlinNoise;
+ }
+ }
+
+ // The value of turbulenceFunctionResult comes from ((turbulenceFunctionResult * 255) + 255) / 2 by fractalNoise
+ // and (turbulenceFunctionResult * 255) by turbulence.
+ if (m_type == FETURBULENCE_TYPE_FRACTALNOISE)
+ turbulenceFunctionResult = turbulenceFunctionResult * 0.5f + 0.5f;
+ // Clamp result
+ turbulenceFunctionResult = std::max(std::min(turbulenceFunctionResult, 1.f), 0.f);
+ return static_cast<unsigned char>(turbulenceFunctionResult * 255);
+}
+
+void FETurbulence::apply(Filter* filter)
+{
+ if (!effectContext())
+ return;
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ if (!imageRect.size().width() || !imageRect.size().height())
+ return;
+
+ RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
+ PaintingData paintingData(m_seed, imageRect.size());
+ initPaint(paintingData);
+
+ FloatRect filterRegion = filter->filterRegion();
+ FloatPoint point;
+ point.setY(filterRegion.y());
+ int indexOfPixelChannel = 0;
+ for (int y = 0; y < imageRect.height(); ++y) {
+ point.setY(point.y() + 1);
+ point.setX(filterRegion.x());
+ for (int x = 0; x < imageRect.width(); ++x) {
+ point.setX(point.x() + 1);
+ for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
+ imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, point));
+ }
+ }
+ resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
+}
+
+void FETurbulence::dump()
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const TurbulanceType& type)
+{
+ switch (type) {
+ case FETURBULENCE_TYPE_UNKNOWN:
+ ts << "UNKNOWN";
+ break;
+ case FETURBULENCE_TYPE_TURBULENCE:
+ ts << "TURBULANCE";
+ break;
+ case FETURBULENCE_TYPE_FRACTALNOISE:
+ ts << "NOISE";
+ break;
+ }
+ return ts;
+}
+
+TextStream& FETurbulence::externalRepresentation(TextStream& ts, int indent) const
+{
+ writeIndent(ts, indent);
+ ts << "[feTurbulence";
+ FilterEffect::externalRepresentation(ts);
+ ts << " type=\"" << type() << "\" "
+ << "baseFrequency=\"" << baseFrequencyX() << ", " << baseFrequencyY() << "\" "
+ << "seed=\"" << seed() << "\" "
+ << "numOctaves=\"" << numOctaves() << "\" "
+ << "stitchTiles=\"" << stitchTiles() << "\"]\n";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FETurbulence.h b/WebCore/platform/graphics/filters/FETurbulence.h
new file mode 100644
index 0000000..1a5a28a
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FETurbulence.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2010 Renata Hodovan <reni@inf.u-szeged.hu>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef FETurbulence_h
+#define FETurbulence_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+enum TurbulanceType {
+ FETURBULENCE_TYPE_UNKNOWN = 0,
+ FETURBULENCE_TYPE_FRACTALNOISE = 1,
+ FETURBULENCE_TYPE_TURBULENCE = 2
+};
+
+class FETurbulence : public FilterEffect {
+public:
+ static PassRefPtr<FETurbulence> create(TurbulanceType, float, float, int, float, bool);
+
+ TurbulanceType type() const;
+ void setType(TurbulanceType);
+
+ float baseFrequencyY() const;
+ void setBaseFrequencyY(float);
+
+ float baseFrequencyX() const;
+ void setBaseFrequencyX(float);
+
+ float seed() const;
+ void setSeed(float);
+
+ int numOctaves() const;
+ void setNumOctaves(bool);
+
+ bool stitchTiles() const;
+ void setStitchTiles(bool);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
+
+private:
+ static const int s_blockSize = 256;
+ static const int s_blockMask = s_blockSize - 1;
+
+ struct PaintingData {
+ long seed;
+ int latticeSelector[2 * s_blockSize + 2];
+ float gradient[4][2 * s_blockSize + 2][2];
+ int width; // How much to subtract to wrap for stitching.
+ int height;
+ int wrapX; // Minimum value to wrap.
+ int wrapY;
+ int channel;
+ IntSize filterSize;
+
+ PaintingData(long paintingSeed, const IntSize& paintingSize);
+ inline long random();
+ };
+
+ FETurbulence(TurbulanceType, float, float, int, float, bool);
+
+ inline void initPaint(PaintingData&);
+ float noise2D(PaintingData&, const FloatPoint&);
+ unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&);
+
+ TurbulanceType m_type;
+ float m_baseFrequencyX;
+ float m_baseFrequencyY;
+ int m_numOctaves;
+ float m_seed;
+ bool m_stitchTiles;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FETurbulence_h
diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h
index 7ad25aa..bce4be3 100644
--- a/WebCore/platform/graphics/filters/Filter.h
+++ b/WebCore/platform/graphics/filters/Filter.h
@@ -1,20 +1,20 @@
/*
- * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
- * aint with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifndef Filter_h
diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp
index b6278b2..461b22a 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -56,7 +56,7 @@ FloatRect FilterEffect::determineFilterPrimitiveSubregion(Filter* filter)
return m_filterPrimitiveSubregion;
}
-IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect) const
+IntRect FilterEffect::requestedRegionOfInputImageData(const FloatRect& effectRect) const
{
ASSERT(m_effectBuffer);
FloatPoint location = m_repaintRectInLocalCoordinates.location();
@@ -64,7 +64,7 @@ IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect) const
return IntRect(roundedIntPoint(location), m_effectBuffer->size());
}
-FloatRect FilterEffect::calculateDrawingRect(const FloatRect& srcRect) const
+FloatRect FilterEffect::drawingRegionOfInputImage(const FloatRect& srcRect) const
{
return FloatRect(FloatPoint(srcRect.x() - m_repaintRectInLocalCoordinates.x(),
srcRect.y() - m_repaintRectInLocalCoordinates.y()), srcRect.size());
@@ -76,7 +76,7 @@ FilterEffect* FilterEffect::inputEffect(unsigned number) const
return m_inputEffects.at(number).get();
}
-GraphicsContext* FilterEffect::getEffectContext()
+GraphicsContext* FilterEffect::effectContext()
{
IntRect bufferRect = enclosingIntRect(m_repaintRectInLocalCoordinates);
m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB);
diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h
index 91c52f3..ebe1880 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/WebCore/platform/graphics/filters/FilterEffect.h
@@ -49,14 +49,14 @@ public:
// Creates the ImageBuffer for the current filter primitive result in the size of the
// repaintRect. Gives back the GraphicsContext of the own ImageBuffer.
- GraphicsContext* getEffectContext();
+ GraphicsContext* effectContext();
FilterEffectVector& inputEffects() { return m_inputEffects; }
FilterEffect* inputEffect(unsigned) const;
unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
- FloatRect calculateDrawingRect(const FloatRect&) const;
- IntRect calculateDrawingIntRect(const FloatRect&) const;
+ FloatRect drawingRegionOfInputImage(const FloatRect&) const;
+ IntRect requestedRegionOfInputImageData(const FloatRect&) const;
// Solid black image with different alpha values.
bool isAlphaImage() const { return m_alphaImage; }
diff --git a/WebCore/platform/graphics/filters/ImageBufferFilter.cpp b/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
index 33953d6..12407f8 100644
--- a/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
+++ b/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
@@ -1,21 +1,21 @@
/*
- * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
- * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
- * aint with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#include "config.h"
diff --git a/WebCore/platform/graphics/filters/ImageBufferFilter.h b/WebCore/platform/graphics/filters/ImageBufferFilter.h
index a2775ea..cd4bc2f 100644
--- a/WebCore/platform/graphics/filters/ImageBufferFilter.h
+++ b/WebCore/platform/graphics/filters/ImageBufferFilter.h
@@ -1,21 +1,21 @@
/*
- * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
- * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
- * aint with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#ifndef ImageBufferFilter_h
diff --git a/WebCore/platform/graphics/filters/LightSource.cpp b/WebCore/platform/graphics/filters/LightSource.cpp
new file mode 100644
index 0000000..a80b14b
--- /dev/null
+++ b/WebCore/platform/graphics/filters/LightSource.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+#include "DistantLightSource.h"
+#include "PointLightSource.h"
+#include "RenderTreeAsText.h"
+#include "SpotLightSource.h"
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+void PointLightSource::initPaintingData(PaintingData&)
+{
+}
+
+void PointLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+{
+ paintingData.lightVector.setX(m_position.x() - x);
+ paintingData.lightVector.setY(m_position.y() - y);
+ paintingData.lightVector.setZ(m_position.z() - z);
+ paintingData.lightVector.normalize();
+}
+
+// spot-light edge darkening depends on an absolute treshold
+// according to the SVG 1.1 SE light regression tests
+static const float antiAliasTreshold = 0.016f;
+
+void SpotLightSource::initPaintingData(PaintingData& paintingData)
+{
+ paintingData.privateColorVector = paintingData.colorVector;
+ paintingData.directionVector.setX(m_direction.x() - m_position.x());
+ paintingData.directionVector.setY(m_direction.y() - m_position.y());
+ paintingData.directionVector.setZ(m_direction.z() - m_position.z());
+ paintingData.directionVector.normalize();
+
+ if (!m_limitingConeAngle) {
+ paintingData.coneCutOffLimit = 0.0f;
+ paintingData.coneFullLight = -antiAliasTreshold;
+ } else {
+ float limitingConeAngle = m_limitingConeAngle;
+ if (limitingConeAngle < 0.0f)
+ limitingConeAngle = -limitingConeAngle;
+ if (limitingConeAngle > 90.0f)
+ limitingConeAngle = 90.0f;
+ paintingData.coneCutOffLimit = cosf(deg2rad(180.0f - limitingConeAngle));
+ paintingData.coneFullLight = paintingData.coneCutOffLimit - antiAliasTreshold;
+ }
+
+ // Optimization for common specularExponent values
+ if (!m_specularExponent)
+ paintingData.specularExponent = 0;
+ else if (m_specularExponent == 1.0f)
+ paintingData.specularExponent = 1;
+ else // It is neither 0.0f nor 1.0f
+ paintingData.specularExponent = 2;
+}
+
+void SpotLightSource::updatePaintingData(PaintingData& paintingData, int x, int y, float z)
+{
+ paintingData.lightVector.setX(m_position.x() - x);
+ paintingData.lightVector.setY(m_position.y() - y);
+ paintingData.lightVector.setZ(m_position.z() - z);
+ paintingData.lightVector.normalize();
+
+ float cosineOfAngle = paintingData.lightVector * paintingData.directionVector;
+ if (cosineOfAngle > paintingData.coneCutOffLimit) {
+ // No light is produced, scanlines are not updated
+ paintingData.colorVector.setX(0.0f);
+ paintingData.colorVector.setY(0.0f);
+ paintingData.colorVector.setZ(0.0f);
+ return;
+ }
+
+ // Set the color of the pixel
+ float lightStrength;
+ switch (paintingData.specularExponent) {
+ case 0:
+ lightStrength = 1.0f; // -cosineOfAngle ^ 0 == 1
+ break;
+ case 1:
+ lightStrength = -cosineOfAngle; // -cosineOfAngle ^ 1 == -cosineOfAngle
+ break;
+ default:
+ lightStrength = powf(-cosineOfAngle, m_specularExponent);
+ break;
+ }
+
+ if (cosineOfAngle > paintingData.coneFullLight)
+ lightStrength *= (paintingData.coneCutOffLimit - cosineOfAngle) / (paintingData.coneCutOffLimit - paintingData.coneFullLight);
+
+ if (lightStrength > 1.0f)
+ lightStrength = 1.0f;
+
+ paintingData.colorVector.setX(paintingData.privateColorVector.x() * lightStrength);
+ paintingData.colorVector.setY(paintingData.privateColorVector.y() * lightStrength);
+ paintingData.colorVector.setZ(paintingData.privateColorVector.z() * lightStrength);
+}
+
+void DistantLightSource::initPaintingData(PaintingData& paintingData)
+{
+ float azimuth = deg2rad(m_azimuth);
+ float elevation = deg2rad(m_elevation);
+ paintingData.lightVector.setX(cosf(azimuth) * cosf(elevation));
+ paintingData.lightVector.setY(sinf(azimuth) * cosf(elevation));
+ paintingData.lightVector.setZ(sinf(elevation));
+}
+
+void DistantLightSource::updatePaintingData(PaintingData&, int, int, float)
+{
+}
+
+static TextStream& operator<<(TextStream& ts, const FloatPoint3D& p)
+{
+ ts << "x=" << p.x() << " y=" << p.y() << " z=" << p.z();
+ return ts;
+}
+
+TextStream& PointLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=POINT-LIGHT] ";
+ ts << "[position=\"" << position() << "\"]";
+ return ts;
+}
+
+TextStream& SpotLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=SPOT-LIGHT] ";
+ ts << "[position=\"" << position() << "\"]";
+ ts << "[direction=\"" << direction() << "\"]";
+ ts << "[specularExponent=\"" << specularExponent() << "\"]";
+ ts << "[limitingConeAngle=\"" << limitingConeAngle() << "\"]";
+ return ts;
+}
+
+TextStream& DistantLightSource::externalRepresentation(TextStream& ts) const
+{
+ ts << "[type=DISTANT-LIGHT] ";
+ ts << "[azimuth=\"" << azimuth() << "\"]";
+ ts << "[elevation=\"" << elevation() << "\"]";
+ return ts;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/LightSource.h b/WebCore/platform/graphics/filters/LightSource.h
new file mode 100644
index 0000000..2e4c579
--- /dev/null
+++ b/WebCore/platform/graphics/filters/LightSource.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2010 Zoltan Herczeg <zherczeg@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LightSource_h
+#define LightSource_h
+
+#if ENABLE(FILTERS)
+#include "FloatPoint3D.h"
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+enum LightType {
+ LS_DISTANT,
+ LS_POINT,
+ LS_SPOT
+};
+
+class TextStream;
+
+class LightSource : public RefCounted<LightSource> {
+public:
+
+ // Light vectors must be calculated for every pixel during
+ // painting. It is expensive to pass all these arguments to
+ // a frequently called function, especially because not all
+ // light sources require all of them. Instead, we just pass
+ // a reference to the following structure
+ struct PaintingData {
+ // SVGFELighting also use them
+ FloatPoint3D lightVector;
+ FloatPoint3D colorVector;
+ // Private members
+ FloatPoint3D directionVector;
+ FloatPoint3D privateColorVector;
+ float coneCutOffLimit;
+ float coneFullLight;
+ int specularExponent;
+ };
+
+ LightSource(LightType type)
+ : m_type(type)
+ { }
+
+ virtual ~LightSource() { }
+
+ LightType type() const { return m_type; }
+ virtual TextStream& externalRepresentation(TextStream&) const = 0;
+
+ virtual void initPaintingData(PaintingData&) = 0;
+ // z is a float number, since it is the alpha value scaled by a user
+ // specified "surfaceScale" constant, which type is <number> in the SVG standard
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z) = 0;
+
+private:
+ LightType m_type;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // LightSource_h
diff --git a/WebCore/platform/graphics/filters/PointLightSource.h b/WebCore/platform/graphics/filters/PointLightSource.h
new file mode 100644
index 0000000..163c829
--- /dev/null
+++ b/WebCore/platform/graphics/filters/PointLightSource.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef PointLightSource_h
+#define PointLightSource_h
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+namespace WebCore {
+
+class PointLightSource : public LightSource {
+public:
+ static PassRefPtr<PointLightSource> create(const FloatPoint3D& position)
+ {
+ return adoptRef(new PointLightSource(position));
+ }
+
+ const FloatPoint3D& position() const { return m_position; }
+
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+
+private:
+ PointLightSource(const FloatPoint3D& position)
+ : LightSource(LS_POINT)
+ , m_position(position)
+ {
+ }
+
+ FloatPoint3D m_position;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // PointLightSource_h
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
index 9c6a953..beaf2e7 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.cpp
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -1,20 +1,20 @@
/*
- * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
- * aint with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#include "config.h"
@@ -57,7 +57,7 @@ FloatRect SourceAlpha::determineFilterPrimitiveSubregion(Filter* filter)
void SourceAlpha::apply(Filter* filter)
{
- GraphicsContext* filterContext = getEffectContext();
+ GraphicsContext* filterContext = effectContext();
if (!filterContext)
return;
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.h b/WebCore/platform/graphics/filters/SourceAlpha.h
index 25a17b2..f0fa319 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.h
+++ b/WebCore/platform/graphics/filters/SourceAlpha.h
@@ -1,21 +1,21 @@
/*
- Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef SourceAlpha_h
#define SourceAlpha_h
@@ -28,22 +28,25 @@
namespace WebCore {
- class SourceAlpha : public FilterEffect {
- public:
- static PassRefPtr<SourceAlpha> create();
+class SourceAlpha : public FilterEffect {
+public:
+ static PassRefPtr<SourceAlpha> create();
+
+ static const AtomicString& effectName();
+
+ virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
+
+ virtual void apply(Filter*);
+ virtual void dump();
+
+ virtual bool isSourceInput() const { return true; }
- static const AtomicString& effectName();
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
+private:
+ SourceAlpha() { }
+};
- virtual bool isSourceInput() const { return true; }
- virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
-
- private:
- SourceAlpha() { }
- };
} //namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp
index 6a32e36..c014e68 100644
--- a/WebCore/platform/graphics/filters/SourceGraphic.cpp
+++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -1,20 +1,20 @@
/*
- * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
*
- * You should have received a copy of the GNU Library General Public License
- * aint with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
#include "config.h"
@@ -56,7 +56,7 @@ FloatRect SourceGraphic::determineFilterPrimitiveSubregion(Filter* filter)
void SourceGraphic::apply(Filter* filter)
{
- GraphicsContext* filterContext = getEffectContext();
+ GraphicsContext* filterContext = effectContext();
if (!filterContext)
return;
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.h b/WebCore/platform/graphics/filters/SourceGraphic.h
index 911648c..2378798 100644
--- a/WebCore/platform/graphics/filters/SourceGraphic.h
+++ b/WebCore/platform/graphics/filters/SourceGraphic.h
@@ -1,22 +1,22 @@
/*
- Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
- 2009 Dirk Schulze <krit@webkit.org>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- aint with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
#ifndef SourceGraphic_h
#define SourceGrahpic_h
@@ -29,22 +29,25 @@
namespace WebCore {
- class SourceGraphic : public FilterEffect {
- public:
- static PassRefPtr<SourceGraphic> create();
+class SourceGraphic : public FilterEffect {
+public:
+ static PassRefPtr<SourceGraphic> create();
+
+ static const AtomicString& effectName();
+
+ virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
+
+ virtual void apply(Filter*);
+ virtual void dump();
- static const AtomicString& effectName();
+ virtual bool isSourceInput() const { return true; }
- void apply(Filter*);
- void dump();
- TextStream& externalRepresentation(TextStream&, int indent) const;
+ virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- virtual bool isSourceInput() const { return true; }
- virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
+private:
+ SourceGraphic() { }
+};
- private:
- SourceGraphic() { }
- };
} //namespace WebCore
#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/SpotLightSource.h b/WebCore/platform/graphics/filters/SpotLightSource.h
new file mode 100644
index 0000000..cd6a614
--- /dev/null
+++ b/WebCore/platform/graphics/filters/SpotLightSource.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2008 Alex Mathews <possessedpenguinbob@gmail.com>
+ * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef SpotLightSource_h
+#define SpotLightSource_h
+
+#if ENABLE(FILTERS)
+#include "LightSource.h"
+
+namespace WebCore {
+
+class SpotLightSource : public LightSource {
+public:
+ static PassRefPtr<SpotLightSource> create(const FloatPoint3D& position,
+ const FloatPoint3D& direction, float specularExponent, float limitingConeAngle)
+ {
+ return adoptRef(new SpotLightSource(position, direction, specularExponent, limitingConeAngle));
+ }
+
+ const FloatPoint3D& position() const { return m_position; }
+ const FloatPoint3D& direction() const { return m_direction; }
+
+ float specularExponent() const { return m_specularExponent; }
+ float limitingConeAngle() const { return m_limitingConeAngle; }
+
+ virtual void initPaintingData(PaintingData&);
+ virtual void updatePaintingData(PaintingData&, int x, int y, float z);
+
+ virtual TextStream& externalRepresentation(TextStream&) const;
+
+private:
+ SpotLightSource(const FloatPoint3D& position, const FloatPoint3D& direction,
+ float specularExponent, float limitingConeAngle)
+ : LightSource(LS_SPOT)
+ , m_position(position)
+ , m_direction(direction)
+ , m_specularExponent(specularExponent)
+ , m_limitingConeAngle(limitingConeAngle)
+ {
+ }
+
+ FloatPoint3D m_position;
+ FloatPoint3D m_direction;
+
+ float m_specularExponent;
+ float m_limitingConeAngle;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // SpotLightSource_h
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.cpp b/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.cpp
new file mode 100644
index 0000000..3b73ff6
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.cpp
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "LoopBlinnLocalTriangulator.h"
+
+#include "LoopBlinnMathUtils.h"
+#include <algorithm>
+
+namespace WebCore {
+
+using LoopBlinnMathUtils::approxEqual;
+using LoopBlinnMathUtils::linesIntersect;
+using LoopBlinnMathUtils::pointInTriangle;
+
+bool LoopBlinnLocalTriangulator::Triangle::contains(LoopBlinnLocalTriangulator::Vertex* v)
+{
+ return indexForVertex(v) >= 0;
+}
+
+LoopBlinnLocalTriangulator::Vertex* LoopBlinnLocalTriangulator::Triangle::nextVertex(LoopBlinnLocalTriangulator::Vertex* current, bool traverseCounterClockwise)
+{
+ int index = indexForVertex(current);
+ ASSERT(index >= 0);
+ if (traverseCounterClockwise)
+ ++index;
+ else
+ --index;
+ if (index < 0)
+ index += 3;
+ else
+ index = index % 3;
+ return m_vertices[index];
+}
+
+int LoopBlinnLocalTriangulator::Triangle::indexForVertex(LoopBlinnLocalTriangulator::Vertex* vertex)
+{
+ for (int i = 0; i < 3; ++i)
+ if (m_vertices[i] == vertex)
+ return i;
+ return -1;
+}
+
+void LoopBlinnLocalTriangulator::Triangle::makeCounterClockwise()
+{
+ // Possibly swaps two vertices so that the triangle's vertices are
+ // always specified in counterclockwise order. This orders the
+ // vertices canonically when walking the interior edges from the
+ // start to the end vertex.
+ FloatPoint3D point0(m_vertices[0]->xyCoordinates());
+ FloatPoint3D point1(m_vertices[1]->xyCoordinates());
+ FloatPoint3D point2(m_vertices[2]->xyCoordinates());
+ FloatPoint3D crossProduct = (point1 - point0).cross(point2 - point0);
+ if (crossProduct.z() < 0)
+ std::swap(m_vertices[1], m_vertices[2]);
+}
+
+LoopBlinnLocalTriangulator::LoopBlinnLocalTriangulator()
+{
+ reset();
+}
+
+void LoopBlinnLocalTriangulator::reset()
+{
+ m_numberOfTriangles = 0;
+ m_numberOfInteriorVertices = 0;
+ for (int i = 0; i < 4; ++i) {
+ m_interiorVertices[i] = 0;
+ m_vertices[i].resetFlags();
+ }
+}
+
+void LoopBlinnLocalTriangulator::triangulate(InsideEdgeComputation computeInsideEdges, LoopBlinnConstants::FillSide sideToFill)
+{
+ triangulateHelper(sideToFill);
+
+ if (computeInsideEdges == ComputeInsideEdges) {
+ // We need to compute which vertices describe the path along the
+ // interior portion of the shape, to feed these vertices to the
+ // more general tessellation algorithm. It is possible that we
+ // could determine this directly while producing triangles above.
+ // Here we try to do it generally just by examining the triangles
+ // that have already been produced. We walk around them in a
+ // specific direction determined by which side of the curve is
+ // being filled. We ignore the interior vertex unless it is also
+ // the ending vertex, and skip the edges shared between two
+ // triangles.
+ Vertex* v = &m_vertices[0];
+ addInteriorVertex(v);
+ int numSteps = 0;
+ while (!v->end() && numSteps < 4) {
+ // Find the next vertex according to the above rules
+ bool gotNext = false;
+ for (int i = 0; i < numberOfTriangles() && !gotNext; ++i) {
+ Triangle* tri = getTriangle(i);
+ if (tri->contains(v)) {
+ Vertex* next = tri->nextVertex(v, sideToFill == LoopBlinnConstants::RightSide);
+ if (!next->marked() && !isSharedEdge(v, next) && (!next->interior() || next->end())) {
+ addInteriorVertex(next);
+ v = next;
+ // Break out of for loop
+ gotNext = true;
+ }
+ }
+ }
+ ++numSteps;
+ }
+ if (!v->end()) {
+ // Something went wrong with the above algorithm; add the last
+ // vertex to the interior vertices anyway. (FIXME: should we
+ // add an assert here and do more extensive testing?)
+ addInteriorVertex(&m_vertices[3]);
+ }
+ }
+}
+
+void LoopBlinnLocalTriangulator::triangulateHelper(LoopBlinnConstants::FillSide sideToFill)
+{
+ reset();
+
+ m_vertices[3].setEnd(true);
+
+ // First test for degenerate cases.
+ for (int i = 0; i < 4; ++i) {
+ for (int j = i + 1; j < 4; ++j) {
+ if (approxEqual(m_vertices[i].xyCoordinates(), m_vertices[j].xyCoordinates())) {
+ // Two of the vertices are coincident, so we can eliminate at
+ // least one triangle. We might be able to eliminate the other
+ // as well, but this seems sufficient to avoid degenerate
+ // triangulations.
+ int indices[3] = { 0 };
+ int index = 0;
+ for (int k = 0; k < 4; ++k)
+ if (k != j)
+ indices[index++] = k;
+ addTriangle(&m_vertices[indices[0]],
+ &m_vertices[indices[1]],
+ &m_vertices[indices[2]]);
+ return;
+ }
+ }
+ }
+
+ // See whether any of the points are fully contained in the
+ // triangle defined by the other three.
+ for (int i = 0; i < 4; ++i) {
+ int indices[3] = { 0 };
+ int index = 0;
+ for (int j = 0; j < 4; ++j)
+ if (i != j)
+ indices[index++] = j;
+ if (pointInTriangle(m_vertices[i].xyCoordinates(),
+ m_vertices[indices[0]].xyCoordinates(),
+ m_vertices[indices[1]].xyCoordinates(),
+ m_vertices[indices[2]].xyCoordinates())) {
+ // Produce three triangles surrounding this interior vertex.
+ for (int j = 0; j < 3; ++j)
+ addTriangle(&m_vertices[indices[j % 3]],
+ &m_vertices[indices[(j + 1) % 3]],
+ &m_vertices[i]);
+ // Mark the interior vertex so we ignore it if trying to trace
+ // the interior edge.
+ m_vertices[i].setInterior(true);
+ return;
+ }
+ }
+
+ // There are only a few permutations of the vertices, ignoring
+ // rotations, which are irrelevant:
+ //
+ // 0--3 0--2 0--3 0--1 0--2 0--1
+ // | | | | | | | | | | | |
+ // | | | | | | | | | | | |
+ // 1--2 1--3 2--1 2--3 3--1 3--2
+ //
+ // Note that three of these are reflections of each other.
+ // Therefore there are only three possible triangulations:
+ //
+ // 0--3 0--2 0--3
+ // |\ | |\ | |\ |
+ // | \| | \| | \|
+ // 1--2 1--3 2--1
+ //
+ // From which we can choose by seeing which of the potential
+ // diagonals intersect. Note that we choose the shortest diagonal
+ // to split the quad.
+ if (linesIntersect(m_vertices[0].xyCoordinates(),
+ m_vertices[2].xyCoordinates(),
+ m_vertices[1].xyCoordinates(),
+ m_vertices[3].xyCoordinates())) {
+ if ((m_vertices[2].xyCoordinates() - m_vertices[0].xyCoordinates()).diagonalLengthSquared() <
+ (m_vertices[3].xyCoordinates() - m_vertices[1].xyCoordinates()).diagonalLengthSquared()) {
+ addTriangle(&m_vertices[0], &m_vertices[1], &m_vertices[2]);
+ addTriangle(&m_vertices[0], &m_vertices[2], &m_vertices[3]);
+ } else {
+ addTriangle(&m_vertices[0], &m_vertices[1], &m_vertices[3]);
+ addTriangle(&m_vertices[1], &m_vertices[2], &m_vertices[3]);
+ }
+ } else if (linesIntersect(m_vertices[0].xyCoordinates(),
+ m_vertices[3].xyCoordinates(),
+ m_vertices[1].xyCoordinates(),
+ m_vertices[2].xyCoordinates())) {
+ if ((m_vertices[3].xyCoordinates() - m_vertices[0].xyCoordinates()).diagonalLengthSquared() <
+ (m_vertices[2].xyCoordinates() - m_vertices[1].xyCoordinates()).diagonalLengthSquared()) {
+ addTriangle(&m_vertices[0], &m_vertices[1], &m_vertices[3]);
+ addTriangle(&m_vertices[0], &m_vertices[3], &m_vertices[2]);
+ } else {
+ addTriangle(&m_vertices[0], &m_vertices[1], &m_vertices[2]);
+ addTriangle(&m_vertices[2], &m_vertices[1], &m_vertices[3]);
+ }
+ } else {
+ // Lines (0->1), (2->3) intersect -- or should, modulo numerical
+ // precision issues
+ if ((m_vertices[1].xyCoordinates() - m_vertices[0].xyCoordinates()).diagonalLengthSquared() <
+ (m_vertices[3].xyCoordinates() - m_vertices[2].xyCoordinates()).diagonalLengthSquared()) {
+ addTriangle(&m_vertices[0], &m_vertices[2], &m_vertices[1]);
+ addTriangle(&m_vertices[0], &m_vertices[1], &m_vertices[3]);
+ } else {
+ addTriangle(&m_vertices[0], &m_vertices[2], &m_vertices[3]);
+ addTriangle(&m_vertices[3], &m_vertices[2], &m_vertices[1]);
+ }
+ }
+}
+
+void LoopBlinnLocalTriangulator::addTriangle(Vertex* v0, Vertex* v1, Vertex* v2)
+{
+ ASSERT(m_numberOfTriangles < 3);
+ m_triangles[m_numberOfTriangles++].setVertices(v0, v1, v2);
+}
+
+void LoopBlinnLocalTriangulator::addInteriorVertex(Vertex* v)
+{
+ ASSERT(m_numberOfInteriorVertices < 4);
+ m_interiorVertices[m_numberOfInteriorVertices++] = v;
+ v->setMarked(true);
+}
+
+bool LoopBlinnLocalTriangulator::isSharedEdge(Vertex* v0, Vertex* v1)
+{
+ bool haveEdge01 = false;
+ bool haveEdge10 = false;
+ for (int i = 0; i < numberOfTriangles(); ++i) {
+ Triangle* tri = getTriangle(i);
+ if (tri->contains(v0) && tri->nextVertex(v0, true) == v1)
+ haveEdge01 = true;
+ if (tri->contains(v1) && tri->nextVertex(v1, true) == v0)
+ haveEdge10 = true;
+ }
+ return haveEdge01 && haveEdge10;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h b/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h
new file mode 100644
index 0000000..ea3d7e3
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef LoopBlinnLocalTriangulator_h
+#define LoopBlinnLocalTriangulator_h
+
+#include "FloatPoint.h"
+#include "FloatPoint3D.h"
+#include "LoopBlinnConstants.h"
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+
+namespace WebCore {
+
+// Performs a localized triangulation of the triangle mesh
+// corresponding to the four control point vertices of a cubic curve
+// segment.
+class LoopBlinnLocalTriangulator : public Noncopyable {
+public:
+ // The vertices that the triangulator operates upon, containing both
+ // the position information as well as the cubic texture
+ // coordinates.
+ class Vertex : public Noncopyable {
+ public:
+ Vertex()
+ {
+ resetFlags();
+ }
+
+ const FloatPoint& xyCoordinates() const
+ {
+ return m_xyCoordinates;
+ }
+
+ const FloatPoint3D& klmCoordinates() const
+ {
+ return m_klmCoordinates;
+ }
+
+ // Sets the position and texture coordinates of the vertex.
+ void set(float x, float y,
+ float k, float l, float m)
+ {
+ m_xyCoordinates.set(x, y);
+ m_klmCoordinates.set(k, l, m);
+ }
+
+ // Flags for walking from the start vertex to the end vertex.
+ bool end()
+ {
+ return m_end;
+ }
+
+ void setEnd(bool end)
+ {
+ m_end = end;
+ }
+
+ bool marked()
+ {
+ return m_marked;
+ }
+
+ void setMarked(bool marked)
+ {
+ m_marked = marked;
+ }
+
+ bool interior()
+ {
+ return m_interior;
+ }
+
+ void setInterior(bool interior)
+ {
+ m_interior = interior;
+ }
+
+ void resetFlags()
+ {
+ m_end = false;
+ m_marked = false;
+ m_interior = false;
+ }
+
+ private:
+ // 2D coordinates of the vertex in the plane.
+ FloatPoint m_xyCoordinates;
+ // Cubic texture coordinates for rendering the curve.
+ FloatPoint3D m_klmCoordinates;
+
+ // Flags for walking from the start vertex to the end vertex.
+ bool m_end;
+ bool m_marked;
+ bool m_interior;
+ };
+
+ // The triangles the Triangulator produces.
+ class Triangle {
+ public:
+ Triangle()
+ {
+ m_vertices[0] = 0;
+ m_vertices[1] = 0;
+ m_vertices[2] = 0;
+ }
+
+ // Gets the vertex at the given index, 0 <= index < 3.
+ Vertex* getVertex(int index)
+ {
+ ASSERT(index >= 0 && index < 3);
+ return m_vertices[index];
+ }
+
+ // Returns true if this triangle contains the given vertex (by
+ // identity, not geometrically).
+ bool contains(Vertex* v);
+
+ // Returns the vertex following the current one in the specified
+ // direction, counterclockwise or clockwise.
+ Vertex* nextVertex(Vertex* current, bool traverseCounterClockwise);
+
+ // Sets the vertices of this triangle, potentially reordering them
+ // to produce a canonical orientation.
+ void setVertices(Vertex* v0,
+ Vertex* v1,
+ Vertex* v2)
+ {
+ m_vertices[0] = v0;
+ m_vertices[1] = v1;
+ m_vertices[2] = v2;
+ makeCounterClockwise();
+ }
+
+ private:
+ // Returns the index [0..2] associated with the given vertex, or
+ // -1 if not found.
+ int indexForVertex(Vertex* vertex);
+
+ // Reorders the vertices in this triangle to make them
+ // counterclockwise when viewed in the 2D plane, in order to
+ // achieve a canonical ordering.
+ void makeCounterClockwise();
+
+ // Note: these are raw pointers because they point to the
+ // m_vertices contained in the surrounding triangulator.
+ Vertex* m_vertices[3];
+ };
+
+ LoopBlinnLocalTriangulator();
+
+ // Resets the triangulator's state. After each triangulation and
+ // before the next, call this to re-initialize the internal
+ // vertices' state.
+ void reset();
+
+ // Returns a mutable vertex stored in the triangulator. Use this to
+ // set up the vertices before a triangulation.
+ Vertex* getVertex(int index)
+ {
+ ASSERT(index >= 0 && index < 4);
+ return &m_vertices[index];
+ }
+
+ enum InsideEdgeComputation {
+ ComputeInsideEdges,
+ DontComputeInsideEdges
+ };
+
+ // Once the vertices' contents have been set up, call triangulate()
+ // to recompute the triangles.
+ //
+ // If computeInsideEdges is ComputeInsideEdges, then sideToFill
+ // will be used to determine which side of the cubic curve defined
+ // by the four control points is to be filled.
+ //
+ // The triangulation obeys the following guarantees:
+ // - If the convex hull is a quadrilateral, then the shortest edge
+ // will be chosen for the cut into two triangles.
+ // - If one of the vertices is contained in the triangle spanned
+ // by the other three, three triangles will be produced.
+ void triangulate(InsideEdgeComputation computeInsideEdges,
+ LoopBlinnConstants::FillSide sideToFill);
+
+ // Number of triangles computed by triangulate().
+ int numberOfTriangles() const
+ {
+ return m_numberOfTriangles;
+ }
+
+ // Returns the computed triangle at index, 0 <= index < numberOfTriangles().
+ Triangle* getTriangle(int index)
+ {
+ ASSERT(index >= 0 && index < m_numberOfTriangles);
+ return &m_triangles[index];
+ }
+
+ // Number of vertices facing the inside of the shape, if
+ // ComputeInsideEdges was passed when triangulate() was called.
+ int numberOfInteriorVertices() const
+ {
+ return m_numberOfInteriorVertices;
+ }
+
+ // Fetches the given interior vertex, 0 <= index < numberOfInteriorVertices().
+ Vertex* getInteriorVertex(int index)
+ {
+ ASSERT(index >= 0 && index < m_numberOfInteriorVertices);
+ return m_interiorVertices[index];
+ }
+
+private:
+ void triangulateHelper(LoopBlinnConstants::FillSide sideToFill);
+
+ // Adds a triangle to the triangulation.
+ void addTriangle(Vertex* v0, Vertex* v1, Vertex* v2);
+
+ // Adds a vertex to the list of interior vertices.
+ void addInteriorVertex(Vertex* v);
+
+ // Indicates whether the edge between vertex v0 and v1 is shared
+ // between two or more triangles.
+ bool isSharedEdge(Vertex* v0, Vertex* v1);
+
+ // The vertices being triangulated.
+ Vertex m_vertices[4];
+
+ // The vertices corresponding to the edges facing the inside of the
+ // shape, in order from the start vertex to the end vertex. The more
+ // general triangulation algorithm tessellates this interior region.
+ Vertex* m_interiorVertices[4];
+ // The number of interior vertices that are valid for the current
+ // triangulation.
+ int m_numberOfInteriorVertices;
+
+ // There can be at most three triangles computed by this local
+ // algorithm, which occurs when one of the vertices is contained in
+ // the triangle spanned by the other three. Most of the time the
+ // algorithm computes two triangles.
+ Triangle m_triangles[3];
+ int m_numberOfTriangles;
+};
+
+} // namespace WebCore
+
+#endif // LoopBlinnLocalTriangulator_h
diff --git a/WebCore/platform/graphics/gpu/Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp
index 95436ba..6023fe9 100644
--- a/WebCore/platform/graphics/gpu/Texture.cpp
+++ b/WebCore/platform/graphics/gpu/Texture.cpp
@@ -129,7 +129,7 @@ static uint32_t* copySubRect(uint32_t* src, int srcX, int srcY, uint32_t* dst, i
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width ; ++x) {
uint32_t pixel = srcOffset[x + y * srcStride];
- *dstPixel = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
+ *dstPixel = (pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
dstPixel++;
}
}
diff --git a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp
index 63555bf..5a94fd4 100644
--- a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.cpp
@@ -18,7 +18,7 @@
#include "config.h"
#include "DataSourceGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <gio/gio.h>
#include <glib.h>
@@ -243,4 +243,4 @@ static void webkit_data_src_uri_handler_init(gpointer g_iface, gpointer iface_da
iface->set_uri = webkit_data_src_uri_set_uri;
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h
index 453685a..d462ccc4 100644
--- a/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/DataSourceGStreamer.h
@@ -19,7 +19,7 @@
#ifndef DataSourceGStreamer_h
#define DataSourceGStreamer_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <glib-object.h>
#include <gst/base/gstbasesrc.h>
@@ -53,5 +53,5 @@ GType webkit_data_src_get_type(void);
G_END_DECLS
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
index 6333437..06eec14 100644
--- a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "GOwnPtrGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <gst/gstelement.h>
namespace WTF {
@@ -32,4 +32,4 @@ template <> void freeOwnedGPtr<GstElement>(GstElement* ptr)
}
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h
index 84a3e30..672a23d 100644
--- a/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/GOwnPtrGStreamer.h
@@ -19,7 +19,7 @@
#ifndef GOwnPtrGStreamer_h
#define GOwnPtrGStreamer_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "GOwnPtr.h"
@@ -31,5 +31,5 @@ template<> void freeOwnedGPtr<GstElement>(GstElement* ptr);
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
index efccff0..539d92a 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
@@ -19,7 +19,7 @@
#include "config.h"
#include "GStreamerGWorld.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "GOwnPtrGStreamer.h"
#include <gst/gst.h>
@@ -203,4 +203,4 @@ void GStreamerGWorld::setWindowOverlay(GstMessage* message)
}
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
index 282f13c..f519911 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h
@@ -20,7 +20,7 @@
#ifndef GStreamerGWorld_h
#define GStreamerGWorld_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "PlatformVideoWindow.h"
#include "RefCounted.h"
@@ -62,5 +62,5 @@ private:
};
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
index 4a4ff2b..cf2b9d6 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
@@ -20,7 +20,7 @@
#ifndef ImageGStreamer_h
#define ImageGStreamer_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "BitmapImage.h"
#include <gst/gst.h>
@@ -59,5 +59,5 @@ class ImageGStreamer : public RefCounted<ImageGStreamer> {
};
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm b/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm
index 076df4a..c73adc0 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamerCG.mm
@@ -19,7 +19,7 @@
#include "config.h"
#include "ImageGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
using namespace WebCore;
@@ -57,4 +57,4 @@ ImageGStreamer::~ImageGStreamer()
m_image = 0;
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp b/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
index 2fed892..6a9d068 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
@@ -20,7 +20,7 @@
#include "config.h"
#include "ImageGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "GOwnPtr.h"
@@ -65,4 +65,4 @@ ImageGStreamer::~ImageGStreamer()
m_image = 0;
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index 0071d67..da9255b 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -24,7 +24,7 @@
#include "config.h"
#include "MediaPlayerPrivateGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "ColorSpace.h"
#include "DataSourceGStreamer.h"
@@ -1459,4 +1459,4 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin()
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
index 6d1392d..800ca6d 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
@@ -22,7 +22,7 @@
#ifndef MediaPlayerPrivateGStreamer_h
#define MediaPlayerPrivateGStreamer_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <wtf/Forward.h>
#include "MediaPlayerPrivate.h"
@@ -179,5 +179,5 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface {
};
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
index 3c4904b..f3df207 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
@@ -19,7 +19,7 @@
#ifndef PlatformVideoWindow_h
#define PlatformVideoWindow_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "Widget.h"
#include <wtf/PassRefPtr.h>
@@ -44,5 +44,5 @@ class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> {
};
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
index 68ab7ac..c55b9cc 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
@@ -19,7 +19,7 @@
#include "config.h"
#include "PlatformVideoWindow.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "NotImplemented.h"
@@ -35,4 +35,4 @@ PlatformVideoWindow::~PlatformVideoWindow()
notImplemented();
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
index 88b6552..77343ae 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
@@ -19,7 +19,7 @@
#include "config.h"
#include "PlatformVideoWindow.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <gtk/gtk.h>
@@ -61,4 +61,4 @@ PlatformVideoWindow::~PlatformVideoWindow()
m_videoWindowId = 0;
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
index 00fef4b..4319f6c 100644
--- a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp
@@ -28,7 +28,7 @@
#include "config.h"
#include "VideoSinkGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <glib.h>
#include <gst/gst.h>
@@ -371,4 +371,4 @@ webkit_video_sink_new(void)
return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0);
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
index 767e83f..6cd86c2 100644
--- a/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h
@@ -20,7 +20,7 @@
#ifndef VideoSinkGStreamer_h
#define VideoSinkGStreamer_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include <glib-object.h>
#include <gst/video/gstvideosink.h>
@@ -77,5 +77,5 @@ GstElement *webkit_video_sink_new(void);
G_END_DECLS
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
index 4e57193..635feff 100644
--- a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp
@@ -18,7 +18,7 @@
#include "config.h"
#include "WebKitWebSourceGStreamer.h"
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "Document.h"
#include "GOwnPtr.h"
@@ -795,5 +795,5 @@ void StreamingClient::cannotShowURL(ResourceHandle*)
GST_ELEMENT_ERROR(m_src, RESOURCE, OPEN_READ, ("Can't show \"%s\"", m_src->priv->uri), (0));
}
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
diff --git a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
index 1594062..bdb0833 100644
--- a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.h
@@ -18,7 +18,7 @@
#ifndef WebKitWebSourceGStreamer_h
#define WebKitWebSourceGStreamer_h
-#if ENABLE(VIDEO)
+#if USE(GSTREAMER)
#include "Frame.h"
#include <gst/gst.h>
@@ -50,5 +50,5 @@ void webKitWebSrcSetFrame(WebKitWebSrc* src, WebCore::Frame* frame);
G_END_DECLS
-#endif // ENABLE(VIDEO)
+#endif // USE(GSTREAMER)
#endif
diff --git a/WebCore/platform/graphics/gtk/CairoUtilities.cpp b/WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp
index 81e00f0..d768ce2 100644
--- a/WebCore/platform/graphics/gtk/CairoUtilities.cpp
+++ b/WebCore/platform/graphics/gtk/GdkCairoUtilities.cpp
@@ -24,7 +24,7 @@
*/
#include "config.h"
-#include "CairoUtilities.h"
+#include "GdkCairoUtilities.h"
#include <cairo.h>
#include <gtk/gtk.h>
diff --git a/WebCore/platform/graphics/gtk/CairoUtilities.h b/WebCore/platform/graphics/gtk/GdkCairoUtilities.h
index 594abc0..ff5b3ed 100644
--- a/WebCore/platform/graphics/gtk/CairoUtilities.h
+++ b/WebCore/platform/graphics/gtk/GdkCairoUtilities.h
@@ -23,9 +23,9 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef CairoUtilities_h
-#define CairoUtilities_h
+#ifndef GdkCairoUtilities_h
+#define GdkCairoUtilities_h
GdkPixbuf* cairoImageSurfaceToGdkPixbuf(cairo_surface_t* surface);
-#endif // CairoUtilities_h
+#endif // GdkCairoUtilities_h
diff --git a/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp b/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
index 821cc12..edb26f0 100644
--- a/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
+++ b/WebCore/platform/graphics/gtk/ImageBufferGtk.cpp
@@ -21,7 +21,7 @@
#include "ImageBuffer.h"
#include "Base64.h"
-#include "CairoUtilities.h"
+#include "GdkCairoUtilities.h"
#include "GOwnPtr.h"
#include "GRefPtrGtk.h"
#include "MIMETypeRegistry.h"
diff --git a/WebCore/platform/graphics/gtk/ImageGtk.cpp b/WebCore/platform/graphics/gtk/ImageGtk.cpp
index 5272243..623ace6 100644
--- a/WebCore/platform/graphics/gtk/ImageGtk.cpp
+++ b/WebCore/platform/graphics/gtk/ImageGtk.cpp
@@ -26,7 +26,7 @@
#include "config.h"
#include "BitmapImage.h"
-#include "CairoUtilities.h"
+#include "GdkCairoUtilities.h"
#include "GOwnPtrGtk.h"
#include "SharedBuffer.h"
#include <wtf/text/CString.h>
diff --git a/WebCore/platform/graphics/mac/ComplexTextController.cpp b/WebCore/platform/graphics/mac/ComplexTextController.cpp
index da381f2..a2733f8 100644
--- a/WebCore/platform/graphics/mac/ComplexTextController.cpp
+++ b/WebCore/platform/graphics/mac/ComplexTextController.cpp
@@ -185,25 +185,14 @@ void ComplexTextController::collectComplexTextRuns()
// We break up glyph run generation for the string by FontData and (if needed) the use of small caps.
const UChar* cp = m_run.characters();
- bool hasTrailingSoftHyphen = m_run[m_end - 1] == softHyphen;
- if (m_font.isSmallCaps() || hasTrailingSoftHyphen)
+ if (m_font.isSmallCaps())
m_smallCapsBuffer.resize(m_end);
unsigned indexOfFontTransition = m_run.rtl() ? m_end - 1 : 0;
const UChar* curr = m_run.rtl() ? cp + m_end - 1 : cp;
const UChar* end = m_run.rtl() ? cp - 1 : cp + m_end;
- // FIXME: Using HYPHEN-MINUS rather than HYPHEN because Times has a HYPHEN-MINUS glyph that looks like its
- // SOFT-HYPHEN glyph, and has no HYPHEN glyph.
- static const UChar hyphen = '-';
-
- if (hasTrailingSoftHyphen && m_run.rtl()) {
- collectComplexTextRunsForCharacters(&hyphen, 1, m_end - 1, m_font.glyphDataForCharacter(hyphen, false).fontData);
- indexOfFontTransition--;
- curr--;
- }
-
GlyphData glyphData;
GlyphData nextGlyphData;
@@ -267,14 +256,11 @@ void ComplexTextController::collectComplexTextRuns()
}
}
- int itemLength = m_run.rtl() ? indexOfFontTransition + 1 : m_end - indexOfFontTransition - (hasTrailingSoftHyphen ? 1 : 0);
+ int itemLength = m_run.rtl() ? indexOfFontTransition + 1 : m_end - indexOfFontTransition;
if (itemLength) {
int itemStart = m_run.rtl() ? 0 : indexOfFontTransition;
collectComplexTextRunsForCharacters((nextIsSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, nextGlyphData.glyph ? nextGlyphData.fontData : 0);
}
-
- if (hasTrailingSoftHyphen && m_run.ltr())
- collectComplexTextRunsForCharacters(&hyphen, 1, m_end - 1, m_font.glyphDataForCharacter(hyphen, false).fontData);
}
#if USE(CORE_TEXT) && USE(ATSUI)
@@ -382,9 +368,9 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer)
unsigned glyphEndOffset;
if (complexTextRun.isMonotonic()) {
if (ltr)
- glyphEndOffset = max<unsigned>(glyphStartOffset, g + 1 < glyphCount ? complexTextRun.indexAt(g + 1) : complexTextRun.stringLength());
+ glyphEndOffset = max<unsigned>(glyphStartOffset, g + 1 < glyphCount ? static_cast<unsigned>(complexTextRun.indexAt(g + 1)) : complexTextRun.stringLength());
else
- glyphEndOffset = max<unsigned>(glyphStartOffset, g > 0 ? complexTextRun.indexAt(g - 1) : complexTextRun.stringLength());
+ glyphEndOffset = max<unsigned>(glyphStartOffset, g > 0 ? static_cast<unsigned>(complexTextRun.indexAt(g - 1)) : complexTextRun.stringLength());
} else
glyphEndOffset = complexTextRun.endOffsetAt(g);
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
index 6ff3ff0..17a67ac 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -96,11 +96,10 @@ public:
virtual void suspendAnimations(double time);
virtual void resumeAnimations();
- virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& keyframesName, double timeOffset);
- virtual void removeAnimationsForProperty(AnimatedPropertyID);
- virtual void removeAnimationsForKeyframes(const String& keyframesName);
- virtual void pauseAnimation(const String& keyframesName, double timeOffset);
-
+ virtual bool addAnimation(const KeyframeValueList&, const IntSize& boxSize, const Animation*, const String& animationName, double timeOffset);
+ virtual void pauseAnimation(const String& animationName, double timeOffset);
+ virtual void removeAnimation(const String& animationName);
+
virtual void setContentsToImage(Image*);
virtual void setContentsToMedia(PlatformLayer*);
virtual void setContentsToCanvas(PlatformLayer*);
@@ -119,6 +118,9 @@ public:
virtual void syncCompositingState();
virtual void syncCompositingStateForThisLayerOnly();
+ // Should only be called by animationDidStart: callback
+ void animationDidStart(CAAnimation*);
+
protected:
virtual void setOpacityInternal(float);
@@ -128,17 +130,17 @@ private:
CALayer* primaryLayer() const { return m_structuralLayer.get() ? m_structuralLayer.get() : m_layer.get(); }
CALayer* hostLayerForSublayers() const;
CALayer* layerForSuperlayer() const;
- CALayer* animatedLayer(AnimatedPropertyID property) const;
+ CALayer* animatedLayer(AnimatedPropertyID) const;
typedef String CloneID; // Identifier for a given clone, based on original/replica branching down the tree.
static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0U] & 1; }
typedef HashMap<CloneID, RetainPtr<CALayer> > LayerMap;
LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); }
- LayerMap* animatedLayerClones(AnimatedPropertyID property) const;
+ LayerMap* animatedLayerClones(AnimatedPropertyID) const;
- bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset);
- bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset, const IntSize& boxSize);
+ bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset);
+ bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& animationName, double timeOffset, const IntSize& boxSize);
// Return autoreleased animation (use RetainPtr?)
CABasicAnimation* createBasicAnimation(const Animation*, AnimatedPropertyID, bool additive);
@@ -153,9 +155,9 @@ private:
bool setTransformAnimationEndpoints(const KeyframeValueList&, const Animation*, CABasicAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
bool setTransformAnimationKeyframes(const KeyframeValueList&, const Animation*, CAKeyframeAnimation*, int functionIndex, TransformOperation::OperationType, bool isMatrixAnimation, const IntSize& boxSize);
- bool animationIsRunning(const String& keyframesName) const
+ bool animationIsRunning(const String& animationName) const
{
- return m_runningKeyframeAnimations.find(keyframesName) != m_runningKeyframeAnimations.end();
+ return m_runningAnimations.find(animationName) != m_runningAnimations.end();
}
void commitLayerChangesBeforeSublayers();
@@ -271,13 +273,13 @@ private:
void ensureStructuralLayer(StructuralLayerPurpose);
StructuralLayerPurpose structuralLayerPurpose() const;
- void setAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, const String& keyframesName, int index, double timeOffset);
- bool removeAnimationFromLayer(AnimatedPropertyID, const String& keyframesName, int index);
- void pauseAnimationOnLayer(AnimatedPropertyID, const String& keyframesName, int index, double timeOffset);
+ void setCAAnimationOnLayer(CAPropertyAnimation*, AnimatedPropertyID, const String& animationName, int index, double timeOffset);
+ bool removeCAAnimationFromLayer(AnimatedPropertyID, const String& animationName, int index);
+ void pauseCAAnimationOnLayer(AnimatedPropertyID, const String& animationName, int index, double timeOffset);
enum MoveOrCopy { Move, Copy };
- void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID property, CALayer * fromLayer, CALayer * toLayer);
- static void moveOrCopyAllAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, const String& keyframesName, CALayer * fromLayer, CALayer * toLayer);
+ static void moveOrCopyLayerAnimation(MoveOrCopy, const String& animationIdentifier, CALayer *fromLayer, CALayer *toLayer);
+ void moveOrCopyAnimationsForProperty(MoveOrCopy, AnimatedPropertyID, CALayer * fromLayer, CALayer * toLayer);
enum LayerChange {
NoChange = 0,
@@ -335,29 +337,26 @@ private:
RetainPtr<CGImageRef> m_uncorrectedContentsImage;
RetainPtr<CGImageRef> m_pendingContentsImage;
- struct LayerAnimation {
- LayerAnimation(CAPropertyAnimation* caAnim, const String& keyframesName, AnimatedPropertyID property, int index, double timeOffset)
- : m_animation(caAnim)
- , m_keyframesName(keyframesName)
+ // This represents the animation of a single property. There may be multiple transform animations for
+ // a single transition or keyframe animation, so index is used to distinguish these.
+ struct LayerPropertyAnimation {
+ LayerPropertyAnimation(CAPropertyAnimation* caAnimation, const String& animationName, AnimatedPropertyID property, int index, double timeOffset)
+ : m_animation(caAnimation)
+ , m_name(animationName)
, m_property(property)
, m_index(index)
, m_timeOffset(timeOffset)
{ }
RetainPtr<CAPropertyAnimation*> m_animation;
- String m_keyframesName;
+ String m_name;
AnimatedPropertyID m_property;
int m_index;
double m_timeOffset;
};
- Vector<LayerAnimation> m_uncomittedAnimations;
-
- // Animations on the layer are identified by property + index.
- typedef int AnimatedProperty; // std containers choke on the AnimatedPropertyID enum
- typedef pair<AnimatedProperty, int> AnimationPair;
-
- HashSet<AnimatedProperty> m_transitionPropertiesToRemove;
+ // Uncommitted transitions and animations.
+ Vector<LayerPropertyAnimation> m_uncomittedAnimations;
enum Action { Remove, Pause };
struct AnimationProcessingAction {
@@ -367,15 +366,15 @@ private:
{
}
Action action;
- double timeOffset; // only used for pause
+ double timeOffset; // only used for pause
};
typedef HashMap<String, AnimationProcessingAction> AnimationsToProcessMap;
- AnimationsToProcessMap m_keyframeAnimationsToProcess;
+ AnimationsToProcessMap m_animationsToProcess;
+
+ // Map of animation names to their associated lists of property animations, so we can remove/pause them.
+ typedef HashMap<String, Vector<LayerPropertyAnimation> > AnimationsMap;
+ AnimationsMap m_runningAnimations;
- // Map of keyframe names to their associated lists of animations for running animations, so we can remove/pause them.
- typedef HashMap<String, Vector<AnimationPair> > KeyframeAnimationsMap;
- KeyframeAnimationsMap m_runningKeyframeAnimations;
-
Vector<FloatRect> m_dirtyRects;
LayerChangeFlags m_uncommittedChanges;
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index 395a691..d4cd851 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -55,6 +55,8 @@ using namespace std;
namespace WebCore {
+static NSString * const WebKitAnimationBeginTimeSetKey = @"WebKitAnimationBeginTimeSet";
+
// The threshold width or height above which a tiled layer will be used. This should be
// large enough to avoid tiled layers for most GraphicsLayers, but less than the OpenGL
// texture size limit on all supported hardware.
@@ -101,11 +103,8 @@ static double mediaTimeToCurrentTime(CFTimeInterval t)
- (void)animationDidStart:(CAAnimation *)animation
{
- if (!m_graphicsLayer)
- return;
-
- double startTime = WebCore::mediaTimeToCurrentTime([animation beginTime]);
- m_graphicsLayer->client()->notifyAnimationStarted(m_graphicsLayer, startTime);
+ if (m_graphicsLayer)
+ m_graphicsLayer->animationDidStart(animation);
}
- (WebCore::GraphicsLayerCA*)graphicsLayer
@@ -197,7 +196,7 @@ static NSValue* getTransformFunctionValue(const TransformOperation* transformOp,
}
#if HAVE_MODERN_QUARTZCORE
-static NSString* getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
+static NSString *getValueFunctionNameForTransformOperation(TransformOperation::OperationType transformType)
{
// Use literal strings to avoid link-time dependency on those symbols.
switch (transformType) {
@@ -247,20 +246,9 @@ static String propertyIdToString(AnimatedPropertyID property)
return "";
}
-static String animationIdentifier(AnimatedPropertyID property, const String& keyframesName, int index)
+static String animationIdentifier(const String& animationName, AnimatedPropertyID property, int index)
{
- StringBuilder builder;
-
- builder.append(propertyIdToString(property));
- builder.append("_");
-
- if (!keyframesName.isEmpty()) {
- builder.append(keyframesName);
- builder.append("_");
- }
- builder.append("_");
- builder.append(String::number(index));
- return builder.toString();
+ return animationName + String::format("_%d_%d", property, index);
}
static CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction* timingFunction)
@@ -550,39 +538,40 @@ void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t)
noteLayerPropertyChanged(ChildrenTransformChanged);
}
-void GraphicsLayerCA::moveOrCopyAllAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, const String& keyframesName, CALayer *fromLayer, CALayer *toLayer)
+void GraphicsLayerCA::moveOrCopyLayerAnimation(MoveOrCopy operation, const String& animationIdentifier, CALayer *fromLayer, CALayer *toLayer)
{
- for (int index = 0; ; ++index) {
- String animName = animationIdentifier(property, keyframesName, index);
+ NSString *animationID = animationIdentifier;
+ CAAnimation *anim = [fromLayer animationForKey:animationID];
+ if (!anim)
+ return;
- CAAnimation* anim = [fromLayer animationForKey:animName];
- if (!anim)
+ switch (operation) {
+ case Move:
+ [anim retain];
+ [fromLayer removeAnimationForKey:animationID];
+ [toLayer addAnimation:anim forKey:animationID];
+ [anim release];
break;
- switch (operation) {
- case Move:
- [anim retain];
- [fromLayer removeAnimationForKey:animName];
- [toLayer addAnimation:anim forKey:animName];
- [anim release];
- break;
-
- case Copy:
- [toLayer addAnimation:anim forKey:animName];
- break;
- }
+ case Copy:
+ [toLayer addAnimation:anim forKey:animationID];
+ break;
}
}
void GraphicsLayerCA::moveOrCopyAnimationsForProperty(MoveOrCopy operation, AnimatedPropertyID property, CALayer *fromLayer, CALayer *toLayer)
{
- // Move transitions for this property.
- moveOrCopyAllAnimationsForProperty(operation, property, "", fromLayer, toLayer);
-
// Look for running animations affecting this property.
- KeyframeAnimationsMap::const_iterator end = m_runningKeyframeAnimations.end();
- for (KeyframeAnimationsMap::const_iterator it = m_runningKeyframeAnimations.begin(); it != end; ++it)
- moveOrCopyAllAnimationsForProperty(operation, property, it->first, fromLayer, toLayer);
+ AnimationsMap::const_iterator end = m_runningAnimations.end();
+ for (AnimationsMap::const_iterator it = m_runningAnimations.begin(); it != end; ++it) {
+ const Vector<LayerPropertyAnimation>& propertyAnimations = it->second;
+ size_t numAnimations = propertyAnimations.size();
+ for (size_t i = 0; i < numAnimations; ++i) {
+ const LayerPropertyAnimation& currAnimation = propertyAnimations[i];
+ if (currAnimation.m_property == property)
+ moveOrCopyLayerAnimation(operation, animationIdentifier(currAnimation.m_name, currAnimation.m_property, currAnimation.m_index), fromLayer, toLayer);
+ }
+ }
}
void GraphicsLayerCA::setPreserves3D(bool preserves3D)
@@ -704,8 +693,10 @@ void GraphicsLayerCA::setContentsRect(const IntRect& rect)
noteLayerPropertyChanged(ContentsRectChanged);
}
-bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& keyframesName, double timeOffset)
+bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const IntSize& boxSize, const Animation* anim, const String& animationName, double timeOffset)
{
+ ASSERT(!animationName.isEmpty());
+
if (forceSoftwareAnimation() || !anim || anim->isEmptyOrZeroDuration() || valueList.size() < 2)
return false;
@@ -723,9 +714,9 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
bool createdAnimations = false;
if (valueList.property() == AnimatedPropertyWebkitTransform)
- createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, keyframesName, timeOffset, boxSize);
+ createdAnimations = createTransformAnimationsFromKeyframes(valueList, anim, animationName, timeOffset, boxSize);
else
- createdAnimations = createAnimationFromKeyframes(valueList, anim, keyframesName, timeOffset);
+ createdAnimations = createAnimationFromKeyframes(valueList, anim, animationName, timeOffset);
if (createdAnimations)
noteLayerPropertyChanged(AnimationChanged);
@@ -733,39 +724,46 @@ bool GraphicsLayerCA::addAnimation(const KeyframeValueList& valueList, const Int
return createdAnimations;
}
-void GraphicsLayerCA::removeAnimationsForProperty(AnimatedPropertyID property)
+void GraphicsLayerCA::pauseAnimation(const String& animationName, double timeOffset)
{
- if (m_transitionPropertiesToRemove.find(property) != m_transitionPropertiesToRemove.end())
+ if (!animationIsRunning(animationName))
return;
- m_transitionPropertiesToRemove.add(property);
+ AnimationsToProcessMap::iterator it = m_animationsToProcess.find(animationName);
+ if (it != m_animationsToProcess.end()) {
+ AnimationProcessingAction& processingInfo = it->second;
+ // If an animation is scheduled to be removed, don't change the remove to a pause.
+ if (processingInfo.action != Remove)
+ processingInfo.action = Pause;
+ } else
+ m_animationsToProcess.add(animationName, AnimationProcessingAction(Pause, timeOffset));
+
noteLayerPropertyChanged(AnimationChanged);
}
-void GraphicsLayerCA::removeAnimationsForKeyframes(const String& animationName)
+void GraphicsLayerCA::removeAnimation(const String& animationName)
{
if (!animationIsRunning(animationName))
return;
- m_keyframeAnimationsToProcess.add(animationName, AnimationProcessingAction(Remove));
+ m_animationsToProcess.add(animationName, AnimationProcessingAction(Remove));
noteLayerPropertyChanged(AnimationChanged);
}
-void GraphicsLayerCA::pauseAnimation(const String& keyframesName, double timeOffset)
+void GraphicsLayerCA::animationDidStart(CAAnimation* caAnimation)
{
- if (!animationIsRunning(keyframesName))
- return;
+ bool hadNonZeroBeginTime = [[caAnimation valueForKey:WebKitAnimationBeginTimeSetKey] boolValue];
- AnimationsToProcessMap::iterator it = m_keyframeAnimationsToProcess.find(keyframesName);
- if (it != m_keyframeAnimationsToProcess.end()) {
- AnimationProcessingAction& processingInfo = it->second;
- // If an animation is scheduled to be removed, don't change the remove to a pause.
- if (processingInfo.action != Remove)
- processingInfo.action = Pause;
+ double startTime;
+ if (hadNonZeroBeginTime) {
+ // We don't know what time CA used to commit the animation, so just use the current time
+ // (even though this will be slightly off).
+ startTime = WebCore::mediaTimeToCurrentTime(CACurrentMediaTime());
} else
- m_keyframeAnimationsToProcess.add(keyframesName, AnimationProcessingAction(Pause, timeOffset));
+ startTime = WebCore::mediaTimeToCurrentTime([caAnimation beginTime]);
- noteLayerPropertyChanged(AnimationChanged);
+ if (m_client)
+ m_client->notifyAnimationStarted(this, startTime);
}
void GraphicsLayerCA::setContentsToImage(Image* image)
@@ -1496,68 +1494,49 @@ CALayer *GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState)
void GraphicsLayerCA::updateLayerAnimations()
{
- if (m_transitionPropertiesToRemove.size()) {
- HashSet<int>::const_iterator end = m_transitionPropertiesToRemove.end();
- for (HashSet<AnimatedProperty>::const_iterator it = m_transitionPropertiesToRemove.begin(); it != end; ++it) {
- AnimatedPropertyID currProperty = static_cast<AnimatedPropertyID>(*it);
- // Remove all animations with this property in the key.
- for (int index = 0; ; ++index) {
- if (!removeAnimationFromLayer(currProperty, "", index))
- break;
- }
- }
-
- m_transitionPropertiesToRemove.clear();
- }
-
- if (m_keyframeAnimationsToProcess.size()) {
- AnimationsToProcessMap::const_iterator end = m_keyframeAnimationsToProcess.end();
- for (AnimationsToProcessMap::const_iterator it = m_keyframeAnimationsToProcess.begin(); it != end; ++it) {
- const String& currKeyframeName = it->first;
- KeyframeAnimationsMap::iterator animationIt = m_runningKeyframeAnimations.find(currKeyframeName);
- if (animationIt == m_runningKeyframeAnimations.end())
+ if (m_animationsToProcess.size()) {
+ AnimationsToProcessMap::const_iterator end = m_animationsToProcess.end();
+ for (AnimationsToProcessMap::const_iterator it = m_animationsToProcess.begin(); it != end; ++it) {
+ const String& currAnimationName = it->first;
+ AnimationsMap::iterator animationIt = m_runningAnimations.find(currAnimationName);
+ if (animationIt == m_runningAnimations.end())
continue;
const AnimationProcessingAction& processingInfo = it->second;
- const Vector<AnimationPair>& animations = animationIt->second;
+ const Vector<LayerPropertyAnimation>& animations = animationIt->second;
for (size_t i = 0; i < animations.size(); ++i) {
- const AnimationPair& currPair = animations[i];
+ const LayerPropertyAnimation& currAnimation = animations[i];
switch (processingInfo.action) {
case Remove:
- removeAnimationFromLayer(static_cast<AnimatedPropertyID>(currPair.first), currKeyframeName, currPair.second);
+ removeCAAnimationFromLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index);
break;
case Pause:
- pauseAnimationOnLayer(static_cast<AnimatedPropertyID>(currPair.first), currKeyframeName, currPair.second, processingInfo.timeOffset);
+ pauseCAAnimationOnLayer(currAnimation.m_property, currAnimationName, currAnimation.m_index, processingInfo.timeOffset);
break;
}
}
if (processingInfo.action == Remove)
- m_runningKeyframeAnimations.remove(currKeyframeName);
+ m_runningAnimations.remove(currAnimationName);
}
- m_keyframeAnimationsToProcess.clear();
+ m_animationsToProcess.clear();
}
size_t numAnimations;
if ((numAnimations = m_uncomittedAnimations.size())) {
for (size_t i = 0; i < numAnimations; ++i) {
- const LayerAnimation& pendingAnimation = m_uncomittedAnimations[i];
- setAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_keyframesName, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
+ const LayerPropertyAnimation& pendingAnimation = m_uncomittedAnimations[i];
+ setCAAnimationOnLayer(pendingAnimation.m_animation.get(), pendingAnimation.m_property, pendingAnimation.m_name, pendingAnimation.m_index, pendingAnimation.m_timeOffset);
- if (!pendingAnimation.m_keyframesName.isEmpty()) {
- // If this is a keyframe anim, we have to remember the association of keyframes name to property/index pairs,
- // so we can remove the animations later if needed.
- // For transitions, we can just generate animation names with property and index.
- KeyframeAnimationsMap::iterator it = m_runningKeyframeAnimations.find(pendingAnimation.m_keyframesName);
- if (it == m_runningKeyframeAnimations.end()) {
- Vector<AnimationPair> firstPair;
- firstPair.append(AnimationPair(pendingAnimation.m_property, pendingAnimation.m_index));
- m_runningKeyframeAnimations.add(pendingAnimation.m_keyframesName, firstPair);
- } else {
- Vector<AnimationPair>& animPairs = it->second;
- animPairs.append(AnimationPair(pendingAnimation.m_property, pendingAnimation.m_index));
- }
+ AnimationsMap::iterator it = m_runningAnimations.find(pendingAnimation.m_name);
+ if (it == m_runningAnimations.end()) {
+ Vector<LayerPropertyAnimation> animations;
+ animations.append(pendingAnimation);
+ m_runningAnimations.add(pendingAnimation.m_name, animations);
+ } else {
+ Vector<LayerPropertyAnimation>& animations = it->second;
+ animations.append(pendingAnimation);
}
}
@@ -1565,16 +1544,19 @@ void GraphicsLayerCA::updateLayerAnimations()
}
}
-void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, const String& keyframesName, int index, double timeOffset)
+void GraphicsLayerCA::setCAAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
{
PlatformLayer* layer = animatedLayer(property);
- [caAnim setTimeOffset:timeOffset];
-
- String animationName = animationIdentifier(property, keyframesName, index);
-
- [layer removeAnimationForKey:animationName];
- [layer addAnimation:caAnim forKey:animationName];
+ if (timeOffset) {
+ [caAnim setBeginTime:CACurrentMediaTime() - timeOffset];
+ [caAnim setValue:[NSNumber numberWithBool:YES] forKey:WebKitAnimationBeginTimeSetKey];
+ }
+
+ NSString *animationID = animationIdentifier(animationName, property, index);
+
+ [layer removeAnimationForKey:animationID];
+ [layer addAnimation:caAnim forKey:animationID];
if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
LayerMap::const_iterator end = layerCloneMap->end();
@@ -1583,8 +1565,8 @@ void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedP
if (m_replicaLayer && isReplicatedRootClone(it->first))
continue;
CALayer *currLayer = it->second.get();
- [currLayer removeAnimationForKey:animationName];
- [currLayer addAnimation:caAnim forKey:animationName];
+ [currLayer removeAnimationForKey:animationID];
+ [currLayer addAnimation:caAnim forKey:animationID];
}
}
}
@@ -1604,16 +1586,16 @@ static void bug7311367Workaround(CALayer* transformLayer, const TransformationMa
[transformLayer setTransform:caTransform];
}
-bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, const String& keyframesName, int index)
+bool GraphicsLayerCA::removeCAAnimationFromLayer(AnimatedPropertyID property, const String& animationName, int index)
{
PlatformLayer* layer = animatedLayer(property);
- String animationName = animationIdentifier(property, keyframesName, index);
+ NSString *animationID = animationIdentifier(animationName, property, index);
- if (![layer animationForKey:animationName])
+ if (![layer animationForKey:animationID])
return false;
- [layer removeAnimationForKey:animationName];
+ [layer removeAnimationForKey:animationID];
bug7311367Workaround(m_structuralLayer.get(), m_transform);
if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
@@ -1624,7 +1606,7 @@ bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, cons
continue;
CALayer *currLayer = it->second.get();
- [currLayer removeAnimationForKey:animationName];
+ [currLayer removeAnimationForKey:animationID];
}
}
return true;
@@ -1644,15 +1626,18 @@ static void copyAnimationProperties(CAPropertyAnimation* from, CAPropertyAnimati
#if HAVE_MODERN_QUARTZCORE
[to setValueFunction:[from valueFunction]];
#endif
+
+ if (id object = [from valueForKey:WebKitAnimationBeginTimeSetKey])
+ [to setValue:object forKey:WebKitAnimationBeginTimeSetKey];
}
-void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const String& keyframesName, int index, double timeOffset)
+void GraphicsLayerCA::pauseCAAnimationOnLayer(AnimatedPropertyID property, const String& animationName, int index, double timeOffset)
{
PlatformLayer* layer = animatedLayer(property);
- String animationName = animationIdentifier(property, keyframesName, index);
+ NSString *animationID = animationIdentifier(animationName, property, index);
- CAAnimation* caAnim = [layer animationForKey:animationName];
+ CAAnimation *caAnim = [layer animationForKey:animationID];
if (!caAnim)
return;
@@ -1679,7 +1664,7 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const S
[pausedAnim setSpeed:0];
[pausedAnim setTimeOffset:timeOffset];
- [layer addAnimation:pausedAnim forKey:animationName]; // This will replace the running animation.
+ [layer addAnimation:pausedAnim forKey:animationID]; // This will replace the running animation.
// Pause the animations on the clones too.
if (LayerMap* layerCloneMap = animatedLayerClones(property)) {
@@ -1689,7 +1674,7 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, const S
if (m_replicaLayer && isReplicatedRootClone(it->first))
continue;
CALayer *currLayer = it->second.get();
- [currLayer addAnimation:pausedAnim forKey:animationName];
+ [currLayer addAnimation:pausedAnim forKey:animationID];
}
}
}
@@ -1726,7 +1711,7 @@ void GraphicsLayerCA::updateContentsNeedsDisplay()
[m_contentsLayer.get() setNeedsDisplay];
}
-bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset)
+bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset)
{
ASSERT(valueList.property() != AnimatedPropertyWebkitTransform);
@@ -1752,14 +1737,14 @@ bool GraphicsLayerCA::createAnimationFromKeyframes(const KeyframeValueList& valu
if (!valuesOK)
return false;
- m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
+ m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
END_BLOCK_OBJC_EXCEPTIONS;
return true;
}
-bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& keyframesName, double timeOffset, const IntSize& boxSize)
+bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValueList& valueList, const Animation* animation, const String& animationName, double timeOffset, const IntSize& boxSize)
{
ASSERT(valueList.property() == AnimatedPropertyWebkitTransform);
@@ -1810,7 +1795,7 @@ bool GraphicsLayerCA::createTransformAnimationsFromKeyframes(const KeyframeValue
if (!validMatrices)
break;
- m_uncomittedAnimations.append(LayerAnimation(caAnimation, keyframesName, valueList.property(), animationIndex, timeOffset));
+ m_uncomittedAnimations.append(LayerPropertyAnimation(caAnimation, animationName, valueList.property(), animationIndex, timeOffset));
}
END_BLOCK_OBJC_EXCEPTIONS;
@@ -1844,7 +1829,7 @@ void GraphicsLayerCA::setupAnimation(CAPropertyAnimation* propertyAnim, const An
else if (anim->direction() == Animation::AnimationDirectionAlternate)
repeatCount /= 2;
- NSString* fillMode = 0;
+ NSString *fillMode = 0;
switch (anim->fillMode()) {
case AnimationFillModeNone:
fillMode = kCAFillModeForwards; // Use "forwards" rather than "removed" because the style system will remove the animation when it is finished. This avoids a flash.
@@ -1983,7 +1968,7 @@ bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& va
[basicAnim setToValue:toValue];
#if HAVE_MODERN_QUARTZCORE
- if (NSString* valueFunctionName = getValueFunctionNameForTransformOperation(transformOp))
+ if (NSString *valueFunctionName = getValueFunctionNameForTransformOperation(transformOp))
[basicAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
#endif
@@ -2028,7 +2013,7 @@ bool GraphicsLayerCA::setTransformAnimationKeyframes(const KeyframeValueList& va
[keyframeAnim setTimingFunctions:timingFunctions.get()];
#if HAVE_MODERN_QUARTZCORE
- if (NSString* valueFunctionName = getValueFunctionNameForTransformOperation(transformOpType))
+ if (NSString *valueFunctionName = getValueFunctionNameForTransformOperation(transformOpType))
[keyframeAnim setValueFunction:[CAValueFunction functionWithName:valueFunctionName]];
#endif
return true;
@@ -2045,7 +2030,7 @@ void GraphicsLayerCA::suspendAnimations(double time)
LayerMap::const_iterator end = layerCloneMap->end();
for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) {
CALayer *currLayer = it->second.get();
- [currLayer setSpeed:0 ];
+ [currLayer setSpeed:0];
[currLayer setTimeOffset:t];
}
}
diff --git a/WebCore/platform/graphics/mac/ImageMac.mm b/WebCore/platform/graphics/mac/ImageMac.mm
index 96b93be..6ad3080 100644
--- a/WebCore/platform/graphics/mac/ImageMac.mm
+++ b/WebCore/platform/graphics/mac/ImageMac.mm
@@ -27,7 +27,6 @@
#import "BitmapImage.h"
#import "FloatRect.h"
-#import "FoundationExtras.h"
#import "GraphicsContext.h"
#import "PlatformString.h"
#import "SharedBuffer.h"
diff --git a/WebCore/platform/graphics/qt/ContextShadowQt.cpp b/WebCore/platform/graphics/qt/ContextShadowQt.cpp
new file mode 100644
index 0000000..342e027
--- /dev/null
+++ b/WebCore/platform/graphics/qt/ContextShadowQt.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2010 Sencha, Inc.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ContextShadow.h"
+
+#include <QPainter>
+#include <QTimerEvent>
+
+namespace WebCore {
+
+// ContextShadow needs a scratch image as the buffer for the blur filter.
+// Instead of creating and destroying the buffer for every operation,
+// we create a buffer which will be automatically purged via a timer.
+
+class ShadowBuffer: public QObject {
+public:
+ ShadowBuffer(QObject* parent = 0);
+
+ QImage* scratchImage(const QSize& size);
+
+ void schedulePurge();
+
+protected:
+ void timerEvent(QTimerEvent* event);
+
+private:
+ QImage image;
+ int timerId;
+};
+
+ShadowBuffer::ShadowBuffer(QObject* parent)
+ : QObject(parent)
+ , timerId(0)
+{
+}
+
+QImage* ShadowBuffer::scratchImage(const QSize& size)
+{
+ int width = size.width();
+ int height = size.height();
+
+ // We do not need to recreate the buffer if the buffer is reasonably
+ // larger than the requested size. However, if the requested size is
+ // much smaller than our buffer, reduce our buffer so that we will not
+ // keep too many allocated pixels for too long.
+ if (!image.isNull() && (image.width() > width) && (image.height() > height))
+ if (((2 * width) > image.width()) && ((2 * height) > image.height())) {
+ image.fill(Qt::transparent);
+ return &image;
+ }
+
+ // Round to the nearest 32 pixels so we do not grow the buffer everytime
+ // there is larger request by 1 pixel.
+ width = (1 + (width >> 5)) << 5;
+ height = (1 + (height >> 5)) << 5;
+
+ image = QImage(width, height, QImage::Format_ARGB32_Premultiplied);
+ image.fill(Qt::transparent);
+ return &image;
+}
+
+void ShadowBuffer::schedulePurge()
+{
+ static const double BufferPurgeDelay = 2; // seconds
+ killTimer(timerId);
+ timerId = startTimer(BufferPurgeDelay * 1000);
+}
+
+void ShadowBuffer::timerEvent(QTimerEvent* event)
+{
+ if (event->timerId() == timerId) {
+ killTimer(timerId);
+ image = QImage();
+ }
+ QObject::timerEvent(event);
+}
+
+Q_GLOBAL_STATIC(ShadowBuffer, scratchShadowBuffer)
+
+PlatformContext ContextShadow::beginShadowLayer(PlatformContext p, const FloatRect& layerArea)
+{
+ QRect clipRect;
+ if (p->hasClipping())
+#if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0)
+ clipRect = p->clipBoundingRect().toAlignedRect();
+#else
+ clipRect = p->clipRegion().boundingRect();
+#endif
+ else
+ clipRect = p->transform().inverted().mapRect(p->window());
+
+ calculateLayerBoundingRect(layerArea, IntRect(clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()));
+
+ // Don't paint if we are totally outside the clip region.
+ if (m_layerRect.isEmpty())
+ return 0;
+
+ ShadowBuffer* shadowBuffer = scratchShadowBuffer();
+ QImage* shadowImage = shadowBuffer->scratchImage(m_layerRect.size());
+ m_layerImage = QImage(*shadowImage);
+
+ m_layerContext = new QPainter;
+ m_layerContext->begin(&m_layerImage);
+ m_layerContext->setFont(p->font());
+ m_layerContext->translate(m_offset.width(), m_offset.height());
+
+ // The origin is now the top left corner of the scratch image.
+ m_layerContext->translate(-m_layerRect.x(), -m_layerRect.y());
+
+ return m_layerContext;
+}
+
+void ContextShadow::endShadowLayer(PlatformContext p)
+{
+ m_layerContext->end();
+ delete m_layerContext;
+ m_layerContext = 0;
+
+ if (m_type == BlurShadow) {
+ blurLayerImage(m_layerImage.bits(), IntSize(m_layerImage.width(), m_layerImage.height()),
+ m_layerImage.bytesPerLine());
+
+ // "Colorize" with the right shadow color.
+ QPainter p(&m_layerImage);
+ p.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ p.fillRect(m_layerImage.rect(), m_color.rgb());
+ p.end();
+ }
+
+ p->drawImage(m_layerRect.topLeft(), m_layerImage);
+ scratchShadowBuffer()->schedulePurge();
+}
+
+}
diff --git a/WebCore/platform/graphics/qt/FontQt.cpp b/WebCore/platform/graphics/qt/FontQt.cpp
index 2b246de..e7566eb 100644
--- a/WebCore/platform/graphics/qt/FontQt.cpp
+++ b/WebCore/platform/graphics/qt/FontQt.cpp
@@ -125,37 +125,38 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
ContextShadow* ctxShadow = ctx->contextShadow();
- if (ctxShadow->type != ContextShadow::NoShadow) {
+ if (ctxShadow->m_type != ContextShadow::NoShadow) {
qreal dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
- if (ctxShadow->offset.x() > 0)
- dx2 = ctxShadow->offset.x();
+ if (ctxShadow->offset().x() > 0)
+ dx2 = ctxShadow->offset().x();
else
- dx1 = -ctxShadow->offset.x();
- if (ctxShadow->offset.y() > 0)
- dy2 = ctxShadow->offset.y();
+ dx1 = -ctxShadow->offset().x();
+ if (ctxShadow->offset().y() > 0)
+ dy2 = ctxShadow->offset().y();
else
- dy1 = -ctxShadow->offset.y();
+ dy1 = -ctxShadow->offset().y();
// expand the clip rect to include the text shadow as well
clip.adjust(dx1, dx2, dy1, dy2);
- clip.adjust(-ctxShadow->blurRadius, -ctxShadow->blurRadius, ctxShadow->blurRadius, ctxShadow->blurRadius);
+ clip.adjust(-ctxShadow->m_blurRadius, -ctxShadow->m_blurRadius, ctxShadow->m_blurRadius, ctxShadow->m_blurRadius);
}
p->save();
p->setClipRect(clip.toRect(), Qt::IntersectClip);
pt.setY(pt.y() - ascent);
- if (ctxShadow->type != ContextShadow::NoShadow) {
+ if (ctxShadow->m_type != ContextShadow::NoShadow) {
ContextShadow* ctxShadow = ctx->contextShadow();
- if (ctxShadow->type != ContextShadow::BlurShadow) {
+ if (ctxShadow->m_type != ContextShadow::BlurShadow) {
p->save();
- p->setPen(ctxShadow->color);
- p->translate(ctxShadow->offset);
+ p->setPen(ctxShadow->m_color);
+ p->translate(ctxShadow->offset());
line.draw(p, pt);
p->restore();
} else {
QPainter* shadowPainter = ctxShadow->beginShadowLayer(p, boundingRect);
if (shadowPainter) {
// Since it will be blurred anyway, we don't care about render hints.
- shadowPainter->setPen(ctxShadow->color);
+ shadowPainter->setFont(p->font());
+ shadowPainter->setPen(ctxShadow->m_color);
line.draw(shadowPainter, pt);
ctxShadow->endShadowLayer(p);
}
@@ -181,12 +182,12 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
if (!isComplexText && !(ctx->textDrawingMode() & cTextStroke))
flags |= Qt::TextBypassShaping;
#endif
- if (ctx->contextShadow()->type != ContextShadow::NoShadow) {
+ if (ctx->contextShadow()->m_type != ContextShadow::NoShadow) {
ContextShadow* ctxShadow = ctx->contextShadow();
- if (ctxShadow->type != ContextShadow::BlurShadow) {
+ if (ctxShadow->m_type != ContextShadow::BlurShadow) {
p->save();
- p->setPen(ctxShadow->color);
- p->translate(ctxShadow->offset);
+ p->setPen(ctxShadow->m_color);
+ p->translate(ctxShadow->offset());
p->drawText(pt, string, flags, run.padding());
p->restore();
} else {
@@ -196,7 +197,7 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
if (shadowPainter) {
// Since it will be blurred anyway, we don't care about render hints.
shadowPainter->setFont(p->font());
- shadowPainter->setPen(ctxShadow->color);
+ shadowPainter->setPen(ctxShadow->m_color);
shadowPainter->drawText(pt, string, flags, run.padding());
ctxShadow->endShadowLayer(p);
}
@@ -205,12 +206,13 @@ static void drawTextCommon(GraphicsContext* ctx, const TextRun& run, const Float
if (ctx->textDrawingMode() & cTextStroke) {
QPainterPath path;
path.addText(pt, font, string);
- p->setPen(textStrokePen);
- p->strokePath(path, p->pen());
+ p->strokePath(path, textStrokePen);
}
if (ctx->textDrawingMode() & cTextFill) {
+ QPen previousPen = p->pen();
p->setPen(textFillPen);
p->drawText(pt, string, flags, run.padding());
+ p->setPen(previousPen);
}
}
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 5a29ad4..7e4af40 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -201,7 +201,7 @@ public:
bool hasShadow() const
{
- return shadow.type != ContextShadow::NoShadow;
+ return shadow.m_type != ContextShadow::NoShadow;
}
QRectF clipBoundingRect() const
@@ -440,9 +440,9 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
if (m_data->hasShadow()) {
p->save();
- p->translate(m_data->shadow.offset);
+ p->translate(m_data->shadow.offset());
QPen pen(p->pen());
- pen.setColor(m_data->shadow.color);
+ pen.setColor(m_data->shadow.m_color);
p->setPen(pen);
p->drawArc(rect, startAngle, angleSpan);
p->restore();
@@ -470,12 +470,12 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
p->setRenderHint(QPainter::Antialiasing, shouldAntialias);
if (m_data->hasShadow()) {
p->save();
- p->translate(m_data->shadow.offset);
+ p->translate(m_data->shadow.offset());
if (p->brush().style() != Qt::NoBrush)
- p->setBrush(QBrush(m_data->shadow.color));
+ p->setBrush(QBrush(m_data->shadow.m_color));
QPen pen(p->pen());
if (pen.style() != Qt::NoPen) {
- pen.setColor(m_data->shadow.color);
+ pen.setColor(m_data->shadow.m_color);
p->setPen(pen);
}
p->drawConvexPolygon(polygon);
@@ -519,9 +519,9 @@ void GraphicsContext::fillPath()
path.setFillRule(toQtFillRule(fillRule()));
if (m_data->hasShadow()) {
- p->translate(m_data->shadow.offset);
- p->fillPath(path, m_data->shadow.color);
- p->translate(-m_data->shadow.offset);
+ p->translate(m_data->shadow.offset());
+ p->fillPath(path, QColor(m_data->shadow.m_color));
+ p->translate(-m_data->shadow.offset());
}
if (m_common->state.fillPattern) {
AffineTransform affine;
@@ -547,11 +547,11 @@ void GraphicsContext::strokePath()
path.setFillRule(toQtFillRule(fillRule()));
if (m_data->hasShadow()) {
- p->translate(m_data->shadow.offset);
+ p->translate(m_data->shadow.offset());
QPen shadowPen(pen);
- shadowPen.setColor(m_data->shadow.color);
+ shadowPen.setColor(m_data->shadow.m_color);
p->strokePath(path, shadowPen);
- p->translate(-m_data->shadow.offset);
+ p->translate(-m_data->shadow.offset());
}
if (m_common->state.strokePattern) {
AffineTransform affine;
@@ -653,7 +653,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
if (shadowPainter) {
drawRepeatPattern(shadowPainter, image, normalizedRect, m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
- shadowPainter->fillRect(normalizedRect, shadow->color);
+ shadowPainter->fillRect(normalizedRect, shadow->m_color);
shadow->endShadowLayer(p);
}
drawRepeatPattern(p, image, normalizedRect, m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY());
@@ -664,13 +664,13 @@ void GraphicsContext::fillRect(const FloatRect& rect)
if (shadowPainter) {
shadowPainter->fillRect(normalizedRect, brush);
shadowPainter->setCompositionMode(QPainter::CompositionMode_SourceIn);
- shadowPainter->fillRect(normalizedRect, shadow->color);
+ shadowPainter->fillRect(normalizedRect, shadow->m_color);
shadow->endShadowLayer(p);
}
p->fillRect(normalizedRect, brush);
} else {
if (m_data->hasShadow()) {
- if (shadow->type == ContextShadow::BlurShadow) {
+ if (shadow->m_type == ContextShadow::BlurShadow) {
QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
if (shadowPainter) {
shadowPainter->fillRect(normalizedRect, p->brush());
@@ -679,9 +679,9 @@ void GraphicsContext::fillRect(const FloatRect& rect)
} else {
// Solid rectangle fill with no blur shadow can be done faster
// without using the shadow layer at all.
- QColor shadowColor = shadow->color;
+ QColor shadowColor = shadow->m_color;
shadowColor.setAlphaF(shadowColor.alphaF() * p->brush().color().alphaF());
- p->fillRect(normalizedRect.translated(shadow->offset), shadowColor);
+ p->fillRect(normalizedRect.translated(shadow->offset()), shadowColor);
}
}
p->fillRect(normalizedRect, p->brush());
@@ -701,14 +701,14 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (m_data->hasShadow()) {
ContextShadow* shadow = contextShadow();
- if (shadow->type != ContextShadow::BlurShadow) {
+ if (shadow->m_type != ContextShadow::BlurShadow) {
// We do not need any layer for simple shadow.
- p->fillRect(normalizedRect.translated(shadow->offset), shadow->color);
+ p->fillRect(normalizedRect.translated(shadow->offset()), shadow->m_color);
} else {
QPainter* shadowPainter = shadow->beginShadowLayer(p, normalizedRect);
if (shadowPainter) {
shadowPainter->setCompositionMode(QPainter::CompositionMode_Source);
- shadowPainter->fillRect(normalizedRect, shadow->color);
+ shadowPainter->fillRect(normalizedRect, shadow->m_color);
shadow->endShadowLayer(p);
}
}
@@ -725,9 +725,9 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef
Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight);
QPainter* p = m_data->p();
if (m_data->hasShadow()) {
- p->translate(m_data->shadow.offset);
- p->fillPath(path.platformPath(), m_data->shadow.color);
- p->translate(-m_data->shadow.offset);
+ p->translate(m_data->shadow.offset());
+ p->fillPath(path.platformPath(), QColor(m_data->shadow.m_color));
+ p->translate(-m_data->shadow.offset());
}
p->fillPath(path.platformPath(), QColor(color));
}
@@ -884,9 +884,9 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const
// Meaning that this graphics context is associated with a CanvasRenderingContext
// We flip the height since CG and HTML5 Canvas have opposite Y axis
m_common->state.shadowOffset = FloatSize(size.width(), -size.height());
- m_data->shadow = ContextShadow(color, blur, size.width(), -size.height());
+ m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), -size.height()));
} else {
- m_data->shadow = ContextShadow(color, blur, size.width(), size.height());
+ m_data->shadow = ContextShadow(color, blur, FloatSize(size.width(), size.height()));
}
}
@@ -1002,7 +1002,7 @@ void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
pattern.append(dashes[i % dashLength] / penWidth);
pen.setDashPattern(pattern);
- pen.setDashOffset(dashOffset);
+ pen.setDashOffset(dashOffset / penWidth);
} else
pen.setStyle(Qt::SolidLine);
p->setPen(pen);
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
index 08eb816..b881036 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp
@@ -51,7 +51,7 @@ using namespace Phonon;
#define LOG_MEDIAOBJECT() (LOG(Media, "%s", debugMediaObject(this, *m_mediaObject).constData()))
#if !LOG_DISABLED
-static QByteArray debugMediaObject(WebCore::MediaPlayerPrivate* mediaPlayer, const MediaObject& mediaObject)
+static QByteArray debugMediaObject(WebCore::MediaPlayerPrivatePhonon* mediaPlayer, const MediaObject& mediaObject)
{
QByteArray byteArray;
QTextStream stream(&byteArray);
@@ -84,7 +84,7 @@ using namespace WTF;
namespace WebCore {
-MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
+MediaPlayerPrivatePhonon::MediaPlayerPrivatePhonon(MediaPlayer* player)
: m_player(player)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
@@ -118,19 +118,19 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
connect(m_mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
}
-MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player)
+MediaPlayerPrivateInterface* MediaPlayerPrivatePhonon::create(MediaPlayer* player)
{
- return new MediaPlayerPrivate(player);
+ return new MediaPlayerPrivatePhonon(player);
}
-void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
+void MediaPlayerPrivatePhonon::registerMediaEngine(MediaEngineRegistrar registrar)
{
if (isAvailable())
registrar(create, getSupportedTypes, supportsType);
}
-MediaPlayerPrivate::~MediaPlayerPrivate()
+MediaPlayerPrivatePhonon::~MediaPlayerPrivatePhonon()
{
LOG(Media, "MediaPlayerPrivatePhonon::dtor deleting videowidget");
m_videoWidget->close();
@@ -146,7 +146,7 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
m_mediaObject = 0;
}
-HashSet<String>& MediaPlayerPrivate::supportedTypesCache()
+HashSet<String>& MediaPlayerPrivatePhonon::supportedTypesCache()
{
static HashSet<String> supportedTypes;
if (!supportedTypes.isEmpty())
@@ -190,12 +190,12 @@ HashSet<String>& MediaPlayerPrivate::supportedTypesCache()
return supportedTypes;
}
-void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types)
+void MediaPlayerPrivatePhonon::getSupportedTypes(HashSet<String>& types)
{
types = supportedTypesCache();
}
-MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs)
+MediaPlayer::SupportsType MediaPlayerPrivatePhonon::supportsType(const String& type, const String& codecs)
{
if (type.isEmpty())
return MediaPlayer::IsNotSupported;
@@ -205,14 +205,14 @@ MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, c
return MediaPlayer::IsNotSupported;
}
-bool MediaPlayerPrivate::hasVideo() const
+bool MediaPlayerPrivatePhonon::hasVideo() const
{
bool hasVideo = m_mediaObject->hasVideo();
LOG(Media, "MediaPlayerPrivatePhonon::hasVideo() -> %s", hasVideo ? "true" : "false");
return hasVideo;
}
-bool MediaPlayerPrivate::hasAudio() const
+bool MediaPlayerPrivatePhonon::hasAudio() const
{
// FIXME: Phonon::MediaObject does not have such a hasAudio() function
bool hasAudio = true;
@@ -220,7 +220,7 @@ bool MediaPlayerPrivate::hasAudio() const
return hasAudio;
}
-void MediaPlayerPrivate::load(const String& url)
+void MediaPlayerPrivatePhonon::load(const String& url)
{
LOG(Media, "MediaPlayerPrivatePhonon::load(\"%s\")", url.utf8().data());
@@ -241,33 +241,33 @@ void MediaPlayerPrivate::load(const String& url)
setVisible(m_player->visible());
}
-void MediaPlayerPrivate::cancelLoad()
+void MediaPlayerPrivatePhonon::cancelLoad()
{
notImplemented();
}
-void MediaPlayerPrivate::play()
+void MediaPlayerPrivatePhonon::play()
{
LOG(Media, "MediaPlayerPrivatePhonon::play()");
m_mediaObject->play();
}
-void MediaPlayerPrivate::pause()
+void MediaPlayerPrivatePhonon::pause()
{
LOG(Media, "MediaPlayerPrivatePhonon::pause()");
m_mediaObject->pause();
}
-bool MediaPlayerPrivate::paused() const
+bool MediaPlayerPrivatePhonon::paused() const
{
bool paused = m_mediaObject->state() == Phonon::PausedState;
LOG(Media, "MediaPlayerPrivatePhonon::paused() --> %s", paused ? "true" : "false");
return paused;
}
-void MediaPlayerPrivate::seek(float position)
+void MediaPlayerPrivatePhonon::seek(float position)
{
LOG(Media, "MediaPlayerPrivatePhonon::seek(%f)", position);
@@ -280,12 +280,12 @@ void MediaPlayerPrivate::seek(float position)
m_mediaObject->seek(position * 1000.0f);
}
-bool MediaPlayerPrivate::seeking() const
+bool MediaPlayerPrivatePhonon::seeking() const
{
return false;
}
-float MediaPlayerPrivate::duration() const
+float MediaPlayerPrivatePhonon::duration() const
{
if (m_readyState < MediaPlayer::HaveMetadata)
return 0.0f;
@@ -299,7 +299,7 @@ float MediaPlayerPrivate::duration() const
return duration;
}
-float MediaPlayerPrivate::currentTime() const
+float MediaPlayerPrivatePhonon::currentTime() const
{
float currentTime = m_mediaObject->currentTime() / 1000.0f;
@@ -307,48 +307,48 @@ float MediaPlayerPrivate::currentTime() const
return currentTime;
}
-PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
+PassRefPtr<TimeRanges> MediaPlayerPrivatePhonon::buffered() const
{
notImplemented();
return TimeRanges::create();
}
-float MediaPlayerPrivate::maxTimeSeekable() const
+float MediaPlayerPrivatePhonon::maxTimeSeekable() const
{
notImplemented();
return 0.0f;
}
-unsigned MediaPlayerPrivate::bytesLoaded() const
+unsigned MediaPlayerPrivatePhonon::bytesLoaded() const
{
notImplemented();
return 0;
}
-unsigned MediaPlayerPrivate::totalBytes() const
+unsigned MediaPlayerPrivatePhonon::totalBytes() const
{
//notImplemented();
return 0;
}
-void MediaPlayerPrivate::setRate(float)
+void MediaPlayerPrivatePhonon::setRate(float)
{
notImplemented();
}
-void MediaPlayerPrivate::setVolume(float volume)
+void MediaPlayerPrivatePhonon::setVolume(float volume)
{
LOG(Media, "MediaPlayerPrivatePhonon::setVolume()");
m_audioOutput->setVolume(volume);
}
-void MediaPlayerPrivate::setMuted(bool muted)
+void MediaPlayerPrivatePhonon::setMuted(bool muted)
{
LOG(Media, "MediaPlayerPrivatePhonon::setMuted()");
m_audioOutput->setMuted(muted);
}
-MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
+MediaPlayer::NetworkState MediaPlayerPrivatePhonon::networkState() const
{
const QMetaObject* metaObj = this->metaObject();
QMetaEnum networkStates = metaObj->enumerator(metaObj->indexOfEnumerator("NetworkState"));
@@ -356,7 +356,7 @@ MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
return m_networkState;
}
-MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
+MediaPlayer::ReadyState MediaPlayerPrivatePhonon::readyState() const
{
const QMetaObject* metaObj = this->metaObject();
QMetaEnum readyStates = metaObj->enumerator(metaObj->indexOfEnumerator("ReadyState"));
@@ -364,7 +364,7 @@ MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
return m_readyState;
}
-void MediaPlayerPrivate::updateStates()
+void MediaPlayerPrivatePhonon::updateStates()
{
MediaPlayer::NetworkState oldNetworkState = m_networkState;
MediaPlayer::ReadyState oldReadyState = m_readyState;
@@ -412,7 +412,7 @@ void MediaPlayerPrivate::updateStates()
}
}
-void MediaPlayerPrivate::setVisible(bool visible)
+void MediaPlayerPrivatePhonon::setVisible(bool visible)
{
m_isVisible = visible;
LOG(Media, "MediaPlayerPrivatePhonon::setVisible(%s)", visible ? "true" : "false");
@@ -420,7 +420,7 @@ void MediaPlayerPrivate::setVisible(bool visible)
m_videoWidget->setVisible(m_isVisible);
}
-void MediaPlayerPrivate::setSize(const IntSize& newSize)
+void MediaPlayerPrivatePhonon::setSize(const IntSize& newSize)
{
if (!m_videoWidget)
return;
@@ -434,7 +434,7 @@ void MediaPlayerPrivate::setSize(const IntSize& newSize)
m_videoWidget->resize(newSize.width(), newSize.height());
}
-IntSize MediaPlayerPrivate::naturalSize() const
+IntSize MediaPlayerPrivatePhonon::naturalSize() const
{
if (!hasVideo()) {
LOG(Media, "MediaPlayerPrivatePhonon::naturalSize() -> %dx%d",
@@ -455,7 +455,7 @@ IntSize MediaPlayerPrivate::naturalSize() const
return naturalSize;
}
-bool MediaPlayerPrivate::eventFilter(QObject* obj, QEvent* event)
+bool MediaPlayerPrivatePhonon::eventFilter(QObject* obj, QEvent* event)
{
if (event->type() == QEvent::UpdateRequest)
m_player->repaint();
@@ -463,7 +463,7 @@ bool MediaPlayerPrivate::eventFilter(QObject* obj, QEvent* event)
return QObject::eventFilter(obj, event);
}
-void MediaPlayerPrivate::paint(GraphicsContext* graphicsContect, const IntRect& rect)
+void MediaPlayerPrivatePhonon::paint(GraphicsContext* graphicsContect, const IntRect& rect)
{
if (graphicsContect->paintingDisabled())
return;
@@ -481,7 +481,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* graphicsContect, const IntRect&
// ====================== Phonon::MediaObject signals ======================
-void MediaPlayerPrivate::stateChanged(Phonon::State newState, Phonon::State oldState)
+void MediaPlayerPrivatePhonon::stateChanged(Phonon::State newState, Phonon::State oldState)
{
const QMetaObject* metaObj = this->metaObject();
QMetaEnum phononStates = metaObj->enumerator(metaObj->indexOfEnumerator("PhononState"));
@@ -491,48 +491,48 @@ void MediaPlayerPrivate::stateChanged(Phonon::State newState, Phonon::State oldS
updateStates();
}
-void MediaPlayerPrivate::metaDataChanged()
+void MediaPlayerPrivatePhonon::metaDataChanged()
{
LOG(Media, "MediaPlayerPrivatePhonon::metaDataChanged()");
LOG_MEDIAOBJECT();
}
-void MediaPlayerPrivate::seekableChanged(bool)
+void MediaPlayerPrivatePhonon::seekableChanged(bool)
{
notImplemented();
LOG_MEDIAOBJECT();
}
-void MediaPlayerPrivate::hasVideoChanged(bool hasVideo)
+void MediaPlayerPrivatePhonon::hasVideoChanged(bool hasVideo)
{
LOG(Media, "MediaPlayerPrivatePhonon::hasVideoChanged(%s)", hasVideo ? "true" : "false");
}
-void MediaPlayerPrivate::bufferStatus(int)
+void MediaPlayerPrivatePhonon::bufferStatus(int)
{
notImplemented();
LOG_MEDIAOBJECT();
}
-void MediaPlayerPrivate::finished()
+void MediaPlayerPrivatePhonon::finished()
{
notImplemented();
LOG_MEDIAOBJECT();
}
-void MediaPlayerPrivate::currentSourceChanged(const Phonon::MediaSource&)
+void MediaPlayerPrivatePhonon::currentSourceChanged(const Phonon::MediaSource&)
{
notImplemented();
LOG_MEDIAOBJECT();
}
-void MediaPlayerPrivate::aboutToFinish()
+void MediaPlayerPrivatePhonon::aboutToFinish()
{
notImplemented();
LOG_MEDIAOBJECT();
}
-void MediaPlayerPrivate::totalTimeChanged(qint64 totalTime)
+void MediaPlayerPrivatePhonon::totalTimeChanged(qint64 totalTime)
{
#if OS(WINDOWS)
LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%I64d)", totalTime);
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
index ff6a01c..d793675 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.h
@@ -40,13 +40,13 @@ QT_END_NAMESPACE
namespace WebCore {
- class MediaPlayerPrivate : public QObject, public MediaPlayerPrivateInterface {
+ class MediaPlayerPrivatePhonon : public QObject, public MediaPlayerPrivateInterface {
Q_OBJECT
public:
static void registerMediaEngine(MediaEngineRegistrar);
- ~MediaPlayerPrivate();
+ ~MediaPlayerPrivatePhonon();
// These enums are used for debugging
Q_ENUMS(ReadyState NetworkState PhononState)
@@ -127,7 +127,7 @@ namespace WebCore {
void totalTimeChanged(qint64);
private:
- MediaPlayerPrivate(MediaPlayer*);
+ MediaPlayerPrivatePhonon(MediaPlayer*);
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
static void getSupportedTypes(HashSet<String>&);
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
index 1bf1a3d..1a31d1e 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp
@@ -53,17 +53,17 @@ using namespace WTF;
namespace WebCore {
-MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player)
+MediaPlayerPrivateInterface* MediaPlayerPrivateQt::create(MediaPlayer* player)
{
- return new MediaPlayerPrivate(player);
+ return new MediaPlayerPrivateQt(player);
}
-void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
+void MediaPlayerPrivateQt::registerMediaEngine(MediaEngineRegistrar registrar)
{
registrar(create, getSupportedTypes, supportsType);
}
-void MediaPlayerPrivate::getSupportedTypes(HashSet<String> &supported)
+void MediaPlayerPrivateQt::getSupportedTypes(HashSet<String> &supported)
{
QStringList types = QMediaPlayer::supportedMimeTypes();
@@ -74,7 +74,7 @@ void MediaPlayerPrivate::getSupportedTypes(HashSet<String> &supported)
}
}
-MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& mime, const String& codec)
+MediaPlayer::SupportsType MediaPlayerPrivateQt::supportsType(const String& mime, const String& codec)
{
if (!mime.startsWith("audio/") && !mime.startsWith("video/"))
return MediaPlayer::IsNotSupported;
@@ -85,8 +85,8 @@ MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& mime, c
return MediaPlayer::MayBeSupported;
}
-MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
- : m_player(player)
+MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player)
+ : m_webCorePlayer(player)
, m_mediaPlayer(new QMediaPlayer)
, m_mediaPlayerControl(0)
, m_videoItem(new QGraphicsVideoItem)
@@ -132,23 +132,23 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
}
}
-MediaPlayerPrivate::~MediaPlayerPrivate()
+MediaPlayerPrivateQt::~MediaPlayerPrivateQt()
{
delete m_mediaPlayer;
delete m_videoScene;
}
-bool MediaPlayerPrivate::hasVideo() const
+bool MediaPlayerPrivateQt::hasVideo() const
{
return m_mediaPlayer->isVideoAvailable();
}
-bool MediaPlayerPrivate::hasAudio() const
+bool MediaPlayerPrivateQt::hasAudio() const
{
return true;
}
-void MediaPlayerPrivate::load(const String& url)
+void MediaPlayerPrivateQt::load(const String& url)
{
m_mediaUrl = url;
@@ -162,25 +162,25 @@ void MediaPlayerPrivate::load(const String& url)
commitLoad(url);
}
-void MediaPlayerPrivate::commitLoad(const String& url)
+void MediaPlayerPrivateQt::commitLoad(const String& url)
{
// We are now loading
if (m_networkState != MediaPlayer::Loading) {
m_networkState = MediaPlayer::Loading;
- m_player->networkStateChanged();
+ m_webCorePlayer->networkStateChanged();
}
// And we don't have any data yet
if (m_readyState != MediaPlayer::HaveNothing) {
m_readyState = MediaPlayer::HaveNothing;
- m_player->readyStateChanged();
+ m_webCorePlayer->readyStateChanged();
}
const QUrl rUrl = QUrl(QString(url));
const QString scheme = rUrl.scheme().toLower();
// Grab the client media element
- HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_player->mediaPlayerClient());
+ HTMLMediaElement* element = static_cast<HTMLMediaElement*>(m_webCorePlayer->mediaPlayerClient());
// Construct the media content with a network request if the resource is http[s]
if (scheme == "http" || scheme == "https") {
@@ -236,7 +236,7 @@ void MediaPlayerPrivate::commitLoad(const String& url)
m_mediaPlayer->play();
}
-void MediaPlayerPrivate::resumeLoad()
+void MediaPlayerPrivateQt::resumeLoad()
{
m_delayingLoad = false;
@@ -244,36 +244,36 @@ void MediaPlayerPrivate::resumeLoad()
commitLoad(m_mediaUrl);
}
-void MediaPlayerPrivate::cancelLoad()
+void MediaPlayerPrivateQt::cancelLoad()
{
m_mediaPlayer->setMedia(QMediaContent());
updateStates();
}
-void MediaPlayerPrivate::prepareToPlay()
+void MediaPlayerPrivateQt::prepareToPlay()
{
if (m_mediaPlayer->media().isNull() || m_delayingLoad)
resumeLoad();
}
-void MediaPlayerPrivate::play()
+void MediaPlayerPrivateQt::play()
{
if (m_mediaPlayer->state() != QMediaPlayer::PlayingState)
m_mediaPlayer->play();
}
-void MediaPlayerPrivate::pause()
+void MediaPlayerPrivateQt::pause()
{
if (m_mediaPlayer->state() == QMediaPlayer::PlayingState)
m_mediaPlayer->pause();
}
-bool MediaPlayerPrivate::paused() const
+bool MediaPlayerPrivateQt::paused() const
{
return (m_mediaPlayer->state() != QMediaPlayer::PlayingState);
}
-void MediaPlayerPrivate::seek(float position)
+void MediaPlayerPrivateQt::seek(float position)
{
if (!m_mediaPlayer->isSeekable())
return;
@@ -309,12 +309,12 @@ void MediaPlayerPrivate::seek(float position)
}
}
-bool MediaPlayerPrivate::seeking() const
+bool MediaPlayerPrivateQt::seeking() const
{
return m_isSeeking;
}
-float MediaPlayerPrivate::duration() const
+float MediaPlayerPrivateQt::duration() const
{
if (m_readyState < MediaPlayer::HaveMetadata)
return 0.0f;
@@ -328,13 +328,13 @@ float MediaPlayerPrivate::duration() const
return duration;
}
-float MediaPlayerPrivate::currentTime() const
+float MediaPlayerPrivateQt::currentTime() const
{
float currentTime = m_mediaPlayer->position() / 1000.0f;
return currentTime;
}
-PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
+PassRefPtr<TimeRanges> MediaPlayerPrivateQt::buffered() const
{
RefPtr<TimeRanges> buffered = TimeRanges::create();
@@ -352,7 +352,7 @@ PassRefPtr<TimeRanges> MediaPlayerPrivate::buffered() const
return buffered.release();
}
-float MediaPlayerPrivate::maxTimeSeekable() const
+float MediaPlayerPrivateQt::maxTimeSeekable() const
{
if (!m_mediaPlayerControl)
return 0;
@@ -360,7 +360,7 @@ float MediaPlayerPrivate::maxTimeSeekable() const
return static_cast<float>(m_mediaPlayerControl->availablePlaybackRanges().latestTime()) / 1000.0f;
}
-unsigned MediaPlayerPrivate::bytesLoaded() const
+unsigned MediaPlayerPrivateQt::bytesLoaded() const
{
QLatin1String bytesLoadedKey("bytes-loaded");
if (m_mediaPlayer->availableExtendedMetaData().contains(bytesLoadedKey))
@@ -369,7 +369,7 @@ unsigned MediaPlayerPrivate::bytesLoaded() const
return m_mediaPlayer->bufferStatus();
}
-unsigned MediaPlayerPrivate::totalBytes() const
+unsigned MediaPlayerPrivateQt::totalBytes() const
{
if (m_mediaPlayer->availableMetaData().contains(QtMultimediaKit::Size))
return m_mediaPlayer->metaData(QtMultimediaKit::Size).toInt();
@@ -377,59 +377,59 @@ unsigned MediaPlayerPrivate::totalBytes() const
return 100;
}
-void MediaPlayerPrivate::setPreload(MediaPlayer::Preload preload)
+void MediaPlayerPrivateQt::setPreload(MediaPlayer::Preload preload)
{
m_preload = preload;
if (m_delayingLoad && m_preload != MediaPlayer::None)
resumeLoad();
}
-void MediaPlayerPrivate::setRate(float rate)
+void MediaPlayerPrivateQt::setRate(float rate)
{
m_mediaPlayer->setPlaybackRate(rate);
}
-void MediaPlayerPrivate::setVolume(float volume)
+void MediaPlayerPrivateQt::setVolume(float volume)
{
m_mediaPlayer->setVolume(static_cast<int>(volume * 100.0));
}
-bool MediaPlayerPrivate::supportsMuting() const
+bool MediaPlayerPrivateQt::supportsMuting() const
{
return true;
}
-void MediaPlayerPrivate::setMuted(bool muted)
+void MediaPlayerPrivateQt::setMuted(bool muted)
{
m_mediaPlayer->setMuted(muted);
}
-MediaPlayer::NetworkState MediaPlayerPrivate::networkState() const
+MediaPlayer::NetworkState MediaPlayerPrivateQt::networkState() const
{
return m_networkState;
}
-MediaPlayer::ReadyState MediaPlayerPrivate::readyState() const
+MediaPlayer::ReadyState MediaPlayerPrivateQt::readyState() const
{
return m_readyState;
}
-void MediaPlayerPrivate::setVisible(bool visible)
+void MediaPlayerPrivateQt::setVisible(bool visible)
{
m_isVisible = visible;
}
-void MediaPlayerPrivate::mediaStatusChanged(QMediaPlayer::MediaStatus)
+void MediaPlayerPrivateQt::mediaStatusChanged(QMediaPlayer::MediaStatus)
{
updateStates();
}
-void MediaPlayerPrivate::handleError(QMediaPlayer::Error)
+void MediaPlayerPrivateQt::handleError(QMediaPlayer::Error)
{
updateStates();
}
-void MediaPlayerPrivate::stateChanged(QMediaPlayer::State state)
+void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State state)
{
if (state != QMediaPlayer::PlayingState && m_isSeeking && m_queuedSeek >= 0) {
m_mediaPlayer->setPosition(m_queuedSeek);
@@ -437,12 +437,12 @@ void MediaPlayerPrivate::stateChanged(QMediaPlayer::State state)
}
}
-void MediaPlayerPrivate::nativeSizeChanged(const QSizeF&)
+void MediaPlayerPrivateQt::nativeSizeChanged(const QSizeF&)
{
- m_player->sizeChanged();
+ m_webCorePlayer->sizeChanged();
}
-void MediaPlayerPrivate::queuedSeekTimeout()
+void MediaPlayerPrivateQt::queuedSeekTimeout()
{
// If we haven't heard anything, assume the player is now paused
// and we can attempt the seek
@@ -455,45 +455,45 @@ void MediaPlayerPrivate::queuedSeekTimeout()
}
}
-void MediaPlayerPrivate::seekTimeout()
+void MediaPlayerPrivateQt::seekTimeout()
{
// If we haven't heard anything, assume the seek succeeded
if (m_isSeeking) {
- m_player->timeChanged();
+ m_webCorePlayer->timeChanged();
m_isSeeking = false;
}
}
-void MediaPlayerPrivate::positionChanged(qint64)
+void MediaPlayerPrivateQt::positionChanged(qint64)
{
// Only propogate this event if we are seeking
if (m_isSeeking && m_queuedSeek == -1) {
- m_player->timeChanged();
+ m_webCorePlayer->timeChanged();
m_isSeeking = false;
}
}
-void MediaPlayerPrivate::bufferStatusChanged(int)
+void MediaPlayerPrivateQt::bufferStatusChanged(int)
{
notImplemented();
}
-void MediaPlayerPrivate::durationChanged(qint64)
+void MediaPlayerPrivateQt::durationChanged(qint64)
{
- m_player->durationChanged();
+ m_webCorePlayer->durationChanged();
}
-void MediaPlayerPrivate::volumeChanged(int volume)
+void MediaPlayerPrivateQt::volumeChanged(int volume)
{
- m_player->volumeChanged(static_cast<float>(volume) / 100.0);
+ m_webCorePlayer->volumeChanged(static_cast<float>(volume) / 100.0);
}
-void MediaPlayerPrivate::mutedChanged(bool muted)
+void MediaPlayerPrivateQt::mutedChanged(bool muted)
{
- m_player->muteChanged(muted);
+ m_webCorePlayer->muteChanged(muted);
}
-void MediaPlayerPrivate::updateStates()
+void MediaPlayerPrivateQt::updateStates()
{
// Store the old states so that we can detect a change and raise change events
MediaPlayer::NetworkState oldNetworkState = m_networkState;
@@ -538,13 +538,13 @@ void MediaPlayerPrivate::updateStates()
// Breaking this invariant will cause the resource selection algorithm for multiple
// sources to fail.
if (m_readyState != oldReadyState)
- m_player->readyStateChanged();
+ m_webCorePlayer->readyStateChanged();
if (m_networkState != oldNetworkState)
- m_player->networkStateChanged();
+ m_webCorePlayer->networkStateChanged();
}
-void MediaPlayerPrivate::setSize(const IntSize& size)
+void MediaPlayerPrivateQt::setSize(const IntSize& size)
{
if (size == m_currentSize)
return;
@@ -553,7 +553,7 @@ void MediaPlayerPrivate::setSize(const IntSize& size)
m_videoItem->setSize(QSizeF(QSize(size)));
}
-IntSize MediaPlayerPrivate::naturalSize() const
+IntSize MediaPlayerPrivateQt::naturalSize() const
{
if (!hasVideo() || m_readyState < MediaPlayer::HaveMetadata)
return IntSize();
@@ -561,7 +561,7 @@ IntSize MediaPlayerPrivate::naturalSize() const
return IntSize(m_videoItem->nativeSize().toSize());
}
-void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
+void MediaPlayerPrivateQt::paint(GraphicsContext* context, const IntRect& rect)
{
#if USE(ACCELERATED_COMPOSITING)
if (m_composited)
@@ -580,15 +580,16 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
m_videoScene->render(painter, QRectF(QRect(rect)), m_videoItem->sceneBoundingRect());
}
-void MediaPlayerPrivate::repaint()
+void MediaPlayerPrivateQt::repaint()
{
- m_player->repaint();
+ m_webCorePlayer->repaint();
}
#if USE(ACCELERATED_COMPOSITING)
-void MediaPlayerPrivate::acceleratedRenderingStateChanged()
+void MediaPlayerPrivateQt::acceleratedRenderingStateChanged()
{
- bool composited = m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player);
+ MediaPlayerClient* client = m_webCorePlayer->mediaPlayerClient();
+ bool composited = client->mediaPlayerRenderingCanBeAccelerated(m_webCorePlayer);
if (composited == m_composited)
return;
@@ -599,17 +600,17 @@ void MediaPlayerPrivate::acceleratedRenderingStateChanged()
m_videoScene->addItem(m_videoItem);
}
-PlatformLayer* MediaPlayerPrivate::platformLayer() const
+PlatformLayer* MediaPlayerPrivateQt::platformLayer() const
{
return m_composited ? m_videoItem : 0;
}
#endif
-PlatformMedia MediaPlayerPrivate::platformMedia() const
+PlatformMedia MediaPlayerPrivateQt::platformMedia() const
{
PlatformMedia pm;
pm.type = PlatformMedia::QtMediaPlayerType;
- pm.media.qtMediaPlayer = const_cast<MediaPlayerPrivate*>(this);
+ pm.media.qtMediaPlayer = const_cast<MediaPlayerPrivateQt*>(this);
return pm;
}
diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
index 117187d..179bf2a 100644
--- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
+++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h
@@ -33,13 +33,13 @@ QT_END_NAMESPACE
namespace WebCore {
-class MediaPlayerPrivate : public QObject, public MediaPlayerPrivateInterface {
+class MediaPlayerPrivateQt : public QObject, public MediaPlayerPrivateInterface {
Q_OBJECT
public:
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
- ~MediaPlayerPrivate();
+ ~MediaPlayerPrivateQt();
static void registerMediaEngine(MediaEngineRegistrar);
static void getSupportedTypes(HashSet<String>&);
@@ -118,9 +118,9 @@ private:
void updateStates();
private:
- MediaPlayerPrivate(MediaPlayer*);
+ MediaPlayerPrivateQt(MediaPlayer*);
- MediaPlayer* m_player;
+ MediaPlayer* m_webCorePlayer;
QMediaPlayer* m_mediaPlayer;
QMediaPlayerControl* m_mediaPlayerControl;
QGraphicsVideoItem* m_videoItem;
diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
index b6d6e65..8301871 100644
--- a/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
+++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.cpp
@@ -36,7 +36,7 @@
#include "Base64.h"
#include "ChromiumBridge.h"
#include "OpenTypeUtilities.h"
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
#include "SkStream.h"
#endif
@@ -47,7 +47,7 @@
#if OS(WINDOWS)
#include <objbase.h>
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
#include <cstring>
#endif
@@ -58,7 +58,7 @@ FontCustomPlatformData::~FontCustomPlatformData()
#if OS(WINDOWS)
if (m_fontReference)
RemoveFontMemResourceEx(m_fontReference);
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
if (m_fontReference)
m_fontReference->unref();
#endif
@@ -99,7 +99,7 @@ FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, b
HFONT hfont = CreateFontIndirect(&logFont);
return FontPlatformData(hfont, size);
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
ASSERT(m_fontReference);
return FontPlatformData(m_fontReference, "", size, bold && !m_fontReference->isBold(), italic && !m_fontReference->isItalic());
#else
@@ -123,7 +123,7 @@ static String createUniqueFontName()
}
#endif
-#if OS(LINUX)
+#if OS(LINUX) || OS(FREEBSD)
class RemoteFontStream : public SkStream {
public:
explicit RemoteFontStream(PassRefPtr<SharedBuffer> buffer)
@@ -189,7 +189,7 @@ FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer)
if (!fontReference)
return 0;
return new FontCustomPlatformData(fontReference, fontName);
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
RemoteFontStream* stream = new RemoteFontStream(buffer);
SkTypeface* typeface = SkTypeface::CreateFromStream(stream);
if (!typeface)
diff --git a/WebCore/platform/graphics/skia/FontCustomPlatformData.h b/WebCore/platform/graphics/skia/FontCustomPlatformData.h
index d451c9c..94d7ec3 100644
--- a/WebCore/platform/graphics/skia/FontCustomPlatformData.h
+++ b/WebCore/platform/graphics/skia/FontCustomPlatformData.h
@@ -39,7 +39,7 @@
#if OS(WINDOWS)
#include "PlatformString.h"
#include <windows.h>
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
#include "SkTypeface.h"
#endif
@@ -54,7 +54,7 @@ struct FontCustomPlatformData : Noncopyable {
: m_fontReference(fontReference)
, m_name(name)
{}
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
explicit FontCustomPlatformData(SkTypeface* typeface)
: m_fontReference(typeface)
{}
@@ -70,7 +70,7 @@ struct FontCustomPlatformData : Noncopyable {
#if OS(WINDOWS)
HANDLE m_fontReference;
String m_name;
-#elif OS(LINUX)
+#elif OS(LINUX) || OS(FREEBSD)
SkTypeface* m_fontReference;
#endif
};
diff --git a/WebCore/platform/graphics/skia/GradientSkia.cpp b/WebCore/platform/graphics/skia/GradientSkia.cpp
index 66a8976..a636d10 100644
--- a/WebCore/platform/graphics/skia/GradientSkia.cpp
+++ b/WebCore/platform/graphics/skia/GradientSkia.cpp
@@ -42,7 +42,7 @@ namespace WebCore {
void Gradient::platformDestroy()
{
if (m_gradient)
- m_gradient->safeUnref();
+ SkSafeUnref(m_gradient);
m_gradient = 0;
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index d618c19..4bc98fb 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -338,13 +338,15 @@ void GraphicsContext::clearRect(const FloatRect& rect)
if (paintingDisabled())
return;
- if (platformContext()->useGPU()) {
+ if (platformContext()->useGPU() && !platformContext()->canvasClipApplied()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->clearRect(rect);
return;
}
- platformContext()->prepareForSoftwareDraw();
+ // Force a readback here (if we're using the GPU), since clearRect() is
+ // incompatible with mixed-mode rendering.
+ platformContext()->syncSoftwareCanvas();
SkRect r = rect;
if (!isRectSkiaSafe(getCTM(), r))
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index 0b96d80..e123256 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -36,7 +36,6 @@
#include "FloatConversion.h"
#include "FloatRect.h"
#include "GLES2Canvas.h"
-#include "GLES2Context.h"
#include "GraphicsContext.h"
#include "Logging.h"
#include "NativeImageSkia.h"
@@ -144,7 +143,9 @@ static ResamplingMode computeResamplingMode(PlatformContextSkia* platformContext
// Everything else gets resampled.
// If the platform context permits high quality interpolation, use it.
- if (platformContext->interpolationQuality() == InterpolationHigh)
+ // High quality interpolation only enabled for scaling and translation.
+ if (platformContext->interpolationQuality() == InterpolationHigh
+ && !(platformContext->canvas()->getTotalMatrix().getType() & (SkMatrix::kAffine_Mask | SkMatrix::kPerspective_Mask)))
return RESAMPLE_AWESOME;
return RESAMPLE_LINEAR;
@@ -174,8 +175,12 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
&& srcIRect.height() == bitmap.height();
// We will always draw in integer sizes, so round the destination rect.
+ // First we need to apply canvas transformation matrix to get desired size of
+ // resampled image.
+ SkRect destRectTransformed;
+ canvas.getTotalMatrix().mapRect(&destRectTransformed, destRect);
SkIRect destRectRounded;
- destRect.round(&destRectRounded);
+ destRectTransformed.round(&destRectRounded);
SkIRect resizedImageRect = // Represents the size of the resized image.
{ 0, 0, destRectRounded.width(), destRectRounded.height() };
@@ -189,7 +194,10 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
// Compute the visible portion of our rect.
SkRect destBitmapSubsetSk;
ClipRectToCanvas(canvas, destRect, &destBitmapSubsetSk);
- destBitmapSubsetSk.offset(-destRect.fLeft, -destRect.fTop);
+ // Determine size of resampled image based on clipped destination rect.
+ SkRect destBitmapSubsetSkTransformed;
+ canvas.getTotalMatrix().mapRect(&destBitmapSubsetSkTransformed, destBitmapSubsetSk);
+ destBitmapSubsetSkTransformed.offset(-destBitmapSubsetSkTransformed.fLeft, -destBitmapSubsetSkTransformed.fTop);
// The matrix inverting, etc. could have introduced rounding error which
// causes the bounds to be outside of the resized bitmap. We round outward
@@ -197,7 +205,7 @@ static void drawResampledBitmap(SkCanvas& canvas, SkPaint& paint, const NativeIm
// need, and then clamp to the bitmap bounds so we don't get any invalid
// data.
SkIRect destBitmapSubsetSkI;
- destBitmapSubsetSk.roundOut(&destBitmapSubsetSkI);
+ destBitmapSubsetSkTransformed.roundOut(&destBitmapSubsetSkI);
if (!destBitmapSubsetSkI.intersect(resizedImageRect))
return; // Resized image does not intersect.
diff --git a/WebCore/platform/graphics/skia/PatternSkia.cpp b/WebCore/platform/graphics/skia/PatternSkia.cpp
index bd27b6a..72fac77 100644
--- a/WebCore/platform/graphics/skia/PatternSkia.cpp
+++ b/WebCore/platform/graphics/skia/PatternSkia.cpp
@@ -42,7 +42,7 @@ namespace WebCore {
void Pattern::platformDestroy()
{
- m_pattern->safeUnref();
+ SkSafeUnref(m_pattern);
m_pattern = 0;
}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 88fbcdd..b469312 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -162,19 +162,19 @@ PlatformContextSkia::State::State(const State& other)
, m_interpolationQuality(other.m_interpolationQuality)
, m_canvasClipApplied(other.m_canvasClipApplied)
{
- // Up the ref count of these. saveRef does nothing if 'this' is NULL.
- m_looper->safeRef();
- m_dash->safeRef();
- m_fillShader->safeRef();
- m_strokeShader->safeRef();
+ // Up the ref count of these. SkSafeRef does nothing if its argument is 0.
+ SkSafeRef(m_looper);
+ SkSafeRef(m_dash);
+ SkSafeRef(m_fillShader);
+ SkSafeRef(m_strokeShader);
}
PlatformContextSkia::State::~State()
{
- m_looper->safeUnref();
- m_dash->safeUnref();
- m_fillShader->safeUnref();
- m_strokeShader->safeUnref();
+ SkSafeUnref(m_looper);
+ SkSafeUnref(m_dash);
+ SkSafeUnref(m_fillShader);
+ SkSafeUnref(m_strokeShader);
}
// Returns a new State with all of this object's inherited properties copied.
@@ -327,7 +327,7 @@ void PlatformContextSkia::drawRect(SkRect rect)
// setFillColor() will set the shader to NULL, so save a ref to it now.
SkShader* oldFillShader = m_state->m_fillShader;
- oldFillShader->safeRef();
+ SkSafeRef(oldFillShader);
setFillColor(m_state->m_strokeColor);
paint.reset();
setupPaintForFilling(&paint);
@@ -341,7 +341,7 @@ void PlatformContextSkia::drawRect(SkRect rect)
canvas()->drawRect(rightBorder, paint);
setFillColor(oldFillColor);
setFillShader(oldFillShader);
- oldFillShader->safeUnref();
+ SkSafeUnref(oldFillShader);
}
}
@@ -487,9 +487,9 @@ void PlatformContextSkia::setStrokeThickness(float thickness)
void PlatformContextSkia::setStrokeShader(SkShader* strokeShader)
{
if (strokeShader != m_state->m_strokeShader) {
- m_state->m_strokeShader->safeUnref();
+ SkSafeUnref(m_state->m_strokeShader);
m_state->m_strokeShader = strokeShader;
- m_state->m_strokeShader->safeRef();
+ SkSafeRef(m_state->m_strokeShader);
}
}
@@ -561,9 +561,9 @@ void PlatformContextSkia::setFillRule(SkPath::FillType fr)
void PlatformContextSkia::setFillShader(SkShader* fillShader)
{
if (fillShader != m_state->m_fillShader) {
- m_state->m_fillShader->safeUnref();
+ SkSafeUnref(m_state->m_fillShader);
m_state->m_fillShader = fillShader;
- m_state->m_fillShader->safeRef();
+ SkSafeRef(m_state->m_fillShader);
}
}
@@ -580,7 +580,7 @@ void PlatformContextSkia::setInterpolationQuality(InterpolationQuality interpola
void PlatformContextSkia::setDashPathEffect(SkDashPathEffect* dash)
{
if (dash != m_state->m_dash) {
- m_state->m_dash->safeUnref();
+ SkSafeUnref(m_state->m_dash);
m_state->m_dash = dash;
}
}
@@ -677,6 +677,11 @@ bool PlatformContextSkia::canAccelerate() const
&& !m_state->m_canvasClipApplied; // Can't accelerate with a clip to path applied.
}
+bool PlatformContextSkia::canvasClipApplied() const
+{
+ return m_state->m_canvasClipApplied;
+}
+
class WillPublishCallbackImpl : public DrawingBuffer::WillPublishCallback {
public:
static PassOwnPtr<WillPublishCallback> create(PlatformContextSkia* pcs)
@@ -840,7 +845,7 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
for (int i = 0; i < width; ++i) {
uint32_t pixel = pixels[i];
// Swizzles from RGBA -> BGRA.
- pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
+ pixels[i] = (pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16);
}
}
}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 4ba85d1..eb03224 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -180,6 +180,7 @@ public:
bool hasImageResamplingHint() const;
bool canAccelerate() const;
+ bool canvasClipApplied() const;
bool useGPU() { return m_useGPU; }
void setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&);
GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); }
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index 9edb775..6acfd35 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -340,7 +340,7 @@ bool paintSkiaText(GraphicsContext* context,
// thing would be to draw to a new layer and then draw that layer
// with a shadow. But this is a lot of extra work for something
// that isn't normally an issue.
- paint.setLooper(0)->safeUnref();
+ SkSafeUnref(paint.setLooper(0));
}
if (!skiaDrawText(hfont, dc, platformContext->canvas(), *origin, &paint,
diff --git a/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp b/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp
index 4072a18..80e01a9 100644
--- a/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp
+++ b/WebCore/platform/graphics/wince/PlatformPathWinCE.cpp
@@ -234,7 +234,6 @@ static void addArcPoints(PathPolygon& poly, const PlatformPathElement::ArcTo& da
static void drawPolygons(HDC dc, const Vector<PathPolygon>& polygons, bool fill, const AffineTransform* transformation)
{
- MemoryAllocationCanFail canFail;
for (Vector<PathPolygon>::const_iterator i = polygons.begin(); i != polygons.end(); ++i) {
int npoints = i->size();
if (!npoints)