summaryrefslogtreecommitdiffstats
path: root/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform')
-rw-r--r--WebCore/platform/FileSystem.h53
-rw-r--r--WebCore/platform/KURLGoogle.cpp2
-rw-r--r--WebCore/platform/SSLKeyGenerator.h9
-rw-r--r--WebCore/platform/ScrollView.cpp29
-rw-r--r--WebCore/platform/ScrollView.h4
-rw-r--r--WebCore/platform/SuddenTermination.h3
-rw-r--r--WebCore/platform/android/ClipboardAndroid.h35
-rw-r--r--WebCore/platform/android/CursorAndroid.cpp7
-rw-r--r--WebCore/platform/android/FileChooserAndroid.cpp8
-rw-r--r--WebCore/platform/android/FileSystemAndroid.cpp10
-rw-r--r--WebCore/platform/android/KeyEventAndroid.cpp288
-rw-r--r--WebCore/platform/android/ScreenAndroid.cpp32
-rw-r--r--WebCore/platform/android/TemporaryLinkStubs.cpp33
-rw-r--r--WebCore/platform/chromium/ChromiumBridge.h8
-rw-r--r--WebCore/platform/chromium/ChromiumDataObject.h31
-rw-r--r--WebCore/platform/chromium/FramelessScrollViewClient.h1
-rw-r--r--WebCore/platform/chromium/KeyCodeConversionGtk.cpp2
-rw-r--r--WebCore/platform/chromium/MIMETypeRegistryChromium.cpp (renamed from WebCore/platform/chromium/MimeTypeRegistryChromium.cpp)2
-rw-r--r--WebCore/platform/chromium/PasteboardChromium.cpp5
-rw-r--r--WebCore/platform/chromium/SSLKeyGeneratorChromium.cpp27
-rw-r--r--WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp14
-rw-r--r--WebCore/platform/chromium/TemporaryLinkStubs.cpp21
-rw-r--r--WebCore/platform/graphics/GraphicsContext.h5
-rw-r--r--WebCore/platform/graphics/GraphicsContext3D.h23
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.cpp16
-rw-r--r--WebCore/platform/graphics/GraphicsLayer.h11
-rw-r--r--WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp5
-rw-r--r--WebCore/platform/graphics/cg/GraphicsContextCG.cpp5
-rw-r--r--WebCore/platform/graphics/chromium/FontLinux.cpp25
-rw-r--r--WebCore/platform/graphics/filters/FEColorMatrix.cpp5
-rw-r--r--WebCore/platform/graphics/filters/FEComponentTransfer.cpp10
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.cpp140
-rw-r--r--WebCore/platform/graphics/filters/FEGaussianBlur.h57
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.cpp7
-rw-r--r--WebCore/platform/graphics/filters/FilterEffect.h18
-rw-r--r--WebCore/platform/graphics/filters/SourceAlpha.cpp2
-rw-r--r--WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp2
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp234
-rw-r--r--WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h19
-rw-r--r--WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp289
-rw-r--r--WebCore/platform/graphics/gtk/VideoSinkGStreamer.h10
-rw-r--r--WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp5
-rw-r--r--WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp16
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.h4
-rw-r--r--WebCore/platform/graphics/mac/Canvas3DLayer.mm63
-rw-r--r--WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp168
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.h2
-rw-r--r--WebCore/platform/graphics/mac/GraphicsLayerCA.mm34
-rw-r--r--WebCore/platform/graphics/mac/WebLayer.mm2
-rw-r--r--WebCore/platform/graphics/qt/GraphicsContextQt.cpp5
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.cpp62
-rw-r--r--WebCore/platform/graphics/qt/ImageDecoderQt.h4
-rw-r--r--WebCore/platform/graphics/skia/GraphicsContextSkia.cpp16
-rw-r--r--WebCore/platform/graphics/skia/PathSkia.cpp21
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.cpp64
-rw-r--r--WebCore/platform/graphics/skia/PlatformContextSkia.h2
-rw-r--r--WebCore/platform/graphics/skia/SkiaUtils.cpp11
-rw-r--r--WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp2
-rw-r--r--WebCore/platform/graphics/wince/GraphicsContextWince.cpp5
-rw-r--r--WebCore/platform/graphics/wx/GraphicsContextWx.cpp5
-rw-r--r--WebCore/platform/gtk/KeyEventGtk.cpp2
-rw-r--r--WebCore/platform/gtk/Language.cpp23
-rw-r--r--WebCore/platform/mac/ClipboardMac.mm21
-rw-r--r--WebCore/platform/network/Credential.cpp3
-rw-r--r--WebCore/platform/network/Credential.h2
-rw-r--r--WebCore/platform/network/CredentialStorage.cpp125
-rw-r--r--WebCore/platform/network/CredentialStorage.h6
-rw-r--r--WebCore/platform/network/FormDataBuilder.cpp38
-rw-r--r--WebCore/platform/network/ResourceRequestBase.cpp24
-rw-r--r--WebCore/platform/network/ResourceRequestBase.h4
-rw-r--r--WebCore/platform/network/cf/ResourceHandleCFNet.cpp22
-rw-r--r--WebCore/platform/network/cf/ResourceRequestCFNet.cpp24
-rw-r--r--WebCore/platform/network/chromium/ResourceRequest.cpp34
-rw-r--r--WebCore/platform/network/curl/ResourceHandleCurl.cpp2
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.cpp32
-rw-r--r--WebCore/platform/network/curl/ResourceHandleManager.h19
-rw-r--r--WebCore/platform/network/mac/AuthenticationMac.mm3
-rw-r--r--WebCore/platform/network/mac/ResourceHandleMac.mm45
-rw-r--r--WebCore/platform/network/mac/ResourceRequestMac.mm7
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.cpp15
-rw-r--r--WebCore/platform/network/qt/QNetworkReplyHandler.h4
-rw-r--r--WebCore/platform/qt/CursorQt.cpp18
-rw-r--r--WebCore/platform/qt/Localizations.cpp4
-rw-r--r--WebCore/platform/qt/PlatformScreenQt.cpp2
-rw-r--r--WebCore/platform/qt/PopupMenuQt.cpp2
-rw-r--r--WebCore/platform/qt/QWebPageClient.h8
-rw-r--r--WebCore/platform/qt/WheelEventQt.cpp4
-rw-r--r--WebCore/platform/sql/SQLiteDatabase.h4
-rw-r--r--WebCore/platform/text/AtomicString.cpp22
-rw-r--r--WebCore/platform/text/AtomicString.h3
-rw-r--r--WebCore/platform/text/String.cpp4
-rw-r--r--WebCore/platform/text/StringImpl.cpp119
-rw-r--r--WebCore/platform/text/StringImpl.h16
-rw-r--r--WebCore/platform/text/TextEncodingRegistry.cpp30
-rw-r--r--WebCore/platform/win/ClipboardWin.cpp28
-rw-r--r--WebCore/platform/win/ScrollbarThemeSafari.cpp2
-rw-r--r--WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp102
97 files changed, 1747 insertions, 1074 deletions
diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h
index 958eb73..9952b39 100644
--- a/WebCore/platform/FileSystem.h
+++ b/WebCore/platform/FileSystem.h
@@ -65,15 +65,23 @@ namespace WebCore {
class CString;
-#if PLATFORM(QT)
-
-typedef QFile* PlatformFileHandle;
-const PlatformFileHandle invalidPlatformFileHandle = 0;
+// PlatformModule
+#if PLATFORM(WIN_OS)
+typedef HMODULE PlatformModule;
+#elif PLATFORM(QT)
#if defined(Q_WS_MAC)
typedef CFBundleRef PlatformModule;
-typedef unsigned PlatformModuleVersion;
-#elif defined(Q_OS_WIN)
-typedef HMODULE PlatformModule;
+#else
+typedef QLibrary* PlatformModule;
+#endif // defined(Q_WS_MAC)
+#elif PLATFORM(GTK)
+typedef GModule* PlatformModule;
+#else
+typedef void* PlatformModule;
+#endif
+
+// PlatformModuleVersion
+#if PLATFORM(WIN_OS)
struct PlatformModuleVersion {
unsigned leastSig;
unsigned mostSig;
@@ -92,44 +100,21 @@ struct PlatformModuleVersion {
};
#else
-typedef QLibrary* PlatformModule;
typedef unsigned PlatformModuleVersion;
#endif
+// PlatformFileHandle
+#if PLATFORM(QT)
+typedef QFile* PlatformFileHandle;
+const PlatformFileHandle invalidPlatformFileHandle = 0;
#elif PLATFORM(WIN_OS)
typedef HANDLE PlatformFileHandle;
-typedef HMODULE PlatformModule;
// FIXME: -1 is INVALID_HANDLE_VALUE, defined in <winbase.h>. Chromium tries to
// avoid using Windows headers in headers. We'd rather move this into the .cpp.
const PlatformFileHandle invalidPlatformFileHandle = reinterpret_cast<HANDLE>(-1);
-
-struct PlatformModuleVersion {
- unsigned leastSig;
- unsigned mostSig;
-
- PlatformModuleVersion(unsigned)
- : leastSig(0)
- , mostSig(0)
- {
- }
-
- PlatformModuleVersion(unsigned lsb, unsigned msb)
- : leastSig(lsb)
- , mostSig(msb)
- {
- }
-
-};
#else
typedef int PlatformFileHandle;
-#if PLATFORM(GTK)
-typedef GModule* PlatformModule;
-#else
-typedef void* PlatformModule;
-#endif
const PlatformFileHandle invalidPlatformFileHandle = -1;
-
-typedef unsigned PlatformModuleVersion;
#endif
bool fileExists(const String&);
diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp
index b323332..d0aae0c 100644
--- a/WebCore/platform/KURLGoogle.cpp
+++ b/WebCore/platform/KURLGoogle.cpp
@@ -106,7 +106,7 @@ static inline bool isUnicodeEncoding(const TextEncoding* encoding)
static bool lowerCaseEqualsASCII(const char* begin, const char* end, const char* str)
{
while (begin != end && *str) {
- ASSERT(isASCIILower(*str));
+ ASSERT(toASCIILower(*str) == *str);
if (toASCIILower(*begin++) != *str++)
return false;
}
diff --git a/WebCore/platform/SSLKeyGenerator.h b/WebCore/platform/SSLKeyGenerator.h
index 398a009..f81f0a5 100644
--- a/WebCore/platform/SSLKeyGenerator.h
+++ b/WebCore/platform/SSLKeyGenerator.h
@@ -33,7 +33,14 @@ namespace WebCore {
class KURL;
- void getSupportedKeySizes(Vector<String>&);
+ // Returns strings representing key sizes that may be used
+ // for the <keygen> tag. The first string is displayed as the default
+ // key size in the <keygen> menu.
+ void getSupportedKeySizes(Vector<String>& sizes);
+
+ // This function handles the <keygen> tag in form elements.
+ // Returns a signed copy of the combined challenge string and public
+ // key (from a newly generated key pair).
String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const KURL&);
} // namespace WebCore
diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp
index d59d10a..1c9b5ce 100644
--- a/WebCore/platform/ScrollView.cpp
+++ b/WebCore/platform/ScrollView.cpp
@@ -762,6 +762,22 @@ void ScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& corn
ScrollbarTheme::nativeTheme()->paintScrollCorner(this, context, cornerRect);
}
+void ScrollView::paintScrollbars(GraphicsContext* context, const IntRect& rect)
+{
+ if (m_horizontalScrollbar)
+ m_horizontalScrollbar->paint(context, rect);
+ if (m_verticalScrollbar)
+ m_verticalScrollbar->paint(context, rect);
+
+ paintScrollCorner(context, scrollCornerRect());
+}
+
+void ScrollView::paintPanScrollIcon(GraphicsContext* context)
+{
+ DEFINE_STATIC_LOCAL(Image*, panScrollIcon, (Image::loadPlatformResource("panIcon").releaseRef()));
+ context->drawImage(panScrollIcon, m_panScrollIconPoint);
+}
+
void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
{
if (platformWidget()) {
@@ -796,20 +812,15 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
scrollViewDirtyRect.intersect(frameRect());
context->translate(x(), y());
scrollViewDirtyRect.move(-x(), -y());
- if (m_horizontalScrollbar)
- m_horizontalScrollbar->paint(context, scrollViewDirtyRect);
- if (m_verticalScrollbar)
- m_verticalScrollbar->paint(context, scrollViewDirtyRect);
- paintScrollCorner(context, scrollCornerRect());
+ paintScrollbars(context, scrollViewDirtyRect);
+
context->restore();
}
// Paint the panScroll Icon
- if (m_drawPanScrollIcon) {
- DEFINE_STATIC_LOCAL(RefPtr<Image>, panScrollIcon, (Image::loadPlatformResource("panIcon")));
- context->drawImage(panScrollIcon.get(), m_panScrollIconPoint);
- }
+ if (m_drawPanScrollIcon)
+ paintPanScrollIcon(context);
}
bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint)
diff --git a/WebCore/platform/ScrollView.h b/WebCore/platform/ScrollView.h
index 2da6829..2844ace 100644
--- a/WebCore/platform/ScrollView.h
+++ b/WebCore/platform/ScrollView.h
@@ -207,6 +207,7 @@ public:
// Widget override. Handles painting of the contents of the view as well as the scrollbars.
virtual void paint(GraphicsContext*, const IntRect&);
+ void paintScrollbars(GraphicsContext*, const IntRect&);
// Widget overrides to ensure that our children's visibility status is kept up to date when we get shown and hidden.
virtual void show();
@@ -217,6 +218,7 @@ public:
static const int noPanScrollRadius = 15;
void addPanScrollIcon(const IntPoint&);
void removePanScrollIcon();
+ void paintPanScrollIcon(GraphicsContext*);
virtual bool isPointInScrollbarCorner(const IntPoint&);
virtual bool scrollbarCornerPresent() const;
@@ -234,7 +236,7 @@ protected:
virtual void contentsResized() = 0;
virtual void visibleContentsResized() = 0;
-
+
// These methods are used to create/destroy scrollbars.
void setHasHorizontalScrollbar(bool);
void setHasVerticalScrollbar(bool);
diff --git a/WebCore/platform/SuddenTermination.h b/WebCore/platform/SuddenTermination.h
index 7171102..3fc5b0f 100644
--- a/WebCore/platform/SuddenTermination.h
+++ b/WebCore/platform/SuddenTermination.h
@@ -30,6 +30,9 @@
namespace WebCore {
+ // Once disabled via one or more more calls to disableSuddenTermination(), fast shutdown
+ // is not valid until enableSuddenTermination() has been called an equal number of times.
+ // On Mac, these are thin wrappers around Mac OS X functions of the same name.
void disableSuddenTermination();
void enableSuddenTermination();
diff --git a/WebCore/platform/android/ClipboardAndroid.h b/WebCore/platform/android/ClipboardAndroid.h
index f11798d..e30ea7d 100644
--- a/WebCore/platform/android/ClipboardAndroid.h
+++ b/WebCore/platform/android/ClipboardAndroid.h
@@ -33,8 +33,9 @@
namespace WebCore {
- class CachedImage;
+class CachedImage;
+<<<<<<< HEAD:WebCore/platform/android/ClipboardAndroid.h
class ClipboardAndroid : public Clipboard, public CachedResourceClient {
public:
ClipboardAndroid(ClipboardAccessPolicy policy, bool isForDragging);
@@ -48,17 +49,31 @@ namespace WebCore {
// extensions beyond IE's API
HashSet<String> types() const;
PassRefPtr<FileList> files() const;
+=======
+class ClipboardAndroid : public Clipboard, public CachedResourceClient {
+public:
+ ClipboardAndroid(ClipboardAccessPolicy policy, bool isForDragging);
+ ~ClipboardAndroid();
+
+ void clearData(const String&);
+ void clearAllData();
+ String getData(const String&, bool& success) const;
+ bool setData(const String&, const String&);
+
+ // extensions beyond IE's API
+ HashSet<String> types() const;
+
+ void setDragImage(CachedImage*, const IntPoint&);
+ void setDragImageElement(Node*, const IntPoint&);
+>>>>>>> webkit.org at r50258.:WebCore/platform/android/ClipboardAndroid.h
- void setDragImage(CachedImage*, const IntPoint&);
- void setDragImageElement(Node*, const IntPoint&);
-
- virtual DragImageRef createDragImage(IntPoint&) const;
- virtual void declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*);
- virtual void writeURL(const KURL&, const String&, Frame*);
- virtual void writeRange(Range*, Frame*);
+ virtual DragImageRef createDragImage(IntPoint&) const;
+ virtual void declareAndWriteDragImage(Element*, const KURL&, const String&, Frame*);
+ virtual void writeURL(const KURL&, const String&, Frame*);
+ virtual void writeRange(Range*, Frame*);
- virtual bool hasData();
- };
+ virtual bool hasData();
+};
} // namespace WebCore
diff --git a/WebCore/platform/android/CursorAndroid.cpp b/WebCore/platform/android/CursorAndroid.cpp
index 5c6e473..beef3b2 100644
--- a/WebCore/platform/android/CursorAndroid.cpp
+++ b/WebCore/platform/android/CursorAndroid.cpp
@@ -23,6 +23,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#define LOG_TAG "WebCore"
#include "config.h"
@@ -282,12 +283,14 @@ const Cursor& westPanningCursor()
return c;
}
-const Cursor& grabCursor() {
+const Cursor& grabCursor()
+{
notImplemented();
return c;
}
-const Cursor& grabbingCursor() {
+const Cursor& grabbingCursor()
+{
notImplemented();
return c;
}
diff --git a/WebCore/platform/android/FileChooserAndroid.cpp b/WebCore/platform/android/FileChooserAndroid.cpp
index c293e66..c8e1999 100644
--- a/WebCore/platform/android/FileChooserAndroid.cpp
+++ b/WebCore/platform/android/FileChooserAndroid.cpp
@@ -36,12 +36,20 @@ String FileChooser::basenameForWidth(const Font& font, int width) const
return String();
// FIXME: This could be a lot faster, but assuming the data will not
// often be much longer than the provided width, this may be fast enough.
+<<<<<<< HEAD:WebCore/platform/android/FileChooserAndroid.cpp
// If this does not need to be threadsafe, we can use crossThreadString().
// See http://trac.webkit.org/changeset/49160.
+=======
+>>>>>>> webkit.org at r50258.:WebCore/platform/android/FileChooserAndroid.cpp
String output = m_filenames[0].threadsafeCopy();
+<<<<<<< HEAD:WebCore/platform/android/FileChooserAndroid.cpp
while (font.width(TextRun(output.impl())) > width && output.length() > 4) {
output = output.replace(0, 4, String("..."));
}
+=======
+ while (font.width(TextRun(output.impl())) > width && output.length() > 4)
+ output = output.replace(output.length() - 4, 4, String("..."));
+>>>>>>> webkit.org at r50258.:WebCore/platform/android/FileChooserAndroid.cpp
return output;
}
diff --git a/WebCore/platform/android/FileSystemAndroid.cpp b/WebCore/platform/android/FileSystemAndroid.cpp
index f2665a2..46c1297 100644
--- a/WebCore/platform/android/FileSystemAndroid.cpp
+++ b/WebCore/platform/android/FileSystemAndroid.cpp
@@ -30,12 +30,12 @@
#include "CString.h"
#include "StringBuilder.h"
-#include <fnmatch.h>
-#include <dlfcn.h>
+#include "cutils/log.h"
#include <dirent.h>
+#include <dlfcn.h>
#include <errno.h>
+#include <fnmatch.h>
#include <sys/stat.h>
-#include "cutils/log.h"
namespace WebCore {
@@ -72,7 +72,7 @@ CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle)
bool unloadModule(PlatformModule module)
{
- return dlclose(module) == 0;
+ return !dlclose(module);
}
void closeFile(PlatformFileHandle& handle)
@@ -90,7 +90,7 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length)
int bytesWritten = write(handle, data, (size_t)(length - totalBytesWritten));
if (bytesWritten < 0 && errno != EINTR)
return -1;
- else if (bytesWritten > 0)
+ if (bytesWritten > 0)
totalBytesWritten += bytesWritten;
}
diff --git a/WebCore/platform/android/KeyEventAndroid.cpp b/WebCore/platform/android/KeyEventAndroid.cpp
index 998c781..af29598 100644
--- a/WebCore/platform/android/KeyEventAndroid.cpp
+++ b/WebCore/platform/android/KeyEventAndroid.cpp
@@ -41,128 +41,128 @@ namespace WebCore {
static int windowsKeyCodeForKeyEvent(unsigned int keyCode)
{
// Does not provide all key codes, and does not handle all keys.
- switch(keyCode) {
- case kKeyCodeDel:
- return VK_BACK;
- case kKeyCodeTab:
- return VK_TAB;
- case kKeyCodeClear:
- return VK_CLEAR;
- case kKeyCodeDpadCenter:
- case kKeyCodeNewline:
- return VK_RETURN;
- case kKeyCodeShiftLeft:
- case kKeyCodeShiftRight:
- return VK_SHIFT;
- // back will serve as escape, although we probably do not have access to it
- case kKeyCodeBack:
- return VK_ESCAPE;
- case kKeyCodeSpace:
- return VK_SPACE;
- case kKeyCodeHome:
- return VK_HOME;
- case kKeyCodeDpadLeft:
- return VK_LEFT;
- case kKeyCodeDpadUp:
- return VK_UP;
- case kKeyCodeDpadRight:
- return VK_RIGHT;
- case kKeyCodeDpadDown:
- return VK_DOWN;
- case kKeyCode0:
- return VK_0;
- case kKeyCode1:
- return VK_1;
- case kKeyCode2:
- return VK_2;
- case kKeyCode3:
- return VK_3;
- case kKeyCode4:
- return VK_4;
- case kKeyCode5:
- return VK_5;
- case kKeyCode6:
- return VK_6;
- case kKeyCode7:
- return VK_7;
- case kKeyCode8:
- return VK_8;
- case kKeyCode9:
- return VK_9;
- case kKeyCodeA:
- return VK_A;
- case kKeyCodeB:
- return VK_B;
- case kKeyCodeC:
- return VK_C;
- case kKeyCodeD:
- return VK_D;
- case kKeyCodeE:
- return VK_E;
- case kKeyCodeF:
- return VK_F;
- case kKeyCodeG:
- return VK_G;
- case kKeyCodeH:
- return VK_H;
- case kKeyCodeI:
- return VK_I;
- case kKeyCodeJ:
- return VK_J;
- case kKeyCodeK:
- return VK_K;
- case kKeyCodeL:
- return VK_L;
- case kKeyCodeM:
- return VK_M;
- case kKeyCodeN:
- return VK_N;
- case kKeyCodeO:
- return VK_O;
- case kKeyCodeP:
- return VK_P;
- case kKeyCodeQ:
- return VK_Q;
- case kKeyCodeR:
- return VK_R;
- case kKeyCodeS:
- return VK_S;
- case kKeyCodeT:
- return VK_T;
- case kKeyCodeU:
- return VK_U;
- case kKeyCodeV:
- return VK_V;
- case kKeyCodeW:
- return VK_W;
- case kKeyCodeX:
- return VK_X;
- case kKeyCodeY:
- return VK_Y;
- case kKeyCodeZ:
- return VK_Z;
- // colon
- case kKeyCodeSemicolon:
- return VK_OEM_1;
- case kKeyCodeComma:
- return VK_OEM_COMMA;
- case kKeyCodeMinus:
- return VK_OEM_MINUS;
- case kKeyCodeEquals:
- return VK_OEM_PLUS;
- case kKeyCodePeriod:
- return VK_OEM_PERIOD;
- case kKeyCodeSlash:
- return VK_OEM_2;
- // maybe not the right choice
- case kKeyCodeLeftBracket:
- return VK_OEM_4;
- case kKeyCodeBackslash:
- return VK_OEM_5;
- case kKeyCodeRightBracket:
- return VK_OEM_6;
- default:
- return 0;
+ switch (keyCode) {
+ case kKeyCodeDel:
+ return VK_BACK;
+ case kKeyCodeTab:
+ return VK_TAB;
+ case kKeyCodeClear:
+ return VK_CLEAR;
+ case kKeyCodeDpadCenter:
+ case kKeyCodeNewline:
+ return VK_RETURN;
+ case kKeyCodeShiftLeft:
+ case kKeyCodeShiftRight:
+ return VK_SHIFT;
+ // back will serve as escape, although we probably do not have access to it
+ case kKeyCodeBack:
+ return VK_ESCAPE;
+ case kKeyCodeSpace:
+ return VK_SPACE;
+ case kKeyCodeHome:
+ return VK_HOME;
+ case kKeyCodeDpadLeft:
+ return VK_LEFT;
+ case kKeyCodeDpadUp:
+ return VK_UP;
+ case kKeyCodeDpadRight:
+ return VK_RIGHT;
+ case kKeyCodeDpadDown:
+ return VK_DOWN;
+ case kKeyCode0:
+ return VK_0;
+ case kKeyCode1:
+ return VK_1;
+ case kKeyCode2:
+ return VK_2;
+ case kKeyCode3:
+ return VK_3;
+ case kKeyCode4:
+ return VK_4;
+ case kKeyCode5:
+ return VK_5;
+ case kKeyCode6:
+ return VK_6;
+ case kKeyCode7:
+ return VK_7;
+ case kKeyCode8:
+ return VK_8;
+ case kKeyCode9:
+ return VK_9;
+ case kKeyCodeA:
+ return VK_A;
+ case kKeyCodeB:
+ return VK_B;
+ case kKeyCodeC:
+ return VK_C;
+ case kKeyCodeD:
+ return VK_D;
+ case kKeyCodeE:
+ return VK_E;
+ case kKeyCodeF:
+ return VK_F;
+ case kKeyCodeG:
+ return VK_G;
+ case kKeyCodeH:
+ return VK_H;
+ case kKeyCodeI:
+ return VK_I;
+ case kKeyCodeJ:
+ return VK_J;
+ case kKeyCodeK:
+ return VK_K;
+ case kKeyCodeL:
+ return VK_L;
+ case kKeyCodeM:
+ return VK_M;
+ case kKeyCodeN:
+ return VK_N;
+ case kKeyCodeO:
+ return VK_O;
+ case kKeyCodeP:
+ return VK_P;
+ case kKeyCodeQ:
+ return VK_Q;
+ case kKeyCodeR:
+ return VK_R;
+ case kKeyCodeS:
+ return VK_S;
+ case kKeyCodeT:
+ return VK_T;
+ case kKeyCodeU:
+ return VK_U;
+ case kKeyCodeV:
+ return VK_V;
+ case kKeyCodeW:
+ return VK_W;
+ case kKeyCodeX:
+ return VK_X;
+ case kKeyCodeY:
+ return VK_Y;
+ case kKeyCodeZ:
+ return VK_Z;
+ // colon
+ case kKeyCodeSemicolon:
+ return VK_OEM_1;
+ case kKeyCodeComma:
+ return VK_OEM_COMMA;
+ case kKeyCodeMinus:
+ return VK_OEM_MINUS;
+ case kKeyCodeEquals:
+ return VK_OEM_PLUS;
+ case kKeyCodePeriod:
+ return VK_OEM_PERIOD;
+ case kKeyCodeSlash:
+ return VK_OEM_2;
+ // maybe not the right choice
+ case kKeyCodeLeftBracket:
+ return VK_OEM_4;
+ case kKeyCodeBackslash:
+ return VK_OEM_5;
+ case kKeyCodeRightBracket:
+ return VK_OEM_6;
+ default:
+ return 0;
}
}
@@ -171,28 +171,28 @@ static String keyIdentifierForAndroidKeyCode(int keyCode)
// Does not return all of the same key identifiers, and
// does not handle all the keys.
switch (keyCode) {
- case kKeyCodeClear:
- return "Clear";
- case kKeyCodeNewline:
- case kKeyCodeDpadCenter:
- return "Enter";
- case kKeyCodeHome:
- return "Home";
- case kKeyCodeDpadDown:
- return "Down";
- case kKeyCodeDpadLeft:
- return "Left";
- case kKeyCodeDpadRight:
- return "Right";
- case kKeyCodeDpadUp:
- return "Up";
- // Standard says that DEL becomes U+00007F.
- case kKeyCodeDel:
- return "U+00007F";
- default:
- char upper[16];
- sprintf(upper, "U+%06X", windowsKeyCodeForKeyEvent(keyCode));
- return String(upper);
+ case kKeyCodeClear:
+ return "Clear";
+ case kKeyCodeNewline:
+ case kKeyCodeDpadCenter:
+ return "Enter";
+ case kKeyCodeHome:
+ return "Home";
+ case kKeyCodeDpadDown:
+ return "Down";
+ case kKeyCodeDpadLeft:
+ return "Left";
+ case kKeyCodeDpadRight:
+ return "Right";
+ case kKeyCodeDpadUp:
+ return "Up";
+ // Standard says that DEL becomes U+00007F.
+ case kKeyCodeDel:
+ return "U+00007F";
+ default:
+ char upper[16];
+ sprintf(upper, "U+%06X", windowsKeyCodeForKeyEvent(keyCode));
+ return String(upper);
}
}
diff --git a/WebCore/platform/android/ScreenAndroid.cpp b/WebCore/platform/android/ScreenAndroid.cpp
index 2439c1f..dcd2d10 100644
--- a/WebCore/platform/android/ScreenAndroid.cpp
+++ b/WebCore/platform/android/ScreenAndroid.cpp
@@ -31,14 +31,12 @@
#include "FloatRect.h"
#include "Widget.h"
-
+#include "ui/DisplayInfo.h"
+#include "ui/PixelFormat.h"
+#include "ui/SurfaceComposerClient.h"
#undef LOG // FIXME: Still have to do this to get the log to show up
#include "utils/Log.h"
-#include "ui/SurfaceComposerClient.h"
-#include "ui/PixelFormat.h"
-#include "ui/DisplayInfo.h"
-
namespace WebCore {
int screenDepth(Widget* page)
@@ -70,18 +68,18 @@ int Screen::orientation() const
// to the values described here
// (http://developer.apple.com/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/chapter_8_section_6.html)
switch (info.orientation) {
- case android::ISurfaceComposer::eOrientationDefault:
- return 0;
- case android::ISurfaceComposer::eOrientation90:
- return 90;
- case android::ISurfaceComposer::eOrientation180:
- return 180;
- case android::ISurfaceComposer::eOrientation270:
- return -90;
- default:
- LOGE("Bad orientation returned from getDisplayIndo %d",
- info.orientation);
- return 0;
+ case android::ISurfaceComposer::eOrientationDefault:
+ return 0;
+ case android::ISurfaceComposer::eOrientation90:
+ return 90;
+ case android::ISurfaceComposer::eOrientation180:
+ return 180;
+ case android::ISurfaceComposer::eOrientation270:
+ return -90;
+ default:
+ LOGE("Bad orientation returned from getDisplayIndo %d",
+ info.orientation);
+ return 0;
}
}
#endif
diff --git a/WebCore/platform/android/TemporaryLinkStubs.cpp b/WebCore/platform/android/TemporaryLinkStubs.cpp
index 215c7f5..e1889f0 100644
--- a/WebCore/platform/android/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/android/TemporaryLinkStubs.cpp
@@ -28,17 +28,15 @@
#define ANDROID_COMPILE_HACK
-#include <stdio.h>
-#include <stdlib.h>
#include "AXObjectCache.h"
+#include "CString.h"
#include "CachedPage.h"
#include "CachedResource.h"
-#include "CookieJar.h"
+#include "Clipboard.h"
#include "Console.h"
#include "ContextMenu.h"
#include "ContextMenuItem.h"
-#include "Clipboard.h"
-#include "CString.h"
+#include "CookieJar.h"
#include "Cursor.h"
#include "Database.h"
#include "DocumentFragment.h"
@@ -48,8 +46,8 @@
#include "File.h"
#include "Font.h"
#include "Frame.h"
-#include "FrameLoader.h"
#include "FrameLoadRequest.h"
+#include "FrameLoader.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HTMLFrameOwnerElement.h"
@@ -59,21 +57,11 @@
#include "IconDatabase.h"
#include "IconLoader.h"
#include "IntPoint.h"
-
-#if USE(JSC)
-#include "JavaScriptCallFrame.h"
-#include "JavaScriptDebugServer.h"
-#include "API/JSClassRef.h"
-#include "JavaScriptProfile.h"
-#include "jni_utility.h"
-#endif
-
#include "KURL.h"
#include "Language.h"
-#include "loader.h"
#include "LocalizedStrings.h"
-#include "MainResourceLoader.h"
#include "MIMETypeRegistry.h"
+#include "MainResourceLoader.h"
#include "Node.h"
#include "NotImplemented.h"
#include "PageCache.h"
@@ -88,6 +76,17 @@
#include "ScrollbarTheme.h"
#include "SmartReplace.h"
#include "Widget.h"
+#include "loader.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#if USE(JSC)
+#include "API/JSClassRef.h"
+#include "JavaScriptCallFrame.h"
+#include "JavaScriptDebugServer.h"
+#include "JavaScriptProfile.h"
+#include "jni_utility.h"
+#endif
using namespace WebCore;
diff --git a/WebCore/platform/chromium/ChromiumBridge.h b/WebCore/platform/chromium/ChromiumBridge.h
index 1afcc23..0c80636 100644
--- a/WebCore/platform/chromium/ChromiumBridge.h
+++ b/WebCore/platform/chromium/ChromiumBridge.h
@@ -32,12 +32,11 @@
#define ChromiumBridge_h
#include "FileSystem.h"
+#include "ImageSource.h"
#include "LinkHash.h"
#include "PassRefPtr.h"
#include "PasteboardPrivate.h"
-class NativeImageSkia;
-
typedef struct NPObject NPObject;
typedef struct _NPP NPP_t;
typedef NPP_t* NPP;
@@ -78,7 +77,7 @@ namespace WebCore {
static void clipboardWriteSelection(const String&, const KURL&, const String&, bool);
static void clipboardWritePlainText(const String&);
static void clipboardWriteURL(const KURL&, const String&);
- static void clipboardWriteImage(const NativeImageSkia*, const KURL&, const String&);
+ static void clipboardWriteImage(NativeImagePtr, const KURL&, const String&);
// Cookies ------------------------------------------------------------
static void setCookies(const KURL& url, const KURL& firstPartyForCookies, const String& value);
@@ -127,6 +126,9 @@ namespace WebCore {
static void notifyJSOutOfMemory(Frame*);
static bool allowScriptDespiteSettings(const KURL& documentURL);
+ // Keygen -------------------------------------------------------------
+ static String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challenge, const KURL& url);
+
// Language -----------------------------------------------------------
static String computedDefaultLanguage();
diff --git a/WebCore/platform/chromium/ChromiumDataObject.h b/WebCore/platform/chromium/ChromiumDataObject.h
index a227001..3e8675e 100644
--- a/WebCore/platform/chromium/ChromiumDataObject.h
+++ b/WebCore/platform/chromium/ChromiumDataObject.h
@@ -55,38 +55,7 @@ namespace WebCore {
void clear();
bool hasData() const;
-
- KURL mainURL() const { return url; }
- void setMainURL(const KURL& newURL) { url = newURL; }
- String mainURLTitle() const { return urlTitle; }
- void setMainURLTitle(const String& newURLTitle) { urlTitle = newURLTitle; }
-
- String textPlain() const { return plainText; }
- void setTextPlain(const String& newText) { plainText = newText; }
-
- String textHTML() const { return textHtml; }
- void setTextHTML(const String& newText) { textHtml = newText; }
-
- KURL htmlBaseURL() const { return htmlBaseUrl; }
- void setHTMLBaseURL(const KURL& newURL) { htmlBaseUrl = newURL; }
-
- SharedBuffer* content() const { return fileContent.get(); }
- PassRefPtr<SharedBuffer> releaseContent() { return fileContent.release(); }
- void setContent(PassRefPtr<SharedBuffer> newContent) { fileContent = newContent; }
-
- String contentFileExtension() const { return fileExtension; }
- void setContentFileExtension(const String& newFileExtension) { fileExtension = newFileExtension; }
-
- String contentFileName() const { return fileContentFilename; }
- void setContentFileName(const String& newFilename) { fileContentFilename = newFilename; }
-
- const Vector<String>& fileNames() const { return filenames; }
- void setFileNames(const Vector<String>& newFilenames) { filenames = newFilenames; }
- void takeFileNames(Vector<String>& newFilenames) { filenames.swap(newFilenames); }
-
- // Interim state: All members will become private, do NOT access them directly!
- // Rather use the above accessor methods (or devise new ones if necessary).
KURL url;
String urlTitle;
diff --git a/WebCore/platform/chromium/FramelessScrollViewClient.h b/WebCore/platform/chromium/FramelessScrollViewClient.h
index 4b32a43..35bae10 100644
--- a/WebCore/platform/chromium/FramelessScrollViewClient.h
+++ b/WebCore/platform/chromium/FramelessScrollViewClient.h
@@ -34,6 +34,7 @@
#include "HostWindow.h"
namespace WebCore {
+ class FramelessScrollView;
class FramelessScrollViewClient : public HostWindow {
public:
diff --git a/WebCore/platform/chromium/KeyCodeConversionGtk.cpp b/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
index 5950de1..e3d5f61 100644
--- a/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
+++ b/WebCore/platform/chromium/KeyCodeConversionGtk.cpp
@@ -91,6 +91,7 @@ int windowsKeyCodeForKeyEvent(unsigned keycode)
case GDK_Control_R:
return VKEY_CONTROL; // (11) CTRL key
case GDK_Menu:
+ return VKEY_APPS; // (5D) Applications key (Natural keyboard)
case GDK_Alt_L:
case GDK_Alt_R:
return VKEY_MENU; // (12) ALT key
@@ -261,7 +262,6 @@ int windowsKeyCodeForKeyEvent(unsigned keycode)
return VKEY_LWIN; // (5B) Left Windows key (Microsoft Natural keyboard)
case GDK_Meta_R:
return VKEY_RWIN; // (5C) Right Windows key (Natural keyboard)
- // VKEY_APPS (5D) Applications key (Natural keyboard)
// VKEY_SLEEP (5F) Computer Sleep key
// VKEY_SEPARATOR (6C) Separator key
// VKEY_SUBTRACT (6D) Subtract key
diff --git a/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp b/WebCore/platform/chromium/MIMETypeRegistryChromium.cpp
index 0f371b1..51bff80 100644
--- a/WebCore/platform/chromium/MimeTypeRegistryChromium.cpp
+++ b/WebCore/platform/chromium/MIMETypeRegistryChromium.cpp
@@ -78,6 +78,8 @@ String MIMETypeRegistry::getMIMETypeForPath(const String& path)
// if a plugin can handle the extension.
mimeType = getPluginMimeTypeFromExtension(extension);
}
+ if (mimeType.isEmpty())
+ return "application/octet-stream";
return mimeType;
}
diff --git a/WebCore/platform/chromium/PasteboardChromium.cpp b/WebCore/platform/chromium/PasteboardChromium.cpp
index 7702730..4929eb8 100644
--- a/WebCore/platform/chromium/PasteboardChromium.cpp
+++ b/WebCore/platform/chromium/PasteboardChromium.cpp
@@ -147,10 +147,7 @@ void Pasteboard::writeImage(Node* node, const KURL&, const String& title)
}
KURL url = urlString.isEmpty() ? KURL() : node->document()->completeURL(deprecatedParseURL(urlString));
- NativeImageSkia* bitmap = 0;
-#if !PLATFORM(CG)
- bitmap = image->nativeImageForCurrentFrame();
-#endif
+ NativeImagePtr bitmap = image->nativeImageForCurrentFrame();
ChromiumBridge::clipboardWriteImage(bitmap, url, title);
}
diff --git a/WebCore/platform/chromium/SSLKeyGeneratorChromium.cpp b/WebCore/platform/chromium/SSLKeyGeneratorChromium.cpp
index fdedf2b..49d9517 100644
--- a/WebCore/platform/chromium/SSLKeyGeneratorChromium.cpp
+++ b/WebCore/platform/chromium/SSLKeyGeneratorChromium.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, 2009, 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
@@ -14,7 +14,7 @@
* * 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
@@ -31,22 +31,29 @@
#include "config.h"
#include "SSLKeyGenerator.h"
+#include "ChromiumBridge.h"
+#include "PlatformString.h"
+
namespace WebCore {
-// These are defined in webkit/glue/localized_strings.cpp.
+// These are defined in webkit/api/src/LocalizedStrings.cpp.
String keygenMenuHighGradeKeySize();
String keygenMenuMediumGradeKeySize();
-// Returns the key sizes supported by the HTML keygen tag. The first string
-// is displayed as the default key size in the keygen menu.
-Vector<String> supportedKeySizes()
+void getSupportedKeySizes(Vector<String>& sizes)
{
- Vector<String> sizes(2);
+ sizes.resize(2);
sizes[0] = keygenMenuHighGradeKeySize();
sizes[1] = keygenMenuMediumGradeKeySize();
- return sizes;
}
-// FIXME: implement signedPublicKeyAndChallengeString here.
+String signedPublicKeyAndChallengeString(unsigned keySizeIndex,
+ const String& challengeString,
+ const KURL& url)
+{
+ return ChromiumBridge::signedPublicKeyAndChallengeString(keySizeIndex,
+ challengeString,
+ url);
+}
} // namespace WebCore
diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
index ed8bf36..64f58c4 100644
--- a/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
+++ b/WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
@@ -140,9 +140,17 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
if (rect.height() > 10 && rect.width() > 10) {
paint.setARGB(0xff, 0x9d, 0x96, 0x8e);
- drawHorizLine(canvas, midx - 1, midx + 3, midy, paint);
- drawHorizLine(canvas, midx - 1, midx + 3, midy - 3, paint);
- drawHorizLine(canvas, midx - 1, midx + 3, midy + 3, paint);
+ const int grippyHalfWidth = 2;
+ const int interGrippyOffset = 3;
+ if (vertical) {
+ drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth, midy - interGrippyOffset, paint);
+ drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth, midy, paint);
+ drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth, midy + interGrippyOffset, paint);
+ } else {
+ drawVertLine(canvas, midx - interGrippyOffset, midy - grippyHalfWidth, midy + grippyHalfWidth, paint);
+ drawVertLine(canvas, midx, midy - grippyHalfWidth, midy + grippyHalfWidth, paint);
+ drawVertLine(canvas, midx + interGrippyOffset, midy - grippyHalfWidth, midy + grippyHalfWidth, paint);
+ }
}
}
diff --git a/WebCore/platform/chromium/TemporaryLinkStubs.cpp b/WebCore/platform/chromium/TemporaryLinkStubs.cpp
index f6e77d4..1f60d95 100644
--- a/WebCore/platform/chromium/TemporaryLinkStubs.cpp
+++ b/WebCore/platform/chromium/TemporaryLinkStubs.cpp
@@ -1,10 +1,10 @@
/*
* Copyright (c) 2008, 2009, 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
@@ -14,7 +14,7 @@
* * 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
@@ -36,11 +36,16 @@
namespace WebCore {
-String signedPublicKeyAndChallengeString(unsigned, const String&, const KURL&) { notImplemented(); return String(); }
-void getSupportedKeySizes(Vector<String>&) { notImplemented(); }
+String KURL::fileSystemPath() const
+{
+ notImplemented();
+ return String();
+}
-String KURL::fileSystemPath() const { notImplemented(); return String(); }
-
-PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&) { notImplemented(); return 0; }
+PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String&)
+{
+ notImplemented();
+ return 0;
+}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index b1d1ef9..5b62b2c 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -334,6 +334,11 @@ namespace WebCore {
void addPath(const Path&);
void clip(const Path&);
+
+ // This clip function is used only by <canvas> code. It allows
+ // implementations to handle clipping on the canvas differently since
+ // the disipline is different.
+ void canvasClip(const Path&);
void clipOut(const Path&);
void scale(const FloatSize&);
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index 5223e05..07ec04d 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -29,6 +29,7 @@
#include "PlatformString.h"
#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
#if PLATFORM(MAC)
#include <OpenGL/OpenGL.h>
@@ -45,6 +46,7 @@ const Platform3DObject NullPlatform3DObject = 0;
#endif
namespace WebCore {
+ class CanvasActiveInfo;
class CanvasArray;
class CanvasBuffer;
class CanvasUnsignedByteArray;
@@ -61,17 +63,23 @@ namespace WebCore {
class HTMLVideoElement;
class ImageData;
class WebKitCSSMatrix;
-
+
+ struct ActiveInfo {
+ String name;
+ unsigned type;
+ int size;
+ };
+
// FIXME: ideally this would be used on all platforms.
#if PLATFORM(CHROMIUM)
class GraphicsContext3DInternal;
#endif
- class GraphicsContext3D : Noncopyable {
+ class GraphicsContext3D : public Noncopyable {
public:
enum ShaderType { FRAGMENT_SHADER, VERTEX_SHADER };
- GraphicsContext3D();
+ static PassOwnPtr<GraphicsContext3D> create();
virtual ~GraphicsContext3D();
#if PLATFORM(MAC)
@@ -85,7 +93,6 @@ namespace WebCore {
Platform3DObject platformTexture() const { return NullPlatform3DObject; }
#endif
void checkError() const;
-
void makeContextCurrent();
// Helper to return the size in bytes of OpenGL data types
@@ -141,6 +148,9 @@ namespace WebCore {
void frontFace(unsigned long mode);
void generateMipmap(unsigned long target);
+ bool getActiveAttrib(CanvasProgram* program, unsigned long index, ActiveInfo&);
+ bool getActiveUniform(CanvasProgram* program, unsigned long index, ActiveInfo&);
+
int getAttribLocation(CanvasProgram*, const String& name);
bool getBoolean(unsigned long pname);
@@ -204,8 +214,7 @@ namespace WebCore {
void pixelStorei(unsigned long pname, long param);
void polygonOffset(double factor, double units);
- // TBD
- //void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels);
+ PassRefPtr<CanvasArray> readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type);
void releaseShaderCompiler();
void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height);
@@ -311,6 +320,8 @@ namespace WebCore {
void deleteTexture(unsigned);
private:
+ GraphicsContext3D();
+
int m_currentWidth, m_currentHeight;
#if PLATFORM(MAC)
diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp
index b375bd3..c8582bb 100644
--- a/WebCore/platform/graphics/GraphicsLayer.cpp
+++ b/WebCore/platform/graphics/GraphicsLayer.cpp
@@ -59,9 +59,7 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
: m_client(client)
, m_anchorPoint(0.5f, 0.5f, 0)
, m_opacity(1)
-#ifndef NDEBUG
, m_zPosition(0)
-#endif
, m_backgroundColorSet(false)
, m_contentsOpaque(false)
, m_preserves3D(false)
@@ -74,9 +72,7 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client)
, m_contentsOrientation(CompositingCoordinatesTopDown)
, m_parent(0)
, m_maskLayer(0)
-#ifndef NDEBUG
, m_repaintCount(0)
-#endif
{
}
@@ -86,6 +82,16 @@ GraphicsLayer::~GraphicsLayer()
removeFromParent();
}
+bool GraphicsLayer::hasAncestor(GraphicsLayer* ancestor) const
+{
+ for (GraphicsLayer* curr = parent(); curr; curr = curr->parent()) {
+ if (curr == ancestor)
+ return true;
+ }
+
+ return false;
+}
+
void GraphicsLayer::addChild(GraphicsLayer* childLayer)
{
ASSERT(childLayer != this);
@@ -219,7 +225,6 @@ void GraphicsLayer::resumeAnimations()
{
}
-#ifndef NDEBUG
void GraphicsLayer::updateDebugIndicators()
{
if (GraphicsLayer::showDebugBorders()) {
@@ -241,7 +246,6 @@ void GraphicsLayer::setZPosition(float position)
{
m_zPosition = position;
}
-#endif
float GraphicsLayer::accumulatedOpacity() const
{
diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h
index 2924073..85eace0 100644
--- a/WebCore/platform/graphics/GraphicsLayer.h
+++ b/WebCore/platform/graphics/GraphicsLayer.h
@@ -172,6 +172,9 @@ public:
GraphicsLayer* parent() const { return m_parent; };
void setParent(GraphicsLayer* layer) { m_parent = layer; } // Internal use only.
+ // Returns true if the layer has the given layer as an ancestor (excluding self).
+ bool hasAncestor(GraphicsLayer*) const;
+
const Vector<GraphicsLayer*>& children() const { return m_children; }
// Add child layers. If the child is already parented, it will be removed from its old parent.
@@ -273,10 +276,8 @@ public:
void dumpLayer(TextStream&, int indent = 0) const;
-#ifndef NDEBUG
int repaintCount() const { return m_repaintCount; }
int incrementRepaintCount() { return ++m_repaintCount; }
-#endif
// Report whether the underlying compositing system uses a top-down
// or a bottom-up coordinate system.
@@ -291,7 +292,6 @@ public:
virtual void setContentsOrientation(CompositingCoordinatesOrientation orientation) { m_contentsOrientation = orientation; }
CompositingCoordinatesOrientation contentsOrientation() const { return m_contentsOrientation; }
-#ifndef NDEBUG
static bool showDebugBorders();
static bool showRepaintCounter();
@@ -302,7 +302,6 @@ public:
// z-position is the z-equivalent of position(). It's only used for debugging purposes.
virtual float zPosition() const { return m_zPosition; }
virtual void setZPosition(float);
-#endif
virtual void distributeOpacity(float);
virtual float accumulatedOpacity() const;
@@ -339,9 +338,7 @@ protected:
Color m_backgroundColor;
float m_opacity;
-#ifndef NDEBUG
float m_zPosition;
-#endif
bool m_backgroundColorSet : 1;
bool m_contentsOpaque : 1;
@@ -362,9 +359,7 @@ protected:
IntRect m_contentsRect;
-#ifndef NDEBUG
int m_repaintCount;
-#endif
};
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index de8afb3..8741c5e 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -931,6 +931,11 @@ void GraphicsContext::clip(const Path& path)
m_data->clip(path);
}
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
void GraphicsContext::clipOut(const Path& path)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 1b843e4..1350bd3 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -849,6 +849,11 @@ void GraphicsContext::clip(const Path& path)
m_data->clip(path);
}
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
void GraphicsContext::clipOut(const Path& path)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp
index dca0efb..a4526a8 100644
--- a/WebCore/platform/graphics/chromium/FontLinux.cpp
+++ b/WebCore/platform/graphics/chromium/FontLinux.cpp
@@ -57,6 +57,23 @@ bool Font::canReturnFallbackFontsForComplexText()
return false;
}
+static bool isCanvasMultiLayered(SkCanvas* canvas)
+{
+ SkCanvas::LayerIter layerIterator(canvas, false);
+ layerIterator.next();
+ return !layerIterator.done();
+}
+
+static bool adjustTextRenderMode(SkPaint* paint, bool isCanvasMultiLayered)
+{
+ // Our layers only have a single alpha channel. This means that subpixel
+ // rendered text cannot be compositied correctly when the layer is
+ // collapsed. Therefore, subpixel text is disabled when we are drawing
+ // onto a layer.
+ if (isCanvasMultiLayered)
+ paint->setLCDRenderText(false);
+}
+
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
const GlyphBuffer& glyphBuffer, int from, int numGlyphs,
const FloatPoint& point) const {
@@ -84,12 +101,14 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
SkCanvas* canvas = gc->platformContext()->canvas();
int textMode = gc->platformContext()->getTextDrawingMode();
+ bool haveMultipleLayers = isCanvasMultiLayered(canvas);
// We draw text up to two times (once for fill, once for stroke).
if (textMode & cTextFill) {
SkPaint paint;
gc->platformContext()->setupPaintForFilling(&paint);
font->platformData().setupPaint(&paint);
+ adjustTextRenderMode(&paint, haveMultipleLayers);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setColor(gc->fillColor().rgb());
canvas->drawPosText(glyphs, numGlyphs << 1, pos, paint);
@@ -102,6 +121,7 @@ void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
SkPaint paint;
gc->platformContext()->setupPaintForStroking(&paint, 0, 0);
font->platformData().setupPaint(&paint);
+ adjustTextRenderMode(&paint, haveMultipleLayers);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
paint.setColor(gc->strokeColor().rgb());
@@ -472,15 +492,18 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run,
}
TextRunWalker walker(run, point.x(), this);
+ bool haveMultipleLayers = isCanvasMultiLayered(canvas);
while (walker.nextScriptRun()) {
if (fill) {
walker.fontPlatformDataForScriptRun()->setupPaint(&fillPaint);
+ adjustTextRenderMode(&fillPaint, haveMultipleLayers);
canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, walker.xPositions(), point.y(), fillPaint);
}
if (stroke) {
walker.fontPlatformDataForScriptRun()->setupPaint(&strokePaint);
+ adjustTextRenderMode(&strokePaint, haveMultipleLayers);
canvas->drawPosTextH(walker.glyphs(), walker.length() << 1, walker.xPositions(), point.y(), strokePaint);
}
}
@@ -645,8 +668,6 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run,
if (toX == -1 && !to)
toX = rightEdge;
- else if (!walker.rtl())
- toX += truncateFixedPointToInteger(toAdvance);
ASSERT(fromX != -1 && toX != -1);
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index 1e2e552..a2ed9bd 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -30,6 +30,7 @@
#include "GraphicsContext.h"
#include "ImageData.h"
#include <math.h>
+#include <wtf/MathExtras.h>
namespace WebCore {
@@ -92,8 +93,8 @@ inline void saturate(double& red, double& green, double& blue, const float& s)
inline void huerotate(double& red, double& green, double& blue, const float& hue)
{
- double cosHue = cos(hue * M_PI / 180);
- double sinHue = sin(hue * M_PI / 180);
+ double cosHue = cos(hue * piDouble / 180);
+ double sinHue = sin(hue * piDouble / 180);
double r = red * (0.213 + cosHue * 0.787 - sinHue * 0.213) +
green * (0.715 - cosHue * 0.715 - sinHue * 0.715) +
blue * (0.072 - cosHue * 0.072 + sinHue * 0.928);
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index 43e5edd..0d76d8d 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -92,11 +92,11 @@ void FEComponentTransfer::setAlphaFunction(const ComponentTransferFunction& func
m_alphaFunc = func;
}
-void identity(unsigned char*, const ComponentTransferFunction&)
+static void identity(unsigned char*, const ComponentTransferFunction&)
{
}
-void table(unsigned char* values, const ComponentTransferFunction& transferFunction)
+static void table(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
const Vector<float>& tableValues = transferFunction.tableValues;
unsigned n = tableValues.size();
@@ -113,7 +113,7 @@ void table(unsigned char* values, const ComponentTransferFunction& transferFunct
}
}
-void discrete(unsigned char* values, const ComponentTransferFunction& transferFunction)
+static void discrete(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
const Vector<float>& tableValues = transferFunction.tableValues;
unsigned n = tableValues.size();
@@ -128,7 +128,7 @@ void discrete(unsigned char* values, const ComponentTransferFunction& transferFu
}
}
-void linear(unsigned char* values, const ComponentTransferFunction& transferFunction)
+static void linear(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
for (unsigned i = 0; i < 256; ++i) {
double val = transferFunction.slope * i + 255 * transferFunction.intercept;
@@ -137,7 +137,7 @@ void linear(unsigned char* values, const ComponentTransferFunction& transferFunc
}
}
-void gamma(unsigned char* values, const ComponentTransferFunction& transferFunction)
+static void gamma(unsigned char* values, const ComponentTransferFunction& transferFunction)
{
for (unsigned i = 0; i < 256; ++i) {
double val = 255.0 * (transferFunction.amplitude * pow((i / 255.0), transferFunction.exponent) + transferFunction.offset);
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
new file mode 100644
index 0000000..f480f10
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -0,0 +1,140 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005 Rob Buis <buis@kde.org>
+ 2005 Eric Seidel <eric@webkit.org>
+ 2009 Dirk Schulze <krit@webkit.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+
+#if ENABLE(FILTERS)
+#include "FEGaussianBlur.h"
+
+#include "CanvasPixelArray.h"
+#include "Filter.h"
+#include "GraphicsContext.h"
+#include "ImageData.h"
+#include <math.h>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+FEGaussianBlur::FEGaussianBlur(FilterEffect* in, const float& x, const float& y)
+ : FilterEffect()
+ , m_in(in)
+ , m_x(x)
+ , m_y(y)
+{
+}
+
+PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(FilterEffect* in, const float& x, const float& y)
+{
+ return adoptRef(new FEGaussianBlur(in, x, y));
+}
+
+float FEGaussianBlur::stdDeviationX() const
+{
+ return m_x;
+}
+
+void FEGaussianBlur::setStdDeviationX(float x)
+{
+ m_x = x;
+}
+
+float FEGaussianBlur::stdDeviationY() const
+{
+ return m_y;
+}
+
+void FEGaussianBlur::setStdDeviationY(float y)
+{
+ m_y = y;
+}
+
+static void boxBlur(CanvasPixelArray*& srcPixelArray, CanvasPixelArray*& dstPixelArray,
+ unsigned dx, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage)
+{
+ int dxLeft = dx / 2;
+ int dxRight = dx - dxLeft;
+
+ for (int y = 0; y < effectHeight; ++y) {
+ int line = y * strideLine;
+ for (int channel = 3; channel >= 0; --channel) {
+ int sum = 0;
+ // Fill the kernel
+ int maxKernelSize = std::min(dxRight, effectWidth);
+ for (int i = 0; i < maxKernelSize; ++i)
+ sum += srcPixelArray->get(line + i * stride + channel);
+
+ // Blurring
+ for (int x = 0; x < effectWidth; ++x) {
+ int pixelByteOffset = line + x * stride + channel;
+ dstPixelArray->set(pixelByteOffset, static_cast<unsigned char>(sum / dx));
+ if (x >= dxLeft)
+ sum -= srcPixelArray->get(pixelByteOffset - dxLeft * stride);
+ if (x + dxRight < effectWidth)
+ sum += srcPixelArray->get(pixelByteOffset + dxRight * stride);
+ }
+ if (alphaImage) // Source image is black, it just has different alpha values
+ break;
+ }
+ }
+}
+
+void FEGaussianBlur::apply(Filter* filter)
+{
+ m_in->apply(filter);
+ if (!m_in->resultImage())
+ return;
+
+ if (!getEffectContext())
+ return;
+
+ setIsAlphaImage(m_in->isAlphaImage());
+
+ if (m_x == 0 || m_y == 0)
+ return;
+
+ unsigned sdx = static_cast<unsigned>(floor(m_x * 3 * sqrt(2 * piDouble) / 4.f + 0.5f));
+ unsigned sdy = static_cast<unsigned>(floor(m_y * 3 * sqrt(2 * piDouble) / 4.f + 0.5f));
+
+ IntRect effectDrawingRect = calculateDrawingIntRect(m_in->subRegion());
+ RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect));
+ CanvasPixelArray* srcPixelArray(srcImageData->data());
+
+ IntRect imageRect(IntPoint(), resultImage()->size());
+ RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height());
+ CanvasPixelArray* tmpPixelArray(tmpImageData->data());
+
+ int stride = 4 * imageRect.width();
+ for (int i = 0; i < 3; ++i) {
+ boxBlur(srcPixelArray, tmpPixelArray, sdx, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage());
+ boxBlur(tmpPixelArray, srcPixelArray, sdy, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage());
+ }
+
+ resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint());
+}
+
+void FEGaussianBlur::dump()
+{
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h
new file mode 100644
index 0000000..ecdb9e3
--- /dev/null
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h
@@ -0,0 +1,57 @@
+/*
+ Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
+ 2004, 2005 Rob Buis <buis@kde.org>
+ 2005 Eric Seidel <eric@webkit.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ aint with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef FEGaussianBlur_h
+#define FEGaussianBlur_h
+
+#if ENABLE(FILTERS)
+#include "FilterEffect.h"
+#include "Filter.h"
+
+namespace WebCore {
+
+ class FEGaussianBlur : public FilterEffect {
+ public:
+ static PassRefPtr<FEGaussianBlur> create(FilterEffect*, const float&, const float&);
+
+ float stdDeviationX() const;
+ void setStdDeviationX(float);
+
+ float stdDeviationY() const;
+ void setStdDeviationY(float);
+
+ virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return calculateUnionOfChildEffectSubregions(filter, m_in.get()); }
+ void apply(Filter*);
+ void dump();
+
+ private:
+ FEGaussianBlur(FilterEffect*, const float&, const float&);
+
+ RefPtr<FilterEffect> m_in;
+ float m_x;
+ float m_y;
+ };
+
+} // namespace WebCore
+
+#endif // ENABLE(FILTERS)
+
+#endif // FEGaussianBlur_h
diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp
index 5818e50..68900b5 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -25,14 +25,11 @@
namespace WebCore {
FilterEffect::FilterEffect()
- : m_xBBoxMode(false)
- , m_yBBoxMode(false)
- , m_widthBBoxMode(false)
- , m_heightBBoxMode(false)
- , m_hasX(false)
+ : m_hasX(false)
, m_hasY(false)
, m_hasWidth(false)
, m_hasHeight(false)
+ , m_alphaImage(false)
{
}
diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h
index e2b8a0e..b30e513 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/WebCore/platform/graphics/filters/FilterEffect.h
@@ -38,18 +38,6 @@ namespace WebCore {
public:
virtual ~FilterEffect();
- bool xBoundingBoxMode() const { return m_xBBoxMode; }
- void setXBoundingBoxMode(bool bboxMode) { m_xBBoxMode = bboxMode; }
-
- bool yBoundingBoxMode() const { return m_yBBoxMode; }
- void setYBoundingBoxMode(bool bboxMode) { m_yBBoxMode = bboxMode; }
-
- bool widthBoundingBoxMode() const { return m_widthBBoxMode; }
- void setWidthBoundingBoxMode(bool bboxMode) { m_widthBBoxMode = bboxMode; }
-
- bool heightBoundingBoxMode() const { return m_heightBBoxMode; }
- void setHeightBoundingBoxMode(bool bboxMode) { m_heightBBoxMode = bboxMode; }
-
void setUnionOfChildEffectSubregions(const FloatRect& uniteRect) { m_unionOfChildEffectSubregions = uniteRect; }
FloatRect unionOfChildEffectSubregions() const { return m_unionOfChildEffectSubregions; }
@@ -79,6 +67,10 @@ namespace WebCore {
FloatRect calculateDrawingRect(const FloatRect&);
IntRect calculateDrawingIntRect(const FloatRect&);
+ // black image with different alpha values
+ bool isAlphaImage() { return m_alphaImage; }
+ void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
+
virtual FloatRect uniteChildEffectSubregions(Filter* filter) { return filter->filterRegion(); }
virtual FloatRect calculateEffectRect(Filter*);
virtual void apply(Filter*) = 0;
@@ -102,6 +94,8 @@ namespace WebCore {
bool m_hasWidth : 1;
bool m_hasHeight : 1;
+ bool m_alphaImage;
+
FloatRect m_subRegion;
FloatRect m_unionOfChildEffectSubregions;
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
index 57436be..1b6309b 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.cpp
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -59,6 +59,8 @@ void SourceAlpha::apply(Filter* filter)
if (!filterContext)
return;
+ setIsAlphaImage(true);
+
FloatRect imageRect(FloatPoint(), filter->sourceImage()->image()->size());
filterContext->save();
filterContext->clipToImageBuffer(imageRect, filter->sourceImage());
diff --git a/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp b/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp
index a6c2dfb..567da74 100644
--- a/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/DataSourceGStreamer.cpp
@@ -214,7 +214,7 @@ static gboolean webkit_data_src_uri_set_uri(GstURIHandler* handler, const gchar*
GInputStream* stream = g_memory_input_stream_new_from_data(decoded_data,
decoded_size,
g_free);
- g_object_set(src->kid, "stream", stream, 0);
+ g_object_set(src->kid, "stream", stream, NULL);
g_object_unref(stream);
if (src->uri) {
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 65c64b4..8d1d261 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -25,9 +25,10 @@
#if ENABLE(VIDEO)
#include "MediaPlayerPrivateGStreamer.h"
-#include "DataSourceGStreamer.h"
+
#include "CString.h"
+#include "DataSourceGStreamer.h"
#include "GraphicsContext.h"
#include "IntRect.h"
#include "KURL.h"
@@ -35,11 +36,10 @@
#include "MediaPlayer.h"
#include "NotImplemented.h"
#include "ScrollView.h"
+#include "TimeRanges.h"
#include "VideoSinkGStreamer.h"
#include "Widget.h"
-#include "TimeRanges.h"
-#include <gst/base/gstbasesrc.h>
#include <gst/gst.h>
#include <gst/interfaces/mixer.h>
#include <gst/interfaces/xoverlay.h>
@@ -52,16 +52,20 @@ using namespace std;
namespace WebCore {
-gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpointer data)
+gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data)
{
- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
- GOwnPtr<GError> err;
- GOwnPtr<gchar> debug;
+ GOwnPtr<GError> err;
+ GOwnPtr<gchar> debug;
+ MediaPlayer::NetworkState error;
+ MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
+ gint percent = 0;
+ switch (GST_MESSAGE_TYPE(message)) {
+ case GST_MESSAGE_ERROR:
gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
- MediaPlayer::NetworkState error = MediaPlayer::Empty;
+ error = MediaPlayer::Empty;
if (err->domain == GST_CORE_ERROR || err->domain == GST_LIBRARY_ERROR)
error = MediaPlayer::DecodeError;
else if (err->domain == GST_RESOURCE_ERROR)
@@ -69,44 +73,32 @@ gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpoin
else if (err->domain == GST_STREAM_ERROR)
error = MediaPlayer::NetworkError;
- MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
if (mp)
mp->loadingFailed(error);
- }
- return true;
-}
-
-gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data)
-{
- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_EOS) {
+ break;
+ case GST_MESSAGE_EOS:
LOG_VERBOSE(Media, "End of Stream");
- MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
mp->didEnd();
- }
- return true;
-}
-
-gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data)
-{
- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_STATE_CHANGED) {
- MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
+ break;
+ case GST_MESSAGE_STATE_CHANGED:
mp->updateStates();
- }
- return true;
-}
-
-gboolean mediaPlayerPrivateBufferingCallback(GstBus* bus, GstMessage* message, gpointer data)
-{
- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_BUFFERING) {
- gint percent = 0;
+ break;
+ case GST_MESSAGE_BUFFERING:
gst_message_parse_buffering(message, &percent);
LOG_VERBOSE(Media, "Buffering %d", percent);
+ break;
+ default:
+ LOG_VERBOSE(Media, "Unhandled GStreamer message type: %s",
+ GST_MESSAGE_TYPE_NAME(message));
+ break;
}
return true;
}
-static void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, MediaPlayerPrivate* playerPrivate)
+void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate)
{
+ g_return_if_fail(GST_IS_BUFFER(buffer));
+ gst_buffer_replace(&playerPrivate->m_buffer, buffer);
playerPrivate->repaint();
}
@@ -123,7 +115,8 @@ void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar)
static bool gstInitialized = false;
-static void do_gst_init() {
+static void do_gst_init()
+{
// FIXME: We should pass the arguments from the command line
if (!gstInitialized) {
gst_init(0, 0);
@@ -139,50 +132,33 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_playBin(0)
, m_videoSink(0)
, m_source(0)
- , m_rate(1.0f)
, m_endTime(numeric_limits<float>::infinity())
- , m_volume(0.5f)
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
, m_startedPlaying(false)
, m_isStreaming(false)
, m_size(IntSize())
- , m_visible(true)
+ , m_buffer(0)
, m_paused(true)
, m_seeking(false)
, m_errorOccured(false)
{
do_gst_init();
-
- // FIXME: The size shouldn't be fixed here, this is just a quick hack.
- m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);
-}
-
-static gboolean idleUnref(gpointer data)
-{
- g_object_unref(reinterpret_cast<GObject*>(data));
- return FALSE;
}
MediaPlayerPrivate::~MediaPlayerPrivate()
{
- if (m_surface)
- cairo_surface_destroy(m_surface);
+ if (m_buffer)
+ gst_buffer_unref(m_buffer);
+ m_buffer = 0;
if (m_playBin) {
gst_element_set_state(m_playBin, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(m_playBin));
}
- // FIXME: We should find a better way to handle the lifetime of this object; this is
- // needed because the object is sometimes being destroyed inbetween a call to
- // webkit_video_sink_render, and the idle it schedules. Adding a ref in
- // webkit_video_sink_render that would be balanced by the idle is not an option,
- // because in some cases the destruction of the sink may happen in time for the idle
- // to be removed from the queue, so it may not run. It would also cause lots of ref
- // counting churn (render/idle are called many times). This is an ugly race.
if (m_videoSink) {
- g_idle_add(idleUnref, m_videoSink);
+ g_object_unref(m_videoSink);
m_videoSink = 0;
}
}
@@ -226,24 +202,14 @@ float MediaPlayerPrivate::duration() const
GstFormat timeFormat = GST_FORMAT_TIME;
gint64 timeLength = 0;
-#if !GST_CHECK_VERSION(0, 10, 23)
- // We try to get the duration, but we do not trust the
- // return value of the query function only; the problem we are
- // trying to work-around here is that pipelines in stream mode may
- // not be able to figure out the duration, but still return true!
- // See https://bugs.webkit.org/show_bug.cgi?id=24639 which has been
- // fixed in gst-plugins-base 0.10.23
- if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeLength <= 0) {
-#else
- if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength)) {
-#endif
+ if (!gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeFormat != GST_FORMAT_TIME || timeLength == GST_CLOCK_TIME_NONE) {
LOG_VERBOSE(Media, "Time duration query failed.");
return numeric_limits<float>::infinity();
}
LOG_VERBOSE(Media, "Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(timeLength));
- return (float) (timeLength / 1000000000.0);
+ return (float) ((guint64) timeLength / 1000000000.0);
// FIXME: handle 3.14.9.5 properly
}
@@ -288,7 +254,7 @@ void MediaPlayerPrivate::seek(float time)
return;
LOG_VERBOSE(Media, "Seek: %" GST_TIME_FORMAT, GST_TIME_ARGS(sec));
- if (!gst_element_seek( m_playBin, m_rate,
+ if (!gst_element_seek(m_playBin, m_player->rate(),
GST_FORMAT_TIME,
(GstSeekFlags)(GST_SEEK_FLAG_FLUSH),
GST_SEEK_TYPE_SET, sec,
@@ -340,14 +306,17 @@ IntSize MediaPlayerPrivate::naturalSize() const
// https://bugzilla.gnome.org/show_bug.cgi?id=596326
int width = 0, height = 0;
if (GstPad* pad = gst_element_get_static_pad(m_videoSink, "sink")) {
- gst_video_get_size(GST_PAD(pad), &width, &height);
GstCaps* caps = GST_PAD_CAPS(pad);
gfloat pixelAspectRatio;
gint pixelAspectRatioNumerator, pixelAspectRatioDenominator;
- if (!gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
- &pixelAspectRatioDenominator))
- pixelAspectRatioNumerator = pixelAspectRatioDenominator = 1;
+ if (!GST_IS_CAPS(caps) || !gst_caps_is_fixed(caps) ||
+ !gst_video_format_parse_caps(caps, NULL, &width, &height) ||
+ !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
+ &pixelAspectRatioDenominator)) {
+ gst_object_unref(GST_OBJECT(pad));
+ return IntSize();
+ }
pixelAspectRatio = (gfloat) pixelAspectRatioNumerator / (gfloat) pixelAspectRatioDenominator;
width *= pixelAspectRatio;
@@ -376,21 +345,10 @@ bool MediaPlayerPrivate::hasAudio() const
void MediaPlayerPrivate::setVolume(float volume)
{
- m_volume = volume;
- LOG_VERBOSE(Media, "Volume to %f", volume);
-
if (!m_playBin)
return;
- g_object_set(G_OBJECT(m_playBin), "volume", m_volume, NULL);
-}
-
-void MediaPlayerPrivate::setMuted(bool mute)
-{
- if (!m_playBin)
- return;
-
- g_object_set(G_OBJECT(m_playBin), "mute", mute, NULL);
+ g_object_set(G_OBJECT(m_playBin), "volume", static_cast<double>(volume), NULL);
}
void MediaPlayerPrivate::setRate(float rate)
@@ -403,7 +361,6 @@ void MediaPlayerPrivate::setRate(float rate)
if (m_isStreaming)
return;
- m_rate = rate;
LOG_VERBOSE(Media, "Set Rate to %f", rate);
seek(currentTime());
}
@@ -495,7 +452,11 @@ unsigned MediaPlayerPrivate::totalBytes() const
void MediaPlayerPrivate::cancelLoad()
{
- notImplemented();
+ if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded)
+ return;
+
+ if (m_playBin)
+ gst_element_set_state(m_playBin, GST_STATE_NULL);
}
void MediaPlayerPrivate::updateStates()
@@ -525,14 +486,15 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(state),
gst_element_state_get_name(pending));
- if (state == GST_STATE_READY) {
- m_readyState = MediaPlayer::HaveEnoughData;
- } else if (state == GST_STATE_PAUSED)
+ if (state == GST_STATE_READY)
+ m_readyState = MediaPlayer::HaveNothing;
+ else if (state == GST_STATE_PAUSED)
m_readyState = MediaPlayer::HaveEnoughData;
- if (state == GST_STATE_PLAYING)
+ if (state == GST_STATE_PLAYING) {
+ m_readyState = MediaPlayer::HaveEnoughData;
m_paused = false;
- else
+ } else
m_paused = true;
if (m_seeking) {
@@ -563,9 +525,9 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(state),
gst_element_state_get_name(pending));
- if (state == GST_STATE_READY) {
- m_readyState = MediaPlayer::HaveFutureData;
- } else if (state == GST_STATE_PAUSED)
+ if (state == GST_STATE_READY)
+ m_readyState = MediaPlayer::HaveNothing;
+ else if (state == GST_STATE_PAUSED)
m_readyState = MediaPlayer::HaveCurrentData;
m_networkState = MediaPlayer::Loading;
@@ -639,23 +601,11 @@ void MediaPlayerPrivate::loadingFailed(MediaPlayer::NetworkState error)
void MediaPlayerPrivate::setSize(const IntSize& size)
{
- // Destroy and re-create the cairo surface only if the size
- // changed.
- if (size != m_size) {
- if (m_surface)
- cairo_surface_destroy(m_surface);
- m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size.width(),
- size.height());
- g_object_set(m_videoSink, "surface", m_surface, 0);
- }
-
m_size = size;
-
}
void MediaPlayerPrivate::setVisible(bool visible)
{
- m_visible = visible;
}
void MediaPlayerPrivate::repaint()
@@ -668,20 +618,65 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
if (context->paintingDisabled())
return;
- if (!m_visible)
+ if (!m_player->visible())
return;
+ if (!m_buffer)
+ return;
+
+ int width = 0, height = 0;
+ int pixelAspectRatioNumerator = 0;
+ int pixelAspectRatioDenominator = 0;
+ double doublePixelAspectRatioNumerator = 0;
+ double doublePixelAspectRatioDenominator = 0;
+ double displayWidth;
+ double displayHeight;
+ double scale, gapHeight, gapWidth;
+
+ GstCaps *caps = gst_buffer_get_caps(m_buffer);
+
+ if (!gst_video_format_parse_caps(caps, NULL, &width, &height) ||
+ !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator)) {
+ gst_caps_unref(caps);
+ return;
+ }
+
+ displayWidth = width;
+ displayHeight = height;
+ doublePixelAspectRatioNumerator = pixelAspectRatioNumerator;
+ doublePixelAspectRatioDenominator = pixelAspectRatioDenominator;
cairo_t* cr = context->platformContext();
+ cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(m_buffer),
+ CAIRO_FORMAT_RGB24,
+ width, height,
+ 4 * width);
cairo_save(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+ displayWidth *= doublePixelAspectRatioNumerator / doublePixelAspectRatioDenominator;
+ displayHeight *= doublePixelAspectRatioDenominator / doublePixelAspectRatioNumerator;
+
+ scale = MIN (rect.width () / displayWidth, rect.height () / displayHeight);
+ displayWidth *= scale;
+ displayHeight *= scale;
+
+ // Calculate gap between border an picture
+ gapWidth = (rect.width() - displayWidth) / 2.0;
+ gapHeight = (rect.height() - displayHeight) / 2.0;
+
// paint the rectangle on the context and draw the surface inside.
- cairo_translate(cr, rect.x(), rect.y());
+ cairo_translate(cr, rect.x() + gapWidth, rect.y() + gapHeight);
cairo_rectangle(cr, 0, 0, rect.width(), rect.height());
- cairo_set_source_surface(cr, m_surface, 0, 0);
+ cairo_scale(cr, doublePixelAspectRatioNumerator / doublePixelAspectRatioDenominator,
+ doublePixelAspectRatioDenominator / doublePixelAspectRatioNumerator);
+ cairo_scale(cr, scale, scale);
+ cairo_set_source_surface(cr, src, 0, 0);
cairo_fill(cr);
cairo_restore(cr);
+
+ cairo_surface_destroy(src);
+ gst_caps_unref(caps);
}
static HashSet<String> mimeTypeCache()
@@ -805,25 +800,18 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
GstBus* bus = gst_pipeline_get_bus(GST_PIPELINE(m_playBin));
gst_bus_add_signal_watch(bus);
- g_signal_connect(bus, "message::error", G_CALLBACK(mediaPlayerPrivateErrorCallback), this);
- g_signal_connect(bus, "message::eos", G_CALLBACK(mediaPlayerPrivateEOSCallback), this);
- g_signal_connect(bus, "message::state-changed", G_CALLBACK(mediaPlayerPrivateStateCallback), this);
- g_signal_connect(bus, "message::buffering", G_CALLBACK(mediaPlayerPrivateBufferingCallback), this);
+ g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this);
gst_object_unref(bus);
- g_object_set(G_OBJECT(m_playBin), "uri", url.utf8().data(), NULL);
-
- m_videoSink = webkit_video_sink_new(m_surface);
+ g_object_set(G_OBJECT(m_playBin), "uri", url.utf8().data(),
+ "volume", static_cast<double>(m_player->volume()), NULL);
- // This ref is to protect the sink from being destroyed before we stop the idle it
- // creates internally. See the comment in ~MediaPlayerPrivate.
- g_object_ref(m_videoSink);
+ m_videoSink = webkit_video_sink_new();
+ g_object_ref_sink(m_videoSink);
g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
g_signal_connect(m_videoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
-
- setVolume(m_volume);
}
}
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index d305759..54da420 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -30,8 +30,10 @@
#include <cairo.h>
#include <glib.h>
-typedef struct _GstElement GstElement;
+typedef struct _WebKitVideoSink WebKitVideoSink;
+typedef struct _GstBuffer GstBuffer;
typedef struct _GstMessage GstMessage;
+typedef struct _GstElement GstElement;
typedef struct _GstBus GstBus;
namespace WebCore {
@@ -41,14 +43,11 @@ namespace WebCore {
class IntRect;
class String;
- gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpointer data);
- gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data);
- gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data);
+ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
- friend gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpointer data);
- friend gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data);
- friend gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data);
+ friend gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
+ friend void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate);
public:
static void registerMediaEngine(MediaEngineRegistrar);
@@ -74,7 +73,6 @@ namespace WebCore {
void setRate(float);
void setVolume(float);
- void setMuted(bool);
int dataRate() const;
@@ -126,17 +124,14 @@ namespace WebCore {
GstElement* m_playBin;
GstElement* m_videoSink;
GstElement* m_source;
- float m_rate;
float m_endTime;
bool m_isEndReached;
- double m_volume;
MediaPlayer::NetworkState m_networkState;
MediaPlayer::ReadyState m_readyState;
bool m_startedPlaying;
mutable bool m_isStreaming;
IntSize m_size;
- bool m_visible;
- cairo_surface_t* m_surface;
+ GstBuffer* m_buffer;
bool m_paused;
bool m_seeking;
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index fb86fe9..b5e1a8b 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
@@ -21,8 +21,9 @@
* SECTION:webkit-video-sink
* @short_description: GStreamer video sink
*
- * #WebKitVideoSink is a GStreamer sink element that sends
- * data to a #cairo_surface_t.
+ * #WebKitVideoSink is a GStreamer sink element that triggers
+ * repaints in the WebKit GStreamer media player for the
+ * current video buffer.
*/
#include "config.h"
@@ -57,22 +58,26 @@ enum {
};
enum {
- PROP_0,
- PROP_SURFACE
+ PROP_0
};
static guint webkit_video_sink_signals[LAST_SIGNAL] = { 0, };
struct _WebKitVideoSinkPrivate {
- cairo_surface_t* surface;
- GAsyncQueue* async_queue;
- gboolean rgb_ordering;
- int width;
- int height;
- int fps_n;
- int fps_d;
- int par_n;
- int par_d;
+ GstBuffer* buffer;
+ guint timeout_id;
+ GMutex* buffer_mutex;
+ GCond* data_cond;
+
+ // If this is TRUE all processing should finish ASAP
+ // This is necessary because there could be a race between
+ // unlock() and render(), where unlock() wins, signals the
+ // GCond, then render() tries to render a frame although
+ // everything else isn't running anymore. This will lead
+ // to deadlocks because render() holds the stream lock.
+ //
+ // Protected by the buffer mutex
+ gboolean unlocked;
};
#define _do_init(bla) \
@@ -83,8 +88,8 @@ struct _WebKitVideoSinkPrivate {
GST_BOILERPLATE_FULL(WebKitVideoSink,
webkit_video_sink,
- GstBaseSink,
- GST_TYPE_BASE_SINK,
+ GstVideoSink,
+ GST_TYPE_VIDEO_SINK,
_do_init);
static void
@@ -102,59 +107,37 @@ webkit_video_sink_init(WebKitVideoSink* sink, WebKitVideoSinkClass* klass)
WebKitVideoSinkPrivate* priv;
sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate);
- priv->async_queue = g_async_queue_new();
+ priv->data_cond = g_cond_new();
+ priv->buffer_mutex = g_mutex_new();
}
static gboolean
-webkit_video_sink_idle_func(gpointer data)
+webkit_video_sink_timeout_func(gpointer data)
{
WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data);
WebKitVideoSinkPrivate* priv = sink->priv;
GstBuffer* buffer;
- GstCaps* caps;
- GstVideoFormat format;
- gint par_n, par_d;
- gfloat par;
- gint bwidth, bheight;
- if (!priv->async_queue)
- return FALSE;
+ g_mutex_lock(priv->buffer_mutex);
+ buffer = priv->buffer;
+ priv->buffer = 0;
+ priv->timeout_id = 0;
- buffer = (GstBuffer*)g_async_queue_try_pop(priv->async_queue);
- if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer)))
+ if (!buffer || priv->unlocked || G_UNLIKELY(!GST_IS_BUFFER(buffer))) {
+ g_cond_signal(priv->data_cond);
+ g_mutex_unlock(priv->buffer_mutex);
return FALSE;
+ }
- caps = GST_BUFFER_CAPS(buffer);
- if (!gst_video_format_parse_caps(caps, &format, &bwidth, &bheight)) {
- GST_ERROR_OBJECT(sink, "Unknown video format in buffer caps '%s'",
- gst_caps_to_string(caps));
- return FALSE;
+ if (G_UNLIKELY(!GST_BUFFER_CAPS(buffer))) {
+ buffer = gst_buffer_make_metadata_writable(buffer);
+ gst_buffer_set_caps(buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(sink)));
}
- if (!gst_video_parse_caps_pixel_aspect_ratio(caps, &par_n, &par_d))
- par_n = par_d = 1;
-
- par = (gfloat) par_n / (gfloat) par_d;
-
- // TODO: consider priv->rgb_ordering?
- cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer),
- CAIRO_FORMAT_RGB24,
- bwidth, bheight,
- 4 * bwidth);
-
- // TODO: We copy the data twice right now. This could be easily improved.
- cairo_t* cr = cairo_create(priv->surface);
- cairo_scale(cr, par, 1.0 / par);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_surface(cr, src, 0, 0);
- cairo_surface_destroy(src);
- cairo_rectangle(cr, 0, 0, priv->width, priv->height);
- cairo_fill(cr);
- cairo_destroy(cr);
+ g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0, buffer);
gst_buffer_unref(buffer);
- g_async_queue_unref(priv->async_queue);
-
- g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0);
+ g_cond_signal(priv->data_cond);
+ g_mutex_unlock(priv->buffer_mutex);
return FALSE;
}
@@ -165,53 +148,24 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink);
WebKitVideoSinkPrivate* priv = sink->priv;
- g_async_queue_ref(priv->async_queue);
- g_async_queue_push(priv->async_queue, gst_buffer_ref(buffer));
- g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, sink, 0);
-
- return GST_FLOW_OK;
-}
-
-static gboolean
-webkit_video_sink_set_caps(GstBaseSink* bsink, GstCaps* caps)
-{
- WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink);
- WebKitVideoSinkPrivate* priv = sink->priv;
- GstStructure* structure;
- gboolean ret;
- gint width, height, fps_n, fps_d;
- int red_mask;
-
- GstCaps* intersection = gst_caps_intersect(gst_static_pad_template_get_caps(&sinktemplate), caps);
+ g_mutex_lock(priv->buffer_mutex);
- if (gst_caps_is_empty(intersection))
- return FALSE;
-
- gst_caps_unref(intersection);
-
- structure = gst_caps_get_structure(caps, 0);
-
- ret = gst_structure_get_int(structure, "width", &width);
- ret &= gst_structure_get_int(structure, "height", &height);
-
- /* We dont yet use fps but handy to have */
- ret &= gst_structure_get_fraction(structure, "framerate",
- &fps_n, &fps_d);
- g_return_val_if_fail(ret, FALSE);
-
- priv->width = width;
- priv->height = height;
- priv->fps_n = fps_n;
- priv->fps_d = fps_d;
+ if (priv->unlocked) {
+ g_mutex_unlock(priv->buffer_mutex);
+ return GST_FLOW_OK;
+ }
- if (!gst_structure_get_fraction(structure, "pixel-aspect-ratio",
- &priv->par_n, &priv->par_d))
- priv->par_n = priv->par_d = 1;
+ priv->buffer = gst_buffer_ref(buffer);
- gst_structure_get_int(structure, "red_mask", &red_mask);
- priv->rgb_ordering = (red_mask == static_cast<int>(0xff000000));
+ // Use HIGH_IDLE+20 priority, like Gtk+ for redrawing operations.
+ priv->timeout_id = g_timeout_add_full(G_PRIORITY_HIGH_IDLE + 20, 0,
+ webkit_video_sink_timeout_func,
+ gst_object_ref(sink),
+ (GDestroyNotify)gst_object_unref);
- return TRUE;
+ g_cond_wait(priv->data_cond, priv->buffer_mutex);
+ g_mutex_unlock(priv->buffer_mutex);
+ return GST_FLOW_OK;
}
static void
@@ -220,56 +174,58 @@ webkit_video_sink_dispose(GObject* object)
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
WebKitVideoSinkPrivate* priv = sink->priv;
- if (priv->surface) {
- cairo_surface_destroy(priv->surface);
- priv->surface = 0;
+ if (priv->data_cond) {
+ g_cond_free(priv->data_cond);
+ priv->data_cond = 0;
}
- if (priv->async_queue) {
- g_async_queue_unref(priv->async_queue);
- priv->async_queue = 0;
+ if (priv->buffer_mutex) {
+ g_mutex_free(priv->buffer_mutex);
+ priv->buffer_mutex = 0;
}
G_OBJECT_CLASS(parent_class)->dispose(object);
}
static void
-webkit_video_sink_finalize(GObject* object)
+unlock_buffer_mutex(WebKitVideoSinkPrivate* priv)
{
- G_OBJECT_CLASS(parent_class)->finalize(object);
+ g_mutex_lock(priv->buffer_mutex);
+
+ if (priv->buffer) {
+ gst_buffer_unref(priv->buffer);
+ priv->buffer = 0;
+ }
+
+ priv->unlocked = TRUE;
+
+ g_cond_signal(priv->data_cond);
+ g_mutex_unlock(priv->buffer_mutex);
}
-static void
-webkit_video_sink_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
+static gboolean
+webkit_video_sink_unlock(GstBaseSink* object)
{
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
- WebKitVideoSinkPrivate* priv = sink->priv;
- switch (prop_id) {
- case PROP_SURFACE:
- if (priv->surface)
- cairo_surface_destroy(priv->surface);
- priv->surface = cairo_surface_reference((cairo_surface_t*)g_value_get_pointer(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
+ unlock_buffer_mutex(sink->priv);
+
+ return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock,
+ (object), TRUE);
}
-static void
-webkit_video_sink_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
+static gboolean
+webkit_video_sink_unlock_stop(GstBaseSink* object)
{
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
+ WebKitVideoSinkPrivate* priv = sink->priv;
- switch (prop_id) {
- case PROP_SURFACE:
- g_value_set_pointer(value, sink->priv->surface);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
+ g_mutex_lock(priv->buffer_mutex);
+ priv->unlocked = FALSE;
+ g_mutex_unlock(priv->buffer_mutex);
+
+ return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock_stop,
+ (object), TRUE);
}
static gboolean
@@ -277,20 +233,46 @@ webkit_video_sink_stop(GstBaseSink* base_sink)
{
WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv;
- g_async_queue_lock(priv->async_queue);
-
- /* Remove all remaining objects from the queue */
- while (GstBuffer* buffer = (GstBuffer*)g_async_queue_try_pop_unlocked(priv->async_queue))
- gst_buffer_unref(buffer);
-
- g_async_queue_unlock(priv->async_queue);
+ unlock_buffer_mutex(priv);
+ return TRUE;
+}
- g_idle_remove_by_data(base_sink);
+static gboolean
+webkit_video_sink_start(GstBaseSink* base_sink)
+{
+ WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv;
+ g_mutex_lock(priv->buffer_mutex);
+ priv->unlocked = FALSE;
+ g_mutex_unlock(priv->buffer_mutex);
return TRUE;
}
static void
+marshal_VOID__MINIOBJECT(GClosure * closure, GValue * return_value,
+ guint n_param_values, const GValue * param_values,
+ gpointer invocation_hint, gpointer marshal_data)
+{
+ typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1, gpointer data2);
+ marshalfunc_VOID__MINIOBJECT callback;
+ GCClosure *cc = (GCClosure *) closure;
+ gpointer data1, data2;
+
+ g_return_if_fail(n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA(closure)) {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer(param_values + 0);
+ } else {
+ data1 = g_value_peek_pointer(param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->callback);
+
+ callback(data1, gst_value_get_mini_object(param_values + 1), data2);
+}
+
+static void
webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
{
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
@@ -298,16 +280,14 @@ webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
g_type_class_add_private(klass, sizeof(WebKitVideoSinkPrivate));
- gobject_class->set_property = webkit_video_sink_set_property;
- gobject_class->get_property = webkit_video_sink_get_property;
-
gobject_class->dispose = webkit_video_sink_dispose;
- gobject_class->finalize = webkit_video_sink_finalize;
+ gstbase_sink_class->unlock = webkit_video_sink_unlock;
+ gstbase_sink_class->unlock_stop = webkit_video_sink_unlock_stop;
gstbase_sink_class->render = webkit_video_sink_render;
gstbase_sink_class->preroll = webkit_video_sink_render;
gstbase_sink_class->stop = webkit_video_sink_stop;
- gstbase_sink_class->set_caps = webkit_video_sink_set_caps;
+ gstbase_sink_class->start = webkit_video_sink_start;
webkit_video_sink_signals[REPAINT_REQUESTED] = g_signal_new("repaint-requested",
G_TYPE_FROM_CLASS(klass),
@@ -315,37 +295,20 @@ webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
0,
0,
0,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- g_object_class_install_property(
- gobject_class, PROP_SURFACE,
- g_param_spec_pointer("surface", "surface", "Target cairo_surface_t*",
- (GParamFlags)(G_PARAM_READWRITE)));
+ marshal_VOID__MINIOBJECT,
+ G_TYPE_NONE, 1, GST_TYPE_BUFFER);
}
/**
* webkit_video_sink_new:
- * @surface: a #cairo_surface_t
*
- * Creates a new GStreamer video sink which uses @surface as the target
- * for sinking a video stream from GStreamer.
+ * Creates a new GStreamer video sink.
*
* Return value: a #GstElement for the newly created video sink
*/
GstElement*
-webkit_video_sink_new(cairo_surface_t* surface)
+webkit_video_sink_new(void)
{
- return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, "surface", surface, 0);
+ return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0);
}
-void
-webkit_video_sink_set_surface(WebKitVideoSink* sink, cairo_surface_t* surface)
-{
- WebKitVideoSinkPrivate* priv;
-
- sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate);
- if (priv->surface)
- cairo_surface_destroy(priv->surface);
- priv->surface = cairo_surface_reference(surface);
-}
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
index be2c94c..7ea7d91 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
@@ -22,7 +22,7 @@
#include <cairo.h>
#include <glib-object.h>
-#include <gst/base/gstbasesink.h>
+#include <gst/video/gstvideosink.h>
G_BEGIN_DECLS
@@ -54,13 +54,13 @@ typedef struct _WebKitVideoSinkPrivate WebKitVideoSinkPrivate;
struct _WebKitVideoSink {
/*< private >*/
- GstBaseSink parent;
+ GstVideoSink parent;
WebKitVideoSinkPrivate *priv;
};
struct _WebKitVideoSinkClass {
/*< private >*/
- GstBaseSinkClass parent_class;
+ GstVideoSinkClass parent_class;
/* Future padding */
void (* _webkit_reserved1)(void);
@@ -72,9 +72,7 @@ struct _WebKitVideoSinkClass {
};
GType webkit_video_sink_get_type(void) G_GNUC_CONST;
-GstElement *webkit_video_sink_new(cairo_surface_t *surface);
-
-void webkit_video_sink_set_surface(WebKitVideoSink *sink, cairo_surface_t *surface);
+GstElement *webkit_video_sink_new(void);
G_END_DECLS
diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
index d785ef4..c23b8a9 100644
--- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
@@ -369,6 +369,11 @@ void GraphicsContext::clip(const Path& path)
m_data->m_view->ConstrainClippingRegion(path.platformPath());
}
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
void GraphicsContext::clipOut(const Path& path)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
index 34941c0..adb7573 100644
--- a/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/SimpleFontDataHaiku.cpp
@@ -39,6 +39,8 @@
#include <unicode/unorm.h>
+extern int charUnicodeToUTF8HACK(unsigned short, char*);
+
namespace WebCore {
void SimpleFontData::platformInit()
@@ -93,15 +95,15 @@ void SimpleFontData::determinePitch()
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
- const char charArray[1] = { glyph };
- float escapements[1];
+ if (!m_platformData.font())
+ return 0;
- if (m_platformData.font()) {
- m_platformData.font()->GetEscapements(charArray, 1, escapements);
- return escapements[0] * m_platformData.font()->Size();
- }
+ char charArray[4];
+ float escapements[1];
- return 0;
+ charUnicodeToUTF8HACK(glyph, charArray);
+ m_platformData.font()->GetEscapements(charArray, 1, escapements);
+ return escapements[0] * m_platformData.font()->Size();
}
} // namespace WebCore
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.h b/WebCore/platform/graphics/mac/Canvas3DLayer.h
index 6c65676..122ef39 100644
--- a/WebCore/platform/graphics/mac/Canvas3DLayer.h
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.h
@@ -41,7 +41,9 @@ namespace WebCore {
GLuint m_texture;
}
--(id)initWithContext:(CGLContextObj)context texture:(GLuint)texture;
+- (id)initWithContext:(CGLContextObj)context texture:(GLuint)texture;
+
+- (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
@end
diff --git a/WebCore/platform/graphics/mac/Canvas3DLayer.mm b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
index 545c58b..94819d4 100644
--- a/WebCore/platform/graphics/mac/Canvas3DLayer.mm
+++ b/WebCore/platform/graphics/mac/Canvas3DLayer.mm
@@ -33,6 +33,8 @@
#import "GraphicsLayer.h"
#import <QuartzCore/QuartzCore.h>
#import <OpenGL/OpenGL.h>
+#import <wtf/RetainPtr.h>
+#include <wtf/FastMalloc.h>
using namespace WebCore;
@@ -48,19 +50,14 @@ using namespace WebCore;
-(CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
{
- CGLPixelFormatAttribute attribs[] =
- {
- (CGLPixelFormatAttribute) kCGLPFAAccelerated,
- (CGLPixelFormatAttribute) kCGLPFAColorSize, (CGLPixelFormatAttribute) 32,
- (CGLPixelFormatAttribute) kCGLPFADisplayMask, (CGLPixelFormatAttribute) mask,
- (CGLPixelFormatAttribute) 0
- };
-
- CGLPixelFormatObj pixelFormatObj;
- GLint numPixelFormats;
-
- CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
- return pixelFormatObj;
+ // FIXME: The mask param tells you which display (on a multi-display system)
+ // is to be used. But since we are now getting the pixel format from the
+ // Canvas CGL context, we don't use it. This seems to do the right thing on
+ // one multi-display system. But there may be cases where this is not the case.
+ // If needed we will have to set the display mask in the Canvas CGLContext and
+ // make sure it matches.
+ UNUSED_PARAM(mask);
+ return CGLRetainPixelFormat(CGLGetPixelFormat(m_contextObj));
}
-(CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat
@@ -72,6 +69,10 @@ using namespace WebCore;
-(void)drawInCGLContext:(CGLContextObj)glContext pixelFormat:(CGLPixelFormatObj)pixelFormat forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
{
+ CGLSetCurrentContext(m_contextObj);
+ glFinish();
+ CGLSetCurrentContext(glContext);
+
CGRect frame = [self frame];
// draw the FBO into the layer
@@ -103,6 +104,42 @@ using namespace WebCore;
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
}
+static void freeData(void *, const void *data, size_t /* size */)
+{
+ fastFree(const_cast<void *>(data));
+}
+
+-(CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace
+{
+ CGLSetCurrentContext(m_contextObj);
+
+ RetainPtr<CGColorSpaceRef> imageColorSpace = colorSpace;
+ if (!imageColorSpace)
+ imageColorSpace.adoptCF(CGColorSpaceCreateDeviceRGB());
+
+ CGRect layerBounds = CGRectIntegral([self bounds]);
+
+ size_t width = layerBounds.size.width;
+ size_t height = layerBounds.size.height;
+
+ size_t rowBytes = (width * 4 + 15) & ~15;
+ size_t dataSize = rowBytes * height;
+ void* data = fastMalloc(dataSize);
+ if (!data)
+ return 0;
+
+ glPixelStorei(GL_PACK_ROW_LENGTH, rowBytes / 4);
+ glReadPixels(0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
+
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, data, dataSize, freeData);
+ CGImageRef image = CGImageCreate(width, height, 8, 32, rowBytes, imageColorSpace.get(),
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
+ provider, 0, true,
+ kCGRenderingIntentDefault);
+ CGDataProviderRelease(provider);
+ return image;
+}
+
@end
@implementation Canvas3DLayer(WebLayerAdditions)
diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
index cd66445..47617d8 100644
--- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
+++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.cpp
@@ -30,9 +30,10 @@
#include "GraphicsContext3D.h"
#include "CachedImage.h"
+#include "CanvasActiveInfo.h"
+#include "CanvasArray.h"
#include "CanvasBuffer.h"
#include "CanvasFramebuffer.h"
-#include "CanvasArray.h"
#include "CanvasFloatArray.h"
#include "CanvasIntArray.h"
#include "CanvasObject.h"
@@ -49,29 +50,91 @@
#include "WebKitCSSMatrix.h"
#include <CoreGraphics/CGBitmapContext.h>
+#include <OpenGL/CGLRenderers.h>
namespace WebCore {
-GraphicsContext3D::GraphicsContext3D()
+static void setPixelFormat(Vector<CGLPixelFormatAttribute>& attribs, int colorBits, int depthBits, bool accelerated, bool supersample, bool closest)
{
- CGLPixelFormatAttribute attribs[] =
- {
- (CGLPixelFormatAttribute) kCGLPFAAccelerated,
- (CGLPixelFormatAttribute) kCGLPFAColorSize, (CGLPixelFormatAttribute) 32,
- (CGLPixelFormatAttribute) kCGLPFADepthSize, (CGLPixelFormatAttribute) 32,
- (CGLPixelFormatAttribute) kCGLPFASupersample,
- (CGLPixelFormatAttribute) 0
- };
+ attribs.clear();
- CGLPixelFormatObj pixelFormatObj;
- GLint numPixelFormats;
+ attribs.append(kCGLPFAColorSize);
+ attribs.append(static_cast<CGLPixelFormatAttribute>(colorBits));
+ attribs.append(kCGLPFADepthSize);
+ attribs.append(static_cast<CGLPixelFormatAttribute>(depthBits));
- CGLChoosePixelFormat(attribs, &pixelFormatObj, &numPixelFormats);
-
- CGLCreateContext(pixelFormatObj, 0, &m_contextObj);
+ if (accelerated)
+ attribs.append(kCGLPFAAccelerated);
+ else {
+ attribs.append(kCGLPFARendererID);
+ attribs.append(static_cast<CGLPixelFormatAttribute>(kCGLRendererGenericFloatID));
+ }
+
+ if (supersample)
+ attribs.append(kCGLPFASupersample);
+
+ if (closest)
+ attribs.append(kCGLPFAClosestPolicy);
+
+ attribs.append(static_cast<CGLPixelFormatAttribute>(0));
+}
+
+PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create()
+{
+ OwnPtr<GraphicsContext3D> context(new GraphicsContext3D());
+ return context->m_contextObj ? context.release() : 0;
+}
+
+GraphicsContext3D::GraphicsContext3D()
+ : m_contextObj(0)
+ , m_texture(0)
+ , m_fbo(0)
+ , m_depthBuffer(0)
+{
+ Vector<CGLPixelFormatAttribute> attribs;
+ CGLPixelFormatObj pixelFormatObj = 0;
+ GLint numPixelFormats = 0;
+
+ // We will try:
+ //
+ // 1) 32 bit RGBA/32 bit depth/accelerated/supersampled
+ // 2) 32 bit RGBA/32 bit depth/accelerated
+ // 3) 32 bit RGBA/16 bit depth/accelerated
+ // 4) closest to 32 bit RGBA/16 bit depth/software renderer
+ //
+ // If none of that works, we simply fail and set m_contextObj to 0.
+
+ setPixelFormat(attribs, 32, 32, true, true, false);
+ CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
+ if (numPixelFormats == 0) {
+ setPixelFormat(attribs, 32, 32, true, false, false);
+ CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
+
+ if (numPixelFormats == 0) {
+ setPixelFormat(attribs, 32, 16, true, false, false);
+ CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
+
+ if (numPixelFormats == 0) {
+ setPixelFormat(attribs, 32, 16, false, false, true);
+ CGLChoosePixelFormat(attribs.data(), &pixelFormatObj, &numPixelFormats);
+
+ if (numPixelFormats == 0) {
+ // Could not find an acceptable renderer - fail
+ return;
+ }
+ }
+ }
+ }
+ CGLError err = CGLCreateContext(pixelFormatObj, 0, &m_contextObj);
CGLDestroyPixelFormat(pixelFormatObj);
+ if (err != kCGLNoError || !m_contextObj) {
+ // Could not create the context - fail
+ m_contextObj = 0;
+ return;
+ }
+
// Set the current context to the one given to us.
CGLSetCurrentContext(m_contextObj);
@@ -102,12 +165,14 @@ GraphicsContext3D::GraphicsContext3D()
GraphicsContext3D::~GraphicsContext3D()
{
- CGLSetCurrentContext(m_contextObj);
- ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
- ::glDeleteTextures(1, &m_texture);
- ::glDeleteFramebuffersEXT(1, &m_fbo);
- CGLSetCurrentContext(0);
- CGLDestroyContext(m_contextObj);
+ if (m_contextObj) {
+ CGLSetCurrentContext(m_contextObj);
+ ::glDeleteRenderbuffersEXT(1, & m_depthBuffer);
+ ::glDeleteTextures(1, &m_texture);
+ ::glDeleteFramebuffersEXT(1, &m_fbo);
+ CGLSetCurrentContext(0);
+ CGLDestroyContext(m_contextObj);
+ }
}
void GraphicsContext3D::checkError() const
@@ -135,7 +200,7 @@ void GraphicsContext3D::endPaint()
void GraphicsContext3D::reshape(int width, int height)
{
- if (width == m_currentWidth && height == m_currentHeight)
+ if (width == m_currentWidth && height == m_currentHeight || !m_contextObj)
return;
m_currentWidth = width;
@@ -167,6 +232,9 @@ void GraphicsContext3D::reshape(int width, int height)
static inline void ensureContext(CGLContextObj context)
{
+ if (!context)
+ return;
+
CGLContextObj currentContext = CGLGetCurrentContext();
if (currentContext != context)
CGLSetCurrentContext(context);
@@ -442,6 +510,46 @@ void GraphicsContext3D::generateMipmap(unsigned long target)
::glGenerateMipmapEXT(target);
}
+bool GraphicsContext3D::getActiveAttrib(CanvasProgram* program, unsigned long index, ActiveInfo& info)
+{
+ if (!program->object())
+ return false;
+ ensureContext(m_contextObj);
+ GLint maxAttributeSize = 0;
+ ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttributeSize);
+ GLchar name[maxAttributeSize]; // GL_ACTIVE_ATTRIBUTE_MAX_LENGTH includes null termination
+ GLsizei nameLength = 0;
+ GLint size = 0;
+ GLenum type = 0;
+ ::glGetActiveAttrib(static_cast<GLuint>(program->object()), index, maxAttributeSize, &nameLength, &size, &type, name);
+ if (!nameLength)
+ return false;
+ info.name = String(name, nameLength);
+ info.type = type;
+ info.size = size;
+ return true;
+}
+
+bool GraphicsContext3D::getActiveUniform(CanvasProgram* program, unsigned long index, ActiveInfo& info)
+{
+ if (!program->object())
+ return false;
+ ensureContext(m_contextObj);
+ GLint maxUniformSize = 0;
+ ::glGetProgramiv(static_cast<GLuint>(program->object()), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformSize);
+ GLchar name[maxUniformSize]; // GL_ACTIVE_UNIFORM_MAX_LENGTH includes null termination
+ GLsizei nameLength = 0;
+ GLint size = 0;
+ GLenum type = 0;
+ ::glGetActiveUniform(static_cast<GLuint>(program->object()), index, maxUniformSize, &nameLength, &size, &type, name);
+ if (!nameLength)
+ return false;
+ info.name = String(name, nameLength);
+ info.type = type;
+ info.size = size;
+ return true;
+}
+
int GraphicsContext3D::getAttribLocation(CanvasProgram* program, const String& name)
{
if (!program)
@@ -556,6 +664,22 @@ void GraphicsContext3D::polygonOffset(double factor, double units)
::glPolygonOffset(static_cast<float>(factor), static_cast<float>(units));
}
+PassRefPtr<CanvasArray> GraphicsContext3D::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type)
+{
+ ensureContext(m_contextObj);
+
+ // FIXME: For now we only accept GL_UNSIGNED_BYTE/GL_RGBA. In reality OpenGL ES 2.0 accepts that pair and one other
+ // as specified by GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE. But for now we will
+ // not accept those.
+ // FIXME: Also, we should throw when an unacceptable value is passed
+ if (type != GL_UNSIGNED_BYTE || format != GL_RGBA)
+ return 0;
+
+ RefPtr<CanvasUnsignedByteArray> array = CanvasUnsignedByteArray::create(width * height * 4);
+ ::glReadPixels(x, y, width, height, format, type, (GLvoid*) array->data());
+ return array;
+}
+
void GraphicsContext3D::releaseShaderCompiler()
{
// FIXME: This is not implemented on desktop OpenGL. We need to have ifdefs for the different GL variants
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
index d0e1108..8cf51b4 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h
@@ -110,10 +110,8 @@ public:
virtual PlatformLayer* platformLayer() const;
-#ifndef NDEBUG
virtual void setDebugBackgroundColor(const Color&);
virtual void setDebugBorder(const Color&, float borderWidth);
-#endif
virtual void setGeometryOrientation(CompositingCoordinatesOrientation);
diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
index e9960f1..b351956 100644
--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm
@@ -274,7 +274,6 @@ static CAMediaTimingFunction* getCAMediaTimingFunction(const TimingFunction& tim
return 0;
}
-#ifndef NDEBUG
static void setLayerBorderColor(PlatformLayer* layer, const Color& color)
{
CGColorRef borderColor = createCGColor(color);
@@ -286,7 +285,6 @@ static void clearBorderColor(PlatformLayer* layer)
{
[layer setBorderColor:nil];
}
-#endif
static void setLayerBackgroundColor(PlatformLayer* layer, const Color& color)
{
@@ -317,7 +315,6 @@ GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayer::compositingCoord
return CompositingCoordinatesBottomUp;
}
-#ifndef NDEBUG
bool GraphicsLayer::showDebugBorders()
{
static bool showDebugBorders = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreLayerBorders"];
@@ -329,7 +326,6 @@ bool GraphicsLayer::showRepaintCounter()
static bool showRepaintCounter = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebCoreLayerRepaintCounter"];
return showRepaintCounter;
}
-#endif
static NSDictionary* nullActionsDictionary()
{
@@ -373,9 +369,7 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client)
setContentsOrientation(defaultContentsOrientation());
#endif
-#ifndef NDEBUG
updateDebugIndicators();
-#endif
m_animationDelegate.adoptNS([[WebAnimationDelegate alloc] init]);
[m_animationDelegate.get() setLayer:this];
@@ -964,9 +958,7 @@ void GraphicsLayerCA::updateChildrenTransform()
void GraphicsLayerCA::updateMasksToBounds()
{
[m_layer.get() setMasksToBounds:m_masksToBounds];
-#ifndef NDEBUG
updateDebugIndicators();
-#endif
}
void GraphicsLayerCA::updateContentsOpaque()
@@ -1051,9 +1043,7 @@ void GraphicsLayerCA::updateLayerDrawsContent()
else
[m_layer.get() setContents:nil];
-#ifndef NDEBUG
updateDebugIndicators();
-#endif
}
void GraphicsLayerCA::updateLayerBackgroundColor()
@@ -1245,6 +1235,21 @@ void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedP
[layer addAnimation:caAnim forKey:animationName];
}
+// Workaround for <rdar://problem/7311367>
+static void bug7311367Workaround(CALayer* transformLayer, const TransformationMatrix& transform)
+{
+ if (!transformLayer)
+ return;
+
+ CATransform3D caTransform;
+ copyTransform(caTransform, transform);
+ caTransform.m41 += 1;
+ [transformLayer setTransform:caTransform];
+
+ caTransform.m41 -= 1;
+ [transformLayer setTransform:caTransform];
+}
+
bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, int index)
{
PlatformLayer* layer = animatedLayer(property);
@@ -1255,10 +1260,11 @@ bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, int
return false;
[layer removeAnimationForKey:animationName];
+
+ bug7311367Workaround(m_transformLayer.get(), m_transform);
return true;
}
-
static void copyAnimationProperties(CAPropertyAnimation* from, CAPropertyAnimation* to)
{
[to setBeginTime:[from beginTime]];
@@ -1679,7 +1685,6 @@ PlatformLayer* GraphicsLayerCA::platformLayer() const
return primaryLayer();
}
-#ifndef NDEBUG
void GraphicsLayerCA::setDebugBackgroundColor(const Color& color)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS
@@ -1706,7 +1711,6 @@ void GraphicsLayerCA::setDebugBorder(const Color& color, float borderWidth)
END_BLOCK_OBJC_EXCEPTIONS
}
-#endif // NDEBUG
bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const
{
@@ -1784,9 +1788,7 @@ void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer)
// need to tell new layer to draw itself
setNeedsDisplay();
-#ifndef NDEBUG
updateDebugIndicators();
-#endif
}
GraphicsLayer::CompositingCoordinatesOrientation GraphicsLayerCA::defaultContentsOrientation() const
@@ -1830,12 +1832,10 @@ void GraphicsLayerCA::setupContentsLayer(CALayer* contentsLayer)
} else
[contentsLayer setAnchorPoint:CGPointZero];
-#ifndef NDEBUG
if (showDebugBorders()) {
setLayerBorderColor(contentsLayer, Color(0, 0, 128, 180));
[contentsLayer setBorderWidth:1.0f];
}
-#endif
}
void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity)
diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm
index 2647466..56b28e6 100644
--- a/WebCore/platform/graphics/mac/WebLayer.mm
+++ b/WebCore/platform/graphics/mac/WebLayer.mm
@@ -80,7 +80,6 @@ using namespace WebCore;
}
#endif
-#ifndef NDEBUG
if (layerContents->showRepaintCounter()) {
bool isTiledLayer = [layer isKindOfClass:[CATiledLayer class]];
@@ -107,7 +106,6 @@ using namespace WebCore;
CGContextRestoreGState(context);
}
-#endif
CGContextRestoreGState(context);
}
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index fa7b070..57a481a 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -1053,6 +1053,11 @@ void GraphicsContext::clip(const Path& path)
m_data->p()->setClipPath(*path.platformPath(), Qt::IntersectClip);
}
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
void GraphicsContext::clipOut(const Path& path)
{
if (paintingDisabled())
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index 3a27fe3..f8403b7 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -43,22 +43,13 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data)
if (data.size() < 4)
return 0;
- QByteArray bytes = QByteArray::fromRawData(data.data(), data.size());
- QBuffer buffer(&bytes);
- if (!buffer.open(QBuffer::ReadOnly))
- return 0;
-
- QByteArray imageFormat = QImageReader::imageFormat(&buffer);
- if (imageFormat.isEmpty())
- return 0; // Image format not supported
-
- return new ImageDecoderQt(imageFormat);
+ return new ImageDecoderQt;
}
-ImageDecoderQt::ImageDecoderQt(const QByteArray& imageFormat)
- : m_buffer(0)
+ImageDecoderQt::ImageDecoderQt()
+ : m_buffer(0)
, m_reader(0)
- , m_repetitionCount(-1)
+ , m_repetitionCount(cAnimationNone)
{
}
@@ -73,13 +64,13 @@ void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived)
if (m_failed)
return;
- // Cache our own new data.
- ImageDecoder::setData(data, allDataReceived);
-
// No progressive loading possible
if (!allDataReceived)
return;
+ // Cache our own new data.
+ ImageDecoder::setData(data, allDataReceived);
+
// We expect to be only called once with allDataReceived
ASSERT(!m_buffer);
ASSERT(!m_reader);
@@ -89,15 +80,12 @@ void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived)
m_buffer = new QBuffer;
m_buffer->setData(imageData);
m_buffer->open(QBuffer::ReadOnly);
- m_reader = new QImageReader(m_buffer);
-
- if (!m_reader->canRead())
- failRead();
+ m_reader = new QImageReader(m_buffer, m_format);
}
bool ImageDecoderQt::isSizeAvailable()
{
- if (!m_failed && !ImageDecoder::isSizeAvailable() && m_reader)
+ if (!ImageDecoder::isSizeAvailable() && m_reader)
internalDecodeSize();
return ImageDecoder::isSizeAvailable();
@@ -134,14 +122,16 @@ int ImageDecoderQt::repetitionCount() const
String ImageDecoderQt::filenameExtension() const
{
- return m_format;
+ return String(m_format.constData(), m_format.length());
};
RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index)
{
- // this information might not have been set
+ // In case the ImageDecoderQt got recreated we don't know
+ // yet how many images we are going to have and need to
+ // find that out now.
int count = m_frameBufferCache.size();
- if (count == 0) {
+ if (!m_failed && count == 0) {
internalDecodeSize();
count = frameCount();
}
@@ -171,7 +161,12 @@ void ImageDecoderQt::internalDecodeSize()
{
ASSERT(m_reader);
+ // If we have a QSize() something failed
QSize size = m_reader->size();
+ if (size.isEmpty())
+ return failRead();
+
+ m_format = m_reader->format();
setSize(size.width(), size.height());
}
@@ -213,9 +208,15 @@ void ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
buffer->setDecodedImage(img);
}
-// We will parse everything and we have no idea how
-// many images we have... We will have to find out the
-// hard way.
+// The QImageIOHandler is not able to tell us how many frames
+// we have and we need to parse every image. We do this by
+// increasing the m_frameBufferCache by one and try to parse
+// the image. We stop when QImage::read fails and then need
+// to resize the m_frameBufferCache to the final size and update
+// the m_failed. In case we failed to decode the first image
+// we want to keep m_failed set to true.
+
+// TODO: Do not increment the m_frameBufferCache.size() by one but more than one
void ImageDecoderQt::forceLoadEverything()
{
int imageCount = 0;
@@ -225,9 +226,12 @@ void ImageDecoderQt::forceLoadEverything()
internalHandleCurrentImage(imageCount - 1);
} while(!m_failed);
- // reset the failed state and resize the vector...
+ // If we failed decoding the first image we actually
+ // have no images and need to keep m_failed set to
+ // true otherwise we want to reset it and forget about
+ // the last attempt to decode a image.
m_frameBufferCache.resize(imageCount - 1);
- m_failed = false;
+ m_failed = imageCount == 1;
}
void ImageDecoderQt::failRead()
diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.h b/WebCore/platform/graphics/qt/ImageDecoderQt.h
index 7b3b686..d11b938 100644
--- a/WebCore/platform/graphics/qt/ImageDecoderQt.h
+++ b/WebCore/platform/graphics/qt/ImageDecoderQt.h
@@ -40,7 +40,7 @@ namespace WebCore {
class ImageDecoderQt : public ImageDecoder
{
public:
- ImageDecoderQt(const QByteArray& imageFormat);
+ ImageDecoderQt();
~ImageDecoderQt();
virtual void setData(SharedBuffer* data, bool allDataReceived);
@@ -65,7 +65,7 @@ private:
void failRead();
private:
- String m_format;
+ QByteArray m_format;
QBuffer* m_buffer;
QImageReader* m_reader;
mutable int m_repetitionCount;
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index c9f1349..889c41b 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -296,7 +296,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
r.inset(SkIntToScalar(thickness), SkIntToScalar(thickness));
path.addOval(r, SkPath::kCCW_Direction);
}
- platformContext()->canvas()->clipPath(path);
+ platformContext()->clipPathAntiAliased(path);
}
void GraphicsContext::addPath(const Path& path)
@@ -356,6 +356,18 @@ void GraphicsContext::clip(const Path& path)
if (!isPathSkiaSafe(getCTM(), p))
return;
+ platformContext()->clipPathAntiAliased(p);
+}
+
+void GraphicsContext::canvasClip(const Path& path)
+{
+ if (paintingDisabled())
+ return;
+
+ const SkPath& p = *path.platformPath();
+ if (!isPathSkiaSafe(getCTM(), p))
+ return;
+
platformContext()->canvas()->clipPath(p);
}
@@ -407,7 +419,7 @@ void GraphicsContext::clipPath(WindRule clipRule)
return;
path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
- platformContext()->canvas()->clipPath(path);
+ platformContext()->clipPathAntiAliased(path);
}
void GraphicsContext::clipToImageBuffer(const FloatRect& rect,
diff --git a/WebCore/platform/graphics/skia/PathSkia.cpp b/WebCore/platform/graphics/skia/PathSkia.cpp
index 5ac14b9..2cbb759 100644
--- a/WebCore/platform/graphics/skia/PathSkia.cpp
+++ b/WebCore/platform/graphics/skia/PathSkia.cpp
@@ -123,26 +123,31 @@ void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlo
SkScalar cx = WebCoreFloatToSkScalar(p.x());
SkScalar cy = WebCoreFloatToSkScalar(p.y());
SkScalar radius = WebCoreFloatToSkScalar(r);
+ SkScalar s360 = SkIntToScalar(360);
SkRect oval;
oval.set(cx - radius, cy - radius, cx + radius, cy + radius);
float sweep = ea - sa;
- // check for a circle
- if (sweep >= 2 * piFloat || sweep <= -2 * piFloat)
+ SkScalar startDegrees = WebCoreFloatToSkScalar(sa * 180 / piFloat);
+ SkScalar sweepDegrees = WebCoreFloatToSkScalar(sweep * 180 / piFloat);
+ // Check for a circle.
+ if (sweepDegrees >= s360 || sweepDegrees <= -s360) {
+ // Move to the start position (0 sweep means we add a single point).
+ m_path->arcTo(oval, startDegrees, 0, false);
+ // Draw the circle.
m_path->addOval(oval);
- else {
- SkScalar startDegrees = WebCoreFloatToSkScalar(sa * 180 / piFloat);
- SkScalar sweepDegrees = WebCoreFloatToSkScalar(sweep * 180 / piFloat);
-
+ // Force a moveTo the end position.
+ m_path->arcTo(oval, startDegrees + sweepDegrees, 0, true);
+ } else {
// Counterclockwise arcs should be drawn with negative sweeps, while
// clockwise arcs should be drawn with positive sweeps. Check to see
// if the situation is reversed and correct it by adding or subtracting
// a full circle
if (anticlockwise && sweepDegrees > 0) {
- sweepDegrees -= SkIntToScalar(360);
+ sweepDegrees -= s360;
} else if (!anticlockwise && sweepDegrees < 0) {
- sweepDegrees += SkIntToScalar(360);
+ sweepDegrees += s360;
}
m_path->arcTo(oval, startDegrees, sweepDegrees, false);
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 1fb62fc..a079da0 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -45,6 +45,7 @@
#include "SkDashPathEffect.h"
#include <wtf/MathExtras.h>
+#include <wtf/Vector.h>
namespace WebCore
{
@@ -95,6 +96,10 @@ struct PlatformContextSkia::State {
WebCore::FloatRect m_clip;
#endif
+ // This is a list of clipping paths which are currently active, in the
+ // order in which they were pushed.
+ WTF::Vector<SkPath> m_antiAliasClipPaths;
+
private:
// Not supported.
void operator=(const State&);
@@ -110,8 +115,8 @@ PlatformContextSkia::State::State()
, m_fillShader(0)
, m_strokeStyle(WebCore::SolidStroke)
, m_strokeColor(WebCore::Color::black)
- , m_strokeThickness(0)
, m_strokeShader(0)
+ , m_strokeThickness(0)
, m_dashRatio(3)
, m_miterLimit(4)
, m_lineCap(SkPaint::kDefault_Cap)
@@ -130,8 +135,8 @@ PlatformContextSkia::State::State(const State& other)
, m_fillShader(other.m_fillShader)
, m_strokeStyle(other.m_strokeStyle)
, m_strokeColor(other.m_strokeColor)
- , m_strokeThickness(other.m_strokeThickness)
, m_strokeShader(other.m_strokeShader)
+ , m_strokeThickness(other.m_strokeThickness)
, m_dashRatio(other.m_dashRatio)
, m_miterLimit(other.m_miterLimit)
, m_lineCap(other.m_lineCap)
@@ -249,6 +254,21 @@ void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rec
}
#endif
+void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
+{
+ // If we are currently tracking any anti-alias clip paths, then we already
+ // have a layer in place and don't need to add another.
+ bool haveLayerOutstanding = m_state->m_antiAliasClipPaths.size();
+
+ // See comments in applyAntiAliasedClipPaths about how this works.
+ m_state->m_antiAliasClipPaths.append(clipPath);
+
+ if (!haveLayerOutstanding) {
+ SkRect bounds = clipPath.getBounds();
+ canvas()->saveLayerAlpha(&bounds, 255, static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag));
+ }
+}
+
void PlatformContextSkia::restore()
{
#if defined(__linux__) || PLATFORM(WIN_OS)
@@ -258,6 +278,9 @@ void PlatformContextSkia::restore()
}
#endif
+ if (!m_state->m_antiAliasClipPaths.isEmpty())
+ applyAntiAliasedClipPaths(m_state->m_antiAliasClipPaths);
+
m_stateStack.removeLast();
m_state = &m_stateStack.last();
@@ -549,3 +572,40 @@ void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, con
m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint);
}
#endif
+
+void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
+{
+ // Anti-aliased clipping:
+ //
+ // Skia's clipping is 1-bit only. Consider what would happen if it were 8-bit:
+ // We have a square canvas, filled with white and we declare a circular
+ // clipping path. Then we fill twice with a black rectangle. The fractional
+ // pixels would first get the correct color (white * alpha + black * (1 -
+ // alpha)), but the second fill would apply the alpha to the already
+ // modified color and the result would be too dark.
+ //
+ // This, anti-aliased clipping needs to be performed after the drawing has
+ // been done. In order to do this, we create a new layer of the canvas in
+ // clipPathAntiAliased and store the clipping path. All drawing is done to
+ // the layer's bitmap while it's in effect. When WebKit calls restore() to
+ // undo the clipping, this function is called.
+ //
+ // Here, we walk the list of clipping paths backwards and, for each, we
+ // clear outside of the clipping path. We only need a single extra layer
+ // for any number of clipping paths.
+ //
+ // When we call restore on the SkCanvas, the layer's bitmap is composed
+ // into the layer below and we end up with correct, anti-aliased clipping.
+
+ SkPaint paint;
+ paint.setXfermodeMode(SkXfermode::kClear_Mode);
+ paint.setAntiAlias(true);
+ paint.setStyle(SkPaint::kFill_Style);
+
+ for (size_t i = paths.size() - 1; i < paths.size(); --i) {
+ paths[i].setFillType(SkPath::kInverseWinding_FillType);
+ m_canvas->drawPath(paths[i], paint);
+ }
+
+ m_canvas->restore();
+}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 0c87fc2..53590bf 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -92,6 +92,7 @@ public:
void beginLayerClippedToImage(const WebCore::FloatRect&,
const WebCore::ImageBuffer*);
#endif
+ void clipPathAntiAliased(const SkPath&);
// Sets up the common flags on a paint for antialiasing, effects, etc.
// This is implicitly called by setupPaintFill and setupPaintStroke, but
@@ -172,6 +173,7 @@ private:
// m_canvas that are also in imageBuffer.
void applyClipFromImage(const WebCore::FloatRect&, const SkBitmap&);
#endif
+ void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
// Defines drawing style.
struct State;
diff --git a/WebCore/platform/graphics/skia/SkiaUtils.cpp b/WebCore/platform/graphics/skia/SkiaUtils.cpp
index bb15aa2..377ca06 100644
--- a/WebCore/platform/graphics/skia/SkiaUtils.cpp
+++ b/WebCore/platform/graphics/skia/SkiaUtils.cpp
@@ -200,8 +200,13 @@ bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::
SkRect bounds = originalPath->getBounds();
- // We can immediately return false if the point is outside the bounding rect
- if (!bounds.contains(SkFloatToScalar(point.x()), SkFloatToScalar(point.y())))
+ // We can immediately return false if the point is outside the bounding
+ // rect. We don't use bounds.contains() here, since it would exclude
+ // points on the right and bottom edges of the bounding rect, and we want
+ // to include them.
+ SkScalar fX = SkFloatToScalar(point.x());
+ SkScalar fY = SkFloatToScalar(point.y());
+ if (fX < bounds.fLeft || fX > bounds.fRight || fY < bounds.fTop || fY > bounds.fBottom)
return false;
originalPath->setFillType(ft);
@@ -225,7 +230,7 @@ bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::
int x = static_cast<int>(floorf(point.x() / scale));
int y = static_cast<int>(floorf(point.y() / scale));
- clip.setRect(x, y, x + 1, y + 1);
+ clip.setRect(x - 1, y - 1, x + 1, y + 1);
bool contains = rgn.setPath(*path, clip);
diff --git a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
index 26b22af..e845d85 100644
--- a/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
+++ b/WebCore/platform/graphics/win/SimpleFontDataCairoWin.cpp
@@ -34,11 +34,11 @@
#include "Font.h"
#include "FontCache.h"
#include "FontDescription.h"
-#include "MathExtras.h"
#include <cairo.h>
#include <cairo-win32.h>
#include <mlang.h>
#include <tchar.h>
+#include <wtf/MathExtras.h>
namespace WebCore {
diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
index c114c0e..f308840 100644
--- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
+++ b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
@@ -1219,6 +1219,11 @@ void GraphicsContext::clip(const Path& path)
notImplemented();
}
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
void GraphicsContext::clipOut(const Path&)
{
notImplemented();
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 686fb07..39f14f4 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -344,6 +344,11 @@ void GraphicsContext::clip(const Path&)
notImplemented();
}
+void GraphicsContext::canvasClip(const Path& path)
+{
+ clip(path);
+}
+
void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
{
notImplemented();
diff --git a/WebCore/platform/gtk/KeyEventGtk.cpp b/WebCore/platform/gtk/KeyEventGtk.cpp
index 4186c2f..3931eff 100644
--- a/WebCore/platform/gtk/KeyEventGtk.cpp
+++ b/WebCore/platform/gtk/KeyEventGtk.cpp
@@ -200,6 +200,7 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode)
case GDK_Control_R:
return VK_CONTROL; // (11) CTRL key
case GDK_Menu:
+ return VK_APPS; // (5D) Applications key (Natural keyboard)
case GDK_Alt_L:
case GDK_Alt_R:
return VK_MENU; // (12) ALT key
@@ -370,7 +371,6 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode)
return VK_LWIN; // (5B) Left Windows key (Microsoft Natural keyboard)
case GDK_Meta_R:
return VK_RWIN; // (5C) Right Windows key (Natural keyboard)
- // VK_APPS (5D) Applications key (Natural keyboard)
// VK_SLEEP (5F) Computer Sleep key
// VK_SEPARATOR (6C) Separator key
// VK_SUBTRACT (6D) Subtract key
diff --git a/WebCore/platform/gtk/Language.cpp b/WebCore/platform/gtk/Language.cpp
index 171cd84..fea2df6 100644
--- a/WebCore/platform/gtk/Language.cpp
+++ b/WebCore/platform/gtk/Language.cpp
@@ -21,16 +21,37 @@
#include "Language.h"
#include "CString.h"
+#include "GOwnPtr.h"
#include "PlatformString.h"
#include <gtk/gtk.h>
+#include <locale.h>
#include <pango/pango.h>
namespace WebCore {
+// Using pango_language_get_default() here is not an option, because
+// it doesn't support changing the locale in runtime, so it returns
+// always the same value.
String defaultLanguage()
{
- return pango_language_to_string(gtk_get_default_language());
+ char* localeDefault = setlocale(LC_CTYPE, NULL);
+
+ if (!localeDefault)
+ return String("c");
+
+ GOwnPtr<gchar> normalizedDefault(g_ascii_strdown(localeDefault, -1));
+ char* ptr = strchr(normalizedDefault.get(), '_');
+
+ if(ptr)
+ *ptr = '-';
+
+ ptr = strchr(normalizedDefault.get(), '.');
+
+ if(ptr)
+ *ptr = '\0';
+
+ return String(normalizedDefault.get());
}
}
diff --git a/WebCore/platform/mac/ClipboardMac.mm b/WebCore/platform/mac/ClipboardMac.mm
index 78fb659..f4321ad 100644
--- a/WebCore/platform/mac/ClipboardMac.mm
+++ b/WebCore/platform/mac/ClipboardMac.mm
@@ -107,11 +107,15 @@ static String utiTypeFromCocoaType(NSString *type)
static void addHTMLClipboardTypesForCocoaType(HashSet<String>& resultTypes, NSString *cocoaType, NSPasteboard *pasteboard)
{
// UTI may not do these right, so make sure we get the right, predictable result
- if ([cocoaType isEqualToString:NSStringPboardType])
+ if ([cocoaType isEqualToString:NSStringPboardType]) {
resultTypes.add("text/plain");
- else if ([cocoaType isEqualToString:NSURLPboardType])
+ return;
+ }
+ if ([cocoaType isEqualToString:NSURLPboardType]) {
resultTypes.add("text/uri-list");
- else if ([cocoaType isEqualToString:NSFilenamesPboardType]) {
+ return;
+ }
+ if ([cocoaType isEqualToString:NSFilenamesPboardType]) {
// If file list is empty, add nothing.
// Note that there is a chance that the file list count could have changed since we grabbed the types array.
// However, this is not really an issue for us doing a sanity check here.
@@ -122,12 +126,15 @@ static void addHTMLClipboardTypesForCocoaType(HashSet<String>& resultTypes, NSSt
resultTypes.add("text/uri-list");
resultTypes.add("Files");
}
- } else if (String utiType = utiTypeFromCocoaType(cocoaType))
+ return;
+ }
+ String utiType = utiTypeFromCocoaType(cocoaType);
+ if (!utiType.isEmpty()) {
resultTypes.add(utiType);
- else {
- // No mapping, just pass the whole string though
- resultTypes.add(cocoaType);
+ return;
}
+ // No mapping, just pass the whole string though
+ resultTypes.add(cocoaType);
}
void ClipboardMac::clearData(const String& type)
diff --git a/WebCore/platform/network/Credential.cpp b/WebCore/platform/network/Credential.cpp
index caca785..f905743 100644
--- a/WebCore/platform/network/Credential.cpp
+++ b/WebCore/platform/network/Credential.cpp
@@ -32,6 +32,7 @@ namespace WebCore {
Credential::Credential()
: m_user("")
, m_password("")
+ , m_persistence(CredentialPersistenceNone)
{
}
@@ -44,7 +45,7 @@ Credential::Credential(const String& user, const String& password, CredentialPer
{
}
-bool Credential::isEmpty()
+bool Credential::isEmpty() const
{
return m_user.isEmpty() && m_password.isEmpty();
}
diff --git a/WebCore/platform/network/Credential.h b/WebCore/platform/network/Credential.h
index ca4a45a..0471fbc 100644
--- a/WebCore/platform/network/Credential.h
+++ b/WebCore/platform/network/Credential.h
@@ -41,7 +41,7 @@ public:
Credential();
Credential(const String& user, const String& password, CredentialPersistence);
- bool isEmpty();
+ bool isEmpty() const;
const String& user() const;
const String& password() const;
diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp
index 407ed5b..ec78372 100644
--- a/WebCore/platform/network/CredentialStorage.cpp
+++ b/WebCore/platform/network/CredentialStorage.cpp
@@ -43,13 +43,19 @@ static ProtectionSpaceToCredentialMap& protectionSpaceToCredentialMap()
return map;
}
-typedef HashMap<String, HashMap<String, Credential> > OriginToDefaultBasicCredentialMap;
-static OriginToDefaultBasicCredentialMap& originToDefaultBasicCredentialMap()
+static HashSet<String>& originsWithCredentials()
{
- DEFINE_STATIC_LOCAL(OriginToDefaultBasicCredentialMap, map, ());
+ DEFINE_STATIC_LOCAL(HashSet<String>, set, ());
+ return set;
+}
+
+typedef HashMap<String, ProtectionSpace> PathToDefaultProtectionSpaceMap;
+static PathToDefaultProtectionSpaceMap& pathToDefaultProtectionSpaceMap()
+{
+ DEFINE_STATIC_LOCAL(PathToDefaultProtectionSpaceMap, map, ());
return map;
}
-
+
static String originStringFromURL(const KURL& url)
{
if (url.port())
@@ -58,32 +64,37 @@ static String originStringFromURL(const KURL& url)
return url.protocol() + "://" + url.host() + "/";
}
+static String protectionSpaceMapKeyFromURL(const KURL& url)
+{
+ ASSERT(url.isValid());
+
+ // Remove the last path component that is not a directory to determine the subtree for which credentials will apply.
+ // We keep a leading slash, but remove a trailing one.
+ String directoryURL = url.string().substring(0, url.pathEnd());
+ unsigned directoryURLPathStart = url.pathStart();
+ ASSERT(directoryURL[directoryURLPathStart] == '/');
+ if (directoryURL.length() > directoryURLPathStart + 1) {
+ int index = directoryURL.reverseFind('/');
+ ASSERT(index > 0);
+ directoryURL = directoryURL.substring(0, (static_cast<unsigned>(index) != directoryURLPathStart) ? index : directoryURLPathStart + 1);
+ }
+ ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/');
+
+ return directoryURL;
+}
+
void CredentialStorage::set(const Credential& credential, const ProtectionSpace& protectionSpace, const KURL& url)
{
ASSERT(url.protocolInHTTPFamily());
ASSERT(url.isValid());
protectionSpaceToCredentialMap().set(protectionSpace, credential);
-
+ originsWithCredentials().add(originStringFromURL(url));
+
ProtectionSpaceAuthenticationScheme scheme = protectionSpace.authenticationScheme();
- if (url.protocolInHTTPFamily() && (scheme == ProtectionSpaceAuthenticationSchemeHTTPBasic || scheme == ProtectionSpaceAuthenticationSchemeDefault)) {
- String origin = originStringFromURL(url);
-
- HashMap<String, Credential> pathToCredentialMap;
- pair<HashMap<String, HashMap<String, Credential> >::iterator, bool> result = originToDefaultBasicCredentialMap().add(origin, pathToCredentialMap);
-
- // Remove the last path component that is not a directory to determine the subpath for which this credential applies.
- // We keep a leading slash, but remove a trailing one.
- String path = url.path();
- ASSERT(path.length() > 0);
- ASSERT(path[0] == '/');
- if (path.length() > 1) {
- int index = path.reverseFind('/');
- path = path.substring(0, index ? index : 1);
- }
- ASSERT(path.length() == 1 || path[path.length() - 1] != '/');
-
- result.first->second.set(path, credential);
+ if (scheme == ProtectionSpaceAuthenticationSchemeHTTPBasic || scheme == ProtectionSpaceAuthenticationSchemeDefault) {
+ // The map can contain both a path and its subpath - while redundant, this makes lookups faster.
+ pathToDefaultProtectionSpaceMap().set(protectionSpaceMapKeyFromURL(url), protectionSpace);
}
}
@@ -92,33 +103,53 @@ Credential CredentialStorage::get(const ProtectionSpace& protectionSpace)
return protectionSpaceToCredentialMap().get(protectionSpace);
}
-Credential CredentialStorage::getDefaultAuthenticationCredential(const KURL& url)
+static PathToDefaultProtectionSpaceMap::iterator findDefaultProtectionSpaceForURL(const KURL& url)
{
ASSERT(url.protocolInHTTPFamily());
- String origin = originStringFromURL(url);
- const HashMap<String, Credential>& pathToCredentialMap(originToDefaultBasicCredentialMap().get(origin));
- if (pathToCredentialMap.isEmpty())
- return Credential();
-
- // Check to see if there is a stored credential for the subpath ancestry of this url.
- String path = url.path();
- Credential credential = pathToCredentialMap.get(path);
- while (credential.isEmpty() && !path.isNull()) {
- int index = path.reverseFind('/');
- if (index == 0) {
- credential = pathToCredentialMap.get("/");
- break;
- } else if (index == -1) {
- // This case should never happen, as all HTTP URL paths should start with a leading /
- ASSERT_NOT_REACHED();
- credential = pathToCredentialMap.get(path);
- break;
- } else {
- path = path.substring(0, index);
- credential = pathToCredentialMap.get(path);
- }
+ ASSERT(url.isValid());
+
+ PathToDefaultProtectionSpaceMap& map = pathToDefaultProtectionSpaceMap();
+
+ // Don't spend time iterating the path for origins that don't have any credentials.
+ if (!originsWithCredentials().contains(originStringFromURL(url)))
+ return map.end();
+
+ String directoryURL = protectionSpaceMapKeyFromURL(url);
+ unsigned directoryURLPathStart = url.pathStart();
+ while (true) {
+ PathToDefaultProtectionSpaceMap::iterator iter = map.find(directoryURL);
+ if (iter != map.end())
+ return iter;
+
+ if (directoryURL.length() == directoryURLPathStart + 1) // path is "/" already, cannot shorten it any more
+ return map.end();
+
+ int index = directoryURL.reverseFind('/', -2);
+ ASSERT(index > 0);
+ directoryURL = directoryURL.substring(0, (static_cast<unsigned>(index) == directoryURLPathStart) ? index + 1 : index);
+ ASSERT(directoryURL.length() > directoryURLPathStart);
+ ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/');
}
- return credential;
+}
+
+bool CredentialStorage::set(const Credential& credential, const KURL& url)
+{
+ ASSERT(url.protocolInHTTPFamily());
+ ASSERT(url.isValid());
+ PathToDefaultProtectionSpaceMap::iterator iter = findDefaultProtectionSpaceForURL(url);
+ if (iter == pathToDefaultProtectionSpaceMap().end())
+ return false;
+ ASSERT(originsWithCredentials().contains(originStringFromURL(url)));
+ protectionSpaceToCredentialMap().set(iter->second, credential);
+ return true;
+}
+
+Credential CredentialStorage::get(const KURL& url)
+{
+ PathToDefaultProtectionSpaceMap::iterator iter = findDefaultProtectionSpaceForURL(url);
+ if (iter == pathToDefaultProtectionSpaceMap().end())
+ return Credential();
+ return protectionSpaceToCredentialMap().get(iter->second);
}
} // namespace WebCore
diff --git a/WebCore/platform/network/CredentialStorage.h b/WebCore/platform/network/CredentialStorage.h
index 737efa6..5086f69 100644
--- a/WebCore/platform/network/CredentialStorage.h
+++ b/WebCore/platform/network/CredentialStorage.h
@@ -36,7 +36,11 @@ class CredentialStorage {
public:
static void set(const Credential&, const ProtectionSpace&, const KURL&);
static Credential get(const ProtectionSpace&);
- static Credential getDefaultAuthenticationCredential(const KURL&);
+
+ // These methods work for authentication schemes that support sending credentials without waiting for a request. E.g., for HTTP Basic authentication scheme
+ // a client should assume that all paths at or deeper than the depth of a known protected resource share are within the same protection space.
+ static bool set(const Credential&, const KURL&); // Returns true if the URL corresponds to a known protection space, so credentials could be updated.
+ static Credential get(const KURL&);
};
} // namespace WebCore
diff --git a/WebCore/platform/network/FormDataBuilder.cpp b/WebCore/platform/network/FormDataBuilder.cpp
index 27bdee3..04c7527 100644
--- a/WebCore/platform/network/FormDataBuilder.cpp
+++ b/WebCore/platform/network/FormDataBuilder.cpp
@@ -108,6 +108,34 @@ static inline void append(Vector<char>& buffer, const CString& string)
buffer.append(string.data(), string.length());
}
+static void appendQuotedString(Vector<char>& buffer, const CString& string)
+{
+ // Append a string as a quoted value, escaping quotes and line breaks.
+ // FIXME: Is it correct to use percent escaping here? Other browsers do not encode these characters yet,
+ // so we should test popular servers to find out if there is an encoding form they can handle.
+ unsigned length = string.length();
+ for (unsigned i = 0; i < length; ++i) {
+ unsigned char c = string.data()[i];
+
+ switch (c) {
+ case 0x0a:
+ append(buffer, "%0A");
+ break;
+ case 0x0d:
+ append(buffer, "%0D");
+ break;
+ case '"':
+ append(buffer, "%22");
+ break;
+ case '%':
+ append(buffer, "%25");
+ break;
+ default:
+ append(buffer, c);
+ }
+ }
+}
+
Vector<char> FormDataBuilder::generateUniqueBoundaryString()
{
Vector<char> boundary;
@@ -161,8 +189,10 @@ void FormDataBuilder::beginMultiPartHeader(Vector<char>& buffer, const CString&
{
addBoundaryToMultiPartHeader(buffer, boundary);
+ // FIXME: This loses data irreversibly if the input name includes characters you can't encode
+ // in the website's character set.
append(buffer, "Content-Disposition: form-data; name=\"");
- append(buffer, name);
+ appendQuotedString(buffer, name);
append(buffer, '"');
}
@@ -179,12 +209,10 @@ void FormDataBuilder::addBoundaryToMultiPartHeader(Vector<char>& buffer, const C
void FormDataBuilder::addFilenameToMultiPartHeader(Vector<char>& buffer, const TextEncoding& encoding, const String& filename)
{
- // FIXME: This won't work if the filename includes a " mark,
- // or control characters like CR or LF. This also does strange
- // things if the filename includes characters you can't encode
+ // FIXME: This loses data irreversibly if the filename includes characters you can't encode
// in the website's character set.
append(buffer, "; filename=\"");
- append(buffer, encoding.encode(filename.characters(), filename.length(), QuestionMarksForUnencodables));
+ appendQuotedString(buffer, encoding.encode(filename.characters(), filename.length(), QuestionMarksForUnencodables));
append(buffer, '"');
}
diff --git a/WebCore/platform/network/ResourceRequestBase.cpp b/WebCore/platform/network/ResourceRequestBase.cpp
index ee11bcb..8ab72c1 100644
--- a/WebCore/platform/network/ResourceRequestBase.cpp
+++ b/WebCore/platform/network/ResourceRequestBase.cpp
@@ -218,6 +218,26 @@ void ResourceRequestBase::setHTTPHeaderField(const AtomicString& name, const Str
m_platformRequestUpdated = false;
}
+void ResourceRequestBase::clearHTTPReferrer()
+{
+ updateResourceRequest();
+
+ m_httpHeaderFields.remove("Referer");
+
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
+}
+
+void ResourceRequestBase::clearHTTPOrigin()
+{
+ updateResourceRequest();
+
+ m_httpHeaderFields.remove("Origin");
+
+ if (url().protocolInHTTPFamily())
+ m_platformRequestUpdated = false;
+}
+
void ResourceRequestBase::setResponseContentDispositionEncodingFallbackArray(const String& encoding1, const String& encoding2, const String& encoding3)
{
updateResourceRequest();
@@ -358,7 +378,11 @@ void ResourceRequestBase::updateResourceRequest() const
m_resourceRequestUpdated = true;
}
+<<<<<<< HEAD:WebCore/platform/network/ResourceRequestBase.cpp
#if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(ANDROID)
+=======
+#if !PLATFORM(MAC) && !USE(CFNETWORK) && !USE(SOUP) && !PLATFORM(CHROMIUM)
+>>>>>>> webkit.org at r50258.:WebCore/platform/network/ResourceRequestBase.cpp
unsigned initializeMaximumHTTPConnectionCountPerHost()
{
// This is used by the loader to control the number of issued parallel load requests.
diff --git a/WebCore/platform/network/ResourceRequestBase.h b/WebCore/platform/network/ResourceRequestBase.h
index 348e6b3..84a7bd0 100644
--- a/WebCore/platform/network/ResourceRequestBase.h
+++ b/WebCore/platform/network/ResourceRequestBase.h
@@ -88,11 +88,11 @@ namespace WebCore {
String httpReferrer() const { return httpHeaderField("Referer"); }
void setHTTPReferrer(const String& httpReferrer) { setHTTPHeaderField("Referer", httpReferrer); }
- void clearHTTPReferrer() { m_httpHeaderFields.remove("Referer"); }
+ void clearHTTPReferrer();
String httpOrigin() const { return httpHeaderField("Origin"); }
void setHTTPOrigin(const String& httpOrigin) { setHTTPHeaderField("Origin", httpOrigin); }
- void clearHTTPOrigin() { m_httpHeaderFields.remove("Origin"); }
+ void clearHTTPOrigin();
String httpUserAgent() const { return httpHeaderField("User-Agent"); }
void setHTTPUserAgent(const String& httpUserAgent) { setHTTPHeaderField("User-Agent", httpUserAgent); }
diff --git a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
index ea5fcc6..38a9705 100644
--- a/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
@@ -156,7 +156,11 @@ CFURLRequestRef willSendRequest(CFURLConnectionRef conn, CFURLRequestRef cfReque
}
if (request.isNull())
request = cfRequest;
-
+
+ // Should not set Referer after a redirect from a secure resource to non-secure one.
+ if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https"))
+ request.clearHTTPReferrer();
+
handle->willSendRequest(request, cfRedirectResponse);
if (request.isNull())
@@ -401,8 +405,18 @@ bool ResourceHandle::start(Frame* frame)
// <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
// try and reuse the credential preemptively, as allowed by RFC 2617.
- if (!client() || client()->shouldUseCredentialStorage(this) && d->m_request.url().protocolInHTTPFamily())
- d->m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(d->m_request.url());
+ if (!client() || client()->shouldUseCredentialStorage(this) && d->m_request.url().protocolInHTTPFamily()) {
+ if (d->m_user.isEmpty() && d->m_pass.isEmpty()) {
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ d->m_initialCredential = CredentialStorage::get(d->m_request.url());
+ } else {
+ // If there is already a protection space known for the URL, update stored credentials before sending a request.
+ // This makes it possible to implement logout by sending an XMLHttpRequest with known incorrect credentials, and aborting it immediately
+ // (so that an authentication dialog doesn't pop up).
+ CredentialStorage::set(Credential(d->m_user, d->m_pass, CredentialPersistenceNone), d->m_request.url());
+ }
+ }
if (!d->m_initialCredential.isEmpty()) {
String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
@@ -769,7 +783,7 @@ RetainPtr<CFDataRef> WebCoreSynchronousLoader::load(const ResourceRequest& reque
// try and reuse the credential preemptively, as allowed by RFC 2617.
ResourceRequest requestWithInitialCredential(request);
if (loader.m_allowStoredCredentials && url.protocolInHTTPFamily())
- loader.m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(url);
+ loader.m_initialCredential = CredentialStorage::get(url);
if (!loader.m_initialCredential.isEmpty()) {
String authHeader = "Basic " + encodeBasicAuthorization(loader.m_initialCredential.user(), loader.m_initialCredential.password());
diff --git a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
index bba3d3e..cc0220e 100644
--- a/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
+++ b/WebCore/platform/network/cf/ResourceRequestCFNet.cpp
@@ -39,9 +39,11 @@ typedef CFArrayRef (*CFURLRequestCopyContentDispositionEncodingFallbackArrayFunc
static HMODULE findCFNetworkModule()
{
- if (HMODULE module = GetModuleHandleA("CFNetwork"))
- return module;
+#ifndef DEBUG_ALL
+ return GetModuleHandleA("CFNetwork");
+#else
return GetModuleHandleA("CFNetwork_debug");
+#endif
}
static CFURLRequestSetContentDispositionEncodingFallbackArrayFunction findCFURLRequestSetContentDispositionEncodingFallbackArrayFunction()
@@ -76,11 +78,18 @@ CFURLRequestRef ResourceRequest::cfURLRequest() const
return m_cfRequest.get();
}
-static inline void addHeadersFromHashMap(CFMutableURLRequestRef request, const HTTPHeaderMap& requestHeaders)
+static inline void setHeaderFields(CFMutableURLRequestRef request, const HTTPHeaderMap& requestHeaders)
{
- if (!requestHeaders.size())
- return;
-
+ // Remove existing headers first, as some of them may no longer be present in the map.
+ RetainPtr<CFDictionaryRef> oldHeaderFields(AdoptCF, CFURLRequestCopyAllHTTPHeaderFields(request));
+ CFIndex oldHeaderFieldCount = CFDictionaryGetCount(oldHeaderFields.get());
+ if (oldHeaderFieldCount) {
+ Vector<CFStringRef> oldHeaderFieldNames(oldHeaderFieldCount);
+ CFDictionaryGetKeysAndValues(oldHeaderFields.get(), reinterpret_cast<const void**>(&oldHeaderFieldNames[0]), 0);
+ for (CFIndex i = 0; i < oldHeaderFieldCount; ++i)
+ CFURLRequestSetHTTPHeaderFieldValue(request, oldHeaderFieldNames[i], 0);
+ }
+
HTTPHeaderMap::const_iterator end = requestHeaders.end();
for (HTTPHeaderMap::const_iterator it = requestHeaders.begin(); it != end; ++it) {
CFStringRef key = it->first.createCFString();
@@ -110,7 +119,7 @@ void ResourceRequest::doUpdatePlatformRequest()
RetainPtr<CFStringRef> requestMethod(AdoptCF, httpMethod().createCFString());
CFURLRequestSetHTTPRequestMethod(cfRequest, requestMethod.get());
- addHeadersFromHashMap(cfRequest, httpHeaderFields());
+ setHeaderFields(cfRequest, httpHeaderFields());
WebCore::setHTTPBody(cfRequest, httpBody());
CFURLRequestSetShouldHandleHTTPCookies(cfRequest, allowCookies());
@@ -148,6 +157,7 @@ void ResourceRequest::doUpdateResourceRequest()
}
m_allowCookies = CFURLRequestShouldHandleHTTPCookies(m_cfRequest.get());
+ m_httpHeaderFields.clear();
if (CFDictionaryRef headers = CFURLRequestCopyAllHTTPHeaderFields(m_cfRequest.get())) {
CFIndex headerCount = CFDictionaryGetCount(headers);
Vector<const void*, 128> keys(headerCount);
diff --git a/WebCore/platform/network/chromium/ResourceRequest.cpp b/WebCore/platform/network/chromium/ResourceRequest.cpp
new file mode 100644
index 0000000..76d1288
--- /dev/null
+++ b/WebCore/platform/network/chromium/ResourceRequest.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Google, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ */
+
+namespace WebCore {
+
+// This is used by the loader to control the number of issued parallel load requests.
+unsigned initializeMaximumHTTPConnectionCountPerHost()
+{
+ return 6;
+}
+
+} // namespace WebCore
diff --git a/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
index 5469ec9..5464e07 100644
--- a/WebCore/platform/network/curl/ResourceHandleCurl.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleCurl.cpp
@@ -156,7 +156,7 @@ void ResourceHandle::setDefersLoading(bool defers)
if (d->m_defersLoading == defers)
return;
-#if LIBCURL_VERSION_NUM > 0x071200
+#if LIBCURL_VERSION_NUM > 0x071800
if (!d->m_handle)
d->m_defersLoading = defers;
else if (defers) {
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.cpp b/WebCore/platform/network/curl/ResourceHandleManager.cpp
index 14c6f31..d8a812f 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.cpp
+++ b/WebCore/platform/network/curl/ResourceHandleManager.cpp
@@ -409,6 +409,25 @@ void ResourceHandleManager::downloadTimerCallback(Timer<ResourceHandleManager>*
m_downloadTimer.startOneShot(pollTimeSeconds);
}
+void ResourceHandleManager::setProxyInfo(const String& host,
+ unsigned long port,
+ ProxyType type,
+ const String& username,
+ const String& password)
+{
+ m_proxyType = type;
+
+ if (!host.length()) {
+ m_proxy = String("");
+ } else {
+ String userPass;
+ if (username.length() || password.length())
+ userPass = username + ":" + password + "@";
+
+ m_proxy = String("http://") + userPass + host + ":" + String::number(port);
+ }
+}
+
void ResourceHandleManager::removeFromCurl(ResourceHandle* job)
{
ResourceHandleInternal* d = job->getInternal();
@@ -678,7 +697,7 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
d->m_handle = curl_easy_init();
-#if LIBCURL_VERSION_NUM > 0x071200
+#if LIBCURL_VERSION_NUM > 0x071800
if (d->m_defersLoading) {
CURLcode error = curl_easy_pause(d->m_handle, CURLPAUSE_ALL);
// If we did not pause the handle, we would ASSERT in the
@@ -753,6 +772,17 @@ void ResourceHandleManager::initializeHandle(ResourceHandle* job)
curl_easy_setopt(d->m_handle, CURLOPT_HTTPHEADER, headers);
d->m_customHeaders = headers;
}
+ // curl CURLOPT_USERPWD expects username:password
+ if (d->m_user.length() || d->m_pass.length()) {
+ String userpass = d->m_user + ":" + d->m_pass;
+ curl_easy_setopt(d->m_handle, CURLOPT_USERPWD, userpass.utf8().data());
+ }
+
+ // Set proxy options if we have them.
+ if (m_proxy.length()) {
+ curl_easy_setopt(d->m_handle, CURLOPT_PROXY, m_proxy.utf8().data());
+ curl_easy_setopt(d->m_handle, CURLOPT_PROXYTYPE, m_proxyType);
+ }
}
void ResourceHandleManager::cancel(ResourceHandle* job)
diff --git a/WebCore/platform/network/curl/ResourceHandleManager.h b/WebCore/platform/network/curl/ResourceHandleManager.h
index 89b27d7..4d73d87 100644
--- a/WebCore/platform/network/curl/ResourceHandleManager.h
+++ b/WebCore/platform/network/curl/ResourceHandleManager.h
@@ -28,8 +28,9 @@
#ifndef ResourceHandleManager_h
#define ResourceHandleManager_h
-#include "Frame.h"
#include "CString.h"
+#include "Frame.h"
+#include "PlatformString.h"
#include "Timer.h"
#include "ResourceHandleClient.h"
@@ -45,6 +46,13 @@ namespace WebCore {
class ResourceHandleManager {
public:
+ enum ProxyType {
+ HTTP = CURLPROXY_HTTP,
+ Socks4 = CURLPROXY_SOCKS4,
+ Socks4A = CURLPROXY_SOCKS4A,
+ Socks5 = CURLPROXY_SOCKS5,
+ Socks5Hostname = CURLPROXY_SOCKS5_HOSTNAME
+ };
static ResourceHandleManager* sharedInstance();
void add(ResourceHandle*);
void cancel(ResourceHandle*);
@@ -55,6 +63,12 @@ public:
void setupPOST(ResourceHandle*, struct curl_slist**);
void setupPUT(ResourceHandle*, struct curl_slist**);
+ void setProxyInfo(const String& host = "",
+ unsigned long port = 0,
+ ProxyType type = HTTP,
+ const String& username = "",
+ const String& password = "");
+
private:
ResourceHandleManager();
~ResourceHandleManager();
@@ -74,6 +88,9 @@ private:
Vector<ResourceHandle*> m_resourceHandleList;
const CString m_certificatePath;
int m_runningJobs;
+
+ String m_proxy;
+ ProxyType m_proxyType;
};
}
diff --git a/WebCore/platform/network/mac/AuthenticationMac.mm b/WebCore/platform/network/mac/AuthenticationMac.mm
index 355931d..93725d5 100644
--- a/WebCore/platform/network/mac/AuthenticationMac.mm
+++ b/WebCore/platform/network/mac/AuthenticationMac.mm
@@ -150,6 +150,9 @@ NSURLProtectionSpace *mac(const ProtectionSpace& coreSpace)
NSURLCredential *mac(const Credential& coreCredential)
{
+ if (coreCredential.isEmpty())
+ return nil;
+
NSURLCredentialPersistence persistence = NSURLCredentialPersistenceNone;
switch (coreCredential.persistence()) {
case CredentialPersistenceNone:
diff --git a/WebCore/platform/network/mac/ResourceHandleMac.mm b/WebCore/platform/network/mac/ResourceHandleMac.mm
index ec60079..3630b30 100644
--- a/WebCore/platform/network/mac/ResourceHandleMac.mm
+++ b/WebCore/platform/network/mac/ResourceHandleMac.mm
@@ -119,6 +119,7 @@ public:
}
};
+#ifndef BUILDING_ON_TIGER
static String encodeBasicAuthorization(const String& user, const String& password)
{
CString unencodedString = (user + ":" + password).utf8();
@@ -128,6 +129,7 @@ static String encodeBasicAuthorization(const String& user, const String& passwor
base64Encode(unencoded, encoded);
return String(encoded.data(), encoded.size());
}
+#endif
ResourceHandleInternal::~ResourceHandleInternal()
{
@@ -175,23 +177,38 @@ bool ResourceHandle::start(Frame* frame)
} else
delegate = ResourceHandle::delegate();
- if ((!d->m_user.isEmpty() || !d->m_pass.isEmpty()) && !d->m_request.url().protocolInHTTPFamily()) {
+ if ((!d->m_user.isEmpty() || !d->m_pass.isEmpty())
+#ifndef BUILDING_ON_TIGER
+ && !d->m_request.url().protocolInHTTPFamily() // On Tiger, always pass credentials in URL, so that they get stored even if the request gets cancelled right away.
+#endif
+ ) {
// Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made.
KURL urlWithCredentials(d->m_request.url());
urlWithCredentials.setUser(d->m_user);
urlWithCredentials.setPass(d->m_pass);
d->m_request.setURL(urlWithCredentials);
}
-
- // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
- // try and reuse the credential preemptively, as allowed by RFC 2617.
- if (!client() || client()->shouldUseCredentialStorage(this) && d->m_request.url().protocolInHTTPFamily())
- d->m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(d->m_request.url());
+
+#ifndef BUILDING_ON_TIGER
+ if ((!client() || client()->shouldUseCredentialStorage(this)) && d->m_request.url().protocolInHTTPFamily()) {
+ if (d->m_user.isEmpty() && d->m_pass.isEmpty()) {
+ // <rdar://problem/7174050> - For URLs that match the paths of those previously challenged for HTTP Basic authentication,
+ // try and reuse the credential preemptively, as allowed by RFC 2617.
+ d->m_initialCredential = CredentialStorage::get(d->m_request.url());
+ } else {
+ // If there is already a protection space known for the URL, update stored credentials before sending a request.
+ // This makes it possible to implement logout by sending an XMLHttpRequest with known incorrect credentials, and aborting it immediately
+ // (so that an authentication dialog doesn't pop up).
+ CredentialStorage::set(Credential(d->m_user, d->m_pass, CredentialPersistenceNone), d->m_request.url());
+ }
+ }
if (!d->m_initialCredential.isEmpty()) {
+ // FIXME: Support Digest authentication, and Proxy-Authorization.
String authHeader = "Basic " + encodeBasicAuthorization(d->m_initialCredential.user(), d->m_initialCredential.password());
d->m_request.addHTTPHeaderField("Authorization", authHeader);
}
+#endif
if (!ResourceHandle::didSendBodyDataDelegateExists())
associateStreamWithResourceHandle([d->m_request.nsURLRequest() HTTPBodyStream], this);
@@ -471,7 +488,7 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
if (!d->m_user.isNull() && !d->m_pass.isNull()) {
NSURLCredential *credential = [[NSURLCredential alloc] initWithUser:d->m_user
password:d->m_pass
- persistence:NSURLCredentialPersistenceNone];
+ persistence:NSURLCredentialPersistenceForSession];
d->m_currentMacChallenge = challenge.nsURLAuthenticationChallenge();
d->m_currentWebChallenge = challenge;
receivedCredential(challenge, core(credential));
@@ -482,6 +499,7 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
return;
}
+#ifndef BUILDING_ON_TIGER
if (!challenge.previousFailureCount() && (!client() || client()->shouldUseCredentialStorage(this))) {
Credential credential = CredentialStorage::get(challenge.protectionSpace());
if (!credential.isEmpty() && credential != d->m_initialCredential) {
@@ -490,6 +508,7 @@ void ResourceHandle::didReceiveAuthenticationChallenge(const AuthenticationChall
return;
}
}
+#endif
d->m_currentMacChallenge = challenge.nsURLAuthenticationChallenge();
NSURLAuthenticationChallenge *webChallenge = [[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:d->m_currentMacChallenge
@@ -521,11 +540,6 @@ void ResourceHandle::receivedCredential(const AuthenticationChallenge& challenge
if (credential.persistence() == CredentialPersistenceNone) {
// NSURLCredentialPersistenceNone doesn't work on Tiger, so we have to use session persistence.
Credential webCredential(credential.user(), credential.password(), CredentialPersistenceForSession);
- KURL urlToStore;
- if (challenge.failureResponse().httpStatusCode() == 401)
- urlToStore = d->m_request.url();
- CredentialStorage::set(webCredential, core([d->m_currentMacChallenge protectionSpace]), urlToStore);
-
[[d->m_currentMacChallenge sender] useCredential:mac(webCredential) forAuthenticationChallenge:d->m_currentMacChallenge];
} else
#else
@@ -620,6 +634,11 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
CallbackGuard guard;
ResourceRequest request = newRequest;
+
+ // Should not set Referer after a redirect from a secure resource to non-secure one.
+ if (!request.url().protocolIs("https") && protocolIs(request.httpReferrer(), "https"))
+ request.clearHTTPReferrer();
+
m_handle->willSendRequest(request, redirectResponse);
if (!ResourceHandle::didSendBodyDataDelegateExists()) {
@@ -1055,7 +1074,7 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen
// try and reuse the credential preemptively, as allowed by RFC 2617.
ResourceRequest requestWithInitialCredentials = request;
if (allowStoredCredentials && url.protocolInHTTPFamily())
- delegate->m_initialCredential = CredentialStorage::getDefaultAuthenticationCredential(url);
+ delegate->m_initialCredential = CredentialStorage::get(url);
if (!delegate->m_initialCredential.isEmpty()) {
String authHeader = "Basic " + encodeBasicAuthorization(delegate->m_initialCredential.user(), delegate->m_initialCredential.password());
diff --git a/WebCore/platform/network/mac/ResourceRequestMac.mm b/WebCore/platform/network/mac/ResourceRequestMac.mm
index c4355b2..c2ad7d1 100644
--- a/WebCore/platform/network/mac/ResourceRequestMac.mm
+++ b/WebCore/platform/network/mac/ResourceRequestMac.mm
@@ -66,6 +66,7 @@ void ResourceRequest::doUpdateResourceRequest()
NSDictionary *headers = [m_nsRequest.get() allHTTPHeaderFields];
NSEnumerator *e = [headers keyEnumerator];
NSString *name;
+ m_httpHeaderFields.clear();
while ((name = [e nextObject]))
m_httpHeaderFields.set(name, [headers objectForKey:name]);
@@ -114,7 +115,11 @@ void ResourceRequest::doUpdatePlatformRequest()
if (!httpMethod().isEmpty())
[nsRequest setHTTPMethod:httpMethod()];
[nsRequest setHTTPShouldHandleCookies:allowCookies()];
-
+
+ // Cannot just use setAllHTTPHeaderFields here, because it does not remove headers.
+ NSArray *oldHeaderFieldNames = [[nsRequest allHTTPHeaderFields] allKeys];
+ for (unsigned i = [oldHeaderFieldNames count]; i != 0; --i)
+ [nsRequest setValue:nil forHTTPHeaderField:[oldHeaderFieldNames objectAtIndex:i - 1]];
HTTPHeaderMap::const_iterator end = httpHeaderFields().end();
for (HTTPHeaderMap::const_iterator it = httpHeaderFields().begin(); it != end; ++it)
[nsRequest setValue:it->second forHTTPHeaderField:it->first];
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
index 7a3703d..ed5e024 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.cpp
@@ -112,23 +112,11 @@ qint64 FormDataIODevice::writeData(const char*, qint64)
return -1;
}
-void FormDataIODevice::setParent(QNetworkReply* reply)
-{
- QIODevice::setParent(reply);
-
- connect(reply, SIGNAL(finished()), SLOT(slotFinished()), Qt::QueuedConnection);
-}
-
bool FormDataIODevice::isSequential() const
{
return true;
}
-void FormDataIODevice::slotFinished()
-{
- deleteLater();
-}
-
QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode loadMode)
: QObject(0)
, m_reply(0)
@@ -187,8 +175,8 @@ void QNetworkReplyHandler::abort()
QNetworkReply* reply = release();
reply->abort();
reply->deleteLater();
- deleteLater();
}
+ deleteLater();
}
QNetworkReply* QNetworkReplyHandler::release()
@@ -200,6 +188,7 @@ QNetworkReply* QNetworkReplyHandler::release()
// posted meta call events that were the result of a signal emission
// don't reach the slots in our instance.
QCoreApplication::removePostedEvents(this, QEvent::MetaCall);
+ m_reply->setParent(0);
m_reply = 0;
}
return reply;
diff --git a/WebCore/platform/network/qt/QNetworkReplyHandler.h b/WebCore/platform/network/qt/QNetworkReplyHandler.h
index 545119e..fccc4a6 100644
--- a/WebCore/platform/network/qt/QNetworkReplyHandler.h
+++ b/WebCore/platform/network/qt/QNetworkReplyHandler.h
@@ -96,16 +96,12 @@ public:
FormDataIODevice(FormData*);
~FormDataIODevice();
- void setParent(QNetworkReply*);
bool isSequential() const;
protected:
qint64 readData(char*, qint64);
qint64 writeData(const char*, qint64);
-private Q_SLOTS:
- void slotFinished();
-
private:
void moveToNextElement();
diff --git a/WebCore/platform/qt/CursorQt.cpp b/WebCore/platform/qt/CursorQt.cpp
index aad84be..3fc83f9 100644
--- a/WebCore/platform/qt/CursorQt.cpp
+++ b/WebCore/platform/qt/CursorQt.cpp
@@ -2,7 +2,7 @@
* Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
* Copyright (C) 2006 George Staikos <staikos@kde.org>
* Copyright (C) 2006 Charles Samuels <charles@kde.org>
- * Copyright (C) 2008 Holger Hans Peter Freyther
+ * Copyright (C) 2008, 2009 Holger Hans Peter Freyther
*
* All rights reserved.
*
@@ -92,14 +92,14 @@ protected:
, SplitVCursor(Qt::SplitVCursor)
, NoDropCursor(Qt::ForbiddenCursor)
, BlankCursor(Qt::BlankCursor)
- , ZoomInCursor(QPixmap(QLatin1String(":/webkit/resources/zoomInCursor.png")))
- , ZoomOutCursor(QPixmap(QLatin1String(":/webkit/resources/zoomOutCursor.png")))
- , VerticalTextCursor(QPixmap(QLatin1String(":/webkit/resources/verticalTextCursor.png")))
- , CellCursor(QPixmap(QLatin1String(":/webkit/resources/cellCursor.png")))
- , ContextMenuCursor(QPixmap(QLatin1String(":/webkit/resources/contextMenuCursor.png")))
- , CopyCursor(QPixmap(QLatin1String(":/webkit/resources/copyCursor.png")))
- , ProgressCursor(QPixmap(QLatin1String(":/webkit/resources/progressCursor.png")))
- , AliasCursor(QPixmap(QLatin1String(":/webkit/resources/aliasCursor.png")))
+ , ZoomInCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/zoomInCursor.png")), 7, 7))
+ , ZoomOutCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/zoomOutCursor.png")), 7, 7))
+ , VerticalTextCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/verticalTextCursor.png")), 7, 7))
+ , CellCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/cellCursor.png")), 7, 7))
+ , ContextMenuCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/contextMenuCursor.png")), 3, 2))
+ , CopyCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/copyCursor.png")), 3, 2))
+ , ProgressCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/progressCursor.png")), 3, 2))
+ , AliasCursor(QCursor(QPixmap(QLatin1String(":/webkit/resources/aliasCursor.png")), 11, 3))
#endif
{
diff --git a/WebCore/platform/qt/Localizations.cpp b/WebCore/platform/qt/Localizations.cpp
index 77cac57..ca3ca9d 100644
--- a/WebCore/platform/qt/Localizations.cpp
+++ b/WebCore/platform/qt/Localizations.cpp
@@ -33,6 +33,7 @@
#include "PlatformString.h"
#include <QCoreApplication>
+#include <QLocale>
namespace WebCore {
@@ -53,7 +54,8 @@ String resetButtonDefaultLabel()
String defaultLanguage()
{
- return "en";
+ QLocale locale;
+ return locale.name().replace("_", "-");
}
String searchableIndexIntroduction()
diff --git a/WebCore/platform/qt/PlatformScreenQt.cpp b/WebCore/platform/qt/PlatformScreenQt.cpp
index 7ba8350..8221760 100644
--- a/WebCore/platform/qt/PlatformScreenQt.cpp
+++ b/WebCore/platform/qt/PlatformScreenQt.cpp
@@ -62,7 +62,7 @@ int screenDepthPerComponent(Widget* w)
QWebPageClient* client = w->root()->hostWindow()->platformPageClient();
if (client) {
- QWidget* view = QWidget::find(client->winId());
+ QWidget* view = client->ownerWidget();
if (view)
return view->depth();
}
diff --git a/WebCore/platform/qt/PopupMenuQt.cpp b/WebCore/platform/qt/PopupMenuQt.cpp
index b44f2ec..f6ec4f7 100644
--- a/WebCore/platform/qt/PopupMenuQt.cpp
+++ b/WebCore/platform/qt/PopupMenuQt.cpp
@@ -92,7 +92,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index)
rect.moveTopLeft(v->contentsToWindow(r.topLeft()));
rect.setHeight(m_popup->sizeHint().height());
- m_popup->setParent(QWidget::find(client->winId()));
+ m_popup->setParent(client->ownerWidget());
m_popup->setGeometry(rect);
m_popup->setCurrentIndex(index);
m_popup->exec();
diff --git a/WebCore/platform/qt/QWebPageClient.h b/WebCore/platform/qt/QWebPageClient.h
index 09f7886..28ef724 100644
--- a/WebCore/platform/qt/QWebPageClient.h
+++ b/WebCore/platform/qt/QWebPageClient.h
@@ -32,7 +32,10 @@ class QWebPageClient {
public:
virtual void scroll(int dx, int dy, const QRect&) = 0;
virtual void update(const QRect&) = 0;
-
+ virtual void setInputMethodEnabled(bool enable) = 0;
+#if QT_VERSION >= 0x040600
+ virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable) = 0;
+#endif
inline void resetCursor()
{
#ifndef QT_NO_CURSOR
@@ -52,8 +55,9 @@ public:
#endif
}
+ virtual QPalette palette() const = 0;
virtual int screenNumber() const = 0;
- virtual WId winId() const = 0;
+ virtual QWidget* ownerWidget() const = 0;
virtual QObject* pluginParent() const = 0;
diff --git a/WebCore/platform/qt/WheelEventQt.cpp b/WebCore/platform/qt/WheelEventQt.cpp
index 66118e1..9cc27ab 100644
--- a/WebCore/platform/qt/WheelEventQt.cpp
+++ b/WebCore/platform/qt/WheelEventQt.cpp
@@ -32,11 +32,11 @@ namespace WebCore {
void PlatformWheelEvent::applyDelta(int delta, Qt::Orientation orientation)
{
if (orientation == Qt::Horizontal) {
- m_deltaX = (delta / 120);
+ m_deltaX = (delta / 120.0f);
m_deltaY = 0;
} else {
m_deltaX = 0;
- m_deltaY = (delta / 120);
+ m_deltaY = (delta / 120.0f);
}
m_wheelTicksX = m_deltaX;
diff --git a/WebCore/platform/sql/SQLiteDatabase.h b/WebCore/platform/sql/SQLiteDatabase.h
index d313435..9982254 100644
--- a/WebCore/platform/sql/SQLiteDatabase.h
+++ b/WebCore/platform/sql/SQLiteDatabase.h
@@ -24,8 +24,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef SQLDatabase_h
-#define SQLDatabase_h
+#ifndef SQLiteDatabase_h
+#define SQLiteDatabase_h
#include "PlatformString.h"
#include <wtf/Threading.h>
diff --git a/WebCore/platform/text/AtomicString.cpp b/WebCore/platform/text/AtomicString.cpp
index 409439e..17d7832 100644
--- a/WebCore/platform/text/AtomicString.cpp
+++ b/WebCore/platform/text/AtomicString.cpp
@@ -65,7 +65,9 @@ struct CStringTranslator {
static void translate(StringImpl*& location, const char* const& c, unsigned hash)
{
- location = new StringImpl(c, strlen(c), hash);
+ location = StringImpl::create(c).releaseRef();
+ location->setHash(hash);
+ location->setInTable();
}
};
@@ -140,7 +142,9 @@ struct UCharBufferTranslator {
static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash)
{
- location = new StringImpl(buf.s, buf.length, hash);
+ location = StringImpl::create(buf.s, buf.length).releaseRef();
+ location->setHash(hash);
+ location->setInTable();
}
};
@@ -164,7 +168,9 @@ struct HashAndCharactersTranslator {
static void translate(StringImpl*& location, const HashAndCharacters& buffer, unsigned hash)
{
- location = new StringImpl(buffer.characters, buffer.length, hash);
+ location = StringImpl::create(buffer.characters, buffer.length).releaseRef();
+ location->setHash(hash);
+ location->setInTable();
}
};
@@ -222,6 +228,16 @@ void AtomicString::remove(StringImpl* r)
{
stringTable().remove(r);
}
+
+AtomicString AtomicString::lower() const
+{
+ // Note: This is a hot function in the Dromaeo benchmark.
+ StringImpl* impl = this->impl();
+ RefPtr<StringImpl> newImpl = impl->lower();
+ if (LIKELY(newImpl == impl))
+ return *this;
+ return AtomicString(newImpl);
+}
#if USE(JSC)
PassRefPtr<StringImpl> AtomicString::add(const JSC::Identifier& identifier)
diff --git a/WebCore/platform/text/AtomicString.h b/WebCore/platform/text/AtomicString.h
index 3307a2d..8805f4c 100644
--- a/WebCore/platform/text/AtomicString.h
+++ b/WebCore/platform/text/AtomicString.h
@@ -83,6 +83,9 @@ public:
bool endsWith(const String& s, bool caseSensitive = true) const
{ return m_string.endsWith(s, caseSensitive); }
+ AtomicString lower() const;
+ AtomicString upper() const { return AtomicString(impl()->upper()); }
+
int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); }
diff --git a/WebCore/platform/text/String.cpp b/WebCore/platform/text/String.cpp
index bef2674..44582a9 100644
--- a/WebCore/platform/text/String.cpp
+++ b/WebCore/platform/text/String.cpp
@@ -441,7 +441,7 @@ String String::number(unsigned long n)
String String::number(long long n)
{
-#if PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS) && !PLATFORM(QT)
return String::format("%I64i", n);
#else
return String::format("%lli", n);
@@ -450,7 +450,7 @@ String String::number(long long n)
String String::number(unsigned long long n)
{
-#if PLATFORM(WIN_OS)
+#if PLATFORM(WIN_OS) && !PLATFORM(QT)
return String::format("%I64u", n);
#else
return String::format("%llu", n);
diff --git a/WebCore/platform/text/StringImpl.cpp b/WebCore/platform/text/StringImpl.cpp
index c3ab4be..5cf4ced 100644
--- a/WebCore/platform/text/StringImpl.cpp
+++ b/WebCore/platform/text/StringImpl.cpp
@@ -89,7 +89,7 @@ StringImpl::StringImpl()
hash();
}
-inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer)
+inline StringImpl::StringImpl(const UChar* characters, unsigned length)
: m_data(characters)
, m_length(length)
, m_hash(0)
@@ -98,41 +98,6 @@ inline StringImpl::StringImpl(UChar* characters, unsigned length, AdoptBuffer)
ASSERT(length);
}
-// This constructor is only for use by AtomicString.
-StringImpl::StringImpl(const UChar* characters, unsigned length, unsigned hash)
- : m_data(0)
- , m_length(length)
- , m_hash(hash)
-{
- ASSERT(hash);
- ASSERT(characters);
- ASSERT(length);
-
- setInTable();
- UChar* data = newUCharVector(length);
- memcpy(data, characters, length * sizeof(UChar));
- m_data = data;
-}
-
-// This constructor is only for use by AtomicString.
-StringImpl::StringImpl(const char* characters, unsigned length, unsigned hash)
- : m_data(0)
- , m_length(length)
- , m_hash(hash)
-{
- ASSERT(hash);
- ASSERT(characters);
- ASSERT(length);
-
- setInTable();
- UChar* data = newUCharVector(length);
- for (unsigned i = 0; i != length; ++i) {
- unsigned char c = characters[i];
- data[i] = c;
- }
- m_data = data;
-}
-
StringImpl::~StringImpl()
{
if (inTable())
@@ -184,46 +149,38 @@ UChar32 StringImpl::characterStartingAt(unsigned i)
return 0;
}
-bool StringImpl::isLower()
+PassRefPtr<StringImpl> StringImpl::lower()
{
- // Do a faster loop for the case where all the characters are ASCII.
- bool allLower = true;
+ // Note: This is a hot function in the Dromaeo benchmark, specifically the
+ // no-op code path up through the first 'return' statement.
+
+ // First scan the string for uppercase and non-ASCII characters:
UChar ored = 0;
- for (unsigned i = 0; i < m_length; i++) {
- UChar c = m_data[i];
- allLower = allLower && isASCIILower(c);
- ored |= c;
+ bool noUpper = true;
+ const UChar *end = m_data + m_length;
+ for (const UChar* chp = m_data; chp != end; chp++) {
+ if (UNLIKELY(isASCIIUpper(*chp)))
+ noUpper = false;
+ ored |= *chp;
}
- if (!(ored & ~0x7F))
- return allLower;
-
- // Do a slower check for cases that include non-ASCII characters.
- allLower = true;
- unsigned i = 0;
- while (i < m_length) {
- UChar32 character;
- U16_NEXT(m_data, i, m_length, character)
- allLower = allLower && Unicode::isLower(character);
- }
- return allLower;
-}
+
+ // Nothing to do if the string is all ASCII with no uppercase.
+ if (noUpper && !(ored & ~0x7F))
+ return this;
-PassRefPtr<StringImpl> StringImpl::lower()
-{
- UChar* data;
- PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
int32_t length = m_length;
+ UChar* data;
+ RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
- // Do a faster loop for the case where all the characters are ASCII.
- UChar ored = 0;
- for (int i = 0; i < length; i++) {
- UChar c = m_data[i];
- ored |= c;
- data[i] = toASCIILower(c);
- }
- if (!(ored & ~0x7F))
+ if (!(ored & ~0x7F)) {
+ // Do a faster loop for the case where all the characters are ASCII.
+ for (int i = 0; i < length; i++) {
+ UChar c = m_data[i];
+ data[i] = toASCIILower(c);
+ }
return newImpl;
-
+ }
+
// Do a slower implementation for cases that include non-ASCII characters.
bool error;
int32_t realLength = Unicode::toLower(data, length, m_data, m_length, &error);
@@ -238,6 +195,9 @@ PassRefPtr<StringImpl> StringImpl::lower()
PassRefPtr<StringImpl> StringImpl::upper()
{
+ // This function could be optimized for no-op cases the way lower() is,
+ // but in empirical testing, few actual calls to upper() are no-ops, so
+ // it wouldn't be worth the extra time for pre-scanning.
UChar* data;
PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
int32_t length = m_length;
@@ -322,6 +282,8 @@ PassRefPtr<StringImpl> StringImpl::stripWhiteSpace()
while (end && isSpaceOrNewline(m_data[end]))
end--;
+ if (!start && end == m_length - 1)
+ return this;
return create(m_data + start, end + 1 - start);
}
@@ -364,12 +326,16 @@ PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace()
const UChar* from = m_data;
const UChar* fromend = from + m_length;
int outc = 0;
+ bool changedToSpace = false;
UChar* to = data.characters();
while (true) {
- while (from != fromend && isSpaceOrNewline(*from))
+ while (from != fromend && isSpaceOrNewline(*from)) {
+ if (*from != ' ')
+ changedToSpace = true;
from++;
+ }
while (from != fromend && !isSpaceOrNewline(*from))
to[outc++] = *from++;
if (from != fromend)
@@ -381,6 +347,9 @@ PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace()
if (outc > 0 && to[outc - 1] == ' ')
outc--;
+ if (static_cast<unsigned>(outc) == m_length && !changedToSpace)
+ return this;
+
data.shrink(outc);
return adopt(data);
@@ -933,7 +902,7 @@ PassRefPtr<StringImpl> StringImpl::adopt(StringBuffer& buffer)
unsigned length = buffer.length();
if (length == 0)
return empty();
- return adoptRef(new StringImpl(buffer.release(), length, AdoptBuffer()));
+ return adoptRef(new StringImpl(buffer.release(), length));
}
PassRefPtr<StringImpl> StringImpl::adopt(Vector<UChar>& vector)
@@ -941,7 +910,7 @@ PassRefPtr<StringImpl> StringImpl::adopt(Vector<UChar>& vector)
size_t size = vector.size();
if (size == 0)
return empty();
- return adoptRef(new StringImpl(vector.releaseBuffer(), size, AdoptBuffer()));
+ return adoptRef(new StringImpl(vector.releaseBuffer(), size));
}
PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
@@ -957,7 +926,7 @@ PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*&
size_t size = sizeof(StringImpl) + length * sizeof(UChar);
StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
data = reinterpret_cast<UChar*>(string + 1);
- string = new (string) StringImpl(data, length, AdoptBuffer());
+ string = new (string) StringImpl(data, length);
return adoptRef(string);
}
@@ -998,7 +967,7 @@ PassRefPtr<StringImpl> StringImpl::create(const JSC::UString& str)
{
SharedUChar* sharedBuffer = const_cast<JSC::UString*>(&str)->rep()->sharedBuffer();
if (sharedBuffer) {
- PassRefPtr<StringImpl> impl = adoptRef(new StringImpl(const_cast<UChar*>(str.data()), str.size(), AdoptBuffer()));
+ PassRefPtr<StringImpl> impl = adoptRef(new StringImpl(str.data(), str.size()));
sharedBuffer->ref();
impl->m_sharedBufferAndFlags.set(sharedBuffer);
return impl;
@@ -1043,7 +1012,7 @@ PassRefPtr<StringImpl> StringImpl::crossThreadString()
{
SharedUChar* shared = sharedBuffer();
if (shared) {
- RefPtr<StringImpl> impl = adoptRef(new StringImpl(const_cast<UChar*>(m_data), m_length, AdoptBuffer()));
+ RefPtr<StringImpl> impl = adoptRef(new StringImpl(m_data, m_length));
impl->m_sharedBufferAndFlags.set(shared->crossThreadCopy().releaseRef());
return impl.release();
}
diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h
index f3256cc..dac25b2 100644
--- a/WebCore/platform/text/StringImpl.h
+++ b/WebCore/platform/text/StringImpl.h
@@ -47,7 +47,6 @@ typedef const struct __CFString * CFStringRef;
namespace WebCore {
-class AtomicString;
class StringBuffer;
struct CStringTranslator;
@@ -60,21 +59,19 @@ enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
typedef bool (*CharacterMatchFunctionPtr)(UChar);
class StringImpl : public RefCounted<StringImpl> {
- friend class AtomicString;
friend struct CStringTranslator;
friend struct HashAndCharactersTranslator;
friend struct UCharBufferTranslator;
private:
friend class ThreadGlobalData;
StringImpl();
+
+ // This adopts the UChar* without copying the buffer.
+ StringImpl(const UChar*, unsigned length);
- struct AdoptBuffer { };
- StringImpl(UChar*, unsigned length, AdoptBuffer);
-
- // For AtomicString.
- StringImpl(const UChar*, unsigned length, unsigned hash);
- StringImpl(const char*, unsigned length, unsigned hash);
-
+ // For use only by AtomicString's XXXTranslator helpers.
+ void setHash(unsigned hash) { ASSERT(!m_hash); m_hash = hash; }
+
typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
public:
@@ -138,7 +135,6 @@ public:
double toDouble(bool* ok = 0);
float toFloat(bool* ok = 0);
- bool isLower();
PassRefPtr<StringImpl> lower();
PassRefPtr<StringImpl> upper();
PassRefPtr<StringImpl> secure(UChar aChar);
diff --git a/WebCore/platform/text/TextEncodingRegistry.cpp b/WebCore/platform/text/TextEncodingRegistry.cpp
index 5d82511..d3e2965 100644
--- a/WebCore/platform/text/TextEncodingRegistry.cpp
+++ b/WebCore/platform/text/TextEncodingRegistry.cpp
@@ -129,6 +129,10 @@ static TextEncodingNameMap* textEncodingNameMap;
static TextCodecMap* textCodecMap;
static bool didExtendTextCodecMaps;
+static const char* const textEncodingNameBlacklist[] = {
+ "UTF-7"
+};
+
#if ERROR_DISABLED
static inline void checkExistingName(const char*, const char*) { }
@@ -171,6 +175,30 @@ static void addToTextCodecMap(const char* name, NewTextCodecFunction function, c
textCodecMap->add(atomicName, TextCodecFactory(function, additionalData));
}
+static void pruneBlacklistedCodecs()
+{
+ size_t blacklistedCodecListLength = sizeof(textEncodingNameBlacklist) / sizeof(textEncodingNameBlacklist[0]);
+ for (size_t i = 0; i < blacklistedCodecListLength; ++i) {
+ const char* atomicName = textEncodingNameMap->get(textEncodingNameBlacklist[i]);
+ if (!atomicName)
+ continue;
+
+ Vector<const char*> names;
+ TextEncodingNameMap::const_iterator it = textEncodingNameMap->begin();
+ TextEncodingNameMap::const_iterator end = textEncodingNameMap->end();
+ for (; it != end; ++it) {
+ if (it->second == atomicName)
+ names.append(it->first);
+ }
+
+ size_t length = names.size();
+ for (size_t j = 0; j < length; ++j)
+ textEncodingNameMap->remove(names[j]);
+
+ textCodecMap->remove(atomicName);
+ }
+}
+
static void buildBaseTextCodecMaps()
{
ASSERT(isMainThread());
@@ -221,6 +249,8 @@ static void extendTextCodecMaps()
TextCodecWince::registerExtendedEncodingNames(addToTextEncodingNameMap);
TextCodecWince::registerExtendedCodecs(addToTextCodecMap);
#endif
+
+ pruneBlacklistedCodecs();
}
PassOwnPtr<TextCodec> newTextCodec(const TextEncoding& encoding)
diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp
index b2e8e3e..b75ce46 100644
--- a/WebCore/platform/win/ClipboardWin.cpp
+++ b/WebCore/platform/win/ClipboardWin.cpp
@@ -577,8 +577,32 @@ HashSet<String> ClipboardWin::types() const
PassRefPtr<FileList> ClipboardWin::files() const
{
- notImplemented();
- return 0;
+ RefPtr<FileList> files = FileList::create();
+ if (policy() != ClipboardReadable && policy() != ClipboardTypesReadable)
+ return files.release();
+
+ if (!m_dataObject)
+ return files.release();
+
+ STGMEDIUM medium;
+ if (FAILED(m_dataObject->GetData(cfHDropFormat(), &medium)))
+ return files.release();
+
+ HDROP hdrop = reinterpret_cast<HDROP>(GlobalLock(medium.hGlobal));
+ if (!hdrop)
+ return files.release();
+
+ WCHAR filename[MAX_PATH];
+ UINT fileCount = DragQueryFileW(hdrop, 0xFFFFFFFF, 0, 0);
+ for (UINT i = 0; i < fileCount; i++) {
+ if (!DragQueryFileW(hdrop, i, filename, ARRAYSIZE(filename)))
+ continue;
+ files->append(File::create(reinterpret_cast<UChar*>(filename)));
+ }
+
+ GlobalUnlock(medium.hGlobal);
+ ReleaseStgMedium(&medium);
+ return files.release();
}
void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint &loc)
diff --git a/WebCore/platform/win/ScrollbarThemeSafari.cpp b/WebCore/platform/win/ScrollbarThemeSafari.cpp
index 06a6533..4e979f2 100644
--- a/WebCore/platform/win/ScrollbarThemeSafari.cpp
+++ b/WebCore/platform/win/ScrollbarThemeSafari.cpp
@@ -73,7 +73,7 @@ static int cButtonHitInset[] = { 3, 2 };
static int cButtonLength[] = { 14, 10 };
static int cThumbMinLength[] = { 26, 20 };
-#if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME)
+#ifdef DEBUG_ALL
SOFT_LINK_DEBUG_LIBRARY(SafariTheme)
#else
SOFT_LINK_LIBRARY(SafariTheme)
diff --git a/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp b/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp
index 653f142..23dea6b 100644
--- a/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp
+++ b/WebCore/platform/wx/wxcode/mac/carbon/fontprops.cpp
@@ -30,6 +30,7 @@
#include <wx/defs.h>
#include <wx/gdicmn.h>
+#include <wx/graphics.h>
#ifdef BUILDING_ON_TIGER
void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm);
@@ -91,98 +92,21 @@ m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height,
wxCoord *descent, wxCoord *externalLeading )
{
- ATSUStyle* ATSUIStyle;
-
- if ( font.Ok() )
+ wxGraphicsContext * const gc = wxGraphicsContext::Create();
+ gc->SetFont(font, *wxBLACK); // colour doesn't matter but must be specified
+ struct GCTextExtent
{
- OSStatus status ;
-
- status = ATSUCreateAndCopyStyle( (ATSUStyle) font.MacGetATSUStyle() , (ATSUStyle*) &ATSUIStyle ) ;
-
- wxASSERT_MSG( status == noErr, wxT("couldn't create ATSU style") ) ;
-
- // we need the scale here ...
-
- Fixed atsuSize = IntToFixed( int( /*m_scaleY*/ 1 * font.GetPointSize()) ) ;
- //RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColor.GetPixel() ) ;
- ATSUAttributeTag atsuTags[] =
- {
- kATSUSizeTag //,
- // kATSUColorTag ,
- } ;
- ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
- {
- sizeof( Fixed ) //,
- // sizeof( RGBColor ) ,
- } ;
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
- {
- &atsuSize //,
- // &atsuColor ,
- } ;
-
- status = ::ATSUSetAttributes(
- (ATSUStyle)ATSUIStyle, sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
- atsuTags, atsuSizes, atsuValues);
-
- wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ) ;
- }
-
- wxCHECK_RET( ATSUIStyle != NULL, wxT("GetTextExtent - no valid font set") ) ;
-
- OSStatus status = noErr ;
-
- ATSUTextLayout atsuLayout ;
- UniCharCount chars = str.length() ;
- UniChar* ubuf = NULL ;
-
-#if SIZEOF_WCHAR_T == 4
- wxMBConvUTF16 converter ;
-#if wxUSE_UNICODE
- size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
- ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
- converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
-#else
- const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
- size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
- ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
- converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
-#endif
- chars = unicharlen / 2 ;
-#else
-#if wxUSE_UNICODE
- ubuf = (UniChar*) str.wc_str() ;
-#else
- wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
- chars = wxWcslen( wchar.data() ) ;
- ubuf = (UniChar*) wchar.data() ;
-#endif
-#endif
-
- status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
- &chars , (ATSUStyle*) &ATSUIStyle , &atsuLayout ) ;
-
- wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") );
-
- ATSUTextMeasurement textBefore, textAfter ;
- ATSUTextMeasurement textAscent, textDescent ;
-
- status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
- &textBefore , &textAfter, &textAscent , &textDescent );
-
+ wxDouble width, height, descent, externalLeading;
+ } e;
+ gc->GetTextExtent(str, &e.width, &e.height, &e.descent, &e.externalLeading);
+ if ( width )
+ *width = wxCoord(e.width + .5);
if ( height )
- *height = FixedToInt(textAscent + textDescent) ;
+ *height = wxCoord(e.height + .5);
if ( descent )
- *descent = FixedToInt(textDescent) ;
+ *descent = wxCoord(e.descent + .5);
if ( externalLeading )
- *externalLeading = 0 ;
- if ( width )
- *width = FixedToInt(textAfter - textBefore) ;
-
-#if SIZEOF_WCHAR_T == 4
- free( ubuf ) ;
-#endif
+ *externalLeading = wxCoord(e.externalLeading + .5);
- ::ATSUDisposeTextLayout(atsuLayout);
- ::ATSUDisposeStyle((ATSUStyle)ATSUIStyle);
+ delete gc;
}