summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/AsyncFileSystem.cpp76
-rw-r--r--WebCore/platform/AsyncFileSystem.h126
-rw-r--r--WebCore/platform/AsyncFileSystemCallbacks.h69
-rw-r--r--WebCore/platform/BlobItem.cpp192
-rw-r--r--WebCore/platform/BlobItem.h209
-rw-r--r--WebCore/platform/FileSystem.h6
-rw-r--r--WebCore/platform/Length.h2
-rw-r--r--WebCore/platform/MIMETypeRegistry.cpp4
-rw-r--r--WebCore/platform/PurgeableBuffer.h2
-rw-r--r--WebCore/platform/ScrollView.cpp2
-rw-r--r--WebCore/platform/ScrollView.h2
-rw-r--r--WebCore/platform/Scrollbar.cpp30
-rw-r--r--WebCore/platform/Scrollbar.h11
-rw-r--r--WebCore/platform/ScrollbarClient.h2
-rw-r--r--WebCore/platform/ThemeTypes.h2
-rw-r--r--WebCore/platform/TreeShared.h6
-rw-r--r--WebCore/platform/audio/Cone.cpp84
-rw-r--r--WebCore/platform/audio/Cone.h63
-rw-r--r--WebCore/platform/audio/FFTConvolver.cpp108
-rw-r--r--WebCore/platform/audio/FFTConvolver.h71
-rw-r--r--WebCore/platform/audio/Reverb.cpp227
-rw-r--r--WebCore/platform/audio/Reverb.h66
-rw-r--r--WebCore/platform/audio/ReverbAccumulationBuffer.cpp117
-rw-r--r--WebCore/platform/audio/ReverbAccumulationBuffer.h67
-rw-r--r--WebCore/platform/audio/ReverbConvolver.cpp228
-rw-r--r--WebCore/platform/audio/ReverbConvolver.h97
-rw-r--r--WebCore/platform/audio/ReverbConvolverStage.cpp163
-rw-r--r--WebCore/platform/audio/ReverbConvolverStage.h83
-rw-r--r--WebCore/platform/audio/ReverbInputBuffer.cpp89
-rw-r--r--WebCore/platform/audio/ReverbInputBuffer.h64
-rw-r--r--WebCore/platform/brew/SharedBufferBrew.cpp76
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h2
-rw-r--r--WebCore/platform/chromium/ClipboardMimeTypes.cpp40
-rw-r--r--WebCore/platform/chromium/ClipboardMimeTypes.h42
-rw-r--r--WebCore/platform/chromium/ReadableDataObject.cpp120
-rw-r--r--WebCore/platform/chromium/ReadableDataObject.h76
-rw-r--r--WebCore/platform/chromium/WritableDataObject.cpp152
-rw-r--r--WebCore/platform/chromium/WritableDataObject.h87
-rw-r--r--WebCore/platform/efl/ClipboardEfl.cpp2
-rw-r--r--WebCore/platform/efl/ClipboardEfl.h8
-rw-r--r--WebCore/platform/efl/ScrollbarEfl.cpp2
-rw-r--r--WebCore/platform/graphics/FloatPoint.cpp16
-rw-r--r--WebCore/platform/graphics/FloatPoint.h24
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.cpp18
-rw-r--r--WebCore/platform/graphics/FloatPoint3D.h72
-rw-r--r--WebCore/platform/graphics/FloatRect.cpp69
-rw-r--r--WebCore/platform/graphics/FloatRect.h14
-rw-r--r--WebCore/platform/graphics/FloatSize.cpp6
-rw-r--r--WebCore/platform/graphics/FloatSize.h6
-rw-r--r--WebCore/platform/graphics/GraphicsContext.cpp14
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h15
-rw-r--r--WebCore/platform/graphics/GraphicsContextPrivate.h2
-rw-r--r--WebCore/platform/graphics/MediaPlayer.cpp15
-rw-r--r--WebCore/platform/graphics/PathTraversalState.cpp2
-rw-r--r--WebCore/platform/graphics/cairo/FontCairo.cpp12
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp287
-rw-r--r--WebCore/platform/graphics/cairo/ImageCairo.cpp8
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp147
-rw-r--r--WebCore/platform/graphics/chromium/CrossProcessFontLoading.h100
-rw-r--r--WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm217
-rw-r--r--WebCore/platform/graphics/chromium/FontChromiumWin.cpp14
-rw-r--r--WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm458
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.cpp206
-rw-r--r--WebCore/platform/graphics/chromium/GLES2Canvas.h34
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.cpp33
-rw-r--r--WebCore/platform/graphics/chromium/LayerChromium.h6
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.cpp118
-rw-r--r--WebCore/platform/graphics/chromium/LayerRendererChromium.h10
-rw-r--r--WebCore/platform/graphics/cocoa/FontPlatformData.h (renamed from WebCore/platform/graphics/mac/FontPlatformData.h)21
-rw-r--r--WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm (renamed from WebCore/platform/graphics/mac/FontPlatformDataMac.mm)60
-rw-r--r--WebCore/platform/graphics/gpu/Shader.cpp111
-rw-r--r--WebCore/platform/graphics/gpu/Shader.h58
-rw-r--r--WebCore/platform/graphics/gpu/SolidFillShader.cpp86
-rw-r--r--WebCore/platform/graphics/gpu/SolidFillShader.h53
-rw-r--r--WebCore/platform/graphics/gpu/TexShader.cpp93
-rw-r--r--WebCore/platform/graphics/gpu/TexShader.h55
-rw-r--r--WebCore/platform/graphics/gpu/Texture.cpp (renamed from WebCore/platform/graphics/chromium/GLES2Texture.cpp)30
-rw-r--r--WebCore/platform/graphics/gpu/Texture.h (renamed from WebCore/platform/graphics/chromium/GLES2Texture.h)18
-rw-r--r--[-rwxr-xr-x]WebCore/platform/graphics/gpu/TilingData.cpp (renamed from WebCore/platform/graphics/chromium/TilingData.cpp)0
-rw-r--r--[-rwxr-xr-x]WebCore/platform/graphics/gpu/TilingData.h (renamed from WebCore/platform/graphics/chromium/TilingData.h)0
-rw-r--r--WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp6
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamer.h1
-rw-r--r--WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp12
-rw-r--r--WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp11
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h16
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp35
-rw-r--r--WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp1
-rw-r--r--WebCore/platform/graphics/gtk/CairoUtilities.h2
-rw-r--r--WebCore/platform/graphics/gtk/FontGtk.cpp8
-rw-r--r--WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp2
-rw-r--r--WebCore/platform/graphics/mac/FontMac.mm10
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContextMac.mm50
-rw-r--r--WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm48
-rw-r--r--WebCore/platform/graphics/mac/SimpleFontDataMac.mm6
-rw-r--r--WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp4
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp4
-rw-r--r--WebCore/platform/graphics/qt/ImageQt.cpp6
-rw-r--r--WebCore/platform/graphics/qt/StillImageQt.cpp6
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp50
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp45
-rw-r--r--WebCore/platform/graphics/skia/ImageSkia.cpp21
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp20
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h22
-rw-r--r--WebCore/platform/graphics/skia/SkiaFontWin.cpp4
-rw-r--r--WebCore/platform/graphics/win/FontCGWin.cpp16
-rw-r--r--WebCore/platform/graphics/win/GraphicsContextCGWin.cpp7
-rw-r--r--WebCore/platform/graphics/win/QTMovie.cpp3
-rw-r--r--WebCore/platform/graphics/wince/FontPlatformData.h2
-rw-r--r--WebCore/platform/graphics/wince/GraphicsContextWince.cpp19
-rw-r--r--WebCore/platform/graphics/wince/ImageBufferWince.cpp29
-rw-r--r--WebCore/platform/graphics/wx/GraphicsContextWx.cpp16
-rw-r--r--WebCore/platform/gtk/ClipboardGtk.h2
-rw-r--r--WebCore/platform/gtk/DataObjectGtk.h4
-rw-r--r--WebCore/platform/gtk/FileSystemGtk.cpp3
-rw-r--r--WebCore/platform/gtk/GOwnPtrGtk.h3
-rw-r--r--WebCore/platform/gtk/GRefPtrGtk.h3
-rw-r--r--WebCore/platform/gtk/GtkVersioning.c (renamed from WebCore/platform/gtk/GtkVersioning.cpp)21
-rw-r--r--WebCore/platform/gtk/GtkVersioning.h11
-rw-r--r--WebCore/platform/gtk/PasteboardHelper.h7
-rw-r--r--WebCore/platform/gtk/PopupMenuGtk.h4
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.cpp164
-rw-r--r--WebCore/platform/gtk/RenderThemeGtk.h21
-rw-r--r--WebCore/platform/gtk/ScrollbarGtk.h2
-rw-r--r--WebCore/platform/gtk/ScrollbarThemeGtk.cpp323
-rw-r--r--WebCore/platform/gtk/ScrollbarThemeGtk.h44
-rw-r--r--WebCore/platform/gtk/gtk2drawing.c3
-rw-r--r--WebCore/platform/mac/PopupMenuMac.h4
-rw-r--r--WebCore/platform/mac/PurgeableBufferMac.cpp2
-rw-r--r--WebCore/platform/mac/WebCoreSystemInterface.h1
-rw-r--r--WebCore/platform/mac/WebCoreSystemInterface.mm1
-rw-r--r--WebCore/platform/network/BlobRegistryImpl.cpp16
-rw-r--r--WebCore/platform/network/BlobResourceHandle.cpp3
-rw-r--r--WebCore/platform/network/BlobResourceHandle.h2
-rw-r--r--WebCore/platform/network/FormData.cpp132
-rw-r--r--WebCore/platform/network/FormData.h18
-rw-r--r--WebCore/platform/network/mac/FormDataStreamMac.mm56
-rw-r--r--WebCore/platform/qt/FileSystemQt.cpp27
-rw-r--r--WebCore/platform/qt/ScrollbarQt.cpp12
-rw-r--r--WebCore/platform/win/PasteboardWin.cpp9
-rw-r--r--WebCore/platform/win/ScrollbarThemeWin.cpp5
-rw-r--r--WebCore/platform/win/SoftLinking.h10
-rw-r--r--WebCore/platform/win/SystemInfo.cpp4
142 files changed, 5030 insertions, 1752 deletions
diff --git a/WebCore/platform/AsyncFileSystem.cpp b/WebCore/platform/AsyncFileSystem.cpp
new file mode 100644
index 0000000..b4fcd0d
--- /dev/null
+++ b/WebCore/platform/AsyncFileSystem.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 "AsyncFileSystem.h"
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "AsyncFileSystemCallbacks.h"
+#include "FileSystem.h"
+
+namespace WebCore {
+
+PassOwnPtr<AsyncFileSystem> AsyncFileSystem::create(const String&)
+{
+ // FIXME: return default AsyncFileSystem implementation.
+ return 0;
+}
+
+// Default implementation.
+void AsyncFileSystem::openFileSystem(const String& basePath, const String& storageIdentifier, Type type, PassOwnPtr<AsyncFileSystemCallbacks> callbacks)
+{
+ String typeString = (type == Persistent) ? "Persistent" : "Temporary";
+
+ String name = storageIdentifier;
+ name += ":";
+ name += typeString;
+
+ String rootPath = basePath;
+ rootPath.append(PlatformFilePathSeparator);
+ rootPath += storageIdentifier;
+ rootPath.append(PlatformFilePathSeparator);
+ rootPath += typeString;
+ rootPath.append(PlatformFilePathSeparator);
+
+ callbacks->didOpenFileSystem(name, AsyncFileSystem::create(rootPath));
+}
+
+// Default implementation.
+String AsyncFileSystem::virtualToPlatformPath(const String& path) const
+{
+ ASSERT(!m_platformRootPath.isEmpty());
+ String virtualPath = path;
+ return m_platformRootPath + virtualPath.replace('/', PlatformFilePathSeparator);
+}
+
+} // namespace
+
+#endif // ENABLE(FILE_SYSTEM)
diff --git a/WebCore/platform/AsyncFileSystem.h b/WebCore/platform/AsyncFileSystem.h
new file mode 100644
index 0000000..601f0ea
--- /dev/null
+++ b/WebCore/platform/AsyncFileSystem.h
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+#ifndef AsyncFileSystem_h
+#define AsyncFileSystem_h
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "PlatformString.h"
+#include "Timer.h"
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class AsyncFileSystem;
+class AsyncFileSystemCallbacks;
+
+// This class provides async interface for platform-specific file system implementation. Note that all the methods take platform paths.
+class AsyncFileSystem : public Noncopyable {
+public:
+ virtual ~AsyncFileSystem() { }
+
+ // FileSystem type
+ enum Type {
+ Temporary,
+ Persistent,
+ };
+
+ virtual void stop() { }
+ virtual bool hasPendingActivity() { return false; }
+
+ // Creates and returns a new platform-specific AsyncFileSystem instance if the platform has its own implementation.
+ static PassOwnPtr<AsyncFileSystem> create(const String& rootPath);
+
+ // Opens a new file system.
+ static void openFileSystem(const String& basePath, const String& storageIdentifier, Type, PassOwnPtr<AsyncFileSystemCallbacks>);
+
+ // Moves a file or directory from srcPath to destPath.
+ // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void move(const String& srcPath, const String& destPath, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Copies a file or directory from srcPath to destPath.
+ // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void copy(const String& srcPath, const String& destPath, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Deletes a file or directory at a given path.
+ // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void remove(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Retrieves the metadata information of the file or directory at a given path.
+ // AsyncFileSystemCallbacks::didReadMetadata() is called when the operation is completed successfully.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void readMetadata(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Creates a file at a given path. If exclusive flag is true, it fails if the path already exists.
+ // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void createFile(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Creates a directory at a given path. If exclusive flag is true, it fails if the path already exists.
+ // AsyncFileSystemCallbacks::didSucceed() is called when the operation is completed successfully.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void createDirectory(const String& path, bool exclusive, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Checks if a file exists at a given path.
+ // AsyncFileSystemCallbacks::didSucceed() is called if the file exists.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void fileExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Checks if a directory exists at a given path.
+ // AsyncFileSystemCallbacks::didSucceed() is called if the directory exists.
+ // AsyncFileSystemCallbacks::didFail() is called otherwise.
+ virtual void directoryExists(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Reads directory entries of a given directory at path.
+ // AsyncFileSystemCallbacks::didReadDirectoryEntry() is called when each directory entry is called. AsyncFileSystemCallbacks::didReadDirectoryEntries() is called after a chunk of directory entries have been read.
+ // AsyncFileSystemCallbacks::didFail() is when there is an error.
+ virtual void readDirectory(const String& path, PassOwnPtr<AsyncFileSystemCallbacks>) = 0;
+
+ // Converts a given absolute virtual path to a platform path that starts with the platform root path of this file system.
+ virtual String virtualToPlatformPath(const String& path) const;
+
+protected:
+ AsyncFileSystem(const String& platformRootPath)
+ : m_platformRootPath(platformRootPath)
+ {
+ }
+
+ String m_platformRootPath;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(FILE_SYSTEM)
+
+#endif // AsyncFileSystem_h
diff --git a/WebCore/platform/AsyncFileSystemCallbacks.h b/WebCore/platform/AsyncFileSystemCallbacks.h
new file mode 100644
index 0000000..0547fad
--- /dev/null
+++ b/WebCore/platform/AsyncFileSystemCallbacks.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#ifndef AsyncFileSystemCallbacks_h
+#define AsyncFileSystemCallbacks_h
+
+#if ENABLE(FILE_SYSTEM)
+
+#include "PlatformString.h"
+
+namespace WebCore {
+
+class AsyncFileSystem;
+
+class AsyncFileSystemCallbacks : public Noncopyable {
+public:
+ // Called when a requested operation is completed successfully.
+ virtual void didSucceed() = 0;
+
+ // Called when a requested file system is opened.
+ virtual void didOpenFileSystem(const String& name, PassOwnPtr<AsyncFileSystem>) = 0;
+
+ // Called when a file metadata is read successfully.
+ virtual void didReadMetadata(double modificationTime) = 0;
+
+ // Called when a directory entry is read.
+ virtual void didReadDirectoryEntry(const String& name, bool isDirectory) = 0;
+
+ // Called after a chunk of directory entries have been read (i.e. indicates it's good time to call back to the application). If hasMore is true there can be more chunks.
+ virtual void didReadDirectoryEntries(bool hasMore) = 0;
+
+ // Called when there was an error.
+ virtual void didFail(int code) = 0;
+
+ virtual ~AsyncFileSystemCallbacks() { }
+};
+
+} // namespace
+
+#endif // ENABLE(FILE_SYSTEM)
+
+#endif // AsyncFileSystemCallbacks_h
diff --git a/WebCore/platform/BlobItem.cpp b/WebCore/platform/BlobItem.cpp
deleted file mode 100644
index 591516d..0000000
--- a/WebCore/platform/BlobItem.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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 "BlobItem.h"
-
-#include "FileSystem.h"
-#include "UUID.h"
-#include <wtf/Assertions.h>
-
-namespace WebCore {
-
-#if ENABLE(BLOB)
-static const double invalidModificationTime = 0;
-
-static double getFileSnapshotModificationTime(const String& path)
-{
- // FIXME: synchronized file call
- time_t modificationTime;
- if (getFileModificationTime(path, modificationTime))
- return static_cast<double>(modificationTime);
- return invalidModificationTime;
-}
-#endif // ENABLE(BLOB)
-
-// DataBlobItem ----------------------------------------------------------------
-
-#if ENABLE(BLOB)
-PassRefPtr<BlobItem> DataBlobItem::slice(long long start, long long length)
-{
- ASSERT(start >= 0 && length >= 0);
- ASSERT(static_cast<unsigned long long>(start) < size());
- if (!start && size() <= static_cast<unsigned long long>(length))
- return this;
- if (static_cast<unsigned long long>(start + length) > size())
- length = size() - start;
- return DataRangeBlobItem::create(this, start, length);
-}
-#endif
-
-// FileBlobItem ----------------------------------------------------------------
-
-PassRefPtr<BlobItem> FileBlobItem::create(const String& path)
-{
- return adoptRef(static_cast<BlobItem*>(new FileBlobItem(path)));
-}
-
-FileBlobItem::FileBlobItem(const String& path)
- : m_path(path)
- , m_fileName(pathGetFileName(m_path))
-{
-}
-
-#if ENABLE(DIRECTORY_UPLOAD)
-PassRefPtr<BlobItem> FileBlobItem::create(const String& path, const String& relativePath)
-{
- return adoptRef(static_cast<BlobItem*>(new FileBlobItem(path, relativePath)));
-}
-
-FileBlobItem::FileBlobItem(const String& path, const String& relativePath)
- : m_path(path)
- , m_fileName(pathGetFileName(m_path))
- , m_relativePath(relativePath)
-{
-}
-#endif
-
-unsigned long long FileBlobItem::size() const
-{
- // FIXME: synchronized file call
- long long size;
- if (!getFileSize(m_path, size))
- return 0;
- return static_cast<unsigned long long>(size);
-}
-
-#if ENABLE(BLOB)
-PassRefPtr<BlobItem> FileBlobItem::slice(long long start, long long length)
-{
- ASSERT(start >= 0 && length >= 0);
- long long fileSize = size();
- ASSERT(start < fileSize);
- if (!start && fileSize <= length)
- return this;
- if (start + length > fileSize)
- length = fileSize - start;
- const FileRangeBlobItem* fileRangeItem = toFileRangeBlobItem();
- double modificationTime = fileRangeItem ? fileRangeItem->snapshotModificationTime() : getFileSnapshotModificationTime(path());
- return FileRangeBlobItem::create(path(), start, length, modificationTime);
-}
-#endif // ENABLE(BLOB)
-
-// StringBlobItem --------------------------------------------------------------
-
-PassRefPtr<BlobItem> StringBlobItem::create(const CString& text)
-{
- return adoptRef(static_cast<BlobItem*>(new StringBlobItem(text)));
-}
-
-StringBlobItem::StringBlobItem(const CString& text)
- : m_data(text)
-{
-}
-
-// ByteArrayBlobItem ----------------------------------------------------------
-
-PassRefPtr<BlobItem> ByteArrayBlobItem::create(const char* data, size_t size)
-{
- return adoptRef(static_cast<BlobItem*>(new ByteArrayBlobItem(data, size)));
-}
-
-ByteArrayBlobItem::ByteArrayBlobItem(const char* data, size_t size)
-{
- m_bytesArray.append(data, size);
-}
-
-#if ENABLE(BLOB)
-
-// DataRangeBlobItem -----------------------------------------------------------
-
-PassRefPtr<BlobItem> DataRangeBlobItem::create(PassRefPtr<DataBlobItem> item, long long start, long long length)
-{
- return adoptRef(static_cast<BlobItem*>(new DataRangeBlobItem(item, start, length)));
-}
-
-DataRangeBlobItem::DataRangeBlobItem(PassRefPtr<DataBlobItem> item, long long start, long long length)
- : m_length(length)
-{
- const DataRangeBlobItem* rangeItem = item->toDataRangeBlobItem();
- if (rangeItem) {
- m_item = rangeItem->m_item;
- m_start = start + rangeItem->m_start;
- ASSERT(!m_item->toDataRangeBlobItem());
- ASSERT(static_cast<unsigned long long>(m_start + m_length) <= m_item->size());
- } else {
- m_item = item;
- m_start = start;
- }
-}
-
-const char* DataRangeBlobItem::data() const
-{
- return m_item->data() + m_start;
-}
-
-// FileRangeBlobItem -----------------------------------------------------------
-
-PassRefPtr<BlobItem> FileRangeBlobItem::create(const String& path, long long start, long long length, double snapshotModificationTime)
-{
- return adoptRef(static_cast<BlobItem*>(new FileRangeBlobItem(path, start, length, snapshotModificationTime)));
-}
-
-FileRangeBlobItem::FileRangeBlobItem(const String& path, long long start, long long length, double modificationTime)
- : FileBlobItem(path)
- , m_start(start)
- , m_length(length)
- , m_snapshotModificationTime(modificationTime)
-{
- m_uniqueName = "Blob" + createCanonicalUUIDString();
- m_uniqueName.replace("-", ""); // For safty, remove '-' from the filename snce some servers may not like it.
-}
-
-#endif // ENABLE(BLOB)
-
-} // namespace WebCore
diff --git a/WebCore/platform/BlobItem.h b/WebCore/platform/BlobItem.h
deleted file mode 100644
index 42ece92..0000000
--- a/WebCore/platform/BlobItem.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef BlobItem_h
-#define BlobItem_h
-
-#include "PlatformString.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassRefPtr.h>
-#include <wtf/RefCounted.h>
-#include <wtf/Vector.h>
-#include <wtf/text/CString.h>
-
-namespace WebCore {
-
-class ByteArrayBlobItem;
-class DataBlobItem;
-class DataRangeBlobItem;
-class FileBlobItem;
-class FileRangeBlobItem;
-class StringBlobItem;
-
-// A base interface for all arbitrary-data-object component items.
-// The BlobItem and its subclasses are structured like the following:
-// BlobItem
-// |
-// +-------> DataBlobItem
-// | |
-// | +---------> StringBlobItem
-// | +---------> ByteArrayBlobItem
-// | +---------> DataRangeBlobItem
-// |
-// +-------> FileBlobItem
-// |
-// +---------> FileRangeBlobItem
-//
-class BlobItem : public RefCounted<BlobItem> {
-public:
- virtual ~BlobItem() { }
- virtual unsigned long long size() const = 0;
-
- virtual const DataBlobItem* toDataBlobItem() const { return 0; }
- virtual const StringBlobItem* toStringBlobItem() const { return 0; }
- virtual const ByteArrayBlobItem* toByteArrayBlobItem() const { return 0; }
- virtual const FileBlobItem* toFileBlobItem() const { return 0; }
-#if ENABLE(BLOB)
- virtual const DataRangeBlobItem* toDataRangeBlobItem() const { return 0; }
- virtual const FileRangeBlobItem* toFileRangeBlobItem() const { return 0; }
-
- // Note: no external methods except for Blob::slice should call this.
- virtual PassRefPtr<BlobItem> slice(long long start, long long length) = 0;
-#endif // ENABLE(BLOB)
-
-protected:
- BlobItem() { }
-};
-
-typedef Vector<RefPtr<BlobItem> > BlobItemList;
-
-class DataBlobItem : public BlobItem {
-public:
- virtual const char* data() const = 0;
-
- // BlobItem methods.
- virtual const DataBlobItem* toDataBlobItem() const { return this; }
-#if ENABLE(BLOB)
- virtual PassRefPtr<BlobItem> slice(long long start, long long length);
-#endif // ENABLE(BLOB)
-};
-
-class FileBlobItem : public BlobItem {
-public:
- static PassRefPtr<BlobItem> create(const String& path);
-#if ENABLE(DIRECTORY_UPLOAD)
- static PassRefPtr<BlobItem> create(const String& path, const String& relativePath);
-#endif
- virtual const String& name() const { return m_fileName; }
- virtual const String& path() const { return m_path; }
-#if ENABLE(DIRECTORY_UPLOAD)
- const String& relativePath() const { return m_relativePath; }
-#endif
-
- // BlobItem methods.
- virtual unsigned long long size() const;
- virtual const FileBlobItem* toFileBlobItem() const { return this; }
-#if ENABLE(BLOB)
- virtual PassRefPtr<BlobItem> slice(long long start, long long length);
-#endif // ENABLE(BLOB)
-
-protected:
- FileBlobItem(const String& path);
-#if ENABLE(DIRECTORY_UPLOAD)
- FileBlobItem(const String& path, const String& relativePath);
-#endif
- String m_path;
- String m_fileName;
-#if ENABLE(DIRECTORY_UPLOAD)
- String m_relativePath;
-#endif
-};
-
-class StringBlobItem : public DataBlobItem {
-public:
- static PassRefPtr<BlobItem> create(const CString&);
- const CString& cstr() const { return m_data; }
-
- // BlobItem methods.
- virtual unsigned long long size() const { return m_data.length(); }
- virtual const StringBlobItem* toStringBlobItem() const { return this; }
-
- // DataBlobItem methods.
- virtual const char* data() const { return m_data.data(); }
-
-private:
- StringBlobItem(const CString&);
- CString m_data;
-};
-
-class ByteArrayBlobItem : public DataBlobItem {
-public:
- static PassRefPtr<BlobItem> create(const char* data, size_t size);
-
- // BlobItem methods.
- virtual unsigned long long size() const { return m_bytesArray.size(); }
- virtual const ByteArrayBlobItem* toByteArrayBlobItem() const { return this; }
-
- // DataBlobItem methods.
- virtual const char* data() const { return m_bytesArray.data(); }
-
-private:
- ByteArrayBlobItem(const char* data, size_t size);
- Vector<char> m_bytesArray;
-};
-
-#if ENABLE(BLOB)
-
-// BlobItem class for sliced data (string or bytes-array).
-class DataRangeBlobItem : public DataBlobItem {
-public:
- static PassRefPtr<BlobItem> create(PassRefPtr<DataBlobItem>, long long start, long long length);
-
- // BlobItem methods.
- virtual unsigned long long size() const { return m_length; }
- virtual const DataRangeBlobItem* toDataRangeBlobItem() const { return this; }
-
- // DataBlobItem methods.
- virtual const char* data() const;
-
-private:
- DataRangeBlobItem(PassRefPtr<DataBlobItem>, long long start, long long length);
- RefPtr<DataBlobItem> m_item;
- long long m_start;
- long long m_length;
-};
-
-class FileRangeBlobItem : public FileBlobItem {
-public:
- static PassRefPtr<BlobItem> create(const String& path, long long start, long long length, double snapshotModificationTime);
- long long start() const { return m_start; }
- double snapshotModificationTime() const { return m_snapshotModificationTime; }
-
- // BlobItem methods.
- virtual unsigned long long size() const { return m_length; }
- virtual const FileRangeBlobItem* toFileRangeBlobItem() const { return this; }
-
- // FileBlobItem methods.
- virtual const String& name() const { return m_uniqueName; }
-
-private:
- FileRangeBlobItem(const String& path, long long start, long long length, double snapshotModificationTime);
- long long m_start;
- long long m_length;
- String m_uniqueName;
-
- double m_snapshotModificationTime;
-};
-
-#endif // ENABLE(BLOB)
-
-} // namespace WebCore
-
-#endif // BlobItem_h
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index ec75a21..e3916cf 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -138,6 +138,12 @@ enum FileSeekOrigin {
SeekFromEnd
};
+#if OS(WINDOWS)
+static const char PlatformFilePathSeparator = '\\';
+#else
+static const char PlatformFilePathSeparator = '/';
+#endif
+
bool fileExists(const String&);
bool deleteFile(const String&);
bool deleteEmptyDirectory(const String&);
diff --git a/WebCore/platform/Length.h b/WebCore/platform/Length.h
index a3b1eda..7dd875e 100644
--- a/WebCore/platform/Length.h
+++ b/WebCore/platform/Length.h
@@ -30,6 +30,8 @@ namespace WebCore {
const int undefinedLength = -1;
const int percentScaleFactor = 128;
+const int intMaxForLength = 0x7ffffff; // max value for a 28-bit int
+const int intMinForLength = (-0x7ffffff - 1); // min value for a 28-bit int
enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic };
diff --git a/WebCore/platform/MIMETypeRegistry.cpp b/WebCore/platform/MIMETypeRegistry.cpp
index b489d3b..5c20e08 100644
--- a/WebCore/platform/MIMETypeRegistry.cpp
+++ b/WebCore/platform/MIMETypeRegistry.cpp
@@ -279,6 +279,10 @@ static MediaMIMETypeMap& mediaMIMETypeMap()
{ "video/annodex", "axv" },
{ "audio/speex", "spx" },
+ // WebM
+ { "video/webm", "webm" },
+ { "audio/webm", "webm" },
+
// MPEG
{ "audio/mpeg", "m1a" },
{ "audio/mpeg", "m2a" },
diff --git a/WebCore/platform/PurgeableBuffer.h b/WebCore/platform/PurgeableBuffer.h
index 3caf482..32341c2 100644
--- a/WebCore/platform/PurgeableBuffer.h
+++ b/WebCore/platform/PurgeableBuffer.h
@@ -63,7 +63,7 @@ namespace WebCore {
mutable State m_state;
};
-#if !OS(DARWIN) || defined(BUILDING_ON_TIGER) || PLATFORM(QT) || PLATFORM(GTK)
+#if !ENABLE(PURGEABLE_MEMORY)
inline PassOwnPtr<PurgeableBuffer> PurgeableBuffer::create(const char*, size_t) { return PassOwnPtr<PurgeableBuffer>(); }
inline PurgeableBuffer::~PurgeableBuffer() { }
inline const char* PurgeableBuffer::data() const { return 0; }
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index 927a9fc..854fef5 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -699,7 +699,7 @@ void ScrollView::wheelEvent(PlatformWheelEvent& e)
if (e.granularity() == ScrollByPageWheelEvent) {
ASSERT(deltaX == 0);
bool negative = deltaY < 0;
- deltaY = max(max<int>(visibleHeight() * Scrollbar::minFractionToStepWhenPaging(), visibleHeight() - Scrollbar::maxOverlapBetweenPages()), 1);
+ deltaY = max(max(static_cast<float>(visibleHeight()) * Scrollbar::minFractionToStepWhenPaging(), static_cast<float>(visibleHeight() - Scrollbar::maxOverlapBetweenPages())), 1.0f);
if (negative)
deltaY = -deltaY;
}
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 6853969..5624d70 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -57,7 +57,7 @@ class ScrollView : public Widget, public ScrollbarClient {
public:
~ScrollView();
- // ScrollbarClient function. FrameView overrides the other two.
+ // ScrollbarClient function. FrameView overrides the others.
virtual void valueChanged(Scrollbar*);
// The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
diff --git a/WebCore/platform/Scrollbar.cpp b/WebCore/platform/Scrollbar.cpp
index 119a9dc..ff8f66f 100644
--- a/WebCore/platform/Scrollbar.cpp
+++ b/WebCore/platform/Scrollbar.cpp
@@ -142,24 +142,20 @@ bool Scrollbar::scroll(ScrollDirection direction, ScrollGranularity granularity,
}
#endif
+ // Ignore perpendicular scrolls.
+ if ((m_orientation == HorizontalScrollbar) ? (direction == ScrollUp || direction == ScrollDown) : (direction == ScrollLeft || direction == ScrollRight))
+ return false;
float step = 0;
- if ((direction == ScrollUp && m_orientation == VerticalScrollbar) || (direction == ScrollLeft && m_orientation == HorizontalScrollbar))
- step = -1;
- else if ((direction == ScrollDown && m_orientation == VerticalScrollbar) || (direction == ScrollRight && m_orientation == HorizontalScrollbar))
- step = 1;
-
- if (granularity == ScrollByLine)
- step *= m_lineStep;
- else if (granularity == ScrollByPage)
- step *= m_pageStep;
- else if (granularity == ScrollByDocument)
- step *= m_totalSize;
- else if (granularity == ScrollByPixel)
- step *= m_pixelStep;
-
- float newPos = m_currentPos + step * multiplier;
- float maxPos = m_totalSize - m_visibleSize;
- return setCurrentPos(max(min(newPos, maxPos), 0.0f));
+ switch (granularity) {
+ case ScrollByLine: step = m_lineStep; break;
+ case ScrollByPage: step = m_pageStep; break;
+ case ScrollByDocument: step = m_totalSize; break;
+ case ScrollByPixel: step = m_pixelStep; break;
+ }
+ if (direction == ScrollUp || direction == ScrollLeft)
+ multiplier = -multiplier;
+
+ return setCurrentPos(max(min(m_currentPos + (step * multiplier), static_cast<float>(m_totalSize - m_visibleSize)), 0.0f));
}
void Scrollbar::updateThumb()
diff --git a/WebCore/platform/Scrollbar.h b/WebCore/platform/Scrollbar.h
index 6b3cd0d..f8ef96d 100644
--- a/WebCore/platform/Scrollbar.h
+++ b/WebCore/platform/Scrollbar.h
@@ -79,7 +79,7 @@ public:
void setProportion(int visibleSize, int totalSize);
void setPressedPos(int p) { m_pressedPos = p; }
- bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1.0f);
+ bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
virtual void paint(GraphicsContext*, const IntRect& damageRect);
@@ -124,9 +124,6 @@ public:
virtual IntPoint convertToContainingView(const IntPoint&) const;
virtual IntPoint convertFromContainingView(const IntPoint&) const;
-private:
- virtual bool isScrollbar() const { return true; }
-
protected:
Scrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize, ScrollbarTheme* = 0);
@@ -142,7 +139,6 @@ protected:
ScrollGranularity pressedPartScrollGranularity();
void moveThumb(int pos);
- bool setCurrentPos(float pos);
ScrollbarClient* m_client;
ScrollbarOrientation m_orientation;
@@ -167,6 +163,11 @@ protected:
bool m_overlapsResizer;
bool m_suppressInvalidation;
+
+private:
+ virtual bool isScrollbar() const { return true; }
+
+ bool setCurrentPos(float pos);
};
}
diff --git a/WebCore/platform/ScrollbarClient.h b/WebCore/platform/ScrollbarClient.h
index 6efe72e..fa94ecc 100644
--- a/WebCore/platform/ScrollbarClient.h
+++ b/WebCore/platform/ScrollbarClient.h
@@ -34,7 +34,7 @@ namespace WebCore {
class ScrollbarClient {
public:
- virtual ~ScrollbarClient() {}
+ virtual ~ScrollbarClient() { }
virtual void valueChanged(Scrollbar*) = 0;
virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
diff --git a/WebCore/platform/ThemeTypes.h b/WebCore/platform/ThemeTypes.h
index d82aa73..3567004 100644
--- a/WebCore/platform/ThemeTypes.h
+++ b/WebCore/platform/ThemeTypes.h
@@ -51,7 +51,7 @@ enum ControlPart {
MediaFullscreenButtonPart, MediaMuteButtonPart, MediaPlayButtonPart, MediaSeekBackButtonPart,
MediaSeekForwardButtonPart, MediaRewindButtonPart, MediaReturnToRealtimeButtonPart, MediaToggleClosedCaptionsButtonPart,
MediaSliderPart, MediaSliderThumbPart, MediaVolumeSliderContainerPart, MediaVolumeSliderPart, MediaVolumeSliderThumbPart,
- MediaVolumeSliderMuteButtonPart, MediaControlsBackgroundPart, MediaCurrentTimePart, MediaTimeRemainingPart,
+ MediaVolumeSliderMuteButtonPart, MediaControlsBackgroundPart, MediaControlsFullscreenBackgroundPart, MediaCurrentTimePart, MediaTimeRemainingPart,
MenulistPart, MenulistButtonPart, MenulistTextPart, MenulistTextFieldPart, MeterPart, OuterSpinButtonPart, ProgressBarPart, ProgressBarValuePart,
SliderHorizontalPart, SliderVerticalPart, SliderThumbHorizontalPart,
SliderThumbVerticalPart, CaretPart, SearchFieldPart, SearchFieldDecorationPart,
diff --git a/WebCore/platform/TreeShared.h b/WebCore/platform/TreeShared.h
index 6e60656..9d9ac1f 100644
--- a/WebCore/platform/TreeShared.h
+++ b/WebCore/platform/TreeShared.h
@@ -34,11 +34,11 @@ template<typename T> void adopted(TreeShared<T>*);
template<typename T> class TreeShared : public Noncopyable {
public:
- TreeShared(int initialRefCount = 1)
- : m_refCount(initialRefCount)
+ TreeShared()
+ : m_refCount(1)
, m_parent(0)
#ifndef NDEBUG
- , m_adoptionIsRequired(initialRefCount == 1)
+ , m_adoptionIsRequired(true)
#endif
{
ASSERT(isMainThread());
diff --git a/WebCore/platform/audio/Cone.cpp b/WebCore/platform/audio/Cone.cpp
new file mode 100644
index 0000000..91813ab
--- /dev/null
+++ b/WebCore/platform/audio/Cone.cpp
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "Cone.h"
+
+namespace WebCore {
+
+ConeEffect::ConeEffect()
+ : m_innerAngle(360.0)
+ , m_outerAngle(360.0)
+ , m_outerGain(0.0)
+{
+}
+
+double ConeEffect::gain(Vector3 sourcePosition, Vector3 sourceOrientation, Vector3 listenerPosition)
+{
+ if (sourceOrientation.isZero() || ((m_innerAngle == 360.0) && (m_outerAngle == 360.0)))
+ return 1.0; // no cone specified - unity gain
+
+ // Normalized source-listener vector
+ Vector3 sourceToListener = listenerPosition - sourcePosition;
+ sourceToListener.normalize();
+
+ Vector3 normalizedSourceOrientation = sourceOrientation;
+ normalizedSourceOrientation.normalize();
+
+ // Angle between the source orientation vector and the source-listener vector
+ double dotProduct = dot(sourceToListener, normalizedSourceOrientation);
+ double angle = 180.0 * acos(dotProduct) / M_PI;
+ double absAngle = fabs(angle);
+
+ // Divide by 2.0 here since API is entire angle (not half-angle)
+ double absInnerAngle = fabs(m_innerAngle) / 2.0;
+ double absOuterAngle = fabs(m_outerAngle) / 2.0;
+ double gain = 1.0;
+
+ if (absAngle <= absInnerAngle)
+ // No attenuation
+ gain = 1.0;
+ else if (absAngle >= absOuterAngle)
+ // Max attenuation
+ gain = m_outerGain;
+ else {
+ // Between inner and outer cones
+ // inner -> outer, x goes from 0 -> 1
+ double x = (absAngle - absInnerAngle) / (absOuterAngle - absInnerAngle);
+ gain = (1.0 - x) + m_outerGain * x;
+ }
+
+ return gain;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/Cone.h b/WebCore/platform/audio/Cone.h
new file mode 100644
index 0000000..9936f28
--- /dev/null
+++ b/WebCore/platform/audio/Cone.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 Cone_h
+#define Cone_h
+
+#include <wtf/Vector3.h>
+
+namespace WebCore {
+
+// Cone gain is defined according to the OpenAL specification
+
+class ConeEffect {
+public:
+ ConeEffect();
+
+ // Returns scalar gain for the given source/listener positions/orientations
+ double gain(Vector3 sourcePosition, Vector3 sourceOrientation, Vector3 listenerPosition);
+
+ // Angles in degrees
+ void setInnerAngle(double innerAngle) { m_innerAngle = innerAngle; }
+ double innerAngle() const { return m_innerAngle; }
+
+ void setOuterAngle(double outerAngle) { m_outerAngle = outerAngle; }
+ double outerAngle() const { return m_outerAngle; }
+
+ void setOuterGain(double outerGain) { m_outerGain = outerGain; }
+ double outerGain() const { return m_outerGain; }
+
+protected:
+ double m_innerAngle;
+ double m_outerAngle;
+ double m_outerGain;
+};
+
+} // namespace WebCore
+
+#endif // Cone_h
diff --git a/WebCore/platform/audio/FFTConvolver.cpp b/WebCore/platform/audio/FFTConvolver.cpp
new file mode 100644
index 0000000..b0211fd
--- /dev/null
+++ b/WebCore/platform/audio/FFTConvolver.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "FFTConvolver.h"
+
+#include "Accelerate.h"
+
+namespace WebCore {
+
+FFTConvolver::FFTConvolver(size_t fftSize)
+ : m_frame(fftSize)
+ , m_readWriteIndex(0)
+ , m_inputBuffer(fftSize) // 2nd half of buffer is always zeroed
+ , m_outputBuffer(fftSize)
+ , m_lastOverlapBuffer(fftSize / 2)
+{
+}
+
+void FFTConvolver::process(FFTFrame* fftKernel, float* sourceP, float* destP, size_t framesToProcess)
+{
+ // FIXME: make so framesToProcess is not required to fit evenly into fftSize/2
+
+ // Copy samples to input buffer (note contraint above!)
+ float* inputP = m_inputBuffer.data();
+
+ // Sanity check
+ bool isCopyGood1 = sourceP && inputP && m_readWriteIndex + framesToProcess <= m_inputBuffer.size();
+ ASSERT(isCopyGood1);
+ if (!isCopyGood1)
+ return;
+
+ memcpy(inputP + m_readWriteIndex, sourceP, sizeof(float) * framesToProcess);
+
+ // Copy samples from output buffer
+ float* outputP = m_outputBuffer.data();
+
+ // Sanity check
+ bool isCopyGood2 = destP && outputP && m_readWriteIndex + framesToProcess <= m_outputBuffer.size();
+ ASSERT(isCopyGood2);
+ if (!isCopyGood2)
+ return;
+
+ memcpy(destP, outputP + m_readWriteIndex, sizeof(float) * framesToProcess);
+ m_readWriteIndex += framesToProcess;
+
+
+ // Check if it's time to perform the next FFT
+ size_t halfSize = fftSize() / 2;
+ if (m_readWriteIndex == halfSize) {
+ // The input buffer is now filled (get frequency-domain version)
+ m_frame.doFFT(m_inputBuffer.data());
+ m_frame.multiply(*fftKernel);
+ m_frame.doInverseFFT(m_outputBuffer.data());
+
+ // Overlap-add 1st half from previous time
+ vadd(m_outputBuffer.data(), 1, m_lastOverlapBuffer.data(), 1, m_outputBuffer.data(), 1, halfSize);
+
+ // Finally, save 2nd half of result
+ bool isCopyGood3 = m_outputBuffer.size() == 2 * halfSize && m_lastOverlapBuffer.size() == halfSize;
+ ASSERT(isCopyGood3);
+ if (!isCopyGood3)
+ return;
+
+ memcpy(m_lastOverlapBuffer.data(), m_outputBuffer.data() + halfSize, sizeof(float) * halfSize);
+
+ // Reset index back to start for next time
+ m_readWriteIndex = 0;
+ }
+}
+
+void FFTConvolver::reset()
+{
+ m_lastOverlapBuffer.zero();
+ m_readWriteIndex = 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/FFTConvolver.h b/WebCore/platform/audio/FFTConvolver.h
new file mode 100644
index 0000000..0eec7c1
--- /dev/null
+++ b/WebCore/platform/audio/FFTConvolver.h
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 FFTConvolver_h
+#define FFTConvolver_h
+
+#include "AudioFloatArray.h"
+#include "FFTFrame.h"
+
+namespace WebCore {
+
+class FFTConvolver {
+public:
+ // fftSize must be a power of two
+ FFTConvolver(size_t fftSize);
+
+ // For now, with multiple calls to Process(), framesToProcess MUST add up EXACTLY to fftSize / 2
+ //
+ // FIXME: Later, we can do more sophisticated buffering to relax this requirement...
+ //
+ // The input to output latency is equal to fftSize / 2
+ //
+ // Processing in-place is allowed...
+ void process(FFTFrame* fftKernel, float* sourceP, float* destP, size_t framesToProcess);
+
+ void reset();
+
+ size_t fftSize() const { return m_frame.fftSize(); }
+
+private:
+ FFTFrame m_frame;
+
+ // Buffer input until we get fftSize / 2 samples then do an FFT
+ size_t m_readWriteIndex;
+ AudioFloatArray m_inputBuffer;
+
+ // Stores output which we read a little at a time
+ AudioFloatArray m_outputBuffer;
+
+ // Saves the 2nd half of the FFT buffer, so we can do an overlap-add with the 1st half of the next one
+ AudioFloatArray m_lastOverlapBuffer;
+};
+
+} // namespace WebCore
+
+#endif // FFTConvolver_h
diff --git a/WebCore/platform/audio/Reverb.cpp b/WebCore/platform/audio/Reverb.cpp
new file mode 100644
index 0000000..886a553
--- /dev/null
+++ b/WebCore/platform/audio/Reverb.cpp
@@ -0,0 +1,227 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "Reverb.h"
+
+#include "AudioBus.h"
+#include "AudioFileReader.h"
+#include "ReverbConvolver.h"
+#include <math.h>
+#include <wtf/MathExtras.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+#if OS(DARWIN)
+using namespace std;
+#endif
+
+namespace WebCore {
+
+// Empirical gain calibration tested across many impulse responses to ensure perceived volume is same as dry (unprocessed) signal
+const double GainCalibration = -58.0;
+
+// A minimum power value to when normalizing a silent (or very quiet) impulse response
+const double MinPower = 0.000125;
+
+static double calculateNormalizationScale(AudioBus* response)
+{
+ // Normalize by RMS power
+ size_t numberOfChannels = response->numberOfChannels();
+ size_t frameSize = response->frameSize();
+
+ double power = 0.0;
+
+ for (size_t i = 0; i < numberOfChannels; ++i) {
+ int n = frameSize;
+ float* p = response->channel(i)->data();
+
+ while (n--) {
+ float sample = *p++;
+ power += sample * sample;
+ }
+ }
+
+ power = sqrt(power / (numberOfChannels * frameSize));
+
+ // Protect against accidental overload
+ if (isinf(power) || isnan(power) || power < MinPower)
+ power = MinPower;
+
+ double scale = 1.0 / power;
+
+ scale *= pow(10.0, GainCalibration * 0.05); // calibrate to make perceived volume same as unprocessed
+
+ // True-stereo compensation
+ if (response->numberOfChannels() == 4)
+ scale *= 0.5;
+
+ return scale;
+}
+
+Reverb::Reverb(AudioBus* impulseResponse, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads)
+{
+ double scale = calculateNormalizationScale(impulseResponse);
+ if (scale)
+ impulseResponse->scale(scale);
+
+ initialize(impulseResponse, renderSliceSize, maxFFTSize, numberOfChannels, useBackgroundThreads);
+
+ // Undo scaling since this shouldn't be a destructive operation on impulseResponse
+ if (scale)
+ impulseResponse->scale(1.0 / scale);
+}
+
+void Reverb::initialize(AudioBus* impulseResponseBuffer, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads)
+{
+ m_impulseResponseLength = impulseResponseBuffer->frameSize();
+
+ // The reverb can handle a mono impulse response and still do stereo processing
+ size_t numResponseChannels = impulseResponseBuffer->numberOfChannels();
+ m_convolvers.reserveCapacity(numberOfChannels);
+
+ int convolverRenderPhase = 0;
+ for (size_t i = 0; i < numResponseChannels; ++i) {
+ AudioChannel* channel = impulseResponseBuffer->channel(i);
+
+ ReverbConvolver* convolver = new ReverbConvolver(channel, renderSliceSize, maxFFTSize, convolverRenderPhase, useBackgroundThreads);
+ m_convolvers.append(convolver);
+
+ convolverRenderPhase += renderSliceSize;
+ }
+
+ // For "True" stereo processing we allocate a temporary buffer to avoid repeatedly allocating it in the process() method.
+ // It can be bad to allocate memory in a real-time thread.
+ if (numResponseChannels == 4)
+ m_tempBuffer = new AudioBus(2, MaxFrameSize);
+}
+
+void Reverb::process(AudioBus* sourceBus, AudioBus* destinationBus, size_t framesToProcess)
+{
+ // Do a fairly comprehensive sanity check.
+ // If these conditions are satisfied, all of the source and destination pointers will be valid for the various matrixing cases.
+ bool isSafeToProcess = sourceBus && destinationBus && sourceBus->numberOfChannels() > 0 && destinationBus->numberOfChannels() > 0
+ && framesToProcess <= MaxFrameSize && framesToProcess <= sourceBus->frameSize() && framesToProcess <= destinationBus->frameSize();
+
+ ASSERT(isSafeToProcess);
+ if (!isSafeToProcess)
+ return;
+
+ // For now only handle mono or stereo output
+ if (destinationBus->numberOfChannels() > 2) {
+ destinationBus->zero();
+ return;
+ }
+
+ AudioChannel* destinationChannelL = destinationBus->channel(0);
+ AudioChannel* sourceChannelL = sourceBus->channel(0);
+
+ // Handle input -> output matrixing...
+ size_t numInputChannels = sourceBus->numberOfChannels();
+ size_t numOutputChannels = destinationBus->numberOfChannels();
+ size_t numReverbChannels = m_convolvers.size();
+
+ if (numInputChannels == 2 && numReverbChannels == 2 && numOutputChannels == 2) {
+ // 2 -> 2 -> 2
+ AudioChannel* sourceChannelR = sourceBus->channel(1);
+ AudioChannel* destinationChannelR = destinationBus->channel(1);
+ m_convolvers[0]->process(sourceChannelL, destinationChannelL, framesToProcess);
+ m_convolvers[1]->process(sourceChannelR, destinationChannelR, framesToProcess);
+ } else if (numInputChannels == 1 && numOutputChannels == 2 && numReverbChannels == 2) {
+ // 1 -> 2 -> 2
+ for (int i = 0; i < 2; ++i) {
+ AudioChannel* destinationChannel = destinationBus->channel(i);
+ m_convolvers[i]->process(sourceChannelL, destinationChannel, framesToProcess);
+ }
+ } else if (numInputChannels == 1 && numReverbChannels == 1 && numOutputChannels == 2) {
+ // 1 -> 1 -> 2
+ m_convolvers[0]->process(sourceChannelL, destinationChannelL, framesToProcess);
+
+ // simply copy L -> R
+ AudioChannel* destinationChannelR = destinationBus->channel(1);
+ bool isCopySafe = destinationChannelL->data() && destinationChannelR->data() && destinationChannelL->frameSize() >= framesToProcess && destinationChannelR->frameSize() >= framesToProcess;
+ ASSERT(isCopySafe);
+ if (!isCopySafe)
+ return;
+ memcpy(destinationChannelR->data(), destinationChannelL->data(), sizeof(float) * framesToProcess);
+ } else if (numInputChannels == 1 && numReverbChannels == 1 && numOutputChannels == 1) {
+ // 1 -> 1 -> 1
+ m_convolvers[0]->process(sourceChannelL, destinationChannelL, framesToProcess);
+ } else if (numInputChannels == 2 && numReverbChannels == 4 && numOutputChannels == 2) {
+ // 2 -> 4 -> 2 ("True" stereo)
+ AudioChannel* sourceChannelR = sourceBus->channel(1);
+ AudioChannel* destinationChannelR = destinationBus->channel(1);
+
+ AudioChannel* tempChannelL = m_tempBuffer->channel(0);
+ AudioChannel* tempChannelR = m_tempBuffer->channel(1);
+
+ // Process left virtual source
+ m_convolvers[0]->process(sourceChannelL, destinationChannelL, framesToProcess);
+ m_convolvers[1]->process(sourceChannelL, destinationChannelR, framesToProcess);
+
+ // Process right virtual source
+ m_convolvers[2]->process(sourceChannelR, tempChannelL, framesToProcess);
+ m_convolvers[3]->process(sourceChannelR, tempChannelR, framesToProcess);
+
+ destinationBus->sumFrom(*m_tempBuffer);
+ } else if (numInputChannels == 1 && numReverbChannels == 4 && numOutputChannels == 2) {
+ // 1 -> 4 -> 2 (Processing mono with "True" stereo impulse response)
+ // This is an inefficient use of a four-channel impulse response, but we should handle the case.
+ AudioChannel* destinationChannelR = destinationBus->channel(1);
+
+ AudioChannel* tempChannelL = m_tempBuffer->channel(0);
+ AudioChannel* tempChannelR = m_tempBuffer->channel(1);
+
+ // Process left virtual source
+ m_convolvers[0]->process(sourceChannelL, destinationChannelL, framesToProcess);
+ m_convolvers[1]->process(sourceChannelL, destinationChannelR, framesToProcess);
+
+ // Process right virtual source
+ m_convolvers[2]->process(sourceChannelL, tempChannelL, framesToProcess);
+ m_convolvers[3]->process(sourceChannelL, tempChannelR, framesToProcess);
+
+ destinationBus->sumFrom(*m_tempBuffer);
+ } else {
+ // Handle gracefully any unexpected / unsupported matrixing
+ // FIXME: add code for 5.1 support...
+ destinationBus->zero();
+ }
+}
+
+void Reverb::reset()
+{
+ for (size_t i = 0; i < m_convolvers.size(); ++i)
+ m_convolvers[i]->reset();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/Reverb.h b/WebCore/platform/audio/Reverb.h
new file mode 100644
index 0000000..26f5f8e
--- /dev/null
+++ b/WebCore/platform/audio/Reverb.h
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 Reverb_h
+#define Reverb_h
+
+#include "ReverbConvolver.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioBus;
+
+// Multi-channel convolution reverb with channel matrixing - one or more ReverbConvolver objects are used internally.
+
+class Reverb {
+public:
+ enum { MaxFrameSize = 256 };
+
+ // renderSliceSize is a rendering hint, so the FFTs can be optimized to not all occur at the same time (very bad when rendering on a real-time thread).
+ Reverb(AudioBus* impulseResponseBuffer, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads);
+
+ void process(AudioBus* sourceBus, AudioBus* destinationBus, size_t framesToProcess);
+ void reset();
+
+ unsigned impulseResponseLength() const { return m_impulseResponseLength; }
+
+private:
+ void initialize(AudioBus* impulseResponseBuffer, size_t renderSliceSize, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads);
+
+ size_t m_impulseResponseLength;
+
+ Vector<OwnPtr<ReverbConvolver> > m_convolvers;
+
+ // For "True" stereo processing
+ OwnPtr<AudioBus> m_tempBuffer;
+};
+
+} // namespace WebCore
+
+#endif // Reverb_h
diff --git a/WebCore/platform/audio/ReverbAccumulationBuffer.cpp b/WebCore/platform/audio/ReverbAccumulationBuffer.cpp
new file mode 100644
index 0000000..7b1c63b
--- /dev/null
+++ b/WebCore/platform/audio/ReverbAccumulationBuffer.cpp
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "ReverbAccumulationBuffer.h"
+
+#include "Accelerate.h"
+
+namespace WebCore {
+
+ReverbAccumulationBuffer::ReverbAccumulationBuffer(size_t length)
+ : m_buffer(length)
+ , m_readIndex(0)
+ , m_readTimeFrame(0)
+{
+}
+
+void ReverbAccumulationBuffer::readAndClear(float* destination, size_t numberOfFrames)
+{
+ size_t bufferLength = m_buffer.size();
+ bool isCopySafe = m_readIndex <= bufferLength && numberOfFrames <= bufferLength;
+
+ ASSERT(isCopySafe);
+ if (!isCopySafe)
+ return;
+
+ size_t framesAvailable = bufferLength - m_readIndex;
+ size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable);
+ size_t numberOfFrames2 = numberOfFrames - numberOfFrames1;
+
+ float* source = m_buffer.data();
+ memcpy(destination, source + m_readIndex, sizeof(float) * numberOfFrames1);
+ memset(source + m_readIndex, 0, sizeof(float) * numberOfFrames1);
+
+ // Handle wrap-around if necessary
+ if (numberOfFrames2 > 0) {
+ memcpy(destination + numberOfFrames1, source, sizeof(float) * numberOfFrames2);
+ memset(source, 0, sizeof(float) * numberOfFrames2);
+ }
+
+ m_readIndex = (m_readIndex + numberOfFrames) % bufferLength;
+ m_readTimeFrame += numberOfFrames;
+}
+
+void ReverbAccumulationBuffer::updateReadIndex(int* readIndex, size_t numberOfFrames) const
+{
+ // Update caller's readIndex
+ *readIndex = (*readIndex + numberOfFrames) % m_buffer.size();
+}
+
+int ReverbAccumulationBuffer::accumulate(float* source, size_t numberOfFrames, int* readIndex, size_t delayFrames)
+{
+ size_t bufferLength = m_buffer.size();
+
+ size_t writeIndex = (*readIndex + delayFrames) % bufferLength;
+
+ // Update caller's readIndex
+ *readIndex = (*readIndex + numberOfFrames) % bufferLength;
+
+ size_t framesAvailable = bufferLength - writeIndex;
+ size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable);
+ size_t numberOfFrames2 = numberOfFrames - numberOfFrames1;
+
+ float* destination = m_buffer.data();
+
+ bool isSafe = writeIndex <= bufferLength && numberOfFrames1 + writeIndex <= bufferLength && numberOfFrames2 <= bufferLength;
+ ASSERT(isSafe);
+ if (!isSafe)
+ return 0;
+
+ vadd(source, 1, destination + writeIndex, 1, destination + writeIndex, 1, numberOfFrames1);
+
+ // Handle wrap-around if necessary
+ if (numberOfFrames2 > 0)
+ vadd(source + numberOfFrames1, 1, destination, 1, destination, 1, numberOfFrames2);
+
+ return writeIndex;
+}
+
+void ReverbAccumulationBuffer::reset()
+{
+ m_buffer.zero();
+ m_readIndex = 0;
+ m_readTimeFrame = 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/ReverbAccumulationBuffer.h b/WebCore/platform/audio/ReverbAccumulationBuffer.h
new file mode 100644
index 0000000..44a0773
--- /dev/null
+++ b/WebCore/platform/audio/ReverbAccumulationBuffer.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 ReverbAccumulationBuffer_h
+#define ReverbAccumulationBuffer_h
+
+#include "AudioFloatArray.h"
+
+namespace WebCore {
+
+// ReverbAccumulationBuffer is a circular delay buffer with one client reading from it and multiple clients
+// writing/accumulating to it at different delay offsets from the read position. The read operation will zero the memory
+// just read from the buffer, so it will be ready for accumulation the next time around.
+class ReverbAccumulationBuffer {
+public:
+ ReverbAccumulationBuffer(size_t length);
+
+ // This will read from, then clear-out numberOfFrames
+ void readAndClear(float* destination, size_t numberOfFrames);
+
+ // Each ReverbConvolverStage will accumulate its output at the appropriate delay from the read position.
+ // We need to pass in and update readIndex here, since each ReverbConvolverStage may be running in
+ // a different thread than the realtime thread calling ReadAndClear() and maintaining m_readIndex
+ // Returns the writeIndex where the accumulation took place
+ int accumulate(float* source, size_t numberOfFrames, int* readIndex, size_t delayFrames);
+
+ size_t readIndex() const { return m_readIndex; }
+ void updateReadIndex(int* readIndex, size_t numberOfFrames) const;
+
+ size_t readTimeFrame() const { return m_readTimeFrame; }
+
+ void reset();
+
+private:
+ AudioFloatArray m_buffer;
+ size_t m_readIndex;
+ size_t m_readTimeFrame; // for debugging (frame on continuous timeline)
+};
+
+} // namespace WebCore
+
+#endif // ReverbAccumulationBuffer_h
diff --git a/WebCore/platform/audio/ReverbConvolver.cpp b/WebCore/platform/audio/ReverbConvolver.cpp
new file mode 100644
index 0000000..719e586
--- /dev/null
+++ b/WebCore/platform/audio/ReverbConvolver.cpp
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "ReverbConvolver.h"
+
+#include "Accelerate.h"
+#include "AudioBus.h"
+
+namespace WebCore {
+
+const int InputBufferSize = 8 * 16384;
+
+// We only process the leading portion of the impulse response in the real-time thread. We don't exceed this length.
+// It turns out then, that the background thread has about 278msec of scheduling slop.
+// Empirically, this has been found to be a good compromise between giving enough time for scheduling slop,
+// while still minimizing the amount of processing done in the primary (high-priority) thread.
+// This was found to be a good value on Mac OS X, and may work well on other platforms as well, assuming
+// the very rough scheduling latencies are similar on these time-scales. Of course, this code may need to be
+// tuned for individual platforms if this assumption is found to be incorrect.
+const size_t RealtimeFrameLimit = 8192 + 4096; // ~278msec @ 44.1KHz
+
+const size_t MinFFTSize = 256;
+const size_t MaxRealtimeFFTSize = 2048;
+
+static void* backgroundThreadEntry(void* threadData)
+{
+ ReverbConvolver* reverbConvolver = static_cast<ReverbConvolver*>(threadData);
+ reverbConvolver->backgroundThreadEntry();
+ return 0;
+}
+
+ReverbConvolver::ReverbConvolver(AudioChannel* impulseResponse, size_t renderSliceSize, size_t maxFFTSize, size_t convolverRenderPhase, bool useBackgroundThreads)
+ : m_impulseResponseLength(impulseResponse->frameSize())
+ , m_accumulationBuffer(impulseResponse->frameSize() + renderSliceSize)
+ , m_inputBuffer(InputBufferSize)
+ , m_renderSliceSize(renderSliceSize)
+ , m_minFFTSize(MinFFTSize) // First stage will have this size - successive stages will double in size each time
+ , m_maxFFTSize(maxFFTSize) // until we hit m_maxFFTSize
+ , m_useBackgroundThreads(useBackgroundThreads)
+ , m_backgroundThread(0)
+ , m_wantsToExit(false)
+ , m_moreInputBuffered(false)
+{
+ // If we are using background threads then don't exceed this FFT size for the
+ // stages which run in the real-time thread. This avoids having only one or two
+ // large stages (size 16384 or so) at the end which take a lot of time every several
+ // processing slices. This way we amortize the cost over more processing slices.
+ m_maxRealtimeFFTSize = MaxRealtimeFFTSize;
+
+ // For the moment, a good way to know if we have real-time constraint is to check if we're using background threads.
+ // Otherwise, assume we're being run from a command-line tool.
+ bool hasRealtimeConstraint = useBackgroundThreads;
+
+ float* response = impulseResponse->data();
+ size_t totalResponseLength = impulseResponse->frameSize();
+
+ // Because we're not using direct-convolution in the leading portion, the reverb has an overall latency of half the first-stage FFT size
+ size_t reverbTotalLatency = m_minFFTSize / 2;
+
+ size_t stageOffset = 0;
+ int i = 0;
+ size_t fftSize = m_minFFTSize;
+ while (stageOffset < totalResponseLength) {
+ size_t stageSize = fftSize / 2;
+
+ // For the last stage, it's possible that stageOffset is such that we're straddling the end
+ // of the impulse response buffer (if we use stageSize), so reduce the last stage's length...
+ if (stageSize + stageOffset > totalResponseLength)
+ stageSize = totalResponseLength - stageOffset;
+
+ // This "staggers" the time when each FFT happens so they don't all happen at the same time
+ int renderPhase = convolverRenderPhase + i * renderSliceSize;
+
+ OwnPtr<ReverbConvolverStage> stage(new ReverbConvolverStage(response, totalResponseLength, reverbTotalLatency, stageOffset, stageSize, fftSize, renderPhase, renderSliceSize, &m_accumulationBuffer));
+
+ bool isBackgroundStage = false;
+
+ if (this->useBackgroundThreads() && stageOffset > RealtimeFrameLimit) {
+ m_backgroundStages.append(stage.release());
+ isBackgroundStage = true;
+ } else
+ m_stages.append(stage.release());
+
+ stageOffset += stageSize;
+ ++i;
+
+ // Figure out next FFT size
+ fftSize *= 2;
+ if (hasRealtimeConstraint && !isBackgroundStage && fftSize > m_maxRealtimeFFTSize)
+ fftSize = m_maxRealtimeFFTSize;
+ if (fftSize > m_maxFFTSize)
+ fftSize = m_maxFFTSize;
+ }
+
+ // Start up background thread
+ // FIXME: would be better to up the thread priority here. It doesn't need to be real-time, but higher than the default...
+ if (this->useBackgroundThreads() && m_backgroundStages.size() > 0)
+ m_backgroundThread = createThread(WebCore::backgroundThreadEntry, this, "convolution background thread");
+}
+
+ReverbConvolver::~ReverbConvolver()
+{
+ // Wait for background thread to stop
+ if (useBackgroundThreads() && m_backgroundThread) {
+ m_wantsToExit = true;
+
+ // Wake up thread so it can return
+ {
+ MutexLocker locker(m_backgroundThreadLock);
+ m_moreInputBuffered = true;
+ m_backgroundThreadCondition.signal();
+ }
+
+ waitForThreadCompletion(m_backgroundThread, 0);
+ }
+}
+
+void ReverbConvolver::backgroundThreadEntry()
+{
+ while (!m_wantsToExit) {
+ // Wait for realtime thread to give us more input
+ m_moreInputBuffered = false;
+ {
+ MutexLocker locker(m_backgroundThreadLock);
+ while (!m_moreInputBuffered && !m_wantsToExit)
+ m_backgroundThreadCondition.wait(m_backgroundThreadLock);
+ }
+
+ // Process all of the stages until their read indices reach the input buffer's write index
+ int writeIndex = m_inputBuffer.writeIndex();
+
+ // Even though it doesn't seem like every stage needs to maintain its own version of readIndex
+ // we do this in case we want to run in more than one background thread.
+ int readIndex;
+
+ while ((readIndex = m_backgroundStages[0]->inputReadIndex()) != writeIndex) { // FIXME: do better to detect buffer overrun...
+ // The ReverbConvolverStages need to process in amounts which evenly divide half the FFT size
+ const int SliceSize = MinFFTSize / 2;
+
+ // Accumulate contributions from each stage
+ for (size_t i = 0; i < m_backgroundStages.size(); ++i)
+ m_backgroundStages[i]->processInBackground(this, SliceSize);
+ }
+ }
+}
+
+void ReverbConvolver::process(AudioChannel* sourceChannel, AudioChannel* destinationChannel, size_t framesToProcess)
+{
+ bool isSafe = sourceChannel && destinationChannel && sourceChannel->frameSize() >= framesToProcess && destinationChannel->frameSize() >= framesToProcess;
+ ASSERT(isSafe);
+ if (!isSafe)
+ return;
+
+ float* source = sourceChannel->data();
+ float* destination = destinationChannel->data();
+ bool isDataSafe = source && destination;
+ ASSERT(isDataSafe);
+ if (!isDataSafe)
+ return;
+
+ // Feed input buffer (read by all threads)
+ m_inputBuffer.write(source, framesToProcess);
+
+ // Accumulate contributions from each stage
+ for (size_t i = 0; i < m_stages.size(); ++i)
+ m_stages[i]->process(source, framesToProcess);
+
+ // Finally read from accumulation buffer
+ m_accumulationBuffer.readAndClear(destination, framesToProcess);
+
+ // Now that we've buffered more input, wake up our background thread.
+
+ // Not using a MutexLocker looks strange, but we use a tryLock() instead because this is run on the real-time
+ // thread where it is a disaster for the lock to be contended (causes audio glitching). It's OK if we fail to
+ // signal from time to time, since we'll get to it the next time we're called. We're called repeatedly
+ // and frequently (around every 3ms). The background thread is processing well into the future and has a considerable amount of
+ // leeway here...
+ if (m_backgroundThreadLock.tryLock()) {
+ m_moreInputBuffered = true;
+ m_backgroundThreadCondition.signal();
+ m_backgroundThreadLock.unlock();
+ }
+}
+
+void ReverbConvolver::reset()
+{
+ for (size_t i = 0; i < m_stages.size(); ++i)
+ m_stages[i]->reset();
+
+ for (size_t i = 0; i < m_backgroundStages.size(); ++i)
+ m_backgroundStages[i]->reset();
+
+ m_accumulationBuffer.reset();
+ m_inputBuffer.reset();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/ReverbConvolver.h b/WebCore/platform/audio/ReverbConvolver.h
new file mode 100644
index 0000000..34f77d3
--- /dev/null
+++ b/WebCore/platform/audio/ReverbConvolver.h
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 ReverbConvolver_h
+#define ReverbConvolver_h
+
+#include "AudioFloatArray.h"
+#include "FFTConvolver.h"
+#include "ReverbAccumulationBuffer.h"
+#include "ReverbConvolverStage.h"
+#include "ReverbInputBuffer.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Threading.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class AudioChannel;
+
+class ReverbConvolver {
+public:
+ // maxFFTSize can be adjusted (from say 2048 to 32768) depending on how much precision is necessary.
+ // For certain tweaky de-convolving applications the phase errors add up quickly and lead to non-sensical results with
+ // larger FFT sizes and single-precision floats. In these cases 2048 is a good size.
+ // If not doing multi-threaded convolution, then should not go > 8192.
+ ReverbConvolver(AudioChannel* impulseResponse, size_t renderSliceSize, size_t maxFFTSize, size_t convolverRenderPhase, bool useBackgroundThreads);
+ ~ReverbConvolver();
+
+ void process(AudioChannel* sourceChannel, AudioChannel* destinationChannel, size_t framesToProcess);
+ void reset();
+
+ size_t impulseResponseLength() const { return m_impulseResponseLength; }
+
+ ReverbInputBuffer* inputBuffer() { return &m_inputBuffer; }
+
+ bool useBackgroundThreads() const { return m_useBackgroundThreads; }
+ void backgroundThreadEntry();
+
+private:
+ Vector<OwnPtr<ReverbConvolverStage> > m_stages;
+ Vector<OwnPtr<ReverbConvolverStage> > m_backgroundStages;
+ size_t m_impulseResponseLength;
+
+ ReverbAccumulationBuffer m_accumulationBuffer;
+
+ // One or more background threads read from this input buffer which is fed from the realtime thread.
+ ReverbInputBuffer m_inputBuffer;
+
+ // We're given a rendering hint, so the FFTs can be optimized to not all occur at the same time
+ // (very bad when rendering on a real-time thread).
+ size_t m_renderSliceSize;
+
+ // First stage will be of size m_minFFTSize. Each next stage will be twice as big until we hit m_maxFFTSize.
+ size_t m_minFFTSize;
+ size_t m_maxFFTSize;
+
+ // But don't exceed this size in the real-time thread (if we're doing background processing).
+ size_t m_maxRealtimeFFTSize;
+
+ // Background thread and synchronization
+ bool m_useBackgroundThreads;
+ ThreadIdentifier m_backgroundThread;
+ bool m_wantsToExit;
+ bool m_moreInputBuffered;
+ mutable Mutex m_backgroundThreadLock;
+ mutable ThreadCondition m_backgroundThreadCondition;
+};
+
+} // namespace WebCore
+
+#endif // ReverbConvolver_h
diff --git a/WebCore/platform/audio/ReverbConvolverStage.cpp b/WebCore/platform/audio/ReverbConvolverStage.cpp
new file mode 100644
index 0000000..8606502
--- /dev/null
+++ b/WebCore/platform/audio/ReverbConvolverStage.cpp
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "ReverbConvolverStage.h"
+
+#include "Accelerate.h"
+#include "ReverbAccumulationBuffer.h"
+#include "ReverbConvolver.h"
+#include "ReverbInputBuffer.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+ReverbConvolverStage::ReverbConvolverStage(float* impulseResponse, size_t responseLength, size_t reverbTotalLatency, size_t stageOffset, size_t stageLength,
+ size_t fftSize, size_t renderPhase, size_t renderSliceSize, ReverbAccumulationBuffer* accumulationBuffer)
+ : m_fftKernel(fftSize)
+ , m_accumulationBuffer(accumulationBuffer)
+ , m_accumulationReadIndex(0)
+ , m_inputReadIndex(0)
+ , m_impulseResponseLength(responseLength)
+{
+ ASSERT(impulseResponse);
+ ASSERT(accumulationBuffer);
+
+ m_fftKernel.doPaddedFFT(impulseResponse + stageOffset, stageLength);
+ m_convolver = new FFTConvolver(fftSize);
+ m_temporaryBuffer.allocate(renderSliceSize);
+
+ // The convolution stage at offset stageOffset needs to have a corresponding delay to cancel out the offset.
+ size_t totalDelay = stageOffset + reverbTotalLatency;
+
+ // But, the FFT convolution itself incurs fftSize / 2 latency, so subtract this out...
+ size_t halfSize = fftSize / 2;
+ ASSERT(totalDelay >= halfSize);
+ if (totalDelay >= halfSize)
+ totalDelay -= halfSize;
+
+ // We divide up the total delay, into pre and post delay sections so that we can schedule at exactly the moment when the FFT will happen.
+ // This is coordinated with the other stages, so they don't all do their FFTs at the same time...
+ int maxPreDelayLength = std::min(halfSize, totalDelay);
+ m_preDelayLength = totalDelay > 0 ? renderPhase % maxPreDelayLength : 0;
+ if (m_preDelayLength > totalDelay)
+ m_preDelayLength = 0;
+
+ m_postDelayLength = totalDelay - m_preDelayLength;
+ m_preReadWriteIndex = 0;
+ m_framesProcessed = 0; // total frames processed so far
+
+ m_preDelayBuffer.allocate(m_preDelayLength < fftSize ? fftSize : m_preDelayLength);
+}
+
+void ReverbConvolverStage::processInBackground(ReverbConvolver* convolver, size_t framesToProcess)
+{
+ ReverbInputBuffer* inputBuffer = convolver->inputBuffer();
+ float* source = inputBuffer->directReadFrom(&m_inputReadIndex, framesToProcess);
+ process(source, framesToProcess);
+}
+
+void ReverbConvolverStage::process(float* source, size_t framesToProcess)
+{
+ ASSERT(source);
+ if (!source)
+ return;
+
+ // Deal with pre-delay stream : note special handling of zero delay.
+
+ float* preDelayedSource;
+ float* temporaryBuffer;
+ bool isTemporaryBufferSafe = false;
+ if (m_preDelayLength > 0) {
+ // Handles both the read case (call to process() ) and the write case (memcpy() )
+ bool isPreDelaySafe = m_preReadWriteIndex + framesToProcess <= m_preDelayBuffer.size();
+ ASSERT(isPreDelaySafe);
+ if (!isPreDelaySafe)
+ return;
+
+ isTemporaryBufferSafe = framesToProcess <= m_temporaryBuffer.size();
+
+ preDelayedSource = m_preDelayBuffer.data() + m_preReadWriteIndex;
+ temporaryBuffer = m_temporaryBuffer.data();
+ } else {
+ // Zero delay
+ preDelayedSource = source;
+ temporaryBuffer = m_preDelayBuffer.data();
+
+ isTemporaryBufferSafe = framesToProcess <= m_preDelayBuffer.size();
+ }
+
+ ASSERT(isTemporaryBufferSafe);
+ if (!isTemporaryBufferSafe)
+ return;
+
+ int writeIndex = 0;
+
+ if (m_framesProcessed < m_preDelayLength) {
+ // For the first m_preDelayLength frames don't process the convolver, instead simply buffer in the pre-delay.
+ // But while buffering the pre-delay, we still need to update our index.
+ m_accumulationBuffer->updateReadIndex(&m_accumulationReadIndex, framesToProcess);
+ } else {
+ // Now, run the convolution (into the delay buffer).
+ // An expensive FFT will happen every fftSize / 2 frames.
+ // We process in-place here...
+ m_convolver->process(&m_fftKernel, preDelayedSource, temporaryBuffer, framesToProcess);
+
+ // Now accumulate into reverb's accumulation buffer.
+ writeIndex = m_accumulationBuffer->accumulate(temporaryBuffer, framesToProcess, &m_accumulationReadIndex, m_postDelayLength);
+ }
+
+ // Finally copy input to pre-delay.
+ if (m_preDelayLength > 0) {
+ memcpy(preDelayedSource, source, sizeof(float) * framesToProcess);
+ m_preReadWriteIndex += framesToProcess;
+
+ ASSERT(m_preReadWriteIndex <= m_preDelayLength);
+ if (m_preReadWriteIndex >= m_preDelayLength)
+ m_preReadWriteIndex = 0;
+ }
+
+ m_framesProcessed += framesToProcess;
+}
+
+void ReverbConvolverStage::reset()
+{
+ m_convolver->reset();
+ m_preDelayBuffer.zero();
+ m_accumulationReadIndex = 0;
+ m_inputReadIndex = 0;
+ m_framesProcessed = 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/ReverbConvolverStage.h b/WebCore/platform/audio/ReverbConvolverStage.h
new file mode 100644
index 0000000..88351af
--- /dev/null
+++ b/WebCore/platform/audio/ReverbConvolverStage.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 ReverbConvolverStage_h
+#define ReverbConvolverStage_h
+
+#include "AudioFloatArray.h"
+#include "FFTFrame.h"
+#include <wtf/OwnPtr.h>
+
+namespace WebCore {
+
+class ReverbAccumulationBuffer;
+class ReverbConvolver;
+class FFTConvolver;
+
+// A ReverbConvolverStage represents the convolution associated with a sub-section of a large impulse response.
+// It incorporates a delay line to account for the offset of the sub-section within the larger impulse response.
+class ReverbConvolverStage {
+public:
+ // renderPhase is useful to know so that we can manipulate the pre versus post delay so that stages will perform
+ // their heavy work (FFT processing) on different slices to balance the load in a real-time thread.
+ ReverbConvolverStage(float* impulseResponse, size_t responseLength, size_t reverbTotalLatency, size_t stageOffset, size_t stageLength,
+ size_t fftSize, size_t renderPhase, size_t renderSliceSize, ReverbAccumulationBuffer* accumulationBuffer);
+
+ // WARNING: framesToProcess must be such that it evenly divides the delay buffer size (stage_offset).
+ void process(float* source, size_t framesToProcess);
+
+ void processInBackground(ReverbConvolver* convolver, size_t framesToProcess);
+
+ void reset();
+
+ // Useful for background processing
+ int inputReadIndex() const { return m_inputReadIndex; }
+
+private:
+ FFTFrame m_fftKernel;
+ OwnPtr<FFTConvolver> m_convolver;
+
+ AudioFloatArray m_preDelayBuffer;
+
+ ReverbAccumulationBuffer* m_accumulationBuffer;
+ int m_accumulationReadIndex;
+ int m_inputReadIndex;
+
+ size_t m_preDelayLength;
+ size_t m_postDelayLength;
+ size_t m_preReadWriteIndex;
+ size_t m_framesProcessed;
+
+ AudioFloatArray m_temporaryBuffer;
+
+ size_t m_impulseResponseLength;
+};
+
+} // namespace WebCore
+
+#endif // ReverbConvolverStage_h
diff --git a/WebCore/platform/audio/ReverbInputBuffer.cpp b/WebCore/platform/audio/ReverbInputBuffer.cpp
new file mode 100644
index 0000000..f270f6f
--- /dev/null
+++ b/WebCore/platform/audio/ReverbInputBuffer.cpp
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "ReverbInputBuffer.h"
+
+namespace WebCore {
+
+ReverbInputBuffer::ReverbInputBuffer(size_t length)
+ : m_buffer(length)
+ , m_writeIndex(0)
+{
+}
+
+void ReverbInputBuffer::write(float* sourceP, size_t numberOfFrames)
+{
+ size_t bufferLength = m_buffer.size();
+ bool isCopySafe = m_writeIndex + numberOfFrames <= bufferLength;
+ ASSERT(isCopySafe);
+ if (!isCopySafe)
+ return;
+
+ memcpy(m_buffer.data() + m_writeIndex, sourceP, sizeof(float) * numberOfFrames);
+
+ m_writeIndex += numberOfFrames;
+ ASSERT(m_writeIndex <= bufferLength);
+
+ if (m_writeIndex >= bufferLength)
+ m_writeIndex = 0;
+}
+
+float* ReverbInputBuffer::directReadFrom(int* readIndex, size_t numberOfFrames)
+{
+ size_t bufferLength = m_buffer.size();
+ bool isPointerGood = readIndex && *readIndex >= 0 && *readIndex + numberOfFrames <= bufferLength;
+ ASSERT(isPointerGood);
+ if (!isPointerGood) {
+ // Should never happen in practice but return pointer to start of buffer (avoid crash)
+ if (readIndex)
+ *readIndex = 0;
+ return m_buffer.data();
+ }
+
+ float* sourceP = m_buffer.data();
+ float* p = sourceP + *readIndex;
+
+ // Update readIndex
+ *readIndex = (*readIndex + numberOfFrames) % bufferLength;
+
+ return p;
+}
+
+void ReverbInputBuffer::reset()
+{
+ m_buffer.zero();
+ m_writeIndex = 0;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/WebCore/platform/audio/ReverbInputBuffer.h b/WebCore/platform/audio/ReverbInputBuffer.h
new file mode 100644
index 0000000..aa9cf41
--- /dev/null
+++ b/WebCore/platform/audio/ReverbInputBuffer.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 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 ReverbInputBuffer_h
+#define ReverbInputBuffer_h
+
+#include "AudioFloatArray.h"
+
+namespace WebCore {
+
+// ReverbInputBuffer is used to buffer input samples for deferred processing by the background threads.
+class ReverbInputBuffer {
+public:
+ ReverbInputBuffer(size_t length);
+
+ // The realtime audio thread keeps writing samples here.
+ // The assumption is that the buffer's length is evenly divisible by numberOfFrames (for nearly all cases this will be fine).
+ // FIXME: remove numberOfFrames restriction...
+ void write(float* sourceP, size_t numberOfFrames);
+
+ // Background threads can call this to check if there's anything to read...
+ size_t writeIndex() const { return m_writeIndex; }
+
+ // The individual background threads read here (and hope that they can keep up with the buffer writing).
+ // readIndex is updated with the next readIndex to read from...
+ // The assumption is that the buffer's length is evenly divisible by numberOfFrames.
+ // FIXME: remove numberOfFrames restriction...
+ float* directReadFrom(int* readIndex, size_t numberOfFrames);
+
+ void reset();
+
+private:
+ AudioFloatArray m_buffer;
+ size_t m_writeIndex;
+};
+
+} // namespace WebCore
+
+#endif // ReverbInputBuffer_h
diff --git a/WebCore/platform/brew/SharedBufferBrew.cpp b/WebCore/platform/brew/SharedBufferBrew.cpp
new file mode 100644
index 0000000..597825c
--- /dev/null
+++ b/WebCore/platform/brew/SharedBufferBrew.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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:
+ * 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 "SharedBuffer.h"
+
+#include "FileSystem.h"
+#include "ShellBrew.h"
+
+#include <AEEAppGen.h>
+#include <AEEFile.h>
+#include <AEEStdLib.h>
+
+#include <wtf/OwnPtr.h>
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath)
+{
+ if (filePath.isEmpty())
+ return 0;
+
+ long long fileSize;
+ if (!fileExists(filePath) || !getFileSize(filePath, fileSize))
+ return 0;
+
+ RefPtr<SharedBuffer> result = create();
+ result->m_buffer.grow(fileSize);
+
+ OwnPtr<IFileMgr> fileMgr = createInstance<IFileMgr>(AEECLSID_FILEMGR);
+
+ CString filename = fileSystemRepresentation(filePath);
+ OwnPtr<IFile> file(IFILEMGR_OpenFile(fileMgr.get(), filename.data(), _OFM_READ));
+
+ if (!file) {
+ LOG_ERROR("Failed to open file %s to create shared buffer, errno(%i)", filePath.ascii().data(), IFILEMGR_GetLastError(fileMgr.get()));
+ return 0;
+ }
+
+ size_t totalBytesRead = 0;
+ int32 bytesRead;
+ while ((bytesRead = IFILE_Read(file.get(), result->m_buffer.data() + totalBytesRead, fileSize - totalBytesRead)) > 0)
+ totalBytesRead += bytesRead;
+
+ if (totalBytesRead != fileSize) {
+ LOG_ERROR("Failed to fully read contents of file %s - errno(%i)", filePath.ascii().data(), IFILEMGR_GetLastError(fileMgr.get()));
+ return 0;
+ }
+
+ return result.release();
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index 35ace89..bc86de2 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -102,7 +102,7 @@ namespace WebCore {
static void clipboardWritePlainText(const String&);
static void clipboardWriteURL(const KURL&, const String&);
static void clipboardWriteImage(NativeImagePtr, const KURL&, const String&);
- static void clipboardWriteData(ClipboardData*);
+ static void clipboardWriteData(const String& type, const String& data, const String& metadata);
// Interface for handling copy and paste, drag and drop, and selection copy.
static HashSet<String> clipboardReadAvailableTypes(PasteboardPrivate::ClipboardBuffer, bool* containsFilenames);
diff --git a/WebCore/platform/chromium/ClipboardMimeTypes.cpp b/WebCore/platform/chromium/ClipboardMimeTypes.cpp
new file mode 100644
index 0000000..b95744f8
--- /dev/null
+++ b/WebCore/platform/chromium/ClipboardMimeTypes.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 "ClipboardMimeTypes.h"
+
+namespace WebCore {
+
+const char textPlainType[] = "text/plain";
+const char textHtmlType[] = "text/html";
+const char textUriListType[] = "text/uri-list";
+
+} // namespace WebCore
diff --git a/WebCore/platform/chromium/ClipboardMimeTypes.h b/WebCore/platform/chromium/ClipboardMimeTypes.h
new file mode 100644
index 0000000..d7468f2
--- /dev/null
+++ b/WebCore/platform/chromium/ClipboardMimeTypes.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#ifndef ClipboardMimeTypes_h
+#define ClipboardMimeTypes_h
+
+namespace WebCore {
+
+extern const char textPlainType[];
+extern const char textHtmlType[];
+extern const char textUriListType[];
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/chromium/ReadableDataObject.cpp b/WebCore/platform/chromium/ReadableDataObject.cpp
new file mode 100644
index 0000000..1a333bb
--- /dev/null
+++ b/WebCore/platform/chromium/ReadableDataObject.cpp
@@ -0,0 +1,120 @@
+/*
+ * 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 "ReadableDataObject.h"
+
+#include "ChromiumBridge.h"
+#include "ClipboardMimeTypes.h"
+
+namespace WebCore {
+
+static PasteboardPrivate::ClipboardBuffer clipboardBuffer(bool isForDragging)
+{
+ return isForDragging ? PasteboardPrivate::DragBuffer : PasteboardPrivate::StandardBuffer;
+}
+
+PassRefPtr<ReadableDataObject> ReadableDataObject::create(bool isForDragging)
+{
+ return adoptRef(new ReadableDataObject(isForDragging));
+}
+
+ReadableDataObject::ReadableDataObject(bool isForDragging)
+ : m_isForDragging(isForDragging)
+ , m_containsFilenames(false)
+ , m_isTypeCacheInitialized(false)
+{
+}
+
+bool ReadableDataObject::hasData() const
+{
+ ensureTypeCacheInitialized();
+ return !m_types.isEmpty() || m_containsFilenames;
+}
+
+HashSet<String> ReadableDataObject::types() const
+{
+ ensureTypeCacheInitialized();
+ return m_types;
+}
+
+String ReadableDataObject::getData(const String& type, bool& succeeded) const
+{
+ String data;
+ String ignoredMetadata;
+ succeeded = ChromiumBridge::clipboardReadData(
+ clipboardBuffer(m_isForDragging), type, data, ignoredMetadata);
+ return data;
+}
+
+String ReadableDataObject::getURL(String* title) const
+{
+ String url;
+ String ignoredTitle;
+ if (!title)
+ title = &ignoredTitle;
+ ChromiumBridge::clipboardReadData(
+ clipboardBuffer(m_isForDragging), textUriListType, url, *title);
+ return url;
+}
+
+String ReadableDataObject::getHTML(String* baseURL) const
+{
+ String html;
+ String ignoredBaseURL;
+ if (!baseURL)
+ baseURL = &ignoredBaseURL;
+ ChromiumBridge::clipboardReadData(
+ clipboardBuffer(m_isForDragging), textHtmlType, html, *baseURL);
+ return html;
+}
+
+bool ReadableDataObject::hasFilenames() const
+{
+ ensureTypeCacheInitialized();
+ return m_containsFilenames;
+}
+
+Vector<String> ReadableDataObject::filenames() const
+{
+ return ChromiumBridge::clipboardReadFilenames(clipboardBuffer(m_isForDragging));
+}
+
+void ReadableDataObject::ensureTypeCacheInitialized() const
+{
+ if (m_isTypeCacheInitialized)
+ return;
+
+ m_types = ChromiumBridge::clipboardReadAvailableTypes(
+ clipboardBuffer(m_isForDragging), &m_containsFilenames);
+ m_isTypeCacheInitialized = true;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/chromium/ReadableDataObject.h b/WebCore/platform/chromium/ReadableDataObject.h
new file mode 100644
index 0000000..60f6d45
--- /dev/null
+++ b/WebCore/platform/chromium/ReadableDataObject.h
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+#ifndef ReadableDataObject_h
+#define ReadableDataObject_h
+
+#include "PlatformString.h"
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+// Used for one way communication of drag/drop and copy/paste data from the
+// browser to the renderer.
+class ReadableDataObject : public RefCounted<ReadableDataObject> {
+public:
+ static PassRefPtr<ReadableDataObject> create(bool isForDragging);
+
+ virtual bool hasData() const;
+ virtual HashSet<String> types() const;
+ virtual String getData(const String& type, bool& succeeded) const;
+
+ virtual String getURL(String* title) const;
+ virtual String getHTML(String* baseURL) const;
+
+ virtual bool hasFilenames() const;
+ virtual Vector<String> filenames() const;
+
+private:
+ explicit ReadableDataObject(bool isForDragging);
+
+ // This isn't always const... but most of the time it is.
+ void ensureTypeCacheInitialized() const;
+
+
+ bool m_isForDragging;
+
+ // To avoid making a lot of IPC calls for each drag event, we cache some
+ // values in the renderer.
+ mutable HashSet<String> m_types;
+ mutable bool m_containsFilenames;
+ mutable bool m_isTypeCacheInitialized;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/chromium/WritableDataObject.cpp b/WebCore/platform/chromium/WritableDataObject.cpp
new file mode 100644
index 0000000..6e7c283
--- /dev/null
+++ b/WebCore/platform/chromium/WritableDataObject.cpp
@@ -0,0 +1,152 @@
+/*
+ * 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 "WritableDataObject.h"
+
+#include "ChromiumBridge.h"
+#include "ClipboardMimeTypes.h"
+
+namespace WebCore {
+
+PassRefPtr<WritableDataObject> WritableDataObject::create(bool isForDragging)
+{
+ return adoptRef(new WritableDataObject(isForDragging));
+}
+
+WritableDataObject::WritableDataObject(bool isForDragging)
+ : m_isForDragging(isForDragging)
+{
+}
+
+void WritableDataObject::clearData(const String& type)
+{
+ m_dataMap.remove(type);
+ if (type == textUriListType)
+ m_urlTitle = "";
+ else if (type == textHtmlType)
+ m_htmlBaseURL = KURL();
+}
+
+void WritableDataObject::clearAllExceptFiles()
+{
+ // FIXME: The spec does not provide a way to populate FileList currently. In
+ // fact, the spec explicitly states that dragging files can only happen from
+ // outside a browsing context.
+ clearAll();
+}
+
+void WritableDataObject::clearAll()
+{
+ m_dataMap.clear();
+ m_urlTitle = "";
+ m_htmlBaseURL = KURL();
+ m_fileContentFilename = "";
+ if (m_fileContent)
+ m_fileContent->clear();
+ m_fileExtension = "";
+}
+
+bool WritableDataObject::setData(const String& type, const String& data)
+{
+ if (!m_isForDragging) {
+ ChromiumBridge::clipboardWriteData(type, data, "");
+ return true;
+ }
+ m_dataMap.set(type, data);
+ if (type == textUriListType)
+ m_urlTitle = "";
+ else if (type == textHtmlType)
+ m_htmlBaseURL = KURL();
+ return true;
+}
+
+void WritableDataObject::setURL(const String& url, const String& title)
+{
+ setData(textUriListType, url);
+ m_urlTitle = title;
+}
+
+void WritableDataObject::setHTML(const String& html, const KURL& baseURL)
+{
+ setData(textHtmlType, html);
+ m_htmlBaseURL = baseURL;
+}
+
+// Accessors used when transferring drag data from the renderer to the
+// browser.
+HashMap<String, String> WritableDataObject::dataMap() const
+{
+ return m_dataMap;
+}
+
+String WritableDataObject::urlTitle() const
+{
+ return m_urlTitle;
+}
+
+KURL WritableDataObject::htmlBaseURL() const
+{
+ return m_htmlBaseURL;
+}
+
+// Used for transferring file data from the renderer to the browser.
+String WritableDataObject::fileExtension() const
+{
+ return m_fileExtension;
+}
+
+String WritableDataObject::fileContentFilename() const
+{
+ return m_fileContentFilename;
+}
+
+PassRefPtr<SharedBuffer> WritableDataObject::fileContent() const
+{
+ return m_fileContent;
+}
+
+void WritableDataObject::setFileExtension(const String& fileExtension)
+{
+ m_fileExtension = fileExtension;
+}
+
+void WritableDataObject::setFileContentFilename(const String& fileContentFilename)
+{
+ m_fileContentFilename = fileContentFilename;
+}
+
+void WritableDataObject::setFileContent(PassRefPtr<SharedBuffer> fileContent)
+{
+ m_fileContent = fileContent;
+}
+
+
+} // namespace WebCore
diff --git a/WebCore/platform/chromium/WritableDataObject.h b/WebCore/platform/chromium/WritableDataObject.h
new file mode 100644
index 0000000..71e2e26
--- /dev/null
+++ b/WebCore/platform/chromium/WritableDataObject.h
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+#ifndef WritableDataObject_h
+#define WritableDataObject_h
+
+#include "KURL.h"
+#include "PlatformString.h"
+#include "SharedBuffer.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+// Used for one way communication of drag/drop and copy/paste data from the
+// renderer to the browser. This is intenteded to be used in dragstart/copy/cut
+// events. Due to shortcomings, writes to the pasteboard cannot be performed
+// atomically.
+class WritableDataObject : public RefCounted<WritableDataObject> {
+public:
+ static PassRefPtr<WritableDataObject> create(bool isForDragging);
+
+ virtual void clearData(const String& type);
+ virtual void clearAllExceptFiles();
+ virtual void clearAll();
+ virtual bool setData(const String& type, const String& data);
+
+ virtual void setURL(const String& url, const String& title);
+ virtual void setHTML(const String& html, const KURL& baseURL);
+
+ // Used for transferring drag data from the renderer to the browser.
+ virtual HashMap<String, String> dataMap() const;
+ virtual String urlTitle() const;
+ virtual KURL htmlBaseURL() const;
+
+ virtual String fileExtension() const;
+ virtual String fileContentFilename() const;
+ virtual PassRefPtr<SharedBuffer> fileContent() const;
+ virtual void setFileExtension(const String&);
+ virtual void setFileContentFilename(const String&);
+ virtual void setFileContent(PassRefPtr<SharedBuffer>);
+
+private:
+ explicit WritableDataObject(bool isForDragging);
+
+ bool m_isForDragging;
+
+ HashMap<String, String> m_dataMap;
+ String m_urlTitle;
+ KURL m_htmlBaseURL;
+ String m_fileExtension;
+ String m_fileContentFilename;
+ RefPtr<SharedBuffer> m_fileContent;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/WebCore/platform/efl/ClipboardEfl.cpp b/WebCore/platform/efl/ClipboardEfl.cpp
index caff813..6fc80dc 100644
--- a/WebCore/platform/efl/ClipboardEfl.cpp
+++ b/WebCore/platform/efl/ClipboardEfl.cpp
@@ -29,7 +29,7 @@
namespace WebCore {
PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy, Frame*)
{
- return new ClipboardEfl(policy, false);
+ return ClipboardEfl::create(policy, false);
}
PassRefPtr<Clipboard> Clipboard::create(ClipboardAccessPolicy, DragData*, Frame*)
diff --git a/WebCore/platform/efl/ClipboardEfl.h b/WebCore/platform/efl/ClipboardEfl.h
index d5b17c0..5db2fed 100644
--- a/WebCore/platform/efl/ClipboardEfl.h
+++ b/WebCore/platform/efl/ClipboardEfl.h
@@ -28,7 +28,10 @@ class CachedImage;
class ClipboardEfl : public Clipboard {
public:
- ClipboardEfl(ClipboardAccessPolicy, bool);
+ static PassRefPtr<ClipboardEfl> create(ClipboardAccessPolicy policy, bool forDragging = false)
+ {
+ return adoptRef(new ClipboardEfl(policy, forDragging));
+ }
~ClipboardEfl();
void clearData(const String&);
@@ -53,6 +56,9 @@ public:
virtual bool hasData();
virtual void writePlainText(const WTF::String&);
+
+private:
+ ClipboardEfl(ClipboardAccessPolicy, bool);
};
}
diff --git a/WebCore/platform/efl/ScrollbarEfl.cpp b/WebCore/platform/efl/ScrollbarEfl.cpp
index 1030ebd..e413260 100644
--- a/WebCore/platform/efl/ScrollbarEfl.cpp
+++ b/WebCore/platform/efl/ScrollbarEfl.cpp
@@ -125,7 +125,7 @@ void ScrollbarEfl::setParent(ScrollView* view)
int err = edje_object_load_error_get(o);
const char* errmsg = edje_load_error_str(err);
EINA_LOG_ERR("Could not load theme '%s' from file '%s': #%d '%s'",
- theme.utf8().data(), group, err, errmsg);
+ group, theme.utf8().data(), err, errmsg);
return;
}
diff --git a/WebCore/platform/graphics/FloatPoint.cpp b/WebCore/platform/graphics/FloatPoint.cpp
index cf3d548..7e85b52 100644
--- a/WebCore/platform/graphics/FloatPoint.cpp
+++ b/WebCore/platform/graphics/FloatPoint.cpp
@@ -30,6 +30,7 @@
#include "TransformationMatrix.h"
#include "FloatConversion.h"
#include "IntPoint.h"
+#include <math.h>
namespace WebCore {
@@ -37,6 +38,21 @@ FloatPoint::FloatPoint(const IntPoint& p) : m_x(p.x()), m_y(p.y())
{
}
+void FloatPoint::normalize()
+{
+ float tempLength = length();
+
+ if (tempLength) {
+ m_x /= tempLength;
+ m_y /= tempLength;
+ }
+}
+
+float FloatPoint::length() const
+{
+ return sqrtf(lengthSquared());
+}
+
FloatPoint FloatPoint::matrixTransform(const AffineTransform& transform) const
{
double newX, newY;
diff --git a/WebCore/platform/graphics/FloatPoint.h b/WebCore/platform/graphics/FloatPoint.h
index 5018f1d..73a1bac 100644
--- a/WebCore/platform/graphics/FloatPoint.h
+++ b/WebCore/platform/graphics/FloatPoint.h
@@ -80,6 +80,11 @@ public:
void setX(float x) { m_x = x; }
void setY(float y) { m_y = y; }
+ void set(float x, float y)
+ {
+ m_x = x;
+ m_y = y;
+ }
void move(float dx, float dy)
{
m_x += dx;
@@ -91,6 +96,19 @@ public:
m_y *= sy;
}
+ void normalize();
+
+ float dot(const FloatPoint& a) const
+ {
+ return m_x * a.x() + m_y * a.y();
+ }
+
+ float length() const;
+ float lengthSquared() const
+ {
+ return m_x * m_x + m_y * m_y;
+ }
+
#if PLATFORM(CG)
FloatPoint(const CGPoint&);
operator CGPoint() const;
@@ -173,6 +191,12 @@ inline bool operator!=(const FloatPoint& a, const FloatPoint& b)
return a.x() != b.x() || a.y() != b.y();
}
+inline float operator*(const FloatPoint& a, const FloatPoint& b)
+{
+ // dot product
+ return a.dot(b);
+}
+
inline IntPoint roundedIntPoint(const FloatPoint& p)
{
return IntPoint(static_cast<int>(roundf(p.x())), static_cast<int>(roundf(p.y())));
diff --git a/WebCore/platform/graphics/FloatPoint3D.cpp b/WebCore/platform/graphics/FloatPoint3D.cpp
index 3d37eea..bb05e7f 100644
--- a/WebCore/platform/graphics/FloatPoint3D.cpp
+++ b/WebCore/platform/graphics/FloatPoint3D.cpp
@@ -21,21 +21,27 @@
#include "config.h"
-#include <math.h>
#include "FloatPoint3D.h"
+#include <math.h>
+
namespace WebCore {
void FloatPoint3D::normalize()
{
- float length = sqrtf(m_x * m_x + m_y * m_y + m_z * m_z);
+ float tempLength = length();
- if (length != 0) {
- m_x /= length;
- m_y /= length;
- m_z /= length;
+ if (tempLength) {
+ m_x /= tempLength;
+ m_y /= tempLength;
+ m_z /= tempLength;
}
}
+float FloatPoint3D::length() const
+{
+ return sqrtf(lengthSquared());
+}
+
} // namespace WebCore
diff --git a/WebCore/platform/graphics/FloatPoint3D.h b/WebCore/platform/graphics/FloatPoint3D.h
index d10e3c1..9ee548d 100644
--- a/WebCore/platform/graphics/FloatPoint3D.h
+++ b/WebCore/platform/graphics/FloatPoint3D.h
@@ -65,15 +65,85 @@ public:
float z() const { return m_z; }
void setZ(float z) { m_z = z; }
+ void set(float x, float y, float z)
+ {
+ m_x = x;
+ m_y = y;
+ m_z = z;
+ }
+ void move(float dx, float dy, float dz)
+ {
+ m_x += dx;
+ m_y += dy;
+ m_z += dz;
+ }
+ void scale(float sx, float sy, float sz)
+ {
+ m_x *= sx;
+ m_y *= sy;
+ m_z *= sz;
+ }
void normalize();
+ float dot(const FloatPoint3D& a) const
+ {
+ return m_x * a.x() + m_y * a.y() + m_z * a.z();
+ }
+
+ // Sets this FloatPoint3D to the cross product of the passed two.
+ // It is safe for "this" to be the same as either or both of the
+ // arguments.
+ void cross(const FloatPoint3D& a, const FloatPoint3D& b)
+ {
+ float x = a.y() * b.z() - a.z() * b.y();
+ float y = a.z() * b.x() - a.x() * b.z();
+ float z = a.x() * b.y() - a.y() * b.x();
+ m_x = x;
+ m_y = y;
+ m_z = z;
+ }
+
+ // Convenience function returning "this cross point" as a
+ // stack-allocated result.
+ FloatPoint3D cross(const FloatPoint3D& point) const
+ {
+ FloatPoint3D result;
+ result.cross(*this, point);
+ return result;
+ }
+
+ float length() const;
+ float lengthSquared() const { return this->dot(*this); }
+
private:
float m_x;
float m_y;
float m_z;
};
+inline FloatPoint3D& operator +=(FloatPoint3D& a, const FloatPoint3D& b)
+{
+ a.move(b.x(), b.y(), b.z());
+ return a;
+}
+
+inline FloatPoint3D& operator -=(FloatPoint3D& a, const FloatPoint3D& b)
+{
+ a.move(-b.x(), -b.y(), -b.z());
+ return a;
+}
+
+inline FloatPoint3D operator+(const FloatPoint3D& a, const FloatPoint3D& b)
+{
+ return FloatPoint3D(a.x() + b.x(), a.y() + b.y(), a.z() + b.z());
+}
+
+inline FloatPoint3D operator-(const FloatPoint3D& a, const FloatPoint3D& b)
+{
+ return FloatPoint3D(a.x() - b.x(), a.y() - b.y(), a.z() - b.z());
+}
+
inline bool operator==(const FloatPoint3D& a, const FloatPoint3D& b)
{
return a.x() == b.x() && a.y() == b.y() && a.z() == b.z();
@@ -87,7 +157,7 @@ inline bool operator!=(const FloatPoint3D& a, const FloatPoint3D& b)
inline float operator*(const FloatPoint3D& a, const FloatPoint3D& b)
{
// dot product
- return a.x() * b.x() + a.y() * b.y() + a.z() * b.z();
+ return a.dot(b);
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/FloatRect.cpp b/WebCore/platform/graphics/FloatRect.cpp
index 6dfa808..0d8a24e 100644
--- a/WebCore/platform/graphics/FloatRect.cpp
+++ b/WebCore/platform/graphics/FloatRect.cpp
@@ -76,10 +76,7 @@ void FloatRect::intersect(const FloatRect& other)
b = 0;
}
- m_location.setX(l);
- m_location.setY(t);
- m_size.setWidth(r - l);
- m_size.setHeight(b - t);
+ setLocationAndSizeFromEdges(l, t, r, b);
}
void FloatRect::unite(const FloatRect& other)
@@ -97,10 +94,7 @@ void FloatRect::unite(const FloatRect& other)
float r = max(right(), other.right());
float b = max(bottom(), other.bottom());
- m_location.setX(l);
- m_location.setY(t);
- m_size.setWidth(r - l);
- m_size.setHeight(b - t);
+ setLocationAndSizeFromEdges(l, t, r, b);
}
void FloatRect::scale(float sx, float sy)
@@ -111,6 +105,65 @@ void FloatRect::scale(float sx, float sy)
m_size.setHeight(height() * sy);
}
+void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1)
+{
+ float left = min(p0.x(), p1.x());
+ float top = min(p0.y(), p1.y());
+ float right = max(p0.x(), p1.x());
+ float bottom = max(p0.y(), p1.y());
+
+ setLocationAndSizeFromEdges(left, top, right, bottom);
+}
+
+namespace {
+// Helpers for 3- and 4-way max and min.
+
+template <typename T>
+T min3(const T& v1, const T& v2, const T& v3)
+{
+ return min(min(v1, v2), v3);
+}
+
+template <typename T>
+T max3(const T& v1, const T& v2, const T& v3)
+{
+ return max(max(v1, v2), v3);
+}
+
+template <typename T>
+T min4(const T& v1, const T& v2, const T& v3, const T& v4)
+{
+ return min(min(v1, v2), min(v3, v4));
+}
+
+template <typename T>
+T max4(const T& v1, const T& v2, const T& v3, const T& v4)
+{
+ return max(max(v1, v2), max(v3, v4));
+}
+
+} // anonymous namespace
+
+void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2)
+{
+ float left = min3(p0.x(), p1.x(), p2.x());
+ float top = min3(p0.y(), p1.y(), p2.y());
+ float right = max3(p0.x(), p1.x(), p2.x());
+ float bottom = max3(p0.y(), p1.y(), p2.y());
+
+ setLocationAndSizeFromEdges(left, top, right, bottom);
+}
+
+void FloatRect::fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3)
+{
+ float left = min4(p0.x(), p1.x(), p2.x(), p3.x());
+ float top = min4(p0.y(), p1.y(), p2.y(), p3.y());
+ float right = max4(p0.x(), p1.x(), p2.x(), p3.x());
+ float bottom = max4(p0.y(), p1.y(), p2.y(), p3.y());
+
+ setLocationAndSizeFromEdges(left, top, right, bottom);
+}
+
static inline int safeFloatToInt(float x)
{
static const int s_intMax = std::numeric_limits<int>::max();
diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h
index 2b23576..e387927 100644
--- a/WebCore/platform/graphics/FloatRect.h
+++ b/WebCore/platform/graphics/FloatRect.h
@@ -96,7 +96,9 @@ public:
bool isEmpty() const { return m_size.isEmpty(); }
+ float left() const { return x(); }
float right() const { return x() + width(); }
+ float top() const { return y(); }
float bottom() const { return y() + height(); }
FloatPoint center() const { return FloatPoint(x() + width() / 2, y() + height() / 2); }
@@ -129,6 +131,11 @@ public:
void scale(float s) { scale(s, s); }
void scale(float sx, float sy);
+ // Re-initializes this rectangle to fit the sets of passed points.
+ void fitToPoints(const FloatPoint& p0, const FloatPoint& p1);
+ void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2);
+ void fitToPoints(const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3);
+
#if PLATFORM(CG)
FloatRect(const CGRect&);
operator CGRect() const;
@@ -168,6 +175,13 @@ public:
private:
FloatPoint m_location;
FloatSize m_size;
+
+ void setLocationAndSizeFromEdges(float left, float top, float right, float bottom)
+ {
+ m_location.set(left, top);
+ m_size.setWidth(right - left);
+ m_size.setHeight(bottom - top);
+ }
};
inline FloatRect intersection(const FloatRect& a, const FloatRect& b)
diff --git a/WebCore/platform/graphics/FloatSize.cpp b/WebCore/platform/graphics/FloatSize.cpp
index 86fa4c0..c199297 100644
--- a/WebCore/platform/graphics/FloatSize.cpp
+++ b/WebCore/platform/graphics/FloatSize.cpp
@@ -29,6 +29,7 @@
#include "FloatConversion.h"
#include "IntSize.h"
+#include <math.h>
namespace WebCore {
@@ -36,6 +37,11 @@ FloatSize::FloatSize(const IntSize& size) : m_width(size.width()), m_height(size
{
}
+float FloatSize::diagonalLength() const
+{
+ return sqrtf(diagonalLengthSquared());
+}
+
FloatSize FloatSize::narrowPrecision(double width, double height)
{
return FloatSize(narrowPrecisionToFloat(width), narrowPrecisionToFloat(height));
diff --git a/WebCore/platform/graphics/FloatSize.h b/WebCore/platform/graphics/FloatSize.h
index ff3d4de..160fc9a 100644
--- a/WebCore/platform/graphics/FloatSize.h
+++ b/WebCore/platform/graphics/FloatSize.h
@@ -83,6 +83,12 @@ public:
m_height < other.m_height ? m_height : other.m_height);
}
+ float diagonalLength() const;
+ float diagonalLengthSquared() const
+ {
+ return m_width * m_width + m_height * m_height;
+ }
+
#if PLATFORM(CG) || (PLATFORM(WX) && OS(DARWIN))
explicit FloatSize(const CGSize&); // don't do this implicitly since it's lossy
operator CGSize() const;
diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp
index bb4f858..94f3424 100644
--- a/WebCore/platform/graphics/GraphicsContext.cpp
+++ b/WebCore/platform/graphics/GraphicsContext.cpp
@@ -130,29 +130,29 @@ void GraphicsContext::setStrokeColor(const Color& color, ColorSpace colorSpace)
setPlatformStrokeColor(color, colorSpace);
}
-void GraphicsContext::setShadow(const FloatSize& size, float blur, const Color& color, ColorSpace colorSpace)
+void GraphicsContext::setShadow(const FloatSize& offset, float blur, const Color& color, ColorSpace colorSpace)
{
- m_common->state.shadowSize = size;
+ m_common->state.shadowOffset = offset;
m_common->state.shadowBlur = blur;
m_common->state.shadowColor = color;
- setPlatformShadow(size, blur, color, colorSpace);
+ setPlatformShadow(offset, blur, color, colorSpace);
}
void GraphicsContext::clearShadow()
{
- m_common->state.shadowSize = IntSize();
+ m_common->state.shadowOffset = FloatSize();
m_common->state.shadowBlur = 0;
m_common->state.shadowColor = Color();
clearPlatformShadow();
}
-bool GraphicsContext::getShadow(FloatSize& size, float& blur, Color& color) const
+bool GraphicsContext::getShadow(FloatSize& offset, float& blur, Color& color) const
{
- size = m_common->state.shadowSize;
+ offset = m_common->state.shadowOffset;
blur = m_common->state.shadowBlur;
color = m_common->state.shadowColor;
- return color.isValid() && color.alpha() && (blur || size.width() || size.height());
+ return color.isValid() && color.alpha() && (blur || offset.width() || offset.height());
}
float GraphicsContext::strokeThickness() const
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index 1056d81..c5440f3 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -40,6 +40,7 @@
#if PLATFORM(CG)
typedef struct CGContext PlatformGraphicsContext;
#elif PLATFORM(CAIRO)
+#include "PlatformRefPtrCairo.h"
typedef struct _cairo PlatformGraphicsContext;
#elif PLATFORM(OPENVG)
namespace WebCore {
@@ -306,7 +307,12 @@ namespace WebCore {
FloatRect roundToDevicePixels(const FloatRect&);
void drawLineForText(const IntPoint&, int width, bool printing);
- void drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar);
+ enum TextCheckingLineStyle {
+ TextCheckingSpellingLineStyle,
+ TextCheckingGrammarLineStyle,
+ TextCheckingReplacementLineStyle
+ };
+ void drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle);
bool paintingDisabled() const;
void setPaintingDisabled(bool);
@@ -332,8 +338,11 @@ namespace WebCore {
void setAlpha(float);
#if PLATFORM(CAIRO)
float getAlpha();
- void createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius);
- static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur);
+ void applyPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius);
+ PlatformRefPtr<cairo_surface_t> createShadowMask(PassOwnPtr<ImageBuffer>, const FloatRect&, float radius);
+
+ static void calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowOffset, float shadowBlur);
+ void drawTiledShadow(const IntRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius, ColorSpace colorSpace);
#endif
void setCompositeOperation(CompositeOperator);
diff --git a/WebCore/platform/graphics/GraphicsContextPrivate.h b/WebCore/platform/graphics/GraphicsContextPrivate.h
index 6bf465b..903c7e3 100644
--- a/WebCore/platform/graphics/GraphicsContextPrivate.h
+++ b/WebCore/platform/graphics/GraphicsContextPrivate.h
@@ -72,7 +72,7 @@ namespace WebCore {
bool paintingDisabled;
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp
index 87060a4..a5db85f 100644
--- a/WebCore/platform/graphics/MediaPlayer.cpp
+++ b/WebCore/platform/graphics/MediaPlayer.cpp
@@ -564,17 +564,10 @@ MediaPlayer::SupportsType MediaPlayer::supportsType(ContentType contentType)
String type = contentType.type().lower();
String typeCodecs = contentType.parameter(codecs());
- // 4.8.10.3 MIME types - In the absence of a specification to the contrary, the MIME type "application/octet-stream"
- // when used with parameters, e.g. "application/octet-stream;codecs=theora", is a type that the user agent knows
- // it cannot render.
- if (type == applicationOctetStream()) {
- if (!typeCodecs.isEmpty())
- return IsNotSupported;
-
- // The MIME type "application/octet-stream" with no parameters is never a type that the user agent knows it
- // cannot render.
- return MayBeSupported;
- }
+ // 4.8.10.3 MIME types - The canPlayType(type) method must return the empty string if type is a type that the
+ // user agent knows it cannot render or is the type "application/octet-stream"
+ if (type == applicationOctetStream())
+ return IsNotSupported;
MediaPlayerFactory* engine = chooseBestEngineForTypeAndCodecs(type, typeCodecs);
if (!engine)
diff --git a/WebCore/platform/graphics/PathTraversalState.cpp b/WebCore/platform/graphics/PathTraversalState.cpp
index d202649..ecdcb1b 100644
--- a/WebCore/platform/graphics/PathTraversalState.cpp
+++ b/WebCore/platform/graphics/PathTraversalState.cpp
@@ -160,7 +160,7 @@ PathTraversalState::PathTraversalState(PathTraversalAction action)
float PathTraversalState::closeSubpath()
{
float distance = distanceLine(m_current, m_start);
- m_start = m_control1 = m_control2 = m_current;
+ m_current = m_control1 = m_control2 = m_start;
return distance;
}
diff --git a/WebCore/platform/graphics/cairo/FontCairo.cpp b/WebCore/platform/graphics/cairo/FontCairo.cpp
index f6d8f3d..cd5d362 100644
--- a/WebCore/platform/graphics/cairo/FontCairo.cpp
+++ b/WebCore/platform/graphics/cairo/FontCairo.cpp
@@ -70,11 +70,11 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
}
// Text shadow, inspired by FontMac
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur = 0;
Color shadowColor;
bool hasShadow = context->textDrawingMode() & cTextFill
- && context->getShadow(shadowSize, shadowBlur, shadowColor);
+ && context->getShadow(shadowOffset, shadowBlur, shadowColor);
// TODO: Blur support
if (hasShadow) {
@@ -95,7 +95,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
IntSize shadowBufferSize;
FloatRect shadowRect;
float radius = 0;
- context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
+ context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur);
// Draw shadow into a new ImageBuffer
OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
@@ -113,9 +113,9 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
cairo_restore(shadowCr);
}
cairo_translate(cr, 0.0, -extents.height);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+ context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
#else
- cairo_translate(cr, shadowSize.width(), shadowSize.height());
+ cairo_translate(cr, shadowOffset.width(), shadowOffset.height());
cairo_show_glyphs(cr, glyphs, numGlyphs);
if (font->syntheticBoldOffset()) {
cairo_save(cr);
@@ -195,7 +195,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
// Re-enable the platform shadow we disabled earlier
if (hasShadow)
- context->setShadow(shadowSize, shadowBlur, shadowColor, DeviceColorSpace);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace);
cairo_restore(cr);
}
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 3a667ac..19cc518 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -44,6 +44,7 @@
#include "NotImplemented.h"
#include "Path.h"
#include "Pattern.h"
+#include "PlatformRefPtrCairo.h"
#include "SimpleFontData.h"
#include "SourceGraphic.h"
@@ -175,7 +176,7 @@ static void addConvexPolygonToContext(cairo_t* context, size_t numPoints, const
cairo_close_path(context);
}
-void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)
+void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& radius, const FloatRect& sourceRect, const FloatSize& shadowOffset, float shadowBlur)
{
#if ENABLE(FILTERS)
// limit radius to 128
@@ -185,17 +186,17 @@ void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize,
// determine dimensions of shadow rect
shadowRect = FloatRect(sourceRect.location(), shadowBufferSize);
- shadowRect.move(shadowSize.width() - radius, shadowSize.height() - radius);
+ shadowRect.move(shadowOffset.width() - radius, shadowOffset.height() - radius);
#endif
}
static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPrivate* gcp, bool fillShadow, bool strokeShadow)
{
#if ENABLE(FILTERS)
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (!context->getShadow(shadowSize, shadowBlur, shadowColor))
+ if (!context->getShadow(shadowOffset, shadowBlur, shadowColor))
return;
// Calculate filter values to create appropriate shadow.
@@ -211,7 +212,7 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva
IntSize shadowBufferSize;
FloatRect shadowRect;
float radius = 0;
- GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
+ GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur);
// Create suitably-sized ImageBuffer to hold the shadow.
OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
@@ -228,7 +229,7 @@ static inline void drawPathShadow(GraphicsContext* context, GraphicsContextPriva
if (strokeShadow)
setPlatformStroke(context, shadowContext, gcp);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+ context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
#endif
}
@@ -623,24 +624,38 @@ void GraphicsContext::fillRect(const FloatRect& rect)
static void drawBorderlessRectShadow(GraphicsContext* context, const FloatRect& rect, const Color& rectColor)
{
#if ENABLE(FILTERS)
- FloatSize shadowSize;
+ AffineTransform transform = context->getCTM();
+ // drawTiledShadow still does not work with rotations.
+ if ((transform.isIdentityOrTranslationOrFlipped())) {
+ cairo_t* cr = context->platformContext();
+ cairo_save(cr);
+ appendWebCorePathToCairoContext(cr, Path::createRectangle(rect));
+ FloatSize corner;
+ IntRect shadowRect(rect);
+ context->drawTiledShadow(shadowRect, corner, corner, corner, corner, DeviceColorSpace);
+ cairo_restore(cr);
+
+ return;
+ }
+
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (!context->getShadow(shadowSize, shadowBlur, shadowColor))
+ if (!context->getShadow(shadowOffset, shadowBlur, shadowColor))
return;
IntSize shadowBufferSize;
FloatRect shadowRect;
float radius = 0;
- GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowSize, shadowBlur);
+ GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, rect, shadowOffset, shadowBlur);
// Draw shadow into a new ImageBuffer
OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
GraphicsContext* shadowContext = shadowBuffer->context();
shadowContext->fillRect(FloatRect(FloatPoint(radius, radius), rect.size()), rectColor, DeviceColorSpace);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+ context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
#endif
}
@@ -759,7 +774,7 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
#include "DrawErrorUnderline.h"
#endif
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style)
{
if (paintingDisabled())
return;
@@ -767,12 +782,17 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin,
cairo_t* cr = m_data->cr;
cairo_save(cr);
- // Convention is green for grammar, red for spelling
- // These need to become configurable
- if (grammar)
- cairo_set_source_rgb(cr, 0, 1, 0);
- else
+ switch (style) {
+ case TextCheckingSpellingLineStyle:
cairo_set_source_rgb(cr, 1, 0, 0);
+ break;
+ case TextCheckingGrammarLineStyle:
+ cairo_set_source_rgb(cr, 0, 1, 0);
+ break;
+ default:
+ cairo_restore(cr);
+ return;
+ }
#if PLATFORM(GTK)
// We ignore most of the provided constants in favour of the platform style
@@ -917,24 +937,29 @@ void GraphicsContext::setPlatformShadow(FloatSize const& size, float, Color cons
if (m_common->state.shadowsIgnoreTransforms) {
// 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.shadowSize = FloatSize(size.width(), -size.height());
+ m_common->state.shadowOffset = FloatSize(size.width(), -size.height());
}
}
-void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius)
+void GraphicsContext::applyPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const Color& shadowColor, const FloatRect& shadowRect, float radius)
{
#if ENABLE(FILTERS)
- cairo_t* cr = m_data->cr;
+ setColor(m_data->cr, shadowColor);
+ PlatformRefPtr<cairo_surface_t> shadowMask(createShadowMask(buffer, shadowRect, radius));
+ cairo_mask_surface(m_data->cr, shadowMask.get(), shadowRect.x(), shadowRect.y());
+#endif
+}
- // calculate the standard deviation
- float sd = FEGaussianBlur::calculateStdDeviation(radius);
+PlatformRefPtr<cairo_surface_t> GraphicsContext::createShadowMask(PassOwnPtr<ImageBuffer> buffer, const FloatRect& shadowRect, float radius)
+{
+#if ENABLE(FILTERS)
+ if (!radius)
+ return buffer->m_data.m_surface;
- // draw the shadow without blurring, if radius is zero
- if (!radius || !sd) {
- setColor(cr, shadowColor);
- cairo_mask_surface(cr, buffer->m_data.m_surface, shadowRect.x(), shadowRect.y());
- return;
- }
+ FloatPoint blurRadius = FloatPoint(radius, radius);
+ float sd = FEGaussianBlur::calculateStdDeviation(radius);
+ if (!sd)
+ return buffer->m_data.m_surface;
// create filter
RefPtr<Filter> filter = ImageBufferFilter::create();
@@ -945,14 +970,11 @@ void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const
RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), sd, sd);
blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
blur->apply(filter.get());
-
- // Mask the filter with the shadow color and draw it to the context.
- // Masking makes it possible to just blur the alpha channel.
- setColor(cr, shadowColor);
- cairo_mask_surface(cr, blur->resultImage()->m_data.m_surface, shadowRect.x(), shadowRect.y());
+ return blur->resultImage()->m_data.m_surface;
#endif
}
+
void GraphicsContext::clearPlatformShadow()
{
notImplemented();
@@ -1218,6 +1240,200 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& r)
clipOut(p);
}
+static inline FloatPoint getPhase(const FloatRect& dest, const FloatRect& tile)
+{
+ FloatPoint phase = dest.location();
+ phase.move(-tile.x(), -tile.y());
+
+ return phase;
+}
+
+/*
+ This function uses tiling to improve the performance of the shadow
+ drawing of rounded rectangles. The code basically does the following
+ steps:
+
+ 1. Calculate the minimum rectangle size required to create the
+ tiles
+
+ 2. If that size is smaller than the real rectangle render the new
+ small rectangle and its shadow in a new surface, in other case
+ render the shadow of the real rectangle in the destination
+ surface.
+
+ 3. Calculate the sizes and positions of the tiles and their
+ destinations and use drawPattern to render the final shadow. The
+ code divides the rendering in 8 tiles:
+
+ 1 | 2 | 3
+ -----------
+ 4 | | 5
+ -----------
+ 6 | 7 | 8
+
+ The corners are directly copied from the small rectangle to the
+ real one and the side tiles are 1 pixel width, we use them as
+
+ tiles to cover the destination side. The corner tiles are bigger
+ than just the side of the rounded corner, we need to increase it
+ because the modifications caused by the corner over the blur
+ effect. We fill the central part with solid color to complete the
+ shadow.
+ */
+void GraphicsContext::drawTiledShadow(const IntRect& rect, const FloatSize& topLeftRadius, const FloatSize& topRightRadius, const FloatSize& bottomLeftRadius, const FloatSize& bottomRightRadius, ColorSpace colorSpace)
+{
+#if ENABLE(FILTERS)
+ FloatSize shadowSize;
+ float shadowBlur;
+ Color shadowColor;
+ if (!getShadow(shadowSize, shadowBlur, shadowColor))
+ return;
+
+ // Calculate filter values to create appropriate shadow.
+ cairo_t* cr = m_data->cr;
+
+ IntSize shadowBufferSize;
+ FloatRect shadowRect;
+ float blurRadius = 0;
+ GraphicsContext::calculateShadowBufferDimensions(shadowBufferSize, shadowRect, blurRadius, rect, shadowSize, shadowBlur);
+
+ // Size of the tiling side.
+ int sideTileWidth = 1;
+ float radiusTwice = blurRadius * 2;
+
+ // Find the extra space needed from the curve of the corners.
+ int extraWidthFromCornerRadii = radiusTwice + max(topLeftRadius.width(), bottomLeftRadius.width()) +
+ radiusTwice + max(topRightRadius.width(), bottomRightRadius.width());
+ int extraHeightFromCornerRadii = radiusTwice + max(topLeftRadius.height(), topRightRadius.height()) +
+ radiusTwice + max(bottomLeftRadius.height(), bottomRightRadius.height());
+
+ // The length of a side of the buffer is the enough space for four blur radii,
+ // the radii of the corners, and then 1 pixel to draw the side tiles.
+ IntSize smallBufferSize = IntSize(sideTileWidth + extraWidthFromCornerRadii,
+ sideTileWidth + extraHeightFromCornerRadii);
+
+ if ((smallBufferSize.width() > shadowBufferSize.width()) || (smallBufferSize.height() > shadowBufferSize.height()) || (blurRadius <= 0)) {
+ // Create suitably-sized ImageBuffer to hold the shadow.
+ OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
+ if (!shadowBuffer)
+ return;
+
+ // Draw shadow into a new ImageBuffer.
+ cairo_t* shadowContext = shadowBuffer->context()->platformContext();
+ 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);
+
+ setPlatformFill(this, shadowContext, m_common);
+
+ applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, blurRadius);
+
+ return;
+ }
+
+ OwnPtr<ImageBuffer> smallBuffer = ImageBuffer::create(smallBufferSize);
+ if (!smallBuffer)
+ return;
+
+ IntRect smallRect = IntRect(blurRadius, blurRadius, smallBufferSize.width() - radiusTwice, smallBufferSize.height() - radiusTwice);
+
+ // Draw shadow into a new ImageBuffer.
+ cairo_t* smallBufferContext = smallBuffer->context()->platformContext();
+ copyContextProperties(cr, smallBufferContext);
+ appendWebCorePathToCairoContext(smallBuffer->context()->platformContext(), Path::createRoundedRectangle(smallRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius));
+ setPlatformFill(this, smallBufferContext, m_common);
+
+ OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(smallBufferSize);
+ if (!shadowBuffer)
+ return;
+
+ smallRect.setSize(smallBufferSize);
+
+ PlatformRefPtr<cairo_surface_t> shadowMask(createShadowMask(smallBuffer.release(), smallRect, blurRadius));
+
+ cairo_t* shadowContext = shadowBuffer->context()->platformContext();
+ setColor(shadowContext, shadowColor);
+ cairo_mask_surface(shadowContext, shadowMask.get(), 0, 0);
+
+ // Fill the internal part of the shadow.
+ shadowRect.inflate(-radiusTwice);
+ if (!shadowRect.isEmpty()) {
+ cairo_save(cr);
+ appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(shadowRect, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius));
+ setColor(cr, shadowColor);
+ cairo_fill(cr);
+ cairo_restore(cr);
+ }
+ shadowRect.inflate(radiusTwice);
+
+ // Draw top side.
+ FloatRect tileRect = FloatRect(radiusTwice + topLeftRadius.width(), 0, sideTileWidth, radiusTwice);
+ FloatRect destRect = tileRect;
+ destRect.move(shadowRect.x(), shadowRect.y());
+ destRect.setWidth(shadowRect.width() - topLeftRadius.width() - topRightRadius.width() - blurRadius * 4);
+ FloatPoint phase = getPhase(destRect, tileRect);
+ AffineTransform patternTransform;
+ patternTransform.makeIdentity();
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the bottom side.
+ tileRect = FloatRect(radiusTwice + bottomLeftRadius.width(), smallBufferSize.height() - radiusTwice, sideTileWidth, radiusTwice);
+ destRect = tileRect;
+ destRect.move(shadowRect.x(), shadowRect.y() + radiusTwice + rect.height() - smallBufferSize.height());
+ destRect.setWidth(shadowRect.width() - bottomLeftRadius.width() - bottomRightRadius.width() - blurRadius * 4);
+ phase = getPhase(destRect, tileRect);
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the right side.
+ tileRect = FloatRect(smallBufferSize.width() - radiusTwice, radiusTwice + topRightRadius.height(), radiusTwice, sideTileWidth);
+ destRect = tileRect;
+ destRect.move(shadowRect.x() + radiusTwice + rect.width() - smallBufferSize.width(), shadowRect.y());
+ destRect.setHeight(shadowRect.height() - topRightRadius.height() - bottomRightRadius.height() - blurRadius * 4);
+ phase = getPhase(destRect, tileRect);
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the left side.
+ tileRect = FloatRect(0, radiusTwice + topLeftRadius.height(), radiusTwice, sideTileWidth);
+ destRect = tileRect;
+ destRect.move(shadowRect.x(), shadowRect.y());
+ destRect.setHeight(shadowRect.height() - topLeftRadius.height() - bottomLeftRadius.height() - blurRadius * 4);
+ phase = FloatPoint(destRect.x() - tileRect.x(), destRect.y() - tileRect.y());
+ shadowBuffer->drawPattern(this, tileRect, patternTransform,
+ phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the top left corner.
+ tileRect = FloatRect(0, 0, radiusTwice + topLeftRadius.width(), radiusTwice + topLeftRadius.height());
+ destRect = tileRect;
+ destRect.move(shadowRect.x(), shadowRect.y());
+ phase = getPhase(destRect, tileRect);
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the top right corner.
+ tileRect = FloatRect(smallBufferSize.width() - radiusTwice - topRightRadius.width(), 0, radiusTwice + topRightRadius.width(), radiusTwice + topRightRadius.height());
+ destRect = tileRect;
+ destRect.move(shadowRect.x() + rect.width() - smallBufferSize.width() + radiusTwice, shadowRect.y());
+ phase = getPhase(destRect, tileRect);
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the bottom right corner.
+ tileRect = FloatRect(smallBufferSize.width() - radiusTwice - bottomRightRadius.width(), smallBufferSize.height() - radiusTwice - bottomRightRadius.height(), radiusTwice + bottomRightRadius.width(), radiusTwice + bottomRightRadius.height());
+ destRect = tileRect;
+ destRect.move(shadowRect.x() + rect.width() - smallBufferSize.width() + radiusTwice, shadowRect.y() + rect.height() - smallBufferSize.height() + radiusTwice);
+ phase = getPhase(destRect, tileRect);
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+
+ // Draw the bottom left corner.
+ tileRect = FloatRect(0, smallBufferSize.height() - radiusTwice - bottomLeftRadius.height(), radiusTwice + bottomLeftRadius.width(), radiusTwice + bottomLeftRadius.height());
+ destRect = tileRect;
+ destRect.move(shadowRect.x(), shadowRect.y() + rect.height() - smallBufferSize.height() + radiusTwice);
+ phase = getPhase(destRect, tileRect);
+ shadowBuffer->drawPattern(this, tileRect, patternTransform, phase, colorSpace, CompositeSourceOver, destRect);
+#endif
+}
+
void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color, ColorSpace colorSpace)
{
if (paintingDisabled())
@@ -1227,7 +1443,12 @@ void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft,
cairo_save(cr);
appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
setColor(cr, color);
- drawPathShadow(this, m_common, true, false);
+ AffineTransform transform = this->getCTM();
+ // drawTiledShadow still does not work with rotations.
+ if (transform.isIdentityOrTranslationOrFlipped())
+ drawTiledShadow(r, topLeft, topRight, bottomLeft, bottomRight, colorSpace);
+ else
+ drawPathShadow(this, m_common, true, false);
cairo_fill(cr);
cairo_restore(cr);
}
diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp
index d9eb5e6..904e819 100644
--- a/WebCore/platform/graphics/cairo/ImageCairo.cpp
+++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp
@@ -135,14 +135,14 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
// Draw the shadow
#if ENABLE(FILTERS)
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (context->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ if (context->getShadow(shadowOffset, shadowBlur, shadowColor)) {
IntSize shadowBufferSize;
FloatRect shadowRect;
float radius = 0;
- context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowSize, shadowBlur);
+ context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowOffset, shadowBlur);
shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() * context->getAlpha()) / 255.f);
//draw shadow into a new ImageBuffer
@@ -153,7 +153,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height());
cairo_fill(shadowContext);
- context->createPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
+ context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
}
#endif
diff --git a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
index df14f9d..c4008cc 100644
--- a/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContext3DCG.cpp
@@ -34,6 +34,7 @@
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreGraphics/CGContext.h>
+#include <CoreGraphics/CGDataProvider.h>
#include <CoreGraphics/CGImage.h>
#include <wtf/RetainPtr.h>
@@ -48,62 +49,108 @@ bool GraphicsContext3D::getImageData(Image* image,
{
if (!image)
return false;
- CGImageRef cgImage = image->nativeImageForCurrentFrame();
+ CGImageRef cgImage;
+ RetainPtr<CGImageRef> decodedImage;
+ if (image->data()) {
+ ImageSource decoder(false);
+ decoder.setData(image->data(), true);
+ if (!decoder.frameCount())
+ return false;
+ decodedImage = decoder.createFrameAtIndex(0);
+ cgImage = decodedImage.get();
+ } else
+ cgImage = image->nativeImageForCurrentFrame();
if (!cgImage)
return false;
- int width = CGImageGetWidth(cgImage);
- int height = CGImageGetHeight(cgImage);
- // FIXME: we should get rid of this temporary copy where possible.
- int tempRowBytes = width * 4;
- Vector<uint8_t> tempVector;
- tempVector.resize(height * tempRowBytes);
- // Try to reuse the color space from the image to preserve its colors.
- // Some images use a color space (such as indexed) unsupported by the bitmap context.
- CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
- bool releaseColorSpace = false;
- CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
- switch (colorSpaceModel) {
- case kCGColorSpaceModelMonochrome:
- case kCGColorSpaceModelRGB:
- case kCGColorSpaceModelCMYK:
- case kCGColorSpaceModelLab:
- case kCGColorSpaceModelDeviceN:
+ size_t width = CGImageGetWidth(cgImage);
+ size_t height = CGImageGetHeight(cgImage);
+ if (!width || !height || CGImageGetBitsPerComponent(cgImage) != 8)
+ return false;
+ size_t componentsPerPixel = CGImageGetBitsPerPixel(cgImage) / 8;
+ SourceDataFormat srcDataFormat = kSourceFormatRGBA8;
+ AlphaOp neededAlphaOp = kAlphaDoNothing;
+ switch (CGImageGetAlphaInfo(cgImage)) {
+ case kCGImageAlphaPremultipliedFirst:
+ case kCGImageAlphaFirst:
+ case kCGImageAlphaNoneSkipFirst:
+ return false;
+ case kCGImageAlphaPremultipliedLast:
+ // 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 = kSourceFormatRA8;
+ break;
+ case 4:
+ srcDataFormat = kSourceFormatRGBA8;
+ break;
+ default:
+ return false;
+ }
break;
- default:
- colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear);
- releaseColorSpace = true;
+ case kCGImageAlphaLast:
+ if (premultiplyAlpha)
+ neededAlphaOp = kAlphaDoPremultiply;
+ switch (componentsPerPixel) {
+ case 1:
+ srcDataFormat = kSourceFormatA8;
+ break;
+ case 2:
+ srcDataFormat = kSourceFormatRA8;
+ break;
+ case 4:
+ srcDataFormat = kSourceFormatRGBA8;
+ break;
+ default:
+ return false;
+ }
break;
- }
- CGContextRef tempContext = CGBitmapContextCreate(tempVector.data(),
- width, height, 8, tempRowBytes,
- colorSpace,
- // FIXME: change this!
- kCGImageAlphaPremultipliedLast);
- if (releaseColorSpace)
- CGColorSpaceRelease(colorSpace);
- if (!tempContext)
+ case kCGImageAlphaNoneSkipLast:
+ switch (componentsPerPixel) {
+ case 2:
+ srcDataFormat = kSourceFormatRA8;
+ break;
+ case 4:
+ srcDataFormat = kSourceFormatRGBA8;
+ break;
+ default:
+ return false;
+ }
+ case kCGImageAlphaNone:
+ switch (componentsPerPixel) {
+ case 1:
+ srcDataFormat = kSourceFormatR8;
+ break;
+ case 3:
+ srcDataFormat = kSourceFormatRGB8;
+ break;
+ default:
+ return false;
+ }
+ break;
+ default:
return false;
- CGContextSetBlendMode(tempContext, kCGBlendModeCopy);
- CGContextDrawImage(tempContext,
- CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)),
- cgImage);
- CGContextRelease(tempContext);
- // Pack the pixel data into the output vector.
- unsigned long componentsPerPixel, bytesPerComponent;
- if (!computeFormatAndTypeParameters(format, type, &componentsPerPixel, &bytesPerComponent))
+ }
+ RetainPtr<CFDataRef> pixelData;
+ pixelData.adoptCF(CGDataProviderCopyData(CGImageGetDataProvider(cgImage)));
+ if (!pixelData)
return false;
- int rowBytes = width * componentsPerPixel * bytesPerComponent;
- outputVector.resize(height * rowBytes);
- CGImageAlphaInfo info = CGImageGetAlphaInfo(cgImage);
- bool hasAlphaChannel = (info != kCGImageAlphaNone
- && info != kCGImageAlphaNoneSkipLast
- && info != kCGImageAlphaNoneSkipFirst);
- AlphaOp neededAlphaOp = kAlphaDoNothing;
- if (!premultiplyAlpha && hasAlphaChannel)
- // FIXME: must fetch the image data before the premultiplication step.
- neededAlphaOp = kAlphaDoUnmultiply;
- return packPixels(tempVector.data(), kSourceFormatRGBA8, width, height, 0,
- format, type, neededAlphaOp, outputVector.data());
+ const UInt8* rgba = CFDataGetBytePtr(pixelData.get());
+ outputVector.resize(width * height * 4);
+ unsigned int srcUnpackAlignment = 0;
+ size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
+ unsigned int padding = bytesPerRow - componentsPerPixel * width;
+ if (padding) {
+ srcUnpackAlignment = padding + 1;
+ while (bytesPerRow % srcUnpackAlignment)
+ ++srcUnpackAlignment;
+ }
+ bool rt = packPixels(rgba, srcDataFormat, width, height, srcUnpackAlignment,
+ format, type, neededAlphaOp, outputVector.data());
+ return rt;
}
void GraphicsContext3D::paintToCanvas(const unsigned char* imagePixels, int imageWidth, int imageHeight, int canvasWidth, int canvasHeight, CGContextRef context)
diff --git a/WebCore/platform/graphics/chromium/CrossProcessFontLoading.h b/WebCore/platform/graphics/chromium/CrossProcessFontLoading.h
new file mode 100644
index 0000000..e1fb740
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/CrossProcessFontLoading.h
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+#ifndef CrossProcessFontLoading_h
+#define CrossProcessFontLoading_h
+
+#import <wtf/RefCounted.h>
+#import <wtf/RetainPtr.h>
+
+typedef struct CGFont* CGFontRef;
+typedef UInt32 ATSFontContainerRef;
+typedef UInt32 ATSFontRef;
+
+namespace WebCore {
+
+// MemoryActivatedFont encapsulates a font loaded from another process and
+// activated from memory.
+//
+// Responsibilities:
+// * Holder for the CGFontRef & ATSFontRef belonging to the activated font.
+// * Responsible for unloading the font container when done.
+//
+// Memory Management:
+// The class is reference counted, with each instance of FontPlatformData that
+// uses this class holding a reference to it.
+// Entries are kept track of internally in a hash to allow quick lookup
+// of existing instances for reuse:
+// - fontCacheBySrcFontContainerRef() - key is the ATSFontContainerRef
+// corresponding to the *original in-process NSFont* whose loading was blocked
+// by the sandbox.
+// This is needed to allow lookup of a pre-existing MemoryActivatedFont when
+// creating a new FontPlatformData object.
+//
+// Assumptions:
+// This code assumes that an ATSFontRef is a unique identifier tied to an
+// activated font. i.e. After we activate a font, its ATSFontRef doesn't
+// change.
+// It also assumes that the ATSFoncontainerRef for two in-memory NSFonts that
+// correspond to the same on-disk font file are always the same and don't change
+// with time.
+//
+// Flushing caches:
+// When the system notifies us of a system font cache flush, all FontDataCache
+// objects are destroyed. This should in turn dereference all
+// MemoryActivatedFonts and thus unload all in-memory fonts.
+class MemoryActivatedFont : public RefCounted<MemoryActivatedFont> {
+public:
+ // Use to create a new object, see docs on constructor below.
+ static PassRefPtr<MemoryActivatedFont> create(ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container);
+ ~MemoryActivatedFont();
+
+ // Get cached CGFontRef corresponding to the in-memory font.
+ CGFontRef cgFont() { return m_cgFont.get(); }
+
+ // Get cached ATSFontRef corresponding to the in-memory font.
+ ATSFontRef atsFontRef() { return m_atsFontRef; }
+
+private:
+ // srcFontRef - ATSFontRef belonging to the NSFont object that failed to
+ // load in-process.
+ // container - a font container corresponding to an identical font that
+ // we loaded cross-process.
+ MemoryActivatedFont(ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container);
+
+ ATSFontContainerRef m_fontContainer;
+ WTF::RetainPtr<CGFontRef> m_cgFont;
+ ATSFontRef m_atsFontRef;
+ ATSFontContainerRef m_srcFontContainerRef;
+};
+
+} // namespace WebCore
+
+#endif // CrossProcessFontLoading_h
diff --git a/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm b/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
new file mode 100644
index 0000000..a7ec03a
--- /dev/null
+++ b/WebCore/platform/graphics/chromium/CrossProcessFontLoading.mm
@@ -0,0 +1,217 @@
+/*
+ * This file is part of the internal font implementation.
+ *
+ * Copyright (c) 2010 Google Inc. 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.
+ *
+ */
+
+// This file provides additional functionality to the Mac FontPlatformData class
+// defined in WebCore/platform/cocoa/FontPlatformDataCocoa.mm .
+// Because we want to support loading fonts between processes in the face of
+// font loading being blocked by the sandbox, we need a mechnasim to both
+// do the loading of in-memory fonts and keep track of them.
+
+#import "config.h"
+#import "CrossProcessFontLoading.h"
+
+#import "../graphics/cocoa/FontPlatformData.h"
+#import "ChromiumBridge.h"
+#import <AppKit/NSFont.h>
+#import <wtf/HashMap.h>
+
+namespace WebCore {
+
+namespace {
+
+typedef HashMap<ATSFontContainerRef, MemoryActivatedFont*> FontContainerRefMemoryFontHash;
+
+// On 10.5, font loading is not blocked by the sandbox and thus there is no
+// need for the cross-process font loading mechanim.
+// On system versions >=10.6 cross-process font loading is required.
+bool OutOfProcessFontLoadingEnabled()
+{
+ static SInt32 systemVersion = 0;
+ if (!systemVersion) {
+ if (Gestalt(gestaltSystemVersion, &systemVersion) != noErr)
+ return false;
+ }
+
+ return systemVersion >= 0x1060;
+}
+
+FontContainerRefMemoryFontHash& fontCacheBySrcFontContainerRef()
+{
+ DEFINE_STATIC_LOCAL(FontContainerRefMemoryFontHash, srcFontRefCache, ());
+ return srcFontRefCache;
+}
+
+ATSFontContainerRef fontContainerRefFromNSFont(NSFont* srcFont)
+{
+ ATSFontRef fontRef = CTFontGetPlatformFont(toCTFontRef(srcFont), 0);
+ if (!fontRef)
+ return kATSFontContainerRefUnspecified;
+ ATSFontContainerRef fontContainer = kATSFontContainerRefUnspecified;
+ if (ATSFontGetContainer(fontRef, 0, &fontContainer) != noErr)
+ return kATSFontContainerRefUnspecified;
+ return fontContainer;
+}
+
+// The only way we can tell that an in-process font has failed to load
+// is if CTFontCopyGraphicsFont() returns the LastResort font.
+bool isLastResortFont(CGFontRef cgFont)
+{
+ NSString* fontName = (NSString*)CGFontCopyPostScriptName(cgFont);
+ return [fontName isEqualToString:@"LastResort"];
+}
+
+// Given an in-process font which has failed to load, return a
+// MemoryActivatedFont* corresponding to an in-memory representation of the
+// same font loaded from the browser process.
+// On failure this function returns a PassRefPtr pointing to 0.
+PassRefPtr<MemoryActivatedFont> loadFontFromBrowserProcess(NSFont* nsFont)
+{
+ ATSFontContainerRef container;
+ // Send cross-process request to load font.
+ if (!ChromiumBridge::loadFont(nsFont, &container))
+ return 0;
+
+ ATSFontContainerRef srcFontContainerRef = fontContainerRefFromNSFont(nsFont);
+ if (!srcFontContainerRef) {
+ ATSFontDeactivate(container, 0, kATSOptionFlagsDefault);
+ return 0;
+ }
+
+ PassRefPtr<MemoryActivatedFont> font = adoptRef(fontCacheBySrcFontContainerRef().get(srcFontContainerRef));
+ if (font.get())
+ return font;
+
+ return MemoryActivatedFont::create(srcFontContainerRef, container);
+}
+
+} // namespace
+
+PassRefPtr<MemoryActivatedFont> MemoryActivatedFont::create(ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container)
+{
+ MemoryActivatedFont* font = new MemoryActivatedFont(srcFontContainerRef, container);
+ if (!font->cgFont()) // Object construction failed.
+ {
+ delete font;
+ return 0;
+ }
+ return adoptRef(font);
+}
+
+MemoryActivatedFont::MemoryActivatedFont(ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container)
+ : m_fontContainer(container)
+ , m_atsFontRef(kATSFontRefUnspecified)
+ , m_srcFontContainerRef(srcFontContainerRef)
+{
+ if (!container)
+ return;
+
+ // Count the number of fonts in the container.
+ ItemCount fontCount = 0;
+ OSStatus err = ATSFontFindFromContainer(container, kATSOptionFlagsDefault, 0, 0, &fontCount);
+ if (err != noErr || fontCount < 1)
+ return;
+
+ // For now always assume that we want the first font in the container.
+ ATSFontFindFromContainer(container, kATSOptionFlagsDefault, 1, &m_atsFontRef, 0);
+
+ if (!m_atsFontRef)
+ return;
+
+ // Cache CGFont representation of the font.
+ m_cgFont.adoptCF(CGFontCreateWithPlatformFont(&m_atsFontRef));
+
+ if (!m_cgFont.get())
+ return;
+
+ // Add ourselves to cache.
+ fontCacheBySrcFontContainerRef().add(m_srcFontContainerRef, this);
+}
+
+// Destructor - Unload font container from memory and remove ourselves
+// from cache.
+MemoryActivatedFont::~MemoryActivatedFont()
+{
+ if (m_cgFont.get()) {
+ // First remove ourselves from the caches.
+ ASSERT(fontCacheBySrcFontContainerRef().contains(m_srcFontContainerRef));
+
+ fontCacheBySrcFontContainerRef().remove(m_srcFontContainerRef);
+
+ // Make sure the CGFont is destroyed before its font container.
+ m_cgFont.releaseRef();
+ }
+
+ if (m_fontContainer != kATSFontContainerRefUnspecified)
+ ATSFontDeactivate(m_fontContainer, 0, kATSOptionFlagsDefault);
+}
+
+// Given an NSFont, try to load a representation of that font into the cgFont
+// parameter. If loading is blocked by the sandbox, the font may be loaded
+// cross-process.
+// If sandbox loading also fails, a fallback font is loaded.
+//
+// Considerations:
+// * cgFont must be CFRelease()ed by the caller when done.
+//
+// Parameters:
+// * nsFont - The font we wish to load.
+// * fontSize - point size of the font we wish to load.
+// * outNSFont - The font that was actually loaded, may be different from nsFont
+// if a fallback font was used.
+// * cgFont - on output this contains the CGFontRef corresponding to the NSFont
+// that was picked in the end. The caller is responsible for calling
+// CFRelease() on this parameter when done with it.
+// * fontID - on output, the ID corresponding to nsFont.
+void FontPlatformData::loadFont(NSFont* nsFont, float fontSize, NSFont*& outNSFont, CGFontRef& cgFont, ATSUFontID& fontID)
+{
+ outNSFont = nsFont;
+ cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0);
+ MemoryActivatedFont* memFont = 0;
+ if (OutOfProcessFontLoadingEnabled() && outNSFont && cgFont && isLastResortFont(cgFont)) {
+ // Release old CGFontRef since it points at the LastResort font which we don't want.
+ CFRelease(cgFont);
+ cgFont = 0;
+
+ // Font loading was blocked by the Sandbox.
+ m_inMemoryFont = loadFontFromBrowserProcess(outNSFont);
+ if (m_inMemoryFont.get()) {
+ cgFont = m_inMemoryFont->cgFont();
+
+ // Need to add an extra retain so output semantics of this function
+ // are consistent.
+ CFRetain(cgFont);
+ } else {
+ // If we still can't load the font, then return Times,
+ // rather than the LastResort font.
+ outNSFont = [NSFont fontWithName:@"Times" size:fontSize];
+ cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0);
+ }
+ }
+
+ if (memFont) {
+ fontID = m_inMemoryFont->atsFontRef();
+ } else {
+ fontID = CTFontGetPlatformFont(toCTFontRef(outNSFont), 0);
+ }
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
index 5b8bad3..78b7517 100644
--- a/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
+++ b/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
@@ -273,10 +273,10 @@ bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
// If there is a non-blur shadow and both the fill color and shadow color
// are opaque, handle without skia.
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (m_graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ if (m_graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor)) {
// If there is a shadow and this code is reached, windowsCanHandleDrawTextShadow()
// will have already returned true during the ctor initiatization of m_useGDI
ASSERT(shadowColor.alpha() == 255);
@@ -285,7 +285,7 @@ bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
COLORREF savedTextColor = GetTextColor(m_hdc);
SetTextColor(m_hdc, textColor);
- ExtTextOut(m_hdc, x + shadowSize.width(), y + shadowSize.height(), ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
+ ExtTextOut(m_hdc, x + shadowOffset.width(), y + shadowOffset.height(), ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
SetTextColor(m_hdc, savedTextColor);
}
@@ -483,15 +483,15 @@ void Font::drawComplexText(GraphicsContext* graphicsContext,
// If there is a non-blur shadow and both the fill color and shadow color
// are opaque, handle without skia.
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor) && windowsCanHandleDrawTextShadow(graphicsContext)) {
+ if (graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor) && windowsCanHandleDrawTextShadow(graphicsContext)) {
COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
COLORREF savedTextColor = GetTextColor(hdc);
SetTextColor(hdc, textColor);
- state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowSize.width(),
- static_cast<int>(point.y() - ascent()) + shadowSize.height(), from, to);
+ state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowOffset.width(),
+ static_cast<int>(point.y() - ascent()) + shadowOffset.height(), from, to);
SetTextColor(hdc, savedTextColor);
}
diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm
deleted file mode 100644
index ad7ebba..0000000
--- a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumMac.mm
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * This file is part of the internal font implementation.
- *
- * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- * Copyright (c) 2010 Google Inc. 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.
- *
- */
-
-// This file is a clone of platform/graphics/mac/FontPlatformDataMac.mm.
-// Because we want to support loading fonts between processes in the face of
-// font loading being blocked by the sandbox, we must maintain a fork.
-// Please maintain this file by performing parallel changes to it.
-//
-// The only changes from FontPlatformDataMac should be:
-// - The functions at the top of this file for loading and caching fonts
-// cross-process.
-// - Changes to FontPlatformData::FontPlatformData(NSFont,bool,bool)
-// - Changes to FontPlatformData::setFont()
-// - Changes to FontPlatformData::~FontPlatformData()
-// - Calls to refMemoryFont() in FontPlatformData::operator= and copy
-// constructor.
-//
-// All changes are marked with "Start/End Chromium Change"
-//
-// For all other differences, if it was introduced in this file, then the
-// maintainer forgot to include it in the list; otherwise it is an update that
-// should have been applied to this file but was not.
-
-
-// Start Chromium Change
-#import "config.h"
-#import "../graphics/mac/FontPlatformData.h"
-
-#import "ChromiumBridge.h"
-#import "PlatformString.h"
-#import "WebCoreSystemInterface.h"
-#import <AppKit/NSFont.h>
-#import <wtf/HashMap.h>
-#import <wtf/RefCounted.h>
-#import <wtf/RetainPtr.h>
-#import <wtf/Vector.h>
-
-namespace WebCore {
-
-namespace {
-
-class MemoryActivatedFont;
-typedef HashMap<ATSFontRef, MemoryActivatedFont*> FontRefMemoryFontHash;
-typedef HashMap<ATSFontContainerRef, MemoryActivatedFont*> FontContainerRefMemoryFontHash;
-
-// On 10.5, font loading is not blocked by the sandbox and thus there is no
-// need for the cross-process font loading mechanim.
-// On system versions >=10.6 cross-process font loading is required.
-bool OutOfProcessFontLoadingEnabled()
-{
- static SInt32 systemVersion = 0;
- if (!systemVersion) {
- if (Gestalt(gestaltSystemVersion, &systemVersion) != noErr)
- return false;
- }
-
- return systemVersion >= 0x1060;
-}
-
-FontContainerRefMemoryFontHash& fontCacheBySrcFontContainerRef()
-{
- DEFINE_STATIC_LOCAL(FontContainerRefMemoryFontHash, srcFontRefCache, ());
- return srcFontRefCache;
-}
-
-FontRefMemoryFontHash& fontCacheByActualFontRef()
-{
- DEFINE_STATIC_LOCAL(FontRefMemoryFontHash, realFontRefCache, ());
- return realFontRefCache;
-}
-
-ATSFontContainerRef fontContainerRefFromNSFont(NSFont* srcFont)
-{
- ATSFontRef fontRef = CTFontGetPlatformFont(toCTFontRef(srcFont), 0);
- if (!fontRef)
- return kATSFontContainerRefUnspecified;
- ATSFontContainerRef fontContainer = kATSFontContainerRefUnspecified;
- if (ATSFontGetContainer(fontRef, 0, &fontContainer) != noErr)
- return kATSFontContainerRefUnspecified;
- return fontContainer;
-}
-
-// MemoryActivatedFont encapsulates a font loaded from another process and
-// activated from memory.
-//
-// Responsibilities:
-// * Holder for the CGFontRef & ATSFontRef belonging to the activated font.
-// * Responsible for unloading the font container when done.
-//
-// Memory Management:
-// The class is reference counted, with each instance of FontPlatformData that
-// uses this class holding a reference to it.
-// Entries in 2 hashes are maintained internally to allow quick lookup
-// of existing instances for reuse:
-// - fontCacheBySrcFontContainerRef() - key is the ATSFontContainerRef
-// corresponding to the *original in-process NSFont* whose loading was blocked
-// by the sandbox.
-// This is needed to allow lookup of a pre-existing MemoryActivatedFont when
-// creating a new FontPlatformData object.
-// - fontCacheByActualFontRef() - key is the ATSFontRef corresponding to the
-// *new in-memory font* that we got from the browser process.
-// This is needed so that a FontPlatformData object can refer back to the
-// MemoryActivatedFont it's using. Currently this is only needed to release
-// the font on FontPlatformData destruction.
-//
-// Assumptions:
-// This code assumes that an ATSFontRef is a unique identifier tied to an
-// activated font. i.e. After we activate a font, its ATSFontRef doesn't
-// change.
-// It also assumes that the ATSFoncontainerRef for two in-memory NSFonts that
-// correspond to the same on-disk font file are always the same and don't change
-// with time.
-//
-// Flushing caches:
-// When the system notifies us of a system font cache flush, all FontDataCache
-// objects are destroyed. This should in turn dereference all
-// MemoryActivatedFonts and thus unload all in-memory fonts.
-class MemoryActivatedFont : public RefCounted<MemoryActivatedFont> {
-public:
- // srcFontRef - ATSFontRef belonging to the NSFont object that failed to
- // load in-process.
- // container - a font container corresponding to an identical font that
- // we loaded cross-process.
- MemoryActivatedFont(ATSFontContainerRef srcFontContainerRef, ATSFontContainerRef container)
- : m_fontContainer(container)
- , m_atsFontRef(kATSFontRefUnspecified)
- , m_srcFontContainerRef(srcFontContainerRef)
- {
- if (!container)
- return;
-
- // Count the number of fonts in the container.
- ItemCount fontCount = 0;
- OSStatus err = ATSFontFindFromContainer(container, kATSOptionFlagsDefault, 0, 0, &fontCount);
- if (err != noErr || fontCount < 1)
- return;
-
- // For now always assume that we want the first font in the container.
- ATSFontFindFromContainer(container, kATSOptionFlagsDefault, 1, &m_atsFontRef, 0);
-
- if (!m_atsFontRef)
- return;
-
- // Cache CGFont representation of the font.
- m_cgFont.adoptCF(CGFontCreateWithPlatformFont(&m_atsFontRef));
-
- if (!m_cgFont.get())
- return;
-
- // Add ourselves to caches.
- fontCacheBySrcFontContainerRef().add(m_srcFontContainerRef, this);
- fontCacheByActualFontRef().add(m_atsFontRef, this);
- }
-
- // Get cached CGFontRef corresponding to the in-memory font.
- CGFontRef cgFont()
- {
- return m_cgFont.get();
- }
-
- // Get cached ATSFontRef corresponding to the in-memory font.
- ATSFontRef atsFontRef()
- {
- return m_atsFontRef;
- }
-
- // Destructor - Unload font container from memory and remove ourselves
- // from hashes.
- ~MemoryActivatedFont()
- {
- if (m_cgFont.get()) { // Object construction succeeded.
- // First remove ourselves from the caches.
- ASSERT(fontCacheBySrcFontContainerRef().contains(m_srcFontContainerRef));
- ASSERT(fontCacheByActualFontRef().contains(m_atsFontRef));
-
- fontCacheBySrcFontContainerRef().remove(m_srcFontContainerRef);
- fontCacheByActualFontRef().remove(m_atsFontRef);
-
- // Make sure the CGFont is destroyed before its font container.
- m_cgFont.releaseRef();
- }
-
- if (m_fontContainer != kATSFontContainerRefUnspecified)
- ATSFontDeactivate(m_fontContainer, 0, kATSOptionFlagsDefault);
- }
-
-private:
- ATSFontContainerRef m_fontContainer;
- WTF::RetainPtr<CGFontRef> m_cgFont;
- ATSFontRef m_atsFontRef;
- ATSFontContainerRef m_srcFontContainerRef;
-};
-
-// The only way we can tell that an in-process font has failed to load
-// is if CTFontCopyGraphicsFont() returns the LastResort font.
-bool isLastResortFont(CGFontRef cgFont)
-{
- NSString* fontName = (NSString*)CGFontCopyPostScriptName(cgFont);
- return [fontName isEqualToString:@"LastResort"];
-}
-
-// Given an in-process font which has failed to load, return a
-// MemoryActivatedFont* corresponding to an in-memory representation of the
-// same font loaded from the browser process.
-// The caller is responsbile for calling derefMemoryFont() on the ATSFontRef
-// of the returned font.
-// On failure this function returns 0, in which case the caller doesn't need
-// to perform any additional cleanup.
-MemoryActivatedFont* loadFontFromBrowserProcess(NSFont* nsFont)
-{
- ATSFontContainerRef container;
- // Send cross-process request to load font.
- if (!ChromiumBridge::loadFont(nsFont, &container))
- return 0;
-
- ATSFontContainerRef srcFontContainerRef = fontContainerRefFromNSFont(nsFont);
- if (!srcFontContainerRef) {
- ATSFontDeactivate(container, 0, kATSOptionFlagsDefault);
- return 0;
- }
-
- MemoryActivatedFont* font = fontCacheBySrcFontContainerRef().get(srcFontContainerRef);
- if (!font) {
- font = new MemoryActivatedFont(srcFontContainerRef, container);
- if (!font->cgFont()) {
- delete font;
- return 0;
- }
- } else {
- font->ref();
- }
-
- return font;
-}
-
-// deref() the MemoryActivatedFont corresponding to the given ATSFontRef. If no
-// corresponding MemoryActivatedFont object exists, no action is performed.
-void derefMemoryFont(ATSFontRef fontRef)
-{
- if (fontRef == kATSFontRefUnspecified)
- return;
- MemoryActivatedFont* font = fontCacheByActualFontRef().get(fontRef);
- if (font)
- font->deref();
-}
-
-// ref() the MemoryActivatedFont corresponding to the given ATSFontRef. If no
-// corresponding MemoryActivatedFont object exists, no action is performed.
-void refMemoryFont(ATSFontRef fontRef)
-{
- if (fontRef == kATSFontRefUnspecified)
- return;
- MemoryActivatedFont* font = fontCacheByActualFontRef().get(fontRef);
- if (font)
- font->ref();
-}
-
-// Given an NSFont, try to load a representation of that font into the cgFont
-// parameter. If loading is blocked by the sandbox, the font may be loaded
-// cross-process.
-// If sandbox loading also fails, a fallback font is loaded.
-//
-// Considerations:
-// * cgFont must be CFReleas()ed by the caller when done.
-//
-// Parameters:
-// * nsFont - The font we wish to load.
-// * fontSize - point size of the font we wish to load.
-// * outNSFont - The font that was actually loaded, may be different from nsFont
-// if a fallback font was used.
-// * cgFont - on output this contains the CGFontRef corresponding to the NSFont
-// that was picked in the end. The caller is responsible for calling
-// CFRelease() on this parameter when done with it.
-// * fontID - on output, the ID corresponding to nsFont.
-void loadFont(NSFont* nsFont, float fontSize, NSFont*& outNSFont, CGFontRef& cgFont, ATSUFontID& fontID)
-{
- outNSFont = nsFont;
- cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0);
- MemoryActivatedFont* memFont = 0;
- if (OutOfProcessFontLoadingEnabled() && outNSFont && cgFont && isLastResortFont(cgFont)) {
- // Release old CGFontRef since it points at the LastResort font which we don't want.
- CFRelease(cgFont);
- cgFont = 0;
-
- // Font loading was blocked by the Sandbox.
- memFont = loadFontFromBrowserProcess(outNSFont);
- if (memFont) {
- cgFont = memFont->cgFont();
-
- // Need to add an extra retain so output semantics of this function
- // are consistent.
- CFRetain(cgFont);
- } else {
- // If we still can't load the font, then return Times,
- // rather than the LastResort font.
- outNSFont = [NSFont fontWithName:@"Times" size:fontSize];
- cgFont = CTFontCopyGraphicsFont(toCTFontRef(outNSFont), 0);
- }
- }
-
- if (memFont) {
- fontID = memFont->atsFontRef();
- } else {
- fontID = CTFontGetPlatformFont(toCTFontRef(outNSFont), 0);
- }
-}
-
-} // namespace
-// End Chromium Change
-
-FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool syntheticOblique)
- : m_syntheticBold(syntheticBold)
- , m_syntheticOblique(syntheticOblique)
- , m_font(nsFont)
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- , m_isColorBitmapFont(CTFontGetSymbolicTraits(toCTFontRef(nsFont)) & kCTFontColorGlyphsTrait)
-#else
- , m_isColorBitmapFont(false)
-#endif
-{
-// Start Chromium Change
- m_size = nsFont ? [nsFont pointSize] : 0.0f;
- CGFontRef cgFont = 0;
- NSFont* loadedFont = 0;
- loadFont(nsFont, m_size, loadedFont, cgFont, m_atsuFontID);
- m_font = loadedFont;
- if (m_font)
- CFRetain(m_font);
- m_cgFont.adoptCF(cgFont);
-// End Chromium Change
-}
-
-FontPlatformData::FontPlatformData(const FontPlatformData& f)
-{
- m_font = f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1) ? const_cast<NSFont *>(static_cast<const NSFont *>(CFRetain(f.m_font))) : f.m_font;
-
- m_syntheticBold = f.m_syntheticBold;
- m_syntheticOblique = f.m_syntheticOblique;
- m_size = f.m_size;
- m_cgFont = f.m_cgFont;
- m_atsuFontID = f.m_atsuFontID;
- m_isColorBitmapFont = f.m_isColorBitmapFont;
- // Start Chromium Change
- refMemoryFont(m_atsuFontID);
- // End Chromium Change
-}
-
-FontPlatformData::~FontPlatformData()
-{
- if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
- CFRelease(m_font);
-
- // Start Chromium Change
- derefMemoryFont(m_atsuFontID);
- // End Chromium Change
-}
-
-const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
-{
- m_syntheticBold = f.m_syntheticBold;
- m_syntheticOblique = f.m_syntheticOblique;
- m_size = f.m_size;
- m_cgFont = f.m_cgFont;
- m_atsuFontID = f.m_atsuFontID;
- if (m_font == f.m_font)
- return *this;
- if (f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1))
- CFRetain(f.m_font);
- if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
- CFRelease(m_font);
- m_font = f.m_font;
- m_isColorBitmapFont = f.m_isColorBitmapFont;
- // Start Chromium Change
- refMemoryFont(m_atsuFontID);
- // End Chromium Change
- return *this;
-}
-
-void FontPlatformData::setFont(NSFont *font)
-{
- if (m_font == font)
- return;
- if (font)
- CFRetain(font);
- if (m_font && m_font != reinterpret_cast<NSFont *>(-1))
- CFRelease(m_font);
- m_font = font;
- m_size = font ? [font pointSize] : 0.0f;
-
- // Start Chromium Change
- CGFontRef cgFont = 0;
- NSFont* loadedFont = 0;
- loadFont(m_font, m_size, loadedFont, cgFont, m_atsuFontID);
-
- // If loadFont replaced m_font with a fallback font, then release the
- // previous font to counter the retain above. Then retain the new font.
- if (loadedFont != m_font) {
- CFRelease(m_font);
- m_font = loadedFont;
- CFRetain(m_font);
- }
- m_cgFont.adoptCF(cgFont);
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(m_font)) & kCTFontColorGlyphsTrait;
-#endif
- // End Chromium Change
-}
-
-bool FontPlatformData::roundsGlyphAdvances() const
-{
- return [m_font renderingMode] == NSFontAntialiasedIntegerAdvancementsRenderingMode;
-}
-
-bool FontPlatformData::allowsLigatures() const
-{
- return ![[m_font coveredCharacterSet] characterIsMember:'a'];
-}
-
-#if USE(CORE_TEXT)
-CTFontRef FontPlatformData::ctFont() const
-{
- if (m_font)
- return toCTFontRef(m_font);
- if (!m_CTFont)
- m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_cgFont.get(), m_size, 0, 0));
- return m_CTFont.get();
-}
-#endif // USE(CORE_TEXT)
-
-#ifndef NDEBUG
-String FontPlatformData::description() const
-{
- RetainPtr<CFStringRef> cgFontDescription(AdoptCF, CFCopyDescription(cgFont()));
- return String(cgFontDescription.get()) + " " + String::number(m_size) + (m_syntheticBold ? " synthetic bold" : "") + (m_syntheticOblique ? " synthetic oblique" : "");
-}
-#endif
-
-} // namespace WebCore
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
index c0cb87c..82d4c0b 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp
@@ -30,15 +30,15 @@
#include "config.h"
-#if USE(GLES2_RENDERING)
-
#include "GLES2Canvas.h"
#include "FloatRect.h"
-#include "GLES2Texture.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
#include "PlatformString.h"
+#include "SolidFillShader.h"
+#include "TexShader.h"
+#include "Texture.h"
#define _USE_MATH_DEFINES
#include <math.h>
@@ -48,19 +48,6 @@
namespace WebCore {
-static inline void affineTo3x3(const AffineTransform& transform, float mat[9])
-{
- mat[0] = transform.a();
- mat[1] = transform.b();
- mat[2] = 0.0f;
- mat[3] = transform.c();
- mat[4] = transform.d();
- mat[5] = 0.0f;
- mat[6] = transform.e();
- mat[7] = transform.f();
- mat[8] = 1.0f;
-}
-
struct GLES2Canvas::State {
State()
: m_fillColor(0, 0, 0, 255)
@@ -76,18 +63,10 @@ struct GLES2Canvas::State {
GLES2Canvas::GLES2Canvas(GraphicsContext3D* context, const IntSize& size)
: m_context(context)
- , m_quadVertices(0)
- , m_simpleProgram(0)
- , m_texProgram(0)
- , m_simpleMatrixLocation(-1)
- , m_simpleColorLocation(-1)
- , m_simplePositionLocation(-1)
- , m_texMatrixLocation(-1)
- , m_texTexMatrixLocation(-1)
- , m_texSamplerLocation(-1)
- , m_texAlphaLocation(-1)
- , m_texPositionLocation(-1)
, m_state(0)
+ , m_quadVertices(0)
+ , m_solidFillShader(SolidFillShader::create(context))
+ , m_texShader(TexShader::create(context))
{
m_flipMatrix.translate(-1.0f, 1.0f);
m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height());
@@ -105,8 +84,6 @@ GLES2Canvas::GLES2Canvas(GraphicsContext3D* context, const IntSize& size)
GLES2Canvas::~GLES2Canvas()
{
- m_context->deleteProgram(m_simpleProgram);
- m_context->deleteProgram(m_texProgram);
m_context->deleteBuffer(m_quadVertices);
}
@@ -131,23 +108,11 @@ void GLES2Canvas::fillRect(const FloatRect& rect, const Color& color, ColorSpace
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
- m_context->useProgram(getSimpleProgram());
-
- float rgba[4];
- color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
- m_context->uniform4f(m_simpleColorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]);
-
AffineTransform matrix(m_flipMatrix);
matrix.multLeft(m_state->m_ctm);
matrix.translate(rect.x(), rect.y());
matrix.scale(rect.width(), rect.height());
- float mat[9];
- affineTo3x3(matrix, mat);
- m_context->uniformMatrix3fv(m_simpleMatrixLocation, false /*transpose*/, mat, 1 /*count*/);
-
- m_context->vertexAttribPointer(m_simplePositionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
-
- m_context->enableVertexAttribArray(m_simplePositionLocation);
+ m_solidFillShader->use(matrix, color);
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
}
@@ -200,49 +165,35 @@ void GLES2Canvas::restore()
m_state = &m_stateStack.last();
}
-void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
+void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace colorSpace, CompositeOperator compositeOp)
{
drawTexturedRect(texture, srcRect, dstRect, m_state->m_ctm, m_state->m_alpha, colorSpace, compositeOp);
}
-void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp)
+void GLES2Canvas::drawTexturedRect(Texture* texture, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha, ColorSpace colorSpace, CompositeOperator compositeOp)
{
applyCompositeOperator(compositeOp);
m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, getQuadVertices());
checkGLError("glBindBuffer");
- m_context->useProgram(getTexProgram());
- checkGLError("glUseProgram");
-
- m_context->activeTexture(GraphicsContext3D::TEXTURE0);
-
- m_context->uniform1i(m_texSamplerLocation, 0);
- checkGLError("glUniform1i");
-
- m_context->uniform1f(m_texAlphaLocation, alpha);
- checkGLError("glUniform1f for alpha");
-
- m_context->vertexAttribPointer(m_texPositionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
-
- m_context->enableVertexAttribArray(m_texPositionLocation);
-
const TilingData& tiles = texture->tiles();
IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect);
for (int y = tileIdxRect.y(); y <= tileIdxRect.bottom(); y++) {
for (int x = tileIdxRect.x(); x <= tileIdxRect.right(); x++)
- drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect, dstRect, transform);
+ drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect, dstRect, transform, alpha);
}
}
-void GLES2Canvas::drawTexturedRectTile(GLES2Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform)
+void GLES2Canvas::drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform, float alpha)
{
if (dstRect.isEmpty())
return;
const TilingData& tiles = texture->tiles();
+ m_context->activeTexture(GraphicsContext3D::TEXTURE0);
texture->bindTile(tile);
FloatRect srcRectClippedInTileSpace;
@@ -255,19 +206,13 @@ void GLES2Canvas::drawTexturedRectTile(GLES2Texture* texture, int tile, const Fl
matrix.multLeft(transform);
matrix.translate(dstRectIntersected.x(), dstRectIntersected.y());
matrix.scale(dstRectIntersected.width(), dstRectIntersected.height());
- float mat[9];
- affineTo3x3(matrix, mat);
- m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, mat, 1 /*count*/);
- checkGLError("glUniformMatrix3fv");
AffineTransform texMatrix;
texMatrix.scale(1.0f / tileBoundsWithBorder.width(), 1.0f / tileBoundsWithBorder.height());
texMatrix.translate(srcRectClippedInTileSpace.x(), srcRectClippedInTileSpace.y());
texMatrix.scale(srcRectClippedInTileSpace.width(), srcRectClippedInTileSpace.height());
- float texMat[9];
- affineTo3x3(texMatrix, texMat);
- m_context->uniformMatrix3fv(m_texTexMatrixLocation, false /*transpose*/, texMat, 1 /*count*/);
- checkGLError("glUniformMatrix3fv");
+
+ m_texShader->use(matrix, texMatrix, 0, alpha);
m_context->drawArrays(GraphicsContext3D::TRIANGLE_STRIP, 0, 4);
checkGLError("glDrawArrays");
@@ -354,131 +299,21 @@ unsigned GLES2Canvas::getQuadVertices()
return m_quadVertices;
}
-
-static unsigned loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource)
+Texture* GLES2Canvas::createTexture(NativeImagePtr ptr, Texture::Format format, int width, int height)
{
- unsigned shader = context->createShader(type);
- if (!shader)
- return 0;
-
- String shaderSourceStr(shaderSource);
- context->shaderSource(shader, shaderSourceStr);
- context->compileShader(shader);
- int compileStatus;
- context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compileStatus);
- if (!compileStatus) {
- String infoLog = context->getShaderInfoLog(shader);
- LOG_ERROR(infoLog.utf8().data());
- context->deleteShader(shader);
- return 0;
- }
- return shader;
-}
-
-unsigned GLES2Canvas::getSimpleProgram()
-{
- if (!m_simpleProgram) {
- unsigned vertexShader = loadShader(m_context, GraphicsContext3D::VERTEX_SHADER,
- "uniform mat3 matrix;\n"
- "uniform vec4 color;\n"
- "attribute vec3 position;\n"
- "void main() {\n"
- " gl_Position = vec4(matrix * position, 1.0);\n"
- "}\n");
- if (!vertexShader)
- return 0;
- unsigned fragmentShader = loadShader(m_context, GraphicsContext3D::FRAGMENT_SHADER,
- "precision mediump float;\n"
- "uniform mat3 matrix;\n"
- "uniform vec4 color;\n"
- "void main() {\n"
- " gl_FragColor = color;\n"
- "}\n");
- if (!fragmentShader)
- return 0;
- m_simpleProgram = m_context->createProgram();
- if (!m_simpleProgram)
- return 0;
- m_context->attachShader(m_simpleProgram, vertexShader);
- m_context->attachShader(m_simpleProgram, fragmentShader);
- m_context->linkProgram(m_simpleProgram);
- int linkStatus;
- m_context->getProgramiv(m_simpleProgram, GraphicsContext3D::LINK_STATUS, &linkStatus);
- if (!linkStatus) {
- m_context->deleteProgram(m_simpleProgram);
- m_simpleProgram = 0;
- }
- m_context->deleteShader(vertexShader);
- m_context->deleteShader(fragmentShader);
- m_simplePositionLocation = m_context->getAttribLocation(m_simpleProgram, "position");
- m_simpleMatrixLocation = m_context->getUniformLocation(m_simpleProgram, "matrix");
- m_simpleColorLocation = m_context->getUniformLocation(m_simpleProgram, "color");
- }
- return m_simpleProgram;
-}
-
-unsigned GLES2Canvas::getTexProgram()
-{
- if (!m_texProgram) {
- unsigned vertexShader = loadShader(m_context, GraphicsContext3D::VERTEX_SHADER,
- "uniform mat3 matrix;\n"
- "uniform mat3 texMatrix;\n"
- "attribute vec3 position;\n"
- "varying vec3 texCoord;\n"
- "void main() {\n"
- " texCoord = texMatrix * position;\n"
- " gl_Position = vec4(matrix * position, 1.0);\n"
- "}\n");
- if (!vertexShader)
- return 0;
- unsigned fragmentShader = loadShader(m_context, GraphicsContext3D::FRAGMENT_SHADER,
- "precision mediump float;\n"
- "uniform sampler2D sampler;\n"
- "uniform float alpha;\n"
- "varying vec3 texCoord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(sampler, texCoord.xy)* vec4(alpha);\n"
- "}\n");
- if (!fragmentShader)
- return 0;
- m_texProgram = m_context->createProgram();
- if (!m_texProgram)
- return 0;
- m_context->attachShader(m_texProgram, vertexShader);
- m_context->attachShader(m_texProgram, fragmentShader);
- m_context->linkProgram(m_texProgram);
- int linkStatus;
- m_context->getProgramiv(m_texProgram, GraphicsContext3D::LINK_STATUS, &linkStatus);
- if (!linkStatus) {
- m_context->deleteProgram(m_texProgram);
- m_texProgram = 0;
- }
- m_context->deleteShader(vertexShader);
- m_context->deleteShader(fragmentShader);
- m_texMatrixLocation = m_context->getUniformLocation(m_texProgram, "matrix");
- m_texSamplerLocation = m_context->getUniformLocation(m_texProgram, "sampler");
- m_texTexMatrixLocation = m_context->getUniformLocation(m_texProgram, "texMatrix");
- m_texPositionLocation = m_context->getAttribLocation(m_texProgram, "position");
- m_texAlphaLocation = m_context->getUniformLocation(m_texProgram, "alpha");
- }
- return m_texProgram;
-}
-
-GLES2Texture* GLES2Canvas::createTexture(NativeImagePtr ptr, GLES2Texture::Format format, int width, int height)
-{
- PassRefPtr<GLES2Texture> texture = m_textures.get(ptr);
+ PassRefPtr<Texture> texture = m_textures.get(ptr);
if (texture)
return texture.get();
- texture = GLES2Texture::create(m_context, format, width, height);
- GLES2Texture* t = texture.get();
+ texture = Texture::create(m_context, format, width, height);
+ Texture* t = texture.get();
m_textures.set(ptr, texture);
return t;
}
-GLES2Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
+Texture* GLES2Canvas::getTexture(NativeImagePtr ptr)
{
- PassRefPtr<GLES2Texture> texture = m_textures.get(ptr);
+ PassRefPtr<Texture> texture = m_textures.get(ptr);
return texture ? texture.get() : 0;
}
@@ -515,4 +350,3 @@ void GLES2Canvas::checkGLError(const char* header)
}
-#endif
diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h
index d00510a..f49ac8b 100644
--- a/WebCore/platform/graphics/chromium/GLES2Canvas.h
+++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h
@@ -31,14 +31,12 @@
#ifndef GLES2Canvas_h
#define GLES2Canvas_h
-#if USE(GLES2_RENDERING)
-
#include "AffineTransform.h"
#include "Color.h"
#include "ColorSpace.h"
-#include "GLES2Texture.h"
#include "GraphicsTypes.h"
#include "ImageSource.h"
+#include "Texture.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
@@ -49,8 +47,10 @@ namespace WebCore {
class Color;
class FloatRect;
class GraphicsContext3D;
+class SolidFillShader;
+class TexShader;
-typedef HashMap<NativeImagePtr, RefPtr<GLES2Texture> > TextureHashMap;
+typedef HashMap<NativeImagePtr, RefPtr<Texture> > TextureHashMap;
class GLES2Canvas : public Noncopyable {
public:
@@ -74,35 +74,25 @@ public:
// non-standard functions
// These are not standard GraphicsContext functions, and should be pushed
// down into a PlatformContextGLES2 at some point.
- void drawTexturedRect(GLES2Texture*, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace, CompositeOperator);
- void drawTexturedRect(GLES2Texture*, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator);
+ void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha, ColorSpace, CompositeOperator);
+ void drawTexturedRect(Texture*, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace, CompositeOperator);
GraphicsContext3D* context() { return m_context; }
- GLES2Texture* createTexture(NativeImagePtr, GLES2Texture::Format, int width, int height);
- GLES2Texture* getTexture(NativeImagePtr);
+ Texture* createTexture(NativeImagePtr, Texture::Format, int width, int height);
+ Texture* getTexture(NativeImagePtr);
private:
- void drawTexturedRectTile(GLES2Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&);
+ void drawTexturedRectTile(Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&, float alpha);
void applyCompositeOperator(CompositeOperator);
void checkGLError(const char* header);
unsigned getQuadVertices();
- unsigned getSimpleProgram();
- unsigned getTexProgram();
GraphicsContext3D* m_context;
struct State;
WTF::Vector<State> m_stateStack;
State* m_state;
unsigned m_quadVertices;
- unsigned m_simpleProgram;
- unsigned m_texProgram;
- int m_simpleMatrixLocation;
- int m_simpleColorLocation;
- int m_simplePositionLocation;
- int m_texMatrixLocation;
- int m_texTexMatrixLocation;
- int m_texSamplerLocation;
- int m_texAlphaLocation;
- int m_texPositionLocation;
+ OwnPtr<SolidFillShader> m_solidFillShader;
+ OwnPtr<TexShader> m_texShader;
AffineTransform m_flipMatrix;
TextureHashMap m_textures;
CompositeOperator m_lastCompositeOp; // This is the one last set, not necessarily the one in the state stack.
@@ -110,6 +100,4 @@ private:
}
-#endif
-
#endif // GLES2Canvas_h
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp
index 3553878..6519f1f 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp
@@ -109,7 +109,7 @@ LayerChromium::SharedValues::SharedValues()
"uniform vec4 color; \n"
"void main() \n"
"{ \n"
- " gl_FragColor = color; \n"
+ " gl_FragColor = vec4(color.xyz * color.w, color.w);\n"
"} \n";
m_borderShaderProgram = createShaderProgram(borderVertexShaderString, borderFragmentShaderString);
@@ -431,6 +431,37 @@ void LayerChromium::drawDebugBorder()
GLC(glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, (void*)(6 * sizeof(unsigned short))));
}
+const FloatRect LayerChromium::getDrawRect() const
+{
+ // Form the matrix used by the shader to map the corners of the layer's
+ // bounds into the view space.
+ TransformationMatrix renderMatrix = drawTransform();
+ renderMatrix.scale3d(bounds().width(), bounds().height(), 1);
+
+ FloatRect layerRect(-0.5, -0.5, 1, 1);
+ FloatRect mappedRect = renderMatrix.mapRect(layerRect);
+ return mappedRect;
+}
+
+// Draws the layer with a single colored shader. This method is used to do
+// quick draws into the stencil buffer.
+void LayerChromium::drawAsMask()
+{
+ ASSERT(layerRenderer());
+ const SharedValues* sv = layerRenderer()->layerSharedValues();
+ ASSERT(sv && sv->initialized());
+ layerRenderer()->useShader(sv->borderShaderProgram());
+
+ // We reuse the border shader here as all we need a single colored shader pass.
+ // The color specified here is only for debug puproses as typically when we call this
+ // method, writes to the color channels are disabled.
+ GLC(glUniform4f(sv->borderShaderColorLocation(), 0, 1 , 0, 0.7));
+
+ drawTexturedQuad(layerRenderer()->projectionMatrix(), drawTransform(),
+ bounds().width(), bounds().height(), drawOpacity(),
+ sv->borderShaderMatrixLocation(), -1);
+}
+
// static
void LayerChromium::prepareForDraw(const SharedValues* sv)
{
diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h
index 0d0d362..ba15088 100644
--- a/WebCore/platform/graphics/chromium/LayerChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerChromium.h
@@ -151,6 +151,9 @@ public:
bool contentsDirty() { return m_contentsDirty; }
+ // Returns the rect containtaining this layer in the current view's coordinate system.
+ const FloatRect getDrawRect() const;
+
// These methods typically need to be overwritten by derived classes.
virtual bool drawsContent() { return false; }
virtual void updateContents() { };
@@ -158,6 +161,9 @@ public:
void drawDebugBorder();
+ // Draws the layer without a texture. This is used for stencil operations.
+ void drawAsMask();
+
// Stores values that are shared between instances of this class that are
// associated with the same LayerRendererChromium (and hence the same GL
// context).
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index cf23871..50338d2 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -183,9 +183,11 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
// Bind the common vertex attributes used for drawing all the layers.
LayerChromium::prepareForDraw(layerSharedValues());
+ // FIXME: These calls can be made once, when the compositor context is initialized.
GLC(glDisable(GL_DEPTH_TEST));
GLC(glDisable(GL_CULL_FACE));
GLC(glDepthFunc(GL_LEQUAL));
+ GLC(glClearStencil(0));
if (m_scrollPosition == IntPoint(-1, -1))
m_scrollPosition = scrollPosition;
@@ -299,14 +301,23 @@ void LayerRendererChromium::drawLayers(const IntRect& updateRect, const IntRect&
for (i = 0; i < sublayers.size(); i++)
updateLayersRecursive(sublayers[i].get(), matrix, opacity);
+ m_rootVisibleRect = visibleRect;
+
// Enable scissoring to avoid rendering composited layers over the scrollbars.
GLC(glEnable(GL_SCISSOR_TEST));
- GLC(glScissor(0, visibleRect.height() - contentRect.height(), contentRect.width(), contentRect.height()));
+ FloatRect scissorRect(contentRect);
+ // The scissorRect should not include the scroll offset.
+ scissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y());
+ scissorToRect(scissorRect);
+
+ // Clear the stencil buffer to 0.
+ GLC(glClear(GL_STENCIL_BUFFER_BIT));
+ // Disable writes to the stencil buffer.
+ GLC(glStencilMask(0));
// Traverse the layer tree one more time to draw the layers.
- m_visibleRect = visibleRect;
for (i = 0; i < sublayers.size(); i++)
- drawLayersRecursive(sublayers[i].get());
+ drawLayersRecursive(sublayers[i].get(), scissorRect);
GLC(glDisable(GL_SCISSOR_TEST));
@@ -419,13 +430,35 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr
layer->setLayerRenderer(this);
}
+// Does a quick draw of the given layer into the stencil buffer. If decrement
+// is true then it decrements the current stencil values otherwise it increments them.
+void LayerRendererChromium::drawLayerIntoStencilBuffer(LayerChromium* layer, bool decrement)
+{
+ // Enable writes to the stencil buffer and increment the stencil values
+ // by one for every pixel under the current layer.
+ GLC(glStencilMask(0xff));
+ GLC(glStencilFunc(GL_ALWAYS, 1, 0xff));
+ GLenum stencilOp = (decrement ? GL_DECR : GL_INCR);
+ GLC(glStencilOp(stencilOp, stencilOp, stencilOp));
+
+ GLC(glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
+
+ layer->drawAsMask();
+
+ // Disable writes to the stencil buffer.
+ GLC(glStencilMask(0));
+ GLC(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
+}
+
// Recursively walk the layer tree and draw the layers.
-void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer)
+void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const FloatRect& scissorRect)
{
static bool depthTestEnabledForSubtree = false;
+ static int currentStencilValue = 0;
// Check if the layer falls within the visible bounds of the page.
- bool layerVisible = isLayerVisible(layer, layer->drawTransform(), m_visibleRect);
+ FloatRect layerRect = layer->getDrawRect();
+ bool isLayerVisible = scissorRect.intersects(layerRect);
// Enable depth testing for this layer and all its descendants if preserves3D is set.
bool mustClearDepth = false;
@@ -439,9 +472,50 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer)
}
}
- if (layerVisible)
+ if (isLayerVisible)
drawLayer(layer);
+ // FIXME: We should check here if the layer has descendants that draw content
+ // before we setup for clipping.
+ FloatRect currentScissorRect = scissorRect;
+ bool mustResetScissorRect = false;
+ bool didStencilDraw = false;
+ if (layer->masksToBounds()) {
+ // If the layer isn't rotated then we can use scissoring otherwise we need
+ // to clip using the stencil buffer.
+ if (layer->drawTransform().isIdentityOrTranslation()) {
+ currentScissorRect.intersect(layerRect);
+ if (currentScissorRect != scissorRect) {
+ scissorToRect(currentScissorRect);
+ mustResetScissorRect = true;
+ }
+ } else if (currentStencilValue < ((1 << m_numStencilBits) - 1)) {
+ // Clipping using the stencil buffer works as follows: When we encounter
+ // a clipping layer we increment the stencil buffer values for all the pixels
+ // the layer touches. As a result 1's will be stored in the stencil buffer for pixels under
+ // the first clipping layer found in a traversal, 2's for pixels in the intersection
+ // of two nested clipping layers, etc. When the sublayers of a clipping layer are drawn
+ // we turn on stencil testing to render only pixels that have the correct stencil
+ // value (one that matches the value of currentStencilValue). As the recursion unravels,
+ // we decrement the stencil buffer values for each clipping layer. When the entire layer tree
+ // is rendered, the stencil values should be all back to zero. An 8 bit stencil buffer
+ // will allow us up to 255 nested clipping layers which is hopefully enough.
+ if (!currentStencilValue)
+ GLC(glEnable(GL_STENCIL_TEST));
+
+ drawLayerIntoStencilBuffer(layer, false);
+
+ currentStencilValue++;
+ didStencilDraw = true;
+ }
+ }
+ // Sublayers will render only if the value in the stencil buffer is equal to
+ // currentStencilValue.
+ if (didStencilDraw) {
+ // The sublayers will render only if the stencil test passes.
+ GLC(glStencilFunc(GL_EQUAL, currentStencilValue, 0xff));
+ }
+
// If we're using depth testing then we need to sort the children in Z to
// get the transparency to work properly.
if (depthTestEnabledForSubtree) {
@@ -456,11 +530,27 @@ void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer)
std::stable_sort(sublayerList.begin(), sublayerList.end(), compareLayerZ);
for (i = 0; i < sublayerList.size(); i++)
- drawLayersRecursive(sublayerList[i]);
+ drawLayersRecursive(sublayerList[i], currentScissorRect);
} else {
const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
for (size_t i = 0; i < sublayers.size(); i++)
- drawLayersRecursive(sublayers[i].get());
+ drawLayersRecursive(sublayers[i].get(), currentScissorRect);
+ }
+
+ if (didStencilDraw) {
+ // Draw into the stencil buffer subtracting 1 for every pixel hit
+ // effectively removing this mask
+ drawLayerIntoStencilBuffer(layer, true);
+ currentStencilValue--;
+ if (!currentStencilValue) {
+ // Disable stencil testing.
+ GLC(glDisable(GL_STENCIL_TEST));
+ GLC(glStencilFunc(GL_ALWAYS, 0, 0xff));
+ }
+ }
+
+ if (mustResetScissorRect) {
+ scissorToRect(scissorRect);
}
if (mustClearDepth) {
@@ -494,6 +584,15 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer)
layer->drawDebugBorder();
}
+// Sets the scissor region to the given rectangle. The coordinate system for the
+// scissorRect has its origin at the top left corner of the current visible rect.
+void LayerRendererChromium::scissorToRect(const FloatRect& scissorRect)
+{
+ // Compute the lower left corner of the scissor rect.
+ float bottom = std::max((float)m_rootVisibleRect.height() - scissorRect.bottom(), 0.f);
+ GLC(glScissor(scissorRect.x(), bottom, scissorRect.width(), scissorRect.height()));
+}
+
bool LayerRendererChromium::makeContextCurrent()
{
return m_gles2Context->makeCurrent();
@@ -565,6 +664,9 @@ bool LayerRendererChromium::initializeSharedObjects()
// Get the max texture size supported by the system.
GLC(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize));
+ // Get the number of bits available in the stencil buffer.
+ GLC(glGetIntegerv(GL_STENCIL_BITS, &m_numStencilBits));
+
m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues());
m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues());
m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues());
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
index 24bbe65..8f44afe 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.h
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.h
@@ -93,12 +93,16 @@ public:
private:
void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, float opacity);
- void drawLayersRecursive(LayerChromium*);
+ void drawLayersRecursive(LayerChromium*, const FloatRect& scissorRect);
void drawLayer(LayerChromium*);
bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect);
+ void drawLayerIntoStencilBuffer(LayerChromium*, bool decrement);
+
+ void scissorToRect(const FloatRect&);
+
bool makeContextCurrent();
bool initializeSharedObjects();
@@ -135,10 +139,12 @@ private:
IntSize m_rootLayerCanvasSize;
- IntRect m_visibleRect;
+ IntRect m_rootVisibleRect;
int m_maxTextureSize;
+ int m_numStencilBits;
+
// Store values that are shared between instances of each layer type
// associated with this instance of the compositor. Since there can be
// multiple instances of the compositor running in the same renderer process
diff --git a/WebCore/platform/graphics/mac/FontPlatformData.h b/WebCore/platform/graphics/cocoa/FontPlatformData.h
index dc876a8..034e23b 100644
--- a/WebCore/platform/graphics/mac/FontPlatformData.h
+++ b/WebCore/platform/graphics/cocoa/FontPlatformData.h
@@ -42,7 +42,13 @@ typedef const struct __CTFont* CTFontRef;
#include <wtf/Forward.h>
#include <wtf/RetainPtr.h>
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+#include "CrossProcessFontLoading.h"
+#endif
+
+
typedef UInt32 ATSUFontID;
+typedef UInt32 ATSFontRef;
namespace WebCore {
@@ -133,6 +139,15 @@ class FontPlatformData {
private:
static NSFont *hashTableDeletedFontValue() { return reinterpret_cast<NSFont *>(-1); }
+
+ // Load various data about the font specified by |nsFont| with the size fontSize into the following output paramters:
+ // Note: Callers should always take into account that for the Chromium port, |outNSFont| isn't necessarily the same
+ // font as |nsFont|. This because the sandbox may block loading of the original font.
+ // * outNSFont - The font that was actually loaded, for the Chromium port this may be different than nsFont.
+ // The caller is responsible for calling CFRelease() on this parameter when done with it.
+ // * cgFont - CGFontRef representing the input font at the specified point size.
+ // * fontID - ID of loaded font.
+ void loadFont(NSFont* nsFont, float fontSize, NSFont*& outNSFont, CGFontRef& cgFont, ATSUFontID& fontID);
NSFont *m_font;
@@ -147,8 +162,12 @@ private:
#endif
bool m_isColorBitmapFont;
+
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+ RefPtr<MemoryActivatedFont> m_inMemoryFont;
+#endif
};
-}
+} // namespace WebCore
#endif
diff --git a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm b/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
index d905b62..bd49dcc 100644
--- a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm
+++ b/WebCore/platform/graphics/cocoa/FontPlatformDataCocoa.mm
@@ -2,6 +2,7 @@
* This file is part of the internal font implementation.
*
* Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2010 Google Inc. 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
@@ -29,11 +30,27 @@
namespace WebCore {
+#if PLATFORM(MAC)
+void FontPlatformData::loadFont(NSFont* nsFont, float, NSFont*& outNSFont, CGFontRef& cgFont, ATSUFontID& fontID)
+{
+ outNSFont = nsFont;
+#ifndef BUILDING_ON_TIGER
+ cgFont = CTFontCopyGraphicsFont(toCTFontRef(nsFont), 0);
+ fontID = CTFontGetPlatformFont(toCTFontRef(nsFont), 0);
+#else
+ cgFont = wkGetCGFontFromNSFont(nsFont);
+ fontID = wkGetNSFontATSUFontId(nsFont);
+#endif
+}
+#endif // PLATFORM(MAC)
+
FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool syntheticOblique)
: m_syntheticBold(syntheticBold)
, m_syntheticOblique(syntheticOblique)
, m_font(nsFont)
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ // FIXME: Chromium: The following code isn't correct for the Chromium port since the sandbox might
+ // have blocked font loading, in which case we'll only have the real loaded font file after the call to loadFont().
, m_isColorBitmapFont(CTFontGetSymbolicTraits(toCTFontRef(nsFont)) & kCTFontColorGlyphsTrait)
#else
, m_isColorBitmapFont(false)
@@ -41,14 +58,18 @@ FontPlatformData::FontPlatformData(NSFont *nsFont, bool syntheticBold, bool synt
{
ASSERT_ARG(nsFont, nsFont);
- CFRetain(nsFont);
m_size = [nsFont pointSize];
+
+ CGFontRef cgFont = 0;
+ loadFont(nsFont, m_size, m_font, cgFont, m_atsuFontID);
+
+ if (m_font)
+ CFRetain(m_font);
+
#ifndef BUILDING_ON_TIGER
- m_cgFont.adoptCF(CTFontCopyGraphicsFont(toCTFontRef(nsFont), 0));
- m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(nsFont), 0);
+ m_cgFont.adoptCF(cgFont);
#else
- m_cgFont = wkGetCGFontFromNSFont(nsFont);
- m_atsuFontID = wkGetNSFontATSUFontId(nsFont);
+ m_cgFont = cgFont;
#endif
}
@@ -65,6 +86,9 @@ FontPlatformData::FontPlatformData(const FontPlatformData& f)
#if USE(CORE_TEXT)
m_CTFont = f.m_CTFont;
#endif
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+ m_inMemoryFont = f.m_inMemoryFont;
+#endif
}
FontPlatformData:: ~FontPlatformData()
@@ -91,6 +115,9 @@ const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f)
#if USE(CORE_TEXT)
m_CTFont = f.m_CTFont;
#endif
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+ m_inMemoryFont = f.m_inMemoryFont;
+#endif
return *this;
}
@@ -107,15 +134,28 @@ void FontPlatformData::setFont(NSFont *font)
CFRelease(m_font);
m_font = font;
m_size = [font pointSize];
+
+ CGFontRef cgFont = 0;
+ NSFont* loadedFont = 0;
+ loadFont(m_font, m_size, loadedFont, cgFont, m_atsuFontID);
+
+#if PLATFORM(CHROMIUM) && OS(DARWIN)
+ // If loadFont replaced m_font with a fallback font, then release the
+ // previous font to counter the retain above. Then retain the new font.
+ if (loadedFont != m_font) {
+ CFRelease(m_font);
+ CFRetain(loadedFont);
+ m_font = loadedFont;
+ }
+#endif
+
#ifndef BUILDING_ON_TIGER
- m_cgFont.adoptCF(CTFontCopyGraphicsFont(toCTFontRef(font), 0));
- m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(font), 0);
+ m_cgFont.adoptCF(cgFont);
#else
- m_cgFont = wkGetCGFontFromNSFont(font);
- m_atsuFontID = wkGetNSFontATSUFontId(font);
+ m_cgFont = cgFont;
#endif
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
- m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(font)) & kCTFontColorGlyphsTrait;
+ m_isColorBitmapFont = CTFontGetSymbolicTraits(toCTFontRef(m_font)) & kCTFontColorGlyphsTrait;
#endif
#if USE(CORE_TEXT)
m_CTFont = 0;
diff --git a/WebCore/platform/graphics/gpu/Shader.cpp b/WebCore/platform/graphics/gpu/Shader.cpp
new file mode 100644
index 0000000..59c50a7
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/Shader.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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 "Shader.h"
+
+#include "AffineTransform.h"
+#include "GraphicsContext3D.h"
+
+#include <wtf/text/CString.h>
+
+namespace WebCore {
+
+// static
+void Shader::affineTo3x3(const AffineTransform& transform, float mat[9])
+{
+ mat[0] = transform.a();
+ mat[1] = transform.b();
+ mat[2] = 0.0f;
+ mat[3] = transform.c();
+ mat[4] = transform.d();
+ mat[5] = 0.0f;
+ mat[6] = transform.e();
+ mat[7] = transform.f();
+ mat[8] = 1.0f;
+}
+
+// static
+unsigned Shader::loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource)
+{
+ unsigned shader = context->createShader(type);
+ if (!shader)
+ return 0;
+
+ String shaderSourceStr(shaderSource);
+ context->shaderSource(shader, shaderSourceStr);
+ context->compileShader(shader);
+ int compileStatus;
+ context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compileStatus);
+ if (!compileStatus) {
+ String infoLog = context->getShaderInfoLog(shader);
+ LOG_ERROR("%s", infoLog.utf8().data());
+ context->deleteShader(shader);
+ return 0;
+ }
+ return shader;
+}
+
+// static
+unsigned Shader::loadProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource)
+{
+ unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource);
+ if (!vertexShader)
+ return 0;
+ unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource);
+ if (!fragmentShader)
+ return 0;
+ unsigned program = context->createProgram();
+ if (!program)
+ return 0;
+ context->attachShader(program, vertexShader);
+ context->attachShader(program, fragmentShader);
+ context->linkProgram(program);
+ int linkStatus;
+ context->getProgramiv(program, GraphicsContext3D::LINK_STATUS, &linkStatus);
+ if (!linkStatus)
+ context->deleteProgram(program);
+ context->deleteShader(vertexShader);
+ context->deleteShader(fragmentShader);
+ return program;
+}
+
+Shader::Shader(GraphicsContext3D* context, unsigned program)
+ : m_context(context)
+ , m_program(program)
+{
+}
+
+Shader::~Shader()
+{
+ m_context->deleteProgram(m_program);
+}
+
+}
diff --git a/WebCore/platform/graphics/gpu/Shader.h b/WebCore/platform/graphics/gpu/Shader.h
new file mode 100644
index 0000000..e5bd8de
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/Shader.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+#ifndef Shader_h
+#define Shader_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WebCore {
+
+class AffineTransform;
+class GraphicsContext3D;
+class Color;
+
+class Shader : public Noncopyable {
+protected:
+ Shader(GraphicsContext3D*, unsigned program);
+ ~Shader();
+
+ static void affineTo3x3(const AffineTransform&, float mat[9]);
+ static unsigned loadShader(GraphicsContext3D*, unsigned type, const char* shaderSource);
+ static unsigned loadProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource);
+
+ GraphicsContext3D* m_context;
+ unsigned m_program;
+};
+
+}
+
+#endif // Shader_h
diff --git a/WebCore/platform/graphics/gpu/SolidFillShader.cpp b/WebCore/platform/graphics/gpu/SolidFillShader.cpp
new file mode 100644
index 0000000..bbc4792
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/SolidFillShader.cpp
@@ -0,0 +1,86 @@
+/*
+ * 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 "SolidFillShader.h"
+
+#include "Color.h"
+#include "GraphicsContext3D.h"
+
+namespace WebCore {
+
+SolidFillShader::SolidFillShader(GraphicsContext3D* context, unsigned program)
+ : Shader(context, program)
+{
+ m_matrixLocation = context->getUniformLocation(program, "matrix");
+ m_colorLocation = context->getUniformLocation(program, "color");
+ m_positionLocation = context->getAttribLocation(program, "position");
+}
+
+PassOwnPtr<SolidFillShader> SolidFillShader::create(GraphicsContext3D* context)
+{
+ static const char* vertexShaderSource =
+ "uniform mat3 matrix;\n"
+ "uniform vec4 color;\n"
+ "attribute vec3 position;\n"
+ "void main() {\n"
+ " gl_Position = vec4(matrix * position, 1.0);\n"
+ "}\n";
+ static const char* fragmentShaderSource =
+ "precision mediump float;\n"
+ "uniform mat3 matrix;\n"
+ "uniform vec4 color;\n"
+ "void main() {\n"
+ " gl_FragColor = color;\n"
+ "}\n";
+ unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource);
+ if (!program)
+ return 0;
+ return new SolidFillShader(context, program);
+}
+
+void SolidFillShader::use(const AffineTransform& transform, const Color& color)
+{
+ m_context->useProgram(m_program);
+
+ float rgba[4];
+ color.getRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
+ m_context->uniform4f(m_colorLocation, rgba[0] * rgba[3], rgba[1] * rgba[3], rgba[2] * rgba[3], rgba[3]);
+
+ float matrix[9];
+ affineTo3x3(transform, matrix);
+ m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/);
+
+ m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+
+ m_context->enableVertexAttribArray(m_positionLocation);
+}
+
+}
diff --git a/WebCore/platform/graphics/gpu/SolidFillShader.h b/WebCore/platform/graphics/gpu/SolidFillShader.h
new file mode 100644
index 0000000..1071e73
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/SolidFillShader.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef SolidFillShader_h
+#define SolidFillShader_h
+
+#include "Shader.h"
+
+namespace WebCore {
+
+class SolidFillShader : public Shader {
+public:
+ static PassOwnPtr<SolidFillShader> create(GraphicsContext3D* context);
+ void use(const AffineTransform& transform, const Color& color);
+
+private:
+ SolidFillShader(GraphicsContext3D* context, unsigned program);
+
+ int m_matrixLocation;
+ int m_colorLocation;
+ int m_positionLocation;
+};
+
+}
+
+#endif // SolidFillShader_h
diff --git a/WebCore/platform/graphics/gpu/TexShader.cpp b/WebCore/platform/graphics/gpu/TexShader.cpp
new file mode 100644
index 0000000..ba3ecdd
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/TexShader.cpp
@@ -0,0 +1,93 @@
+/*
+ * 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 "TexShader.h"
+
+#include "GraphicsContext3D.h"
+
+namespace WebCore {
+
+TexShader::TexShader(GraphicsContext3D* context, unsigned program)
+ : Shader(context, program)
+{
+ m_matrixLocation = context->getUniformLocation(program, "matrix");
+ m_texMatrixLocation = context->getUniformLocation(program, "texMatrix");
+ m_alphaLocation = context->getUniformLocation(program, "alpha");
+ m_positionLocation = context->getAttribLocation(program, "position");
+ m_samplerLocation = context->getUniformLocation(program, "sampler");
+}
+
+PassOwnPtr<TexShader> TexShader::create(GraphicsContext3D* context)
+{
+ static const char* vertexShaderSource =
+ "uniform mat3 matrix;\n"
+ "uniform mat3 texMatrix;\n"
+ "attribute vec3 position;\n"
+ "varying vec3 texCoord;\n"
+ "void main() {\n"
+ " texCoord = texMatrix * position;\n"
+ " gl_Position = vec4(matrix * position, 1.0);\n"
+ "}\n";
+ static const char* fragmentShaderSource =
+ "precision mediump float;\n"
+ "uniform sampler2D sampler;\n"
+ "uniform float alpha;\n"
+ "varying vec3 texCoord;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(sampler, texCoord.xy)* vec4(alpha);\n"
+ "}\n";
+ unsigned program = loadProgram(context, vertexShaderSource, fragmentShaderSource);
+ if (!program)
+ return 0;
+ return new TexShader(context, program);
+}
+
+void TexShader::use(const AffineTransform& transform, const AffineTransform& texTransform, int sampler, float alpha)
+{
+ m_context->useProgram(m_program);
+ float matrix[9];
+ affineTo3x3(transform, matrix);
+ m_context->uniformMatrix3fv(m_matrixLocation, false /*transpose*/, matrix, 1 /*count*/);
+
+ float texMatrix[9];
+ affineTo3x3(texTransform, texMatrix);
+ m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, texMatrix, 1 /*count*/);
+
+ m_context->uniform1i(m_samplerLocation, sampler);
+ m_context->uniform1f(m_alphaLocation, alpha);
+
+ m_context->vertexAttribPointer(m_positionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0);
+
+ m_context->enableVertexAttribArray(m_positionLocation);
+
+}
+
+}
diff --git a/WebCore/platform/graphics/gpu/TexShader.h b/WebCore/platform/graphics/gpu/TexShader.h
new file mode 100644
index 0000000..535997d
--- /dev/null
+++ b/WebCore/platform/graphics/gpu/TexShader.h
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#ifndef TexShader_h
+#define TexShader_h
+
+#include "Shader.h"
+
+namespace WebCore {
+
+class TexShader : public Shader {
+public:
+ static PassOwnPtr<TexShader> create(GraphicsContext3D* context);
+ void use(const AffineTransform& transform, const AffineTransform& texTransform, int sampler, float alpha);
+
+private:
+ TexShader(GraphicsContext3D* context, unsigned program);
+
+ int m_matrixLocation;
+ int m_texMatrixLocation;
+ int m_samplerLocation;
+ int m_alphaLocation;
+ int m_positionLocation;
+};
+
+}
+
+#endif // TexShader_h
diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp
index ae230db..557603c 100644
--- a/WebCore/platform/graphics/chromium/GLES2Texture.cpp
+++ b/WebCore/platform/graphics/gpu/Texture.cpp
@@ -30,9 +30,7 @@
#include "config.h"
-#if USE(GLES2_RENDERING)
-
-#include "GLES2Texture.h"
+#include "Texture.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
@@ -41,7 +39,7 @@
namespace WebCore {
-GLES2Texture::GLES2Texture(GraphicsContext3D* context, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize)
+Texture::Texture(GraphicsContext3D* context, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize)
: m_context(context)
, m_format(format)
, m_tiles(maxTextureSize, width, height, true)
@@ -49,21 +47,21 @@ GLES2Texture::GLES2Texture(GraphicsContext3D* context, PassOwnPtr<Vector<unsigne
{
}
-GLES2Texture::~GLES2Texture()
+Texture::~Texture()
{
for (unsigned int i = 0; i < m_tileTextureIds->size(); i++)
m_context->deleteTexture(m_tileTextureIds->at(i));
}
-static void convertFormat(GraphicsContext3D* context, GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle)
+static void convertFormat(GraphicsContext3D* context, Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle)
{
*swizzle = false;
switch (format) {
- case GLES2Texture::RGBA8:
+ case Texture::RGBA8:
*glFormat = GraphicsContext3D::RGBA;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
break;
- case GLES2Texture::BGRA8:
+ case Texture::BGRA8:
if (context->supportsBGRA()) {
*glFormat = GraphicsContext3D::BGRA_EXT;
*glType = GraphicsContext3D::UNSIGNED_BYTE;
@@ -79,7 +77,7 @@ static void convertFormat(GraphicsContext3D* context, GLES2Texture::Format forma
}
}
-PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format format, int width, int height)
+PassRefPtr<Texture> Texture::create(GraphicsContext3D* context, Format format, int width, int height)
{
int maxTextureSize = 0;
context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize);
@@ -101,7 +99,8 @@ PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format
IntRect tileBoundsWithBorder = tiling.tileBoundsWithBorder(i);
- unsigned int glFormat, glType;
+ unsigned int glFormat = 0;
+ unsigned int glType = 0;
bool swizzle;
convertFormat(context, format, &glFormat, &glType, &swizzle);
context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
@@ -110,7 +109,7 @@ PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format
tileBoundsWithBorder.height(),
0, glFormat, glType, 0);
}
- return adoptRef(new GLES2Texture(context, textureIds.leakPtr(), format, width, height, maxTextureSize));
+ return adoptRef(new Texture(context, textureIds.leakPtr(), format, width, height, maxTextureSize));
}
template <bool swizzle>
@@ -135,10 +134,11 @@ static uint32_t* copySubRect(uint32_t* src, int srcX, int srcY, uint32_t* dst, i
return dst;
}
-void GLES2Texture::load(void* pixels)
+void Texture::load(void* pixels)
{
uint32_t* pixels32 = static_cast<uint32_t*>(pixels);
- unsigned int glFormat, glType;
+ unsigned int glFormat = 0;
+ unsigned int glType = 0;
bool swizzle;
convertFormat(m_context, m_format, &glFormat, &glType, &swizzle);
if (swizzle) {
@@ -168,7 +168,7 @@ void GLES2Texture::load(void* pixels)
}
}
-void GLES2Texture::bindTile(int tile)
+void Texture::bindTile(int tile)
{
m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(tile));
m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
@@ -178,5 +178,3 @@ void GLES2Texture::bindTile(int tile)
}
}
-
-#endif
diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.h b/WebCore/platform/graphics/gpu/Texture.h
index 43a4955..7e4a72b 100644
--- a/WebCore/platform/graphics/chromium/GLES2Texture.h
+++ b/WebCore/platform/graphics/gpu/Texture.h
@@ -28,10 +28,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef GLES2Texture_h
-#define GLES2Texture_h
-
-#if USE(GLES2_RENDERING)
+#ifndef Texture_h
+#define Texture_h
#include "RefCounted.h"
#include "RefPtr.h"
@@ -43,17 +41,17 @@
namespace WebCore {
class GraphicsContext3D;
-class GLES2Texture : public RefCounted<GLES2Texture> {
+class Texture : public RefCounted<Texture> {
public:
- ~GLES2Texture();
+ ~Texture();
enum Format { RGBA8, BGRA8 };
- static PassRefPtr<GLES2Texture> create(GraphicsContext3D*, Format, int width, int height);
+ static PassRefPtr<Texture> create(GraphicsContext3D*, Format, int width, int height);
void bindTile(int tile);
void load(void* pixels);
Format format() const { return m_format; }
const TilingData& tiles() const { return m_tiles; }
private:
- GLES2Texture(GraphicsContext3D*, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize);
+ Texture(GraphicsContext3D*, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize);
GraphicsContext3D* m_context;
Format m_format;
TilingData m_tiles;
@@ -62,6 +60,4 @@ private:
}
-#endif
-
-#endif // GLES2Texture_h
+#endif // Texture_h
diff --git a/WebCore/platform/graphics/chromium/TilingData.cpp b/WebCore/platform/graphics/gpu/TilingData.cpp
index 4da242b..4da242b 100755..100644
--- a/WebCore/platform/graphics/chromium/TilingData.cpp
+++ b/WebCore/platform/graphics/gpu/TilingData.cpp
diff --git a/WebCore/platform/graphics/chromium/TilingData.h b/WebCore/platform/graphics/gpu/TilingData.h
index f12e66e..f12e66e 100755..100644
--- a/WebCore/platform/graphics/chromium/TilingData.h
+++ b/WebCore/platform/graphics/gpu/TilingData.h
diff --git a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
index 96a639b..e1efdd4 100644
--- a/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
+++ b/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp
@@ -115,13 +115,17 @@ bool GStreamerGWorld::enterFullscreen()
GstQuery* query = gst_query_new_segment(GST_FORMAT_TIME);
gboolean queryResult = gst_element_query(m_pipeline, query);
- // See https://bugzilla.gnome.org/show_bug.cgi?id=620490.
#if GST_CHECK_VERSION(0, 10, 30)
if (!queryResult) {
gst_query_unref(query);
gst_object_unref(GST_OBJECT(srcPad));
return true;
}
+#else
+ // GStreamer < 0.10.30 doesn't set the query result correctly, so
+ // just ignore it to avoid a compilation warning.
+ // See https://bugzilla.gnome.org/show_bug.cgi?id=620490.
+ (void) queryResult;
#endif
GstFormat format;
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamer.h b/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
index 3d6d74a..9288df9 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamer.h
@@ -51,7 +51,6 @@ class ImageGStreamer : public RefCounted<ImageGStreamer> {
#if PLATFORM(CAIRO)
ImageGStreamer(GstBuffer*&, IntSize, cairo_format_t&);
- cairo_surface_t* m_surface;
#endif
#if PLATFORM(MAC)
diff --git a/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp b/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
index 6f975a4..aeaee19 100644
--- a/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
+++ b/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp
@@ -49,13 +49,12 @@ PassRefPtr<ImageGStreamer> ImageGStreamer::createImage(GstBuffer* buffer)
ImageGStreamer::ImageGStreamer(GstBuffer*& buffer, IntSize size, cairo_format_t& cairoFormat)
: m_image(0)
- , m_surface(0)
{
- m_surface = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer), cairoFormat,
+ cairo_surface_t* surface = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer), cairoFormat,
size.width(), size.height(),
cairo_format_stride_for_width(cairoFormat, size.width()));
- ASSERT(cairo_surface_status(m_surface) == CAIRO_STATUS_SUCCESS);
- m_image = BitmapImage::create(m_surface);
+ ASSERT(cairo_surface_status(surface) == CAIRO_STATUS_SUCCESS);
+ m_image = BitmapImage::create(surface);
}
ImageGStreamer::~ImageGStreamer()
@@ -64,9 +63,4 @@ ImageGStreamer::~ImageGStreamer()
m_image.clear();
m_image = 0;
-
- if (m_surface && cairo_surface_get_reference_count(m_surface))
- cairo_surface_destroy(m_surface);
-
- m_surface = 0;
}
diff --git a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
index d9d2d97..5628eb3 100644
--- a/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
@@ -1239,6 +1239,7 @@ static HashSet<String> mimeTypeCache()
for (GList* iterator = factories; iterator; iterator = iterator->next) {
GstTypeFindFactory* factory = GST_TYPE_FIND_FACTORY(iterator->data);
GstCaps* caps = gst_type_find_factory_get_caps(factory);
+ gchar** extensions;
if (!caps)
continue;
@@ -1316,6 +1317,16 @@ static HashSet<String> mimeTypeCache()
g_strfreev(mimetype);
}
+
+ // As a last resort try some special cases depending
+ // on the file extensions registered with the typefind
+ // factory.
+ if (!cached && (extensions = gst_type_find_factory_get_extensions(factory))) {
+ for (int index = 0; extensions[index]; index++) {
+ if (g_str_equal(extensions[index], "m4v"))
+ cache.add(String("video/x-m4v"));
+ }
+ }
}
}
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
index 83dc5dd..8d99f05 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h
@@ -22,14 +22,10 @@
#if ENABLE(VIDEO)
+#include "Widget.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-#if PLATFORM(GTK)
-#include <gtk/gtk.h>
-typedef GtkWidget PlatformWindowType;
-#endif
-
namespace WebCore {
class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> {
@@ -39,13 +35,13 @@ class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> {
PlatformVideoWindow();
~PlatformVideoWindow();
- PlatformWindowType* window() const { return m_window; }
- gulong videoWindowId() const { return m_videoWindowId; }
+ PlatformWidget window() const { return m_window; }
+ unsigned long videoWindowId() const { return m_videoWindowId; }
private:
- gulong m_videoWindowId;
- PlatformWindowType* m_videoWindow;
- PlatformWindowType* m_window;
+ unsigned long m_videoWindowId;
+ PlatformWidget m_videoWindow;
+ PlatformWidget m_window;
};
}
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
new file mode 100644
index 0000000..5c0e6ea
--- /dev/null
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowEfl.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 Samsung Electronics
+ *
+ * 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"
+#include "PlatformVideoWindow.h"
+
+#include "NotImplemented.h"
+
+using namespace WebCore;
+
+PlatformVideoWindow::PlatformVideoWindow()
+{
+ notImplemented();
+}
+
+PlatformVideoWindow::~PlatformVideoWindow()
+{
+ notImplemented();
+}
diff --git a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
index 185f535..c5f835c 100644
--- a/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
+++ b/WebCore/platform/graphics/gstreamer/PlatformVideoWindowGtk.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "PlatformVideoWindow.h"
+#include <gtk/gtk.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h> // for GDK_WINDOW_XID
#endif
diff --git a/WebCore/platform/graphics/gtk/CairoUtilities.h b/WebCore/platform/graphics/gtk/CairoUtilities.h
index 89eb458..594abc0 100644
--- a/WebCore/platform/graphics/gtk/CairoUtilities.h
+++ b/WebCore/platform/graphics/gtk/CairoUtilities.h
@@ -26,8 +26,6 @@
#ifndef CairoUtilities_h
#define CairoUtilities_h
-typedef struct _cairo_surface cairo_surface_t;
-typedef struct _GdkPixbuf GdkPixbuf;
GdkPixbuf* cairoImageSurfaceToGdkPixbuf(cairo_surface_t* surface);
#endif // CairoUtilities_h
diff --git a/WebCore/platform/graphics/gtk/FontGtk.cpp b/WebCore/platform/graphics/gtk/FontGtk.cpp
index 92f8816..489bad7 100644
--- a/WebCore/platform/graphics/gtk/FontGtk.cpp
+++ b/WebCore/platform/graphics/gtk/FontGtk.cpp
@@ -241,11 +241,11 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
float red, green, blue, alpha;
// Text shadow, inspired by FontMac
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur = 0;
Color shadowColor;
bool hasShadow = context->textDrawingMode() == cTextFill &&
- context->getShadow(shadowSize, shadowBlur, shadowColor);
+ context->getShadow(shadowOffset, shadowBlur, shadowColor);
// TODO: Blur support
if (hasShadow) {
@@ -257,7 +257,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
shadowFillColor.getRGBA(red, green, blue, alpha);
cairo_set_source_rgba(cr, red, green, blue, alpha);
- cairo_translate(cr, shadowSize.width(), shadowSize.height());
+ cairo_translate(cr, shadowOffset.width(), shadowOffset.height());
if (partialRegion) {
gdk_cairo_region(cr, partialRegion);
@@ -290,7 +290,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
// Re-enable the platform shadow we disabled earlier
if (hasShadow)
- context->setShadow(shadowSize, shadowBlur, shadowColor, DeviceColorSpace);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace);
// Pango sometimes leaves behind paths we don't want
cairo_new_path(cr);
diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
index 6561c11..252abd7 100644
--- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
@@ -248,7 +248,7 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
drawLine(origin, endPoint);
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle)
{
if (paintingDisabled())
return;
diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm
index db77402..33a930b 100644
--- a/WebCore/platform/graphics/mac/FontMac.mm
+++ b/WebCore/platform/graphics/mac/FontMac.mm
@@ -135,11 +135,11 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
CGContextSetFontSize(cgContext, platformData.m_size);
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
ColorSpace fillColorSpace = context->fillColorSpace();
- context->getShadow(shadowSize, shadowBlur, shadowColor);
+ context->getShadow(shadowOffset, shadowBlur, shadowColor);
bool hasSimpleShadow = context->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur && !platformData.isColorBitmapFont();
if (hasSimpleShadow) {
@@ -148,10 +148,10 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
Color fillColor = context->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
context->setFillColor(shadowFillColor, fillColorSpace);
- CGContextSetTextPosition(cgContext, point.x() + shadowSize.width(), point.y() + shadowSize.height());
+ CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width(), point.y() + shadowOffset.height());
showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, point.x() + shadowSize.width() + font->syntheticBoldOffset(), point.y() + shadowSize.height());
+ CGContextSetTextPosition(cgContext, point.x() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + shadowOffset.height());
showGlyphsWithAdvances(platformData, cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
context->setFillColor(fillColor, fillColorSpace);
@@ -165,7 +165,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
}
if (hasSimpleShadow)
- context->setShadow(shadowSize, shadowBlur, shadowColor, fillColorSpace);
+ context->setShadow(shadowOffset, shadowBlur, shadowColor, fillColorSpace);
if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing)
CGContextSetShouldSmoothFonts(cgContext, originalShouldUseFontSmoothing);
diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
index 5f111f6..f3301d8 100644
--- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm
+++ b/WebCore/platform/graphics/mac/GraphicsContextMac.mm
@@ -119,7 +119,7 @@ static NSColor* createPatternColor(NSString* name, NSColor* defaultColor, bool&
}
// WebKit on Mac is a standard platform component, so it must use the standard platform artwork for underline.
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style)
{
if (paintingDisabled())
return;
@@ -127,23 +127,41 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point,
// These are the same for misspelling or bad grammar.
int patternHeight = cMisspellingLineThickness;
int patternWidth = cMisspellingLinePatternWidth;
-
+
bool usingDot;
NSColor *patternColor;
- if (grammar) {
- // Constants for grammar pattern color.
- static bool usingDotForGrammar = false;
- DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, grammarPatternColor, (createPatternColor(@"GrammarDot", [NSColor greenColor], usingDotForGrammar)));
-
- usingDot = usingDotForGrammar;
- patternColor = grammarPatternColor.get();
- } else {
- // Constants for spelling pattern color.
- static bool usingDotForSpelling = false;
- DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, spellingPatternColor, (createPatternColor(@"SpellingDot", [NSColor redColor], usingDotForSpelling)));
-
- usingDot = usingDotForSpelling;
- patternColor = spellingPatternColor.get();
+ switch (style) {
+ case TextCheckingSpellingLineStyle:
+ {
+ // Constants for spelling pattern color.
+ static bool usingDotForSpelling = false;
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, spellingPatternColor, (createPatternColor(@"SpellingDot", [NSColor redColor], usingDotForSpelling)));
+ usingDot = usingDotForSpelling;
+ patternColor = spellingPatternColor.get();
+ break;
+ }
+ case TextCheckingGrammarLineStyle:
+ {
+ // Constants for grammar pattern color.
+ static bool usingDotForGrammar = false;
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, grammarPatternColor, (createPatternColor(@"GrammarDot", [NSColor greenColor], usingDotForGrammar)));
+ usingDot = usingDotForGrammar;
+ patternColor = grammarPatternColor.get();
+ break;
+ }
+#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
+ case TextCheckingReplacementLineStyle:
+ {
+ // Constants for spelling pattern color.
+ static bool usingDotForSpelling = false;
+ DEFINE_STATIC_LOCAL(RetainPtr<NSColor>, spellingPatternColor, (createPatternColor(@"CorrectionDot", [NSColor blueColor], usingDotForSpelling)));
+ usingDot = usingDotForSpelling;
+ patternColor = spellingPatternColor.get();
+ break;
+ }
+#endif
+ default:
+ return;
}
// Make sure to draw only complete dots.
diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
index 435e56e..7b0e7af 100644
--- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
+++ b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm
@@ -82,6 +82,7 @@ SOFT_LINK_POINTER(QTKit, QTMediaTypeSound, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeText, NSString *)
SOFT_LINK_POINTER(QTKit, QTMediaTypeVideo, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieAskUnresolvedDataRefsAttribute, NSString *)
+SOFT_LINK_POINTER(QTKit, QTMovieLoopsAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDataSizeAttribute, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieDidEndNotification, NSString *)
SOFT_LINK_POINTER(QTKit, QTMovieHasVideoAttribute, NSString *)
@@ -118,6 +119,7 @@ SOFT_LINK_POINTER(QTKit, QTMovieApertureModeAttribute, NSString *)
#define QTMediaTypeText getQTMediaTypeText()
#define QTMediaTypeVideo getQTMediaTypeVideo()
#define QTMovieAskUnresolvedDataRefsAttribute getQTMovieAskUnresolvedDataRefsAttribute()
+#define QTMovieLoopsAttribute getQTMovieLoopsAttribute()
#define QTMovieDataSizeAttribute getQTMovieDataSizeAttribute()
#define QTMovieDidEndNotification getQTMovieDidEndNotification()
#define QTMovieHasVideoAttribute getQTMovieHasVideoAttribute()
@@ -153,6 +155,10 @@ enum {
};
#endif
+@interface FakeQTMovieView : NSObject
+- (WebCoreMovieObserver *)delegate;
+@end
+
using namespace WebCore;
using namespace std;
@@ -243,6 +249,7 @@ void MediaPlayerPrivate::createQTMovie(const String& url)
[NSNumber numberWithBool:YES], QTMoviePreventExternalURLLinksAttribute,
[NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute,
[NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute,
+ [NSNumber numberWithBool:NO], QTMovieLoopsAttribute,
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
[NSNumber numberWithBool:YES], @"QTMovieOpenForPlaybackAttribute",
#endif
@@ -254,8 +261,41 @@ void MediaPlayerPrivate::createQTMovie(const String& url)
createQTMovie(cocoaURL, movieAttributes);
}
+static void disableComponentsOnce()
+{
+ static bool sComponentsDisabled = false;
+ if (sComponentsDisabled)
+ return;
+ sComponentsDisabled = true;
+
+ // eat/PDF and grip/PDF components must be disabled twice since they are registered twice
+ // with different flags. However, there is currently a bug in 64-bit QTKit (<rdar://problem/8378237>)
+ // which causes subsequent disable component requests of exactly the same type to be ignored if
+ // QTKitServer has not yet started. As a result, we must pass in exactly the flags we want to
+ // disable per component. As a failsafe, if in the future these flags change, we will disable the
+ // PDF components for a third time with a wildcard flags field:
+ uint32_t componentsToDisable[11][5] = {
+ {'eat ', 'TEXT', 'text', 0, 0},
+ {'eat ', 'TXT ', 'text', 0, 0},
+ {'eat ', 'utxt', 'text', 0, 0},
+ {'eat ', 'TEXT', 'tx3g', 0, 0},
+ {'eat ', 'PDF ', 'vide', 0x44802, 0},
+ {'eat ', 'PDF ', 'vide', 0x45802, 0},
+ {'eat ', 'PDF ', 'vide', 0, 0},
+ {'grip', 'PDF ', 'appl', 0x844a00, 0},
+ {'grip', 'PDF ', 'appl', 0x845a00, 0},
+ {'grip', 'PDF ', 'appl', 0, 0},
+ {'imdc', 'pdf ', 'appl', 0, 0},
+ };
+
+ for (size_t i = 0; i < sizeof(componentsToDisable)/sizeof(componentsToDisable[0]); ++i)
+ wkQTMovieDisableComponent(componentsToDisable[i]);
+}
+
void MediaPlayerPrivate::createQTMovie(NSURL *url, NSDictionary *movieAttributes)
{
+ disableComponentsOnce();
+
[[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()];
bool recreating = false;
@@ -315,11 +355,12 @@ void MediaPlayerPrivate::createQTMovie(NSURL *url, NSDictionary *movieAttributes
static void mainThreadSetNeedsDisplay(id self, SEL)
{
- id movieView = [self superview];
- ASSERT(!movieView || [movieView isKindOfClass:[QTMovieView class]]);
- if (!movieView || ![movieView isKindOfClass:[QTMovieView class]])
+ id view = [self superview];
+ ASSERT(!view || [view isKindOfClass:[QTMovieView class]]);
+ if (!view || ![view isKindOfClass:[QTMovieView class]])
return;
+ FakeQTMovieView *movieView = static_cast<FakeQTMovieView *>(view);
WebCoreMovieObserver* delegate = [movieView delegate];
ASSERT(!delegate || [delegate isKindOfClass:[WebCoreMovieObserver class]]);
if (!delegate || ![delegate isKindOfClass:[WebCoreMovieObserver class]])
@@ -1382,6 +1423,7 @@ void MediaPlayerPrivate::disableUnsupportedTracks()
allowedTrackTypes->add("sdsm"); // MPEG-4 scene description stream
allowedTrackTypes->add("tmcd"); // timecode
allowedTrackTypes->add("tc64"); // timcode-64
+ allowedTrackTypes->add("tmet"); // timed metadata
}
NSArray *tracks = [m_qtMovie.get() tracks];
diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
index 126ef2d..94fcc5e 100644
--- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
+++ b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm
@@ -101,11 +101,11 @@ static NSString *webFallbackFontFamily(void)
}
#if !ERROR_DISABLED
-#ifdef __LP64__
+#if defined(__LP64__) || (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD))
static NSString* pathFromFont(NSFont*)
{
- // FMGetATSFontRefFromFont is not available in 64-bit. As pathFromFont is only used for debugging
- // purposes, returning nil is acceptable.
+ // FMGetATSFontRefFromFont is not available. As pathFromFont is only used for debugging purposes,
+ // returning nil is acceptable.
return nil;
}
#else
diff --git a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
index 0faf3ce..37fd8ad 100644
--- a/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
+++ b/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp
@@ -273,7 +273,7 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
UNUSED_PARAM(printing);
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style)
{
if (paintingDisabled())
return;
@@ -281,7 +281,7 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin,
notImplemented();
UNUSED_PARAM(origin);
UNUSED_PARAM(width);
- UNUSED_PARAM(grammar);
+ UNUSED_PARAM(style);
}
FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect)
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index 41c9759..c9c74dd 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -845,7 +845,7 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool)
drawLine(origin, endPoint);
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int, bool)
+void GraphicsContext::drawLineForTextChecking(const IntPoint&, int, TextCheckingLineStyle)
{
if (paintingDisabled())
return;
@@ -889,7 +889,7 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const
if (m_common->state.shadowsIgnoreTransforms) {
// 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.shadowSize = FloatSize(size.width(), -size.height());
+ m_common->state.shadowOffset = FloatSize(size.width(), -size.height());
m_data->shadow = ContextShadow(color, blur, size.width(), -size.height());
} else {
m_data->shadow = ContextShadow(color, blur, size.width(), size.height());
diff --git a/WebCore/platform/graphics/qt/ImageQt.cpp b/WebCore/platform/graphics/qt/ImageQt.cpp
index e0ac574..c0cfae4 100644
--- a/WebCore/platform/graphics/qt/ImageQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageQt.cpp
@@ -190,12 +190,12 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
QPainter::CompositionMode lastCompositionMode = painter->compositionMode();
painter->setCompositionMode(compositionMode);
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (ctxt->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ if (ctxt->getShadow(shadowOffset, shadowBlur, shadowColor)) {
FloatRect shadowImageRect(normalizedDst);
- shadowImageRect.move(shadowSize.width(), shadowSize.height());
+ shadowImageRect.move(shadowOffset.width(), shadowOffset.height());
QImage shadowImage(QSize(static_cast<int>(normalizedSrc.width()), static_cast<int>(normalizedSrc.height())), QImage::Format_ARGB32_Premultiplied);
QPainter p(&shadowImage);
diff --git a/WebCore/platform/graphics/qt/StillImageQt.cpp b/WebCore/platform/graphics/qt/StillImageQt.cpp
index 9c6acab..3038356 100644
--- a/WebCore/platform/graphics/qt/StillImageQt.cpp
+++ b/WebCore/platform/graphics/qt/StillImageQt.cpp
@@ -76,12 +76,12 @@ void StillImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
ctxt->setCompositeOperation(op);
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- if (ctxt->getShadow(shadowSize, shadowBlur, shadowColor)) {
+ if (ctxt->getShadow(shadowOffset, shadowBlur, shadowColor)) {
FloatRect shadowImageRect(normalizedDst);
- shadowImageRect.move(shadowSize.width(), shadowSize.height());
+ shadowImageRect.move(shadowOffset.width(), shadowOffset.height());
QImage shadowImage(QSize(static_cast<int>(normalizedSrc.width()), static_cast<int>(normalizedSrc.height())), QImage::Format_ARGB32_Premultiplied);
QPainter p(&shadowImage);
diff --git a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
index 61039f2..c503307 100644
--- a/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContext3DSkia.cpp
@@ -44,28 +44,40 @@ bool GraphicsContext3D::getImageData(Image* image,
bool premultiplyAlpha,
Vector<uint8_t>& outputVector)
{
- if (!image || !image->data())
+ if (!image)
return false;
- ImageSource decoder(false);
- decoder.setData(image->data(), true);
- if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
- return false;
- bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
- OwnPtr<NativeImageSkia> pixels(decoder.createFrameAtIndex(0));
- if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
- return false;
- SkBitmap::Config skiaConfig = pixels->config();
- if (skiaConfig != SkBitmap::kARGB_8888_Config)
+ OwnPtr<NativeImageSkia> pixels;
+ NativeImageSkia* skiaImage = 0;
+ AlphaOp neededAlphaOp = kAlphaDoNothing;
+ if (image->data()) {
+ ImageSource decoder(false);
+ decoder.setData(image->data(), true);
+ if (!decoder.frameCount() || !decoder.frameIsCompleteAtIndex(0))
+ return false;
+ bool hasAlpha = decoder.frameHasAlphaAtIndex(0);
+ pixels = decoder.createFrameAtIndex(0);
+ if (!pixels.get() || !pixels->isDataComplete() || !pixels->width() || !pixels->height())
+ return false;
+ SkBitmap::Config skiaConfig = pixels->config();
+ if (skiaConfig != SkBitmap::kARGB_8888_Config)
+ return false;
+ skiaImage = pixels.get();
+ if (hasAlpha && premultiplyAlpha)
+ neededAlphaOp = kAlphaDoPremultiply;
+ } else {
+ // This is a special case for texImage2D with HTMLCanvasElement input.
+ skiaImage = image->nativeImageForCurrentFrame();
+ if (!premultiplyAlpha)
+ neededAlphaOp = kAlphaDoUnmultiply;
+ }
+ if (!skiaImage)
return false;
- SkBitmap& skiaImageRef = *pixels;
+ SkBitmap& skiaImageRef = *skiaImage;
SkAutoLockPixels lock(skiaImageRef);
- ASSERT(pixels->rowBytes() == pixels->width() * 4);
- outputVector.resize(pixels->rowBytes() * pixels->height());
- AlphaOp neededAlphaOp = kAlphaDoNothing;
- if (hasAlpha && premultiplyAlpha)
- neededAlphaOp = kAlphaDoPremultiply;
- return packPixels(reinterpret_cast<const uint8_t*>(pixels->getPixels()),
- kSourceFormatBGRA8, pixels->width(), pixels->height(), 0,
+ ASSERT(skiaImage->rowBytes() == skiaImage->width() * 4);
+ outputVector.resize(skiaImage->rowBytes() * skiaImage->height());
+ return packPixels(reinterpret_cast<const uint8_t*>(skiaImage->getPixels()),
+ kSourceFormatBGRA8, skiaImage->width(), skiaImage->height(), 0,
format, type, neededAlphaOp, outputVector.data());
}
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index 1b20e26..1c80d49 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -34,6 +34,7 @@
#include "AffineTransform.h"
#include "Color.h"
#include "FloatRect.h"
+#include "GLES2Canvas.h"
#include "Gradient.h"
#include "GraphicsContextPlatformPrivate.h"
#include "GraphicsContextPrivate.h"
@@ -55,10 +56,6 @@
#include <wtf/MathExtras.h>
#include <wtf/UnusedParam.h>
-#if USE(GLES2_RENDERING)
-#include "GLES2Canvas.h"
-#endif
-
using namespace std;
namespace WebCore {
@@ -248,10 +245,8 @@ void GraphicsContext::savePlatformState()
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->save();
-#endif
// Save our private State.
platformContext()->save();
@@ -262,10 +257,8 @@ void GraphicsContext::restorePlatformState()
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->restore();
-#endif
// Restore our private State.
platformContext()->restore();
@@ -345,13 +338,11 @@ void GraphicsContext::clearRect(const FloatRect& rect)
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->clearRect(rect);
return;
}
-#endif
platformContext()->prepareForSoftwareDraw();
@@ -459,10 +450,8 @@ void GraphicsContext::concatCTM(const AffineTransform& affine)
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->concatCTM(affine);
-#endif
platformContext()->canvas()->concat(affine);
}
@@ -626,9 +615,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint);
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& pt,
- int width,
- bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style)
{
if (paintingDisabled())
return;
@@ -780,13 +767,11 @@ void GraphicsContext::fillRect(const FloatRect& rect)
ClipRectToCanvas(*platformContext()->canvas(), r, &r);
}
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient && !platformContext()->getDrawLooper()) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect);
return;
}
-#endif
platformContext()->save();
@@ -804,13 +789,11 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU() && !m_common->state.fillPattern && !m_common->state.fillGradient) {
platformContext()->prepareForHardwareDraw();
platformContext()->gpuCanvas()->fillRect(rect, color, colorSpace);
return;
}
-#endif
platformContext()->prepareForSoftwareDraw();
@@ -932,10 +915,8 @@ void GraphicsContext::scale(const FloatSize& size)
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->scale(size);
-#endif
platformContext()->canvas()->scale(WebCoreFloatToSkScalar(size.width()),
WebCoreFloatToSkScalar(size.height()));
@@ -945,10 +926,10 @@ void GraphicsContext::setAlpha(float alpha)
{
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
+
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->setAlpha(alpha);
-#endif
+
platformContext()->setAlpha(alpha);
}
@@ -956,10 +937,10 @@ void GraphicsContext::setCompositeOperation(CompositeOperator op)
{
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
+
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->setCompositeOperation(op);
-#endif
+
platformContext()->setXfermodeMode(WebCoreCompositeToSkiaComposite(op));
}
@@ -1046,10 +1027,9 @@ void GraphicsContext::setPlatformFillColor(const Color& color, ColorSpace colorS
{
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
+
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->setFillColor(color, colorSpace);
-#endif
platformContext()->setFillColor(color.rgb());
}
@@ -1241,10 +1221,8 @@ void GraphicsContext::rotate(float angleInRadians)
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->rotate(angleInRadians);
-#endif
platformContext()->canvas()->rotate(WebCoreFloatToSkScalar(
angleInRadians * (180.0f / 3.14159265f)));
@@ -1255,10 +1233,8 @@ void GraphicsContext::translate(float w, float h)
if (paintingDisabled())
return;
-#if USE(GLES2_RENDERING)
if (platformContext()->useGPU())
platformContext()->gpuCanvas()->translate(w, h);
-#endif
platformContext()->canvas()->translate(WebCoreFloatToSkScalar(w),
WebCoreFloatToSkScalar(h));
@@ -1266,19 +1242,12 @@ void GraphicsContext::translate(float w, float h)
void GraphicsContext::setGraphicsContext3D(GraphicsContext3D* context3D, const IntSize& size)
{
-#if USE(GLES2_RENDERING)
platformContext()->setGraphicsContext3D(context3D, size);
-#else
- UNUSED_PARAM(context3D);
- UNUSED_PARAM(size);
-#endif
}
void GraphicsContext::syncSoftwareCanvas()
{
-#if USE(GLES2_RENDERING)
platformContext()->syncSoftwareCanvas();
-#endif
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp
index 1ff87cc..aed289f 100644
--- a/WebCore/platform/graphics/skia/ImageSkia.cpp
+++ b/WebCore/platform/graphics/skia/ImageSkia.cpp
@@ -36,22 +36,20 @@
#include "ChromiumBridge.h"
#include "FloatConversion.h"
#include "FloatRect.h"
+#include "GLES2Canvas.h"
+#include "GLES2Context.h"
#include "GraphicsContext.h"
#include "Logging.h"
#include "NativeImageSkia.h"
#include "PlatformContextSkia.h"
#include "PlatformString.h"
-#include "SkiaUtils.h"
+#include "SkPixelRef.h"
#include "SkRect.h"
#include "SkShader.h"
+#include "SkiaUtils.h"
#include "skia/ext/image_operations.h"
#include "skia/ext/platform_canvas.h"
-#if USE(GLES2_RENDERING)
-#include "GLES2Canvas.h"
-#include "GLES2Context.h"
-#include "SkPixelRef.h"
-#endif
namespace WebCore {
@@ -409,23 +407,21 @@ void Image::drawPattern(GraphicsContext* context,
context->platformContext()->paintSkPaint(destRect, paint);
}
-#if USE(GLES2_RENDERING)
static void drawBitmapGLES2(GraphicsContext* ctxt, NativeImageSkia* bitmap, const FloatRect& srcRect, const FloatRect& dstRect, ColorSpace styleColorSpace, CompositeOperator compositeOp)
{
ctxt->platformContext()->prepareForHardwareDraw();
GLES2Canvas* gpuCanvas = ctxt->platformContext()->gpuCanvas();
- GLES2Texture* texture = gpuCanvas->getTexture(bitmap);
+ Texture* texture = gpuCanvas->getTexture(bitmap);
if (!texture) {
ASSERT(bitmap->config() == SkBitmap::kARGB_8888_Config);
ASSERT(bitmap->rowBytes() == bitmap->width() * 4);
- texture = gpuCanvas->createTexture(bitmap, GLES2Texture::BGRA8, bitmap->width(), bitmap->height());
+ texture = gpuCanvas->createTexture(bitmap, Texture::BGRA8, bitmap->width(), bitmap->height());
SkAutoLockPixels lock(*bitmap);
ASSERT(bitmap->getPixels());
texture->load(bitmap->getPixels());
}
gpuCanvas->drawTexturedRect(texture, srcRect, dstRect, styleColorSpace, compositeOp);
}
-#endif
// ================================================
// BitmapImage Class
@@ -472,12 +468,11 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect,
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
-#if USE(GLES2_RENDERING)
if (ctxt->platformContext()->useGPU()) {
drawBitmapGLES2(ctxt, bm, normSrcRect, normDstRect, colorSpace, compositeOp);
return;
}
-#endif
+
ctxt->platformContext()->prepareForSoftwareDraw();
paintSkBitmap(ctxt->platformContext(),
@@ -501,12 +496,10 @@ void BitmapImageSingleFrameSkia::draw(GraphicsContext* ctxt,
if (normSrcRect.isEmpty() || normDstRect.isEmpty())
return; // Nothing to draw.
-#if USE(GLES2_RENDERING)
if (ctxt->platformContext()->useGPU()) {
drawBitmapGLES2(ctxt, &m_nativeImage, srcRect, dstRect, styleColorSpace, compositeOp);
return;
}
-#endif
ctxt->platformContext()->prepareForSoftwareDraw();
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index b9de0a2..3b1d015 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -34,11 +34,13 @@
#include "AffineTransform.h"
#include "CanvasLayerChromium.h"
+#include "GLES2Canvas.h"
#include "GraphicsContext.h"
+#include "GraphicsContext3D.h"
#include "ImageBuffer.h"
#include "NativeImageSkia.h"
-#include "PlatformContextSkia.h"
#include "SkiaUtils.h"
+#include "Texture.h"
#include "TilingData.h"
#include "skia/ext/image_operations.h"
@@ -46,14 +48,8 @@
#include "SkBitmap.h"
#include "SkColorPriv.h"
-#include "SkShader.h"
#include "SkDashPathEffect.h"
-
-#if USE(GLES2_RENDERING)
-#include "GraphicsContext3D.h"
-#include "GLES2Canvas.h"
-#include "GLES2Texture.h"
-#endif
+#include "SkShader.h"
#include <wtf/MathExtras.h>
#include <wtf/OwnArrayPtr.h>
@@ -210,11 +206,9 @@ PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
#if OS(WINDOWS)
, m_drawingToImageBuffer(false)
#endif
-#if USE(GLES2_RENDERING)
, m_useGPU(false)
, m_gpuCanvas(0)
, m_backingStoreState(None)
-#endif
{
m_stateStack.append(State());
m_state = &m_stateStack.last();
@@ -222,7 +216,7 @@ PlatformContextSkia::PlatformContextSkia(skia::PlatformCanvas* canvas)
PlatformContextSkia::~PlatformContextSkia()
{
-#if USE(GLES2_RENDERING) && USE(ACCELERATED_COMPOSITING)
+#if USE(ACCELERATED_COMPOSITING)
if (m_gpuCanvas) {
CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(m_gpuCanvas->context()->platformLayer());
layer->setPrepareTextureCallback(0);
@@ -684,7 +678,6 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
m_canvas->restore();
}
-#if USE(GLES2_RENDERING)
#if USE(ACCELERATED_COMPOSITING)
class PrepareTextureCallbackImpl : public CanvasLayerChromium::PrepareTextureCallback {
public:
@@ -793,7 +786,7 @@ void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const
SkAutoLockPixels lock(bitmap);
GraphicsContext3D* context = m_gpuCanvas->context();
if (!m_uploadTexture || m_uploadTexture->tiles().totalSizeX() < bitmap.width() || m_uploadTexture->tiles().totalSizeY() < bitmap.height())
- m_uploadTexture = GLES2Texture::create(context, GLES2Texture::BGRA8, bitmap.width(), bitmap.height());
+ m_uploadTexture = Texture::create(context, Texture::BGRA8, bitmap.width(), bitmap.height());
m_uploadTexture->load(bitmap.getPixels());
IntRect rect(0, 0, bitmap.width(), bitmap.height());
AffineTransform identity;
@@ -823,5 +816,4 @@ void PlatformContextSkia::readbackHardwareToSoftware() const
}
}
-#endif
} // namespace WebCore
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 6c84797..82edc16 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -35,22 +35,20 @@
#include "Noncopyable.h"
#include "SkDashPathEffect.h"
-#include "SkDrawLooper.h"
#include "SkDeque.h"
-#include "skia/ext/platform_canvas.h"
+#include "SkDrawLooper.h"
#include "SkPaint.h"
#include "SkPath.h"
+#include "skia/ext/platform_canvas.h"
#include <wtf/Vector.h>
namespace WebCore {
-#if USE(GLES2_RENDERING)
enum CompositeOperator;
class GLES2Canvas;
-class GLES2Texture;
+class Texture;
class GraphicsContext3D;
-#endif
// This class holds the platform-specific state for GraphicsContext. We put
// most of our Skia wrappers on this class. In theory, a lot of this stuff could
@@ -182,24 +180,16 @@ public:
void setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize);
void clearImageResamplingHint();
bool hasImageResamplingHint() const;
-#if USE(GLES2_RENDERING)
bool useGPU() { return m_useGPU; }
void setGraphicsContext3D(GraphicsContext3D*, const IntSize&);
GLES2Canvas* gpuCanvas() const { return m_gpuCanvas.get(); }
-#endif
-#if USE(GLES2_RENDERING)
// Call these before making a call that manipulates the underlying
// skia::PlatformCanvas or WebCore::GLES2Canvas
void prepareForSoftwareDraw() const;
void prepareForHardwareDraw() const;
// Call to force the skia::PlatformCanvas to contain all rendering results.
void syncSoftwareCanvas() const;
-#else
- void prepareForSoftwareDraw() const {}
- void prepareForHardwareDraw() const {}
- void syncSoftwareCanvas() const {}
-#endif
private:
#if OS(LINUX) || OS(WINDOWS)
@@ -209,10 +199,8 @@ private:
#endif
void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
-#if USE(GLES2_RENDERING)
void uploadSoftwareToHardware(CompositeOperator) const;
void readbackHardwareToSoftware() const;
-#endif
// Defines drawing style.
struct State;
@@ -237,12 +225,10 @@ private:
#if OS(WINDOWS)
bool m_drawingToImageBuffer;
#endif
-#if USE(GLES2_RENDERING)
bool m_useGPU;
OwnPtr<GLES2Canvas> m_gpuCanvas;
mutable enum { None, Software, Mixed, Hardware } m_backingStoreState;
- mutable RefPtr<GLES2Texture> m_uploadTexture;
-#endif
+ mutable RefPtr<Texture> m_uploadTexture;
};
}
diff --git a/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
index 44003bb..9edb775 100644
--- a/WebCore/platform/graphics/skia/SkiaFontWin.cpp
+++ b/WebCore/platform/graphics/skia/SkiaFontWin.cpp
@@ -222,11 +222,11 @@ void SkiaWinOutlineCache::removePathsForFont(HFONT hfont)
bool windowsCanHandleDrawTextShadow(GraphicsContext *context)
{
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- bool hasShadow = context->getShadow(shadowSize, shadowBlur, shadowColor);
+ bool hasShadow = context->getShadow(shadowOffset, shadowBlur, shadowColor);
return (hasShadow && (shadowBlur == 0) && (shadowColor.alpha() == 255) && (context->fillColor().alpha() == 255));
}
diff --git a/WebCore/platform/graphics/win/FontCGWin.cpp b/WebCore/platform/graphics/win/FontCGWin.cpp
index 34f9b07..c6437f2 100644
--- a/WebCore/platform/graphics/win/FontCGWin.cpp
+++ b/WebCore/platform/graphics/win/FontCGWin.cpp
@@ -140,11 +140,11 @@ static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData
drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer();
if (!drawIntoBitmap) {
- FloatSize size;
+ FloatSize offset;
float blur;
Color color;
- graphicsContext->getShadow(size, blur, color);
- drawIntoBitmap = !size.isEmpty() || blur;
+ graphicsContext->getShadow(offset, blur, color);
+ drawIntoBitmap = offset.width() || offset.height() || blur;
}
}
@@ -349,10 +349,10 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
CGContextSetFontSize(cgContext, platformData.size());
wkSetCGContextFontRenderingStyle(cgContext, font->isSystemFont(), false, font->platformData().useGDI());
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur;
Color shadowColor;
- graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor);
+ graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor);
bool hasSimpleShadow = graphicsContext->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur;
if (hasSimpleShadow) {
@@ -361,10 +361,10 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
Color fillColor = graphicsContext->fillColor();
Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
graphicsContext->setFillColor(shadowFillColor, DeviceColorSpace);
- CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width(), point.y() + translation.height() + shadowSize.height());
+ CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowOffset.width(), point.y() + translation.height() + shadowOffset.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
if (font->syntheticBoldOffset()) {
- CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowSize.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowSize.height());
+ CGContextSetTextPosition(cgContext, point.x() + translation.width() + shadowOffset.width() + font->syntheticBoldOffset(), point.y() + translation.height() + shadowOffset.height());
CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs);
}
graphicsContext->setFillColor(fillColor, DeviceColorSpace);
@@ -378,7 +378,7 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
}
if (hasSimpleShadow)
- graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor, DeviceColorSpace);
+ graphicsContext->setShadow(shadowOffset, shadowBlur, shadowColor, DeviceColorSpace);
wkRestoreFontSmoothingStyle(cgContext, oldFontSmoothingStyle);
}
diff --git a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
index 84c4ce0..7b65e96 100644
--- a/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp
@@ -176,11 +176,14 @@ static const Color& grammarPatternColor() {
return grammarColor;
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style)
{
if (paintingDisabled())
return;
+ if (style != TextCheckingSpellingLineStyle && style != TextCheckingGrammarLineStyle)
+ return;
+
// These are the same for misspelling or bad grammar
const int patternHeight = 3; // 3 rows
ASSERT(cMisspellingLineThickness == patternHeight);
@@ -201,7 +204,7 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point,
CGContextRef context = platformContext();
CGContextSaveGState(context);
- const Color& patternColor = grammar ? grammarPatternColor() : spellingPatternColor();
+ const Color& patternColor = style == TextCheckingGrammarLineStyle ? grammarPatternColor() : spellingPatternColor();
setCGStrokeColor(context, patternColor);
wkSetPatternPhaseInUserSpace(context, point);
diff --git a/WebCore/platform/graphics/win/QTMovie.cpp b/WebCore/platform/graphics/win/QTMovie.cpp
index 032b446..cc1349a 100644
--- a/WebCore/platform/graphics/win/QTMovie.cpp
+++ b/WebCore/platform/graphics/win/QTMovie.cpp
@@ -240,6 +240,9 @@ void QTMoviePrivate::createMovieController()
m_movieController = NewMovieController(m_movie, &bounds, flags);
if (!m_movieController)
return;
+
+ // Disable automatic looping.
+ MCDoAction(m_movieController, mcActionSetLooping, 0);
}
void QTMoviePrivate::cacheMovieScale()
diff --git a/WebCore/platform/graphics/wince/FontPlatformData.h b/WebCore/platform/graphics/wince/FontPlatformData.h
index 0b973b8..4a174f0 100644
--- a/WebCore/platform/graphics/wince/FontPlatformData.h
+++ b/WebCore/platform/graphics/wince/FontPlatformData.h
@@ -26,9 +26,9 @@
#define FontPlatformData_h
#include "FontDescription.h"
-#include "StringImpl.h"
#include <wtf/Forward.h>
#include <wtf/Noncopyable.h>
+#include <wtf/text/StringImpl.h>
typedef struct tagTEXTMETRICW TEXTMETRIC;
typedef struct tagLOGFONTW LOGFONT;
diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
index e4466c8..990a31d 100644
--- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
+++ b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
@@ -1062,7 +1062,7 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
setStrokeStyle(oldStyle);
}
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint&, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle style)
{
notImplemented();
}
@@ -1260,15 +1260,15 @@ void GraphicsContext::fillRoundedRect(const IntRect& fillRect, const IntSize& to
if (!m_data->m_dc)
return;
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur = 0;
Color shadowColor;
- getShadow(shadowSize, shadowBlur, shadowColor);
+ getShadow(shadowOffset, shadowBlur, shadowColor);
IntRect dstRect = fillRect;
- dstRect.move(stableRound(shadowSize.width()), stableRound(shadowSize.height()));
+ dstRect.move(stableRound(shadowOffset.width()), stableRound(shadowOffset.height()));
dstRect.inflate(stableRound(shadowBlur));
dstRect = m_data->mapRect(dstRect);
@@ -1548,11 +1548,6 @@ AffineTransform GraphicsContext::getCTM() const
return m_data->m_transform;
}
-void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
-{
- notImplemented();
-}
-
void GraphicsContext::fillRect(const FloatRect& rect)
{
savePlatformState();
@@ -1687,17 +1682,17 @@ void GraphicsContext::drawText(const SimpleFontData* fontData, const GlyphBuffer
return;
}
- FloatSize shadowSize;
+ FloatSize shadowOffset;
float shadowBlur = 0;
Color shadowColor;
bool hasShadow = textDrawingMode() == cTextFill
- && getShadow(shadowSize, shadowBlur, shadowColor)
+ && getShadow(shadowOffset, shadowBlur, shadowColor)
&& shadowColor.alpha();
COLORREF shadowRGBColor;
FloatPoint trShadowPoint;
if (hasShadow) {
shadowRGBColor = RGB(shadowColor.red(), shadowColor.green(), shadowColor.blue());
- trShadowPoint = m_data->mapPoint(startPoint + shadowSize);
+ trShadowPoint = m_data->mapPoint(startPoint + shadowOffset);
}
HGDIOBJ hOldFont = SelectObject(m_data->m_dc, hFont);
diff --git a/WebCore/platform/graphics/wince/ImageBufferWince.cpp b/WebCore/platform/graphics/wince/ImageBufferWince.cpp
index 1a25f4f..10e502d 100644
--- a/WebCore/platform/graphics/wince/ImageBufferWince.cpp
+++ b/WebCore/platform/graphics/wince/ImageBufferWince.cpp
@@ -95,12 +95,33 @@ GraphicsContext* ImageBuffer::context() const
return m_context.get();
}
-Image* ImageBuffer::image() const
+bool ImageBuffer::drawsUsingCopy() const
{
- if (!m_image)
- m_image = adoptRef(new BufferedImage(&m_data));
+ return true;
+}
+
+PassRefPtr<Image> ImageBuffer::copyImage() const
+{
+ return adoptRef(new BufferedImage(&m_data));
+}
+
+void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const
+{
+ notImplemented();
+}
+
+void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect,
+ CompositeOperator op , bool useLowQualityScale)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale);
+}
- return m_image.get();
+void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform,
+ const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect)
+{
+ RefPtr<Image> imageCopy = copyImage();
+ imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect);
}
template <bool premultiplied> PassRefPtr<ImageData>
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 2428e7e..a39404a 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -357,14 +357,18 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool pr
m_data->context->DrawLine(origin.x(), origin.y(), endPoint.x(), endPoint.y());
}
-
-void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& origin, int width, bool grammar)
+void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style)
{
- if (grammar)
- m_data->context->SetPen(wxPen(*wxGREEN, 2, wxLONG_DASH));
- else
+ switch (style) {
+ case TextCheckingSpellingLineStyle:
m_data->context->SetPen(wxPen(*wxRED, 2, wxLONG_DASH));
-
+ break;
+ case TextCheckingGrammarLineStyle:
+ m_data->context->SetPen(wxPen(*wxGREEN, 2, wxLONG_DASH));
+ break;
+ default:
+ return;
+ }
m_data->context->DrawLine(origin.x(), origin.y(), origin.x() + width, origin.y());
}
diff --git a/WebCore/platform/gtk/ClipboardGtk.h b/WebCore/platform/gtk/ClipboardGtk.h
index 8b8ee38..f0af318 100644
--- a/WebCore/platform/gtk/ClipboardGtk.h
+++ b/WebCore/platform/gtk/ClipboardGtk.h
@@ -31,8 +31,6 @@
#include "Clipboard.h"
#include "DataObjectGtk.h"
-typedef struct _GtkClipboard GtkClipboard;
-
namespace WebCore {
class CachedImage;
class Frame;
diff --git a/WebCore/platform/gtk/DataObjectGtk.h b/WebCore/platform/gtk/DataObjectGtk.h
index 6f7149c..e6095da 100644
--- a/WebCore/platform/gtk/DataObjectGtk.h
+++ b/WebCore/platform/gtk/DataObjectGtk.h
@@ -27,10 +27,6 @@
#include <wtf/text/CString.h>
#include <wtf/text/StringHash.h>
-typedef struct _GdkPixbuf GdkPixbuf;
-typedef struct _GdkDragContext GdkDragContext;
-typedef struct _GtkClipboard GtkClipboard;
-
namespace WebCore {
class DataObjectGtk : public RefCounted<DataObjectGtk> {
diff --git a/WebCore/platform/gtk/FileSystemGtk.cpp b/WebCore/platform/gtk/FileSystemGtk.cpp
index 7ad2a39..6f3fa19 100644
--- a/WebCore/platform/gtk/FileSystemGtk.cpp
+++ b/WebCore/platform/gtk/FileSystemGtk.cpp
@@ -187,8 +187,7 @@ String pathGetFileName(const String& pathName)
String directoryName(const String& path)
{
/* No null checking needed */
- GOwnPtr<char> tmpFilename(const_cast<char*>(fileSystemRepresentation(path).data()));
- GOwnPtr<char> dirname(g_path_get_dirname(tmpFilename.get()));
+ GOwnPtr<char> dirname(g_path_get_dirname(fileSystemRepresentation(path).data()));
return String::fromUTF8(dirname.get());
}
diff --git a/WebCore/platform/gtk/GOwnPtrGtk.h b/WebCore/platform/gtk/GOwnPtrGtk.h
index 8341661..c5d9cdc 100644
--- a/WebCore/platform/gtk/GOwnPtrGtk.h
+++ b/WebCore/platform/gtk/GOwnPtrGtk.h
@@ -22,9 +22,6 @@
#include "GOwnPtr.h"
-typedef union _GdkEvent GdkEvent;
-typedef struct _GtkIconInfo GtkIconInfo;
-
namespace WTF {
template <> void freeOwnedGPtr<GdkEvent>(GdkEvent*);
diff --git a/WebCore/platform/gtk/GRefPtrGtk.h b/WebCore/platform/gtk/GRefPtrGtk.h
index ea1b089..5e6ab78 100644
--- a/WebCore/platform/gtk/GRefPtrGtk.h
+++ b/WebCore/platform/gtk/GRefPtrGtk.h
@@ -23,9 +23,6 @@
#include "GRefPtr.h"
-typedef struct _GtkTargetList GtkTargetList;
-typedef struct _GdkCursor GdkCursor;
-
namespace WTF {
template <> GtkTargetList* refPlatformPtr(GtkTargetList* ptr);
diff --git a/WebCore/platform/gtk/GtkVersioning.cpp b/WebCore/platform/gtk/GtkVersioning.c
index e7734a8..7dd601e 100644
--- a/WebCore/platform/gtk/GtkVersioning.cpp
+++ b/WebCore/platform/gtk/GtkVersioning.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Collabora Ltd.
+ * 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
@@ -17,7 +18,6 @@
* Boston, MA 02110-1301, USA.
*/
-#include "config.h"
#include "GtkVersioning.h"
#include <gtk/gtk.h>
@@ -48,3 +48,22 @@ void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble
gtk_adjustment_value_changed(adjustment);
}
#endif
+
+GdkDevice *getDefaultGDKPointerDevice(GdkWindow* window)
+{
+#ifndef GTK_API_VERSION_2
+ GdkDeviceManager *manager = gdk_display_get_device_manager(gdk_drawable_get_display(window));
+ return gdk_device_manager_get_client_pointer(manager);
+#else
+ return gdk_device_get_core_pointer();
+#endif // GTK_API_VERSION_2
+}
+
+#if !GTK_CHECK_VERSION(2, 17, 3)
+static void gdk_window_get_root_coords(GdkWindow* window, gint x, gint y, gint* rootX, gint* rootY)
+{
+ gdk_window_get_root_origin(window, rootX, rootY);
+ *rootX = *rootX + x;
+ *rootY = *rootY + y;
+}
+#endif
diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h
index 34e6081..eac3cb5 100644
--- a/WebCore/platform/gtk/GtkVersioning.h
+++ b/WebCore/platform/gtk/GtkVersioning.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2010 Collabora Ltd.
+ * 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
@@ -22,6 +23,8 @@
#include <gtk/gtk.h>
+G_BEGIN_DECLS
+
// Macros to avoid deprecation checking churn
#if !GTK_CHECK_VERSION(2, 21, 2)
#define gdk_visual_get_depth(visual) (visual)->depth
@@ -51,6 +54,10 @@
#define gtk_widget_set_allocation(widget, alloc) ((widget)->allocation = *(alloc))
#endif // GTK_CHECK_VERSION(2, 18, 0)
+#if !GTK_CHECK_VERSION(2, 17, 3)
+static void gdk_window_get_root_coords(GdkWindow* window, gint x, gint y, gint* rootX, gint* rootY);
+#endif //GTK_CHECK_VERSION(2, 17, 3)
+
#if !GTK_CHECK_VERSION(2, 14, 0)
#define gtk_widget_get_window(widget) (widget)->window
#define gtk_adjustment_get_value(adj) (adj)->value
@@ -67,4 +74,8 @@ void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble
void gtk_adjustment_set_value(GtkAdjustment* adjusment, gdouble value);
#endif // GTK_CHECK_VERSION(2, 14, 0)
+GdkDevice* getDefaultGDKPointerDevice(GdkWindow* window);
+
+G_END_DECLS
+
#endif // GtkVersioning_h
diff --git a/WebCore/platform/gtk/PasteboardHelper.h b/WebCore/platform/gtk/PasteboardHelper.h
index 33be1a8..bb1b580 100644
--- a/WebCore/platform/gtk/PasteboardHelper.h
+++ b/WebCore/platform/gtk/PasteboardHelper.h
@@ -32,13 +32,6 @@
#include "Frame.h"
-typedef struct _GtkClipboard GtkClipboard;
-typedef struct _GtkTargetList GtkTargetList;
-typedef struct _GtkWidget GtkWidget;
-typedef struct _GtkSelectionData GtkSelectionData;
-typedef struct _GdkDragContext GdkDragContext;
-typedef struct _GdkAtom* GdkAtom;
-
namespace WebCore {
class DataObjectGtk;
diff --git a/WebCore/platform/gtk/PopupMenuGtk.h b/WebCore/platform/gtk/PopupMenuGtk.h
index d63e6d9..8848e06 100644
--- a/WebCore/platform/gtk/PopupMenuGtk.h
+++ b/WebCore/platform/gtk/PopupMenuGtk.h
@@ -29,10 +29,6 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
-typedef struct _GtkMenu GtkMenu;
-typedef struct _GtkMenuItem GtkMenuItem;
-typedef struct _GtkWidget GtkWidget;
-
namespace WebCore {
class FrameView;
diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp
index 5019f35..9329179 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.cpp
+++ b/WebCore/platform/gtk/RenderThemeGtk.cpp
@@ -34,8 +34,11 @@
#include "HTMLNames.h"
#include "MediaControlElements.h"
#include "NotImplemented.h"
+#include "PlatformMouseEvent.h"
#include "RenderBox.h"
#include "RenderObject.h"
+#include "Scrollbar.h"
+#include "TimeRanges.h"
#include "UserAgentStyleSheets.h"
#include "gtkdrawing.h"
#include <gdk/gdk.h>
@@ -281,55 +284,24 @@ static void adjustMozillaStyle(const RenderThemeGtk* theme, RenderStyle* style,
style->setPaddingBottom(Length(ypadding + bottom, Fixed));
}
-static void setMozillaState(const RenderTheme* theme, GtkThemeWidgetType type, RenderObject* o, GtkWidgetState* state)
-{
- state->active = theme->isPressed(o);
- state->focused = theme->isFocused(o);
- state->inHover = theme->isHovered(o);
- // FIXME: Disabled does not always give the correct appearance for ReadOnly
- state->disabled = !theme->isEnabled(o) || theme->isReadOnlyControl(o);
- state->isDefault = false;
- state->canDefault = false;
-
-
- // FIXME: The depressed value should probably apply for other theme parts too.
- // It must be used for range thumbs, because otherwise when the thumb is pressed,
- // the rendering is incorrect.
- if (type == MOZ_GTK_SCALE_THUMB_HORIZONTAL || type == MOZ_GTK_SCALE_THUMB_VERTICAL)
- state->depressed = theme->isPressed(o);
- else
- state->depressed = false;
-}
-
-static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetType type, RenderObject* o, const PaintInfo& i, const IntRect& rect)
+bool RenderThemeGtk::paintMozillaGtkWidget(GtkThemeWidgetType type, GraphicsContext* context, const IntRect& rect, GtkWidgetState* widgetState, int flags, GtkTextDirection textDirection)
{
// Painting is disabled so just claim to have succeeded
- if (i.context->paintingDisabled())
+ if (context->paintingDisabled())
return false;
- GtkWidgetState widgetState;
- setMozillaState(theme, type, o, &widgetState);
-
- // We might want to make setting flags the caller's job at some point rather than doing it here.
- int flags = 0;
- if (type == MOZ_GTK_BUTTON)
- flags = GTK_RELIEF_NORMAL;
- else if (type == MOZ_GTK_CHECKBUTTON || type == MOZ_GTK_RADIOBUTTON)
- flags = theme->isChecked(o);
-
- PlatformRefPtr<GdkDrawable> drawable(i.context->gdkDrawable());
+ PlatformRefPtr<GdkDrawable> drawable(context->gdkDrawable());
GdkRectangle paintRect, clipRect;
if (drawable) {
- AffineTransform ctm = i.context->getCTM();
+ AffineTransform ctm = context->getCTM();
IntPoint pos = ctm.mapPoint(rect.location());
paintRect = IntRect(pos.x(), pos.y(), rect.width(), rect.height());
// Intersect the cairo rectangle with the target widget region. This will
// prevent the theme drawing code from drawing into regions that cairo will
// clip anyway.
- cairo_t* cr = i.context->platformContext();
double clipX1, clipX2, clipY1, clipY2;
- cairo_clip_extents(cr, &clipX1, &clipY1, &clipX2, &clipY2);
+ cairo_clip_extents(context->platformContext(), &clipX1, &clipY1, &clipX2, &clipY2);
IntPoint clipPos = ctm.mapPoint(IntPoint(clipX1, clipY1));
clipRect.width = clipX2 - clipX1;
@@ -346,13 +318,13 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp
paintRect = clipRect = IntRect(0, 0, rect.width(), rect.height());
}
- moz_gtk_use_theme_parts(theme->partsForDrawable(drawable.get()));
- bool success = moz_gtk_widget_paint(type, drawable.get(), &paintRect, &clipRect, &widgetState, flags, gtkTextDirection(o->style()->direction())) == MOZ_GTK_SUCCESS;
+ moz_gtk_use_theme_parts(partsForDrawable(drawable.get()));
+ bool success = moz_gtk_widget_paint(type, drawable.get(), &paintRect, &clipRect, widgetState, flags, textDirection) == MOZ_GTK_SUCCESS;
// If the drawing was successful and we rendered onto a pixmap, copy the
// results back to the original GraphicsContext.
- if (success && !i.context->gdkDrawable()) {
- cairo_t* cairoContext = i.context->platformContext();
+ if (success && !context->gdkDrawable()) {
+ cairo_t* cairoContext = context->platformContext();
cairo_save(cairoContext);
gdk_cairo_set_source_pixmap(cairoContext, drawable.get(), rect.x(), rect.y());
cairo_paint(cairoContext);
@@ -362,6 +334,34 @@ static bool paintMozillaGtkWidget(const RenderThemeGtk* theme, GtkThemeWidgetTyp
return !success;
}
+bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags)
+{
+ // Painting is disabled so just claim to have succeeded
+ if (context->paintingDisabled())
+ return false;
+
+ GtkWidgetState widgetState;
+ widgetState.active = isPressed(renderObject);
+ widgetState.focused = isFocused(renderObject);
+ widgetState.inHover = isHovered(renderObject);
+
+ // FIXME: Disabled does not always give the correct appearance for ReadOnly
+ widgetState.disabled = !isEnabled(renderObject) || isReadOnlyControl(renderObject);
+ widgetState.isDefault = false;
+ widgetState.canDefault = false;
+
+ // FIXME: The depressed value should probably apply for other theme parts too.
+ // It must be used for range thumbs, because otherwise when the thumb is pressed,
+ // the rendering is incorrect.
+ if (type == MOZ_GTK_SCALE_THUMB_HORIZONTAL || type == MOZ_GTK_SCALE_THUMB_VERTICAL)
+ widgetState.depressed = isPressed(renderObject);
+ else
+ widgetState.depressed = false;
+
+ GtkTextDirection textDirection = gtkTextDirection(renderObject->style()->direction());
+ return paintMozillaGtkWidget(type, context, rect, &widgetState, flags, textDirection);
+}
+
static void setButtonPadding(RenderStyle* style)
{
// FIXME: This looks incorrect.
@@ -411,7 +411,7 @@ void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const
bool RenderThemeGtk::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- return paintMozillaGtkWidget(this, MOZ_GTK_CHECKBUTTON, o, i, rect);
+ return paintRenderObject(MOZ_GTK_CHECKBUTTON, o, i.context, rect, isChecked(o));
}
void RenderThemeGtk::setRadioSize(RenderStyle* style) const
@@ -421,7 +421,7 @@ void RenderThemeGtk::setRadioSize(RenderStyle* style) const
bool RenderThemeGtk::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- return paintMozillaGtkWidget(this, MOZ_GTK_RADIOBUTTON, o, i, rect);
+ return paintRenderObject(MOZ_GTK_RADIOBUTTON, o, i.context, rect, isChecked(o));
}
void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
@@ -442,7 +442,7 @@ void RenderThemeGtk::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle*
bool RenderThemeGtk::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- return paintMozillaGtkWidget(this, MOZ_GTK_BUTTON, o, i, rect);
+ return paintRenderObject(MOZ_GTK_BUTTON, o, i.context, rect, GTK_RELIEF_NORMAL);
}
void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, WebCore::Element* e) const
@@ -456,7 +456,7 @@ void RenderThemeGtk::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle
bool RenderThemeGtk::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN, o, i, rect);
+ return paintRenderObject(MOZ_GTK_DROPDOWN, o, i.context, rect);
}
void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const
@@ -470,7 +470,7 @@ void RenderThemeGtk::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyl
bool RenderThemeGtk::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect)
{
- return paintMozillaGtkWidget(this, MOZ_GTK_ENTRY, o, i, rect);
+ return paintRenderObject(MOZ_GTK_ENTRY, o, i.context, rect);
}
bool RenderThemeGtk::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r)
@@ -550,7 +550,7 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& inf
if (part == SliderVerticalPart)
gtkPart = MOZ_GTK_SCALE_VERTICAL;
- return paintMozillaGtkWidget(this, gtkPart, object, info, rect);
+ return paintRenderObject(gtkPart, object, info.context, rect);
}
void RenderThemeGtk::adjustSliderTrackStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
@@ -567,7 +567,7 @@ bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& inf
if (part == SliderThumbVerticalPart)
gtkPart = MOZ_GTK_SCALE_THUMB_VERTICAL;
- return paintMozillaGtkWidget(this, gtkPart, object, info, rect);
+ return paintRenderObject(gtkPart, object, info.context, rect);
}
void RenderThemeGtk::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style, Element*) const
@@ -732,6 +732,11 @@ GtkWidget* RenderThemeGtk::gtkTreeView() const
return m_gtkTreeView;
}
+GtkWidget* RenderThemeGtk::gtkScrollbar()
+{
+ return moz_gtk_get_scrollbar_widget();
+}
+
void RenderThemeGtk::platformColorsDidChange()
{
#if ENABLE(VIDEO)
@@ -806,33 +811,48 @@ bool RenderThemeGtk::paintMediaSliderTrack(RenderObject* o, const PaintInfo& pai
return false;
// Draw the buffered ranges. This code is highly inspired from
- // Chrome.
- // FIXME: Draw multiple ranges if there are multiple buffered
- // ranges. The current implementation of the player is always
- // buffering a single range anyway.
- IntRect bufferedRect = r;
- bufferedRect.inflate(-style->borderLeftWidth());
- bufferedRect.setWidth((bufferedRect.width() * mediaElement->percentLoaded()));
-
- // Don't bother drawing an empty area.
- if (bufferedRect.isEmpty())
- return false;
-
- IntPoint sliderTopLeft = bufferedRect.location();
- IntPoint sliderTopRight = sliderTopLeft;
- sliderTopRight.move(0, bufferedRect.height());
-
- RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
- Color startColor = m_panelColor;
- gradient->addColorStop(0.0, startColor);
- gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));
+ // Chrome for the gradient code.
+ float mediaDuration = mediaElement->duration();
+ RefPtr<TimeRanges> timeRanges = mediaElement->buffered();
+ IntRect trackRect = r;
+ int totalWidth = trackRect.width();
+ trackRect.inflate(-style->borderLeftWidth());
context->save();
context->setStrokeStyle(NoStroke);
- context->setFillGradient(gradient);
- context->fillRect(bufferedRect);
- context->restore();
+ for (unsigned index = 0; index < timeRanges->length(); ++index) {
+ ExceptionCode ignoredException;
+ float start = timeRanges->start(index, ignoredException);
+ float end = timeRanges->end(index, ignoredException);
+ int width = ((end - start) * totalWidth) / mediaDuration;
+ IntRect rangeRect;
+ if (!index) {
+ rangeRect = trackRect;
+ rangeRect.setWidth(width);
+ } else {
+ rangeRect.setLocation(IntPoint((start * totalWidth) / mediaDuration, trackRect.y()));
+ rangeRect.setSize(IntSize(width, trackRect.height()));
+ }
+
+ // Don't bother drawing empty range.
+ if (rangeRect.isEmpty())
+ continue;
+
+ IntPoint sliderTopLeft = rangeRect.location();
+ IntPoint sliderTopRight = sliderTopLeft;
+ sliderTopRight.move(0, rangeRect.height());
+
+ RefPtr<Gradient> gradient = Gradient::create(sliderTopLeft, sliderTopRight);
+ Color startColor = m_panelColor;
+ gradient->addColorStop(0.0, startColor);
+ gradient->addColorStop(1.0, Color(startColor.red() / 2, startColor.green() / 2, startColor.blue() / 2, startColor.alpha()));
+
+ context->setFillGradient(gradient);
+ context->fillRect(rangeRect);
+ }
+
+ context->restore();
return false;
}
@@ -873,7 +893,7 @@ bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf
if (!progressBarWidget)
return true;
- if (paintMozillaGtkWidget(this, MOZ_GTK_PROGRESSBAR, renderObject, paintInfo, rect))
+ if (paintRenderObject(MOZ_GTK_PROGRESSBAR, renderObject, paintInfo.context, rect))
return true;
IntRect chunkRect(rect);
@@ -888,7 +908,7 @@ bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInf
else
chunkRect.setX(chunkRect.x() + style->xthickness);
- return paintMozillaGtkWidget(this, MOZ_GTK_PROGRESS_CHUNK, renderObject, paintInfo, chunkRect);
+ return paintRenderObject(MOZ_GTK_PROGRESS_CHUNK, renderObject, paintInfo.context, chunkRect);
}
#endif
diff --git a/WebCore/platform/gtk/RenderThemeGtk.h b/WebCore/platform/gtk/RenderThemeGtk.h
index b9c076d..4e24c97 100644
--- a/WebCore/platform/gtk/RenderThemeGtk.h
+++ b/WebCore/platform/gtk/RenderThemeGtk.h
@@ -29,21 +29,9 @@
#define RenderThemeGtk_h
#include "GRefPtr.h"
+#include "gtkdrawing.h"
#include "RenderTheme.h"
-typedef struct _GtkWidget GtkWidget;
-typedef struct _GtkStyle GtkStyle;
-typedef struct _GtkContainer GtkContainer;
-#ifdef GTK_API_VERSION_2
-typedef struct _GdkRectangle GdkRectangle;
-#else
-typedef struct _cairo_rectangle_int cairo_rectangle_int_t;
-typedef cairo_rectangle_int_t GdkRectangle;
-#endif
-typedef struct _GdkDrawable GdkDrawable;
-typedef struct _GtkBorder GtkBorder;
-typedef struct _GtkThemeParts GtkThemeParts;
-
namespace WebCore {
class RenderThemeGtk : public RenderTheme {
@@ -95,7 +83,9 @@ public:
virtual String extraMediaControlsStyleSheet();
#endif
- GtkThemeParts* partsForDrawable(GdkDrawable*) const;
+ bool paintMozillaGtkWidget(GtkThemeWidgetType, GraphicsContext*, const IntRect&, GtkWidgetState*, int flags, GtkTextDirection = GTK_TEXT_DIR_NONE);
+
+ GtkWidget* gtkScrollbar();
protected:
virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r);
@@ -167,6 +157,9 @@ private:
*/
GtkContainer* gtkContainer() const;
+ bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect& rect, int flags = 0);
+ GtkThemeParts* partsForDrawable(GdkDrawable*) const;
+
mutable GtkWidget* m_gtkWindow;
mutable GtkContainer* m_gtkContainer;
mutable GtkWidget* m_gtkButton;
diff --git a/WebCore/platform/gtk/ScrollbarGtk.h b/WebCore/platform/gtk/ScrollbarGtk.h
index e02bb50..1a078c9 100644
--- a/WebCore/platform/gtk/ScrollbarGtk.h
+++ b/WebCore/platform/gtk/ScrollbarGtk.h
@@ -29,8 +29,6 @@
#include "Scrollbar.h"
#include <wtf/PassRefPtr.h>
-typedef struct _GtkAdjustment GtkAdjustment;
-
namespace WebCore {
class ScrollbarGtk : public Scrollbar {
diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
index fee2c70..b6efe54 100644
--- a/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
+++ b/WebCore/platform/gtk/ScrollbarThemeGtk.cpp
@@ -26,30 +26,339 @@
#include "config.h"
#include "ScrollbarThemeGtk.h"
+#include "PlatformMouseEvent.h"
+#include "RenderThemeGtk.h"
+#include "ScrollView.h"
+#include "Scrollbar.h"
#include "gtkdrawing.h"
#include <gtk/gtk.h>
namespace WebCore {
+static HashSet<Scrollbar*>* gScrollbars;
+static void gtkStyleSetCallback(GtkWidget*, GtkStyle*, ScrollbarThemeGtk*);
+
ScrollbarTheme* ScrollbarTheme::nativeTheme()
{
static ScrollbarThemeGtk theme;
return &theme;
}
+ScrollbarThemeGtk::ScrollbarThemeGtk()
+{
+ updateThemeProperties();
+ g_signal_connect(static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkScrollbar(),
+ "style-set", G_CALLBACK(gtkStyleSetCallback), this);
+}
+
ScrollbarThemeGtk::~ScrollbarThemeGtk()
{
}
-int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize controlSize)
+void ScrollbarThemeGtk::registerScrollbar(Scrollbar* scrollbar)
+{
+ if (!gScrollbars)
+ gScrollbars = new HashSet<Scrollbar*>;
+ gScrollbars->add(scrollbar);
+}
+
+void ScrollbarThemeGtk::unregisterScrollbar(Scrollbar* scrollbar)
+{
+ gScrollbars->remove(scrollbar);
+ if (gScrollbars->isEmpty()) {
+ delete gScrollbars;
+ gScrollbars = 0;
+ }
+}
+
+void ScrollbarThemeGtk::updateThemeProperties()
+{
+ MozGtkScrollbarMetrics metrics;
+ moz_gtk_get_scrollbar_metrics(&metrics);
+
+ m_thumbFatness = metrics.slider_width;
+ m_troughBorderWidth = metrics.trough_border;
+ m_stepperSize = metrics.stepper_size;
+ m_stepperSpacing = metrics.stepper_spacing;
+ m_minThumbLength = metrics.min_slider_size;
+ m_troughUnderSteppers = metrics.trough_under_steppers;
+
+ if (!gScrollbars)
+ return;
+
+ // Update the thickness of every interior frame scrollbar widget. The
+ // platform-independent scrollbar them code isn't yet smart enough to get
+ // this information when it paints.
+ HashSet<Scrollbar*>::iterator end = gScrollbars->end();
+ for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) {
+ Scrollbar* scrollbar = (*it);
+
+ // Top-level scrollbar i.e. scrollbars who have a parent ScrollView
+ // with no parent are native, and thus do not need to be resized.
+ if (!scrollbar->parent() || !scrollbar->parent()->parent())
+ return;
+
+ int thickness = scrollbarThickness(scrollbar->controlSize());
+ if (scrollbar->orientation() == HorizontalScrollbar)
+ scrollbar->setFrameRect(IntRect(0, scrollbar->parent()->height() - thickness, scrollbar->width(), thickness));
+ else
+ scrollbar->setFrameRect(IntRect(scrollbar->parent()->width() - thickness, 0, thickness, scrollbar->height()));
+ }
+}
+
+static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, ScrollbarThemeGtk* scrollbarTheme)
+{
+ scrollbarTheme->updateThemeProperties();
+}
+
+bool ScrollbarThemeGtk::hasThumb(Scrollbar* scrollbar)
+{
+ // This method is just called as a paint-time optimization to see if
+ // painting the thumb can be skipped. We don't have to be exact here.
+ return thumbLength(scrollbar) > 0;
+}
+
+IntRect ScrollbarThemeGtk::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
+{
+ // We do not support multiple steppers per end yet.
+ if (part == BackButtonEndPart)
+ return IntRect();
+
+ IntSize size = buttonSize(scrollbar);
+ return IntRect(scrollbar->x() + m_troughBorderWidth, scrollbar->y() + m_troughBorderWidth, size.width(), size.height());
+}
+
+IntRect ScrollbarThemeGtk::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
+{
+ // We do not support multiple steppers per end yet.
+ if (part == ForwardButtonStartPart)
+ return IntRect();
+
+ IntSize size = buttonSize(scrollbar);
+ int x, y;
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ x = scrollbar->x() + scrollbar->width() - size.width() - m_troughBorderWidth;
+ y = scrollbar->y() + m_troughBorderWidth;
+ } else {
+ x = scrollbar->x() + m_troughBorderWidth;
+ y = scrollbar->y() + scrollbar->height() - size.height() - m_troughBorderWidth;
+ }
+ return IntRect(x, y, size.width(), size.height());
+}
+
+IntRect ScrollbarThemeGtk::trackRect(Scrollbar* scrollbar, bool)
+{
+ // The padding along the thumb movement axis (from outside to in)
+ // is the size of trough border plus the size of the stepper (button)
+ // plus the size of stepper spacing (the space between the stepper and
+ // the place where the thumb stops). There is often no stepper spacing.
+ int movementAxisPadding = m_troughBorderWidth + m_stepperSize + m_stepperSpacing;
+
+ // The fatness of the scrollbar on the non-movement axis.
+ int thickness = scrollbarThickness(scrollbar->controlSize());
+
+ if (scrollbar->orientation() == HorizontalScrollbar) {
+ // Once the scrollbar becomes smaller than the natural size of the
+ // two buttons, the track disappears.
+ if (scrollbar->width() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar->x() + movementAxisPadding, scrollbar->y(), scrollbar->width() - (2 * movementAxisPadding), thickness);
+ }
+
+ if (scrollbar->height() < 2 * thickness)
+ return IntRect();
+ return IntRect(scrollbar->x(), scrollbar->y() + movementAxisPadding, thickness, scrollbar->height() - (2 * movementAxisPadding));
+}
+
+void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
+{
+ GtkWidgetState state;
+ state.focused = FALSE;
+ state.isDefault = FALSE;
+ state.canDefault = FALSE;
+ state.disabled = FALSE;
+ state.active = FALSE;
+ state.inHover = FALSE;
+
+ // Paint the track background. If the trough-under-steppers property is true, this
+ // should be the full size of the scrollbar, but if is false, it should only be the
+ // track rect.
+ IntRect fullScrollbarRect = rect;
+ if (m_troughUnderSteppers)
+ fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
+
+ GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_TRACK_VERTICAL : MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL;
+ static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, fullScrollbarRect, &state, 0);
+}
+
+void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar)
+{
+ GtkWidgetState state;
+ state.focused = FALSE;
+ state.isDefault = FALSE;
+ state.canDefault = FALSE;
+ state.disabled = FALSE;
+ state.active = TRUE;
+ state.inHover = FALSE;
+
+ IntRect fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
+ static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLED_WINDOW, context, fullScrollbarRect, &state, 0);
+}
+
+void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
+{
+ GtkWidgetState state;
+ state.focused = FALSE;
+ state.isDefault = FALSE;
+ state.canDefault = FALSE;
+ state.disabled = FALSE;
+ state.active = scrollbar->pressedPart() == ThumbPart;
+ state.inHover = scrollbar->hoveredPart() == ThumbPart;
+ state.maxpos = scrollbar->maximum();
+ state.curpos = scrollbar->currentPos();
+
+ GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_THUMB_VERTICAL : MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL;
+ static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(type, context, rect, &state, 0);
+}
+
+IntRect ScrollbarThemeGtk::thumbRect(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect)
+{
+ IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrainedTrackRect);
+ int thumbPos = thumbPosition(scrollbar);
+ if (scrollbar->orientation() == HorizontalScrollbar)
+ return IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - m_thumbFatness) / 2, thumbLength(scrollbar), m_thumbFatness);
+
+ // VerticalScrollbar
+ return IntRect(trackRect.x() + (trackRect.width() - m_thumbFatness) / 2, trackRect.y() + thumbPos, m_thumbFatness, thumbLength(scrollbar));
+}
+
+bool ScrollbarThemeGtk::paint(Scrollbar* scrollbar, GraphicsContext* graphicsContext, const IntRect& damageRect)
{
- static int size;
- if (!size) {
- MozGtkScrollbarMetrics metrics;
- moz_gtk_get_scrollbar_metrics(&metrics);
- size = metrics.slider_width;
+ // Create the ScrollbarControlPartMask based on the damageRect
+ ScrollbarControlPartMask scrollMask = NoPart;
+
+ IntRect backButtonStartPaintRect;
+ IntRect backButtonEndPaintRect;
+ IntRect forwardButtonStartPaintRect;
+ IntRect forwardButtonEndPaintRect;
+ if (hasButtons(scrollbar)) {
+ backButtonStartPaintRect = backButtonRect(scrollbar, BackButtonStartPart, true);
+ if (damageRect.intersects(backButtonStartPaintRect))
+ scrollMask |= BackButtonStartPart;
+ backButtonEndPaintRect = backButtonRect(scrollbar, BackButtonEndPart, true);
+ if (damageRect.intersects(backButtonEndPaintRect))
+ scrollMask |= BackButtonEndPart;
+ forwardButtonStartPaintRect = forwardButtonRect(scrollbar, ForwardButtonStartPart, true);
+ if (damageRect.intersects(forwardButtonStartPaintRect))
+ scrollMask |= ForwardButtonStartPart;
+ forwardButtonEndPaintRect = forwardButtonRect(scrollbar, ForwardButtonEndPart, true);
+ if (damageRect.intersects(forwardButtonEndPaintRect))
+ scrollMask |= ForwardButtonEndPart;
+ }
+
+ IntRect trackPaintRect = trackRect(scrollbar, true);
+ if (damageRect.intersects(trackPaintRect))
+ scrollMask |= TrackBGPart;
+
+ if (m_troughUnderSteppers && (scrollMask & BackButtonStartPart
+ || scrollMask & BackButtonEndPart
+ || scrollMask & ForwardButtonStartPart
+ || scrollMask & ForwardButtonEndPart))
+ scrollMask |= TrackBGPart;
+
+ bool thumbPresent = hasThumb(scrollbar);
+ IntRect currentThumbRect;
+ if (thumbPresent) {
+ IntRect track = trackRect(scrollbar, false);
+ currentThumbRect = thumbRect(scrollbar, track);
+ if (damageRect.intersects(currentThumbRect))
+ scrollMask |= ThumbPart;
}
- return size;
+
+ // Paint the scrollbar background (only used by custom CSS scrollbars).
+ paintScrollbarBackground(graphicsContext, scrollbar);
+
+ if (scrollMask & TrackBGPart)
+ paintTrackBackground(graphicsContext, scrollbar, trackPaintRect);
+
+ // Paint the back and forward buttons.
+ if (scrollMask & BackButtonStartPart)
+ paintButton(graphicsContext, scrollbar, backButtonStartPaintRect, BackButtonStartPart);
+ if (scrollMask & BackButtonEndPart)
+ paintButton(graphicsContext, scrollbar, backButtonEndPaintRect, BackButtonEndPart);
+ if (scrollMask & ForwardButtonStartPart)
+ paintButton(graphicsContext, scrollbar, forwardButtonStartPaintRect, ForwardButtonStartPart);
+ if (scrollMask & ForwardButtonEndPart)
+ paintButton(graphicsContext, scrollbar, forwardButtonEndPaintRect, ForwardButtonEndPart);
+
+ // Paint the thumb.
+ if (scrollMask & ThumbPart)
+ paintThumb(graphicsContext, scrollbar, currentThumbRect);
+
+ return true;
+}
+
+void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
+{
+ int flags = 0;
+ if (scrollbar->orientation() == VerticalScrollbar)
+ flags |= MOZ_GTK_STEPPER_VERTICAL;
+
+ if (part == ForwardButtonEndPart) {
+ flags |= MOZ_GTK_STEPPER_DOWN;
+ flags |= MOZ_GTK_STEPPER_BOTTOM;
+ }
+
+ GtkWidgetState state;
+ state.focused = TRUE;
+ state.isDefault = TRUE;
+ state.canDefault = TRUE;
+
+ if ((BackButtonStartPart == part && scrollbar->currentPos())
+ || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum())) {
+ state.disabled = FALSE;
+ state.active = part == scrollbar->pressedPart();
+ state.inHover = part == scrollbar->hoveredPart();
+ } else {
+ state.disabled = TRUE;
+ state.active = FALSE;
+ state.inHover = FALSE;
+ }
+
+ static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->paintMozillaGtkWidget(MOZ_GTK_SCROLLBAR_BUTTON, context, rect, &state, flags);
+}
+
+void ScrollbarThemeGtk::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect)
+{
+ // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the
+ // ScrollView is a FrameView (see FramelessScrollView), so we cannot let
+ // that code run. For FrameView's this is correct since we don't do custom
+ // scrollbar corner rendering, which ScrollbarThemeComposite supports.
+ ScrollbarTheme::paintScrollCorner(view, context, cornerRect);
+}
+
+bool ScrollbarThemeGtk::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& event)
+{
+ return (event.shiftKey() && event.button() == LeftButton) || (event.button() == MiddleButton);
+}
+
+int ScrollbarThemeGtk::scrollbarThickness(ScrollbarControlSize)
+{
+ return m_thumbFatness + (m_troughBorderWidth * 2);
+}
+
+IntSize ScrollbarThemeGtk::buttonSize(Scrollbar* scrollbar)
+{
+ if (scrollbar->orientation() == VerticalScrollbar)
+ return IntSize(m_thumbFatness, m_stepperSize);
+
+ // HorizontalScrollbar
+ return IntSize(m_stepperSize, m_thumbFatness);
+}
+
+int ScrollbarThemeGtk::minimumThumbLength(Scrollbar* scrollbar)
+{
+ return m_minThumbLength;
}
}
diff --git a/WebCore/platform/gtk/ScrollbarThemeGtk.h b/WebCore/platform/gtk/ScrollbarThemeGtk.h
index 618da35..eff2fee 100644
--- a/WebCore/platform/gtk/ScrollbarThemeGtk.h
+++ b/WebCore/platform/gtk/ScrollbarThemeGtk.h
@@ -26,20 +26,48 @@
#ifndef ScrollbarThemeGtk_h
#define ScrollbarThemeGtk_h
-#include "ScrollbarTheme.h"
-
-typedef struct _GtkWidget GtkWidget;
-typedef struct _GtkStyle GtkStyle;
-typedef struct _GtkContainer GtkContainer;
-typedef struct _GtkBorder GtkBorder;
+#include "ScrollbarThemeComposite.h"
namespace WebCore {
-class ScrollbarThemeGtk : public ScrollbarTheme {
+class Scrollbar;
+
+class ScrollbarThemeGtk : public ScrollbarThemeComposite {
public:
+ ScrollbarThemeGtk();
virtual ~ScrollbarThemeGtk();
- virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar);
+ virtual bool hasButtons(Scrollbar*) { return true; }
+ virtual bool hasThumb(Scrollbar*);
+ virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool);
+ virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool);
+ virtual IntRect trackRect(Scrollbar*, bool);
+ IntRect thumbRect(Scrollbar*, const IntRect& unconstrainedTrackRect);
+ bool paint(Scrollbar*, GraphicsContext*, const IntRect& damageRect);
+ void paintScrollbarBackground(GraphicsContext*, Scrollbar*);
+ void paintTrackBackground(GraphicsContext*, Scrollbar*, const IntRect&);
+ void paintThumb(GraphicsContext*, Scrollbar*, const IntRect&);
+ virtual void paintButton(GraphicsContext*, Scrollbar*, const IntRect&, ScrollbarPart);
+ virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect&);
+ virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&);
+ virtual int scrollbarThickness(ScrollbarControlSize);
+ virtual IntSize buttonSize(Scrollbar*);
+ virtual int minimumThumbLength(Scrollbar*);
+
+ // TODO: These are the default GTK+ values. At some point we should pull these from the theme itself.
+ virtual double initialAutoscrollTimerDelay() { return 0.20; }
+ virtual double autoscrollTimerDelay() { return 0.02; }
+ void updateThemeProperties();
+ void registerScrollbar(Scrollbar*);
+ void unregisterScrollbar(Scrollbar*);
+
+protected:
+ int m_thumbFatness;
+ int m_troughBorderWidth;
+ int m_stepperSize;
+ int m_stepperSpacing;
+ int m_minThumbLength;
+ bool m_troughUnderSteppers;
};
}
diff --git a/WebCore/platform/gtk/gtk2drawing.c b/WebCore/platform/gtk/gtk2drawing.c
index 349bde0..b33fb1f 100644
--- a/WebCore/platform/gtk/gtk2drawing.c
+++ b/WebCore/platform/gtk/gtk2drawing.c
@@ -46,10 +46,7 @@
#include <gdk/gdkprivate.h>
#include "gtkdrawing.h"
-
-#include "Assertions.h"
#include "GtkVersioning.h"
-
#include <math.h>
#include <string.h>
diff --git a/WebCore/platform/mac/PopupMenuMac.h b/WebCore/platform/mac/PopupMenuMac.h
index e969fff..8e21913 100644
--- a/WebCore/platform/mac/PopupMenuMac.h
+++ b/WebCore/platform/mac/PopupMenuMac.h
@@ -26,7 +26,11 @@
#include <wtf/RefCounted.h>
#include <wtf/RetainPtr.h>
+#ifdef __OBJC__
+@class NSPopUpButtonCell;
+#else
class NSPopUpButtonCell;
+#endif
namespace WebCore {
diff --git a/WebCore/platform/mac/PurgeableBufferMac.cpp b/WebCore/platform/mac/PurgeableBufferMac.cpp
index ce00494..54de4ed 100644
--- a/WebCore/platform/mac/PurgeableBufferMac.cpp
+++ b/WebCore/platform/mac/PurgeableBufferMac.cpp
@@ -25,7 +25,7 @@
#include "config.h"
-#ifndef BUILDING_ON_TIGER
+#if ENABLE(PURGEABLE_MEMORY)
#include "PurgeableBuffer.h"
diff --git a/WebCore/platform/mac/WebCoreSystemInterface.h b/WebCore/platform/mac/WebCoreSystemInterface.h
index 1f14311..0cc7fd5 100644
--- a/WebCore/platform/mac/WebCoreSystemInterface.h
+++ b/WebCore/platform/mac/WebCoreSystemInterface.h
@@ -121,6 +121,7 @@ extern BOOL (*wkMediaControllerThemeAvailable)(int themeStyle);
extern void (*wkPopupMenu)(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*);
extern unsigned (*wkQTIncludeOnlyModernMediaFileTypes)(void);
extern int (*wkQTMovieDataRate)(QTMovie*);
+extern void (*wkQTMovieDisableComponent)(uint32_t[5]);
extern float (*wkQTMovieMaxTimeLoaded)(QTMovie*);
extern NSString *(*wkQTMovieMaxTimeLoadedChangeNotification)(void);
extern float (*wkQTMovieMaxTimeSeekable)(QTMovie*);
diff --git a/WebCore/platform/mac/WebCoreSystemInterface.mm b/WebCore/platform/mac/WebCoreSystemInterface.mm
index 2a06f15..309a8fb 100644
--- a/WebCore/platform/mac/WebCoreSystemInterface.mm
+++ b/WebCore/platform/mac/WebCoreSystemInterface.mm
@@ -56,6 +56,7 @@ void (*wkGetWheelEventDeltas)(NSEvent*, float* deltaX, float* deltaY, BOOL* cont
void (*wkPopupMenu)(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*);
unsigned (*wkQTIncludeOnlyModernMediaFileTypes)(void);
int (*wkQTMovieDataRate)(QTMovie*);
+void (*wkQTMovieDisableComponent)(uint32_t[5]);
float (*wkQTMovieMaxTimeLoaded)(QTMovie*);
NSString *(*wkQTMovieMaxTimeLoadedChangeNotification)(void);
float (*wkQTMovieMaxTimeSeekable)(QTMovie*);
diff --git a/WebCore/platform/network/BlobRegistryImpl.cpp b/WebCore/platform/network/BlobRegistryImpl.cpp
index ee872e6..c5beb64 100644
--- a/WebCore/platform/network/BlobRegistryImpl.cpp
+++ b/WebCore/platform/network/BlobRegistryImpl.cpp
@@ -30,8 +30,11 @@
#include "config.h"
+#if ENABLE(BLOB)
+
#include "BlobRegistryImpl.h"
+#include "BlobResourceHandle.h"
#include "ResourceError.h"
#include "ResourceHandle.h"
#include "ResourceLoader.h"
@@ -60,22 +63,21 @@ bool BlobRegistryImpl::shouldLoadResource(const ResourceRequest& request) const
return true;
}
-PassRefPtr<ResourceHandle> BlobRegistryImpl::createResourceHandle(const ResourceRequest& request, ResourceHandleClient*)
+PassRefPtr<ResourceHandle> BlobRegistryImpl::createResourceHandle(const ResourceRequest& request, ResourceHandleClient* client)
{
if (!shouldLoadResource(request))
return 0;
- // FIXME: To be implemented.
- return 0;
+ return BlobResourceHandle::create(m_blobs.get(request.url().string()), request, client);
}
-bool BlobRegistryImpl::loadResourceSynchronously(const ResourceRequest& request, ResourceError&, ResourceResponse&, Vector<char>&)
+bool BlobRegistryImpl::loadResourceSynchronously(const ResourceRequest& request, ResourceError& error, ResourceResponse& response, Vector<char>& data)
{
if (!shouldLoadResource(request))
return false;
- // FIXME: To be implemented.
- return false;
+ BlobResourceHandle::loadResourceSynchronously(m_blobs.get(request.url().string()), request, error, response, data);
+ return true;
}
void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobDataItemList& items)
@@ -175,3 +177,5 @@ PassRefPtr<BlobStorageData> BlobRegistryImpl::getBlobDataFromURL(const KURL& url
}
} // namespace WebCore
+
+#endif // ENABLE(BLOB)
diff --git a/WebCore/platform/network/BlobResourceHandle.cpp b/WebCore/platform/network/BlobResourceHandle.cpp
index 63335f6..8767b55 100644
--- a/WebCore/platform/network/BlobResourceHandle.cpp
+++ b/WebCore/platform/network/BlobResourceHandle.cpp
@@ -159,7 +159,8 @@ BlobResourceHandle::BlobResourceHandle(PassRefPtr<BlobStorageData> blobData, con
, m_fileOpened(false)
{
if (m_async) {
- m_asyncStream = adoptRef(client->createAsyncFileStream(this));
+ // We need to take a ref.
+ m_asyncStream = client->createAsyncFileStream(this);
callOnMainThread(delayedStart, this);
} else
m_stream = FileStream::create();
diff --git a/WebCore/platform/network/BlobResourceHandle.h b/WebCore/platform/network/BlobResourceHandle.h
index b2a0854..63e8578 100644
--- a/WebCore/platform/network/BlobResourceHandle.h
+++ b/WebCore/platform/network/BlobResourceHandle.h
@@ -42,11 +42,11 @@
namespace WebCore {
class AsyncFileStream;
-class BlobDataItem;
class BlobStorageData;
class FileStream;
class ResourceHandleClient;
class ResourceRequest;
+struct BlobDataItem;
class BlobResourceHandle : public FileStreamClient, public ResourceHandle {
public:
diff --git a/WebCore/platform/network/FormData.cpp b/WebCore/platform/network/FormData.cpp
index 4f2b365..786f1b6 100644
--- a/WebCore/platform/network/FormData.cpp
+++ b/WebCore/platform/network/FormData.cpp
@@ -22,23 +22,21 @@
#include "FormData.h"
-#include "BlobItem.h"
+#include "BlobData.h"
+#include "BlobURL.h"
#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
+#include "File.h"
#include "FileSystem.h"
#include "FormDataBuilder.h"
+#include "FormDataList.h"
#include "MIMETypeRegistry.h"
#include "Page.h"
#include "TextEncoding.h"
namespace WebCore {
-#if ENABLE(BLOB)
-const long long FormDataElement::toEndOfFile = -1;
-const double FormDataElement::doNotCheckFileChange = 0;
-#endif
-
inline FormData::FormData()
: m_identifier(0)
, m_hasGeneratedFiles(false)
@@ -99,17 +97,17 @@ PassRefPtr<FormData> FormData::create(const Vector<char>& vector)
return result.release();
}
-PassRefPtr<FormData> FormData::create(const BlobItemList& items, const TextEncoding& encoding)
+PassRefPtr<FormData> FormData::create(const FormDataList& list, const TextEncoding& encoding)
{
RefPtr<FormData> result = create();
- result->appendKeyValuePairItems(items, encoding, false, 0);
+ result->appendKeyValuePairItems(list, encoding, false, 0);
return result.release();
}
-PassRefPtr<FormData> FormData::createMultiPart(const BlobItemList& items, const TextEncoding& encoding, Document* document)
+PassRefPtr<FormData> FormData::createMultiPart(const FormDataList& list, const TextEncoding& encoding, Document* document)
{
RefPtr<FormData> result = create();
- result->appendKeyValuePairItems(items, encoding, true, document);
+ result->appendKeyValuePairItems(list, encoding, true, document);
return result.release();
}
@@ -162,44 +160,12 @@ void FormData::appendData(const void* data, size_t size)
void FormData::appendFile(const String& filename, bool shouldGenerateFile)
{
#if ENABLE(BLOB)
- m_elements.append(FormDataElement(filename, 0, FormDataElement::toEndOfFile, FormDataElement::doNotCheckFileChange, shouldGenerateFile));
+ m_elements.append(FormDataElement(filename, 0, BlobDataItem::toEndOfFile, BlobDataItem::doNotCheckFileChange, shouldGenerateFile));
#else
m_elements.append(FormDataElement(filename, shouldGenerateFile));
#endif
}
-void FormData::appendItems(const BlobItemList& items)
-{
- for (BlobItemList::const_iterator iter(items.begin()); iter != items.end(); ++iter)
- appendItem(iter->get(), false);
-}
-
-void FormData::appendItem(const BlobItem* item, bool shouldGenerateFile)
-{
- const DataBlobItem* dataItem = item->toDataBlobItem();
- if (dataItem) {
- appendData(dataItem->data(), static_cast<size_t>(dataItem->size()));
- return;
- }
-
- const FileBlobItem* fileItem = item->toFileBlobItem();
- ASSERT(fileItem);
- if (fileItem->path().isEmpty()) {
- // If the path is empty do not add the item.
- return;
- }
-
-#if ENABLE(BLOB)
- const FileRangeBlobItem* fileRangeItem = item->toFileRangeBlobItem();
- if (fileRangeItem) {
- appendFileRange(fileItem->path(), fileRangeItem->start(), fileRangeItem->size(), fileRangeItem->snapshotModificationTime(), shouldGenerateFile);
- return;
- }
-#endif
-
- appendFile(fileItem->path(), shouldGenerateFile);
-}
-
#if ENABLE(BLOB)
void FormData::appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile)
{
@@ -212,80 +178,82 @@ void FormData::appendBlob(const KURL& blobURL)
}
#endif
-void FormData::appendKeyValuePairItems(const BlobItemList& items, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
+void FormData::appendKeyValuePairItems(const FormDataList& list, const TextEncoding& encoding, bool isMultiPartForm, Document* document)
{
if (isMultiPartForm)
m_boundary = FormDataBuilder::generateUniqueBoundaryString();
Vector<char> encodedData;
+ const Vector<FormDataList::Item>& items = list.items();
size_t formDataListSize = items.size();
ASSERT(!(formDataListSize % 2));
for (size_t i = 0; i < formDataListSize; i += 2) {
- const StringBlobItem* key = items[i]->toStringBlobItem();
- const BlobItem* value = items[i + 1].get();
- ASSERT(key);
+ const FormDataList::Item& key = items[i];
+ const FormDataList::Item& value = items[i + 1];
if (isMultiPartForm) {
Vector<char> header;
- FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key->cstr());
+ FormDataBuilder::beginMultiPartHeader(header, m_boundary.data(), key.data());
bool shouldGenerateFile = false;
- // If the current type is FILE, then we also need to include the filename
- const FileBlobItem* fileItem = value->toFileBlobItem();
- if (fileItem) {
- const String& path = fileItem->path();
-#if ENABLE(DIRECTORY_UPLOAD)
- String fileName = !fileItem->relativePath().isEmpty() ? fileItem->relativePath() : fileItem->name();
+ // If the current type is blob, then we also need to include the filename
+ if (value.blob()) {
+ String name;
+ if (value.blob()->isFile()) {
+ // For file blob, use the filename (or relative path if it is present) as the name.
+ File* file = static_cast<File*>(value.blob());
+#if ENABLE(DIRECTORY_UPLOAD)
+ name = file->webkitRelativePath().isEmpty() ? file->name() : file->webkitRelativePath();
#else
- String fileName = fileItem->name();
-#endif
+ name = file->name();
+#endif
- // Let the application specify a filename if it's going to generate a replacement file for the upload.
- if (!path.isEmpty()) {
+ // Let the application specify a filename if it's going to generate a replacement file for the upload.
if (Page* page = document->page()) {
String generatedFileName;
- shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(path, generatedFileName);
+ shouldGenerateFile = page->chrome()->client()->shouldReplaceWithGeneratedFileForUpload(file->path(), generatedFileName);
if (shouldGenerateFile)
- fileName = generatedFileName;
+ name = generatedFileName;
}
+ } else {
+ // For non-file blob, use the identifier part of the URL as the name.
+ name = "Blob" + BlobURL::getIdentifier(value.blob()->url());
+ name = name.replace("-", ""); // For safety, remove '-' from the filename since some servers may not like it.
}
// We have to include the filename=".." part in the header, even if the filename is empty
- FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, fileName);
+ FormDataBuilder::addFilenameToMultiPartHeader(header, encoding, name);
- // If the item is sliced from a file, do not add the content type.
-#if ENABLE(BLOB)
- if (!fileName.isEmpty() && !value->toFileRangeBlobItem()) {
-#else
- if (!fileName.isEmpty()) {
-#endif
- // FIXME: The MIMETypeRegistry function's name makes it sound like it takes a path,
- // not just a basename. But filename is not the path. But note that it's not safe to
- // just use path instead since in the generated-file case it will not reflect the
- // MIME type of the generated file.
- String mimeType = MIMETypeRegistry::getMIMETypeForPath(fileName);
- if (!mimeType.isEmpty())
- FormDataBuilder::addContentTypeToMultiPartHeader(header, mimeType.latin1());
- }
+ // Add the content type if it is available.
+ if (value.blob()->type().isEmpty())
+ FormDataBuilder::addContentTypeToMultiPartHeader(header, value.blob()->type().latin1());
}
FormDataBuilder::finishMultiPartHeader(header);
// Append body
appendData(header.data(), header.size());
- appendItem(value, shouldGenerateFile);
+ if (value.blob()) {
+ if (value.blob()->isFile()) {
+ // Do not add the file if the path is empty.
+ if (!static_cast<File*>(value.blob())->path().isEmpty())
+ appendFile(static_cast<File*>(value.blob())->path(), shouldGenerateFile);
+ }
+#if ENABLE(BLOB)
+ else
+ appendBlob(value.blob()->url());
+#endif
+ } else
+ appendData(value.data().data(), value.data().length());
appendData("\r\n", 2);
} else {
// Omit the name "isindex" if it's the first form data element.
// FIXME: Why is this a good rule? Is this obsolete now?
- const StringBlobItem* stringValue = value->toStringBlobItem();
- if (!stringValue)
- continue;
- if (encodedData.isEmpty() && key->cstr() == "isindex")
- FormDataBuilder::encodeStringAsFormData(encodedData, stringValue->cstr());
+ if (encodedData.isEmpty() && key.data() == "isindex")
+ FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
else
- FormDataBuilder::addKeyValuePairAsFormData(encodedData, key->cstr(), stringValue->cstr());
+ FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data());
}
}
diff --git a/WebCore/platform/network/FormData.h b/WebCore/platform/network/FormData.h
index d7faa89..22ceb25 100644
--- a/WebCore/platform/network/FormData.h
+++ b/WebCore/platform/network/FormData.h
@@ -28,10 +28,9 @@
namespace WebCore {
-class BlobItem;
class Document;
+class FormDataList;
class TextEncoding;
-typedef Vector<RefPtr<BlobItem> > BlobItemList;
class FormDataElement {
public:
@@ -62,11 +61,6 @@ public:
#endif
String m_generatedFilename;
bool m_shouldGenerateFile;
-
-#if ENABLE(BLOB)
- static const long long toEndOfFile;
- static const double doNotCheckFileChange;
-#endif
};
inline bool operator==(const FormDataElement& a, const FormDataElement& b)
@@ -101,15 +95,14 @@ public:
static PassRefPtr<FormData> create(const void*, size_t);
static PassRefPtr<FormData> create(const CString&);
static PassRefPtr<FormData> create(const Vector<char>&);
- static PassRefPtr<FormData> create(const BlobItemList&, const TextEncoding&);
- static PassRefPtr<FormData> createMultiPart(const BlobItemList&, const TextEncoding&, Document*);
+ static PassRefPtr<FormData> create(const FormDataList&, const TextEncoding&);
+ static PassRefPtr<FormData> createMultiPart(const FormDataList&, const TextEncoding&, Document*);
PassRefPtr<FormData> copy() const;
PassRefPtr<FormData> deepCopy() const;
~FormData();
void appendData(const void* data, size_t);
- void appendItems(const BlobItemList&);
- void appendFile(const String& filename, bool shouldGenerateFile = false);
+ void appendFile(const String& filePath, bool shouldGenerateFile = false);
#if ENABLE(BLOB)
void appendFileRange(const String& filename, long long start, long long length, double expectedModificationTime, bool shouldGenerateFile = false);
void appendBlob(const KURL& blobURL);
@@ -137,8 +130,7 @@ private:
FormData();
FormData(const FormData&);
- void appendItem(const BlobItem*, bool shouldGenerateFile);
- void appendKeyValuePairItems(const BlobItemList&, const TextEncoding&, bool isMultiPartForm, Document*);
+ void appendKeyValuePairItems(const FormDataList&, const TextEncoding&, bool isMultiPartForm, Document*);
Vector<FormDataElement> m_elements;
diff --git a/WebCore/platform/network/mac/FormDataStreamMac.mm b/WebCore/platform/network/mac/FormDataStreamMac.mm
index c7bd2e7..ed98356 100644
--- a/WebCore/platform/network/mac/FormDataStreamMac.mm
+++ b/WebCore/platform/network/mac/FormDataStreamMac.mm
@@ -31,6 +31,7 @@
#import "config.h"
#import "FormDataStreamMac.h"
+#import "BlobRegistryImpl.h"
#import "FileSystem.h"
#import "FormData.h"
#import "ResourceHandle.h"
@@ -141,7 +142,7 @@ static void closeCurrentStream(FormStreamFields *form)
CFRelease(form->currentStream);
form->currentStream = NULL;
#if ENABLE(BLOB)
- form->currentStreamRangeLength = FormDataElement::toEndOfFile;
+ form->currentStreamRangeLength = BlobDataItem::toEndOfFile;
#endif
}
if (form->currentData) {
@@ -169,7 +170,7 @@ static bool advanceCurrentStream(FormStreamFields* form)
} else {
#if ENABLE(BLOB)
// Check if the file has been changed or not if required.
- if (nextInput.m_expectedFileModificationTime != FormDataElement::doNotCheckFileChange) {
+ if (nextInput.m_expectedFileModificationTime != BlobDataItem::doNotCheckFileChange) {
time_t fileModificationTime;
if (!getFileModificationTime(nextInput.m_filename, fileModificationTime) || fileModificationTime != static_cast<time_t>(nextInput.m_expectedFileModificationTime))
return false;
@@ -225,7 +226,7 @@ static void* formCreate(CFReadStreamRef stream, void* context)
FormStreamFields* newInfo = new FormStreamFields;
newInfo->currentStream = NULL;
#if ENABLE(BLOB)
- newInfo->currentStreamRangeLength = FormDataElement::toEndOfFile;
+ newInfo->currentStreamRangeLength = BlobDataItem::toEndOfFile;
#endif
newInfo->currentData = 0;
newInfo->formStream = stream; // Don't retain. That would create a reference cycle.
@@ -273,7 +274,7 @@ static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
while (form->currentStream) {
CFIndex bytesToRead = bufferLength;
#if ENABLE(BLOB)
- if (form->currentStreamRangeLength != FormDataElement::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
+ if (form->currentStreamRangeLength != BlobDataItem::toEndOfFile && form->currentStreamRangeLength < bytesToRead)
bytesToRead = static_cast<CFIndex>(form->currentStreamRangeLength);
#endif
CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bytesToRead);
@@ -286,7 +287,7 @@ static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLen
*atEOF = FALSE;
form->bytesSent += bytesRead;
#if ENABLE(BLOB)
- if (form->currentStreamRangeLength != FormDataElement::toEndOfFile)
+ if (form->currentStreamRangeLength != BlobDataItem::toEndOfFile)
form->currentStreamRangeLength -= bytesRead;
#endif
@@ -394,6 +395,49 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
}
}
+#if ENABLE(BLOB)
+ // Check if there is a blob in the form data.
+ bool hasBlob = false;
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::encodedBlob) {
+ hasBlob = true;
+ break;
+ }
+ }
+
+ // If yes, we have to resolve all the blob references and regenerate the form data with only data and file types.
+ if (hasBlob) {
+ RefPtr<FormData> newFormData = FormData::create();
+ newFormData->setAlwaysStream(formData->alwaysStream());
+ newFormData->setIdentifier(formData->identifier());
+ for (size_t i = 0; i < count; ++i) {
+ const FormDataElement& element = formData->elements()[i];
+ if (element.m_type == FormDataElement::data)
+ newFormData->appendData(element.m_data.data(), element.m_data.size());
+ else if (element.m_type == FormDataElement::encodedFile)
+ newFormData->appendFile(element.m_filename, element.m_shouldGenerateFile);
+ else {
+ ASSERT(element.m_type == FormDataElement::encodedBlob);
+ RefPtr<BlobStorageData> blobData = static_cast<BlobRegistryImpl&>(blobRegistry()).getBlobDataFromURL(KURL(ParsedURLString, element.m_blobURL));
+ if (blobData) {
+ for (size_t j = 0; j < blobData->items().size(); ++j) {
+ const BlobDataItem& blobItem = blobData->items()[j];
+ if (blobItem.type == BlobDataItem::Data) {
+ newFormData->appendData(blobItem.data.data() + static_cast<int>(blobItem.offset), static_cast<int>(blobItem.length));
+ } else {
+ ASSERT(blobItem.type == BlobDataItem::File);
+ newFormData->appendFileRange(blobItem.path, blobItem.offset, blobItem.length, blobItem.expectedModificationTime);
+ }
+ }
+ }
+ }
+ }
+ formData = newFormData;
+ count = formData->elements().size();
+ }
+#endif
+
// Precompute the content length so NSURLConnection doesn't use chunked mode.
long long length = 0;
for (size_t i = 0; i < count; ++i) {
@@ -403,7 +447,7 @@ void setHTTPBody(NSMutableURLRequest *request, PassRefPtr<FormData> formData)
else {
#if ENABLE(BLOB)
// If we're sending the file range, use the existing range length for now. We will detect if the file has been changed right before we read the file and abort the operation if necessary.
- if (element.m_fileLength != FormDataElement::toEndOfFile) {
+ if (element.m_fileLength != BlobDataItem::toEndOfFile) {
length += element.m_fileLength;
continue;
}
diff --git a/WebCore/platform/qt/FileSystemQt.cpp b/WebCore/platform/qt/FileSystemQt.cpp
index 96c2093..b384091 100644
--- a/WebCore/platform/qt/FileSystemQt.cpp
+++ b/WebCore/platform/qt/FileSystemQt.cpp
@@ -128,6 +128,33 @@ CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
return CString();
}
+#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
+PlatformFileHandle openFile(const String& path, FileOpenMode mode)
+{
+ QIODevice::OpenMode platformMode;
+
+ if (mode == OpenForRead)
+ platformMode = QIODevice::ReadOnly;
+ else if (mode == OpenForWrite)
+ platformMode = (QIODevice::WriteOnly | QIODevice::Truncate);
+ else
+ return invalidPlatformFileHandle;
+
+ QFile* file = new QFile(path);
+ if (file->open(platformMode))
+ return file;
+
+ return invalidPlatformFileHandle;
+}
+
+int readFromFile(PlatformFileHandle handle, char* data, int length)
+{
+ if (handle && handle->exists() && handle->isReadable())
+ return handle->read(data, length);
+ return 0;
+}
+#endif
+
void closeFile(PlatformFileHandle& handle)
{
if (handle) {
diff --git a/WebCore/platform/qt/ScrollbarQt.cpp b/WebCore/platform/qt/ScrollbarQt.cpp
index 70aa5db..85dc107 100644
--- a/WebCore/platform/qt/ScrollbarQt.cpp
+++ b/WebCore/platform/qt/ScrollbarQt.cpp
@@ -72,9 +72,7 @@ bool Scrollbar::contextMenu(const PlatformMouseEvent& event)
const QPoint globalPos = QPoint(event.globalX(), event.globalY());
QAction* actionSelected = menu.exec(globalPos);
- if (!actionSelected)
- { /* Do nothing */ }
- else if (actionSelected == actScrollHere) {
+ if (actionSelected == actScrollHere) {
const QPoint pos = convertFromContainingWindow(event.pos());
moveThumb(horizontal ? pos.x() : pos.y());
} else if (actionSelected == actScrollTop)
@@ -82,13 +80,13 @@ bool Scrollbar::contextMenu(const PlatformMouseEvent& event)
else if (actionSelected == actScrollBottom)
setValue(maximum());
else if (actionSelected == actPageUp)
- scroll(horizontal ? ScrollLeft: ScrollUp, ScrollByPage, 1);
+ scroll(horizontal ? ScrollLeft: ScrollUp, ScrollByPage);
else if (actionSelected == actPageDown)
- scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage, 1);
+ scroll(horizontal ? ScrollRight : ScrollDown, ScrollByPage);
else if (actionSelected == actScrollUp)
- scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByLine, 1);
+ scroll(horizontal ? ScrollLeft : ScrollUp, ScrollByLine);
else if (actionSelected == actScrollDown)
- scroll(horizontal ? ScrollRight : ScrollDown, ScrollByLine, 1);
+ scroll(horizontal ? ScrollRight : ScrollDown, ScrollByLine);
#endif // QT_NO_CONTEXTMENU
return true;
}
diff --git a/WebCore/platform/win/PasteboardWin.cpp b/WebCore/platform/win/PasteboardWin.cpp
index 03ecd36..c065f04 100644
--- a/WebCore/platform/win/PasteboardWin.cpp
+++ b/WebCore/platform/win/PasteboardWin.cpp
@@ -230,14 +230,7 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String&)
HGDIOBJ oldSource = SelectObject(sourceDC, coreBitmap);
image->getHBITMAP(coreBitmap);
-#if !defined(NO_ALPHABLEND)
- BLENDFUNCTION bf = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
- AlphaBlend(compatibleDC, 0, 0, image->width(), image->height(),
- sourceDC, 0, 0, image->width(), image->height(), bf);
-#else
- StretchBlt(compatibleDC, 0, 0, image->width(), image->height(),
- sourceDC, 0, 0, image->width(), image->height(), SRCCOPY);
-#endif
+ BitBlt(compatibleDC, 0, 0, image->width(), image->height(), sourceDC, 0, 0, SRCCOPY);
SelectObject(sourceDC, oldSource);
DeleteObject(coreBitmap);
diff --git a/WebCore/platform/win/ScrollbarThemeWin.cpp b/WebCore/platform/win/ScrollbarThemeWin.cpp
index 2ee3512..a8d374a 100644
--- a/WebCore/platform/win/ScrollbarThemeWin.cpp
+++ b/WebCore/platform/win/ScrollbarThemeWin.cpp
@@ -288,7 +288,10 @@ void ScrollbarThemeWin::paintButton(GraphicsContext* context, Scrollbar* scrollb
(scrollbar->hoveredPart() == ForwardButtonEndPart && !start)) {
if (scrollbar->pressedPart() == scrollbar->hoveredPart()) {
xpState += TS_ACTIVE;
- classicState |= DFCS_PUSHED | DFCS_FLAT;
+ classicState |= DFCS_PUSHED;
+#if !OS(WINCE)
+ classicState |= DFCS_FLAT;
+#endif
} else
xpState += TS_HOVER;
} else {
diff --git a/WebCore/platform/win/SoftLinking.h b/WebCore/platform/win/SoftLinking.h
index a82fe35..b67cc81 100644
--- a/WebCore/platform/win/SoftLinking.h
+++ b/WebCore/platform/win/SoftLinking.h
@@ -39,6 +39,12 @@
return library; \
}
+#if OS(WINCE)
+#define SOFT_LINK_GETPROCADDRESS GetProcAddressA
+#else
+#define SOFT_LINK_GETPROCADDRESS GetProcAddress
+#endif
+
#define SOFT_LINK_LIBRARY(lib) SOFT_LINK_LIBRARY_HELPER(lib, L".dll")
#define SOFT_LINK_DEBUG_LIBRARY(lib) SOFT_LINK_LIBRARY_HELPER(lib, L"_debug.dll")
@@ -48,7 +54,7 @@
\
static resultType callingConvention init##functionName parameterDeclarations \
{ \
- softLink##functionName = reinterpret_cast<resultType (callingConvention*) parameterDeclarations>(GetProcAddress(library##Library(), #functionName)); \
+ softLink##functionName = reinterpret_cast<resultType (callingConvention*) parameterDeclarations>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
ASSERT(softLink##functionName); \
return softLink##functionName parameterNames; \
}\
@@ -69,7 +75,7 @@
return ptr; \
initialized = true; \
\
- ptr = reinterpret_cast<functionName##PtrType>(GetProcAddress(library##Library(), #functionName)); \
+ ptr = reinterpret_cast<functionName##PtrType>(SOFT_LINK_GETPROCADDRESS(library##Library(), #functionName)); \
return ptr; \
}\
diff --git a/WebCore/platform/win/SystemInfo.cpp b/WebCore/platform/win/SystemInfo.cpp
index f010769..f2fe62b 100644
--- a/WebCore/platform/win/SystemInfo.cpp
+++ b/WebCore/platform/win/SystemInfo.cpp
@@ -32,6 +32,9 @@ namespace WebCore {
bool isRunningOnVistaOrLater()
{
+#if OS(WINCE)
+ return false;
+#else
static bool isVistaOrLater;
static bool initialized;
@@ -47,6 +50,7 @@ bool isRunningOnVistaOrLater()
isVistaOrLater = vi.dwMajorVersion >= 6;
return isVistaOrLater;
+#endif
}
} // namespace WebCore