diff options
Diffstat (limited to 'Tools/DumpRenderTree')
64 files changed, 1205 insertions, 128 deletions
diff --git a/Tools/DumpRenderTree/CyclicRedundancyCheck.cpp b/Tools/DumpRenderTree/CyclicRedundancyCheck.cpp new file mode 100644 index 0000000..361ea0f --- /dev/null +++ b/Tools/DumpRenderTree/CyclicRedundancyCheck.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010, Robert Eisele <robert@xarg.org> All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "CyclicRedundancyCheck.h" + +#include <wtf/Vector.h> + +static void makeCrcTable(unsigned crcTable[256]) +{ + for (unsigned i = 0; i < 256; i++) { + unsigned c = i; + for (int k = 0; k < 8; k++) { + if (c & 1) + c = -306674912 ^ ((c >> 1) & 0x7fffffff); + else + c = c >> 1; + } + crcTable[i] = c; + } +} + +unsigned computeCrc(const Vector<unsigned char>& buffer) +{ + static unsigned crcTable[256]; + static bool crcTableComputed = false; + if (!crcTableComputed) { + makeCrcTable(crcTable); + crcTableComputed = true; + } + + unsigned crc = 0xffffffffL; + for (size_t i = 0; i < buffer.size(); ++i) + crc = crcTable[(crc ^ buffer[i]) & 0xff] ^ ((crc >> 8) & 0x00ffffffL); + return crc ^ 0xffffffffL; +} + diff --git a/Tools/DumpRenderTree/CyclicRedundancyCheck.h b/Tools/DumpRenderTree/CyclicRedundancyCheck.h new file mode 100644 index 0000000..ef1d78e --- /dev/null +++ b/Tools/DumpRenderTree/CyclicRedundancyCheck.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CyclicRedundancyCheck_h +#define CyclicRedundancyCheck_h + +#include <wtf/Vector.h> + +unsigned computeCrc(const Vector<unsigned char>&); + +#endif diff --git a/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj b/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj index 67a7556..4eaecb9 100644 --- a/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj +++ b/Tools/DumpRenderTree/DumpRenderTree.xcodeproj/project.pbxproj @@ -36,6 +36,7 @@ 1A215A8211F2609C008AD0F5 /* PluginTest.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A215A8011F2609C008AD0F5 /* PluginTest.h */; }; 1A215BE711F27658008AD0F5 /* DocumentOpenInDestroyStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A215A7511F26072008AD0F5 /* DocumentOpenInDestroyStream.cpp */; }; 1A24BAA9120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */; }; + 1A31EB3813466AC100017372 /* ConvertPoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A31EB3713466AC100017372 /* ConvertPoint.cpp */; }; 1A3E28AA1311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A3E28A91311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp */; }; 1A8F02E80BB9B4EC008CFA34 /* TestObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8F024C0BB9B056008CFA34 /* TestObject.h */; }; 1AC6C8490D07638600CD3161 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AC6C77F0D07589B00CD3161 /* main.cpp */; }; @@ -58,6 +59,8 @@ 4437730F125CBC4D00AAE02C /* WebArchiveDumpSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 44A997820FCDE86400580F10 /* WebArchiveDumpSupport.h */; }; 5185F6B210714E07007AA393 /* HistoryDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5185F69F10714A57007AA393 /* HistoryDelegate.mm */; }; 5185F6B310714E12007AA393 /* HistoryDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5185F69E10714A57007AA393 /* HistoryDelegate.h */; }; + 53CBB832134E42F3001CE6A4 /* CyclicRedundancyCheck.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53CBB830134E42F3001CE6A4 /* CyclicRedundancyCheck.cpp */; }; + 53CBB833134E42F3001CE6A4 /* CyclicRedundancyCheck.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CBB831134E42F3001CE6A4 /* CyclicRedundancyCheck.h */; }; 5DB9AC970F722C3600684641 /* AHEM____.TTF in Copy Font Files */ = {isa = PBXBuildFile; fileRef = AA7F10C20CB3C1030003BDC9 /* AHEM____.TTF */; }; 5DB9AC980F722C3600684641 /* WebKitWeightWatcher100.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 375F09710DAC3CB600C8B4E5 /* WebKitWeightWatcher100.ttf */; }; 5DB9AC990F722C3600684641 /* WebKitWeightWatcher200.ttf in Copy Font Files */ = {isa = PBXBuildFile; fileRef = 375F09720DAC3CB600C8B4E5 /* WebKitWeightWatcher200.ttf */; }; @@ -136,6 +139,7 @@ BCD08B3A0E1057EF00A7D0C1 /* AccessibilityController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */; }; BCD08B710E1059D200A7D0C1 /* AccessibilityControllerMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */; }; BCF6C6500C98E9C000AC063E /* GCController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCF6C64F0C98E9C000AC063E /* GCController.cpp */; }; + C031182B134E4A2B00919757 /* NPPSetWindowCalledDuringDestruction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C031182A134E4A2B00919757 /* NPPSetWindowCalledDuringDestruction.cpp */; }; C06F9ABC1267A7060058E1F6 /* PassDifferentNPPStruct.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */; }; C0E720751281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */; }; C0EC3C9C12787F0500939164 /* NullNPPGetValuePointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */; }; @@ -209,6 +213,7 @@ 1A215A7F11F2609C008AD0F5 /* PluginTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PluginTest.cpp; sourceTree = "<group>"; }; 1A215A8011F2609C008AD0F5 /* PluginTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PluginTest.h; sourceTree = "<group>"; }; 1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NPRuntimeObjectFromDestroyedPlugin.cpp; sourceTree = "<group>"; }; + 1A31EB3713466AC100017372 /* ConvertPoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConvertPoint.cpp; sourceTree = "<group>"; }; 1A3E28A91311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetURLWithJavaScriptURLDestroyingPlugin.cpp; sourceTree = "<group>"; }; 1A8F024C0BB9B056008CFA34 /* TestObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestObject.h; sourceTree = "<group>"; }; 1AC6C77F0D07589B00CD3161 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; }; @@ -241,6 +246,8 @@ 44A997830FCDE86400580F10 /* WebArchiveDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebArchiveDumpSupport.cpp; path = cf/WebArchiveDumpSupport.cpp; sourceTree = "<group>"; }; 5185F69E10714A57007AA393 /* HistoryDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryDelegate.h; path = mac/HistoryDelegate.h; sourceTree = "<group>"; }; 5185F69F10714A57007AA393 /* HistoryDelegate.mm */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; name = HistoryDelegate.mm; path = mac/HistoryDelegate.mm; sourceTree = "<group>"; }; + 53CBB830134E42F3001CE6A4 /* CyclicRedundancyCheck.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CyclicRedundancyCheck.cpp; sourceTree = "<group>"; }; + 53CBB831134E42F3001CE6A4 /* CyclicRedundancyCheck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CyclicRedundancyCheck.h; sourceTree = "<group>"; }; 8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PixelDumpSupport.cpp; sourceTree = "<group>"; }; 9335435F03D75502008635CE /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = WebKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 933BF5A90F93FA5C000F0441 /* PlainTextController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlainTextController.h; path = mac/PlainTextController.h; sourceTree = "<group>"; }; @@ -317,6 +324,7 @@ BCD08B390E1057EF00A7D0C1 /* AccessibilityController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AccessibilityController.cpp; sourceTree = "<group>"; }; BCD08B700E1059D200A7D0C1 /* AccessibilityControllerMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AccessibilityControllerMac.mm; path = mac/AccessibilityControllerMac.mm; sourceTree = "<group>"; }; BCF6C64F0C98E9C000AC063E /* GCController.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = GCController.cpp; sourceTree = "<group>"; }; + C031182A134E4A2B00919757 /* NPPSetWindowCalledDuringDestruction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NPPSetWindowCalledDuringDestruction.cpp; sourceTree = "<group>"; }; C06F9ABB1267A7060058E1F6 /* PassDifferentNPPStruct.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PassDifferentNPPStruct.cpp; sourceTree = "<group>"; }; C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EvaluateJSAfterRemovingPluginElement.cpp; sourceTree = "<group>"; }; C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NullNPPGetValuePointer.cpp; sourceTree = "<group>"; }; @@ -475,11 +483,13 @@ 1A215A6E11F25FF1008AD0F5 /* Tests */ = { isa = PBXGroup; children = ( + 1A31EB3613466AC100017372 /* mac */, 1A215A7511F26072008AD0F5 /* DocumentOpenInDestroyStream.cpp */, C0E720741281C828004EF533 /* EvaluateJSAfterRemovingPluginElement.cpp */, 1A3E28A91311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp */, 1AD4CB2012A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp */, 1ACF898B132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp */, + C031182A134E4A2B00919757 /* NPPSetWindowCalledDuringDestruction.cpp */, 1A24BAA8120734EE00FBB059 /* NPRuntimeObjectFromDestroyedPlugin.cpp */, 1AC77DCE120605B6005C19EF /* NPRuntimeRemoveProperty.cpp */, C0EC3C9B12787F0500939164 /* NullNPPGetValuePointer.cpp */, @@ -489,6 +499,14 @@ path = Tests; sourceTree = "<group>"; }; + 1A31EB3613466AC100017372 /* mac */ = { + isa = PBXGroup; + children = ( + 1A31EB3713466AC100017372 /* ConvertPoint.cpp */, + ); + path = mac; + sourceTree = "<group>"; + }; 9340995508540CAF007F3BC8 /* Products */ = { isa = PBXGroup; children = ( @@ -570,6 +588,8 @@ BCB284870CFA81ED007E533E /* PixelDump */ = { isa = PBXGroup; children = ( + 53CBB830134E42F3001CE6A4 /* CyclicRedundancyCheck.cpp */, + 53CBB831134E42F3001CE6A4 /* CyclicRedundancyCheck.h */, BCB284F30CFA84F2007E533E /* ImageDiffCG.cpp */, 8465E2C60FFA8DF2003B8342 /* PixelDumpSupport.cpp */, BCB2848A0CFA820F007E533E /* PixelDumpSupport.h */, @@ -600,6 +620,7 @@ BC0E24E00E2D9451001B6BC2 /* AccessibilityUIElement.h in Headers */, BCA18B380C9B021900114369 /* AppleScriptController.h in Headers */, A8B91BFF0CF522B4008F91FF /* CheckedMalloc.h in Headers */, + 53CBB833134E42F3001CE6A4 /* CyclicRedundancyCheck.h in Headers */, BCA18B7A0C9B08F100114369 /* DumpRenderTreeDraggingInfo.h in Headers */, A8D79CEA0FC28B2C004AC8FE /* DumpRenderTreeFileDraggingSource.h in Headers */, BCA18C0B0C9B59EF00114369 /* DumpRenderTreeMac.h in Headers */, @@ -774,6 +795,8 @@ 1AD4CB2212A6D1350027A7AF /* GetUserAgentWithNullNPPFromNPPNew.cpp in Sources */, 1A3E28AA1311D73B00501349 /* GetURLWithJavaScriptURLDestroyingPlugin.cpp in Sources */, 1ACF898D132EF41C00E915D4 /* NPDeallocateCalledBeforeNPShutdown.cpp in Sources */, + 1A31EB3813466AC100017372 /* ConvertPoint.cpp in Sources */, + C031182B134E4A2B00919757 /* NPPSetWindowCalledDuringDestruction.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -787,6 +810,7 @@ BC0E26150E2DA4C6001B6BC2 /* AccessibilityUIElementMac.mm in Sources */, BCA18B390C9B021900114369 /* AppleScriptController.m in Sources */, A8B91BFD0CF522B4008F91FF /* CheckedMalloc.cpp in Sources */, + 53CBB832134E42F3001CE6A4 /* CyclicRedundancyCheck.cpp in Sources */, BCA18C470C9B5B9400114369 /* DumpRenderTree.mm in Sources */, BCA18B7B0C9B08F100114369 /* DumpRenderTreeDraggingInfo.mm in Sources */, A8D79CEB0FC28B2C004AC8FE /* DumpRenderTreeFileDraggingSource.m in Sources */, diff --git a/Tools/DumpRenderTree/ForwardingHeaders/wtf/Alignment.h b/Tools/DumpRenderTree/ForwardingHeaders/wtf/Alignment.h new file mode 100644 index 0000000..e83483e --- /dev/null +++ b/Tools/DumpRenderTree/ForwardingHeaders/wtf/Alignment.h @@ -0,0 +1 @@ +#include <JavaScriptCore/Alignment.h> diff --git a/Tools/DumpRenderTree/ForwardingHeaders/wtf/DynamicAnnotations.h b/Tools/DumpRenderTree/ForwardingHeaders/wtf/DynamicAnnotations.h new file mode 100644 index 0000000..1280da8 --- /dev/null +++ b/Tools/DumpRenderTree/ForwardingHeaders/wtf/DynamicAnnotations.h @@ -0,0 +1 @@ +#include <JavaScriptCore/DynamicAnnotations.h> diff --git a/Tools/DumpRenderTree/LayoutTestController.cpp b/Tools/DumpRenderTree/LayoutTestController.cpp index 18b3dcd..3105ce4 100644 --- a/Tools/DumpRenderTree/LayoutTestController.cpp +++ b/Tools/DumpRenderTree/LayoutTestController.cpp @@ -44,6 +44,7 @@ LayoutTestController::LayoutTestController(const std::string& testPathOrURL, const std::string& expectedPixelHash) : m_dumpApplicationCacheDelegateCallbacks(false) + , m_dumpAsAudio(false) , m_dumpAsPDF(false) , m_dumpAsText(false) , m_dumpBackForwardList(false) @@ -315,6 +316,25 @@ static JSValueRef setCloseRemainingWindowsWhenCompleteCallback(JSContextRef cont return JSValueMakeUndefined(context); } +static JSValueRef setEncodedAudioDataCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount < 1) + return JSValueMakeUndefined(context); + + JSRetainPtr<JSStringRef> encodedAudioData(Adopt, JSValueToStringCopy(context, arguments[0], exception)); + ASSERT(!*exception); + + size_t maxLength = JSStringGetMaximumUTF8CStringSize(encodedAudioData.get()); + OwnArrayPtr<char> encodedAudioDataBuffer = adoptArrayPtr(new char[maxLength + 1]); + JSStringGetUTF8CString(encodedAudioData.get(), encodedAudioDataBuffer.get(), maxLength + 1); + + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + controller->setEncodedAudioData(encodedAudioDataBuffer.get()); + controller->setDumpAsAudio(true); + + return JSValueMakeUndefined(context); +} + static JSValueRef testOnscreenCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -1687,6 +1707,14 @@ static JSValueRef setAsynchronousSpellCheckingEnabledCallback(JSContextRef conte return JSValueMakeUndefined(context); } +static JSValueRef shadowRootCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + if (argumentCount != 1) + return JSValueMakeUndefined(context); + LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); + return controller->shadowRoot(context, arguments[0]); +} + static JSValueRef showWebInspectorCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject)); @@ -2213,6 +2241,7 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "setAlwaysAcceptCookies", setAlwaysAcceptCookiesCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAppCacheMaximumSize", setAppCacheMaximumSizeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setApplicationCacheOriginQuota", setApplicationCacheOriginQuotaCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "setEncodedAudioData", setEncodedAudioDataCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAuthenticationPassword", setAuthenticationPasswordCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAuthenticationUsername", setAuthenticationUsernameCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAuthorAndUserStylesEnabled", setAuthorAndUserStylesEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, @@ -2264,6 +2293,7 @@ JSStaticFunction* LayoutTestController::staticFunctions() { "setJavaScriptCanAccessClipboard", setJavaScriptCanAccessClipboardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setXSSAuditorEnabled", setXSSAuditorEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "setAsynchronousSpellCheckingEnabled", setAsynchronousSpellCheckingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { "shadowRoot", shadowRootCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "showWebInspector", showWebInspectorCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "testOnscreen", testOnscreenCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, { "testRepaint", testRepaintCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, diff --git a/Tools/DumpRenderTree/LayoutTestController.h b/Tools/DumpRenderTree/LayoutTestController.h index 4a6e59c..a429dbf 100644 --- a/Tools/DumpRenderTree/LayoutTestController.h +++ b/Tools/DumpRenderTree/LayoutTestController.h @@ -122,6 +122,7 @@ public: void setSpatialNavigationEnabled(bool enable); void setScrollbarPolicy(JSStringRef orientation, JSStringRef policy); void setEditingBehavior(const char* editingBehavior); + JSValueRef shadowRoot(JSContextRef, JSValueRef); void waitForPolicyDelegate(); size_t webHistoryItemCount(); @@ -133,6 +134,9 @@ public: bool elementDoesAutoCompleteForElementWithId(JSStringRef id); + bool dumpAsAudio() const { return m_dumpAsAudio; } + void setDumpAsAudio(bool dumpAsAudio) { m_dumpAsAudio = dumpAsAudio; } + bool dumpAsPDF() const { return m_dumpAsPDF; } void setDumpAsPDF(bool dumpAsPDF) { m_dumpAsPDF = dumpAsPDF; } @@ -262,6 +266,9 @@ public: const std::string& testPathOrURL() const { return m_testPathOrURL; } const std::string& expectedPixelHash() const { return m_expectedPixelHash; } + + const std::string& encodedAudioData() const { return m_encodedAudioData; } + void setEncodedAudioData(const std::string& encodedAudioData) { m_encodedAudioData = encodedAudioData; } bool pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId); bool pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId); @@ -333,6 +340,7 @@ private: void setGeolocationPermissionCommon(bool allow); bool m_dumpApplicationCacheDelegateCallbacks; + bool m_dumpAsAudio; bool m_dumpAsPDF; bool m_dumpAsText; bool m_dumpBackForwardList; @@ -382,6 +390,9 @@ private: std::set<std::string> m_willSendRequestClearHeaders; + // base64 encoded WAV audio data is stored here. + std::string m_encodedAudioData; + // origins which have been granted desktop notification access std::vector<JSStringRef> m_desktopNotificationAllowedOrigins; diff --git a/Tools/DumpRenderTree/PixelDumpSupport.cpp b/Tools/DumpRenderTree/PixelDumpSupport.cpp index 352eaaa..24fbf4b 100644 --- a/Tools/DumpRenderTree/PixelDumpSupport.cpp +++ b/Tools/DumpRenderTree/PixelDumpSupport.cpp @@ -29,15 +29,17 @@ #include "config.h" #include "PixelDumpSupport.h" +#include "CyclicRedundancyCheck.h" #include "DumpRenderTree.h" #include "LayoutTestController.h" #include <cstdio> #include <wtf/Assertions.h> #include <wtf/RefPtr.h> +#include <wtf/Vector.h> -#if PLATFORM(CG) +#if USE(CG) #include "PixelDumpSupportCG.h" -#elif PLATFORM(CAIRO) +#elif USE(CAIRO) #include "PixelDumpSupportCairo.h" #endif @@ -69,16 +71,60 @@ void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash) } if (dumpImage) - dumpBitmap(context.get()); + dumpBitmap(context.get(), actualHash); } -void printPNG(const unsigned char* data, const size_t dataLength) +static void appendIntToVector(unsigned number, Vector<unsigned char>& vector) { + size_t offset = vector.size(); + vector.grow(offset + 4); + vector[offset] = ((number >> 24) & 0xff); + vector[offset + 1] = ((number >> 16) & 0xff); + vector[offset + 2] = ((number >> 8) & 0xff); + vector[offset + 3] = (number & 0xff); +} + +static void convertChecksumToPNGComment(const char* checksum, Vector<unsigned char>& bytesToAdd) +{ + // Chunks of PNG files are <length>, <type>, <data>, <crc>. + static const char textCommentPrefix[] = "\x00\x00\x00\x29tEXtchecksum\x00"; + static const size_t prefixLength = sizeof(textCommentPrefix) - 1; // The -1 is for the null at the end of the char[]. + static const size_t checksumLength = 32; + + bytesToAdd.append(textCommentPrefix, prefixLength); + bytesToAdd.append(checksum, checksumLength); + + Vector<unsigned char> dataToCrc; + dataToCrc.append(textCommentPrefix + 4, prefixLength - 4); // Don't include the chunk length in the crc. + dataToCrc.append(checksum, checksumLength); + unsigned crc32 = computeCrc(dataToCrc); + + appendIntToVector(crc32, bytesToAdd); +} + +static size_t offsetAfterIHDRChunk(const unsigned char* data, const size_t dataLength) +{ + const int pngHeaderLength = 8; + const int pngIHDRChunkLength = 25; // chunk length + "IHDR" + 13 bytes of data + checksum + return pngHeaderLength + pngIHDRChunkLength; +} + +void printPNG(const unsigned char* data, const size_t dataLength, const char* checksum) +{ + Vector<unsigned char> bytesToAdd; + convertChecksumToPNGComment(checksum, bytesToAdd); + printf("Content-Type: %s\n", "image/png"); - printf("Content-Length: %lu\n", static_cast<unsigned long>(dataLength)); + printf("Content-Length: %lu\n", static_cast<unsigned long>(dataLength + bytesToAdd.size())); + + size_t insertOffset = offsetAfterIHDRChunk(data, dataLength); + + fwrite(data, 1, insertOffset, stdout); + fwrite(bytesToAdd.data(), 1, bytesToAdd.size(), stdout); const size_t bytesToWriteInOneChunk = 1 << 15; - size_t dataRemainingToWrite = dataLength; + data += insertOffset; + size_t dataRemainingToWrite = dataLength - insertOffset; while (dataRemainingToWrite) { size_t bytesToWriteInThisChunk = std::min(dataRemainingToWrite, bytesToWriteInOneChunk); size_t bytesWritten = fwrite(data, 1, bytesToWriteInThisChunk, stdout); diff --git a/Tools/DumpRenderTree/PixelDumpSupport.h b/Tools/DumpRenderTree/PixelDumpSupport.h index e172a83..87e6402 100644 --- a/Tools/DumpRenderTree/PixelDumpSupport.h +++ b/Tools/DumpRenderTree/PixelDumpSupport.h @@ -38,9 +38,9 @@ class BitmapContext; void computeMD5HashStringForBitmapContext(BitmapContext*, char hashString[33]); PassRefPtr<BitmapContext> createPagedBitmapContext(); PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool incrementalRepaint, bool sweepHorizontally, bool drawSelectionRect); -void dumpBitmap(BitmapContext*); +void dumpBitmap(BitmapContext*, const char* checksum); void dumpWebViewAsPixelsAndCompareWithExpected(const std::string& expectedHash); -void printPNG(const unsigned char* data, const size_t dataLength); +void printPNG(const unsigned char* data, const size_t dataLength, const char* checksum); #if PLATFORM(MAC) diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp index 24ee12c..75b848b 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.cpp @@ -73,14 +73,10 @@ static void pluginLogWithWindowObjectVariableArgs(NPObject* windowObject, NPP in pluginLogWithWindowObject(windowObject, instance, message); } -// Helper function to log to the console object. -void pluginLog(NPP instance, const char* format, ...) +void pluginLogWithArguments(NPP instance, const char* format, va_list args) { - va_list args; - va_start(args, format); char message[2048] = "PLUGIN: "; vsprintf(message + strlen(message), format, args); - va_end(args); NPObject* windowObject = 0; NPError error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject); @@ -93,6 +89,15 @@ void pluginLog(NPP instance, const char* format, ...) browser->releaseobject(windowObject); } +// Helper function to log to the console object. +void pluginLog(NPP instance, const char* format, ...) +{ + va_list args; + va_start(args, format); + pluginLogWithArguments(instance, format, args); + va_end(args); +} + static void pluginInvalidate(NPObject*); static bool pluginHasProperty(NPObject*, NPIdentifier name); static bool pluginHasMethod(NPObject*, NPIdentifier name); diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h index c264e49..efca1d5 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginObject.h @@ -27,6 +27,7 @@ #define PluginObject_h #include <WebKit/npfunctions.h> +#include <stdarg.h> #if defined(XP_MACOSX) #if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 @@ -87,6 +88,7 @@ extern void handleCallback(PluginObject* object, const char *url, NPReason reaso extern void notifyStream(PluginObject* object, const char *url, const char *headers); extern void testNPRuntime(NPP npp); extern void pluginLog(NPP instance, const char* format, ...); +extern void pluginLogWithArguments(NPP instance, const char* format, va_list args); extern bool testDocumentOpen(NPP npp); extern bool testWindowOpen(NPP npp); diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp index 98ef799..9181a86 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.cpp @@ -25,6 +25,7 @@ #include "PluginTest.h" +#include "PluginObject.h" #include <assert.h> #include <string.h> @@ -69,6 +70,18 @@ void PluginTest::registerNPShutdownFunction(void (*func)()) shutdownFunction = func; } +void PluginTest::indicateTestFailure() +{ + // This should really be an assert, but there's no way for the test framework + // to know that the plug-in process crashed, so we'll just sleep for a while + // to ensure that the test times out. +#if defined(XP_WIN) + ::Sleep(100000); +#else + sleep(1000); +#endif +} + NPError PluginTest::NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved) { return NPERR_NO_ERROR; @@ -135,6 +148,13 @@ bool PluginTest::NPN_RemoveProperty(NPObject* npObject, NPIdentifier propertyNam return browser->removeproperty(m_npp, npObject, propertyName); } +#ifdef XP_MACOSX +bool PluginTest::NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace) +{ + return browser->convertpoint(m_npp, sourceX, sourceY, sourceSpace, destX, destY, destSpace); +} +#endif + void PluginTest::executeScript(const char* script) { NPObject* windowScriptObject; @@ -149,6 +169,14 @@ void PluginTest::executeScript(const char* script) browser->releasevariantvalue(&browserResult); } +void PluginTest::log(const char* format, ...) +{ + va_list args; + va_start(args, format); + pluginLogWithArguments(m_npp, format, args); + va_end(args); +} + void PluginTest::waitUntilDone() { executeScript("layoutTestController.waitUntilDone()"); diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h index cf94165..b704014 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/PluginTest.h @@ -73,11 +73,17 @@ public: NPError NPN_GetValue(NPNVariable, void* value); NPObject* NPN_CreateObject(NPClass*); bool NPN_RemoveProperty(NPObject*, NPIdentifier propertyName); - +#ifdef XP_MACOSX + bool NPN_ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); +#endif + void executeScript(const char*); + void log(const char* format, ...); void registerNPShutdownFunction(void (*)()); + static void indicateTestFailure(); + template<typename TestClassTy> class Register { public: Register(const std::string& identifier) diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp index c53ec97..91f47af 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPDeallocateCalledBeforeNPShutdown.cpp @@ -42,16 +42,8 @@ private: public: ~TestObject() { - // This should really be an assert, but there's no way for the test framework - // to know that the plug-in process crashed, so we'll just sleep for a while - // to ensure that the test times out. - if (wasShutdownCalled) { -#if defined(XP_WIN) - ::Sleep(100000); -#else - sleep(1000); -#endif - } + if (wasShutdownCalled) + indicateTestFailure(); } }; diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPPSetWindowCalledDuringDestruction.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPPSetWindowCalledDuringDestruction.cpp new file mode 100644 index 0000000..ba63243 --- /dev/null +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/NPPSetWindowCalledDuringDestruction.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PluginTest.h" + +#include "PluginObject.h" + +using namespace std; + +// NPP_SetWindow should be called with a null window handle as destruction begins on non-Mac platforms. + +class NPPSetWindowCalledDuringDestruction : public PluginTest { +public: + NPPSetWindowCalledDuringDestruction(NPP, const string& identifier); + + void setWillBeDestroyed() { m_willBeDestroyed = true; } + +private: + struct ScriptObject : Object<ScriptObject> { + bool hasMethod(NPIdentifier); + bool invoke(NPIdentifier, const NPVariant*, uint32_t, NPVariant*); + }; + + virtual NPError NPP_GetValue(NPPVariable, void*); + virtual NPError NPP_SetWindow(NPP, NPWindow*); + virtual NPError NPP_Destroy(NPSavedData**); + + bool m_willBeDestroyed; + bool m_setWindowCalledBeforeDestruction; + bool m_setWindowCalledDuringDestruction; +}; + +static PluginTest::Register<NPPSetWindowCalledDuringDestruction> registrar("npp-set-window-called-during-destruction"); + +NPPSetWindowCalledDuringDestruction::NPPSetWindowCalledDuringDestruction(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + , m_willBeDestroyed(false) + , m_setWindowCalledBeforeDestruction(false) + , m_setWindowCalledDuringDestruction(false) +{ +} + +NPError NPPSetWindowCalledDuringDestruction::NPP_GetValue(NPPVariable variable, void* value) +{ + if (variable != NPPVpluginScriptableNPObject) + return NPERR_GENERIC_ERROR; + + *static_cast<NPObject**>(value) = ScriptObject::create(this); + + return NPERR_NO_ERROR; +} + +NPError NPPSetWindowCalledDuringDestruction::NPP_SetWindow(NPP, NPWindow* window) +{ + if (m_willBeDestroyed) { + m_setWindowCalledDuringDestruction = true; + if (!m_setWindowCalledBeforeDestruction) { + log("Fail: setWillBeDestroyed() was called before the initial NPP_SetWindow call"); + return NPERR_NO_ERROR; + } +#ifndef XP_MACOSX + if (window->window) + log("Fail: NPP_SetWindow passed a non-null window during plugin destruction"); +#endif + return NPERR_NO_ERROR; + } + + if (m_setWindowCalledBeforeDestruction) { + log("Fail: NPP_SetWindow called more than once before plugin destruction"); + return NPERR_NO_ERROR; + } + + m_setWindowCalledBeforeDestruction = true; + return NPERR_NO_ERROR; +} + +NPError NPPSetWindowCalledDuringDestruction::NPP_Destroy(NPSavedData**) +{ +#ifdef XP_MACOSX + bool shouldHaveBeenCalledDuringDestruction = false; +#else + bool shouldHaveBeenCalledDuringDestruction = true; +#endif + + if (m_setWindowCalledDuringDestruction == shouldHaveBeenCalledDuringDestruction) + log("Success: NPP_SetWindow %s called during plugin destruction", shouldHaveBeenCalledDuringDestruction ? "was" : "was not"); + else + log("Fail: NPP_SetWindow %s called during plugin destruction", shouldHaveBeenCalledDuringDestruction ? "was not" : "was"); + + return NPERR_NO_ERROR; +} + +bool NPPSetWindowCalledDuringDestruction::ScriptObject::hasMethod(NPIdentifier methodName) +{ + return methodName == pluginTest()->NPN_GetStringIdentifier("setWillBeDestroyed"); +} + +bool NPPSetWindowCalledDuringDestruction::ScriptObject::invoke(NPIdentifier identifier, const NPVariant*, uint32_t, NPVariant*) +{ + assert(identifier == pluginTest()->NPN_GetStringIdentifier("setWillBeDestroyed")); + static_cast<NPPSetWindowCalledDuringDestruction*>(pluginTest())->setWillBeDestroyed(); + return true; +} diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/mac/ConvertPoint.cpp b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/mac/ConvertPoint.cpp new file mode 100644 index 0000000..7cef707 --- /dev/null +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/Tests/mac/ConvertPoint.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PluginTest.h" + +using namespace std; + +// Test that NPN_ConvertPoint converts correctly. +class ConvertPoint : public PluginTest { +public: + ConvertPoint(NPP npp, const string& identifier) + : PluginTest(npp, identifier) + { + } + + bool testConvert(double x, double y, NPCoordinateSpace sourceSpace, NPCoordinateSpace destSpace) + { + // First convert from src to dest. + double destX, destY; + if (!NPN_ConvertPoint(x, y, sourceSpace, &destX, &destY, destSpace)) + return false; + + // Then convert back to src + double srcX, srcY; + if (!NPN_ConvertPoint(destX, destY, destSpace, &srcX, &srcY, sourceSpace)) + return false; + + + // Then compare. + if (srcX != x || srcY != y) + return false; + + return true; + } + + bool testConvert() + { + static const NPCoordinateSpace spaces[] = { NPCoordinateSpacePlugin, NPCoordinateSpaceWindow, NPCoordinateSpaceFlippedWindow, NPCoordinateSpaceScreen, NPCoordinateSpaceFlippedScreen }; + + static const size_t numSpaces = sizeof(spaces) / sizeof(spaces[0]); + for (size_t i = 0; i < numSpaces; ++i) { + for (size_t j = 0; j < numSpaces; ++j) { + if (!testConvert(1234, 5678, spaces[i], spaces[j])) + return false; + } + } + return true; + } +private: + virtual NPError NPP_New(NPMIMEType pluginType, uint16_t mode, int16_t argc, char *argn[], char *argv[], NPSavedData *saved) + { + if (testConvert()) + executeScript("document.getElementById('result').innerHTML = 'SUCCESS!'"); + + return NPERR_NO_ERROR; + } +}; + +static PluginTest::Register<ConvertPoint> convertPoint("convert-point"); diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj index 5856985..b7bf54b 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePlugin.vcproj @@ -410,6 +410,10 @@ > </File> <File + RelativePath="..\Tests\NPPSetWindowCalledDuringDestruction.cpp" + > + </File> + <File RelativePath="..\Tests\NPRuntimeObjectFromDestroyedPlugin.cpp" > </File> diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginProduction.vsprops b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginProduction.vsprops index 4a65c62..8d64b41 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginProduction.vsprops +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginProduction.vsprops @@ -5,7 +5,7 @@ Name="TestNetscapePluginProduction" InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; - $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops; .\TestNetscapePluginCommon.vsprops" > diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginRelease.vsprops b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginRelease.vsprops index c410e11..1aeb953 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginRelease.vsprops +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginRelease.vsprops @@ -5,6 +5,7 @@ Name="TestNetscapePluginRelease" InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; .\TestNetscapePluginCommon.vsprops" > diff --git a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginReleaseCairoCFLite.vsprops b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginReleaseCairoCFLite.vsprops index eb51008..03651ab 100644 --- a/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginReleaseCairoCFLite.vsprops +++ b/Tools/DumpRenderTree/TestNetscapePlugIn/win/TestNetscapePluginReleaseCairoCFLite.vsprops @@ -5,6 +5,7 @@ Name="TestNetscapePluginReleaseCairoCFLite" InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops; .\TestNetscapePluginCommon.vsprops" diff --git a/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp b/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp index 7de019d..c10a3a7 100644 --- a/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp +++ b/Tools/DumpRenderTree/cairo/PixelDumpSupportCairo.cpp @@ -49,7 +49,7 @@ static cairo_status_t writeFunction(void* closure, const unsigned char* data, un return CAIRO_STATUS_SUCCESS; } -static void printPNG(cairo_surface_t* image) +static void printPNG(cairo_surface_t* image, const char* checksum) { Vector<unsigned char> pixelData; // Only PNG output is supported for now. @@ -58,7 +58,7 @@ static void printPNG(cairo_surface_t* image) const size_t dataLength = pixelData.size(); const unsigned char* data = pixelData.data(); - printPNG(data, dataLength); + printPNG(data, dataLength, checksum); } void computeMD5HashStringForBitmapContext(BitmapContext* context, char hashString[33]) @@ -86,8 +86,8 @@ void computeMD5HashStringForBitmapContext(BitmapContext* context, char hashStrin hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]); } -void dumpBitmap(BitmapContext* context) +void dumpBitmap(BitmapContext* context, const char* checksum) { cairo_surface_t* surface = cairo_get_target(context->cairoContext()); - printPNG(surface); + printPNG(surface, checksum); } diff --git a/Tools/DumpRenderTree/cg/PixelDumpSupportCG.cpp b/Tools/DumpRenderTree/cg/PixelDumpSupportCG.cpp index 5cf32f1..bf59b03 100644 --- a/Tools/DumpRenderTree/cg/PixelDumpSupportCG.cpp +++ b/Tools/DumpRenderTree/cg/PixelDumpSupportCG.cpp @@ -55,7 +55,7 @@ using namespace std; static const CFStringRef kUTTypePNG = CFSTR("public.png"); #endif -static void printPNG(CGImageRef image) +static void printPNG(CGImageRef image, const char* checksum) { RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0)); RetainPtr<CGImageDestinationRef> imageDest(AdoptCF, CGImageDestinationCreateWithData(imageData.get(), kUTTypePNG, 1, 0)); @@ -65,7 +65,7 @@ static void printPNG(CGImageRef image) const UInt8* data = CFDataGetBytePtr(imageData.get()); CFIndex dataLength = CFDataGetLength(imageData.get()); - printPNG(static_cast<const unsigned char*>(data), static_cast<size_t>(dataLength)); + printPNG(static_cast<const unsigned char*>(data), static_cast<size_t>(dataLength), checksum); } void computeMD5HashStringForBitmapContext(BitmapContext* context, char hashString[33]) @@ -106,8 +106,8 @@ void computeMD5HashStringForBitmapContext(BitmapContext* context, char hashStrin snprintf(hashString, 33, "%s%02x", hashString, hash[i]); } -void dumpBitmap(BitmapContext* context) +void dumpBitmap(BitmapContext* context, const char* checksum) { RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(context->cgContext())); - printPNG(image.get()); + printPNG(image.get(), checksum); } diff --git a/Tools/DumpRenderTree/chromium/LayoutTestController.cpp b/Tools/DumpRenderTree/chromium/LayoutTestController.cpp index d91cd6e..72c05b1 100644 --- a/Tools/DumpRenderTree/chromium/LayoutTestController.cpp +++ b/Tools/DumpRenderTree/chromium/LayoutTestController.cpp @@ -214,6 +214,7 @@ LayoutTestController::LayoutTestController(TestShell* shell) bindProperty("globalFlag", &m_globalFlag); // webHistoryItemCount is used by tests in LayoutTests\http\tests\history bindProperty("webHistoryItemCount", &m_webHistoryItemCount); + bindProperty("titleTextDirection", &m_titleTextDirection); } LayoutTestController::~LayoutTestController() @@ -573,6 +574,7 @@ void LayoutTestController::reset() m_deferMainResourceDataLoad = true; m_globalFlag.set(false); m_webHistoryItemCount.set(0); + m_titleTextDirection.set("ltr"); m_userStyleSheetLocation = WebURL(); webkit_support::SetAcceptAllCookies(false); diff --git a/Tools/DumpRenderTree/chromium/LayoutTestController.h b/Tools/DumpRenderTree/chromium/LayoutTestController.h index a9c6ce4..5df7153 100644 --- a/Tools/DumpRenderTree/chromium/LayoutTestController.h +++ b/Tools/DumpRenderTree/chromium/LayoutTestController.h @@ -44,6 +44,7 @@ #include "CppBoundClass.h" #include "Task.h" #include "WebString.h" +#include "WebTextDirection.h" #include "WebURL.h" #include <wtf/Deque.h> #include <wtf/OwnPtr.h> @@ -391,6 +392,10 @@ public: bool stopProvisionalFrameLoads() { return m_stopProvisionalFrameLoads; } bool deferMainResourceDataLoad() { return m_deferMainResourceDataLoad; } void setShowDebugLayerTree(bool value) { m_showDebugLayerTree = value; } + void setTitleTextDirection(WebKit::WebTextDirection dir) + { + m_titleTextDirection.set(dir == WebKit::WebTextDirectionLeftToRight ? "ltr" : "rtl"); + } bool testRepaint() const { return m_testRepaint; } bool sweepHorizontally() const { return m_sweepHorizontally; } @@ -574,6 +579,9 @@ private: // Bound variable counting the number of top URLs visited. CppVariant m_webHistoryItemCount; + // Bound variable tracking the directionality of the <title> tag. + CppVariant m_titleTextDirection; + WebKit::WebURL m_userStyleSheetLocation; OwnPtr<WebKit::WebSpeechInputControllerMock> m_speechInputControllerMock; diff --git a/Tools/DumpRenderTree/chromium/TestShell.cpp b/Tools/DumpRenderTree/chromium/TestShell.cpp index 4790509..4a092e7 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.cpp +++ b/Tools/DumpRenderTree/chromium/TestShell.cpp @@ -50,7 +50,6 @@ #include "WebURLResponse.h" #include "WebView.h" #include "WebViewHost.h" -#include "skia/ext/bitmap_platform_device.h" #include "skia/ext/platform_canvas.h" #include "webkit/support/webkit_support.h" #include "webkit/support/webkit_support_gfx.h" @@ -77,6 +76,21 @@ static const char fileTestPrefix[] = "(file test):"; static const char dataUrlPattern[] = "data:"; static const string::size_type dataUrlPatternSize = sizeof(dataUrlPattern) - 1; +// FIXME: Move this to a common place so that it can be shared with +// WebCore::TransparencyWin::makeLayerOpaque(). +static void makeCanvasOpaque(SkCanvas* canvas) +{ + const SkBitmap& bitmap = canvas->getTopDevice()->accessBitmap(true); + ASSERT(bitmap.config() == SkBitmap::kARGB_8888_Config); + + SkAutoLockPixels lock(bitmap); + for (int y = 0; y < bitmap.height(); y++) { + uint32_t* row = bitmap.getAddr32(0, y); + for (int x = 0; x < bitmap.width(); x++) + row[x] |= 0xFF000000; // Set alpha bits to 1. + } +} + TestShell::TestShell(bool testShellMode) : m_testIsPending(false) , m_testIsPreparing(false) @@ -516,14 +530,8 @@ void TestShell::dump() fflush(stderr); } -void TestShell::dumpImage(skia::PlatformCanvas* canvas) const +void TestShell::dumpImage(SkCanvas* canvas) const { - skia::BitmapPlatformDevice& device = - static_cast<skia::BitmapPlatformDevice&>(canvas->getTopPlatformDevice()); - const SkBitmap& sourceBitmap = device.accessBitmap(false); - - SkAutoLockPixels sourceBitmapLock(sourceBitmap); - // Fix the alpha. The expected PNGs on Mac have an alpha channel, so we want // to keep it. On Windows, the alpha channel is wrong since text/form control // drawing may have erased it in a few places. So on Windows we force it to @@ -533,9 +541,12 @@ void TestShell::dumpImage(skia::PlatformCanvas* canvas) const bool discardTransparency = false; #else bool discardTransparency = true; - device.makeOpaque(0, 0, sourceBitmap.width(), sourceBitmap.height()); + makeCanvasOpaque(canvas); #endif + const SkBitmap& sourceBitmap = canvas->getTopDevice()->accessBitmap(false); + SkAutoLockPixels sourceBitmapLock(sourceBitmap); + // Compute MD5 sum. MD5 digester; Vector<uint8_t, 16> digestValue; diff --git a/Tools/DumpRenderTree/chromium/TestShell.h b/Tools/DumpRenderTree/chromium/TestShell.h index d84d642..10d6909 100644 --- a/Tools/DumpRenderTree/chromium/TestShell.h +++ b/Tools/DumpRenderTree/chromium/TestShell.h @@ -54,9 +54,6 @@ class WebNotificationPresenter; class WebView; class WebURL; } -namespace skia { -class PlatformCanvas; -} class DRTDevToolsAgent; class DRTDevToolsCallArgs; @@ -182,7 +179,7 @@ private: void resetWebSettings(WebKit::WebView&); void dump(); std::string dumpAllBackForwardLists(); - void dumpImage(skia::PlatformCanvas*) const; + void dumpImage(SkCanvas*) const; bool m_testIsPending; bool m_testIsPreparing; diff --git a/Tools/DumpRenderTree/chromium/WebPreferences.cpp b/Tools/DumpRenderTree/chromium/WebPreferences.cpp index 84f84b6..c609397 100644 --- a/Tools/DumpRenderTree/chromium/WebPreferences.cpp +++ b/Tools/DumpRenderTree/chromium/WebPreferences.cpp @@ -165,5 +165,8 @@ void WebPreferences::applyTo(WebView* webView) settings->setUsesEncodingDetector(false); settings->setImagesEnabled(true); settings->setInteractiveFormValidationEnabled(true); + // Enable fullscreen so the fullscreen layout tests can run. + settings->setFullScreenEnabled(true); + settings->setValidationMessageTimerMagnification(-1); } diff --git a/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.cpp b/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.cpp index b1d9fa1..a2dda1d 100755 --- a/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.cpp +++ b/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.cpp @@ -46,7 +46,6 @@ #include <wtf/Assertions.h> using namespace std; -using namespace skia; static const SkColor edgeColor = SK_ColorBLACK; static const SkColor readOnlyColor = SkColorSetRGB(0xe9, 0xc2, 0xa6); @@ -93,7 +92,7 @@ static SkIRect validate(const SkIRect& rect, WebThemeControlDRTWin::Type ctype) // WebThemeControlDRTWin -WebThemeControlDRTWin::WebThemeControlDRTWin(PlatformCanvas* canvas, +WebThemeControlDRTWin::WebThemeControlDRTWin(SkCanvas* canvas, const SkIRect& irect, Type ctype, State cstate) @@ -304,7 +303,7 @@ void WebThemeControlDRTWin::draw() // Indents for the the slider track. const int sliderIndent = 2; - m_canvas->beginPlatformPaint(); + skia::BeginPlatformPaint(m_canvas); switch (m_type) { case UnknownType: @@ -475,7 +474,7 @@ void WebThemeControlDRTWin::draw() } markState(); - m_canvas->endPlatformPaint(); + skia::EndPlatformPaint(m_canvas); } // Because rendering a text field is dependent on input @@ -485,7 +484,7 @@ void WebThemeControlDRTWin::drawTextField(bool drawEdges, bool fillContentArea, { SkPaint paint; - m_canvas->beginPlatformPaint(); + skia::BeginPlatformPaint(m_canvas); if (fillContentArea) { paint.setColor(color); paint.setStyle(SkPaint::kFill_Style); @@ -498,14 +497,14 @@ void WebThemeControlDRTWin::drawTextField(bool drawEdges, bool fillContentArea, } markState(); - m_canvas->endPlatformPaint(); + skia::EndPlatformPaint(m_canvas); } void WebThemeControlDRTWin::drawProgressBar(const SkIRect& fillRect) { SkPaint paint; - m_canvas->beginPlatformPaint(); + skia::BeginPlatformPaint(m_canvas); paint.setColor(m_bgColor); paint.setStyle(SkPaint::kFill_Style); m_canvas->drawIRect(m_irect, paint); @@ -518,6 +517,6 @@ void WebThemeControlDRTWin::drawProgressBar(const SkIRect& fillRect) m_canvas->drawIRect(tofill, paint); markState(); - m_canvas->endPlatformPaint(); + skia::EndPlatformPaint(m_canvas); } diff --git a/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.h b/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.h index ede1458..6448dc6 100644 --- a/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.h +++ b/Tools/DumpRenderTree/chromium/WebThemeControlDRTWin.h @@ -120,12 +120,9 @@ public: ProgressBarType }; - // canvas is the canvas to draw onto, and rect gives the size of the - // control. ctype and cstate specify the type and state of the control. - WebThemeControlDRTWin(skia::PlatformCanvas* canvas, - const SkIRect& rect, - Type ctype, - State cstate); + // Constructs a control of the given size, type and state to draw + // on to the given canvas. + WebThemeControlDRTWin(SkCanvas*, const SkIRect&, Type, State); ~WebThemeControlDRTWin(); // Draws the control. @@ -184,7 +181,7 @@ private: // color is which. void markState(); - skia::PlatformCanvas* m_canvas; + SkCanvas* m_canvas; const SkIRect m_irect; const Type m_type; const State m_state; diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.cpp b/Tools/DumpRenderTree/chromium/WebViewHost.cpp index 97c00e2..ae4a1b1 100644 --- a/Tools/DumpRenderTree/chromium/WebViewHost.cpp +++ b/Tools/DumpRenderTree/chromium/WebViewHost.cpp @@ -66,7 +66,6 @@ using namespace WebCore; using namespace WebKit; -using namespace skia; using namespace std; static const int screenWidth = 1920; @@ -406,7 +405,7 @@ bool WebViewHost::handleCurrentKeyboardEvent() return frame->executeCommand(WebString::fromUTF8(m_editCommandName), WebString::fromUTF8(m_editCommandValue)); } -void WebViewHost::spellCheck(const WebString& text, int& misspelledOffset, int& misspelledLength) +void WebViewHost::spellCheck(const WebString& text, int& misspelledOffset, int& misspelledLength, WebVector<WebString>* optionalSuggestions) { // Check the spelling of the given text. m_spellcheck.spellCheckWord(text, &misspelledOffset, &misspelledLength); @@ -933,7 +932,7 @@ void WebViewHost::didClearWindowObject(WebFrame* frame) m_shell->bindJSObjectsToWindow(frame); } -void WebViewHost::didReceiveTitle(WebFrame* frame, const WebString& title) +void WebViewHost::didReceiveTitle(WebFrame* frame, const WebString& title, WebTextDirection direction) { WebCString title8 = title.utf8(); @@ -946,6 +945,7 @@ void WebViewHost::didReceiveTitle(WebFrame* frame, const WebString& title) printf("TITLE CHANGED: %s\n", title8.data()); setPageTitle(title); + layoutTestController()->setTitleTextDirection(direction); } void WebViewHost::didFinishDocumentLoad(WebFrame* frame) @@ -1470,8 +1470,9 @@ void WebViewHost::paintRect(const WebRect& rect) ASSERT(!m_isPainting); ASSERT(canvas()); m_isPainting = true; -#if PLATFORM(CG) - webWidget()->paint(canvas()->getTopPlatformDevice().GetBitmapContext(), rect); +#if USE(CG) + webWidget()->paint(skia::BeginPlatformPaint(canvas()), rect); + skia::EndPlatformPaint(canvas()); #else webWidget()->paint(canvas(), rect); #endif @@ -1512,13 +1513,14 @@ void WebViewHost::paintInvalidatedRegion() ASSERT(m_paintRect.isEmpty()); } -PlatformCanvas* WebViewHost::canvas() +SkCanvas* WebViewHost::canvas() { if (m_canvas) return m_canvas.get(); WebSize widgetSize = webWidget()->size(); resetScrollRect(); - m_canvas.set(new PlatformCanvas(widgetSize.width, widgetSize.height, true)); + m_canvas.set(skia::CreateBitmapCanvas( + widgetSize.width, widgetSize.height, true)); return m_canvas.get(); } diff --git a/Tools/DumpRenderTree/chromium/WebViewHost.h b/Tools/DumpRenderTree/chromium/WebViewHost.h index 014be2e..3251823 100644 --- a/Tools/DumpRenderTree/chromium/WebViewHost.h +++ b/Tools/DumpRenderTree/chromium/WebViewHost.h @@ -45,7 +45,9 @@ #include <wtf/text/WTFString.h> class LayoutTestController; +class SkCanvas; class TestShell; + namespace WebKit { class WebFrame; class WebDeviceOrientationClient; @@ -61,9 +63,6 @@ struct WebRect; struct WebURLError; struct WebWindowFeatures; } -namespace skia { -class PlatformCanvas; -} class WebViewHost : public WebKit::WebSpellCheckClient, public WebKit::WebViewClient, public WebKit::WebFrameClient, public NavigationHost { public: @@ -87,7 +86,7 @@ class WebViewHost : public WebKit::WebSpellCheckClient, public WebKit::WebViewCl void paintRect(const WebKit::WebRect&); void updatePaintRect(const WebKit::WebRect&); void paintInvalidatedRegion(); - skia::PlatformCanvas* canvas(); + SkCanvas* canvas(); void displayRepaintMask(); void loadURLForFrame(const WebKit::WebURL&, const WebKit::WebString& frameName); @@ -106,7 +105,7 @@ class WebViewHost : public WebKit::WebSpellCheckClient, public WebKit::WebViewCl virtual bool navigate(const TestNavigationEntry&, bool reload); // WebKit::WebSpellCheckClient - virtual void spellCheck(const WebKit::WebString&, int& offset, int& length); + virtual void spellCheck(const WebKit::WebString&, int& offset, int& length, WebKit::WebVector<WebKit::WebString>* optionalSuggestions); virtual void requestCheckingOfText(const WebKit::WebString&, WebKit::WebTextCheckingCompletion*); virtual WebKit::WebString autoCorrectWord(const WebKit::WebString&); @@ -193,7 +192,7 @@ class WebViewHost : public WebKit::WebSpellCheckClient, public WebKit::WebViewCl virtual void didFailProvisionalLoad(WebKit::WebFrame*, const WebKit::WebURLError&); virtual void didCommitProvisionalLoad(WebKit::WebFrame*, bool isNewNavigation); virtual void didClearWindowObject(WebKit::WebFrame*); - virtual void didReceiveTitle(WebKit::WebFrame*, const WebKit::WebString&); + virtual void didReceiveTitle(WebKit::WebFrame*, const WebKit::WebString&, WebKit::WebTextDirection); virtual void didFinishDocumentLoad(WebKit::WebFrame*); virtual void didHandleOnloadEvents(WebKit::WebFrame*); virtual void didFailLoad(WebKit::WebFrame*, const WebKit::WebURLError&); @@ -333,7 +332,7 @@ private: MockSpellCheck m_spellcheck; // Painting. - OwnPtr<skia::PlatformCanvas> m_canvas; + OwnPtr<SkCanvas> m_canvas; WebKit::WebRect m_paintRect; bool m_isPainting; diff --git a/Tools/DumpRenderTree/config.h b/Tools/DumpRenderTree/config.h index 90cfcf6..bde0cc8 100644 --- a/Tools/DumpRenderTree/config.h +++ b/Tools/DumpRenderTree/config.h @@ -48,8 +48,8 @@ #define WEBKIT_EXPORTDATA #endif -#define WTF_EXPORT_PRIVATE JS_EXPORTDATA -#define JS_EXPORT_PRIVATE JS_EXPORTDATA +#define WTF_EXPORT_PRIVATE +#define JS_EXPORT_PRIVATE #endif /* USE(EXPORT_MACROS) */ @@ -74,10 +74,10 @@ #if PLATFORM(WIN) #define WTF_USE_CF 1 #if defined(WIN_CAIRO) -#define WTF_PLATFORM_CAIRO 1 +#define WTF_USE_CAIRO 1 #define WTF_USE_CURL 1 #else -#define WTF_PLATFORM_CG 1 +#define WTF_USE_CG 1 #define WTF_USE_CFNETWORK 1 #endif diff --git a/Tools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp b/Tools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp index ff76e4b..8a4a490 100644 --- a/Tools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp +++ b/Tools/DumpRenderTree/gtk/AccessibilityUIElementGtk.cpp @@ -26,15 +26,14 @@ #include "config.h" #include "AccessibilityUIElement.h" + #include "GOwnPtr.h" #include "GRefPtr.h" - +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include <JavaScriptCore/JSStringRef.h> -#include <wtf/Assertions.h> - #include <atk/atk.h> #include <gtk/gtk.h> - +#include <wtf/Assertions.h> AccessibilityUIElement::AccessibilityUIElement(PlatformUIElement element) : m_element(element) @@ -488,16 +487,56 @@ int AccessibilityUIElement::indexInTable() return 0; } +static JSStringRef indexRangeInTable(PlatformUIElement element, bool isRowRange) +{ + GOwnPtr<gchar> rangeString(g_strdup("{0, 0}")); + + if (!element) + return JSStringCreateWithUTF8CString(rangeString.get()); + + ASSERT(ATK_IS_OBJECT(element)); + + AtkObject* axTable = atk_object_get_parent(ATK_OBJECT(element)); + if (!axTable || !ATK_IS_TABLE(axTable)) + return JSStringCreateWithUTF8CString(rangeString.get()); + + // Look for the cell in the table. + gint indexInParent = atk_object_get_index_in_parent(ATK_OBJECT(element)); + if (indexInParent == -1) + return JSStringCreateWithUTF8CString(rangeString.get()); + + int row = -1; + int column = -1; + row = atk_table_get_row_at_index(ATK_TABLE(axTable), indexInParent); + column = atk_table_get_column_at_index(ATK_TABLE(axTable), indexInParent); + + // Get the actual values, if row and columns are valid values. + if (row != -1 && column != -1) { + int base = 0; + int length = 0; + if (isRowRange) { + base = row; + length = atk_table_get_row_extent_at(ATK_TABLE(axTable), row, column); + } else { + base = column; + length = atk_table_get_column_extent_at(ATK_TABLE(axTable), row, column); + } + rangeString.set(g_strdup_printf("{%d, %d}", base, length)); + } + + return JSStringCreateWithUTF8CString(rangeString.get()); +} + JSStringRef AccessibilityUIElement::rowIndexRange() { - // FIXME: implement - return JSStringCreateWithCharacters(0, 0); + // Range in table for rows. + return indexRangeInTable(m_element, true); } JSStringRef AccessibilityUIElement::columnIndexRange() { - // FIXME: implement - return JSStringCreateWithCharacters(0, 0); + // Range in table for columns. + return indexRangeInTable(m_element, false); } int AccessibilityUIElement::lineForIndex(int) @@ -532,8 +571,13 @@ bool AccessibilityUIElement::attributedStringRangeIsMisspelled(unsigned location AccessibilityUIElement AccessibilityUIElement::cellForColumnAndRow(unsigned column, unsigned row) { - // FIXME: implement - return 0; + if (!m_element) + return 0; + + ASSERT(ATK_IS_TABLE(m_element)); + + AtkObject* foundCell = atk_table_ref_at(ATK_TABLE(m_element), row, column); + return foundCell ? AccessibilityUIElement(foundCell) : 0; } JSStringRef AccessibilityUIElement::selectedTextRange() @@ -572,12 +616,20 @@ bool AccessibilityUIElement::isAttributeSupported(JSStringRef attribute) void AccessibilityUIElement::increment() { - // FIXME: implement + if (!m_element) + return; + + ASSERT(ATK_IS_OBJECT(m_element)); + DumpRenderTreeSupportGtk::incrementAccessibilityValue(ATK_OBJECT(m_element)); } void AccessibilityUIElement::decrement() { - // FIXME: implement + if (!m_element) + return; + + ASSERT(ATK_IS_OBJECT(m_element)); + DumpRenderTreeSupportGtk::decrementAccessibilityValue(ATK_OBJECT(m_element)); } void AccessibilityUIElement::press() diff --git a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp index f768b43..a281e48 100644 --- a/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/gtk/DumpRenderTree.cpp @@ -39,6 +39,7 @@ #include "GOwnPtr.h" #include "LayoutTestController.h" #include "PixelDumpSupport.h" +#include "PlainTextController.h" #include "TextInputController.h" #include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include "WorkQueue.h" @@ -814,6 +815,13 @@ static void webViewOnloadEvent(WebKitWebView* view, WebKitWebFrame* frame, void* } } +static void addControllerToWindow(JSContextRef context, JSObjectRef windowObject, const char* controllerName, JSValueRef controller) +{ + JSStringRef controllerNameStr = JSStringCreateWithUTF8CString(controllerName); + JSObjectSetProperty(context, windowObject, controllerNameStr, controller, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); + JSStringRelease(controllerNameStr); +} + static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* frame, JSGlobalContextRef context, JSObjectRef windowObject, gpointer data) { JSValueRef exception = 0; @@ -828,15 +836,9 @@ static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* fram axController->makeWindowObject(context, windowObject, &exception); ASSERT(!exception); - JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender"); - JSValueRef eventSender = makeEventSender(context, !webkit_web_frame_get_parent(frame)); - JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); - JSStringRelease(eventSenderStr); - - JSStringRef textInputControllerStr = JSStringCreateWithUTF8CString("textInputController"); - JSValueRef textInputController = makeTextInputController(context); - JSObjectSetProperty(context, windowObject, textInputControllerStr, textInputController, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); - JSStringRelease(textInputControllerStr); + addControllerToWindow(context, windowObject, "eventSender", makeEventSender(context, !webkit_web_frame_get_parent(frame))); + addControllerToWindow(context, windowObject, "plainText", makePlainTextController(context)); + addControllerToWindow(context, windowObject, "textInputController", makeTextInputController(context)); } static gboolean webViewConsoleMessage(WebKitWebView* view, const gchar* message, unsigned int line, const gchar* sourceId, gpointer data) @@ -941,10 +943,8 @@ static void webViewStatusBarTextChanged(WebKitWebView* view, const gchar* messag { // Are we doing anything wrong? One test that does not call // dumpStatusCallbacks gets true here - if (gLayoutTestController->dumpStatusCallbacks()) { - if (message && strcmp(message, "")) - printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message); - } + if (gLayoutTestController->dumpStatusCallbacks()) + printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", message); } static gboolean webViewClose(WebKitWebView* view) @@ -1048,6 +1048,9 @@ static void frameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* webFram static void willSendRequestCallback(WebKitWebView* webView, WebKitWebFrame*, WebKitWebResource*, WebKitNetworkRequest* request, WebKitNetworkResponse*) { + if (!done && gLayoutTestController->willSendRequestReturnsNull()) + return; + SoupMessage* soupMessage = webkit_network_request_get_message(request); SoupURI* uri = soup_uri_new(webkit_network_request_get_uri(request)); @@ -1058,8 +1061,8 @@ static void willSendRequestCallback(WebKitWebView* webView, WebKitWebFrame*, Web soup_uri_free(uri); return; } - soup_uri_free(uri); - + if (uri) + soup_uri_free(uri); if (soupMessage) { const set<string>& clearHeaders = gLayoutTestController->willSendRequestClearHeaders(); diff --git a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp index c26e2db..29742be 100644 --- a/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp +++ b/Tools/DumpRenderTree/gtk/LayoutTestControllerGtk.cpp @@ -778,6 +778,8 @@ void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value propertyName = "enable-plugins"; else if (g_str_equal(originalName.get(), "WebKitHyperlinkAuditingEnabled")) propertyName = "enable-hyperlink-auditing"; + else if (g_str_equal(originalName.get(), "WebKitWebGLEnabled")) + propertyName = "enable-webgl"; else if (g_str_equal(originalName.get(), "WebKitTabToLinksPreferenceKey")) { DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(!g_ascii_strcasecmp(valueAsString.get(), "true") || !g_ascii_strcasecmp(valueAsString.get(), "1")); return; @@ -917,6 +919,11 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior) g_object_set(G_OBJECT(settings), "editing-behavior", WEBKIT_EDITING_BEHAVIOR_UNIX, NULL); } +JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef element) +{ + return DumpRenderTreeSupportGtk::shadowRoot(context, element); +} + void LayoutTestController::abortModal() { } diff --git a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp index 1e591bb..2bd8fe2 100644 --- a/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp +++ b/Tools/DumpRenderTree/gtk/PixelDumpSupportGtk.cpp @@ -32,9 +32,10 @@ #include "DumpRenderTree.h" #include "GtkVersioning.h" #include "PixelDumpSupportCairo.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" #include <webkit/webkit.h> -PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) +PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool drawSelectionRect) { WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); GtkWidget* viewContainer = gtk_widget_get_parent(GTK_WIDGET(view)); @@ -49,6 +50,7 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) cairo_surface_t* imageSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); cairo_t* context = cairo_create(imageSurface); + #ifdef GTK_API_VERSION_2 gdk_cairo_set_source_pixmap(context, pixmap, 0, 0); cairo_paint(context); @@ -57,5 +59,15 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool, bool, bool, bool) gtk_widget_draw(viewContainer, context); #endif + if (drawSelectionRect) { + GdkRectangle rectangle; + DumpRenderTreeSupportGtk::rectangleForSelection(mainFrame, &rectangle); + + cairo_set_line_width(context, 1.0); + cairo_rectangle(context, rectangle.x, rectangle.y, rectangle.width, rectangle.height); + cairo_set_source_rgba(context, 1.0, 0.0, 0.0, 1.0); + cairo_stroke(context); + } + return BitmapContext::createByAdoptingBitmapAndContext(0, context); } diff --git a/Tools/DumpRenderTree/gtk/PlainTextController.cpp b/Tools/DumpRenderTree/gtk/PlainTextController.cpp new file mode 100644 index 0000000..25e251a --- /dev/null +++ b/Tools/DumpRenderTree/gtk/PlainTextController.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PlainTextController.h" + +#include "DumpRenderTree.h" +#include "WebCoreSupport/DumpRenderTreeSupportGtk.h" +#include <GOwnPtrGtk.h> +#include <JavaScriptCore/JSObjectRef.h> +#include <JavaScriptCore/JSRetainPtr.h> +#include <JavaScriptCore/JSStringRef.h> +#include <webkit/webkit.h> + +static JSValueRef plainTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) +{ + g_return_val_if_fail(argumentCount == 1, JSValueMakeUndefined(context)); + WebKitDOMRange* kitRange = DumpRenderTreeSupportGtk::jsValueToDOMRange(context, arguments[0]); + g_return_val_if_fail(kitRange, JSValueMakeUndefined(context)); + + GOwnPtr<gchar> text(webkit_dom_range_get_text(kitRange)); + JSRetainPtr<JSStringRef> jsText(Adopt, JSStringCreateWithUTF8CString(text.get())); + return JSValueMakeString(context, jsText.get()); +} + +JSObjectRef makePlainTextController(JSContextRef context) +{ + static JSStaticFunction staticFunctions[] = { + { "plainText", plainTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, + { 0, 0, 0 } + }; + + static JSClassRef plainTextControllerClass = 0; + if (!plainTextControllerClass) { + JSClassDefinition classDefinition = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + classDefinition.staticFunctions = staticFunctions; + plainTextControllerClass = JSClassCreate(&classDefinition); + } + return JSObjectMake(context, plainTextControllerClass, 0); +} diff --git a/Tools/DumpRenderTree/gtk/PlainTextController.h b/Tools/DumpRenderTree/gtk/PlainTextController.h new file mode 100644 index 0000000..dadfc13 --- /dev/null +++ b/Tools/DumpRenderTree/gtk/PlainTextController.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PlainTextController_h +#define PlainTextController_h + +typedef const struct OpaqueJSContext* JSContextRef; +typedef struct OpaqueJSValue* JSObjectRef; + +JSObjectRef makePlainTextController(JSContextRef); + +#endif diff --git a/Tools/DumpRenderTree/gtk/TextInputController.cpp b/Tools/DumpRenderTree/gtk/TextInputController.cpp index 7243fdc..d1aa33d 100644 --- a/Tools/DumpRenderTree/gtk/TextInputController.cpp +++ b/Tools/DumpRenderTree/gtk/TextInputController.cpp @@ -36,6 +36,7 @@ #include <JavaScriptCore/JSRetainPtr.h> #include <JavaScriptCore/JSStringRef.h> #include <cstring> +#include <webkit/webkit.h> static JSValueRef setMarkedTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { diff --git a/Tools/DumpRenderTree/mac/DumpRenderTree.mm b/Tools/DumpRenderTree/mac/DumpRenderTree.mm index 207e8fb..441f6bb 100644 --- a/Tools/DumpRenderTree/mac/DumpRenderTree.mm +++ b/Tools/DumpRenderTree/mac/DumpRenderTree.mm @@ -455,6 +455,7 @@ static void resetDefaultsToConsistentValues() [preferences setOfflineWebApplicationCacheEnabled:YES]; [preferences setDeveloperExtrasEnabled:NO]; [preferences setLoadsImagesAutomatically:YES]; + [preferences setLoadsSiteIconsIgnoringImageLoadingPreference:NO]; [preferences setFrameFlatteningEnabled:NO]; [preferences setSpatialNavigationEnabled:NO]; [preferences setEditingBehavior:WebKitEditingMacBehavior]; @@ -468,6 +469,10 @@ static void resetDefaultsToConsistentValues() // So, turn it off for now, but we might want to turn it back on some day. [preferences setUsesPageCache:NO]; [preferences setAcceleratedCompositingEnabled:YES]; +#if USE(CA) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + [preferences setCanvasUsesAcceleratedDrawing:YES]; + [preferences setAcceleratedDrawingEnabled:NO]; +#endif [preferences setWebGLEnabled:NO]; [preferences setUsePreHTML5ParserQuirks:NO]; [preferences setAsynchronousSpellCheckingEnabled:NO]; @@ -730,6 +735,14 @@ static NSInteger compareHistoryItems(id item1, id item2, void *context) return [[item1 target] caseInsensitiveCompare:[item2 target]]; } +static NSData *dumpAudio() +{ + const char *encodedAudioData = gLayoutTestController->encodedAudioData().c_str(); + + NSData *data = [NSData dataWithBytes:encodedAudioData length:gLayoutTestController->encodedAudioData().length()]; + return data; +} + static void dumpHistoryItem(WebHistoryItem *item, int indent, BOOL current) { int start = 0; @@ -933,7 +946,10 @@ void dump() gLayoutTestController->setDumpAsText(true); gLayoutTestController->setGeneratePixelResults(false); } - if (gLayoutTestController->dumpAsText()) { + if (gLayoutTestController->dumpAsAudio()) { + resultData = dumpAudio(); + resultMimeType = @"audio/wav"; + } else if (gLayoutTestController->dumpAsText()) { resultString = dumpFramesAsText(mainFrame); } else if (gLayoutTestController->dumpAsPDF()) { resultData = dumpFrameAsPDF(mainFrame); @@ -956,6 +972,9 @@ void dump() printf("Content-Type: %s\n", [resultMimeType UTF8String]); + if (gLayoutTestController->dumpAsAudio()) + printf("Content-Transfer-Encoding: base64\n"); + if (resultData) { fwrite([resultData bytes], 1, [resultData length], stdout); @@ -1022,6 +1041,7 @@ static void resetWebViewToConsistentStateBeforeTesting() [(EditingDelegate *)[webView editingDelegate] setAcceptsEditing:YES]; [webView makeTextStandardSize:nil]; [webView resetPageZoom:nil]; + [webView _scaleWebView:1.0 atOrigin:NSZeroPoint]; [webView setTabKeyCyclesThroughElements:YES]; [webView setPolicyDelegate:nil]; [policyDelegate setPermissive:NO]; diff --git a/Tools/DumpRenderTree/mac/EventSendingController.mm b/Tools/DumpRenderTree/mac/EventSendingController.mm index 9031c63..4497105 100644 --- a/Tools/DumpRenderTree/mac/EventSendingController.mm +++ b/Tools/DumpRenderTree/mac/EventSendingController.mm @@ -135,6 +135,7 @@ BOOL replayingSavedEvents; || aSelector == @selector(textZoomOut) || aSelector == @selector(zoomPageIn) || aSelector == @selector(zoomPageOut) + || aSelector == @selector(scalePageBy:atX:andY:) || aSelector == @selector(mouseScrollByX:andY:) || aSelector == @selector(continuousMouseScrollByX:andY:)) return NO; @@ -174,6 +175,8 @@ BOOL replayingSavedEvents; return @"mouseScrollBy"; if (aSelector == @selector(continuousMouseScrollByX:andY:)) return @"continuousMouseScrollBy"; + if (aSelector == @selector(scalePageBy:atX:andY:)) + return @"scalePageBy"; return nil; } @@ -361,6 +364,11 @@ static int buildModifierFlags(const WebScriptObject* modifiers) [[mainFrame webView] zoomPageOut:self]; } +- (void)scalePageBy:(float)scale atX:(float)x andY:(float)y +{ + [[mainFrame webView] _scaleWebView:scale atOrigin:NSMakePoint(x, y)]; +} + - (void)mouseUp:(int)buttonNumber withModifiers:(WebScriptObject*)modifiers { if (dragMode && !replayingSavedEvents) { diff --git a/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm b/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm index 66c0cce..4ebf271 100644 --- a/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm +++ b/Tools/DumpRenderTree/mac/LayoutTestControllerMac.mm @@ -1068,6 +1068,14 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior) [editingBehaviorNS release]; } +JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef jsElement) +{ + DOMElement *element = [DOMElement _DOMElementFromJSContext:context value:jsElement]; + if (!element) + return JSValueMakeNull(context); + return [element _shadowRoot:context]; +} + void LayoutTestController::abortModal() { [NSApp abortModal]; diff --git a/Tools/DumpRenderTree/qt/DumpRenderTree.pro b/Tools/DumpRenderTree/qt/DumpRenderTree.pro index a76b886..242651d 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTree.pro +++ b/Tools/DumpRenderTree/qt/DumpRenderTree.pro @@ -1,6 +1,6 @@ TARGET = DumpRenderTree CONFIG -= app_bundle -CONFIG += uitools +!isEqual(QT_ARCH,sh4): CONFIG += uitools BASEDIR = $$PWD/../ isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../.. @@ -13,7 +13,7 @@ INCLUDEPATH += ../../../Source/WebKit/qt/WebCoreSupport INCLUDEPATH += $$BASEDIR DESTDIR = ../../bin -unix:!mac:!symbian { +unix:!mac:!symbian:!embedded { CONFIG += link_pkgconfig PKGCONFIG += fontconfig } diff --git a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp index 97d9f20..1a6c833 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp +++ b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.cpp @@ -190,6 +190,7 @@ void WebPage::resetSettings() settings()->resetAttribute(QWebSettings::LinksIncludedInFocusChain); settings()->resetAttribute(QWebSettings::OfflineWebApplicationCacheEnabled); settings()->resetAttribute(QWebSettings::LocalContentCanAccessRemoteUrls); + settings()->resetAttribute(QWebSettings::LocalContentCanAccessFileUrls); settings()->resetAttribute(QWebSettings::PluginsEnabled); settings()->resetAttribute(QWebSettings::JavascriptCanAccessClipboard); settings()->resetAttribute(QWebSettings::AutoLoadImages); @@ -997,6 +998,8 @@ void DumpRenderTree::dump() } if (dumpImage) { + image.setText("checksum", actualHash); + QBuffer buffer; buffer.open(QBuffer::WriteOnly); image.save(&buffer, "PNG"); @@ -1136,6 +1139,17 @@ void DumpRenderTree::switchFocus(bool focused) } +QList<WebPage*> DumpRenderTree::getAllPages() const +{ + QList<WebPage*> pages; + pages.append(m_page); + foreach (QObject* widget, windows) { + if (WebPage* page = widget->findChild<WebPage*>()) + pages.append(page); + } + return pages; +} + #if defined(Q_WS_X11) void DumpRenderTree::initializeFonts() { diff --git a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h index 858856f..cb66296 100644 --- a/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h +++ b/Tools/DumpRenderTree/qt/DumpRenderTreeQt.h @@ -100,6 +100,7 @@ public: void switchFocus(bool focused); WebPage *webPage() const { return m_page; } + QList<WebPage*> getAllPages() const; #if defined(Q_WS_X11) static void initializeFonts(); diff --git a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp index 4e3087e..d9f1a74 100644 --- a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp +++ b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.cpp @@ -780,10 +780,19 @@ void LayoutTestController::setGeolocationPermission(bool allow) DumpRenderTreeSupportQt::setMockGeolocationPermission(m_drt->webPage(), allow); } +QVariant LayoutTestController::shadowRoot(const QWebElement& element) +{ + return DumpRenderTreeSupportQt::shadowRoot(element); +} + int LayoutTestController::numberOfPendingGeolocationPermissionRequests() { - // FIXME: Implement for Geolocation layout tests. - return -1; + int pendingPermissionCount = 0; + QList<WebCore::WebPage*> pages = m_drt->getAllPages(); + foreach (WebCore::WebPage* page, pages) + pendingPermissionCount += DumpRenderTreeSupportQt::numberOfPendingGeolocationPermissionRequests(page); + + return pendingPermissionCount; } void LayoutTestController::setGeolocationPermissionCommon(bool allow) diff --git a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h index f29233a..2c33401 100644 --- a/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h +++ b/Tools/DumpRenderTree/qt/LayoutTestControllerQt.h @@ -197,7 +197,7 @@ public slots: void clearAllDatabases(); void setIconDatabaseEnabled(bool enable); - void setCustomPolicyDelegate(bool enabled, bool permissive = true); + void setCustomPolicyDelegate(bool enabled, bool permissive = false); void waitForPolicyDelegate(); void overridePreference(const QString& name, const QVariant& value); @@ -249,6 +249,8 @@ public slots: void setEditingBehavior(const QString& editingBehavior); + QVariant shadowRoot(const QWebElement&); + void evaluateScriptInIsolatedWorld(int worldID, const QString& script); bool isPageBoxVisible(int pageIndex); QString pageSizeAndMarginsInPixels(int pageIndex, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft); diff --git a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index 6741668..e03c876 100644 --- a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -33,6 +33,7 @@ SOURCES = PluginObject.cpp \ Tests/GetURLWithJavaScriptURLDestroyingPlugin.cpp \ Tests/GetUserAgentWithNullNPPFromNPPNew.cpp \ Tests/NPDeallocateCalledBeforeNPShutdown.cpp \ + Tests/NPPSetWindowCalledDuringDestruction.cpp \ Tests/NPRuntimeObjectFromDestroyedPlugin.cpp \ Tests/NPRuntimeRemoveProperty.cpp \ Tests/NullNPPGetValuePointer.cpp \ diff --git a/Tools/DumpRenderTree/qt/main.cpp b/Tools/DumpRenderTree/qt/main.cpp index bc762e5..89a5128 100644 --- a/Tools/DumpRenderTree/qt/main.cpp +++ b/Tools/DumpRenderTree/qt/main.cpp @@ -54,7 +54,7 @@ #include <limits.h> #include <signal.h> -#if defined(__GLIBC__) +#if defined(__GLIBC__) && !defined(__UCLIBC__) #include <execinfo.h> #endif @@ -97,7 +97,7 @@ void printUsage() QString get_backtrace() { QString s; -#if defined(__GLIBC__) +#if defined(__GLIBC__) && !defined(__UCLIBC__) void* array[256]; size_t size; /* number of stack frames */ diff --git a/Tools/DumpRenderTree/win/DumpRenderTree.cpp b/Tools/DumpRenderTree/win/DumpRenderTree.cpp index 66e7311..2db43da 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTree.cpp +++ b/Tools/DumpRenderTree/win/DumpRenderTree.cpp @@ -168,12 +168,15 @@ wstring urlSuitableForTestResult(const wstring& urlString) return cfStringRefToWString(substringFromIndex(path.get(), CFStringGetLength(basePath.get())).get()); } -wstring lastPathComponent(const wstring& url) +wstring lastPathComponent(const wstring& urlString) { - if (url.empty()) - return url; + if (urlString.empty()) + return urlString; + + RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithBytes(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(urlString.c_str()), urlString.length() * sizeof(wstring::value_type), kCFStringEncodingUTF16, 0)); + RetainPtr<CFStringRef> lastPathComponent(CFURLCopyLastPathComponent(url.get())); - return PathFindFileNameW(url.c_str()); + return cfStringRefToWString(lastPathComponent.get()); } static string toUTF8(const wchar_t* wideString, size_t length) @@ -873,6 +876,7 @@ static void resetDefaultsToConsistentValues(IWebPreferences* preferences) prefsPrivate->setXSSAuditorEnabled(FALSE); prefsPrivate->setFrameFlatteningEnabled(FALSE); prefsPrivate->setOfflineWebApplicationCacheEnabled(TRUE); + prefsPrivate->setLoadsSiteIconsIgnoringImageLoadingPreference(FALSE); } setAlwaysAcceptCookies(false); diff --git a/Tools/DumpRenderTree/win/DumpRenderTree.vcproj b/Tools/DumpRenderTree/win/DumpRenderTree.vcproj index 39d2df2..803917a 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTree.vcproj +++ b/Tools/DumpRenderTree/win/DumpRenderTree.vcproj @@ -515,6 +515,14 @@ > </File> <File + RelativePath="..\CyclicRedundancyCheck.cpp" + > + </File> + <File + RelativePath="..\CyclicRedundancyCheck.h" + > + </File> + <File RelativePath=".\DraggingInfo.h" > </File> diff --git a/Tools/DumpRenderTree/win/DumpRenderTreeProduction.vsprops b/Tools/DumpRenderTree/win/DumpRenderTreeProduction.vsprops index 818bff2..df20c64 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTreeProduction.vsprops +++ b/Tools/DumpRenderTree/win/DumpRenderTreeProduction.vsprops @@ -6,7 +6,7 @@ InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; - $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops; .\DumpRenderTreeCommon.vsprops; .\DumpRenderTreeApple.vsprops" diff --git a/Tools/DumpRenderTree/win/DumpRenderTreeRelease.vsprops b/Tools/DumpRenderTree/win/DumpRenderTreeRelease.vsprops index c39a9cd..5f12a6b 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTreeRelease.vsprops +++ b/Tools/DumpRenderTree/win/DumpRenderTreeRelease.vsprops @@ -6,6 +6,7 @@ InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefines.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; .\DumpRenderTreeCommon.vsprops; .\DumpRenderTreeApple.vsprops" diff --git a/Tools/DumpRenderTree/win/DumpRenderTreeReleaseCairoCFLite.vsprops b/Tools/DumpRenderTree/win/DumpRenderTreeReleaseCairoCFLite.vsprops index 508e8c5..27fefbb 100644 --- a/Tools/DumpRenderTree/win/DumpRenderTreeReleaseCairoCFLite.vsprops +++ b/Tools/DumpRenderTree/win/DumpRenderTreeReleaseCairoCFLite.vsprops @@ -6,6 +6,7 @@ InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\FeatureDefinesCairo.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\cURL.vsprops; diff --git a/Tools/DumpRenderTree/win/ImageDiff.vcproj b/Tools/DumpRenderTree/win/ImageDiff.vcproj index 7094fec..66d4b65 100644 --- a/Tools/DumpRenderTree/win/ImageDiff.vcproj +++ b/Tools/DumpRenderTree/win/ImageDiff.vcproj @@ -199,6 +199,7 @@ </Configuration> <Configuration Name="Debug_Cairo_CFLite|Win32" + IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" InheritedPropertySheets=".\ImageDiffDebugCairoCFLite.vsprops" CharacterSet="2" @@ -386,8 +387,60 @@ </References> <Files> <File + RelativePath="..\win\ImageDiffCairo.cpp" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug_All|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Production|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File RelativePath="..\cg\ImageDiffCG.cpp" > + <FileConfiguration + Name="Debug_Cairo_CFLite|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release_Cairo_CFLite|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> </File> </Files> <Globals> diff --git a/Tools/DumpRenderTree/win/ImageDiffCairo.cpp b/Tools/DumpRenderTree/win/ImageDiffCairo.cpp new file mode 100644 index 0000000..d10cc14 --- /dev/null +++ b/Tools/DumpRenderTree/win/ImageDiffCairo.cpp @@ -0,0 +1,260 @@ +/* + * Copyright (C) 2005, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2005 Ben La Monica <ben.lamonica@gmail.com>. All rights reserved. + * Copyright (C) 2011 Brent Fulgham. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + */ + +// FIXME: We need to be able to include these defines from a config.h somewhere. +#define JS_EXPORT_PRIVATE +#define WTF_EXPORT_PRIVATE + +#include <cairo.h> +#include <stdio.h> +#include <wtf/Platform.h> +#include <wtf/RefPtr.h> +#include <wtf/RetainPtr.h> + +#if PLATFORM(WIN) +#include <fcntl.h> +#include <io.h> +#include <windows.h> +#include <wtf/MathExtras.h> +#endif + +using namespace std; + +static const int s_bufferSize = 2048; +static const int s_bytesPerPixel = 4; +static cairo_user_data_key_t s_imageDataKey; + + +#if PLATFORM(WIN) +#undef min +#undef max + +static inline float strtof(const char* inputString, char** endptr) +{ + return strtod(inputString, endptr); +} +#endif + +static cairo_status_t readFromData(void* closure, unsigned char* data, unsigned int length) +{ + CFMutableDataRef dataSource = reinterpret_cast<CFMutableDataRef>(closure); + + CFRange range = CFRangeMake(0, length); + CFDataGetBytes(dataSource, range, data); + CFDataDeleteBytes(dataSource, range); + + return CAIRO_STATUS_SUCCESS; +} + +static cairo_surface_t* createImageFromStdin(int bytesRemaining) +{ + unsigned char buffer[s_bufferSize]; + RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(0, bytesRemaining)); + + while (bytesRemaining > 0) { + size_t bytesToRead = min(bytesRemaining, s_bufferSize); + size_t bytesRead = fread(buffer, 1, bytesToRead, stdin); + CFDataAppendBytes(data.get(), buffer, static_cast<CFIndex>(bytesRead)); + bytesRemaining -= static_cast<int>(bytesRead); + } + + return cairo_image_surface_create_from_png_stream (static_cast<cairo_read_func_t>(readFromData), data.get()); +} + +static void releaseMallocBuffer(void* data) +{ + free(data); +} + +static inline float pixelDifference(float expected, float actual) +{ + return (actual - expected) / max<float>(255 - expected, expected); +} + +static inline void normalizeBuffer(float maxDistance, unsigned char* buffer, size_t length) +{ + if (maxDistance >= 1) + return; + + for (size_t p = 0; p < length; ++p) + buffer[p] /= maxDistance; +} + +static cairo_surface_t* createDifferenceImage(cairo_surface_t* baselineImage, cairo_surface_t* actualImage, float& difference) +{ + size_t width = cairo_image_surface_get_width(baselineImage); + size_t height = cairo_image_surface_get_height(baselineImage); + + unsigned char* baselinePixel = cairo_image_surface_get_data(baselineImage); + unsigned char* actualPixel = cairo_image_surface_get_data(actualImage); + + // Compare the content of the 2 bitmaps + void* diffBuffer = malloc(width * height); + unsigned char* diffPixel = reinterpret_cast<unsigned char*>(diffBuffer); + + float count = 0; + float sum = 0; + float maxDistance = 0; + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < width; ++x) { + float red = pixelDifference(baselinePixel[0], actualPixel[0]); + float green = pixelDifference(baselinePixel[1], actualPixel[1]); + float blue = pixelDifference(baselinePixel[2], actualPixel[2]); + float alpha = pixelDifference(baselinePixel[3], actualPixel[3]); + + float distance = sqrtf(red * red + green * green + blue * blue + alpha * alpha) / 2.0; + + *diffPixel++ = static_cast<unsigned char>(distance * 255); + + if (distance >= 1.0 / 255.0) { + ++count; + sum += distance; + if (distance > maxDistance) + maxDistance = distance; + } + + baselinePixel += s_bytesPerPixel; + actualPixel += s_bytesPerPixel; + } + } + + // Compute the difference as a percentage combining both the number of different pixels and their difference amount i.e. the average distance over the entire image + if (count > 0) + difference = 100.0f * sum / (height * width); + else + difference = 0; + + if (!difference) { + free(diffBuffer); + return 0; + } + + // Generate a normalized diff image + normalizeBuffer(maxDistance, reinterpret_cast<unsigned char*>(diffBuffer), height * width); + + cairo_surface_t* diffImage = cairo_image_surface_create_for_data(diffPixel, CAIRO_FORMAT_ARGB32, width, height, width * s_bytesPerPixel); + cairo_surface_set_user_data(diffImage, &s_imageDataKey, diffBuffer, releaseMallocBuffer); + + return diffImage; +} + +static inline bool imageHasAlpha(cairo_surface_t* image) +{ + return (cairo_image_surface_get_format(image) == CAIRO_FORMAT_ARGB32); +} + +static cairo_status_t writeToData(void* closure, unsigned char* data, unsigned int length) +{ + CFMutableDataRef dataTarget = reinterpret_cast<CFMutableDataRef>(closure); + + CFDataAppendBytes(dataTarget, data, length); + + return CAIRO_STATUS_SUCCESS; +} + +int main(int argc, const char* argv[]) +{ +#if PLATFORM(WIN) + _setmode(0, _O_BINARY); + _setmode(1, _O_BINARY); +#endif + + float tolerance = 0; + + for (int i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "-t") || !strcmp(argv[i], "--tolerance")) { + if (i >= argc - 1) + exit(1); + tolerance = strtof(argv[i + 1], 0); + ++i; + continue; + } + } + + char buffer[s_bufferSize]; + cairo_surface_t* actualImage = 0; + cairo_surface_t* baselineImage = 0; + + while (fgets(buffer, sizeof(buffer), stdin)) { + char* newLineCharacter = strchr(buffer, '\n'); + if (newLineCharacter) + *newLineCharacter = '\0'; + + if (!strncmp("Content-Length: ", buffer, 16)) { + strtok(buffer, " "); + int imageSize = strtol(strtok(0, " "), 0, 10); + + if (imageSize > 0 && !actualImage) + actualImage = createImageFromStdin(imageSize); + else if (imageSize > 0 && !baselineImage) + baselineImage = createImageFromStdin(imageSize); + else + fputs("error, image size must be specified.\n", stdout); + } + + if (actualImage && baselineImage) { + cairo_surface_t* diffImage = 0; + float difference = 100.0; + + if ((cairo_image_surface_get_width(actualImage) == cairo_image_surface_get_width(baselineImage)) + && (cairo_image_surface_get_height(actualImage) == cairo_image_surface_get_height(baselineImage)) + && (imageHasAlpha(actualImage) == imageHasAlpha(baselineImage))) { + diffImage = createDifferenceImage(actualImage, baselineImage, difference); // difference is passed by reference + if (difference <= tolerance) + difference = 0; + else { + difference = roundf(difference * 100.0) / 100.0; + difference = max<float>(difference, 0.01); // round to 2 decimal places + } + } else + fputs("error, test and reference image have different properties.\n", stderr); + + if (difference > 0.0) { + if (diffImage) { + RetainPtr<CFMutableDataRef> imageData(AdoptCF, CFDataCreateMutable(0, 0)); + cairo_surface_write_to_png_stream(diffImage, (cairo_write_func_t)writeToData, imageData.get()); + printf("Content-Length: %lu\n", CFDataGetLength(imageData.get())); + fwrite(CFDataGetBytePtr(imageData.get()), 1, CFDataGetLength(imageData.get()), stdout); + cairo_surface_destroy(diffImage); + diffImage = 0; + } + + fprintf(stdout, "diff: %01.2f%% failed\n", difference); + } else + fprintf(stdout, "diff: %01.2f%% passed\n", difference); + + cairo_surface_destroy(actualImage); + cairo_surface_destroy(baselineImage); + actualImage = 0; + baselineImage = 0; + } + + fflush(stdout); + } + + return 0; +} diff --git a/Tools/DumpRenderTree/win/ImageDiffDebugCairoCFLite.vsprops b/Tools/DumpRenderTree/win/ImageDiffDebugCairoCFLite.vsprops index bd6bc8a..0205f9a 100644 --- a/Tools/DumpRenderTree/win/ImageDiffDebugCairoCFLite.vsprops +++ b/Tools/DumpRenderTree/win/ImageDiffDebugCairoCFLite.vsprops @@ -7,6 +7,6 @@ $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\debug_wincairo.vsprops; - .\ImageDiffCommon.vsprops" + .\ImageDiffWinCairoCommon.vsprops" > </VisualStudioPropertySheet> diff --git a/Tools/DumpRenderTree/win/ImageDiffProduction.vsprops b/Tools/DumpRenderTree/win/ImageDiffProduction.vsprops index 37ff9de..bd14a38 100644 --- a/Tools/DumpRenderTree/win/ImageDiffProduction.vsprops +++ b/Tools/DumpRenderTree/win/ImageDiffProduction.vsprops @@ -5,7 +5,7 @@ Name="ImageDiffProduction" InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; - $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\production.vsprops; .\ImageDiffCommon.vsprops" > diff --git a/Tools/DumpRenderTree/win/ImageDiffRelease.vsprops b/Tools/DumpRenderTree/win/ImageDiffRelease.vsprops index 79e9749..16ba125 100644 --- a/Tools/DumpRenderTree/win/ImageDiffRelease.vsprops +++ b/Tools/DumpRenderTree/win/ImageDiffRelease.vsprops @@ -5,6 +5,7 @@ Name="ImageDiffRelease" InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; .\ImageDiffCommon.vsprops" > diff --git a/Tools/DumpRenderTree/win/ImageDiffReleaseCairoCFLite.vsprops b/Tools/DumpRenderTree/win/ImageDiffReleaseCairoCFLite.vsprops index 1cb062b..7ca4b32 100644 --- a/Tools/DumpRenderTree/win/ImageDiffReleaseCairoCFLite.vsprops +++ b/Tools/DumpRenderTree/win/ImageDiffReleaseCairoCFLite.vsprops @@ -5,8 +5,9 @@ Name="ImageDiffReleaseCairoCFLite" InheritedPropertySheets=" $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\common.vsprops; + $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\releaseproduction.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\release.vsprops; $(WebKitVSPropsRedirectionDir)..\..\..\WebKitLibraries\win\tools\vsprops\WinCairo.vsprops; - .\ImageDiffCommon.vsprops" + .\ImageDiffWinCairoCommon.vsprops" > </VisualStudioPropertySheet> diff --git a/Tools/DumpRenderTree/win/ImageDiffWinCairoCommon.vsprops b/Tools/DumpRenderTree/win/ImageDiffWinCairoCommon.vsprops new file mode 100644 index 0000000..eb1b922 --- /dev/null +++ b/Tools/DumpRenderTree/win/ImageDiffWinCairoCommon.vsprops @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioPropertySheet + ProjectType="Visual C++" + Version="8.00" + Name="ImageDiffCommon" + > + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories=""$(ConfigurationBuildDir)\include";"$(ConfigurationBuildDir)\include\private";"$(ConfigurationBuildDir)\include\WebCore\ForwardingHeaders";"$(WebKitLibrariesDir)\include";"$(WebKitLibrariesDir)\include\private"" + PreprocessorDefinitions="NOMINMAX" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/NXCOMPAT" + AdditionalDependencies="JavaScriptCore$(WebKitDLLConfigSuffix).lib cairo$(LibraryConfigSuffix).lib libjpeg.lib libpng$(LibraryConfigSuffix).lib zlib.lib Msimg32.lib CFLite$(LibraryConfigSuffix).lib" + SubSystem="1" + /> +</VisualStudioPropertySheet> diff --git a/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp b/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp index 1d2f3d8..2086ae7 100644 --- a/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp +++ b/Tools/DumpRenderTree/win/LayoutTestControllerWin.cpp @@ -1441,6 +1441,12 @@ void LayoutTestController::setEditingBehavior(const char* editingBehavior) preferences->setEditingBehavior(WebKitEditingUnixBehavior); } +JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef jsElement) +{ + // FIXME: Implement this. + return JSValueMakeUndefined(context); +} + void LayoutTestController::abortModal() { } diff --git a/Tools/DumpRenderTree/win/PixelDumpSupportWin.cpp b/Tools/DumpRenderTree/win/PixelDumpSupportWin.cpp index 752cc39..f7a95d3 100644 --- a/Tools/DumpRenderTree/win/PixelDumpSupportWin.cpp +++ b/Tools/DumpRenderTree/win/PixelDumpSupportWin.cpp @@ -28,15 +28,15 @@ #include "config.h" -#if PLATFORM(CG) +#if USE(CG) #include "PixelDumpSupportCG.h" -#elif PLATFORM(CAIRO) +#elif USE(CAIRO) #include "PixelDumpSupportCairo.h" #endif #include "DumpRenderTree.h" -#if PLATFORM(CG) +#if USE(CG) // Note: Must be included *after* DumpRenderTree.h to avoid compile error. #include <CoreGraphics/CGBitmapContext.h> #endif @@ -70,11 +70,11 @@ PassRefPtr<BitmapContext> createBitmapContextFromWebView(bool onscreen, bool inc GetObject(bitmap, sizeof(info), &info); ASSERT(info.bmBitsPixel == 32); -#if PLATFORM(CG) +#if USE(CG) RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); CGContextRef context = CGBitmapContextCreate(info.bmBits, info.bmWidth, info.bmHeight, 8, info.bmWidthBytes, colorSpace.get(), kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst); -#elif PLATFORM(CAIRO) +#elif USE(CAIRO) cairo_surface_t* image = cairo_image_surface_create_for_data((unsigned char*)info.bmBits, CAIRO_FORMAT_ARGB32, info.bmWidth, info.bmHeight, info.bmWidthBytes); cairo_t* context = cairo_create(image); diff --git a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp index c45ea0e..b2a1f58 100644 --- a/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp +++ b/Tools/DumpRenderTree/wx/LayoutTestControllerWx.cpp @@ -612,3 +612,9 @@ void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL) { // FIXME: Implement. } + +const OpaqueJSValue* LayoutTestController::shadowRoot(const OpaqueJSContext*, const OpaqueJSValue*) +{ + // FIXME: Implement. + return 0; +} |