diff options
author | Ben Murdoch <benm@google.com> | 2011-05-13 16:23:25 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-16 11:35:02 +0100 |
commit | 65f03d4f644ce73618e5f4f50dd694b26f55ae12 (patch) | |
tree | f478babb801e720de7bfaee23443ffe029f58731 /Source/WebCore/platform | |
parent | 47de4a2fb7262c7ebdb9cd133ad2c54c187454d0 (diff) | |
download | external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.zip external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.gz external_webkit-65f03d4f644ce73618e5f4f50dd694b26f55ae12.tar.bz2 |
Merge WebKit at r75993: Initial merge by git.
Change-Id: I602bbdc3974787a3b0450456a30a7868286921c3
Diffstat (limited to 'Source/WebCore/platform')
166 files changed, 2120 insertions, 3815 deletions
diff --git a/Source/WebCore/platform/ContextMenuItem.h b/Source/WebCore/platform/ContextMenuItem.h index 441829f..145d795 100644 --- a/Source/WebCore/platform/ContextMenuItem.h +++ b/Source/WebCore/platform/ContextMenuItem.h @@ -42,7 +42,6 @@ class NSMenuItem; #elif PLATFORM(WIN) typedef struct tagMENUITEMINFOW MENUITEMINFO; #elif PLATFORM(GTK) -#include <GRefPtr.h> typedef struct _GtkMenuItem GtkMenuItem; #elif PLATFORM(QT) #include <QAction> @@ -288,8 +287,6 @@ namespace WebCore { #else #if PLATFORM(MAC) RetainPtr<NSMenuItem> m_platformDescription; -#elif PLATFORM(GTK) - GRefPtr<GtkMenuItem> m_platformDescription; #else PlatformMenuItemDescription m_platformDescription; #endif diff --git a/Source/WebCore/platform/DragData.cpp b/Source/WebCore/platform/DragData.cpp index 4518909..a61feab 100644 --- a/Source/WebCore/platform/DragData.cpp +++ b/Source/WebCore/platform/DragData.cpp @@ -31,13 +31,24 @@ namespace WebCore { #if !PLATFORM(MAC) DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, - DragOperation sourceOperationMask) + DragOperation sourceOperationMask, DragApplicationFlags flags) : m_clientPosition(clientPosition) , m_globalPosition(globalPosition) , m_platformDragData(data) , m_draggingSourceOperationMask(sourceOperationMask) + , m_applicationFlags(flags) { } + +DragData::DragData(const String&, const IntPoint& clientPosition, const IntPoint& globalPosition, + DragOperation sourceOperationMask, DragApplicationFlags flags) + : m_clientPosition(clientPosition) + , m_globalPosition(globalPosition) + , m_platformDragData(0) + , m_draggingSourceOperationMask(sourceOperationMask) + , m_applicationFlags(flags) +{ +} #endif } // namespace WebCore diff --git a/Source/WebCore/platform/DragData.h b/Source/WebCore/platform/DragData.h index d90a424..3bd27fc 100644 --- a/Source/WebCore/platform/DragData.h +++ b/Source/WebCore/platform/DragData.h @@ -34,12 +34,15 @@ #include <wtf/Vector.h> #if PLATFORM(MAC) +#include <wtf/RetainPtr.h> #ifdef __OBJC__ #import <Foundation/Foundation.h> #import <AppKit/NSDragging.h> typedef id <NSDraggingInfo> DragDataRef; +@class NSPasteboard; #else typedef void* DragDataRef; +class NSPasteboard; #endif #elif PLATFORM(QT) QT_BEGIN_NAMESPACE @@ -68,54 +71,61 @@ typedef void* DragDataRef; namespace WebCore { - - class Document; - class DocumentFragment; - class KURL; - -#if PLATFORM(MAC) - class PasteboardHelper; -#endif +class Frame; +class DocumentFragment; +class KURL; +class Range; + +enum DragApplicationFlags { + DragApplicationNone = 0, + DragApplicationIsModal = 1, + DragApplicationIsSource = 2, + DragApplicationHasAttachedSheet = 4, + DragApplicationIsCopyKeyDown = 8 +}; - class DragData { - public: - enum FilenameConversionPolicy { DoNotConvertFilenames, ConvertFilenames }; +class DragData { +public: + enum FilenameConversionPolicy { DoNotConvertFilenames, ConvertFilenames }; + // clientPosition is taken to be the position of the drag event within the target window, with (0,0) at the top left + DragData(DragDataRef, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone); + DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation, DragApplicationFlags = DragApplicationNone); + + const IntPoint& clientPosition() const { return m_clientPosition; } + const IntPoint& globalPosition() const { return m_globalPosition; } + DragApplicationFlags flags() { return m_applicationFlags; } + DragDataRef platformData() const { return m_platformDragData; } + DragOperation draggingSourceOperationMask() const { return m_draggingSourceOperationMask; } + bool containsURL(Frame*, FilenameConversionPolicy filenamePolicy = ConvertFilenames) const; + bool containsPlainText() const; + bool containsCompatibleContent() const; + String asURL(Frame*, FilenameConversionPolicy filenamePolicy = ConvertFilenames, String* title = 0) const; + String asPlainText(Frame*) const; + void asFilenames(Vector<String>&) const; + Color asColor() const; + PassRefPtr<DocumentFragment> asFragment(Frame*, PassRefPtr<Range> context, + bool allowPlainText, bool& chosePlainText) const; + bool canSmartReplace() const; + bool containsColor() const; + bool containsFiles() const; +private: + IntPoint m_clientPosition; + IntPoint m_globalPosition; + DragDataRef m_platformDragData; + DragOperation m_draggingSourceOperationMask; + DragApplicationFlags m_applicationFlags; #if PLATFORM(MAC) - //FIXME: In the future the WebKit functions provided by the helper class should be moved into WebCore, - //after which this constructor should be removed - DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, - DragOperation operation, PasteboardHelper*); -#else - //clientPosition is taken to be the position of the drag event within the target window, with (0,0) at the top left - DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, DragOperation operation); -#endif - const IntPoint& clientPosition() const { return m_clientPosition; } - const IntPoint& globalPosition() const { return m_globalPosition; } - DragDataRef platformData() const { return m_platformDragData; } - DragOperation draggingSourceOperationMask() const { return m_draggingSourceOperationMask; } - bool containsURL(FilenameConversionPolicy filenamePolicy = ConvertFilenames) const; - bool containsPlainText() const; - bool containsCompatibleContent() const; - String asURL(FilenameConversionPolicy filenamePolicy = ConvertFilenames, String* title = 0) const; - String asPlainText() const; - void asFilenames(Vector<String>&) const; - Color asColor() const; - PassRefPtr<DocumentFragment> asFragment(Document*) const; - bool canSmartReplace() const; - bool containsColor() const; - bool containsFiles() const; - private: - IntPoint m_clientPosition; - IntPoint m_globalPosition; - DragDataRef m_platformDragData; - DragOperation m_draggingSourceOperationMask; -#if PLATFORM(MAC) - PasteboardHelper* m_pasteboardHelper; + RetainPtr<NSPasteboard> m_pasteboard; #endif }; -} //namespace WebCore +} +<<<<<<< HEAD #endif //!DragData_h +======= +#endif // !DragData_h + +>>>>>>> WebKit.org @ r75993 diff --git a/Source/WebCore/platform/FileSystem.h b/Source/WebCore/platform/FileSystem.h index 3b65d34..4f088e1 100644 --- a/Source/WebCore/platform/FileSystem.h +++ b/Source/WebCore/platform/FileSystem.h @@ -195,6 +195,7 @@ bool safeCreateFile(const String&, CFDataRef); #if PLATFORM(GTK) String filenameToString(const char*); String filenameForDisplay(const String&); +CString applicationDirectoryPath(); #endif #if PLATFORM(CHROMIUM) diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h index 7c50737..78a40b3 100644 --- a/Source/WebCore/platform/Pasteboard.h +++ b/Source/WebCore/platform/Pasteboard.h @@ -88,6 +88,8 @@ public: static void writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame); static void writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame); static void writePlainText(NSPasteboard* pasteboard, const String& text); + + Pasteboard(NSPasteboard *); #endif static Pasteboard* generalPasteboard(); @@ -97,11 +99,13 @@ public: void writeImage(Node*, const KURL&, const String& title); #if PLATFORM(MAC) void writeFileWrapperAsRTFDAttachment(NSFileWrapper*); + String asURL(Frame*); #endif void clear(); bool canSmartReplace(); PassRefPtr<DocumentFragment> documentFragment(Frame*, PassRefPtr<Range>, bool allowPlainText, bool& chosePlainText); String plainText(Frame* = 0); + #if PLATFORM(QT) || PLATFORM(CHROMIUM) bool isSelectionMode() const; void setSelectionMode(bool selectionMode); @@ -110,17 +114,17 @@ public: #if PLATFORM(GTK) void setHelper(PasteboardHelper*); PasteboardHelper* helper(); + ~Pasteboard(); #endif private: Pasteboard(); - ~Pasteboard(); #if PLATFORM(MAC) - Pasteboard(NSPasteboard *); RetainPtr<NSPasteboard> m_pasteboard; PassRefPtr<DocumentFragment> documentFragmentWithImageResource(Frame* frame, PassRefPtr<ArchiveResource> resource); PassRefPtr<DocumentFragment> documentFragmentWithRtf(Frame* frame, NSString* pboardType); + NSURL *getBestURL(Frame *); #endif #if PLATFORM(WIN) diff --git a/Source/WebCore/platform/PlatformWheelEvent.h b/Source/WebCore/platform/PlatformWheelEvent.h index 6747392..1e5cd53 100644 --- a/Source/WebCore/platform/PlatformWheelEvent.h +++ b/Source/WebCore/platform/PlatformWheelEvent.h @@ -68,8 +68,22 @@ namespace WebCore { // and synthesized in other cases where platforms generate line-by-line scrolling events. // The ScrollByPageWheelEvent indicates that the wheel event should scroll an entire page. In this case WebCore's built in paging behavior is used to page // up and down (you get the same behavior as if the user was clicking in a scrollbar track to page up or page down). Page scrolling only works in the vertical direction. - enum PlatformWheelEventGranularity { ScrollByPageWheelEvent, ScrollByPixelWheelEvent }; - + enum PlatformWheelEventGranularity { + ScrollByPageWheelEvent, + ScrollByPixelWheelEvent + }; + +#if PLATFORM(MAC) + enum PlatformWheelEventPhase { + PlatformWheelEventPhaseNone = 0, + PlatformWheelEventPhaseBegan = 1 << 1, + PlatformWheelEventPhaseStationary = 1 << 2, + PlatformWheelEventPhaseChanged = 1 << 3, + PlatformWheelEventPhaseEnded = 1 << 4, + PlatformWheelEventPhaseCancelled = 1 << 5, + }; +#endif + class PlatformWheelEvent { public: PlatformWheelEvent() @@ -83,6 +97,9 @@ namespace WebCore { , m_ctrlKey(false) , m_altKey(false) , m_metaKey(false) +#if PLATFORM(MAC) + , m_phase(PlatformWheelEventPhaseNone) +#endif { } @@ -128,10 +145,14 @@ namespace WebCore { PlatformWheelEvent(const Evas_Event_Mouse_Wheel*); #endif -#if PLATFORM(MAC) && defined(__OBJC__) +#if PLATFORM(MAC) +#if defined(__OBJC__) PlatformWheelEvent(NSEvent *, NSView *windowView); #endif + PlatformWheelEventPhase phase() const { return m_phase; } +#endif + #if PLATFORM(QT) PlatformWheelEvent(QWheelEvent*); PlatformWheelEvent(QGraphicsSceneWheelEvent*); @@ -164,6 +185,9 @@ namespace WebCore { bool m_ctrlKey; bool m_altKey; bool m_metaKey; +#if PLATFORM(MAC) + PlatformWheelEventPhase m_phase; +#endif }; } // namespace WebCore diff --git a/Source/WebCore/platform/SchemeRegistry.cpp b/Source/WebCore/platform/SchemeRegistry.cpp index 58df51a..71697cb 100644 --- a/Source/WebCore/platform/SchemeRegistry.cpp +++ b/Source/WebCore/platform/SchemeRegistry.cpp @@ -45,6 +45,12 @@ static URLSchemesMap& localURLSchemes() return localSchemes; } +static URLSchemesMap& displayIsolatedURLSchemes() +{ + DEFINE_STATIC_LOCAL(URLSchemesMap, displayIsolatedSchemes, ()); + return displayIsolatedSchemes; +} + static URLSchemesMap& secureSchemes() { DEFINE_STATIC_LOCAL(URLSchemesMap, secureSchemes, ()); @@ -82,7 +88,7 @@ static URLSchemesMap& emptyDocumentSchemes() void SchemeRegistry::registerURLSchemeAsLocal(const String& scheme) { - WebCore::localURLSchemes().add(scheme); + localURLSchemes().add(scheme); } void SchemeRegistry::removeURLSchemeRegisteredAsLocal(const String& scheme) @@ -93,50 +99,19 @@ void SchemeRegistry::removeURLSchemeRegisteredAsLocal(const String& scheme) if (scheme == "applewebdata") return; #endif - WebCore::localURLSchemes().remove(scheme); -} - -const URLSchemesMap& SchemeRegistry::localURLSchemes() -{ - return WebCore::localURLSchemes(); + localURLSchemes().remove(scheme); } -bool SchemeRegistry::shouldTreatURLAsLocal(const String& url) +const URLSchemesMap& SchemeRegistry::localSchemes() { - // This avoids an allocation of another String and the HashSet contains() - // call for the file: and http: schemes. - if (url.length() >= 5) { - const UChar* s = url.characters(); - if (s[0] == 'h' && s[1] == 't' && s[2] == 't' && s[3] == 'p' && s[4] == ':') - return false; - if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e' && s[4] == ':') - return true; - } - - size_t loc = url.find(':'); - if (loc == notFound) - return false; - - String scheme = url.left(loc); - return WebCore::localURLSchemes().contains(scheme); + return localURLSchemes(); } bool SchemeRegistry::shouldTreatURLSchemeAsLocal(const String& scheme) { - // This avoids an allocation of another String and the HashSet contains() - // call for the file: and http: schemes. - if (scheme.length() == 4) { - const UChar* s = scheme.characters(); - if (s[0] == 'h' && s[1] == 't' && s[2] == 't' && s[3] == 'p') - return false; - if (s[0] == 'f' && s[1] == 'i' && s[2] == 'l' && s[3] == 'e') - return true; - } - if (scheme.isEmpty()) return false; - - return WebCore::localURLSchemes().contains(scheme); + return localURLSchemes().contains(scheme); } void SchemeRegistry::registerURLSchemeAsNoAccess(const String& scheme) @@ -149,6 +124,16 @@ bool SchemeRegistry::shouldTreatURLSchemeAsNoAccess(const String& scheme) return schemesWithUniqueOrigins().contains(scheme); } +void SchemeRegistry::registerURLSchemeAsDisplayIsolated(const String& scheme) +{ + displayIsolatedURLSchemes().add(scheme); +} + +bool SchemeRegistry::shouldTreatURLSchemeAsDisplayIsolated(const String& scheme) +{ + return displayIsolatedURLSchemes().contains(scheme); +} + void SchemeRegistry::registerURLSchemeAsSecure(const String& scheme) { secureSchemes().add(scheme); diff --git a/Source/WebCore/platform/SchemeRegistry.h b/Source/WebCore/platform/SchemeRegistry.h index 56e3b33..530fcab 100644 --- a/Source/WebCore/platform/SchemeRegistry.h +++ b/Source/WebCore/platform/SchemeRegistry.h @@ -38,9 +38,8 @@ class SchemeRegistry { public: static void registerURLSchemeAsLocal(const String&); static void removeURLSchemeRegisteredAsLocal(const String&); - static const URLSchemesMap& localURLSchemes(); + static const URLSchemesMap& localSchemes(); - static bool shouldTreatURLAsLocal(const String&); static bool shouldTreatURLSchemeAsLocal(const String&); // Secure schemes do not trigger mixed content warnings. For example, @@ -51,7 +50,12 @@ public: static void registerURLSchemeAsNoAccess(const String&); static bool shouldTreatURLSchemeAsNoAccess(const String&); - + + // Display-isolated schemes can only be displayed (in the sense of + // SecurityOrigin::canDisplay) by documents from the same scheme. + static void registerURLSchemeAsDisplayIsolated(const String&); + static bool shouldTreatURLSchemeAsDisplayIsolated(const String&); + static void registerURLSchemeAsEmptyDocument(const String&); static bool shouldLoadURLSchemeAsEmptyDocument(const String&); }; diff --git a/Source/WebCore/platform/UUID.cpp b/Source/WebCore/platform/UUID.cpp index 5c2e076..c072f4a 100644 --- a/Source/WebCore/platform/UUID.cpp +++ b/Source/WebCore/platform/UUID.cpp @@ -39,11 +39,11 @@ #if OS(WINDOWS) #include <objbase.h> -#elif OS(DARWIN) +#elif OS(DARWIN) && PLATFORM(CF) #include <CoreFoundation/CoreFoundation.h> #elif OS(LINUX) && !PLATFORM(CHROMIUM) #include <stdio.h> -#elif OS(LINUX) && PLATFORM(CHROMIUM) +#elif (OS(LINUX) && PLATFORM(CHROMIUM)) || (OS(DARWIN) && !PLATFORM(CF)) #include <wtf/RandomNumber.h> #include <wtf/text/StringBuilder.h> #endif @@ -71,7 +71,7 @@ String createCanonicalUUIDString() String canonicalUuidStr = String(uuidStr + 1, num - 3).lower(); // remove opening and closing bracket and make it lower. ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired); return canonicalUuidStr; -#elif OS(DARWIN) +#elif OS(DARWIN) && PLATFORM(CF) CFUUIDRef uuid = CFUUIDCreate(0); CFStringRef uuidStrRef = CFUUIDCreateString(0, uuid); String uuidStr(uuidStrRef); @@ -93,7 +93,7 @@ String createCanonicalUUIDString() String canonicalUuidStr = String(uuidStr).lower(); // make it lower. ASSERT(canonicalUuidStr[uuidVersionIdentifierIndex] == uuidVersionRequired); return canonicalUuidStr; -#elif OS(LINUX) && PLATFORM(CHROMIUM) +#elif (OS(LINUX) && PLATFORM(CHROMIUM)) || (OS(DARWIN) && !PLATFORM(CF)) unsigned randomData[4]; for (size_t i = 0; i < WTF_ARRAY_LENGTH(randomData); ++i) randomData[i] = static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)); diff --git a/Source/WebCore/platform/Widget.cpp b/Source/WebCore/platform/Widget.cpp index 77560ff..9a980c0 100644 --- a/Source/WebCore/platform/Widget.cpp +++ b/Source/WebCore/platform/Widget.cpp @@ -106,6 +106,10 @@ IntPoint Widget::convertToContainingWindow(const IntPoint& localPoint) const } #if !PLATFORM(MAC) +void Widget::setBoundsSize(const IntSize&) +{ +} + IntRect Widget::convertFromRootToContainingWindow(const Widget*, const IntRect& rect) { return rect; diff --git a/Source/WebCore/platform/Widget.h b/Source/WebCore/platform/Widget.h index 2b3a1a6..a6562ef 100644 --- a/Source/WebCore/platform/Widget.h +++ b/Source/WebCore/platform/Widget.h @@ -158,6 +158,7 @@ public: IntPoint pos() const { return frameRect().location(); } virtual void setFrameRect(const IntRect&); + virtual void setBoundsSize(const IntSize&); virtual IntRect frameRect() const; IntRect boundsRect() const { return IntRect(0, 0, width(), height()); } diff --git a/Source/WebCore/platform/android/DragDataAndroid.cpp b/Source/WebCore/platform/android/DragDataAndroid.cpp index 4e99b2c..2c341b0 100644 --- a/Source/WebCore/platform/android/DragDataAndroid.cpp +++ b/Source/WebCore/platform/android/DragDataAndroid.cpp @@ -47,7 +47,7 @@ bool DragData::containsPlainText() const return false; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { return String(); } @@ -62,18 +62,18 @@ bool DragData::containsCompatibleContent() const return false; } -bool DragData::containsURL(FilenameConversionPolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy) const { return false; } -String DragData::asURL(FilenameConversionPolicy, String*) const +String DragData::asURL(Frame*, FilenameConversionPolicy, String*) const { return String(); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame*, PassRefPtr<Range>, bool, bool&) const { return 0; } diff --git a/Source/WebCore/platform/chromium/ChromiumBridge.h b/Source/WebCore/platform/chromium/ChromiumBridge.h index 56969ef..d3b8528 100644 --- a/Source/WebCore/platform/chromium/ChromiumBridge.h +++ b/Source/WebCore/platform/chromium/ChromiumBridge.h @@ -159,10 +159,6 @@ namespace WebCore { // Forms -------------------------------------------------------------- static void notifyFormStateChanged(const Document*); -#if !ENABLE(CLIENT_BASED_GEOLOCATION) - // Geolocation -------------------------------------------------------- - static GeolocationServiceBridge* createGeolocationServiceBridge(GeolocationServiceChromium*); -#endif // Databases ---------------------------------------------------------- // Returns a handle to the DB file and ooptionally a handle to its containing directory static PlatformFileHandle databaseOpenFile(const String& vfsFleName, int desiredFlags); diff --git a/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h b/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h index 9fdad42..3e6f92a 100644 --- a/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h +++ b/Source/WebCore/platform/chromium/ClipboardUtilitiesChromium.h @@ -28,6 +28,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef ClipboardUtilitiesChromium_h +#define ClipboardUtilitiesChromium_h + #include <wtf/Forward.h> namespace WebCore { @@ -40,3 +43,5 @@ void replaceNewlinesWithWindowsStyleNewlines(String&); void replaceNBSPWithSpace(String&); } // namespace WebCore + +#endif // ClipboardUtilitiesChromium_h diff --git a/Source/WebCore/platform/chromium/DragDataChromium.cpp b/Source/WebCore/platform/chromium/DragDataChromium.cpp index 2b04523..8c20a00 100644 --- a/Source/WebCore/platform/chromium/DragDataChromium.cpp +++ b/Source/WebCore/platform/chromium/DragDataChromium.cpp @@ -35,6 +35,7 @@ #include "ClipboardMimeTypes.h" #include "DocumentFragment.h" #include "FileSystem.h" +#include "Frame.h" #include "KURL.h" #include "markup.h" #include "NotImplemented.h" @@ -47,13 +48,13 @@ static bool containsHTML(const ChromiumDataObject* dropData) return dropData->types().contains(mimeTypeTextHTML); } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { return m_platformDragData->types().contains(mimeTypeURL) || (filenamePolicy == ConvertFilenames && m_platformDragData->containsFilenames()); } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { String url; if (m_platformDragData->types().contains(mimeTypeURL)) { @@ -84,7 +85,7 @@ bool DragData::containsPlainText() const return m_platformDragData->types().contains(mimeTypeTextPlain); } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { bool ignoredSuccess; return m_platformDragData->getData(mimeTypeTextPlain, ignoredSuccess); @@ -109,13 +110,13 @@ bool DragData::canSmartReplace() const bool DragData::containsCompatibleContent() const { return containsPlainText() - || containsURL() + || containsURL(0) || containsHTML(m_platformDragData) || containsColor() || containsFiles(); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const { /* * Order is richest format first. On OSX this is: @@ -137,7 +138,7 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const if (m_platformDragData->types().contains(mimeTypeTextHTML)) { bool ignoredSuccess; - RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(doc, + RefPtr<DocumentFragment> fragment = createFragmentFromMarkup(frame->document(), m_platformDragData->getData(mimeTypeTextHTML, ignoredSuccess), m_platformDragData->htmlBaseUrl(), FragmentScriptingNotAllowed); return fragment.release(); } diff --git a/Source/WebCore/platform/chromium/GeolocationServiceChromium.cpp b/Source/WebCore/platform/chromium/GeolocationServiceChromium.cpp deleted file mode 100644 index c5e73ae..0000000 --- a/Source/WebCore/platform/chromium/GeolocationServiceChromium.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) 2010, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "GeolocationServiceChromium.h" - -#include "ChromiumBridge.h" - -#if ENABLE(CLIENT_BASED_GEOLOCATION) -#error "This file should not be compiled when ENABLE(CLIENT_BASED_GEOLOCATION)" -#endif // ENABLE(CLIENT_BASED_GEOLOCATION) - -namespace WebCore { - -GeolocationServiceBridge::~GeolocationServiceBridge() -{ -} - -GeolocationServiceChromium::GeolocationServiceChromium(GeolocationServiceClient* c) - : GeolocationService(c), - m_geolocation(static_cast<Geolocation*>(c)), - m_geolocationServiceBridge(ChromiumBridge::createGeolocationServiceBridge(this)), - m_lastError(PositionError::create(PositionError::POSITION_UNAVAILABLE, "")) -{ -} - -void GeolocationServiceChromium::setIsAllowed(bool allowed) -{ - m_geolocation->setIsAllowed(allowed); -} - -void GeolocationServiceChromium::setLastPosition(PassRefPtr<Geoposition> geoposition) -{ - m_lastPosition = geoposition; - positionChanged(); -} - -void GeolocationServiceChromium::setLastError(int errorCode, const String& message) -{ - m_lastError = PositionError::create(static_cast<PositionError::ErrorCode>(errorCode), message); - errorOccurred(); -} - -Frame* GeolocationServiceChromium::frame() -{ - return m_geolocation->frame(); -} - -bool GeolocationServiceChromium::startUpdating(PositionOptions* options) -{ - return m_geolocationServiceBridge->startUpdating(options); -} - -void GeolocationServiceChromium::stopUpdating() -{ - return m_geolocationServiceBridge->stopUpdating(); -} - -void GeolocationServiceChromium::suspend() -{ - return m_geolocationServiceBridge->suspend(); -} - -void GeolocationServiceChromium::resume() -{ - return m_geolocationServiceBridge->resume(); -} - -Geoposition* GeolocationServiceChromium::lastPosition() const -{ - return m_lastPosition.get(); -} - -PositionError* GeolocationServiceChromium::lastError() const -{ - return m_lastError.get(); -} - -static GeolocationService* createGeolocationServiceChromium(GeolocationServiceClient* c) -{ - return new GeolocationServiceChromium(c); -} - -// Sets up the factory function for GeolocationService. -GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &createGeolocationServiceChromium; - -} // namespace WebCore diff --git a/Source/WebCore/platform/chromium/GeolocationServiceChromium.h b/Source/WebCore/platform/chromium/GeolocationServiceChromium.h deleted file mode 100644 index 7e6f633..0000000 --- a/Source/WebCore/platform/chromium/GeolocationServiceChromium.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2010, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef GeolocationServiceChromium_h -#define GeolocationServiceChromium_h - -#include "Geolocation.h" -#include "GeolocationService.h" -#include "Geoposition.h" -#include "PlatformString.h" -#include "PositionError.h" - -namespace WebCore { - -// Provides an interface for GeolocationServiceChromium to call into the embedder. -class GeolocationServiceBridge { -public: - virtual ~GeolocationServiceBridge(); - // Called by GeolocationServiceChromium. - virtual bool startUpdating(PositionOptions*) = 0; - virtual void stopUpdating() = 0; - virtual void suspend() = 0; - virtual void resume() = 0; - - // Called by the embedder, to identify this bridge. - virtual int getBridgeId() const = 0; - virtual void attachBridgeIfNeeded() = 0; -}; - -// This class extends GeolocationService, and uses GeolocationServiceBridge to -// call into the embedder, as well as provides a few extra methods so that the -// embedder can notify permission, position, error, etc. -class GeolocationServiceChromium : public GeolocationService { -public: - explicit GeolocationServiceChromium(GeolocationServiceClient*); - - GeolocationServiceBridge* geolocationServiceBridge() const { return m_geolocationServiceBridge.get(); } - void setIsAllowed(bool allowed); - void setLastPosition(PassRefPtr<Geoposition>); - void setLastError(int errorCode, const String& message); - Frame* frame(); - - // From GeolocationService. - virtual bool startUpdating(PositionOptions*); - virtual void stopUpdating(); - virtual void suspend(); - virtual void resume(); - virtual Geoposition* lastPosition() const; - virtual PositionError* lastError() const; - -private: - Geolocation* m_geolocation; - OwnPtr<GeolocationServiceBridge> m_geolocationServiceBridge; - RefPtr<Geoposition> m_lastPosition; - RefPtr<PositionError> m_lastError; -}; - -} // namespace WebCore - -#endif // GeolocationServiceChromium_h diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp index 04eeb93..bb45e79 100644 --- a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -329,11 +329,8 @@ PopupContainer::~PopupContainer() removeChild(m_listBox.get()); } -void PopupContainer::showPopup(FrameView* view) +IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, const IntPoint& popupInitialCoordinate) { - // Pre-layout, our size matches the <select> dropdown control. - int selectHeight = frameRect().height(); - // Reset the max height to its default value, it will be recomputed below // if necessary. m_listBox->setMaxHeight(kMaxHeight); @@ -341,23 +338,26 @@ void PopupContainer::showPopup(FrameView* view) // Lay everything out to figure out our preferred size, then tell the view's // WidgetClient about it. It should assign us a client. layout(); + + // Assume m_listBox size is already calculated. + IntSize targetSize(m_listBox->width() + kBorderSize * 2, + m_listBox->height() + kBorderSize * 2); - m_frameView = view; + IntRect widgetRect; ChromeClientChromium* chromeClient = chromeClientChromium(); if (chromeClient) { // If the popup would extend past the bottom of the screen, open upwards // instead. - FloatRect screen = screenAvailableRect(view); - IntRect widgetRect = chromeClient->windowToScreen(frameRect()); - + FloatRect screen = screenAvailableRect(m_frameView.get()); + widgetRect = chromeClient->windowToScreen(IntRect(popupInitialCoordinate, targetSize)); if (widgetRect.bottom() > static_cast<int>(screen.bottom())) { - if (widgetRect.y() - widgetRect.height() - selectHeight > 0) { + if (widgetRect.y() - widgetRect.height() - targetControlHeight > 0) { // There is enough room to open upwards. - widgetRect.move(0, -(widgetRect.height() + selectHeight)); + widgetRect.move(0, -(widgetRect.height() + targetControlHeight)); } else { // Figure whether upwards or downwards has more room and set the // maximum number of items. - int spaceAbove = widgetRect.y() - selectHeight; + int spaceAbove = widgetRect.y() - targetControlHeight; int spaceBelow = screen.bottom() - widgetRect.y(); if (spaceAbove > spaceBelow) m_listBox->setMaxHeight(spaceAbove); @@ -368,10 +368,21 @@ void PopupContainer::showPopup(FrameView* view) widgetRect = chromeClient->windowToScreen(frameRect()); // And move upwards if necessary. if (spaceAbove > spaceBelow) - widgetRect.move(0, -(widgetRect.height() + selectHeight)); + widgetRect.move(0, -(widgetRect.height() + targetControlHeight)); } } - chromeClient->popupOpened(this, widgetRect, false); + } + return widgetRect; +} + +void PopupContainer::showPopup(FrameView* view) +{ + m_frameView = view; + + ChromeClientChromium* chromeClient = chromeClientChromium(); + if (chromeClient) { + IntRect popupRect = frameRect(); + chromeClient->popupOpened(this, layoutAndCalculateWidgetRect(popupRect.height(), popupRect.location()), false); m_popupOpen = true; } @@ -556,15 +567,24 @@ void PopupContainer::show(const IntRect& r, FrameView* v, int index) // Move it below the select widget. location.move(0, r.height()); - IntRect popupRect(location, r.size()); - setFrameRect(popupRect); + setFrameRect(IntRect(location, r.size())); showPopup(v); } -void PopupContainer::refresh() +void PopupContainer::refresh(const IntRect& targetControlRect) { + IntPoint location = m_frameView->contentsToWindow(targetControlRect.location()); + // Move it below the select widget. + location.move(0, targetControlRect.height()); + listBox()->updateFromElement(); - layout(); + // Store the original height to check if we need to request the location. + int originalHeight = height(); + IntRect widgetRect = layoutAndCalculateWidgetRect(targetControlRect.height(), location); + if (originalHeight != widgetRect.height()) + setFrameRect(widgetRect); + + invalidate(); } int PopupContainer::selectedIndex() const diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.h b/Source/WebCore/platform/chromium/PopupMenuChromium.h index ca47ccf..f326b48 100644 --- a/Source/WebCore/platform/chromium/PopupMenuChromium.h +++ b/Source/WebCore/platform/chromium/PopupMenuChromium.h @@ -168,7 +168,7 @@ public: int selectedIndex() const; // Refresh the popup values from the PopupMenuClient. - void refresh(); + void refresh(const IntRect& targetControlRect); // The menu per-item data. const WTF::Vector<PopupItem*>& popupData() const; @@ -193,6 +193,9 @@ private: // Paint the border. void paintBorder(GraphicsContext*, const IntRect&); + // Layout and calculate popup widget size and location and returns it as IntRect. + IntRect layoutAndCalculateWidgetRect(int targetControlHeight, const IntPoint& popupInitialCoordinate); + // Returns the ChromeClient of the page this popup is associated with. ChromeClientChromium* chromeClientChromium(); diff --git a/Source/WebCore/platform/efl/DragDataEfl.cpp b/Source/WebCore/platform/efl/DragDataEfl.cpp index a8458d6..b35b963 100644 --- a/Source/WebCore/platform/efl/DragDataEfl.cpp +++ b/Source/WebCore/platform/efl/DragDataEfl.cpp @@ -50,7 +50,7 @@ bool DragData::containsPlainText() const return false; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { return String(); } @@ -65,17 +65,17 @@ bool DragData::containsCompatibleContent() const return false; } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { return false; } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { return String(); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame*, PassRefPtr<Range>, bool, bool&) const { return 0; } diff --git a/Source/WebCore/platform/efl/PasteboardEfl.cpp b/Source/WebCore/platform/efl/PasteboardEfl.cpp index 1af5a92..77c1d90 100644 --- a/Source/WebCore/platform/efl/PasteboardEfl.cpp +++ b/Source/WebCore/platform/efl/PasteboardEfl.cpp @@ -46,11 +46,6 @@ Pasteboard::Pasteboard() notImplemented(); } -Pasteboard::~Pasteboard() -{ - notImplemented(); -} - void Pasteboard::writePlainText(const String&) { notImplemented(); diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.cpp b/Source/WebCore/platform/efl/RenderThemeEfl.cpp index 7cf635f..9df12e9 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.cpp +++ b/Source/WebCore/platform/efl/RenderThemeEfl.cpp @@ -32,6 +32,7 @@ #include "FrameView.h" #include "GraphicsContext.h" #include "NotImplemented.h" +#include "PaintInfo.h" #include "Page.h" #include "RenderBox.h" #include "RenderObject.h" diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp index b8a6859..c9c1f63 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp @@ -30,6 +30,7 @@ #include "Font.h" #include "Generator.h" #include "ImageBuffer.h" +#include "IntRect.h" using namespace std; diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index d72cba1..a648680 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -32,10 +32,8 @@ #include "FloatRect.h" #include "Gradient.h" #include "Image.h" -#include "IntRect.h" #include "Path.h" #include "Pattern.h" -#include "TextDirection.h" #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> @@ -129,6 +127,7 @@ namespace WebCore { class Generator; class GraphicsContextPlatformPrivate; class ImageBuffer; + class IntRect; class KURL; class SharedGraphicsContext3D; class TextRun; diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp index 1224bce..f7c5a66 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -33,6 +33,7 @@ #include "ArrayBufferView.h" #include "CheckedInt.h" #include "DrawingBuffer.h" +#include "Extensions3D.h" #include "Image.h" #include "ImageData.h" @@ -43,62 +44,6 @@ namespace WebCore { namespace { - unsigned int bytesPerComponent(GC3Denum type) - { - switch (type) { - case GraphicsContext3D::UNSIGNED_BYTE: - return 1; - case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: - case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: - case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: - return 2; - case GraphicsContext3D::FLOAT: - return 4; - default: - return 1; - } - } - - unsigned int componentsPerPixel(GC3Denum format, GC3Denum type) - { - switch (type) { - case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: - case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: - case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: - case GraphicsContext3D::FLOAT: - return 1; - default: - break; - } - switch (format) { - case GraphicsContext3D::ALPHA: - case GraphicsContext3D::LUMINANCE: - return 1; - case GraphicsContext3D::LUMINANCE_ALPHA: - return 2; - case GraphicsContext3D::RGB: - return 3; - case GraphicsContext3D::RGBA: - return 4; - default: - return 4; - } - } - - // This function should only be called if width and height is non-zero and - // format/type are valid. Return 0 if overflow happens. - unsigned int imageSizeInBytes(GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type) - { - ASSERT(width > 0 && height > 0); - CheckedInt<uint32_t> checkedWidth(width); - CheckedInt<uint32_t> checkedHeight(height); - CheckedInt<uint32_t> checkedBytesPerPixel(bytesPerComponent(type) * componentsPerPixel(format, type)); - CheckedInt<uint32_t> checkedSize = checkedWidth * checkedHeight * checkedBytesPerPixel; - if (checkedSize.valid()) - return checkedSize.value(); - return 0; - } - uint8_t convertColor16LittleTo8(uint16_t value) { return value >> 8; @@ -117,17 +62,19 @@ PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize& return DrawingBuffer::create(this, size); } -bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type) +bool GraphicsContext3D::texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint unpackAlignment) { + ASSERT(unpackAlignment == 1 || unpackAlignment == 2 || unpackAlignment == 4 || unpackAlignment == 8); OwnArrayPtr<unsigned char> zero; if (width > 0 && height > 0) { - unsigned int size = imageSizeInBytes(width, height, format, type); - if (!size) { - synthesizeGLError(GraphicsContext3D::INVALID_VALUE); + unsigned int size; + GC3Denum error = computeImageSizeInBytes(format, type, width, height, unpackAlignment, &size, 0); + if (error != GraphicsContext3D::NO_ERROR) { + synthesizeGLError(error); return false; } zero = adoptArrayPtr(new unsigned char[size]); - if (!zero.get()) { + if (!zero) { synthesizeGLError(GraphicsContext3D::INVALID_VALUE); return false; } @@ -155,6 +102,7 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, *componentsPerPixel = 3; break; case GraphicsContext3D::RGBA: + case Extensions3D::BGRA_EXT: // GL_EXT_texture_format_BGRA8888 *componentsPerPixel = 4; break; default: @@ -162,16 +110,16 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, } switch (type) { case GraphicsContext3D::UNSIGNED_BYTE: - *bytesPerComponent = sizeof(unsigned char); + *bytesPerComponent = sizeof(GC3Dubyte); break; case GraphicsContext3D::UNSIGNED_SHORT_5_6_5: case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4: case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1: *componentsPerPixel = 1; - *bytesPerComponent = sizeof(unsigned short); + *bytesPerComponent = sizeof(GC3Dushort); break; case GraphicsContext3D::FLOAT: // OES_texture_float - *bytesPerComponent = sizeof(float); + *bytesPerComponent = sizeof(GC3Dfloat); break; default: return false; @@ -179,6 +127,44 @@ bool GraphicsContext3D::computeFormatAndTypeParameters(GC3Denum format, return true; } +GC3Denum GraphicsContext3D::computeImageSizeInBytes(GC3Denum format, GC3Denum type, GC3Dsizei width, GC3Dsizei height, GC3Dint alignment, + unsigned int* imageSizeInBytes, unsigned int* paddingInBytes) +{ + ASSERT(imageSizeInBytes); + ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8); + if (width < 0 || height < 0) + return GraphicsContext3D::INVALID_VALUE; + unsigned int bytesPerComponent, componentsPerPixel; + if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &componentsPerPixel)) + return GraphicsContext3D::INVALID_ENUM; + if (!width || !height) { + *imageSizeInBytes = 0; + if (paddingInBytes) + *paddingInBytes = 0; + return GraphicsContext3D::NO_ERROR; + } + CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); + checkedValue *= width; + if (!checkedValue.valid()) + return GraphicsContext3D::INVALID_VALUE; + unsigned int validRowSize = checkedValue.value(); + unsigned int padding = 0; + unsigned int residual = validRowSize % alignment; + if (residual) { + padding = alignment - residual; + checkedValue += padding; + } + // Last row needs no padding. + checkedValue *= (height - 1); + checkedValue += validRowSize; + if (!checkedValue.valid()) + return GraphicsContext3D::INVALID_VALUE; + *imageSizeInBytes = checkedValue.value(); + if (paddingInBytes) + *paddingInBytes = padding; + return GraphicsContext3D::NO_ERROR; +} + bool GraphicsContext3D::extractImageData(Image* image, GC3Denum format, GC3Denum type, diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h index a0d2778..10aa0d7 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h @@ -47,6 +47,8 @@ typedef unsigned int GC3Denum; typedef unsigned char GC3Dboolean; typedef unsigned int GC3Dbitfield; +typedef unsigned char GC3Dubyte; +typedef unsigned short GC3Dushort; typedef int GC3Dint; typedef int GC3Dsizei; typedef unsigned int GC3Duint; @@ -491,7 +493,8 @@ public: // Helper to texImage2D with pixel==0 case: pixels are initialized to 0. // Return true if no GL error is synthesized. - bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type); + // By default, alignment is 4, the OpenGL default setting. + bool texImage2DResourceSafe(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, GC3Dint alignment = 4); bool isGLES2Compliant() const; @@ -507,6 +510,19 @@ public: unsigned int* componentsPerPixel, unsigned int* bytesPerComponent); + // Computes the image size in bytes. If paddingInBytes is not null, padding + // is also calculated in return. Returns NO_ERROR if succeed, otherwise + // return the suggested GL error indicating the cause of the failure: + // INVALID_VALUE if width/height is negative or overflow happens. + // INVALID_ENUM if format/type is illegal. + GC3Denum computeImageSizeInBytes(GC3Denum format, + GC3Denum type, + GC3Dsizei width, + GC3Dsizei height, + GC3Dint alignment, + unsigned int* imageSizeInBytes, + unsigned int* paddingInBytes); + // Extracts the contents of the given Image into the passed Vector, // packing the pixel data according to the given format and type, // and obeying the flipY, premultiplyAlpha, and ignoreGammaAndColorProfile diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.h b/Source/WebCore/platform/graphics/GraphicsLayer.h index ef3c1bc..8943f6c 100644 --- a/Source/WebCore/platform/graphics/GraphicsLayer.h +++ b/Source/WebCore/platform/graphics/GraphicsLayer.h @@ -322,6 +322,11 @@ public: // For hosting this GraphicsLayer in a native layer hierarchy. virtual PlatformLayer* platformLayer() const { return 0; } + // Change the scale at which the contents are rendered. Note that contentsScale may not return + // the same value passed to setContentsScale(), because of clamping and hysteresis. + virtual float contentsScale() const { return 1; } + virtual void setContentsScale(float) { } + void dumpLayer(TextStream&, int indent = 0, LayerTreeAsTextBehavior = LayerTreeAsTextBehaviorNormal) const; int repaintCount() const { return m_repaintCount; } diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp index 92553c5..984b7d2 100644 --- a/Source/WebCore/platform/graphics/ImageSource.cpp +++ b/Source/WebCore/platform/graphics/ImageSource.cpp @@ -130,8 +130,8 @@ NativeImagePtr ImageSource::createFrameAtIndex(size_t index) if (!m_decoder) return 0; - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) + ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); + if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return 0; // Zero-height images can cause problems for some ports. If we have an @@ -149,8 +149,8 @@ float ImageSource::frameDurationAtIndex(size_t index) if (!m_decoder) return 0; - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - if (!buffer || buffer->status() == RGBA32Buffer::FrameEmpty) + ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); + if (!buffer || buffer->status() == ImageFrame::FrameEmpty) return 0; // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. @@ -180,8 +180,8 @@ bool ImageSource::frameIsCompleteAtIndex(size_t index) if (!m_decoder) return false; - RGBA32Buffer* buffer = m_decoder->frameBufferAtIndex(index); - return buffer && buffer->status() == RGBA32Buffer::FrameComplete; + ImageFrame* buffer = m_decoder->frameBufferAtIndex(index); + return buffer && buffer->status() == ImageFrame::FrameComplete; } } diff --git a/Source/WebCore/platform/graphics/Pen.cpp b/Source/WebCore/platform/graphics/Pen.cpp deleted file mode 100644 index a3dcb86..0000000 --- a/Source/WebCore/platform/graphics/Pen.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Pen.h" - -namespace WebCore { - -Pen::Pen(const Color &color, unsigned width, PenStyle style) : m_style(style), m_width(width), m_color(color) -{ -} - -const Color &Pen::color() const -{ - return m_color; -} - -unsigned Pen::width() const -{ - return m_width; -} - -Pen::PenStyle Pen::style() const -{ - return m_style; -} - -void Pen::setColor(const Color &color) -{ - m_color = color; -} - -void Pen::setWidth(unsigned width) -{ - m_width = width; -} - -void Pen::setStyle(PenStyle style) -{ - m_style = style; -} - -bool Pen::operator==(const Pen &compareTo) const -{ - return (m_width == compareTo.m_width) && - (m_style == compareTo.m_style) && - (m_color == compareTo.m_color); -} - -bool Pen::operator!=(const Pen &compareTo) const -{ - return !(*this == compareTo); -} - -} diff --git a/Source/WebCore/platform/graphics/Pen.h b/Source/WebCore/platform/graphics/Pen.h deleted file mode 100644 index cb45a2e..0000000 --- a/Source/WebCore/platform/graphics/Pen.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2003-6 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef Pen_h -#define Pen_h - -#include "Color.h" - -#if PLATFORM(WX) -class wxPen; -#endif - -namespace WebCore { - -class Pen { -public: - enum PenStyle { - NoPen, - SolidLine, - DotLine, - DashLine - }; - - Pen(const Color &c = Color::black, unsigned w = 0, PenStyle ps = SolidLine); - - const Color &color() const; - unsigned width() const; - PenStyle style() const; - - void setColor(const Color &); - void setWidth(unsigned); - void setStyle(PenStyle); - - bool operator==(const Pen &) const; - bool operator!=(const Pen &) const; - -#if PLATFORM(WX) - Pen(const wxPen&); - operator wxPen() const; -#endif - -private: - PenStyle m_style; - unsigned m_width; - Color m_color; -}; - -} - -#endif diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp index 37385c0..b72d761 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp @@ -253,6 +253,7 @@ GraphicsLayerCA::GraphicsLayerCA(GraphicsLayerClient* client) , m_contentsLayerPurpose(NoContentsLayer) , m_contentsLayerHasBackgroundColor(false) , m_uncommittedChanges(NoChange) + , m_contentsScale(1) { m_layer = PlatformCALayer::create(PlatformCALayer::LayerTypeWebLayer, this); @@ -857,6 +858,9 @@ void GraphicsLayerCA::commitLayerChangesBeforeSublayers() if (m_uncommittedChanges & AcceleratesDrawingChanged) updateAcceleratesDrawing(); + + if (m_uncommittedChanges & ContentsScaleChanged) + updateContentsScale(); } void GraphicsLayerCA::commitLayerChangesAfterSublayers() @@ -1897,6 +1901,44 @@ GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedProperty return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones(); } +void GraphicsLayerCA::setContentsScale(float scale) +{ + float newScale = clampedContentsScaleForScale(scale); + if (newScale == m_contentsScale) + return; + + m_contentsScale = newScale; + noteLayerPropertyChanged(ContentsScaleChanged); +} + +float GraphicsLayerCA::clampedContentsScaleForScale(float scale) const +{ + // Define some limits as a sanity check for the incoming scale value + // those too small to see. + const float maxScale = 5.0f; + const float minScale = 0.01f; + + // Avoid very slight scale changes that would be doing extra work for no benefit + const float maxAllowableDelta = 0.05f; + + // Clamp + float result = max(minScale, min(scale, maxScale)); + + // If it hasn't changed much, don't do any work + return ((fabs(result - m_contentsScale) / m_contentsScale) < maxAllowableDelta) ? m_contentsScale : result; +} + +void GraphicsLayerCA::updateContentsScale() +{ + bool needTiledLayer = requiresTiledLayer(m_size); + if (needTiledLayer != m_usingTiledLayer) + swapFromOrToTiledLayer(needTiledLayer); + + m_layer->setContentsScale(m_contentsScale); + if (drawsContent()) + m_layer->setNeedsDisplay(); +} + void GraphicsLayerCA::setDebugBackgroundColor(const Color& color) { if (color.isValid()) @@ -1950,12 +1992,11 @@ bool GraphicsLayerCA::requiresTiledLayer(const FloatSize& size) const void GraphicsLayerCA::swapFromOrToTiledLayer(bool useTiledLayer) { - if (useTiledLayer == m_usingTiledLayer) - return; - + ASSERT(useTiledLayer != m_usingTiledLayer); RefPtr<PlatformCALayer> oldLayer = m_layer; m_layer = PlatformCALayer::create(useTiledLayer ? PlatformCALayer::LayerTypeWebTiledLayer : PlatformCALayer::LayerTypeWebLayer, this); + m_layer->setContentsScale(m_contentsScale); m_usingTiledLayer = useTiledLayer; @@ -2230,6 +2271,7 @@ PassRefPtr<PlatformCALayer> GraphicsLayerCA::cloneLayer(PlatformCALayer *layer, newLayer->setDoubleSided(layer->isDoubleSided()); newLayer->setOpaque(layer->isOpaque()); newLayer->setBackgroundColor(layer->backgroundColor()); + newLayer->setContentsScale(layer->contentsScale()); if (cloneLevel == IntermediateCloneLevel) { newLayer->setOpacity(layer->opacity()); diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h index 13cbdd1..2c39c0a 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h @@ -56,6 +56,9 @@ public: virtual PlatformLayer* platformLayer() const; virtual PlatformCALayer* platformCALayer() const { return primaryLayer(); } + virtual float contentsScale() const { return m_contentsScale; } + virtual void setContentsScale(float); + virtual bool setChildren(const Vector<GraphicsLayer*>&); virtual void addChild(GraphicsLayer*); virtual void addChildAtIndex(GraphicsLayer*, int index); @@ -278,6 +281,7 @@ private: void updateLayerAnimations(); void updateContentsNeedsDisplay(); void updateAcceleratesDrawing(); + void updateContentsScale(); enum StructuralLayerPurpose { NoStructuralLayer = 0, @@ -320,7 +324,8 @@ private: MaskLayerChanged = 1 << 21, ReplicatedLayerChanged = 1 << 22, ContentsNeedsDisplay = 1 << 23, - AcceleratesDrawingChanged = 1 << 24 + AcceleratesDrawingChanged = 1 << 24, + ContentsScaleChanged = 1 << 25 }; typedef unsigned LayerChangeFlags; void noteLayerPropertyChanged(LayerChangeFlags flags); @@ -391,6 +396,9 @@ private: Vector<FloatRect> m_dirtyRects; LayerChangeFlags m_uncommittedChanges; + + float clampedContentsScaleForScale(float) const; + float m_contentsScale; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h index 46f4bbf..68566b3 100644 --- a/Source/WebCore/platform/graphics/ca/PlatformCALayer.h +++ b/Source/WebCore/platform/graphics/ca/PlatformCALayer.h @@ -182,6 +182,9 @@ public: CFTimeInterval timeOffset() const; void setTimeOffset(CFTimeInterval); + + float contentsScale() const; + void setContentsScale(float); #if PLATFORM(WIN) && !defined(NDEBUG) void printTree() const; diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm index 28460a7..2e20c3f 100644 --- a/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm +++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCALayerMac.mm @@ -723,4 +723,24 @@ void PlatformCALayer::setTimeOffset(CFTimeInterval value) END_BLOCK_OBJC_EXCEPTIONS } +float PlatformCALayer::contentsScale() const +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + return [m_layer.get() contentsScale]; +#else + return 1; +#endif +} + +void PlatformCALayer::setContentsScale(float value) +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + BEGIN_BLOCK_OBJC_EXCEPTIONS + [m_layer.get() setContentsScale:value]; + END_BLOCK_OBJC_EXCEPTIONS +#else + UNUSED_PARAM(value); +#endif +} + #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp index 919c3b3..66d0732 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp @@ -253,15 +253,8 @@ size_t PlatformCALayer::sublayerCount() const void PlatformCALayer::adoptSublayers(PlatformCALayer* source) { - // Make a list of the sublayers from source PlatformCALayerList sublayers; - size_t n = source->sublayerCount(); - CFArrayRef sourceSublayers = CACFLayerGetSublayers(source->platformLayer()); - - for (size_t i = 0; i < n; ++i) { - CACFLayerRef layer = static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sourceSublayers, i))); - sublayers.append(platformCALayer(layer)); - } + intern(source)->getSublayers(sublayers); // Use setSublayers() because it properly nulls out the superlayer pointers. setSublayers(sublayers); @@ -586,6 +579,15 @@ void PlatformCALayer::setTimeOffset(CFTimeInterval value) setNeedsCommit(); } +float PlatformCALayer::contentsScale() const +{ + return 1; +} + +void PlatformCALayer::setContentsScale(float) +{ +} + #ifndef NDEBUG static void printIndent(int indent) { @@ -681,11 +683,11 @@ static void printLayer(const PlatformCALayer* layer, int indent) printIndent(indent + 1); fprintf(stderr, "(sublayers\n"); - CFArrayRef sublayers = CACFLayerGetSublayers(layer->platformLayer()); - for (int i = 0; i < n; ++i) { - PlatformCALayer* sublayer = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, i))); - printLayer(sublayer, indent + 2); - } + PlatformCALayerList sublayers; + intern(layer)->getSublayers(sublayers); + ASSERT(n == sublayers.size()); + for (int i = 0; i < n; ++i) + printLayer(sublayers[i].get(), indent + 2); printIndent(indent + 1); fprintf(stderr, ")\n"); diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp index 0b7eea0..cdf90db 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp @@ -210,6 +210,27 @@ void PlatformCALayerWinInternal::setSublayers(const PlatformCALayerList& list) } } +void PlatformCALayerWinInternal::getSublayers(PlatformCALayerList& list) const +{ + CFArrayRef sublayers = CACFLayerGetSublayers(owner()->platformLayer()); + if (!sublayers) { + list.clear(); + return; + } + + size_t count = CFArrayGetCount(sublayers); + + size_t layersToSkip = 0; + if (owner()->layerType() == PlatformCALayer::LayerTypeWebTiledLayer) { + // Exclude the tile parent layer. + layersToSkip = 1; + } + + list.resize(count - layersToSkip); + for (size_t arrayIndex = layersToSkip; arrayIndex < count; ++arrayIndex) + list[arrayIndex - layersToSkip] = PlatformCALayer::platformCALayer(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, arrayIndex))); +} + void PlatformCALayerWinInternal::removeAllSublayers() { CACFLayerSetSublayers(owner()->platformLayer(), 0); diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h index 1be9d26..39ef3b3 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.h @@ -52,6 +52,7 @@ public: PlatformCALayer* owner() const { return m_owner; } void setSublayers(const PlatformCALayerList&); + void getSublayers(PlatformCALayerList&) const; void removeAllSublayers(); void insertSublayer(PlatformCALayer*, size_t); size_t sublayerCount() const; diff --git a/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h b/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h index 1e0a846..b90bb8c 100644 --- a/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h +++ b/Source/WebCore/platform/graphics/cairo/DrawErrorUnderline.h @@ -23,6 +23,9 @@ #if PLATFORM(CAIRO) +#ifndef DrawErrorUnderline_h +#define DrawErrorUnderline_h + #include <cairo.h> // @@ -96,4 +99,6 @@ static inline void drawErrorUnderline(cairo_t* cr, double x, double y, double wi } } +#endif // DrawErrorUnderline_h + #endif diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h index 5602b6c..a0dfc8c 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h @@ -25,6 +25,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef GraphicsContextPlatformPrivateCairo_h +#define GraphicsContextPlatformPrivateCairo_h + #include "GraphicsContext.h" #include "ContextShadow.h" @@ -111,3 +114,4 @@ public: } // namespace WebCore +#endif // GraphicsContextPlatformPrivateCairo_h diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp index 03f1d10..0113427 100644 --- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp @@ -5,6 +5,7 @@ 2005, 2007 Apple Inc. All Rights reserved. 2007 Alp Toker <alp@atoker.com> 2008 Dirk Schulze <krit@webkit.org> + 2011 Igalia S.L. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -143,18 +144,30 @@ void Path::addBezierCurveTo(const FloatPoint& controlPoint1, const FloatPoint& c controlPoint3.x(), controlPoint3.y()); } -void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlockwise) +void Path::addArc(const FloatPoint& p, float r, float startAngle, float endAngle, bool anticlockwise) { // http://bugs.webkit.org/show_bug.cgi?id=16449 // cairo_arc() functions hang or crash when passed inf as radius or start/end angle - if (!isfinite(r) || !isfinite(sa) || !isfinite(ea)) + if (!isfinite(r) || !isfinite(startAngle) || !isfinite(endAngle)) return; cairo_t* cr = platformPath()->context(); - if (anticlockwise) - cairo_arc_negative(cr, p.x(), p.y(), r, sa, ea); - else - cairo_arc(cr, p.x(), p.y(), r, sa, ea); + float sweep = endAngle - startAngle; + const float twoPI = 2 * piFloat; + if ((sweep <= -twoPI || sweep >= twoPI) + && ((anticlockwise && (endAngle < startAngle)) || (!anticlockwise && (startAngle < endAngle)))) { + if (anticlockwise) + cairo_arc_negative(cr, p.x(), p.y(), r, startAngle, startAngle - twoPI); + else + cairo_arc(cr, p.x(), p.y(), r, startAngle, startAngle + twoPI); + cairo_new_sub_path(cr); + cairo_arc(cr, p.x(), p.y(), r, endAngle, endAngle); + } else { + if (anticlockwise) + cairo_arc_negative(cr, p.x(), p.y(), r, startAngle, endAngle); + else + cairo_arc(cr, p.x(), p.y(), r, startAngle, endAngle); + } } void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index acd912f..eddf735 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -546,21 +546,46 @@ void GraphicsContext::fillPath(const Path& path) CGContextRef context = platformContext(); - CGContextBeginPath(context); - CGContextAddPath(context, path.platformPath()); - if (m_state.fillGradient) { - CGContextSaveGState(context); - if (fillRule() == RULE_EVENODD) - CGContextEOClip(context); - else - CGContextClip(context); - CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); - m_state.fillGradient->paint(this); - CGContextRestoreGState(context); + if (hasShadow()) { + FloatRect rect = path.boundingRect(); + CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(rect.width(), rect.height()), 0); + CGContextRef layerContext = CGLayerGetContext(layer); + + CGContextTranslateCTM(layerContext, -rect.x(), -rect.y()); + CGContextBeginPath(layerContext); + CGContextAddPath(layerContext, path.platformPath()); + CGContextConcatCTM(layerContext, m_state.fillGradient->gradientSpaceTransform()); + + if (fillRule() == RULE_EVENODD) + CGContextEOClip(layerContext); + else + CGContextClip(layerContext); + + m_state.fillGradient->paint(layerContext); + CGContextDrawLayerAtPoint(context, CGPointMake(rect.left(), rect.top()), layer); + CGLayerRelease(layer); + } else { + CGContextBeginPath(context); + CGContextAddPath(context, path.platformPath()); + CGContextSaveGState(context); + CGContextConcatCTM(context, m_state.fillGradient->gradientSpaceTransform()); + + if (fillRule() == RULE_EVENODD) + CGContextEOClip(context); + else + CGContextClip(context); + + m_state.fillGradient->paint(this); + CGContextRestoreGState(context); + } + return; } + CGContextBeginPath(context); + CGContextAddPath(context, path.platformPath()); + if (m_state.fillPattern) applyFillPattern(); fillPathWithFillRule(context, fillRule()); diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h index 1d0a99f..d4fa32e 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h @@ -23,6 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef GraphicsContextPlatformPrivateCG_h +#define GraphicsContextPlatformPrivateCG_h + #include <wtf/RetainPtr.h> #include <CoreGraphics/CGContext.h> @@ -84,3 +87,5 @@ public: }; } + +#endif // GraphicsContextPlatformPrivateCG_h diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp index 75a36e5..023d098 100644 --- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -54,6 +54,8 @@ using namespace std; namespace WebCore { #if USE(IOSURFACE_CANVAS_BACKING_STORE) +static const int maxIOSurfaceDimension = 4096; + static RetainPtr<IOSurfaceRef> createIOSurface(const IntSize& size) { unsigned pixelFormat = 'BGRA'; @@ -110,12 +112,15 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace imageColorSpace, Render , m_size(size) , m_accelerateRendering(renderingMode == Accelerated) { -#if !USE(IOSURFACE_CANVAS_BACKING_STORE) - ASSERT(renderingMode == Unaccelerated); -#endif success = false; // Make early return mean failure. if (size.width() < 0 || size.height() < 0) return; +#if USE(IOSURFACE_CANVAS_BACKING_STORE) + if (size.width() >= maxIOSurfaceDimension || size.height() >= maxIOSurfaceDimension) + m_accelerateRendering = false; +#else + ASSERT(renderingMode == Unaccelerated); +#endif unsigned bytesPerRow = size.width(); if (bytesPerRow > 0x3FFFFFFF) // Protect against overflow diff --git a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h index 790d620..ecd57be 100644 --- a/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h +++ b/Source/WebCore/platform/graphics/cg/PDFDocumentImage.h @@ -23,6 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef PDFDocumentImage_h +#define PDFDocumentImage_h + #include "Image.h" #include "FloatRect.h" @@ -76,3 +79,5 @@ namespace WebCore { } #endif // PLATFORM(CG) + +#endif // PDFDocumentImage_h diff --git a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp index b5eda93..99159e6 100644 --- a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.cpp @@ -50,7 +50,6 @@ ComplexTextController::ComplexTextController(const TextRun& run, unsigned starti , m_startingX(startingX) , m_offsetX(m_startingX) , m_run(getNormalizedTextRun(run, m_normalizedRun, m_normalizedBuffer)) - , m_iterateBackwards(m_run.rtl()) , m_wordSpacingAdjustment(0) , m_padding(0) , m_padPerWordBreak(0) @@ -140,54 +139,33 @@ void ComplexTextController::setPadding(int padding) void ComplexTextController::reset() { - if (m_iterateBackwards) - m_indexOfNextScriptRun = m_run.length() - 1; - else - m_indexOfNextScriptRun = 0; + m_indexOfNextScriptRun = 0; m_offsetX = m_startingX; } -void ComplexTextController::setBackwardsIteration(bool isBackwards) -{ - m_iterateBackwards = isBackwards; - reset(); -} - // Advance to the next script run, returning false when the end of the // TextRun has been reached. bool ComplexTextController::nextScriptRun() { - if (m_iterateBackwards) { - // In right-to-left mode we need to render the shaped glyph backwards and - // also render the script runs themselves backwards. So given a TextRun: - // AAAAAAACTTTTTTT (A = Arabic, C = Common, T = Thai) - // we render: - // TTTTTTCAAAAAAA - // (and the glyphs in each A, C and T section are backwards too) - if (!hb_utf16_script_run_prev(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) - return false; - m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; - } else { - if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) - return false; - - // It is actually wrong to consider script runs at all in this code. - // Other WebKit code (e.g. Mac) segments complex text just by finding - // the longest span of text covered by a single font. - // But we currently need to call hb_utf16_script_run_next anyway to fill - // in the harfbuzz data structures to e.g. pick the correct script's shaper. - // So we allow that to run first, then do a second pass over the range it - // found and take the largest subregion that stays within a single font. - m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; - unsigned endOfRun; - for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) { - const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData; - if (nextFontData != m_currentFontData) - break; - } - m_item.item.length = endOfRun; - m_indexOfNextScriptRun = m_item.item.pos + endOfRun; + if (!hb_utf16_script_run_next(&m_numCodePoints, &m_item.item, m_run.characters(), m_run.length(), &m_indexOfNextScriptRun)) + return false; + + // It is actually wrong to consider script runs at all in this code. + // Other WebKit code (e.g. Mac) segments complex text just by finding + // the longest span of text covered by a single font. + // But we currently need to call hb_utf16_script_run_next anyway to fill + // in the harfbuzz data structures to e.g. pick the correct script's shaper. + // So we allow that to run first, then do a second pass over the range it + // found and take the largest subregion that stays within a single font. + m_currentFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos], false).fontData; + unsigned endOfRun; + for (endOfRun = 1; endOfRun < m_item.item.length; ++endOfRun) { + const SimpleFontData* nextFontData = m_font->glyphDataForCharacter(m_item.string[m_item.item.pos + endOfRun], false).fontData; + if (nextFontData != m_currentFontData) + break; } + m_item.item.length = endOfRun; + m_indexOfNextScriptRun = m_item.item.pos + endOfRun; setupFontForScriptRun(); shapeGlyphs(); @@ -273,7 +251,7 @@ void ComplexTextController::shapeGlyphs() { // HB_ShapeItem() resets m_item.num_glyphs. If the previous call to // HB_ShapeItem() used less space than was available, the capacity of - // the array may be larger than the current value of m_item.num_glyphs. + // the array may be larger than the current value of m_item.num_glyphs. // So, we need to reset the num_glyphs to the capacity of the array. m_item.num_glyphs = m_glyphsArrayCapacity; resetGlyphArrays(); @@ -291,62 +269,49 @@ void ComplexTextController::shapeGlyphs() void ComplexTextController::setGlyphXPositions(bool isRTL) { + const double rtlFlip = isRTL ? -1 : 1; double position = 0; - // logClustersIndex indexes logClusters for the first (or last when - // RTL) codepoint of the current glyph. Each time we advance a glyph, - // we skip over all the codepoints that contributed to the current - // glyph. + + // logClustersIndex indexes logClusters for the first codepoint of the current glyph. + // Each time we advance a glyph, we skip over all the codepoints that contributed to the current glyph. int logClustersIndex = 0; - if (isRTL) { - logClustersIndex = m_item.num_glyphs - 1; - - // Glyphs are stored in logical order, but for layout purposes we - // always go left to right. - for (int i = m_item.num_glyphs - 1; i >= 0; --i) { - if (!m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) { - // Whitespace must be laid out in logical order, so when inserting - // spaces in RTL (but iterating in LTR order) we must insert spaces - // _before_ the next glyph. - if (static_cast<unsigned>(i + 1) >= m_item.num_glyphs || m_item.attributes[i + 1].clusterStart) - position += m_letterSpacing; - - position += determineWordBreakSpacing(logClustersIndex); - } - - m_glyphs16[i] = m_item.glyphs[i]; - double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); - m_xPositions[i] = m_offsetX + position + offsetX; - - while (logClustersIndex > 0 && logClusters()[logClustersIndex] == i) - logClustersIndex--; - - if (!m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) - position += truncateFixedPointToInteger(m_item.advances[i]); - } - } else { - for (size_t i = 0; i < m_item.num_glyphs; ++i) { - m_glyphs16[i] = m_item.glyphs[i]; - double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); - m_xPositions[i] = m_offsetX + position + offsetX; + // Iterate through the glyphs in logical order, flipping for RTL where necessary. + // In RTL mode all variables are positive except m_xPositions, which starts from m_offsetX and runs negative. + // It is fixed up in a second pass below. + for (size_t i = 0; i < m_item.num_glyphs; ++i) { + while (static_cast<unsigned>(logClustersIndex) < m_item.item.length && logClusters()[logClustersIndex] < i) + logClustersIndex++; - if (m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) - continue; + // If the current glyph is just after a space, add in the word spacing. + position += determineWordBreakSpacing(logClustersIndex); - double advance = truncateFixedPointToInteger(m_item.advances[i]); + m_glyphs16[i] = m_item.glyphs[i]; + double offsetX = truncateFixedPointToInteger(m_item.offsets[i].x); + double advance = truncateFixedPointToInteger(m_item.advances[i]); + if (isRTL) + offsetX -= advance; - advance += determineWordBreakSpacing(logClustersIndex); + m_xPositions[i] = m_offsetX + (position * rtlFlip) + offsetX; - if (m_item.attributes[i].clusterStart) - advance += m_letterSpacing; + if (m_currentFontData->isZeroWidthSpaceGlyph(m_glyphs16[i])) + continue; - while (static_cast<unsigned>(logClustersIndex) < m_item.item.length && logClusters()[logClustersIndex] == i) - logClustersIndex++; + // At the end of each cluster, add in the letter spacing. + if (i + 1 == m_item.num_glyphs || m_item.attributes[i + 1].clusterStart) + position += m_letterSpacing; - position += advance; - } + position += advance; } - m_pixelWidth = std::max(position, 0.0); + const double width = position; + + // Now that we've computed the total width, do another pass to fix positioning for RTL. + if (isRTL) { + for (size_t i = 0; i < m_item.num_glyphs; ++i) + m_xPositions[i] += width; + } + + m_pixelWidth = std::max(width, 0.0); m_offsetX += m_pixelWidth; } diff --git a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h index 4ebbd89..e264b99 100644 --- a/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h +++ b/Source/WebCore/platform/graphics/chromium/ComplexTextControllerLinux.h @@ -52,9 +52,8 @@ class SimpleFontData; // only ever done with script runs since the shapers only know how to deal with // a single script. // -// After creating it, the script runs are either iterated backwards or forwards. -// It defaults to backwards for RTL and forwards otherwise (which matches the -// presentation order), however you can set it with |setBackwardsIteration|. +// Iteration is always in logical (aka reading) order. For RTL text that means +// the rightmost part of the text will be first. // // Once you have setup the object, call |nextScriptRun| to get the first script // run. This will return false when the iteration is complete. At any time you @@ -70,7 +69,6 @@ public: // WebKit uses this to justify text. void setPadding(int); void reset(); - void setBackwardsIteration(bool); // Advance to the next script run, returning false when the end of the // TextRun has been reached. bool nextScriptRun(); @@ -148,7 +146,6 @@ private: OwnPtr<TextRun> m_normalizedRun; OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run. const TextRun& m_run; - bool m_iterateBackwards; int m_wordSpacingAdjustment; // delta adjustment (pixels) for each word break. float m_padding; // pixels to be distributed over the line at word breaks. float m_padPerWordBreak; // pixels to be added to each word break. diff --git a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp index 507c227..569dff4 100644 --- a/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp @@ -67,9 +67,14 @@ static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize& } -DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) +DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, + const IntSize& size, + bool multisampleExtensionSupported, + bool packedDepthStencilExtensionSupported) : m_context(context) , m_size(size) + , m_multisampleExtensionSupported(multisampleExtensionSupported) + , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) , m_fbo(0) , m_colorBuffer(0) , m_depthStencilBuffer(0) @@ -85,6 +90,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) m_fbo = context->createFramebuffer(); context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo); m_colorBuffer = generateColorTexture(context, size); + createSecondaryBuffers(); } DrawingBuffer::~DrawingBuffer() diff --git a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp index b256e70..f1eadf2 100644 --- a/Source/WebCore/platform/graphics/chromium/FontLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontLinux.cpp @@ -234,28 +234,21 @@ float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFon return controller.widthOfFullRun(); } -static int glyphIndexForXPositionInScriptRun(const ComplexTextController& controller, int x) +static int glyphIndexForXPositionInScriptRun(const ComplexTextController& controller, int targetX) { - const HB_Fixed* advances = controller.advances(); - int letterSpacing = controller.letterSpacing(); - int glyphIndex; - if (controller.rtl()) { - for (glyphIndex = controller.length() - 1; glyphIndex >= 0; --glyphIndex) { - // When iterating LTR over RTL text, we must include the whitespace - // _before_ the glyph, so no + 1 here. - if (x < (static_cast<int>(controller.length()) - glyphIndex) * letterSpacing + truncateFixedPointToInteger(advances[glyphIndex])) - break; - x -= truncateFixedPointToInteger(advances[glyphIndex]); - } - } else { - for (glyphIndex = 0; static_cast<unsigned>(glyphIndex) < controller.length(); ++glyphIndex) { - if (x < (glyphIndex * letterSpacing + truncateFixedPointToInteger(advances[glyphIndex]))) - break; - x -= truncateFixedPointToInteger(advances[glyphIndex]); - } + // Iterate through the glyphs in logical order, seeing whether targetX falls between the previous + // position and halfway through the current glyph. + // FIXME: this code probably belongs in ComplexTextController. + int lastX = controller.rtl() ? controller.width() : 0; + for (int glyphIndex = 0; static_cast<unsigned>(glyphIndex) < controller.length(); ++glyphIndex) { + int advance = truncateFixedPointToInteger(controller.advances()[glyphIndex]); + int nextX = static_cast<int>(controller.xPositions()[glyphIndex]) + advance / 2; + if (std::min(nextX, lastX) <= targetX && targetX <= std::max(nextX, lastX)) + return glyphIndex; + lastX = nextX; } - return glyphIndex; + return controller.length() - 1; } // Return the code point index for the given |x| offset into the text run. @@ -345,20 +338,16 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, const FloatPoint& point, int height, int from, int to) const { - int fromX = -1, toX = -1, fromAdvance = -1, toAdvance = -1; + int fromX = -1, toX = -1; ComplexTextController controller(run, 0, this); controller.setWordSpacingAdjustment(wordSpacing()); controller.setLetterSpacingAdjustment(letterSpacing()); - // Base will point to the x offset for the current script run. Note that, in + // Base will point to the x offset for the start of the current script run. Note that, in // the LTR case, width will be 0. int base = controller.rtl() ? controller.widthOfFullRun() : 0; - const int leftEdge = base; - - // We want to enumerate the script runs in code point order in the following - // code. This call also resets |controller|. - controller.setBackwardsIteration(false); + controller.reset(); while (controller.nextScriptRun() && (fromX == -1 || toX == -1)) { // ComplexTextController will helpfully accululate the x offsets for different // script runs for us. For this code, however, we always want the x offsets @@ -374,14 +363,16 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, // position. int glyph = controller.logClusters()[from]; fromX = base + controller.xPositions()[glyph]; - fromAdvance = controller.advances()[glyph]; + if (controller.rtl()) + fromX += truncateFixedPointToInteger(controller.advances()[glyph]); } else from -= controller.numCodePoints(); if (toX == -1 && to >= 0 && static_cast<unsigned>(to) < controller.numCodePoints()) { int glyph = controller.logClusters()[to]; toX = base + controller.xPositions()[glyph]; - toAdvance = controller.advances()[glyph]; + if (controller.rtl()) + toX += truncateFixedPointToInteger(controller.advances()[glyph]); } else to -= controller.numCodePoints(); @@ -390,14 +381,11 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, } // The position in question might be just after the text. - const int rightEdge = base; + const int endEdge = base; if (fromX == -1 && !from) - fromX = leftEdge; - else if (controller.rtl()) - fromX += truncateFixedPointToInteger(fromAdvance); - + fromX = endEdge; if (toX == -1 && !to) - toX = rightEdge; + toX = endEdge; ASSERT(fromX != -1 && toX != -1); diff --git a/Source/WebCore/platform/graphics/chromium/LayerTexture.h b/Source/WebCore/platform/graphics/chromium/LayerTexture.h index 312adfa..711e687 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTexture.h +++ b/Source/WebCore/platform/graphics/chromium/LayerTexture.h @@ -48,6 +48,11 @@ public: bool isValid(const IntSize&, unsigned format); bool reserve(const IntSize&, unsigned format); void unreserve(); + bool isReserved() + { + ASSERT(m_textureManager); + return m_textureManager->isProtected(m_token); + } void bindTexture(); void framebufferTexture2D(); diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp index 31649a4..b4b4a72 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp @@ -315,12 +315,18 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont IntRect sourceRect = tileContentRect(i, j); const IntPoint anchor = sourceRect.location(); sourceRect.intersect(layerRectToContentRect(tile->m_dirtyLayerRect)); + if (sourceRect.isEmpty()) + continue; // Calculate tile-space rectangle to upload into. IntRect destRect(IntPoint(sourceRect.x() - anchor.x(), sourceRect.y() - anchor.y()), sourceRect.size()); + ASSERT(destRect.x() >= 0); + ASSERT(destRect.y() >= 0); // Offset from paint rectangle to this tile's dirty rectangle. IntPoint paintOffset(sourceRect.x() - paintRect.x(), sourceRect.y() - paintRect.y()); + ASSERT(paintOffset.x() >= 0); + ASSERT(paintOffset.y() >= 0); uint8_t* pixelSource; if (paintRect.width() == sourceRect.width() && !paintOffset.x()) diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index e8b9a12..696828f 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -124,6 +124,9 @@ bool RenderSurfaceChromium::prepareContentsTexture() if (!m_contentsTexture) m_contentsTexture = LayerTexture::create(layerRenderer()->context(), textureManager); + if (m_contentsTexture->isReserved()) + return true; + if (!m_contentsTexture->reserve(requiredSize, GraphicsContext3D::RGBA)) { m_skipsDraw = true; return false; diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp index 9579ef9..c4ad958 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp @@ -70,6 +70,11 @@ bool TextureManager::hasTexture(TextureToken token) return false; } +bool TextureManager::isProtected(TextureToken token) +{ + return token && hasTexture(token) && m_textures.get(token).isProtected; +} + void TextureManager::protectTexture(TextureToken token) { ASSERT(hasTexture(token)); diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.h b/Source/WebCore/platform/graphics/chromium/TextureManager.h index 1e850cd..4891cc7 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.h +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.h @@ -51,6 +51,7 @@ public: void protectTexture(TextureToken); void unprotectTexture(TextureToken); + bool isProtected(TextureToken); private: TextureManager(GraphicsContext3D*, size_t memoryLimitBytes, int maxTextureSize); diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp index 7eeb128..ac68266 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "FloatPoint.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp index e0b15d1..33c4467 100644 --- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -27,6 +27,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp index ca8e5d3..ab59332 100644 --- a/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp +++ b/Source/WebCore/platform/graphics/filters/FEComponentTransfer.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.cpp b/Source/WebCore/platform/graphics/filters/FEComposite.cpp index 80cb2b2..bc7fa80 100644 --- a/Source/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/Source/WebCore/platform/graphics/filters/FEComposite.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp index b8f8aea..0483626 100644 --- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp @@ -27,6 +27,8 @@ #include "FEConvolveMatrix.h" #include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp index 14d57f4..a8a825a 100644 --- a/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDiffuseLighting.cpp @@ -25,6 +25,8 @@ #include "FEDiffuseLighting.h" #include "LightSource.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp index b5151bf..88c87b7 100644 --- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.cpp b/Source/WebCore/platform/graphics/filters/FEFlood.cpp index 8bfdef8..0e0e94c 100644 --- a/Source/WebCore/platform/graphics/filters/FEFlood.cpp +++ b/Source/WebCore/platform/graphics/filters/FEFlood.cpp @@ -27,6 +27,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index 37b5992..20fd923 100644 --- a/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/Source/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -29,6 +29,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FEMerge.cpp b/Source/WebCore/platform/graphics/filters/FEMerge.cpp index 4395321..4099a96 100644 --- a/Source/WebCore/platform/graphics/filters/FEMerge.cpp +++ b/Source/WebCore/platform/graphics/filters/FEMerge.cpp @@ -26,6 +26,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp index 45c7edb..1eb554b 100644 --- a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp +++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp @@ -27,6 +27,8 @@ #include "FEMorphology.h" #include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/Vector.h> diff --git a/Source/WebCore/platform/graphics/filters/FEOffset.cpp b/Source/WebCore/platform/graphics/filters/FEOffset.cpp index f1d5914..99cac2d 100644 --- a/Source/WebCore/platform/graphics/filters/FEOffset.cpp +++ b/Source/WebCore/platform/graphics/filters/FEOffset.cpp @@ -28,6 +28,8 @@ #include "Filter.h" #include "GraphicsContext.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp index d21dafd..36a6b72 100644 --- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp @@ -25,6 +25,8 @@ #include "FESpecularLighting.h" #include "LightSource.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FETile.cpp b/Source/WebCore/platform/graphics/filters/FETile.cpp index e516c7e..1fcb71b 100644 --- a/Source/WebCore/platform/graphics/filters/FETile.cpp +++ b/Source/WebCore/platform/graphics/filters/FETile.cpp @@ -27,7 +27,9 @@ #include "Filter.h" #include "GraphicsContext.h" #include "Pattern.h" +#include "RenderTreeAsText.h" #include "SVGImageBufferTools.h" +#include "TextStream.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp index f1a159b..068acee 100644 --- a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp +++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp @@ -27,6 +27,8 @@ #include "FETurbulence.h" #include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/ByteArray.h> #include <wtf/MathExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp index 05c2a47..85154b5 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -24,6 +24,9 @@ #if ENABLE(FILTERS) #include "FilterEffect.h" +#include "Filter.h" +#include "ImageBuffer.h" +#include "TextStream.h" #include <wtf/ByteArray.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/filters/FilterEffect.h b/Source/WebCore/platform/graphics/filters/FilterEffect.h index 2554d4b..062dd1b 100644 --- a/Source/WebCore/platform/graphics/filters/FilterEffect.h +++ b/Source/WebCore/platform/graphics/filters/FilterEffect.h @@ -23,13 +23,10 @@ #define FilterEffect_h #if ENABLE(FILTERS) -#include "Filter.h" #include "FloatRect.h" -#include "GraphicsContext.h" -#include "ImageBuffer.h" -#include "RenderTreeAsText.h" -#include "TextStream.h" +#include "IntRect.h" +#include <wtf/ByteArray.h> #include <wtf/PassOwnPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> @@ -37,6 +34,11 @@ namespace WebCore { +class Filter; +class FilterEffect; +class ImageBuffer; +class TextStream; + typedef Vector<RefPtr<FilterEffect> > FilterEffectVector; enum FilterEffectType { diff --git a/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp b/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp index 2d2de00..45d74f5 100644 --- a/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp +++ b/Source/WebCore/platform/graphics/filters/SourceAlpha.cpp @@ -23,9 +23,11 @@ #include "SourceAlpha.h" #include "Color.h" +#include "Filter.h" #include "GraphicsContext.h" #include "PlatformString.h" -#include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/StdLibExtras.h> diff --git a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp index 04082ad..8726bf3 100644 --- a/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp +++ b/Source/WebCore/platform/graphics/filters/SourceGraphic.cpp @@ -22,9 +22,11 @@ #if ENABLE(FILTERS) #include "SourceGraphic.h" +#include "Filter.h" #include "GraphicsContext.h" #include "PlatformString.h" -#include "Filter.h" +#include "RenderTreeAsText.h" +#include "TextStream.h" #include <wtf/StdLibExtras.h> diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp index d2415ca..c283068 100644 --- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp +++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp @@ -40,14 +40,16 @@ namespace WebCore { PassRefPtr<DrawingBuffer> DrawingBuffer::create(GraphicsContext3D* context, const IntSize& size) { - RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size)); Extensions3D* extensions = context->getExtensions(); bool multisampleSupported = extensions->supports("GL_ANGLE_framebuffer_blit") && extensions->supports("GL_ANGLE_framebuffer_multisample"); if (multisampleSupported) { extensions->ensureEnabled("GL_ANGLE_framebuffer_blit"); extensions->ensureEnabled("GL_ANGLE_framebuffer_multisample"); } - drawingBuffer->m_multisampleExtensionSupported = multisampleSupported; + bool packedDepthStencilSupported = extensions->supports("GL_OES_packed_depth_stencil"); + if (packedDepthStencilSupported) + extensions->ensureEnabled("GL_OES_packed_depth_stencil"); + RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, size, multisampleSupported, packedDepthStencilSupported)); return (drawingBuffer->m_context) ? drawingBuffer.release() : 0; } @@ -88,6 +90,24 @@ void DrawingBuffer::clear() m_context.clear(); } +void DrawingBuffer::createSecondaryBuffers() +{ + const GraphicsContext3D::Attributes& attributes = m_context->getContextAttributes(); + + // Create the stencil and depth buffer if needed + if (!multisample() && (attributes.stencil || attributes.depth)) + m_depthStencilBuffer = m_context->createRenderbuffer(); + + // create a multisample FBO + if (multisample()) { + m_multisampleFBO = m_context->createFramebuffer(); + m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); + m_multisampleColorBuffer = m_context->createRenderbuffer(); + if (attributes.stencil || attributes.depth) + m_multisampleDepthStencilBuffer = m_context->createRenderbuffer(); + } +} + void DrawingBuffer::reset(const IntSize& newSize) { if (m_size == newSize) @@ -111,10 +131,13 @@ void DrawingBuffer::reset(const IntSize& newSize) if (attributes.stencil || attributes.depth) { // We don't allow the logic where stencil is required and depth is not. // See GraphicsContext3D constructor. - if (attributes.stencil && attributes.depth) - internalDepthStencilFormat = GraphicsContext3D::DEPTH_STENCIL; + + // FIXME: If packed depth/stencil is not supported, we should + // create separate renderbuffers for depth and stencil. + if (attributes.stencil && attributes.depth && m_packedDepthStencilExtensionSupported) + internalDepthStencilFormat = Extensions3D::DEPTH24_STENCIL8; else - internalDepthStencilFormat = GraphicsContext3D::DEPTH_COMPONENT; + internalDepthStencilFormat = GraphicsContext3D::DEPTH_COMPONENT16; } // resize multisample FBO @@ -150,7 +173,7 @@ void DrawingBuffer::reset(const IntSize& newSize) m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer); m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE); - m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE, m_colorBuffer, 0); + m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_colorBuffer, 0); m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); if (!multisample() && (attributes.stencil || attributes.depth)) { m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_depthStencilBuffer); diff --git a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h index 9f79889..e0e0ee1 100644 --- a/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h +++ b/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h @@ -63,6 +63,9 @@ public: // Clear all resources from this object, as well as context. Called when context is destroyed // to prevent invalid accesses to the resources. void clear(); + + // Create the depth/stencil and multisample buffers, if needed. + void createSecondaryBuffers(); // Copies the multisample color buffer to the normal color buffer and leaves m_fbo bound void commit(long x = 0, long y = 0, long width = -1, long height = -1); @@ -92,7 +95,7 @@ public: private: static PassRefPtr<DrawingBuffer> create(GraphicsContext3D*, const IntSize&); - DrawingBuffer(GraphicsContext3D*, const IntSize&); + DrawingBuffer(GraphicsContext3D*, const IntSize&, bool multisampleExtensionSupported, bool packedDepthStencilExtensionSupported); // Platform specific function called after reset() so each platform can do extra work if needed void didReset(); @@ -100,6 +103,7 @@ private: RefPtr<GraphicsContext3D> m_context; IntSize m_size; bool m_multisampleExtensionSupported; + bool m_packedDepthStencilExtensionSupported; Platform3DObject m_fbo; Platform3DObject m_colorBuffer; Platform3DObject m_depthStencilBuffer; diff --git a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm index 89dcb9c..601454e 100644 --- a/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm +++ b/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm @@ -36,9 +36,14 @@ namespace WebCore { -DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) +DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, + const IntSize& size, + bool multisampleExtensionSupported, + bool packedDepthStencilExtensionSupported) : m_context(context) , m_size(size) + , m_multisampleExtensionSupported(multisampleExtensionSupported) + , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) , m_fbo(context->createFramebuffer()) , m_colorBuffer(0) , m_depthStencilBuffer(0) @@ -77,21 +82,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, const IntSize& size) return; } - const GraphicsContext3D::Attributes& attributes = context->getContextAttributes(); - - // Create the stencil and depth buffer if needed - if (!multisample() && (attributes.stencil || attributes.depth)) - m_depthStencilBuffer = context->createRenderbuffer(); - - // create a multisample FBO - if (multisample()) { - m_multisampleFBO = context->createFramebuffer(); - context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO); - m_multisampleColorBuffer = context->createRenderbuffer(); - if (attributes.stencil || attributes.depth) - m_multisampleDepthStencilBuffer = context->createRenderbuffer(); - } - + createSecondaryBuffers(); reset(size); } diff --git a/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp b/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp index d179601..a4b20be 100644 --- a/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp @@ -43,7 +43,8 @@ gboolean gstGWorldSyncMessageCallback(GstBus* bus, GstMessage* message, gpointer GStreamerGWorld* gstGWorld = static_cast<GStreamerGWorld*>(data); - if (gst_structure_has_name(message->structure, "prepare-xwindow-id")) + if (gst_structure_has_name(message->structure, "prepare-xwindow-id") + || gst_structure_has_name(message->structure, "have-ns-view")) gstGWorld->setWindowOverlay(message); return TRUE; } diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h index f2a3ff2..d71e6d3 100644 --- a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h +++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindow.h @@ -25,6 +25,10 @@ #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> +#endif + typedef struct _GstMessage GstMessage; namespace WebCore { @@ -38,13 +42,22 @@ class PlatformVideoWindow : public RefCounted<PlatformVideoWindow> { void prepareForOverlay(GstMessage*); +#if !PLATFORM(MAC) PlatformWidget window() const { return m_window; } +#else + PlatformWidget window() const { return m_window.get(); } +#endif unsigned long videoWindowId() const { return m_videoWindowId; } private: unsigned long m_videoWindowId; PlatformWidget m_videoWindow; +#if !PLATFORM(MAC) PlatformWidget m_window; +#else + RetainPtr<NSView> m_window; +#endif + }; } diff --git a/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowMac.mm b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowMac.mm new file mode 100644 index 0000000..e98cf9b --- /dev/null +++ b/Source/WebCore/platform/graphics/gstreamer/PlatformVideoWindowMac.mm @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2011 Igalia S.L + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "config.h" +#include "PlatformVideoWindow.h" + +#if USE(GSTREAMER) + +#include <gst/gst.h> + +using namespace WebCore; + +PlatformVideoWindow::PlatformVideoWindow() +{ + m_window.adoptNS([[NSView alloc] init]); + m_videoWindowId = reinterpret_cast<unsigned long>(m_window.get()); +} + +PlatformVideoWindow::~PlatformVideoWindow() +{ + m_videoWindowId = 0; +} + +void PlatformVideoWindow::prepareForOverlay(GstMessage* message) +{ + if (gst_structure_has_name(message->structure, "have-ns-view")) { + m_videoWindow = static_cast<PlatformWidget>(g_value_get_pointer(gst_structure_get_value(message->structure, "nsview"))); + ASSERT(m_videoWindow); + [m_window.get() addSubview:m_videoWindow]; + } +} + +#endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index acd431d..4e17f94 100644 --- a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -34,7 +34,6 @@ #include "FontData.h" #include "NotImplemented.h" #include "Path.h" -#include "Pen.h" #include <wtf/text/CString.h> #include <GraphicsDefs.h> #include <Region.h> diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index e237fc0..253cd84 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -496,8 +496,17 @@ void GraphicsContext::fillPath(const Path& path) { QPainter* shadowPainter = shadow->beginShadowLayer(this, platformPath.controlPointRect()); if (shadowPainter) { - shadowPainter->setCompositionMode(QPainter::CompositionMode_Source); - shadowPainter->fillPath(platformPath, QColor(m_data->shadow.m_color)); + if (m_state.fillPattern) { + AffineTransform affine; + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); + shadowPainter->fillPath(platformPath, QBrush(m_state.fillPattern->createPlatformPattern(affine))); + } else if (m_state.fillGradient) { + QBrush brush(*m_state.fillGradient->platformGradient()); + brush.setTransform(m_state.fillGradient->gradientSpaceTransform()); + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); + shadowPainter->fillPath(platformPath, brush); + } else + shadowPainter->fillPath(platformPath, QColor(shadow->m_color)); shadow->endShadowLayer(this); } } else { diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index f31844a..75fb427 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "GraphicsLayerQt.h" +#if !defined(QT_NO_GRAPHICSVIEW) + #include "CurrentTime.h" #include "FloatRect.h" #include "GraphicsContext.h" @@ -1375,6 +1377,7 @@ static inline qreal applyTimingFunction(const TimingFunction* timingFunction, qr // Helper functions to safely get a value out of WebCore's AnimationValue*. +#ifndef QT_NO_ANIMATION static void webkitAnimationToQtAnimationValue(const AnimationValue* animationValue, TransformOperations& transformOperations) { transformOperations = TransformOperations(); @@ -1390,7 +1393,6 @@ static void webkitAnimationToQtAnimationValue(const AnimationValue* animationVal realValue = animationValue ? static_cast<const FloatAnimationValue*>(animationValue)->value() : 0; } -#ifndef QT_NO_ANIMATION // We put a bit of the functionality in a base class to allow casting and to save some code size. class AnimationQtBase : public QAbstractAnimation { @@ -1777,3 +1779,6 @@ void GraphicsLayerQt::resumeAnimations() } #include <GraphicsLayerQt.moc> + + +#endif // QT_NO_GRAPHICSVIEW diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h index b1692d2..8027143 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h +++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.h @@ -26,6 +26,8 @@ #include "GraphicsLayer.h" #include "GraphicsLayerClient.h" +#if !defined(QT_NO_GRAPHICSVIEW) + namespace WebCore { class GraphicsLayerQtImpl; @@ -92,4 +94,5 @@ private: }; } +#endif #endif // GraphicsLayerQt_h diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index 2bbb9ce..71352e4 100644 --- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -131,7 +131,7 @@ String ImageDecoderQt::filenameExtension() const return String(m_format.constData(), m_format.length()); }; -RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index) +ImageFrame* ImageDecoderQt::frameBufferAtIndex(size_t index) { // In case the ImageDecoderQt got recreated we don't know // yet how many images we are going to have and need to @@ -145,8 +145,8 @@ RGBA32Buffer* ImageDecoderQt::frameBufferAtIndex(size_t index) if (index >= count) return 0; - RGBA32Buffer& frame = m_frameBufferCache[index]; - if (frame.status() != RGBA32Buffer::FrameComplete && m_reader) + ImageFrame& frame = m_frameBufferCache[index]; + if (frame.status() != ImageFrame::FrameComplete && m_reader) internalReadImage(index); return &frame; } @@ -185,7 +185,7 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex) // Attempt to return some memory for (int i = 0; i < m_frameBufferCache.size(); ++i) { - if (m_frameBufferCache[i].status() != RGBA32Buffer::FrameComplete) + if (m_frameBufferCache[i].status() != ImageFrame::FrameComplete) return; } @@ -211,10 +211,10 @@ bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) return false; } - // now into the RGBA32Buffer - even if the image is not - RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex]; + // now into the ImageFrame - even if the image is not + ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; buffer->setRect(m_reader->currentImageRect()); - buffer->setStatus(RGBA32Buffer::FrameComplete); + buffer->setStatus(ImageFrame::FrameComplete); buffer->setDuration(m_reader->nextImageDelay()); buffer->setPixmap(pixmap); return true; diff --git a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h index 23fb79a..bccb5be 100644 --- a/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h +++ b/Source/WebCore/platform/graphics/qt/ImageDecoderQt.h @@ -48,7 +48,7 @@ public: virtual bool isSizeAvailable(); virtual size_t frameCount(); virtual int repetitionCount() const; - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); virtual String filenameExtension() const; diff --git a/Source/WebCore/platform/graphics/qt/ImageQt.cpp b/Source/WebCore/platform/graphics/qt/ImageQt.cpp index 49afd29..58f82ef 100644 --- a/Source/WebCore/platform/graphics/qt/ImageQt.cpp +++ b/Source/WebCore/platform/graphics/qt/ImageQt.cpp @@ -68,6 +68,10 @@ static QPixmap loadResourcePixmap(const char *name) pixmap = QWebSettings::webGraphic(QWebSettings::DeleteButtonGraphic); else if (!qstrcmp(name, "inputSpeech")) pixmap = QWebSettings::webGraphic(QWebSettings::InputSpeechButtonGraphic); + else if (!qstrcmp(name, "searchCancelButton")) + pixmap = QWebSettings::webGraphic(QWebSettings::SearchCancelButtonGraphic); + else if (!qstrcmp(name, "searchCancelButtonPressed")) + pixmap = QWebSettings::webGraphic(QWebSettings::SearchCancelButtonPressedGraphic); return pixmap; } @@ -121,8 +125,30 @@ void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const if (!pixmap.hasAlpha() && p->compositionMode() == QPainter::CompositionMode_SourceOver) p->setCompositionMode(QPainter::CompositionMode_Source); - /* Translate the coordinates as phase is not in world matrix coordinate space but the tile rect origin is. */ QTransform transform(patternTransform); + + // If this would draw more than one scaled tile, we scale the pixmap first and then use the result to draw. + if (transform.type() == QTransform::TxScale) { + QRectF tileRectInTargetCoords = (transform * QTransform().translate(phase.x(), phase.y())).mapRect(tr); + + bool tileWillBePaintedOnlyOnce = tileRectInTargetCoords.contains(dr); + if (!tileWillBePaintedOnlyOnce) { + QSizeF scaledSize(float(pixmap.width()) * transform.m11(), float(pixmap.height()) * transform.m22()); + QPixmap scaledPixmap(scaledSize.toSize()); + if (pixmap.hasAlpha()) + scaledPixmap.fill(Qt::transparent); + { + QPainter painter(&scaledPixmap); + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.setRenderHints(p->renderHints()); + painter.drawPixmap(QRect(0, 0, scaledPixmap.width(), scaledPixmap.height()), pixmap); + } + pixmap = scaledPixmap; + transform = QTransform::fromTranslate(transform.dx(), transform.dy()); + } + } + + /* Translate the coordinates as phase is not in world matrix coordinate space but the tile rect origin is. */ transform *= QTransform().translate(phase.x(), phase.y()); transform.translate(tr.x(), tr.y()); diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index dd4b6e6..be6f732 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -108,7 +108,7 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player) , m_queuedSeek(-1) , m_preload(MediaPlayer::Auto) { - m_mediaPlayer->bind(m_videoItem); + m_mediaPlayer->setVideoOutput(m_videoItem); m_videoScene->addItem(m_videoItem); // Signal Handlers @@ -587,6 +587,22 @@ IntSize MediaPlayerPrivateQt::naturalSize() const return m_naturalSize; } +void MediaPlayerPrivateQt::removeVideoItem() +{ + m_oldNaturalSize = m_naturalSize; + m_mediaPlayer->setVideoOutput(static_cast<QGraphicsVideoItem*>(0)); + m_videoScene->removeItem(m_videoItem); +} + +void MediaPlayerPrivateQt::restoreVideoItem() +{ + m_mediaPlayer->setVideoOutput(m_videoItem); + m_videoScene->addItem(m_videoItem); + // FIXME: a qtmobility bug, need to reset the size when restore the videoitem, otherwise the size is 0 + // http://bugreports.qt.nokia.com/browse/QTMOBILITY-971 + nativeSizeChanged(QSize(m_oldNaturalSize)); +} + void MediaPlayerPrivateQt::paint(GraphicsContext* context, const IntRect& rect) { #if USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h index 93c9d1c..2621432 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h @@ -90,7 +90,7 @@ public: void paint(GraphicsContext*, const IntRect&); - bool supportsFullscreen() const { return false; } + bool supportsFullscreen() const { return true; } #if USE(ACCELERATED_COMPOSITING) #if USE(TEXTURE_MAPPER) @@ -108,6 +108,11 @@ public: #endif virtual PlatformMedia platformMedia() const; + + QMediaPlayer* mediaPlayer() const { return m_mediaPlayer; } + void removeVideoItem(); + void restoreVideoItem(); + private slots: void mediaStatusChanged(QMediaPlayer::MediaStatus); void handleError(QMediaPlayer::Error); @@ -142,6 +147,7 @@ private: IntSize m_currentSize; IntSize m_naturalSize; + IntSize m_oldNaturalSize; bool m_isVisible; bool m_isSeeking; bool m_composited; diff --git a/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h b/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h index 553f203..974f126 100644 --- a/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h +++ b/Source/WebCore/platform/graphics/skia/BitmapImageSingleFrameSkia.h @@ -82,6 +82,8 @@ private: explicit BitmapImageSingleFrameSkia(const SkBitmap&); }; +FloatRect normalizeRect(const FloatRect&); + } // namespace WebCore #endif // BitmapImageSingleFrameSkia_h diff --git a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp index a9f6d3c..b65b5bd 100644 --- a/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/ImageBufferSkia.cpp @@ -114,11 +114,12 @@ void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, con if (context->platformContext()->canAccelerate()) { DrawingBuffer* sourceDrawingBuffer = m_data.m_platformContext.gpuCanvas()->drawingBuffer(); unsigned sourceTexture = static_cast<unsigned>(sourceDrawingBuffer->platformColorBuffer()); - FloatRect destRectFlipped(destRect); - destRectFlipped.setY(destRect.y() + destRect.height()); - destRectFlipped.setHeight(-destRect.height()); + FloatRect destRectNormalized(normalizeRect(destRect)); + FloatRect srcRectFlipped(normalizeRect(srcRect)); + srcRectFlipped.setY(m_size.height() - srcRect.y()); + srcRectFlipped.setHeight(-srcRect.height()); context->platformContext()->prepareForHardwareDraw(); - context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRect, destRectFlipped, styleColorSpace, op); + context->platformContext()->gpuCanvas()->drawTexturedRect(sourceTexture, m_size, srcRectFlipped, destRectNormalized, styleColorSpace, op); return; } m_data.m_platformContext.syncSoftwareCanvas(); diff --git a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp index c7fa6f4..91a4e4f 100644 --- a/Source/WebCore/platform/graphics/skia/ImageSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/ImageSkia.cpp @@ -298,7 +298,7 @@ static void TransformDimensions(const SkMatrix& matrix, float srcWidth, float sr } // A helper method for translating negative width and height values. -static FloatRect normalizeRect(const FloatRect& rect) +FloatRect normalizeRect(const FloatRect& rect) { FloatRect norm = rect; if (norm.width() < 0) { diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp index cbe38aa..7abe2eb 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateFullscreenWindow.cpp @@ -80,6 +80,10 @@ void MediaPlayerPrivateFullscreenWindow::createWindow(HWND parentHwnd) parentHwnd, 0, WebCore::instanceHandle(), this); ASSERT(IsWindow(m_hwnd)); +#if USE(ACCELERATED_COMPOSITING) + m_layerRenderer->setHostWindow(m_hwnd); +#endif + ::SetFocus(m_hwnd); } @@ -139,17 +143,10 @@ LRESULT MediaPlayerPrivateFullscreenWindow::wndProc(HWND hWnd, UINT message, WPA switch (message) { case WM_CREATE: m_hwnd = hWnd; -#if USE(ACCELERATED_COMPOSITING) - m_layerRenderer->setHostWindow(m_hwnd); - m_layerRenderer->createRenderer(); - if (m_rootChild) - m_layerRenderer->setNeedsDisplay(); -#endif break; case WM_DESTROY: m_hwnd = 0; #if USE(ACCELERATED_COMPOSITING) - m_layerRenderer->destroyRenderer(); m_layerRenderer->setHostWindow(0); #endif break; @@ -169,7 +166,8 @@ LRESULT MediaPlayerPrivateFullscreenWindow::wndProc(HWND hWnd, UINT message, WPA break; case WM_PAINT: #if USE(ACCELERATED_COMPOSITING) - m_layerRenderer->renderSoon(); + m_layerRenderer->paint(); + ::ValidateRect(m_hwnd, 0); #endif break; } diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayer.cpp b/Source/WebCore/platform/graphics/win/WKCACFLayer.cpp deleted file mode 100644 index a8714e3..0000000 --- a/Source/WebCore/platform/graphics/win/WKCACFLayer.cpp +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (C) 2009 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. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if USE(ACCELERATED_COMPOSITING) - -#include "WKCACFLayer.h" - -#include "WKCACFLayerRenderer.h" -#include <WebKitSystemInterface/WebKitSystemInterface.h> -#include <stdio.h> -#include <wtf/CurrentTime.h> -#include <wtf/text/CString.h> - -namespace WebCore { - -using namespace std; - -#ifndef NDEBUG -void WKCACFLayer::internalCheckLayerConsistency() -{ - ASSERT(layer()); - size_t n = sublayerCount(); - for (size_t i = 0; i < n; ++i) { - // This will ASSERT in internalSublayerAtIndex if this entry doesn't have proper user data - WKCACFLayer* sublayer = internalSublayerAtIndex(i); - - // Make sure we don't have any null entries in the list - ASSERT(sublayer); - - // Make sure the each layer has a corresponding CACFLayer - ASSERT(sublayer->layer()); - } -} -#endif - -static void displayCallback(CACFLayerRef layer, CGContextRef context) -{ - ASSERT_ARG(layer, WKCACFLayer::layer(layer)); - WKCACFLayer::layer(layer)->drawInContext(context); -} - -static CFStringRef toCACFLayerType(WKCACFLayer::LayerType type) -{ - switch (type) { - case WKCACFLayer::Layer: return kCACFLayer; - case WKCACFLayer::TransformLayer: return kCACFTransformLayer; - default: return 0; - } -} - -static CFStringRef toCACFContentsGravityType(WKCACFLayer::ContentsGravityType type) -{ - switch (type) { - case WKCACFLayer::Center: return kCACFGravityCenter; - case WKCACFLayer::Top: return kCACFGravityTop; - case WKCACFLayer::Bottom: return kCACFGravityBottom; - case WKCACFLayer::Left: return kCACFGravityLeft; - case WKCACFLayer::Right: return kCACFGravityRight; - case WKCACFLayer::TopLeft: return kCACFGravityTopLeft; - case WKCACFLayer::TopRight: return kCACFGravityTopRight; - case WKCACFLayer::BottomLeft: return kCACFGravityBottomLeft; - case WKCACFLayer::BottomRight: return kCACFGravityBottomRight; - case WKCACFLayer::Resize: return kCACFGravityResize; - case WKCACFLayer::ResizeAspect: return kCACFGravityResizeAspect; - case WKCACFLayer::ResizeAspectFill: return kCACFGravityResizeAspectFill; - default: return 0; - } -} - -static WKCACFLayer::ContentsGravityType fromCACFContentsGravityType(CFStringRef string) -{ - if (CFEqual(string, kCACFGravityTop)) - return WKCACFLayer::Top; - - if (CFEqual(string, kCACFGravityBottom)) - return WKCACFLayer::Bottom; - - if (CFEqual(string, kCACFGravityLeft)) - return WKCACFLayer::Left; - - if (CFEqual(string, kCACFGravityRight)) - return WKCACFLayer::Right; - - if (CFEqual(string, kCACFGravityTopLeft)) - return WKCACFLayer::TopLeft; - - if (CFEqual(string, kCACFGravityTopRight)) - return WKCACFLayer::TopRight; - - if (CFEqual(string, kCACFGravityBottomLeft)) - return WKCACFLayer::BottomLeft; - - if (CFEqual(string, kCACFGravityBottomRight)) - return WKCACFLayer::BottomRight; - - if (CFEqual(string, kCACFGravityResize)) - return WKCACFLayer::Resize; - - if (CFEqual(string, kCACFGravityResizeAspect)) - return WKCACFLayer::ResizeAspect; - - if (CFEqual(string, kCACFGravityResizeAspectFill)) - return WKCACFLayer::ResizeAspectFill; - - return WKCACFLayer::Center; -} - -static CFStringRef toCACFFilterType(WKCACFLayer::FilterType type) -{ - switch (type) { - case WKCACFLayer::Linear: return kCACFFilterLinear; - case WKCACFLayer::Nearest: return kCACFFilterNearest; - case WKCACFLayer::Trilinear: return kCACFFilterTrilinear; - default: return 0; - } -} - -static WKCACFLayer::FilterType fromCACFFilterType(CFStringRef string) -{ - if (CFEqual(string, kCACFFilterNearest)) - return WKCACFLayer::Nearest; - - if (CFEqual(string, kCACFFilterTrilinear)) - return WKCACFLayer::Trilinear; - - return WKCACFLayer::Linear; -} - -PassRefPtr<WKCACFLayer> WKCACFLayer::create(LayerType type) -{ - if (!WKCACFLayerRenderer::acceleratedCompositingAvailable()) - return 0; - return adoptRef(new WKCACFLayer(type)); -} - -// FIXME: It might be good to have a way of ensuring that all WKCACFLayers eventually -// get destroyed in debug builds. A static counter could accomplish this pretty easily. - -WKCACFLayer::WKCACFLayer(LayerType type) - : m_layer(AdoptCF, CACFLayerCreate(toCACFLayerType(type))) - , m_layoutClient(0) - , m_needsDisplayOnBoundsChange(false) -{ - CACFLayerSetUserData(layer(), this); - CACFLayerSetDisplayCallback(layer(), displayCallback); -} - -WKCACFLayer::~WKCACFLayer() -{ - // Our superlayer should be holding a reference to us, so there should be no way for us to be destroyed while we still have a superlayer. - ASSERT(!superlayer()); - - // Get rid of the children so we don't have any dangling references around - removeAllSublayers(); - -#ifndef NDEBUG - CACFLayerSetUserData(layer(), reinterpret_cast<void*>(0xDEADBEEF)); -#else - CACFLayerSetUserData(layer(), 0); -#endif - CACFLayerSetDisplayCallback(layer(), 0); -} - -void WKCACFLayer::becomeRootLayerForContext(WKCACFContext* context) -{ - wkCACFContextSetLayer(context, layer()); - setNeedsCommit(); -} - -void WKCACFLayer::setNeedsCommit() -{ - WKCACFLayer* root = rootLayer(); - - // Call setNeedsRender on the root layer, which will cause a render to - // happen in WKCACFLayerRenderer - root->setNeedsRender(); -} - -bool WKCACFLayer::isTransformLayer() const -{ - return CACFLayerGetClass(layer()) == kCACFTransformLayer; -} - -void WKCACFLayer::addSublayer(PassRefPtr<WKCACFLayer> sublayer) -{ - insertSublayer(sublayer, sublayerCount()); -} - -void WKCACFLayer::internalInsertSublayer(PassRefPtr<WKCACFLayer> sublayer, size_t index) -{ - index = min(index, sublayerCount() + 1); - sublayer->removeFromSuperlayer(); - CACFLayerInsertSublayer(layer(), sublayer->layer(), index); - setNeedsCommit(); - checkLayerConsistency(); -} - -void WKCACFLayer::insertSublayerAboveLayer(PassRefPtr<WKCACFLayer> sublayer, const WKCACFLayer* reference) -{ - if (!reference) { - insertSublayer(sublayer, 0); - return; - } - - int referenceIndex = internalIndexOfSublayer(reference); - if (referenceIndex == -1) { - addSublayer(sublayer); - return; - } - - insertSublayer(sublayer, referenceIndex + 1); -} - -void WKCACFLayer::insertSublayerBelowLayer(PassRefPtr<WKCACFLayer> sublayer, const WKCACFLayer* reference) -{ - if (!reference) { - insertSublayer(sublayer, 0); - return; - } - - int referenceIndex = internalIndexOfSublayer(reference); - if (referenceIndex == -1) { - addSublayer(sublayer); - return; - } - - insertSublayer(sublayer, referenceIndex); -} - -void WKCACFLayer::replaceSublayer(WKCACFLayer* reference, PassRefPtr<WKCACFLayer> newLayer) -{ - ASSERT_ARG(reference, reference); - ASSERT_ARG(reference, reference->superlayer() == this); - - if (reference == newLayer) - return; - - int referenceIndex = internalIndexOfSublayer(reference); - ASSERT(referenceIndex != -1); - if (referenceIndex == -1) - return; - - reference->removeFromSuperlayer(); - - if (newLayer) { - newLayer->removeFromSuperlayer(); - insertSublayer(newLayer, referenceIndex); - } -} - -size_t WKCACFLayer::internalSublayerCount() const -{ - CFArrayRef sublayers = CACFLayerGetSublayers(layer()); - return sublayers ? CFArrayGetCount(sublayers) : 0; -} - -void WKCACFLayer::adoptSublayers(WKCACFLayer* source) -{ - // We will use setSublayers() because it properly nulls - // out the superlayer pointer. - Vector<RefPtr<WKCACFLayer> > sublayers; - size_t n = source->sublayerCount(); - - for (size_t i = 0; i < n; ++i) - sublayers.append(source->internalSublayerAtIndex(i)); - - setSublayers(sublayers); - source->checkLayerConsistency(); -} - -void WKCACFLayer::removeFromSuperlayer() -{ - WKCACFLayer* superlayer = this->superlayer(); - CACFLayerRemoveFromSuperlayer(layer()); - checkLayerConsistency(); - - if (superlayer) - superlayer->setNeedsCommit(); -} - -WKCACFLayer* WKCACFLayer::internalSublayerAtIndex(int index) const -{ - CFArrayRef sublayers = CACFLayerGetSublayers(layer()); - if (!sublayers || index < 0 || CFArrayGetCount(sublayers) <= index) - return 0; - - return layer(static_cast<CACFLayerRef>(const_cast<void*>(CFArrayGetValueAtIndex(sublayers, index)))); -} - -int WKCACFLayer::internalIndexOfSublayer(const WKCACFLayer* reference) -{ - CACFLayerRef ref = reference->layer(); - if (!ref) - return -1; - - CFArrayRef sublayers = CACFLayerGetSublayers(layer()); - if (!sublayers) - return -1; - - size_t n = CFArrayGetCount(sublayers); - - for (size_t i = 0; i < n; ++i) - if (CFArrayGetValueAtIndex(sublayers, i) == ref) - return i; - - return -1; -} - -WKCACFLayer* WKCACFLayer::ancestorOrSelfWithSuperlayer(WKCACFLayer* superlayer) const -{ - WKCACFLayer* layer = const_cast<WKCACFLayer*>(this); - for (WKCACFLayer* ancestor = this->superlayer(); ancestor; layer = ancestor, ancestor = ancestor->superlayer()) { - if (ancestor == superlayer) - return layer; - } - return 0; -} - -void WKCACFLayer::setBounds(const CGRect& rect) -{ - if (CGRectEqualToRect(rect, bounds())) - return; - - CACFLayerSetBounds(layer(), rect); - setNeedsCommit(); - - if (m_needsDisplayOnBoundsChange) - setNeedsDisplay(); - - if (m_layoutClient) - setNeedsLayout(); -} - -void WKCACFLayer::setFrame(const CGRect& rect) -{ - CGRect oldFrame = frame(); - if (CGRectEqualToRect(rect, oldFrame)) - return; - - CACFLayerSetFrame(layer(), rect); - setNeedsCommit(); - - if (m_needsDisplayOnBoundsChange && !CGSizeEqualToSize(rect.size, oldFrame.size)) - setNeedsDisplay(); - - if (m_layoutClient) - setNeedsLayout(); -} - -void WKCACFLayer::setContentsGravity(ContentsGravityType type) -{ - CACFLayerSetContentsGravity(layer(), toCACFContentsGravityType(type)); - setNeedsCommit(); -} - -WKCACFLayer::ContentsGravityType WKCACFLayer::contentsGravity() const -{ - return fromCACFContentsGravityType(CACFLayerGetContentsGravity(layer())); -} - -void WKCACFLayer::setMagnificationFilter(FilterType type) -{ - CACFLayerSetMagnificationFilter(layer(), toCACFFilterType(type)); - setNeedsCommit(); -} - -WKCACFLayer::FilterType WKCACFLayer::magnificationFilter() const -{ - return fromCACFFilterType(CACFLayerGetMagnificationFilter(layer())); -} - -void WKCACFLayer::setMinificationFilter(FilterType type) -{ - CACFLayerSetMinificationFilter(layer(), toCACFFilterType(type)); - setNeedsCommit(); -} - -WKCACFLayer::FilterType WKCACFLayer::minificationFilter() const -{ - return fromCACFFilterType(CACFLayerGetMinificationFilter(layer())); -} - -WKCACFLayer* WKCACFLayer::rootLayer() const -{ - WKCACFLayer* layer = const_cast<WKCACFLayer*>(this); - for (WKCACFLayer* superlayer = layer->superlayer(); superlayer; layer = superlayer, superlayer = superlayer->superlayer()) { } - return layer; -} - -void WKCACFLayer::internalRemoveAllSublayers() -{ - CACFLayerSetSublayers(layer(), 0); - setNeedsCommit(); -} - -void WKCACFLayer::internalSetSublayers(const Vector<RefPtr<WKCACFLayer> >& sublayers) -{ - // Remove all the current sublayers and add the passed layers - CACFLayerSetSublayers(layer(), 0); - - // Perform removeFromSuperLayer in a separate pass. CACF requires superlayer to - // be null or CACFLayerInsertSublayer silently fails. - for (size_t i = 0; i < sublayers.size(); i++) - CACFLayerRemoveFromSuperlayer(sublayers[i]->layer()); - - for (size_t i = 0; i < sublayers.size(); i++) - CACFLayerInsertSublayer(layer(), sublayers[i]->layer(), i); - - setNeedsCommit(); -} - -WKCACFLayer* WKCACFLayer::superlayer() const -{ - CACFLayerRef super = CACFLayerGetSuperlayer(layer()); - if (!super) - return 0; - return WKCACFLayer::layer(super); -} - -void WKCACFLayer::internalSetNeedsDisplay(const CGRect* dirtyRect) -{ - CACFLayerSetNeedsDisplay(layer(), dirtyRect); -} - -void WKCACFLayer::setLayoutClient(WKCACFLayerLayoutClient* layoutClient) -{ - if (layoutClient == m_layoutClient) - return; - - m_layoutClient = layoutClient; - CACFLayerSetLayoutCallback(layer(), m_layoutClient ? layoutSublayersProc : 0); -} - -void WKCACFLayer::layoutSublayersProc(CACFLayerRef caLayer) -{ - WKCACFLayer* layer = WKCACFLayer::layer(caLayer); - if (layer && layer->m_layoutClient) - layer->m_layoutClient->layoutSublayersOfLayer(layer); -} - -#ifndef NDEBUG -static void printIndent(int indent) -{ - for ( ; indent > 0; --indent) - fprintf(stderr, " "); -} - -static void printTransform(const CATransform3D& transform) -{ - fprintf(stderr, "[%g %g %g %g; %g %g %g %g; %g %g %g %g; %g %g %g %g]", - transform.m11, transform.m12, transform.m13, transform.m14, - transform.m21, transform.m22, transform.m23, transform.m24, - transform.m31, transform.m32, transform.m33, transform.m34, - transform.m41, transform.m42, transform.m43, transform.m44); -} - -void WKCACFLayer::printTree() const -{ - // Print heading info - CGRect rootBounds = bounds(); - fprintf(stderr, "\n\n** Render tree at time %g (bounds %g, %g %gx%g) **\n\n", - currentTime(), rootBounds.origin.x, rootBounds.origin.y, rootBounds.size.width, rootBounds.size.height); - - // Print layer tree from the root - printLayer(0); -} - -void WKCACFLayer::printLayer(int indent) const -{ - CGPoint layerPosition = position(); - CGPoint layerAnchorPoint = anchorPoint(); - CGRect layerBounds = bounds(); - printIndent(indent); - fprintf(stderr, "(%s [%g %g %g] [%g %g %g %g] [%g %g %g] superlayer=%p\n", - isTransformLayer() ? "transform-layer" : "layer", - layerPosition.x, layerPosition.y, zPosition(), - layerBounds.origin.x, layerBounds.origin.y, layerBounds.size.width, layerBounds.size.height, - layerAnchorPoint.x, layerAnchorPoint.y, anchorPointZ(), superlayer()); - - // Print name if needed - String layerName = name(); - if (!layerName.isEmpty()) { - printIndent(indent + 1); - fprintf(stderr, "(name %s)\n", layerName.utf8().data()); - } - - // Print masksToBounds if needed - bool layerMasksToBounds = masksToBounds(); - if (layerMasksToBounds) { - printIndent(indent + 1); - fprintf(stderr, "(masksToBounds true)\n"); - } - - // Print opacity if needed - float layerOpacity = opacity(); - if (layerOpacity != 1) { - printIndent(indent + 1); - fprintf(stderr, "(opacity %hf)\n", layerOpacity); - } - - // Print sublayerTransform if needed - CATransform3D layerTransform = sublayerTransform(); - if (!CATransform3DIsIdentity(layerTransform)) { - printIndent(indent + 1); - fprintf(stderr, "(sublayerTransform "); - printTransform(layerTransform); - fprintf(stderr, ")\n"); - } - - // Print transform if needed - layerTransform = transform(); - if (!CATransform3DIsIdentity(layerTransform)) { - printIndent(indent + 1); - fprintf(stderr, "(transform "); - printTransform(layerTransform); - fprintf(stderr, ")\n"); - } - - // Print contents if needed - CFTypeRef layerContents = contents(); - if (layerContents) { - if (CFGetTypeID(layerContents) == CGImageGetTypeID()) { - CGImageRef imageContents = static_cast<CGImageRef>(const_cast<void*>(layerContents)); - printIndent(indent + 1); - fprintf(stderr, "(contents (image [%d %d]))\n", - CGImageGetWidth(imageContents), CGImageGetHeight(imageContents)); - } - } - - // Print sublayers if needed - int n = sublayerCount(); - if (n > 0) { - printIndent(indent + 1); - fprintf(stderr, "(sublayers\n"); - for (int i = 0; i < n; ++i) - internalSublayerAtIndex(i)->printLayer(indent + 2); - - printIndent(indent + 1); - fprintf(stderr, ")\n"); - } - - printIndent(indent); - fprintf(stderr, ")\n"); -} -#endif // #ifndef NDEBUG -} - -#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayer.h b/Source/WebCore/platform/graphics/win/WKCACFLayer.h deleted file mode 100644 index 4c6639a..0000000 --- a/Source/WebCore/platform/graphics/win/WKCACFLayer.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2009 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. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WKCACFLayer_h -#define WKCACFLayer_h - -#if USE(ACCELERATED_COMPOSITING) - -#include <wtf/RefCounted.h> - -#include <QuartzCore/CACFLayer.h> -#include <QuartzCore/CACFVector.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RetainPtr.h> -#include <wtf/Vector.h> -#include <wtf/text/StringHash.h> - -#include "GraphicsContext.h" -#include "PlatformString.h" -#include "TransformationMatrix.h" - -struct WKCACFContext; - -namespace WebCore { - -class WKCACFLayer; - -class WKCACFLayerLayoutClient { -public: - virtual void layoutSublayersOfLayer(WKCACFLayer*) = 0; -protected: - virtual ~WKCACFLayerLayoutClient() {} -}; - -class WKCACFLayer : public RefCounted<WKCACFLayer> { -public: - enum LayerType { Layer, TransformLayer }; - enum FilterType { Linear, Nearest, Trilinear }; - enum ContentsGravityType { Center, Top, Bottom, Left, Right, TopLeft, TopRight, - BottomLeft, BottomRight, Resize, ResizeAspect, ResizeAspectFill }; - - static PassRefPtr<WKCACFLayer> create(LayerType); - static WKCACFLayer* layer(CACFLayerRef layer) - { - ASSERT(CACFLayerGetUserData(layer) != reinterpret_cast<void*>(0xDEADBEEF)); - return static_cast<WKCACFLayer*>(CACFLayerGetUserData(layer)); - } - - virtual ~WKCACFLayer(); - - virtual void setNeedsRender() { } - - virtual void drawInContext(PlatformGraphicsContext*) { } - - void setLayoutClient(WKCACFLayerLayoutClient*); - WKCACFLayerLayoutClient* layoutClient() const { return m_layoutClient; } - void setNeedsLayout() { CACFLayerSetNeedsLayout(layer()); } - - void setNeedsDisplay(const CGRect* dirtyRect = 0) - { - internalSetNeedsDisplay(dirtyRect); - setNeedsCommit(); - } - - // Makes this layer the root when the passed context is rendered - void becomeRootLayerForContext(WKCACFContext*); - - static RetainPtr<CFTypeRef> cfValue(float value) { return RetainPtr<CFTypeRef>(AdoptCF, CFNumberCreate(0, kCFNumberFloat32Type, &value)); } - static RetainPtr<CFTypeRef> cfValue(const TransformationMatrix& value) - { - CATransform3D t; - t.m11 = value.m11(); - t.m12 = value.m12(); - t.m13 = value.m13(); - t.m14 = value.m14(); - t.m21 = value.m21(); - t.m22 = value.m22(); - t.m23 = value.m23(); - t.m24 = value.m24(); - t.m31 = value.m31(); - t.m32 = value.m32(); - t.m33 = value.m33(); - t.m34 = value.m34(); - t.m41 = value.m41(); - t.m42 = value.m42(); - t.m43 = value.m43(); - t.m44 = value.m44(); - return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreateTransform(t)); - } - static RetainPtr<CFTypeRef> cfValue(const FloatPoint& value) - { - CGPoint p; - p.x = value.x(); p.y = value.y(); - return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreatePoint(p)); - } - static RetainPtr<CFTypeRef> cfValue(const FloatRect& rect) - { - CGRect r; - r.origin.x = rect.x(); - r.origin.y = rect.y(); - r.size.width = rect.width(); - r.size.height = rect.height(); - CGFloat v[4] = { CGRectGetMinX(r), CGRectGetMinY(r), CGRectGetMaxX(r), CGRectGetMaxY(r) }; - return RetainPtr<CFTypeRef>(AdoptCF, CACFVectorCreate(4, v)); - } - static RetainPtr<CFTypeRef> cfValue(const Color& color) - { - return RetainPtr<CFTypeRef>(AdoptCF, CGColorCreateGenericRGB(color.red(), color.green(), color.blue(), color.alpha())); - } - - bool isTransformLayer() const; - - void addSublayer(PassRefPtr<WKCACFLayer> sublayer); - void insertSublayerAboveLayer(PassRefPtr<WKCACFLayer>, const WKCACFLayer* reference); - void insertSublayerBelowLayer(PassRefPtr<WKCACFLayer>, const WKCACFLayer* reference); - void replaceSublayer(WKCACFLayer* reference, PassRefPtr<WKCACFLayer>); - void adoptSublayers(WKCACFLayer* source); - - void removeAllSublayers() { internalRemoveAllSublayers(); } - void setSublayers(const Vector<RefPtr<WKCACFLayer> >& sublayers) - { - internalSetSublayers(sublayers); - checkLayerConsistency(); - } - - void insertSublayer(PassRefPtr<WKCACFLayer> layer, size_t index) { internalInsertSublayer(layer, index); } - - size_t sublayerCount() const { return internalSublayerCount(); } - - void removeFromSuperlayer(); - - WKCACFLayer* ancestorOrSelfWithSuperlayer(WKCACFLayer*) const; - - void setAnchorPoint(const CGPoint& p) { CACFLayerSetAnchorPoint(layer(), p); setNeedsCommit(); } - CGPoint anchorPoint() const { return CACFLayerGetAnchorPoint(layer()); } - - void setAnchorPointZ(CGFloat z) { CACFLayerSetAnchorPointZ(layer(), z); setNeedsCommit(); } - CGFloat anchorPointZ() const { return CACFLayerGetAnchorPointZ(layer()); } - - void setBackgroundColor(CGColorRef color) { CACFLayerSetBackgroundColor(layer(), color); setNeedsCommit(); } - CGColorRef backgroundColor() const { return CACFLayerGetBackgroundColor(layer()); } - - void setBorderColor(CGColorRef color) { CACFLayerSetBorderColor(layer(), color); setNeedsCommit(); } - CGColorRef borderColor() const { return CACFLayerGetBorderColor(layer()); } - - void setBorderWidth(CGFloat width) { CACFLayerSetBorderWidth(layer(), width); setNeedsCommit(); } - CGFloat borderWidth() const { return CACFLayerGetBorderWidth(layer()); } - - virtual void setBounds(const CGRect&); - CGRect bounds() const { return CACFLayerGetBounds(layer()); } - - void setContents(CFTypeRef contents) { CACFLayerSetContents(layer(), contents); setNeedsCommit(); } - CFTypeRef contents() const { return CACFLayerGetContents(layer()); } - - void setContentsRect(const CGRect& contentsRect) { CACFLayerSetContentsRect(layer(), contentsRect); setNeedsCommit(); } - CGRect contentsRect() const { return CACFLayerGetContentsRect(layer()); } - - void setContentsGravity(ContentsGravityType); - ContentsGravityType contentsGravity() const; - - void setDoubleSided(bool b) { CACFLayerSetDoubleSided(layer(), b); setNeedsCommit(); } - bool doubleSided() const { return CACFLayerIsDoubleSided(layer()); } - - void setEdgeAntialiasingMask(uint32_t mask) { CACFLayerSetEdgeAntialiasingMask(layer(), mask); setNeedsCommit(); } - uint32_t edgeAntialiasingMask() const { return CACFLayerGetEdgeAntialiasingMask(layer()); } - - virtual void setFrame(const CGRect&); - CGRect frame() const { return CACFLayerGetFrame(layer()); } - - void setHidden(bool hidden) { CACFLayerSetHidden(layer(), hidden); setNeedsCommit(); } - bool isHidden() const { return CACFLayerIsHidden(layer()); } - - void setMasksToBounds(bool b) { CACFLayerSetMasksToBounds(layer(), b); } - bool masksToBounds() const { return CACFLayerGetMasksToBounds(layer()); } - - void setMagnificationFilter(FilterType); - FilterType magnificationFilter() const; - - void setMinificationFilter(FilterType); - FilterType minificationFilter() const; - - void setMinificationFilterBias(float bias) { CACFLayerSetMinificationFilterBias(layer(), bias); } - float minificationFilterBias() const { return CACFLayerGetMinificationFilterBias(layer()); } - - void setName(const String& name) { CACFLayerSetName(layer(), RetainPtr<CFStringRef>(AdoptCF, name.createCFString()).get()); } - String name() const { return CACFLayerGetName(layer()); } - - void setNeedsDisplayOnBoundsChange(bool needsDisplay) { m_needsDisplayOnBoundsChange = needsDisplay; } - - void setOpacity(float opacity) { CACFLayerSetOpacity(layer(), opacity); setNeedsCommit(); } - float opacity() const { return CACFLayerGetOpacity(layer()); } - - void setOpaque(bool b) { CACFLayerSetOpaque(layer(), b); setNeedsCommit(); } - bool opaque() const { return CACFLayerIsOpaque(layer()); } - - void setPosition(const CGPoint& position) { CACFLayerSetPosition(layer(), position); setNeedsCommit(); } - CGPoint position() const { return CACFLayerGetPosition(layer()); } - - void setZPosition(CGFloat position) { CACFLayerSetZPosition(layer(), position); setNeedsCommit(); } - CGFloat zPosition() const { return CACFLayerGetZPosition(layer()); } - - void setSpeed(float speed) { CACFLayerSetSpeed(layer(), speed); } - CFTimeInterval speed() const { return CACFLayerGetSpeed(layer()); } - - void setTimeOffset(CFTimeInterval t) { CACFLayerSetTimeOffset(layer(), t); } - CFTimeInterval timeOffset() const { return CACFLayerGetTimeOffset(layer()); } - - WKCACFLayer* rootLayer() const; - - void setSublayerTransform(const CATransform3D& transform) { CACFLayerSetSublayerTransform(layer(), transform); setNeedsCommit(); } - CATransform3D sublayerTransform() const { return CACFLayerGetSublayerTransform(layer()); } - - WKCACFLayer* superlayer() const; - - void setTransform(const CATransform3D& transform) { CACFLayerSetTransform(layer(), transform); setNeedsCommit(); } - CATransform3D transform() const { return CACFLayerGetTransform(layer()); } - - void setGeometryFlipped(bool flipped) { CACFLayerSetGeometryFlipped(layer(), flipped); setNeedsCommit(); } - bool geometryFlipped() const { return CACFLayerIsGeometryFlipped(layer()); } - -#ifndef NDEBUG - // Print the tree from the root. Also does consistency checks - void printTree() const; -#endif - -protected: - WKCACFLayer(LayerType); - - void setNeedsCommit(); - - CACFLayerRef layer() const { return m_layer.get(); } - // This should only be called from removeFromSuperlayer. - void removeSublayer(const WKCACFLayer*); - - void checkLayerConsistency() - { -#ifndef NDEBUG - internalCheckLayerConsistency(); -#endif - } - - // Methods to be overridden for sublayer and rendering management - virtual WKCACFLayer* internalSublayerAtIndex(int) const; - - // Returns the index of the passed layer in this layer's sublayers list - // or -1 if not found - virtual int internalIndexOfSublayer(const WKCACFLayer*); - - virtual size_t internalSublayerCount() const; - virtual void internalInsertSublayer(PassRefPtr<WKCACFLayer>, size_t index); - virtual void internalRemoveAllSublayers(); - virtual void internalSetSublayers(const Vector<RefPtr<WKCACFLayer> >&); - - virtual void internalSetNeedsDisplay(const CGRect* dirtyRect); - -#ifndef NDEBUG - virtual void internalCheckLayerConsistency(); -#endif - -#ifndef NDEBUG - // Print this layer and its children to the console - void printLayer(int indent) const; -#endif - -private: - static void layoutSublayersProc(CACFLayerRef); - - RetainPtr<CACFLayerRef> m_layer; - WKCACFLayerLayoutClient* m_layoutClient; - bool m_needsDisplayOnBoundsChange; -}; - -} - -#endif // USE(ACCELERATED_COMPOSITING) - -#endif // WKCACFLayer_h diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp index 4c5e61d..7c83f86 100644 --- a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp +++ b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.cpp @@ -187,7 +187,6 @@ WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) , m_context(wkCACFContextCreate()) , m_hostWindow(0) , m_renderTimer(this, &WKCACFLayerRenderer::renderTimerFired) - , m_backingStoreDirty(false) , m_mustResetLostDeviceBeforeRendering(false) , m_syncLayerChanges(false) { @@ -224,32 +223,33 @@ WKCACFLayerRenderer::WKCACFLayerRenderer(WKCACFLayerRendererClient* client) WKCACFLayerRenderer::~WKCACFLayerRenderer() { - destroyRenderer(); + setHostWindow(0); + WKCACFContextFlusher::shared().removeContext(m_context); wkCACFContextDestroy(m_context); } -PlatformCALayer* WKCACFLayerRenderer::rootLayer() const +void WKCACFLayerRenderer::setHostWindow(HWND window) { - return m_rootLayer.get(); -} + if (window == m_hostWindow) + return; -void WKCACFLayerRenderer::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer) -{ - m_pendingAnimatedLayers.add(layer); + if (m_hostWindow) + destroyRenderer(); + + m_hostWindow = window; + + if (m_hostWindow) + createRenderer(); } -void WKCACFLayerRenderer::setRootContents(CGImageRef image) +PlatformCALayer* WKCACFLayerRenderer::rootLayer() const { - ASSERT(m_rootLayer); - m_rootLayer->setContents(image); - renderSoon(); + return m_rootLayer.get(); } -void WKCACFLayerRenderer::setRootContentsAndDisplay(CGImageRef image) +void WKCACFLayerRenderer::addPendingAnimatedLayer(PassRefPtr<PlatformCALayer> layer) { - ASSERT(m_rootLayer); - m_rootLayer->setContents(image); - paint(); + m_pendingAnimatedLayers.add(layer); } void WKCACFLayerRenderer::setRootChildLayer(PlatformCALayer* layer) @@ -266,16 +266,6 @@ void WKCACFLayerRenderer::layerTreeDidChange() renderSoon(); } -void WKCACFLayerRenderer::setNeedsDisplay(bool sync) -{ - if (!m_syncLayerChanges && sync) - m_syncLayerChanges = true; - - ASSERT(m_rootLayer); - m_rootLayer->setNeedsDisplay(0); - renderSoon(); -} - bool WKCACFLayerRenderer::createRenderer() { if (m_d3dDevice || !m_mightBeAbleToCreateDeviceLater) @@ -340,7 +330,7 @@ bool WKCACFLayerRenderer::createRenderer() initD3DGeometry(); - wkCACFContextInitializeD3DDevice(m_context, m_d3dDevice.get()); + wkCACFContextSetD3DDevice(m_context, m_d3dDevice.get()); if (IsWindow(m_hostWindow)) m_rootLayer->setBounds(bounds()); @@ -352,6 +342,7 @@ void WKCACFLayerRenderer::destroyRenderer() { wkCACFContextSetLayer(m_context, m_rootLayer->platformLayer()); + wkCACFContextSetD3DDevice(m_context, 0); m_d3dDevice = 0; if (s_d3d) s_d3d->Release(); @@ -422,15 +413,6 @@ void WKCACFLayerRenderer::paint() return; } - if (m_backingStoreDirty) { - // If the backing store is still dirty when we are about to draw the - // composited content, we need to force the window to paint into the - // backing store. The paint will only paint the dirty region that - // if being tracked in WebView. - UpdateWindow(m_hostWindow); - return; - } - Vector<CGRect> dirtyRects; getDirtyRects(m_hostWindow, dirtyRects); render(dirtyRects); @@ -545,6 +527,12 @@ void WKCACFLayerRenderer::renderSoon() m_renderTimer.startOneShot(0); } +void WKCACFLayerRenderer::syncCompositingStateSoon() +{ + m_syncLayerChanges = true; + renderSoon(); +} + CGRect WKCACFLayerRenderer::bounds() const { RECT clientRect; diff --git a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h index aff1f83..02cdbdb 100644 --- a/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h +++ b/Source/WebCore/platform/graphics/win/WKCACFLayerRenderer.h @@ -54,7 +54,6 @@ class WKCACFLayerRendererClient { public: virtual ~WKCACFLayerRendererClient() { } virtual bool shouldRender() const = 0; - virtual void animationsStarted(CFTimeInterval) { } virtual void syncCompositingState() { } }; @@ -70,17 +69,12 @@ public: static bool acceleratedCompositingAvailable(); - void setRootContents(CGImageRef); - void setRootContentsAndDisplay(CGImageRef); void setRootChildLayer(PlatformCALayer*); void layerTreeDidChange(); - void setNeedsDisplay(bool sync = false); - void setHostWindow(HWND window) { m_hostWindow = window; } - void setBackingStoreDirty(bool dirty) { m_backingStoreDirty = dirty; } - bool createRenderer(); - void destroyRenderer(); + void setHostWindow(HWND); + void paint(); void resize(); - void renderSoon(); + void syncCompositingStateSoon(); protected: PlatformCALayer* rootLayer() const; @@ -89,6 +83,9 @@ protected: private: WKCACFLayerRenderer(WKCACFLayerRendererClient*); + bool createRenderer(); + void destroyRenderer(); + void renderSoon(); void renderTimerFired(Timer<WKCACFLayerRenderer>*); CGRect bounds() const; @@ -102,7 +99,6 @@ private: bool resetDevice(ResetReason); void render(const Vector<CGRect>& dirtyRects = Vector<CGRect>()); - void paint(); WKCACFLayerRendererClient* m_client; bool m_mightBeAbleToCreateDeviceLater; @@ -112,7 +108,6 @@ private: WKCACFContext* m_context; HWND m_hostWindow; Timer<WKCACFLayerRenderer> m_renderTimer; - bool m_backingStoreDirty; bool m_mustResetLostDeviceBeforeRendering; bool m_syncLayerChanges; HashSet<RefPtr<PlatformCALayer> > m_pendingAnimatedLayers; diff --git a/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp b/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp index c0b2b53..cfcc487 100644 --- a/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/ImageWinCE.cpp @@ -41,7 +41,7 @@ namespace WebCore { -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { return SharedBitmap::create(m_backingStore, m_size, hasAlpha()); } diff --git a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index cee6aee..f1c09c5 100644 --- a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -31,7 +31,6 @@ #include "Font.h" #include "IntRect.h" #include "NotImplemented.h" -#include "Pen.h" #include <wtf/MathExtras.h> #include <math.h> diff --git a/Source/WebCore/platform/graphics/wx/PenWx.cpp b/Source/WebCore/platform/graphics/wx/PenWx.cpp deleted file mode 100644 index 5a131e3..0000000 --- a/Source/WebCore/platform/graphics/wx/PenWx.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Pen.h" - -#include <wx/defs.h> -#include <wx/pen.h> -#include <wx/colour.h> - -namespace WebCore { - -// Pen style conversion functions -static int penStyleToWxPenStyle(int p) -{ - if (p == Pen::SolidLine) - return wxSOLID; - if (p == Pen::DotLine) - return wxDOT; - if (p == Pen::DashLine) - return wxLONG_DASH; - if (p == Pen::NoPen) - return wxTRANSPARENT; - - return wxSOLID; -} - -static Pen::PenStyle wxPenStyleToPenStyle(int p) -{ - if (p == wxSOLID) - return Pen::SolidLine; - if (p == wxDOT) - return Pen::DotLine; - if (p == wxLONG_DASH || p == wxSHORT_DASH || p == wxDOT_DASH || p == wxUSER_DASH) - return Pen::DashLine; - if (p == wxTRANSPARENT) - return Pen::NoPen; - - return Pen::SolidLine; -} - -Pen::Pen(const wxPen& p) -{ - wxColour color = p.GetColour(); - setColor(Color(color.Red(), color.Green(), color.Blue())); - setWidth(p.GetWidth()); - setStyle(wxPenStyleToPenStyle(p.GetStyle())); -} - -Pen::operator wxPen() const -{ - return wxPen(wxColour(m_color.red(), m_color.blue(), m_color.green()), width(), penStyleToWxPenStyle(style())); -} - -} diff --git a/Source/WebCore/platform/gtk/ContextMenuGtk.cpp b/Source/WebCore/platform/gtk/ContextMenuGtk.cpp index 423959a..b34631d 100644 --- a/Source/WebCore/platform/gtk/ContextMenuGtk.cpp +++ b/Source/WebCore/platform/gtk/ContextMenuGtk.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2007 Holger Hans Peter Freyther + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +20,7 @@ #include "config.h" #include "ContextMenu.h" +#include "NotImplemented.h" #include <gtk/gtk.h> namespace WebCore { @@ -26,14 +28,12 @@ namespace WebCore { ContextMenu::ContextMenu() { m_platformDescription = GTK_MENU(gtk_menu_new()); - - g_object_ref_sink(G_OBJECT(m_platformDescription)); } ContextMenu::~ContextMenu() { if (m_platformDescription) - g_object_unref(m_platformDescription); + gtk_widget_destroy(GTK_WIDGET(m_platformDescription)); } void ContextMenu::appendItem(ContextMenuItem& item) @@ -50,10 +50,9 @@ void ContextMenu::setPlatformDescription(PlatformMenuDescription menu) { ASSERT(menu); if (m_platformDescription) - g_object_unref(m_platformDescription); + gtk_widget_destroy(GTK_WIDGET(m_platformDescription)); m_platformDescription = menu; - g_object_ref(m_platformDescription); } PlatformMenuDescription ContextMenu::platformDescription() const @@ -69,4 +68,12 @@ PlatformMenuDescription ContextMenu::releasePlatformDescription() return description; } +Vector<ContextMenuItem> contextMenuItemVector(const PlatformMenuDescription) +{ + notImplemented(); + + Vector<ContextMenuItem> menuItemVector; + return menuItemVector; +} + } diff --git a/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp b/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp index 4d79f13..fee7a14 100644 --- a/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp +++ b/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2007 Holger Hans Peter Freyther * Copyright (C) 2010 Igalia S.L + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -144,28 +145,42 @@ ContextMenuItem::ContextMenuItem(ContextMenuItemType type, ContextMenuAction act m_platformDescription = GTK_MENU_ITEM(gtk_action_create_menu_item(platformAction)); g_object_unref(platformAction); - g_object_set_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action)); + g_object_set_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action)); if (subMenu) setSubMenu(subMenu); } +ContextMenuItem::ContextMenuItem(ContextMenuItemType, ContextMenuAction, const String&, bool, bool) +{ + // FIXME: Implement with WebKit2 ContextMenu changes. + notImplemented(); +} + +ContextMenuItem::ContextMenuItem(ContextMenuAction, const String&, bool, bool, Vector<ContextMenuItem>&) +{ + // FIXME: Implement with WebKit2 ContextMenu changes. + notImplemented(); +} + ContextMenuItem::~ContextMenuItem() { } PlatformMenuItemDescription ContextMenuItem::releasePlatformDescription() { - return m_platformDescription.leakRef(); + PlatformMenuItemDescription platformDescription = m_platformDescription; + m_platformDescription = 0; + return platformDescription; } ContextMenuItemType ContextMenuItem::type() const { - if (GTK_IS_SEPARATOR_MENU_ITEM(m_platformDescription.get())) + if (GTK_IS_SEPARATOR_MENU_ITEM(m_platformDescription)) return SeparatorType; - if (GTK_IS_CHECK_MENU_ITEM(m_platformDescription.get())) + if (GTK_IS_CHECK_MENU_ITEM(m_platformDescription)) return CheckableActionType; - if (gtk_menu_item_get_submenu(m_platformDescription.get())) + if (gtk_menu_item_get_submenu(m_platformDescription)) return SubmenuType; return ActionType; } @@ -178,48 +193,62 @@ void ContextMenuItem::setType(ContextMenuItemType type) ContextMenuAction ContextMenuItem::action() const { - return static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION))); + return static_cast<ContextMenuAction>(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION))); } void ContextMenuItem::setAction(ContextMenuAction action) { - g_object_set_data(G_OBJECT(m_platformDescription.get()), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action)); + g_object_set_data(G_OBJECT(m_platformDescription), WEBKIT_CONTEXT_MENU_ACTION, GINT_TO_POINTER(action)); } String ContextMenuItem::title() const { - GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription)); return action ? String(gtk_action_get_label(action)) : String(); } void ContextMenuItem::setTitle(const String& title) { - GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription)); if (action) gtk_action_set_label(action, title.utf8().data()); } PlatformMenuDescription ContextMenuItem::platformSubMenu() const { - GtkWidget* subMenu = gtk_menu_item_get_submenu(m_platformDescription.get()); + GtkWidget* subMenu = gtk_menu_item_get_submenu(m_platformDescription); return subMenu ? GTK_MENU(subMenu) : 0; } void ContextMenuItem::setSubMenu(ContextMenu* menu) { - gtk_menu_item_set_submenu(m_platformDescription.get(), GTK_WIDGET(menu->platformDescription())); + gtk_menu_item_set_submenu(m_platformDescription, GTK_WIDGET(menu->platformDescription())); } void ContextMenuItem::setChecked(bool shouldCheck) { - GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription)); if (action && GTK_IS_TOGGLE_ACTION(action)) gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), shouldCheck); } +bool ContextMenuItem::checked() const +{ + // FIXME: Implement with WebKit2 ContextMenu changes. + notImplemented(); + return false; +} + +bool ContextMenuItem::enabled() const +{ + // FIXME: Implement with WebKit2 ContextMenu changes. + notImplemented(); + return false; +} + void ContextMenuItem::setEnabled(bool shouldEnable) { - GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription.get())); + GtkAction* action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(m_platformDescription)); if (action) gtk_action_set_sensitive(action, shouldEnable); } diff --git a/Source/WebCore/platform/gtk/DragDataGtk.cpp b/Source/WebCore/platform/gtk/DragDataGtk.cpp index 42ddb16..3a1daf1 100644 --- a/Source/WebCore/platform/gtk/DragDataGtk.cpp +++ b/Source/WebCore/platform/gtk/DragDataGtk.cpp @@ -21,6 +21,7 @@ #include "ClipboardGtk.h" #include "Document.h" #include "DocumentFragment.h" +#include "Frame.h" #include "markup.h" namespace WebCore { @@ -50,7 +51,7 @@ bool DragData::containsPlainText() const return m_platformDragData->hasText(); } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { return m_platformDragData->text(); } @@ -62,15 +63,15 @@ Color DragData::asColor() const bool DragData::containsCompatibleContent() const { - return containsPlainText() || containsURL() || m_platformDragData->hasMarkup() || containsColor() || containsFiles(); + return containsPlainText() || containsURL(0) || m_platformDragData->hasMarkup() || containsColor() || containsFiles(); } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { return m_platformDragData->hasURL(); } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { String url(m_platformDragData->url()); if (title) @@ -79,12 +80,12 @@ String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) c } -PassRefPtr<DocumentFragment> DragData::asFragment(Document* document) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const { if (!m_platformDragData->hasMarkup()) return 0; - return createFragmentFromMarkup(document, m_platformDragData->markup(), ""); + return createFragmentFromMarkup(frame->document(), m_platformDragData->markup(), ""); } } diff --git a/Source/WebCore/platform/gtk/FileSystemGtk.cpp b/Source/WebCore/platform/gtk/FileSystemGtk.cpp index b8aa102..b3c4c9f 100644 --- a/Source/WebCore/platform/gtk/FileSystemGtk.cpp +++ b/Source/WebCore/platform/gtk/FileSystemGtk.cpp @@ -2,6 +2,7 @@ * Copyright (C) 2007, 2009 Holger Hans Peter Freyther * Copyright (C) 2008 Collabora, Ltd. * Copyright (C) 2008 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -45,10 +46,8 @@ String filenameToString(const char* filename) #if OS(WINDOWS) return String::fromUTF8(filename); #else - gchar* escapedString = g_uri_escape_string(filename, "/:", false); - String string(escapedString); - g_free(escapedString); - return string; + GOwnPtr<gchar> escapedString(g_uri_escape_string(filename, "/:", false)); + return escapedString.get(); #endif } @@ -57,10 +56,8 @@ CString fileSystemRepresentation(const String& path) #if OS(WINDOWS) return path.utf8(); #else - char* filename = g_uri_unescape_string(path.utf8().data(), 0); - CString cfilename(filename); - g_free(filename); - return cfilename; + GOwnPtr<gchar> filename(g_uri_unescape_string(path.utf8().data(), 0)); + return filename.get(); #endif } @@ -71,14 +68,11 @@ String filenameForDisplay(const String& string) return string; #else CString filename = fileSystemRepresentation(string); - gchar* display = g_filename_to_utf8(filename.data(), 0, 0, 0, 0); + GOwnPtr<gchar> display(g_filename_to_utf8(filename.data(), 0, 0, 0, 0)); if (!display) return string; - String displayString = String::fromUTF8(display); - g_free(display); - - return displayString; + return String::fromUTF8(display.get()); #endif } @@ -176,11 +170,31 @@ String pathGetFileName(const String& pathName) return pathName; CString tmpFilename = fileSystemRepresentation(pathName); - char* baseName = g_path_get_basename(tmpFilename.data()); - String fileName = String::fromUTF8(baseName); - g_free(baseName); + GOwnPtr<gchar> baseName(g_path_get_basename(tmpFilename.data())); + return String::fromUTF8(baseName.get()); +} + +CString applicationDirectoryPath() +{ +#if OS(LINUX) + // Handle the /proc filesystem case. + char pathFromProc[PATH_MAX] = {0}; + if (readlink("/proc/self/exe", pathFromProc, sizeof(pathFromProc) - 1) == -1) + return CString(); + + GOwnPtr<char> dirname(g_path_get_dirname(pathFromProc)); + return dirname.get(); +#elif OS(UNIX) + // If the above fails, check the PATH env variable. + GOwnPtr<char> currentExePath(g_find_program_in_path(g_get_prgname())); + if (!currentExePath.get()) + return CString(); - return fileName; + GOwnPtr<char> dirname(g_path_get_dirname(currentExePath.get())); + return dirname.get(); +#else + return CString(); +#endif } String directoryName(const String& path) diff --git a/Source/WebCore/platform/gtk/GRefPtrGtk.cpp b/Source/WebCore/platform/gtk/GRefPtrGtk.cpp index 6647b99..9a9d679 100644 --- a/Source/WebCore/platform/gtk/GRefPtrGtk.cpp +++ b/Source/WebCore/platform/gtk/GRefPtrGtk.cpp @@ -38,6 +38,7 @@ template <> void derefGPtr(GtkTargetList* ptr) gtk_target_list_unref(ptr); } +#ifdef GTK_API_VERSION_2 template <> GdkCursor* refGPtr(GdkCursor* ptr) { if (ptr) @@ -50,5 +51,6 @@ template <> void derefGPtr(GdkCursor* ptr) if (ptr) gdk_cursor_unref(ptr); } +#endif } diff --git a/Source/WebCore/platform/gtk/GRefPtrGtk.h b/Source/WebCore/platform/gtk/GRefPtrGtk.h index 1fb9772..a9f491f 100644 --- a/Source/WebCore/platform/gtk/GRefPtrGtk.h +++ b/Source/WebCore/platform/gtk/GRefPtrGtk.h @@ -28,8 +28,10 @@ namespace WTF { template <> GtkTargetList* refGPtr(GtkTargetList* ptr); template <> void derefGPtr(GtkTargetList* ptr); +#ifdef GTK_API_VERSION_2 template <> GdkCursor* refGPtr(GdkCursor* ptr); template <> void derefGPtr(GdkCursor* ptr); +#endif } diff --git a/Source/WebCore/platform/gtk/GtkVersioning.h b/Source/WebCore/platform/gtk/GtkVersioning.h index 11d1f8a..7e9fcd1 100644 --- a/Source/WebCore/platform/gtk/GtkVersioning.h +++ b/Source/WebCore/platform/gtk/GtkVersioning.h @@ -37,12 +37,14 @@ GdkPixbuf* gdk_pixbuf_get_from_surface(cairo_surface_t* surface, int srcX, int s int width, int height); #endif -#if !GTK_CHECK_VERSION(2, 24, 0) +#if !GTK_CHECK_VERSION(2, 23, 4) +#define gdk_pixmap_get_size gdk_drawable_get_size +#endif // GTK_CHECK_VERSION(2, 23, 4) + +#if !GTK_CHECK_VERSION(2, 23, 0) #define gdk_window_get_display(window) gdk_drawable_get_display(window) -#ifdef GDK_DISABLE_DEPRECATED #define gdk_window_get_visual gdk_drawable_get_visual -#endif -#endif // GTK_CHECK_VERSION(2, 24, 0) +#endif // GTK_CHECK_VERSION(2, 23, 0) #if !GTK_CHECK_VERSION(2, 21, 2) #define gdk_visual_get_depth(visual) (visual)->depth diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk.cpp b/Source/WebCore/platform/gtk/RenderThemeGtk.cpp index c194946..97c966d 100644 --- a/Source/WebCore/platform/gtk/RenderThemeGtk.cpp +++ b/Source/WebCore/platform/gtk/RenderThemeGtk.cpp @@ -33,6 +33,7 @@ #include "HTMLMediaElement.h" #include "HTMLNames.h" #include "MediaControlElements.h" +#include "PaintInfo.h" #include "RenderBox.h" #include "RenderObject.h" #include "TimeRanges.h" @@ -101,73 +102,22 @@ PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) return rt; } -static int mozGtkRefCount = 0; - RenderThemeGtk::RenderThemeGtk() - : m_gtkWindow(0) - , m_gtkContainer(0) - , m_gtkButton(0) - , m_gtkEntry(0) - , m_gtkTreeView(0) - , m_gtkVScale(0) - , m_gtkHScale(0) - , m_panelColor(Color::white) + : m_panelColor(Color::white) , m_sliderColor(Color::white) , m_sliderThumbColor(Color::white) , m_mediaIconSize(16) , m_mediaSliderHeight(14) , m_mediaSliderThumbWidth(12) , m_mediaSliderThumbHeight(12) -#ifdef GTK_API_VERSION_2 - , m_themePartsHaveRGBAColormap(true) -#endif { - - memset(&m_themeParts, 0, sizeof(GtkThemeParts)); -#ifdef GTK_API_VERSION_2 - GdkColormap* colormap = gdk_screen_get_rgba_colormap(gdk_screen_get_default()); - if (!colormap) { - m_themePartsHaveRGBAColormap = false; - colormap = gdk_screen_get_default_colormap(gdk_screen_get_default()); - } - m_themeParts.colormap = colormap; -#endif - - // Initialize the Mozilla theme drawing code. - if (!mozGtkRefCount) { - moz_gtk_init(); - moz_gtk_use_theme_parts(&m_themeParts); - } - ++mozGtkRefCount; - + platformInit(); #if ENABLE(VIDEO) initMediaColors(); initMediaButtons(); #endif } -RenderThemeGtk::~RenderThemeGtk() -{ - --mozGtkRefCount; - - if (!mozGtkRefCount) - moz_gtk_shutdown(); - - gtk_widget_destroy(m_gtkWindow); -} - -void RenderThemeGtk::getIndicatorMetrics(ControlPart part, int& indicatorSize, int& indicatorSpacing) const -{ - ASSERT(part == CheckboxPart || part == RadioPart); - if (part == CheckboxPart) { - moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing); - return; - } - - // RadioPart - moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing); -} - static bool supportsFocus(ControlPart appearance) { switch (appearance) { @@ -227,13 +177,13 @@ GtkTextDirection gtkTextDirection(TextDirection direction) } } -GtkStateType RenderThemeGtk::gtkIconState(RenderObject* renderObject) +static GtkStateType gtkIconState(RenderTheme* theme, RenderObject* renderObject) { - if (!isEnabled(renderObject)) + if (!theme->isEnabled(renderObject)) return GTK_STATE_INSENSITIVE; - if (isPressed(renderObject)) + if (theme->isPressed(renderObject)) return GTK_STATE_ACTIVE; - if (isHovered(renderObject)) + if (theme->isHovered(renderObject)) return GTK_STATE_PRELIGHT; return GTK_STATE_NORMAL; @@ -318,7 +268,7 @@ bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* renderObjec { GRefPtr<GdkPixbuf> icon = getStockIcon(GTK_TYPE_ENTRY, GTK_STOCK_FIND, gtkTextDirection(renderObject->style()->direction()), - gtkIconState(renderObject), GTK_ICON_SIZE_MENU); + gtkIconState(this, renderObject), GTK_ICON_SIZE_MENU); paintGdkPixbuf(paintInfo.context, icon.get(), centerRectVerticallyInParentInputElement(renderObject, rect)); return false; } @@ -338,7 +288,7 @@ bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* renderObject, co { GRefPtr<GdkPixbuf> icon = getStockIcon(GTK_TYPE_ENTRY, GTK_STOCK_CLEAR, gtkTextDirection(renderObject->style()->direction()), - gtkIconState(renderObject), GTK_ICON_SIZE_MENU); + gtkIconState(this, renderObject), GTK_ICON_SIZE_MENU); paintGdkPixbuf(paintInfo.context, icon.get(), centerRectVerticallyInParentInputElement(renderObject, rect)); return false; } @@ -438,19 +388,16 @@ String RenderThemeGtk::extraMediaControlsStyleSheet() void RenderThemeGtk::adjustMediaSliderThumbSize(RenderObject* renderObject) const { - ControlPart part = renderObject->style()->appearance(); - - if (part == MediaSliderThumbPart) { - renderObject->style()->setWidth(Length(m_mediaSliderThumbWidth, Fixed)); - renderObject->style()->setHeight(Length(m_mediaSliderThumbHeight, Fixed)); - } + ASSERT(renderObject->style()->appearance() == MediaSliderThumbPart); + renderObject->style()->setWidth(Length(m_mediaSliderThumbWidth, Fixed)); + renderObject->style()->setHeight(Length(m_mediaSliderThumbHeight, Fixed)); } bool RenderThemeGtk::paintMediaButton(RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, const char* iconName) { GRefPtr<GdkPixbuf> icon = getStockIcon(GTK_TYPE_CONTAINER, iconName, gtkTextDirection(renderObject->style()->direction()), - gtkIconState(renderObject), + gtkIconState(this, renderObject), getMediaButtonIconSize(m_mediaIconSize)); IntPoint iconPoint(rect.x() + (rect.width() - m_mediaIconSize) / 2, rect.y() + (rect.height() - m_mediaIconSize) / 2); @@ -560,6 +507,23 @@ bool RenderThemeGtk::paintMediaSliderThumb(RenderObject* o, const PaintInfo& pai return false; } +bool RenderThemeGtk::paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo& paintInfo, const IntRect& rect) +{ + GraphicsContext* context = paintInfo.context; + context->fillRect(FloatRect(rect), m_panelColor, ColorSpaceDeviceRGB); + return false; +} + +bool RenderThemeGtk::paintMediaVolumeSliderTrack(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +{ + return paintSliderTrack(renderObject, paintInfo, rect); +} + +bool RenderThemeGtk::paintMediaVolumeSliderThumb(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +{ + return paintSliderThumb(renderObject, paintInfo, rect); +} + String RenderThemeGtk::formatMediaControlsCurrentTime(float currentTime, float duration) const { return formatMediaControlsTime(currentTime) + " / " + formatMediaControlsTime(duration); @@ -575,20 +539,6 @@ bool RenderThemeGtk::paintMediaCurrentTime(RenderObject* renderObject, const Pai #endif #if ENABLE(PROGRESS_TAG) -double RenderThemeGtk::animationRepeatIntervalForProgressBar(RenderProgress*) const -{ - // FIXME: It doesn't look like there is a good way yet to support animated - // progress bars with the Mozilla theme drawing code. - return 0; -} - -double RenderThemeGtk::animationDurationForProgressBar(RenderProgress*) const -{ - // FIXME: It doesn't look like there is a good way yet to support animated - // progress bars with the Mozilla theme drawing code. - return 0; -} - void RenderThemeGtk::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { style->setBoxShadow(0); diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk.h b/Source/WebCore/platform/gtk/RenderThemeGtk.h index ef1df05..90113e5 100644 --- a/Source/WebCore/platform/gtk/RenderThemeGtk.h +++ b/Source/WebCore/platform/gtk/RenderThemeGtk.h @@ -29,9 +29,14 @@ #define RenderThemeGtk_h #include "GRefPtr.h" -#include "gtkdrawing.h" #include "RenderTheme.h" +#ifdef GTK_API_VERSION_2 +#include "gtkdrawing.h" +#endif + +typedef gulong GType; + namespace WebCore { class RenderThemeGtk : public RenderTheme { @@ -86,10 +91,9 @@ public: virtual String formatMediaControlsCurrentTime(float currentTime, float duration) const; #endif - void getIndicatorMetrics(ControlPart, int& indicatorSize, int& indicatorSpacing) const; - #ifdef GTK_API_VERSION_2 GtkWidget* gtkScrollbar(); + static void getIndicatorMetrics(ControlPart, int& indicatorSize, int& indicatorSpacing); #else GtkStyleContext* gtkScrollbarStyle(); #endif @@ -152,6 +156,9 @@ protected: virtual bool paintMediaSeekForwardButton(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderTrack(RenderObject*, const PaintInfo&, const IntRect&); + virtual bool paintMediaVolumeSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); virtual bool paintMediaCurrentTime(RenderObject*, const PaintInfo&, const IntRect&); #endif @@ -163,45 +170,41 @@ protected: #endif private: - GtkWidget* gtkButton() const; - GtkWidget* gtkEntry() const; - GtkWidget* gtkTreeView() const; - GtkWidget* gtkVScale() const; - GtkWidget* gtkHScale() const; - GtkWidget* gtkContainer() const; - - void setupWidgetAndAddToContainer(GtkWidget*, GtkWidget*) const; - GtkStateType getGtkStateType(RenderObject* object); - bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect& rect, int flags = 0); + void platformInit(); #if ENABLE(VIDEO) bool paintMediaButton(RenderObject*, GraphicsContext*, const IntRect&, const char* iconName); #endif - GtkStateType gtkIconState(RenderObject*); static void setTextInputBorders(RenderStyle*); GRefPtr<GdkPixbuf> getStockIcon(GType, const char* iconName, gint direction, gint state, gint iconSize); - mutable GtkWidget* m_gtkWindow; - mutable GtkWidget* m_gtkContainer; - mutable GtkWidget* m_gtkButton; - mutable GtkWidget* m_gtkEntry; - mutable GtkWidget* m_gtkTreeView; - mutable GtkWidget* m_gtkVScale; - mutable GtkWidget* m_gtkHScale; - mutable Color m_panelColor; mutable Color m_sliderColor; mutable Color m_sliderThumbColor; - const int m_mediaIconSize; const int m_mediaSliderHeight; const int m_mediaSliderThumbWidth; const int m_mediaSliderThumbHeight; - GtkThemeParts m_themeParts; #ifdef GTK_API_VERSION_2 + void setupWidgetAndAddToContainer(GtkWidget*, GtkWidget*) const; + bool paintRenderObject(GtkThemeWidgetType, RenderObject*, GraphicsContext*, const IntRect&, int flags = 0); + GtkThemeParts m_themeParts; + GtkWidget* gtkButton() const; + GtkWidget* gtkEntry() const; + GtkWidget* gtkTreeView() const; + GtkWidget* gtkVScale() const; + GtkWidget* gtkHScale() const; + GtkWidget* gtkContainer() const; + mutable GtkWidget* m_gtkWindow; + mutable GtkWidget* m_gtkContainer; + mutable GtkWidget* m_gtkButton; + mutable GtkWidget* m_gtkEntry; + mutable GtkWidget* m_gtkTreeView; + mutable GtkWidget* m_gtkVScale; + mutable GtkWidget* m_gtkHScale; bool m_themePartsHaveRGBAColormap; -#endif friend class WidgetRenderingContext; +#endif }; } diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp b/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp index fd391b7..e01508e 100644 --- a/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp +++ b/Source/WebCore/platform/gtk/RenderThemeGtk2.cpp @@ -32,6 +32,7 @@ #include "GtkVersioning.h" #include "HTMLNames.h" #include "MediaControlElements.h" +#include "PaintInfo.h" #include "RenderObject.h" #include "TextDirection.h" #include "UserAgentStyleSheets.h" @@ -49,6 +50,45 @@ namespace WebCore { // This is not a static method, because we want to avoid having GTK+ headers in RenderThemeGtk.h. extern GtkTextDirection gtkTextDirection(TextDirection); +static int mozGtkRefCount = 0; +void RenderThemeGtk::platformInit() +{ + m_themePartsHaveRGBAColormap = true; + m_gtkWindow = 0; + m_gtkContainer = 0; + m_gtkButton = 0; + m_gtkEntry = 0; + m_gtkTreeView = 0; + m_gtkVScale = 0; + m_gtkHScale = 0; + + memset(&m_themeParts, 0, sizeof(GtkThemeParts)); + GdkColormap* colormap = gdk_screen_get_rgba_colormap(gdk_screen_get_default()); + if (!colormap) { + m_themePartsHaveRGBAColormap = false; + colormap = gdk_screen_get_default_colormap(gdk_screen_get_default()); + } + m_themeParts.colormap = colormap; + + // Initialize the Mozilla theme drawing code. + if (!mozGtkRefCount) { + moz_gtk_init(); + moz_gtk_use_theme_parts(&m_themeParts); + } + ++mozGtkRefCount; +} + +RenderThemeGtk::~RenderThemeGtk() +{ + --mozGtkRefCount; + + if (!mozGtkRefCount) + moz_gtk_shutdown(); + + if (m_gtkWindow) + gtk_widget_destroy(m_gtkWindow); +} + #if ENABLE(VIDEO) void RenderThemeGtk::initMediaColors() { @@ -63,13 +103,13 @@ void RenderThemeGtk::adjustRepaintRect(const RenderObject*, IntRect&) { } -GtkStateType RenderThemeGtk::getGtkStateType(RenderObject* object) +static GtkStateType getGtkStateType(RenderThemeGtk* theme, RenderObject* object) { - if (!isEnabled(object) || isReadOnlyControl(object)) + if (!theme->isEnabled(object) || theme->isReadOnlyControl(object)) return GTK_STATE_INSENSITIVE; - if (isPressed(object)) + if (theme->isPressed(object)) return GTK_STATE_ACTIVE; - if (isHovered(object)) + if (theme->isHovered(object)) return GTK_STATE_PRELIGHT; return GTK_STATE_NORMAL; } @@ -102,6 +142,18 @@ bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* re gtkTextDirection(renderObject->style()->direction())); } +void RenderThemeGtk::getIndicatorMetrics(ControlPart part, int& indicatorSize, int& indicatorSpacing) +{ + ASSERT(part == CheckboxPart || part == RadioPart); + if (part == CheckboxPart) { + moz_gtk_checkbox_get_metrics(&indicatorSize, &indicatorSpacing); + return; + } + + // RadioPart + moz_gtk_radio_get_metrics(&indicatorSize, &indicatorSpacing); +} + static void setToggleSize(const RenderThemeGtk* theme, RenderStyle* style, ControlPart appearance) { // The width and height are both specified, so we shouldn't change them. @@ -110,7 +162,7 @@ static void setToggleSize(const RenderThemeGtk* theme, RenderStyle* style, Contr // FIXME: This is probably not correct use of indicatorSize and indicatorSpacing. gint indicatorSize, indicatorSpacing; - theme->getIndicatorMetrics(appearance, indicatorSize, indicatorSpacing); + RenderThemeGtk::getIndicatorMetrics(appearance, indicatorSize, indicatorSpacing); // Other ports hard-code this to 13, but GTK+ users tend to demand the native look. // It could be made a configuration option values other than 13 actually break site compatibility. @@ -151,7 +203,7 @@ bool RenderThemeGtk::paintButton(RenderObject* object, const PaintInfo& info, co IntRect buttonRect(IntPoint(), rect.size()); IntRect focusRect(buttonRect); - GtkStateType state = getGtkStateType(object); + GtkStateType state = getGtkStateType(this, object); gtk_widget_set_state(widget, state); gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); @@ -248,24 +300,24 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* object, const PaintInfo& inf return false; ControlPart part = object->style()->appearance(); - ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart); + ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart || part == MediaVolumeSliderPart); // We shrink the trough rect slightly to make room for the focus indicator. IntRect troughRect(IntPoint(), rect.size()); // This is relative to rect. GtkWidget* widget = 0; - if (part == SliderVerticalPart) { - widget = gtkVScale(); - troughRect.inflateY(-gtk_widget_get_style(widget)->ythickness); - } else { + if (part == SliderHorizontalPart) { widget = gtkHScale(); troughRect.inflateX(-gtk_widget_get_style(widget)->xthickness); + } else { + widget = gtkVScale(); + troughRect.inflateY(-gtk_widget_get_style(widget)->ythickness); } gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); WidgetRenderingContext widgetContext(info.context, rect); widgetContext.gtkPaintBox(troughRect, widget, GTK_STATE_ACTIVE, GTK_SHADOW_OUT, "trough"); if (isFocused(object)) - widgetContext.gtkPaintFocus(IntRect(IntPoint(), rect.size()), widget, getGtkStateType(object), "trough"); + widgetContext.gtkPaintFocus(IntRect(IntPoint(), rect.size()), widget, getGtkStateType(this, object), "trough"); return false; } @@ -276,19 +328,19 @@ bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& inf return false; ControlPart part = object->style()->appearance(); - ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart); + ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart); GtkWidget* widget = 0; const char* detail = 0; GtkOrientation orientation; - if (part == SliderThumbVerticalPart) { - widget = gtkVScale(); - detail = "vscale"; - orientation = GTK_ORIENTATION_VERTICAL; - } else { + if (part == SliderThumbHorizontalPart) { widget = gtkHScale(); detail = "hscale"; orientation = GTK_ORIENTATION_HORIZONTAL; + } else { + widget = gtkVScale(); + detail = "vscale"; + orientation = GTK_ORIENTATION_VERTICAL; } gtk_widget_set_direction(widget, gtkTextDirection(object->style()->direction())); @@ -298,7 +350,7 @@ bool RenderThemeGtk::paintSliderThumb(RenderObject* object, const PaintInfo& inf // on them. IntRect thumbRect(IntPoint(), rect.size()); WidgetRenderingContext widgetContext(info.context, rect); - widgetContext.gtkPaintSlider(thumbRect, widget, getGtkStateType(object), GTK_SHADOW_OUT, detail, orientation); + widgetContext.gtkPaintSlider(thumbRect, widget, getGtkStateType(this, object), GTK_SHADOW_OUT, detail, orientation); return false; } @@ -306,7 +358,7 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* o) const { ControlPart part = o->style()->appearance(); #if ENABLE(VIDEO) - if (part == MediaSliderThumbPart || part == MediaVolumeSliderThumbPart) { + if (part == MediaSliderThumbPart) { adjustMediaSliderThumbSize(o); return; } @@ -324,12 +376,26 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* o) const o->style()->setHeight(Length(width, Fixed)); return; } - ASSERT(part == SliderThumbVerticalPart); + ASSERT(part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart); o->style()->setWidth(Length(width, Fixed)); o->style()->setHeight(Length(length, Fixed)); } #if ENABLE(PROGRESS_TAG) +double RenderThemeGtk::animationRepeatIntervalForProgressBar(RenderProgress*) const +{ + // FIXME: It doesn't look like there is a good way yet to support animated + // progress bars with the Mozilla theme drawing code. + return 0; +} + +double RenderThemeGtk::animationDurationForProgressBar(RenderProgress*) const +{ + // FIXME: It doesn't look like there is a good way yet to support animated + // progress bars with the Mozilla theme drawing code. + return 0; +} + bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { if (!renderObject->isProgress()) diff --git a/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp b/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp index 663404d..212e29d 100644 --- a/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp +++ b/Source/WebCore/platform/gtk/RenderThemeGtk3.cpp @@ -33,11 +33,11 @@ #include "HTMLNames.h" #include "MediaControlElements.h" #include "Page.h" +#include "PaintInfo.h" #include "RenderObject.h" #include "TextDirection.h" #include "UserAgentStyleSheets.h" -#include "WidgetRenderingContext.h" -#include "gtkdrawing.h" +#include <cmath> #include <gdk/gdk.h> #include <gtk/gtk.h> @@ -47,6 +47,9 @@ namespace WebCore { +// This is the default value defined by GTK+, where it was defined as MIN_ARROW_SIZE in gtkarrow.c. +static const int minArrowSize = 15; + typedef HashMap<GType, GRefPtr<GtkStyleContext> > StyleContextMap; static StyleContextMap& styleContextMap(); @@ -90,16 +93,36 @@ static GtkStyleContext* getStyleContext(GType widgetType) return context.get(); } +GtkStyleContext* RenderThemeGtk::gtkScrollbarStyle() +{ + return getStyleContext(GTK_TYPE_SCROLLBAR); +} + // This is not a static method, because we want to avoid having GTK+ headers in RenderThemeGtk.h. extern GtkTextDirection gtkTextDirection(TextDirection); +void RenderThemeGtk::platformInit() +{ +} + +RenderThemeGtk::~RenderThemeGtk() +{ +} + +#if ENABLE(VIDEO) void RenderThemeGtk::initMediaColors() { - GtkStyle* style = gtk_widget_get_style(GTK_WIDGET(gtkContainer())); - m_panelColor = style->bg[GTK_STATE_NORMAL]; - m_sliderColor = style->bg[GTK_STATE_ACTIVE]; - m_sliderThumbColor = style->bg[GTK_STATE_SELECTED]; + GdkRGBA color; + GtkStyleContext* containerContext = getStyleContext(GTK_TYPE_CONTAINER); + + gtk_style_context_get_background_color(containerContext, GTK_STATE_FLAG_NORMAL, &color); + m_panelColor = color; + gtk_style_context_get_background_color(containerContext, GTK_STATE_FLAG_ACTIVE, &color); + m_sliderColor = color; + gtk_style_context_get_background_color(containerContext, GTK_STATE_FLAG_SELECTED, &color); + m_sliderThumbColor = color; } +#endif static void adjustRectForFocus(GtkStyleContext* context, IntRect& rect) { @@ -113,119 +136,140 @@ static void adjustRectForFocus(GtkStyleContext* context, IntRect& rect) void RenderThemeGtk::adjustRepaintRect(const RenderObject* renderObject, IntRect& rect) { GtkStyleContext* context = 0; + bool checkInteriorFocus = false; ControlPart part = renderObject->style()->appearance(); switch (part) { + case CheckboxPart: + case RadioPart: + context = getStyleContext(part == CheckboxPart ? GTK_TYPE_CHECK_BUTTON : GTK_TYPE_RADIO_BUTTON); + + gint indicatorSpacing; + gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, NULL); + rect.inflate(indicatorSpacing); + + return; case SliderVerticalPart: case SliderHorizontalPart: context = getStyleContext(part == SliderThumbHorizontalPart ? GTK_TYPE_HSCALE : GTK_TYPE_VSCALE); break; case ButtonPart: + case MenulistButtonPart: + case MenulistPart: context = getStyleContext(GTK_TYPE_BUTTON); - - gboolean interiorFocus; - gtk_style_context_get_style(context, "interior-focus", &interiorFocus, NULL); - if (interiorFocus) - return; - + checkInteriorFocus = true; + break; + case TextFieldPart: + case TextAreaPart: + context = getStyleContext(GTK_TYPE_ENTRY); + checkInteriorFocus = true; break; default: return; } ASSERT(context); + if (checkInteriorFocus) { + gboolean interiorFocus; + gtk_style_context_get_style(context, "interior-focus", &interiorFocus, NULL); + if (interiorFocus) + return; + } adjustRectForFocus(context, rect); } -GtkStateType RenderThemeGtk::getGtkStateType(RenderObject* object) +static void setToggleSize(GtkStyleContext* context, RenderStyle* style) { - if (!isEnabled(object) || isReadOnlyControl(object)) - return GTK_STATE_INSENSITIVE; - if (isPressed(object)) - return GTK_STATE_ACTIVE; - if (isHovered(object)) - return GTK_STATE_PRELIGHT; - return GTK_STATE_NORMAL; -} - -bool RenderThemeGtk::paintRenderObject(GtkThemeWidgetType type, RenderObject* renderObject, GraphicsContext* context, const IntRect& rect, int flags) -{ - // Painting is disabled so just claim to have succeeded - if (context->paintingDisabled()) - return false; - - GtkWidgetState widgetState; - widgetState.active = isPressed(renderObject); - widgetState.focused = isFocused(renderObject); + // The width and height are both specified, so we shouldn't change them. + if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) + return; - // https://bugs.webkit.org/show_bug.cgi?id=18364 - // The Mozilla theme drawing code, only paints a button as pressed when it's pressed - // while hovered. Until we move away from the Mozila code, work-around the issue by - // forcing a pressed button into the hovered state. This ensures that buttons activated - // via the keyboard have the proper rendering. - widgetState.inHover = isHovered(renderObject) || (type == MOZ_GTK_BUTTON && isPressed(renderObject)); + // Other ports hard-code this to 13 which is also the default value defined by GTK+. + // GTK+ users tend to demand the native look. + // It could be made a configuration option values other than 13 actually break site compatibility. + gint indicatorSize; + gtk_style_context_get_style(context, "indicator-size", &indicatorSize, NULL); - // FIXME: Disabled does not always give the correct appearance for ReadOnly - widgetState.disabled = !isEnabled(renderObject) || isReadOnlyControl(renderObject); - widgetState.isDefault = false; - widgetState.canDefault = false; - widgetState.depressed = false; + if (style->width().isIntrinsicOrAuto()) + style->setWidth(Length(indicatorSize, Fixed)); - WidgetRenderingContext widgetContext(context, rect); - return !widgetContext.paintMozillaWidget(type, &widgetState, flags, - gtkTextDirection(renderObject->style()->direction())); + if (style->height().isAuto()) + style->setHeight(Length(indicatorSize, Fixed)); } -static void setToggleSize(const RenderThemeGtk* theme, RenderStyle* style, ControlPart appearance) +static void paintToggle(const RenderThemeGtk* theme, GType widgetType, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - // The width and height are both specified, so we shouldn't change them. - if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto()) - return; + GtkStyleContext* context = getStyleContext(widgetType); + gtk_style_context_save(context); - // FIXME: This is probably not correct use of indicatorSize and indicatorSpacing. - gint indicatorSize, indicatorSpacing; - theme->getIndicatorMetrics(appearance, indicatorSize, indicatorSpacing); + gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction()))); + gtk_style_context_add_class(context, widgetType == GTK_TYPE_CHECK_BUTTON ? GTK_STYLE_CLASS_CHECK : GTK_STYLE_CLASS_RADIO); - // Other ports hard-code this to 13, but GTK+ users tend to demand the native look. - // It could be made a configuration option values other than 13 actually break site compatibility. - int length = indicatorSize + indicatorSpacing; - if (style->width().isIntrinsicOrAuto()) - style->setWidth(Length(length, Fixed)); + guint flags = 0; + if (!theme->isEnabled(renderObject) || theme->isReadOnlyControl(renderObject)) + flags |= GTK_STATE_FLAG_INSENSITIVE; + else if (theme->isHovered(renderObject)) + flags |= GTK_STATE_FLAG_PRELIGHT; + if (theme->isIndeterminate(renderObject)) + flags |= GTK_STATE_FLAG_INCONSISTENT; + else if (theme->isChecked(renderObject)) + flags |= GTK_STATE_FLAG_ACTIVE; + if (theme->isPressed(renderObject)) + flags |= GTK_STATE_FLAG_SELECTED; + gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags)); - if (style->height().isAuto()) - style->setHeight(Length(length, Fixed)); + if (widgetType == GTK_TYPE_CHECK_BUTTON) + gtk_render_check(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height()); + else + gtk_render_option(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height()); + + if (theme->isFocused(renderObject)) { + IntRect indicatorRect(rect); + gint indicatorSpacing; + gtk_style_context_get_style(context, "indicator-spacing", &indicatorSpacing, NULL); + indicatorRect.inflate(indicatorSpacing); + gtk_render_focus(context, paintInfo.context->platformContext(), indicatorRect.x(), indicatorRect.y(), + indicatorRect.width(), indicatorRect.height()); + } + + gtk_style_context_restore(context); } void RenderThemeGtk::setCheckboxSize(RenderStyle* style) const { - setToggleSize(this, style, RadioPart); + setToggleSize(getStyleContext(GTK_TYPE_CHECK_BUTTON), style); } -bool RenderThemeGtk::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect) +bool RenderThemeGtk::paintCheckbox(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintRenderObject(MOZ_GTK_CHECKBUTTON, object, info.context, rect, isChecked(object)); + paintToggle(this, GTK_TYPE_CHECK_BUTTON, renderObject, paintInfo, rect); + return false; } void RenderThemeGtk::setRadioSize(RenderStyle* style) const { - setToggleSize(this, style, RadioPart); + setToggleSize(getStyleContext(GTK_TYPE_RADIO_BUTTON), style); } -bool RenderThemeGtk::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect) +bool RenderThemeGtk::paintRadio(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintRenderObject(MOZ_GTK_RADIOBUTTON, object, info.context, rect, isChecked(object)); + paintToggle(this, GTK_TYPE_RADIO_BUTTON, renderObject, paintInfo, rect); + return false; } -bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +static void renderButton(RenderTheme* theme, GtkStyleContext* context, RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - GtkStyleContext* context = getStyleContext(GTK_TYPE_BUTTON); - gtk_style_context_save(context); - - gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction()))); - gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON); - IntRect buttonRect(rect); - if (isDefault(renderObject)) { + guint flags = 0; + if (!theme->isEnabled(renderObject) || theme->isReadOnlyControl(renderObject)) + flags |= GTK_STATE_FLAG_INSENSITIVE; + else if (theme->isHovered(renderObject)) + flags |= GTK_STATE_FLAG_PRELIGHT; + if (theme->isPressed(renderObject)) + flags |= GTK_STATE_FLAG_ACTIVE; + gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags)); + + if (theme->isDefault(renderObject)) { GtkBorder* borderPtr = 0; GtkBorder border = { 1, 1, 1, 1 }; @@ -242,19 +286,10 @@ bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& pa gtk_style_context_add_class(context, GTK_STYLE_CLASS_DEFAULT); } - guint flags = 0; - if (!isEnabled(renderObject) || isReadOnlyControl(renderObject)) - flags |= GTK_STATE_FLAG_INSENSITIVE; - else if (isHovered(renderObject)) - flags |= GTK_STATE_FLAG_PRELIGHT; - if (isPressed(renderObject)) - flags |= GTK_STATE_FLAG_ACTIVE; - gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags)); - gtk_render_background(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height()); gtk_render_frame(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height()); - if (isFocused(renderObject)) { + if (theme->isFocused(renderObject)) { gint focusWidth, focusPad; gboolean displaceFocus, interiorFocus; gtk_style_context_get_style(context, @@ -274,7 +309,7 @@ bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& pa } else buttonRect.inflate(focusWidth + focusPad); - if (displaceFocus && isPressed(renderObject)) { + if (displaceFocus && theme->isPressed(renderObject)) { gint childDisplacementX; gint childDisplacementY; gtk_style_context_get_style(context, @@ -286,64 +321,283 @@ bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& pa gtk_render_focus(context, paintInfo.context->platformContext(), buttonRect.x(), buttonRect.y(), buttonRect.width(), buttonRect.height()); } +} +bool RenderThemeGtk::paintButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +{ + GtkStyleContext* context = getStyleContext(GTK_TYPE_BUTTON); + gtk_style_context_save(context); + + gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction()))); + gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON); + + renderButton(this, context, renderObject, paintInfo, rect); gtk_style_context_restore(context); return false; } -static void getComboBoxPadding(RenderStyle* style, int& left, int& top, int& right, int& bottom) +static void getComboBoxMetrics(RenderStyle* style, GtkBorder& border, int& focus, int& separator) { // If this menu list button isn't drawn using the native theme, we // don't add any extra padding beyond what WebCore already uses. if (style->appearance() == NoControlPart) return; - moz_gtk_get_widget_border(MOZ_GTK_DROPDOWN, &left, &top, &right, &bottom, - gtkTextDirection(style->direction()), TRUE); + + GtkStyleContext* context = getStyleContext(GTK_TYPE_BUTTON); + gtk_style_context_save(context); + + gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON); + gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(style->direction()))); + + gtk_style_context_get_border(context, static_cast<GtkStateFlags>(0), &border); + + gboolean interiorFocus; + gint focusWidth, focusPad; + gtk_style_context_get_style(context, + "interior-focus", &interiorFocus, + "focus-line-width", &focusWidth, + "focus-padding", &focusPad, NULL); + focus = interiorFocus ? focusWidth + focusPad : 0; + + gtk_style_context_restore(context); + + context = getStyleContext(GTK_TYPE_SEPARATOR); + gtk_style_context_save(context); + + GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(style->direction())); + gtk_style_context_set_direction(context, direction); + gtk_style_context_add_class(context, "separator"); + + gboolean wideSeparators; + gint separatorWidth; + gtk_style_context_get_style(context, + "wide-separators", &wideSeparators, + "separator-width", &separatorWidth, + NULL); + + // GTK+ always uses border.left, regardless of text direction. See gtkseperator.c. + if (!wideSeparators) + separatorWidth = border.left; + + separator = separatorWidth; + + gtk_style_context_restore(context); } int RenderThemeGtk::popupInternalPaddingLeft(RenderStyle* style) const { - int left = 0, top = 0, right = 0, bottom = 0; - getComboBoxPadding(style, left, top, right, bottom); + GtkBorder borderWidth = { 0, 0, 0, 0 }; + int focusWidth = 0, separatorWidth = 0; + getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth); + int left = borderWidth.left + focusWidth; + if (style->direction() == RTL) + left += separatorWidth + minArrowSize; return left; } int RenderThemeGtk::popupInternalPaddingRight(RenderStyle* style) const { - int left = 0, top = 0, right = 0, bottom = 0; - getComboBoxPadding(style, left, top, right, bottom); + GtkBorder borderWidth = { 0, 0, 0, 0 }; + int focusWidth = 0, separatorWidth = 0; + getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth); + int right = borderWidth.right + focusWidth; + if (style->direction() == LTR) + right += separatorWidth + minArrowSize; return right; } int RenderThemeGtk::popupInternalPaddingTop(RenderStyle* style) const { - int left = 0, top = 0, right = 0, bottom = 0; - getComboBoxPadding(style, left, top, right, bottom); - return top; + GtkBorder borderWidth = { 0, 0, 0, 0 }; + int focusWidth = 0, separatorWidth = 0; + getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth); + return borderWidth.top + focusWidth; } int RenderThemeGtk::popupInternalPaddingBottom(RenderStyle* style) const { - int left = 0, top = 0, right = 0, bottom = 0; - getComboBoxPadding(style, left, top, right, bottom); - return bottom; + GtkBorder borderWidth = { 0, 0, 0, 0 }; + int focusWidth = 0, separatorWidth = 0; + getComboBoxMetrics(style, borderWidth, focusWidth, separatorWidth); + return borderWidth.bottom + focusWidth; } -bool RenderThemeGtk::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect) +bool RenderThemeGtk::paintMenuList(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintRenderObject(MOZ_GTK_DROPDOWN, object, info.context, rect); + cairo_t* cairoContext = paintInfo.context->platformContext(); + GtkTextDirection direction = static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction())); + + // Paint the button. + GtkStyleContext* buttonStyleContext = getStyleContext(GTK_TYPE_BUTTON); + gtk_style_context_save(buttonStyleContext); + gtk_style_context_set_direction(buttonStyleContext, direction); + gtk_style_context_add_class(buttonStyleContext, GTK_STYLE_CLASS_BUTTON); + renderButton(this, buttonStyleContext, renderObject, paintInfo, rect); + + // Get the inner rectangle. + gint focusWidth, focusPad; + GtkBorder* innerBorderPtr = 0; + GtkBorder innerBorder = { 1, 1, 1, 1 }; + gtk_style_context_get_style(buttonStyleContext, + "inner-border", &innerBorderPtr, + "focus-line-width", &focusWidth, + "focus-padding", &focusPad, + NULL); + if (innerBorderPtr) { + innerBorder = *innerBorderPtr; + gtk_border_free(innerBorderPtr); + } + + GtkBorder borderWidth; + GtkStateFlags state = gtk_style_context_get_state(buttonStyleContext); + gtk_style_context_get_border(buttonStyleContext, state, &borderWidth); + + focusWidth += focusPad; + IntRect innerRect(rect.x() + innerBorder.left + borderWidth.left + focusWidth, + rect.y() + innerBorder.top + borderWidth.top + focusWidth, + rect.width() - borderWidth.left - borderWidth.right - innerBorder.left - innerBorder.right - (2 * focusWidth), + rect.height() - borderWidth.top - borderWidth.bottom - innerBorder.top - innerBorder.bottom - (2 * focusWidth)); + + if (isPressed(renderObject)) { + gint childDisplacementX; + gint childDisplacementY; + gtk_style_context_get_style(buttonStyleContext, + "child-displacement-x", &childDisplacementX, + "child-displacement-y", &childDisplacementY, + NULL); + innerRect.move(childDisplacementX, childDisplacementY); + } + innerRect.setWidth(max(1, innerRect.width())); + innerRect.setHeight(max(1, innerRect.height())); + + gtk_style_context_restore(buttonStyleContext); + + // Paint the arrow. + GtkStyleContext* arrowStyleContext = getStyleContext(GTK_TYPE_ARROW); + gtk_style_context_save(arrowStyleContext); + + gtk_style_context_set_direction(arrowStyleContext, direction); + gtk_style_context_add_class(arrowStyleContext, "arrow"); + gtk_style_context_add_class(arrowStyleContext, GTK_STYLE_CLASS_BUTTON); + + gfloat arrowScaling; + gtk_style_context_get_style(arrowStyleContext, "arrow-scaling", &arrowScaling, NULL); + + IntSize arrowSize(minArrowSize, innerRect.height()); + IntPoint arrowPosition = innerRect.location(); + if (direction == GTK_TEXT_DIR_LTR) + arrowPosition.move(innerRect.width() - arrowSize.width(), 0); + + // GTK+ actually fetches the xalign and valign values from the widget, but since we + // don't have a widget here, we are just using the default xalign and valign values of 0.5. + gint extent = std::min(arrowSize.width(), arrowSize.height()) * arrowScaling; + arrowPosition.move(std::floor((arrowSize.width() - extent) / 2), std::floor((arrowSize.height() - extent) / 2)); + + gtk_style_context_set_state(arrowStyleContext, state); + gtk_render_arrow(arrowStyleContext, cairoContext, G_PI, arrowPosition.x(), arrowPosition.y(), extent); + + gtk_style_context_restore(arrowStyleContext); + + // Paint the separator if needed. + GtkStyleContext* separatorStyleContext = getStyleContext(GTK_TYPE_SEPARATOR); + gtk_style_context_save(separatorStyleContext); + + gtk_style_context_set_direction(separatorStyleContext, direction); + gtk_style_context_add_class(separatorStyleContext, "separator"); + gtk_style_context_add_class(separatorStyleContext, GTK_STYLE_CLASS_BUTTON); + + gboolean wideSeparators; + gint separatorWidth; + gtk_style_context_get_style(separatorStyleContext, + "wide-separators", &wideSeparators, + "separator-width", &separatorWidth, + NULL); + if (wideSeparators && !separatorWidth) { + gtk_style_context_restore(separatorStyleContext); + return false; + } + + gtk_style_context_set_state(separatorStyleContext, state); + IntPoint separatorPosition(arrowPosition.x(), innerRect.y()); + if (wideSeparators) { + if (direction == GTK_TEXT_DIR_LTR) + separatorPosition.move(-separatorWidth, 0); + else + separatorPosition.move(arrowSize.width(), 0); + + gtk_render_frame(separatorStyleContext, cairoContext, + separatorPosition.x(), separatorPosition.y(), + separatorWidth, innerRect.height()); + } else { + GtkBorder padding; + gtk_style_context_get_padding(separatorStyleContext, state, &padding); + GtkBorder border; + gtk_style_context_get_border(separatorStyleContext, state, &border); + + if (direction == GTK_TEXT_DIR_LTR) + separatorPosition.move(-(padding.left + border.left), 0); + else + separatorPosition.move(arrowSize.width(), 0); + + cairo_save(cairoContext); + + // An extra clip prevents the separator bleeding outside of the specified rectangle because of subpixel positioning. + cairo_rectangle(cairoContext, separatorPosition.x(), separatorPosition.y(), border.left, innerRect.height()); + cairo_clip(cairoContext); + gtk_render_line(separatorStyleContext, cairoContext, + separatorPosition.x(), separatorPosition.y(), + separatorPosition.x(), innerRect.bottom()); + cairo_restore(cairoContext); + } + + gtk_style_context_restore(separatorStyleContext); + return false; } -bool RenderThemeGtk::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect) +bool RenderThemeGtk::paintTextField(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { - return paintRenderObject(MOZ_GTK_ENTRY, object, info.context, rect); + GtkStyleContext* context = getStyleContext(GTK_TYPE_ENTRY); + gtk_style_context_save(context); + + gtk_style_context_set_direction(context, static_cast<GtkTextDirection>(gtkTextDirection(renderObject->style()->direction()))); + gtk_style_context_add_class(context, GTK_STYLE_CLASS_ENTRY); + + guint flags = 0; + if (!isEnabled(renderObject) || isReadOnlyControl(renderObject)) + flags |= GTK_STATE_FLAG_INSENSITIVE; + else if (isFocused(renderObject)) + flags |= GTK_STATE_FLAG_FOCUSED; + gtk_style_context_set_state(context, static_cast<GtkStateFlags>(flags)); + + gtk_render_background(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height()); + gtk_render_frame(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height()); + + if (isFocused(renderObject) && isEnabled(renderObject)) { + gboolean interiorFocus; + gint focusWidth, focusPad; + gtk_style_context_get_style(context, + "interior-focus", &interiorFocus, + "focus-line-width", &focusWidth, + "focus-padding", &focusPad, + NULL); + if (!interiorFocus) { + IntRect focusRect(rect); + focusRect.inflate(focusWidth + focusPad); + gtk_render_focus(context, paintInfo.context->platformContext(), + focusRect.x(), focusRect.y(), focusRect.width(), focusRect.height()); + } + } + + gtk_style_context_restore(context); + + return false; } bool RenderThemeGtk::paintSliderTrack(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { ControlPart part = renderObject->style()->appearance(); - ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart); + ASSERT(part == SliderHorizontalPart || part == SliderVerticalPart || part == MediaVolumeSliderPart); GtkStyleContext* context = getStyleContext(part == SliderThumbHorizontalPart ? GTK_TYPE_HSCALE : GTK_TYPE_VSCALE); gtk_style_context_save(context); @@ -378,7 +632,7 @@ bool RenderThemeGtk::paintSliderTrack(RenderObject* renderObject, const PaintInf bool RenderThemeGtk::paintSliderThumb(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { ControlPart part = renderObject->style()->appearance(); - ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart); + ASSERT(part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart); GtkStyleContext* context = getStyleContext(part == SliderThumbHorizontalPart ? GTK_TYPE_HSCALE : GTK_TYPE_VSCALE); gtk_style_context_save(context); @@ -414,7 +668,7 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* renderObject) const { ControlPart part = renderObject->style()->appearance(); #if ENABLE(VIDEO) - if (part == MediaSliderThumbPart || part == MediaVolumeSliderThumbPart) { + if (part == MediaSliderThumbPart) { adjustMediaSliderThumbSize(renderObject); return; } @@ -430,37 +684,73 @@ void RenderThemeGtk::adjustSliderThumbSize(RenderObject* renderObject) const renderObject->style()->setHeight(Length(sliderWidth, Fixed)); return; } - ASSERT(part == SliderThumbVerticalPart); + ASSERT(part == SliderThumbVerticalPart || part == MediaVolumeSliderThumbPart); renderObject->style()->setWidth(Length(sliderWidth, Fixed)); renderObject->style()->setHeight(Length(sliderLength, Fixed)); } #if ENABLE(PROGRESS_TAG) +// These values have been copied from RenderThemeChromiumSkia.cpp +static const int progressActivityBlocks = 5; +static const int progressAnimationFrames = 10; +static const double progressAnimationInterval = 0.125; +double RenderThemeGtk::animationRepeatIntervalForProgressBar(RenderProgress*) const +{ + return progressAnimationInterval; +} + +double RenderThemeGtk::animationDurationForProgressBar(RenderProgress*) const +{ + return progressAnimationInterval * progressAnimationFrames * 2; // "2" for back and forth; +} + bool RenderThemeGtk::paintProgressBar(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) { if (!renderObject->isProgress()) return true; - GtkWidget* progressBarWidget = moz_gtk_get_progress_widget(); - if (!progressBarWidget) - return true; + GtkStyleContext* context = getStyleContext(GTK_TYPE_PROGRESS_BAR); + gtk_style_context_save(context); - if (paintRenderObject(MOZ_GTK_PROGRESSBAR, renderObject, paintInfo.context, rect)) - return true; + gtk_style_context_add_class(context, GTK_STYLE_CLASS_TROUGH); + + gtk_render_background(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height()); + gtk_render_frame(context, paintInfo.context->platformContext(), rect.x(), rect.y(), rect.width(), rect.height()); + + gtk_style_context_restore(context); + + gtk_style_context_save(context); + gtk_style_context_add_class(context, GTK_STYLE_CLASS_PROGRESSBAR); - IntRect chunkRect(rect); RenderProgress* renderProgress = toRenderProgress(renderObject); - GtkStyle* style = gtk_widget_get_style(progressBarWidget); - chunkRect.setHeight(chunkRect.height() - (2 * style->ythickness)); - chunkRect.setY(chunkRect.y() + style->ythickness); - chunkRect.setWidth((chunkRect.width() - (2 * style->xthickness)) * renderProgress->position()); - if (renderObject->style()->direction() == RTL) - chunkRect.setX(rect.x() + rect.width() - chunkRect.width() - style->xthickness); - else - chunkRect.setX(chunkRect.x() + style->xthickness); + GtkBorder padding; + gtk_style_context_get_padding(context, static_cast<GtkStateFlags>(0), &padding); + IntRect progressRect(rect.x() + padding.left, rect.y() + padding.top, + rect.width() - (padding.left + padding.right), + rect.height() - (padding.top + padding.bottom)); + + if (renderProgress->isDeterminate()) { + progressRect.setWidth(progressRect.width() * renderProgress->position()); + if (renderObject->style()->direction() == RTL) + progressRect.setX(rect.x() + rect.width() - progressRect.width() - padding.right); + } else { + double animationProgress = renderProgress->animationProgress(); + + progressRect.setWidth(max(2, progressRect.width() / progressActivityBlocks)); + int movableWidth = rect.width() - progressRect.width(); + if (animationProgress < 0.5) + progressRect.setX(progressRect.x() + (animationProgress * 2 * movableWidth)); + else + progressRect.setX(progressRect.x() + ((1.0 - animationProgress) * 2 * movableWidth)); + } + + if (!progressRect.isEmpty()) + gtk_render_activity(context, paintInfo.context->platformContext(), progressRect.x(), progressRect.y(), progressRect.width(), progressRect.height()); + + gtk_style_context_restore(context); - return paintRenderObject(MOZ_GTK_PROGRESS_CHUNK, renderObject, paintInfo.context, chunkRect); + return false; } #endif @@ -558,86 +848,6 @@ Color RenderThemeGtk::systemColor(int cssValueId) const } } -static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, RenderTheme* renderTheme) -{ - // FIXME: Make sure this function doesn't get called many times for a single GTK+ style change signal. - renderTheme->platformColorsDidChange(); -} - -void RenderThemeGtk::setupWidgetAndAddToContainer(GtkWidget* widget, GtkWidget* window) const -{ - gtk_container_add(GTK_CONTAINER(window), widget); - gtk_widget_realize(widget); - g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); - - // FIXME: Perhaps this should only be called for the containing window or parent container. - g_signal_connect(widget, "style-set", G_CALLBACK(gtkStyleSetCallback), const_cast<RenderThemeGtk*>(this)); -} - -GtkWidget* RenderThemeGtk::gtkContainer() const -{ - if (m_gtkContainer) - return m_gtkContainer; - - m_gtkWindow = gtk_window_new(GTK_WINDOW_POPUP); - gtk_widget_realize(m_gtkWindow); - gtk_widget_set_name(m_gtkWindow, "MozillaGtkWidget"); - - m_gtkContainer = gtk_fixed_new(); - setupWidgetAndAddToContainer(m_gtkContainer, m_gtkWindow); - return m_gtkContainer; -} - -GtkWidget* RenderThemeGtk::gtkButton() const -{ - if (m_gtkButton) - return m_gtkButton; - m_gtkButton = gtk_button_new(); - setupWidgetAndAddToContainer(m_gtkButton, gtkContainer()); - return m_gtkButton; -} - -GtkWidget* RenderThemeGtk::gtkEntry() const -{ - if (m_gtkEntry) - return m_gtkEntry; - m_gtkEntry = gtk_entry_new(); - setupWidgetAndAddToContainer(m_gtkEntry, gtkContainer()); - return m_gtkEntry; -} - -GtkWidget* RenderThemeGtk::gtkTreeView() const -{ - if (m_gtkTreeView) - return m_gtkTreeView; - m_gtkTreeView = gtk_tree_view_new(); - setupWidgetAndAddToContainer(m_gtkTreeView, gtkContainer()); - return m_gtkTreeView; -} - -GtkWidget* RenderThemeGtk::gtkVScale() const -{ - if (m_gtkVScale) - return m_gtkVScale; - m_gtkVScale = gtk_vscale_new(0); - setupWidgetAndAddToContainer(m_gtkVScale, gtkContainer()); - return m_gtkVScale; -} - -GtkWidget* RenderThemeGtk::gtkHScale() const -{ - if (m_gtkHScale) - return m_gtkHScale; - m_gtkHScale = gtk_hscale_new(0); - setupWidgetAndAddToContainer(m_gtkHScale, gtkContainer()); - return m_gtkHScale; -} - -GtkStyleContext* RenderThemeGtk::gtkScrollbarStyle() -{ - return getStyleContext(GTK_TYPE_SCROLLBAR); -} - } // namespace WebCore #endif // !GTK_API_VERSION_2 diff --git a/Source/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp b/Source/WebCore/platform/gtk/WidgetRenderingContext.cpp index e85c570..6d1be31 100644 --- a/Source/WebCore/platform/gtk/WidgetRenderingContextGtk2.cpp +++ b/Source/WebCore/platform/gtk/WidgetRenderingContext.cpp @@ -32,6 +32,7 @@ #include "WidgetRenderingContext.h" #include "GraphicsContext.h" +#include "GtkVersioning.h" #include "RefPtrCairo.h" #include "RenderThemeGtk.h" #include "Timer.h" @@ -107,7 +108,7 @@ WidgetRenderingContext::WidgetRenderingContext(GraphicsContext* graphicsContext, int scratchWidth = 0; int scratchHeight = 0; if (gScratchBuffer) - gdk_drawable_get_size(gScratchBuffer, &scratchWidth, &scratchHeight); + gdk_pixmap_get_size(gScratchBuffer, &scratchWidth, &scratchHeight); // We do not need to recreate the buffer if the current buffer is large enough. if (!gScratchBuffer || scratchWidth < width || scratchHeight < height) { diff --git a/Source/WebCore/platform/gtk/WidgetRenderingContext.h b/Source/WebCore/platform/gtk/WidgetRenderingContext.h index 7334656..8b2a0e2 100644 --- a/Source/WebCore/platform/gtk/WidgetRenderingContext.h +++ b/Source/WebCore/platform/gtk/WidgetRenderingContext.h @@ -22,6 +22,8 @@ #ifndef WidgetRenderingContext_h #define WidgetRenderingContext_h +#ifdef GTK_API_VERSION_2 + #include "IntRect.h" #include "gtkdrawing.h" @@ -46,15 +48,11 @@ private: GdkRectangle m_paintRect; IntSize m_extraSpace; bool m_hadError; - -#ifdef GTK_API_VERSION_2 GdkDrawable* m_target; -#else - cairo_t* m_target; -#endif }; } -#endif +#endif // GTK_API_VERSION_2 +#endif // WidgetRenderingContext_h diff --git a/Source/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp b/Source/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp deleted file mode 100644 index 69c4af5..0000000 --- a/Source/WebCore/platform/gtk/WidgetRenderingContextGtk3.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2010 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "WidgetRenderingContext.h" - -#include "GraphicsContext.h" -#include "IntRect.h" - -#ifndef GTK_API_VERSION_2 - -namespace WebCore { - -WidgetRenderingContext::WidgetRenderingContext(GraphicsContext* context, const IntRect& targetRect) - : m_graphicsContext(context) - , m_targetRect(targetRect) - , m_paintRect(targetRect) - , m_hadError(false) - , m_target(context->platformContext()) -{ -} - -WidgetRenderingContext::~WidgetRenderingContext() -{ -} - -bool WidgetRenderingContext::paintMozillaWidget(GtkThemeWidgetType type, GtkWidgetState* state, int flags, GtkTextDirection textDirection) -{ - m_hadError = moz_gtk_widget_paint(type, m_target, &m_paintRect, state, flags, textDirection) != MOZ_GTK_SUCCESS; - return !m_hadError; -} - -void WidgetRenderingContext::gtkPaintBox(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail) -{ - GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; - gtk_paint_box(gtk_widget_get_style(widget), m_target, stateType, shadowType, widget, - detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height); -} - -void WidgetRenderingContext::gtkPaintFocus(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, const gchar* detail) -{ - GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; - gtk_paint_focus(gtk_widget_get_style(widget), m_target, stateType, widget, - detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height); -} - -void WidgetRenderingContext::gtkPaintSlider(const IntRect& rect, GtkWidget* widget, GtkStateType stateType, GtkShadowType shadowType, const gchar* detail, GtkOrientation orientation) -{ - GdkRectangle paintRect = { m_paintRect.x + rect.x(), m_paintRect.y + rect.y(), rect.width(), rect.height() }; - gtk_paint_slider(gtk_widget_get_style(widget), m_target, stateType, shadowType, widget, - detail, paintRect.x, paintRect.y, paintRect.width, paintRect.height, orientation); -} - -} - -#endif // !GTK_API_VERSION_2 diff --git a/Source/WebCore/platform/gtk/gtk3drawing.c b/Source/WebCore/platform/gtk/gtk3drawing.c deleted file mode 100644 index d3bdd56..0000000 --- a/Source/WebCore/platform/gtk/gtk3drawing.c +++ /dev/null @@ -1,1288 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2002 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brian Ryner <bryner@brianryner.com> (Original Author) - * Pierre Chanial <p_ch@verizon.net> - * Michael Ventnor <m.ventnor@gmail.com> - * Alp Toker <alp@nuanti.com> - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/* - * This file contains painting functions for each of the gtk2 widgets. - * Adapted from the gtkdrawing.c, and gtk+2.0 source. - */ - -#ifndef GTK_API_VERSION_2 - -#include <gdk/gdkprivate.h> -#include "gtkdrawing.h" -#include "GtkVersioning.h" -#include <math.h> -#include <string.h> - -#define XTHICKNESS(style) (style->xthickness) -#define YTHICKNESS(style) (style->ythickness) - -static GtkThemeParts *gParts = NULL; -static style_prop_t style_prop_func; -static gboolean have_arrow_scaling; -static gboolean is_initialized; - -void -moz_gtk_use_theme_parts(GtkThemeParts* parts) -{ - gParts = parts; -} - -/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine - that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific - things they may want to do. */ -static void -moz_gtk_set_widget_name(GtkWidget* widget) -{ - gtk_widget_set_name(widget, "MozillaGtkWidget"); -} - -gint -moz_gtk_enable_style_props(style_prop_t styleGetProp) -{ - style_prop_func = styleGetProp; - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_window_widget() -{ - if (!gParts->protoWindow) { - gParts->protoWindow = gtk_window_new(GTK_WINDOW_POPUP); - gtk_widget_realize(gParts->protoWindow); - moz_gtk_set_widget_name(gParts->protoWindow); - } - return MOZ_GTK_SUCCESS; -} - -static gint -setup_widget_prototype(GtkWidget* widget) -{ - ensure_window_widget(); - if (!gParts->protoLayout) { - gParts->protoLayout = gtk_fixed_new(); - gtk_container_add(GTK_CONTAINER(gParts->protoWindow), gParts->protoLayout); - } - - gtk_container_add(GTK_CONTAINER(gParts->protoLayout), widget); - gtk_widget_realize(widget); - g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_button_widget() -{ - if (!gParts->buttonWidget) { - gParts->buttonWidget = gtk_button_new_with_label("M"); - setup_widget_prototype(gParts->buttonWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_toggle_button_widget() -{ - if (!gParts->toggleButtonWidget) { - gParts->toggleButtonWidget = gtk_toggle_button_new(); - setup_widget_prototype(gParts->toggleButtonWidget); - /* toggle button must be set active to get the right style on hover. */ - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gParts->toggleButtonWidget), TRUE); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_button_arrow_widget() -{ - if (!gParts->buttonArrowWidget) { - ensure_toggle_button_widget(); - - gParts->buttonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT); - gtk_container_add(GTK_CONTAINER(gParts->toggleButtonWidget), gParts->buttonArrowWidget); - gtk_widget_realize(gParts->buttonArrowWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_checkbox_widget() -{ - if (!gParts->checkboxWidget) { - gParts->checkboxWidget = gtk_check_button_new_with_label("M"); - setup_widget_prototype(gParts->checkboxWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_radiobutton_widget() -{ - if (!gParts->radiobuttonWidget) { - gParts->radiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M"); - setup_widget_prototype(gParts->radiobuttonWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_scrollbar_widget() -{ - if (!gParts->vertScrollbarWidget) { - gParts->vertScrollbarWidget = gtk_vscrollbar_new(NULL); - setup_widget_prototype(gParts->vertScrollbarWidget); - } - if (!gParts->horizScrollbarWidget) { - gParts->horizScrollbarWidget = gtk_hscrollbar_new(NULL); - setup_widget_prototype(gParts->horizScrollbarWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_entry_widget() -{ - if (!gParts->entryWidget) { - gParts->entryWidget = gtk_entry_new(); - setup_widget_prototype(gParts->entryWidget); - } - return MOZ_GTK_SUCCESS; -} - -/* We need to have pointers to the inner widgets (button, separator, arrow) - * of the ComboBox to get the correct rendering from theme engines which - * special cases their look. Since the inner layout can change, we ask GTK - * to NULL our pointers when they are about to become invalid because the - * corresponding widgets don't exist anymore. It's the role of - * g_object_add_weak_pointer(). - * Note that if we don't find the inner widgets (which shouldn't happen), we - * fallback to use generic "non-inner" widgets, and they don't need that kind - * of weak pointer since they are explicit children of gParts->protoWindow and as - * such GTK holds a strong reference to them. */ -static void -moz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data) -{ - if (GTK_IS_TOGGLE_BUTTON(widget)) { - gParts->comboBoxButtonWidget = widget; - g_object_add_weak_pointer(G_OBJECT(widget), - (gpointer) &gParts->comboBoxButtonWidget); - gtk_widget_realize(widget); - g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); - } -} - -static void -moz_gtk_get_combo_box_button_inner_widgets(GtkWidget *widget, - gpointer client_data) -{ - if (GTK_IS_SEPARATOR(widget)) { - gParts->comboBoxSeparatorWidget = widget; - g_object_add_weak_pointer(G_OBJECT(widget), - (gpointer) &gParts->comboBoxSeparatorWidget); - } else if (GTK_IS_ARROW(widget)) { - gParts->comboBoxArrowWidget = widget; - g_object_add_weak_pointer(G_OBJECT(widget), - (gpointer) &gParts->comboBoxArrowWidget); - } else - return; - gtk_widget_realize(widget); - g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); -} - -static gint -ensure_combo_box_widgets() -{ - GtkWidget* buttonChild; - - if (gParts->comboBoxButtonWidget && gParts->comboBoxArrowWidget) - return MOZ_GTK_SUCCESS; - - /* Create a ComboBox if needed */ - if (!gParts->comboBoxWidget) { - gParts->comboBoxWidget = gtk_combo_box_new(); - setup_widget_prototype(gParts->comboBoxWidget); - } - - /* Get its inner Button */ - gtk_container_forall(GTK_CONTAINER(gParts->comboBoxWidget), - moz_gtk_get_combo_box_inner_button, - NULL); - - if (gParts->comboBoxButtonWidget) { - /* Get the widgets inside the Button */ - buttonChild = gtk_bin_get_child(GTK_BIN(gParts->comboBoxButtonWidget)); - if (GTK_IS_HBOX(buttonChild)) { - /* appears-as-list = FALSE, cell-view = TRUE; the button - * contains an hbox. This hbox is there because the ComboBox - * needs to place a cell renderer, a separator, and an arrow in - * the button when appears-as-list is FALSE. */ - gtk_container_forall(GTK_CONTAINER(buttonChild), - moz_gtk_get_combo_box_button_inner_widgets, - NULL); - } else if(GTK_IS_ARROW(buttonChild)) { - /* appears-as-list = TRUE, or cell-view = FALSE; - * the button only contains an arrow */ - gParts->comboBoxArrowWidget = buttonChild; - g_object_add_weak_pointer(G_OBJECT(buttonChild), (gpointer) - &gParts->comboBoxArrowWidget); - gtk_widget_realize(gParts->comboBoxArrowWidget); - g_object_set_data(G_OBJECT(gParts->comboBoxArrowWidget), - "transparent-bg-hint", GINT_TO_POINTER(TRUE)); - } - } else { - /* Shouldn't be reached with current internal gtk implementation; we - * use a generic toggle button as last resort fallback to avoid - * crashing. */ - ensure_toggle_button_widget(); - gParts->comboBoxButtonWidget = gParts->toggleButtonWidget; - } - - if (!gParts->comboBoxArrowWidget) { - /* Shouldn't be reached with current internal gtk implementation; - * we gParts->buttonArrowWidget as last resort fallback to avoid - * crashing. */ - ensure_button_arrow_widget(); - gParts->comboBoxArrowWidget = gParts->buttonArrowWidget; - } - - /* We don't test the validity of gParts->comboBoxSeparatorWidget since there - * is none when "appears-as-list" = TRUE or "cell-view" = FALSE; if it - * is invalid we just won't paint it. */ - - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_progress_widget() -{ - if (!gParts->progresWidget) { - gParts->progresWidget = gtk_progress_bar_new(); - setup_widget_prototype(gParts->progresWidget); - } - return MOZ_GTK_SUCCESS; -} - -static gint -ensure_scrolled_window_widget() -{ - if (!gParts->scrolledWindowWidget) { - gParts->scrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL); - setup_widget_prototype(gParts->scrolledWindowWidget); - } - return MOZ_GTK_SUCCESS; -} - -static GtkStateType -ConvertGtkState(GtkWidgetState* state) -{ - if (state->disabled) - return GTK_STATE_INSENSITIVE; - else if (state->depressed) - return (state->inHover ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE); - else if (state->inHover) - return (state->active ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT); - else - return GTK_STATE_NORMAL; -} - -static gint -moz_gtk_button_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, GtkReliefStyle relief, - GtkWidget* widget, GtkTextDirection direction) -{ - GtkShadowType shadow_type; - GtkStyle* style = gtk_widget_get_style(widget); - GtkStateType button_state = ConvertGtkState(state); - gint x = rect->x, y=rect->y, width=rect->width, height=rect->height; - GdkWindow* window = gtk_widget_get_window(widget); - - gboolean interior_focus; - gint focus_width, focus_pad; - - moz_gtk_widget_get_focus(widget, &interior_focus, &focus_width, &focus_pad); - - if (window && gdk_window_is_visible(window)) { - gdk_window_set_background_pattern(window, NULL); - } - - gtk_widget_set_state(widget, button_state); - gtk_widget_set_direction(widget, direction); - gtk_button_set_relief(GTK_BUTTON(widget), relief); - - if (!interior_focus && state->focused) { - x += focus_width + focus_pad; - y += focus_width + focus_pad; - width -= 2 * (focus_width + focus_pad); - height -= 2 * (focus_width + focus_pad); - } - - shadow_type = button_state == GTK_STATE_ACTIVE || - state->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - - if (state->isDefault && relief == GTK_RELIEF_NORMAL) { - gtk_paint_box(style, cr, button_state, shadow_type, - widget, "buttondefault", x, y, width, height); - } - - if (relief != GTK_RELIEF_NONE || state->depressed || - (button_state != GTK_STATE_NORMAL && - button_state != GTK_STATE_INSENSITIVE)) { - /* the following line can trigger an assertion (Crux theme) - file ../../gdk/gdkwindow.c: line 1846 (gdk_window_clear_area): - assertion `GDK_IS_WINDOW (window)' failed */ - gtk_paint_box(style, cr, button_state, shadow_type, - widget, "button", x, y, width, height); - } - - if (state->focused) { - if (interior_focus) { - GtkStyle* style = gtk_widget_get_style(widget); - x += style->xthickness + focus_pad; - y += style->ythickness + focus_pad; - width -= 2 * (style->xthickness + focus_pad); - height -= 2 * (style->ythickness + focus_pad); - } else { - x -= focus_width + focus_pad; - y -= focus_width + focus_pad; - width += 2 * (focus_width + focus_pad); - height += 2 * (focus_width + focus_pad); - } - - gtk_paint_focus(style, cr, button_state, - widget, "button", x, y, width, height); - } - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_init() -{ - GtkWidgetClass *entry_class; - - is_initialized = TRUE; - have_arrow_scaling = (gtk_major_version > 2 || - (gtk_major_version == 2 && gtk_minor_version >= 12)); - - /* Add style property to GtkEntry. - * Adding the style property to the normal GtkEntry class means that it - * will work without issues inside GtkComboBox and for Spinbuttons. */ - entry_class = g_type_class_ref(GTK_TYPE_ENTRY); - gtk_widget_class_install_style_property(entry_class, - g_param_spec_boolean("honors-transparent-bg-hint", - "Transparent BG enabling flag", - "If TRUE, the theme is able to draw the GtkEntry on non-prefilled background.", - FALSE, - G_PARAM_READWRITE)); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_checkbox_get_metrics(gint* indicator_size, gint* indicator_spacing) -{ - ensure_checkbox_widget(); - - gtk_widget_style_get (gParts->checkboxWidget, - "indicator_size", indicator_size, - "indicator_spacing", indicator_spacing, - NULL); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_radio_get_metrics(gint* indicator_size, gint* indicator_spacing) -{ - ensure_radiobutton_widget(); - - gtk_widget_style_get (gParts->radiobuttonWidget, - "indicator_size", indicator_size, - "indicator_spacing", indicator_spacing, - NULL); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_widget_get_focus(GtkWidget* widget, gboolean* interior_focus, - gint* focus_width, gint* focus_pad) -{ - gtk_widget_style_get (widget, - "interior-focus", interior_focus, - "focus-line-width", focus_width, - "focus-padding", focus_pad, - NULL); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_button_get_inner_border(GtkWidget* widget, GtkBorder* inner_border) -{ - static const GtkBorder default_inner_border = { 1, 1, 1, 1 }; - GtkBorder *tmp_border; - - gtk_widget_style_get (widget, "inner-border", &tmp_border, NULL); - - if (tmp_border) { - *inner_border = *tmp_border; - gtk_border_free(tmp_border); - } - else - *inner_border = default_inner_border; - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_toggle_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, gboolean selected, - gboolean inconsistent, gboolean isradio, - GtkTextDirection direction) -{ - GtkStateType state_type = ConvertGtkState(state); - GtkShadowType shadow_type = (selected)?GTK_SHADOW_IN:GTK_SHADOW_OUT; - gint indicator_size, indicator_spacing; - gint x, y, width, height; - gint focus_x, focus_y, focus_width, focus_height; - GtkWidget *w; - GtkStyle *style; - - if (isradio) { - moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing); - w = gParts->radiobuttonWidget; - } else { - moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing); - w = gParts->checkboxWidget; - } - - // "GetMinimumWidgetSize was ignored" - // FIXME: This assert causes a build failure in WebKitGTK+ debug - // builds, because it uses 'false' in its definition. We may want - // to force this file to be built with g++, by renaming it. - // ASSERT(rect->width == indicator_size); - - /* - * vertically center in the box, since XUL sometimes ignores our - * GetMinimumWidgetSize in the vertical dimension - */ - x = rect->x; - y = rect->y + (rect->height - indicator_size) / 2; - width = indicator_size; - height = indicator_size; - - focus_x = x - indicator_spacing; - focus_y = y - indicator_spacing; - focus_width = width + 2 * indicator_spacing; - focus_height = height + 2 * indicator_spacing; - - style = gtk_widget_get_style(w); - - gtk_widget_set_sensitive(w, !state->disabled); - gtk_widget_set_direction(w, direction); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), selected); - - if (isradio) { - gtk_paint_option(style, cr, state_type, shadow_type, - gParts->radiobuttonWidget, "radiobutton", x, y, - width, height); - if (state->focused) { - gtk_paint_focus(style, cr, GTK_STATE_ACTIVE, - gParts->radiobuttonWidget, "radiobutton", focus_x, focus_y, - focus_width, focus_height); - } - } - else { - /* - * 'indeterminate' type on checkboxes. In GTK, the shadow type - * must also be changed for the state to be drawn. - */ - if (inconsistent) { - gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gParts->checkboxWidget), TRUE); - shadow_type = GTK_SHADOW_ETCHED_IN; - } else { - gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gParts->checkboxWidget), FALSE); - } - - gtk_paint_check(style, cr, state_type, shadow_type, - gParts->checkboxWidget, "checkbutton", x, y, width, height); - if (state->focused) { - gtk_paint_focus(style, cr, GTK_STATE_ACTIVE, - gParts->checkboxWidget, "checkbutton", focus_x, focus_y, - focus_width, focus_height); - } - } - - return MOZ_GTK_SUCCESS; -} - -static gint -calculate_button_inner_rect(GtkWidget* button, GdkRectangle* rect, - GdkRectangle* inner_rect, - GtkTextDirection direction, - gboolean ignore_focus) -{ - GtkBorder inner_border; - gboolean interior_focus; - gint focus_width, focus_pad; - GtkStyle* style; - - style = gtk_widget_get_style(button); - - /* This mirrors gtkbutton's child positioning */ - moz_gtk_button_get_inner_border(button, &inner_border); - moz_gtk_widget_get_focus(button, &interior_focus, - &focus_width, &focus_pad); - - if (ignore_focus) - focus_width = focus_pad = 0; - - inner_rect->x = rect->x + XTHICKNESS(style) + focus_width + focus_pad; - inner_rect->x += direction == GTK_TEXT_DIR_LTR ? - inner_border.left : inner_border.right; - inner_rect->y = rect->y + inner_border.top + YTHICKNESS(style) + - focus_width + focus_pad; - inner_rect->width = MAX(1, rect->width - inner_border.left - - inner_border.right - (XTHICKNESS(style) + focus_pad + focus_width) * 2); - inner_rect->height = MAX(1, rect->height - inner_border.top - - inner_border.bottom - (YTHICKNESS(style) + focus_pad + focus_width) * 2); - - return MOZ_GTK_SUCCESS; -} - - -static gint -calculate_arrow_rect(GtkWidget* arrow, GdkRectangle* rect, - GdkRectangle* arrow_rect, GtkTextDirection direction) -{ - /* defined in gtkarrow.c */ - gfloat arrow_scaling = 0.7; - gfloat xalign, xpad; - gint extent; - GtkMisc* misc = GTK_MISC(arrow); - gfloat misc_xalign, misc_yalign; - gint misc_xpad, misc_ypad; - - if (have_arrow_scaling) - gtk_widget_style_get(arrow, "arrow_scaling", &arrow_scaling, NULL); - - gtk_misc_get_padding(misc, &misc_xpad, &misc_ypad); - gtk_misc_get_alignment(misc, &misc_xalign, &misc_yalign); - - extent = MIN((rect->width - misc_xpad * 2), - (rect->height - misc_ypad * 2)) * arrow_scaling; - - xalign = direction == GTK_TEXT_DIR_LTR ? misc_xalign : 1.0 - misc_xalign; - xpad = misc_xpad + (rect->width - extent) * xalign; - - arrow_rect->x = direction == GTK_TEXT_DIR_LTR ? - floor(rect->x + xpad) : ceil(rect->x + xpad); - arrow_rect->y = floor(rect->y + misc_ypad + - ((rect->height - extent) * misc_yalign)); - - arrow_rect->width = arrow_rect->height = extent; - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_scrolled_window_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state) -{ - GtkStyle* style; - GtkAllocation allocation; - GtkWidget* widget; - - ensure_scrolled_window_widget(); - widget = gParts->scrolledWindowWidget; - - gtk_widget_get_allocation(widget, &allocation); - allocation.x = rect->x; - allocation.y = rect->y; - allocation.width = rect->width; - allocation.height = rect->height; - gtk_widget_set_allocation(widget, &allocation); - - style = gtk_widget_get_style(widget); - gtk_paint_shadow(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_IN, - widget, "scrolled_window", rect->x , rect->y, - rect->width, rect->height); - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_scrollbar_button_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, - GtkScrollbarButtonFlags flags, - GtkTextDirection direction) -{ - GtkStateType state_type = ConvertGtkState(state); - GtkShadowType shadow_type = (state->active) ? - GTK_SHADOW_IN : GTK_SHADOW_OUT; - GdkRectangle arrow_rect; - GtkStyle* style; - GtkWidget *scrollbar; - GtkAllocation allocation; - GtkArrowType arrow_type; - gint arrow_displacement_x, arrow_displacement_y; - const char* detail = (flags & MOZ_GTK_STEPPER_VERTICAL) ? - "vscrollbar" : "hscrollbar"; - - ensure_scrollbar_widget(); - - if (flags & MOZ_GTK_STEPPER_VERTICAL) - scrollbar = gParts->vertScrollbarWidget; - else - scrollbar = gParts->horizScrollbarWidget; - - gtk_widget_set_direction(scrollbar, direction); - - /* Some theme engines (i.e., ClearLooks) check the scrollbar's allocation - to determine where it should paint rounded corners on the buttons. - We need to trick them into drawing the buttons the way we want them. */ - - gtk_widget_get_allocation(scrollbar, &allocation); - allocation.x = rect->x; - allocation.y = rect->y; - allocation.width = rect->width; - allocation.height = rect->height; - - if (flags & MOZ_GTK_STEPPER_VERTICAL) { - allocation.height *= 5; - if (flags & MOZ_GTK_STEPPER_DOWN) { - arrow_type = GTK_ARROW_DOWN; - if (flags & MOZ_GTK_STEPPER_BOTTOM) - allocation.y -= 4 * rect->height; - else - allocation.y -= rect->height; - - } else { - arrow_type = GTK_ARROW_UP; - if (flags & MOZ_GTK_STEPPER_BOTTOM) - allocation.y -= 3 * rect->height; - } - } else { - allocation.width *= 5; - if (flags & MOZ_GTK_STEPPER_DOWN) { - arrow_type = GTK_ARROW_RIGHT; - if (flags & MOZ_GTK_STEPPER_BOTTOM) - allocation.x -= 4 * rect->width; - else - allocation.x -= rect->width; - } else { - arrow_type = GTK_ARROW_LEFT; - if (flags & MOZ_GTK_STEPPER_BOTTOM) - allocation.x -= 3 * rect->width; - } - } - - gtk_widget_set_allocation(scrollbar, &allocation); - style = gtk_widget_get_style(scrollbar); - - gtk_paint_box(style, cr, state_type, shadow_type, - scrollbar, detail, rect->x, rect->y, - rect->width, rect->height); - - arrow_rect.width = rect->width / 2; - arrow_rect.height = rect->height / 2; - arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2; - arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2; - - if (state_type == GTK_STATE_ACTIVE) { - gtk_widget_style_get(scrollbar, - "arrow-displacement-x", &arrow_displacement_x, - "arrow-displacement-y", &arrow_displacement_y, - NULL); - - arrow_rect.x += arrow_displacement_x; - arrow_rect.y += arrow_displacement_y; - } - - gtk_paint_arrow(style, cr, state_type, shadow_type, - scrollbar, detail, arrow_type, TRUE, arrow_rect.x, - arrow_rect.y, arrow_rect.width, arrow_rect.height); - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_scrollbar_trough_paint(GtkThemeWidgetType widget, - cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, - GtkTextDirection direction) -{ - GtkStyle* style; - GtkScrollbar *scrollbar; - - ensure_scrollbar_widget(); - - if (widget == MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL) - scrollbar = GTK_SCROLLBAR(gParts->horizScrollbarWidget); - else - scrollbar = GTK_SCROLLBAR(gParts->vertScrollbarWidget); - - gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction); - - style = gtk_widget_get_style(GTK_WIDGET(scrollbar)); - - gtk_paint_box(style, cr, GTK_STATE_ACTIVE, GTK_SHADOW_IN, - GTK_WIDGET(scrollbar), "trough", rect->x, rect->y, - rect->width, rect->height); - - if (state->focused) { - gtk_paint_focus(style, cr, GTK_STATE_ACTIVE, - GTK_WIDGET(scrollbar), "trough", - rect->x, rect->y, rect->width, rect->height); - } - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_scrollbar_thumb_paint(GtkThemeWidgetType widget, - cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, - GtkTextDirection direction) -{ - GtkStateType state_type = (state->inHover || state->active) ? - GTK_STATE_PRELIGHT : GTK_STATE_NORMAL; - GtkShadowType shadow_type = GTK_SHADOW_OUT; - GtkStyle* style; - GtkScrollbar *scrollbar; - GtkAdjustment *adj; - - ensure_scrollbar_widget(); - - if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) - scrollbar = GTK_SCROLLBAR(gParts->horizScrollbarWidget); - else - scrollbar = GTK_SCROLLBAR(gParts->vertScrollbarWidget); - - gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction); - - /* Make sure to set the scrollbar range before painting so that - everything is drawn properly. At least the bluecurve (and - maybe other) themes don't draw the top or bottom black line - surrounding the scrollbar if the theme thinks that it's butted - up against the scrollbar arrows. Note the increases of the - clip rect below. */ - adj = gtk_range_get_adjustment(GTK_RANGE(scrollbar)); - - if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) { - gtk_adjustment_set_page_size(adj, rect->width); - } - else { - gtk_adjustment_set_page_size(adj, rect->height); - } - - gtk_adjustment_configure(adj, - state->curpos, - 0, - state->maxpos, - gtk_adjustment_get_step_increment(adj), - gtk_adjustment_get_page_increment(adj), - gtk_adjustment_get_page_size(adj)); - - style = gtk_widget_get_style(GTK_WIDGET(scrollbar)); - - gtk_paint_slider(style, cr, state_type, shadow_type, - GTK_WIDGET(scrollbar), "slider", rect->x, rect->y, - rect->width, rect->height, - (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ? - GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_entry_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, GtkWidget* widget, - GtkTextDirection direction) -{ - GtkStateType bg_state = state->disabled ? - GTK_STATE_INSENSITIVE : GTK_STATE_NORMAL; - gint x, y, width = rect->width, height = rect->height; - GtkStyle* style; - gboolean interior_focus; - gboolean theme_honors_transparency = FALSE; - gint focus_width; - - gtk_widget_set_direction(widget, direction); - - style = gtk_widget_get_style(widget); - - gtk_widget_style_get(widget, - "interior-focus", &interior_focus, - "focus-line-width", &focus_width, - "honors-transparent-bg-hint", &theme_honors_transparency, - NULL); - - /* gtkentry.c uses two windows, one for the entire widget and one for the - * text area inside it. The background of both windows is set to the "base" - * color of the new state in gtk_entry_state_changed, but only the inner - * textarea window uses gtk_paint_flat_box when exposed */ - - /* This gets us a lovely greyish disabledish look */ - gtk_widget_set_sensitive(widget, !state->disabled); - - /* GTK fills the outer widget window with the base color before drawing the widget. - * Some older themes rely on this behavior, but many themes nowadays use rounded - * corners on their widgets. While most GTK apps are blissfully unaware of this - * problem due to their use of the default window background, we render widgets on - * many kinds of backgrounds on the web. - * If the theme is able to cope with transparency, then we can skip pre-filling - * and notify the theme it will paint directly on the canvas. */ - if (theme_honors_transparency) { - g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(TRUE)); - } else { - cairo_save(cr); - gdk_cairo_set_source_color(cr, (const GdkColor*)&style->base[bg_state]); - cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); - cairo_fill(cr); - cairo_restore(cr); - g_object_set_data(G_OBJECT(widget), "transparent-bg-hint", GINT_TO_POINTER(FALSE)); - } - - /* Get the position of the inner window, see _gtk_entry_get_borders */ - x = XTHICKNESS(style); - y = YTHICKNESS(style); - - if (!interior_focus) { - x += focus_width; - y += focus_width; - } - - /* Simulate an expose of the inner window */ - gtk_paint_flat_box(style, cr, bg_state, GTK_SHADOW_NONE, - widget, "entry_bg", rect->x + x, - rect->y + y, rect->width - 2*x, rect->height - 2*y); - - /* Now paint the shadow and focus border. - * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad - * smaller when focused if the focus is not interior, then the focus. */ - x = rect->x; - y = rect->y; - - if (state->focused && !state->disabled) { - /* This will get us the lit borders that focused textboxes enjoy on - * some themes. */ - if (!interior_focus) { - /* Indent the border a little bit if we have exterior focus - (this is what GTK does to draw native entries) */ - x += focus_width; - y += focus_width; - width -= 2 * focus_width; - height -= 2 * focus_width; - } - } - - gtk_paint_shadow(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_IN, - widget, "entry", x, y, width, height); - - if (state->focused && !state->disabled) { - if (!interior_focus) { - gtk_paint_focus(style, cr, GTK_STATE_NORMAL, - widget, "entry", - rect->x, rect->y, rect->width, rect->height); - } - } - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_combo_box_paint(cairo_t* cr, GdkRectangle* rect, - GtkWidgetState* state, gboolean ishtml, - GtkTextDirection direction) -{ - GdkRectangle arrow_rect, real_arrow_rect; - gint /* arrow_size, */ separator_width; - gboolean wide_separators; - GtkStateType state_type = ConvertGtkState(state); - GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT; - GtkStyle* style; - GtkRequisition arrow_req; - - ensure_combo_box_widgets(); - - /* Also sets the direction on gParts->comboBoxButtonWidget, which is then - * inherited by the separator and arrow */ - moz_gtk_button_paint(cr, rect, state, GTK_RELIEF_NORMAL, - gParts->comboBoxButtonWidget, direction); - - calculate_button_inner_rect(gParts->comboBoxButtonWidget, - rect, &arrow_rect, direction, ishtml); - /* Now arrow_rect contains the inner rect ; we want to correct the width - * to what the arrow needs (see gtk_combo_box_size_allocate) */ - gtk_widget_get_preferred_size(gParts->comboBoxArrowWidget, &arrow_req, NULL); - if (direction == GTK_TEXT_DIR_LTR) - arrow_rect.x += arrow_rect.width - arrow_req.width; - arrow_rect.width = arrow_req.width; - - calculate_arrow_rect(gParts->comboBoxArrowWidget, - &arrow_rect, &real_arrow_rect, direction); - - style = gtk_widget_get_style(gParts->comboBoxArrowWidget); - - gtk_widget_size_allocate(gParts->comboBoxWidget, rect); - - gtk_paint_arrow(style, cr, state_type, shadow_type, - gParts->comboBoxArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE, - real_arrow_rect.x, real_arrow_rect.y, - real_arrow_rect.width, real_arrow_rect.height); - - - /* If there is no separator in the theme, there's nothing left to do. */ - if (!gParts->comboBoxSeparatorWidget) - return MOZ_GTK_SUCCESS; - - style = gtk_widget_get_style(gParts->comboBoxSeparatorWidget); - - gtk_widget_style_get(gParts->comboBoxSeparatorWidget, - "wide-separators", &wide_separators, - "separator-width", &separator_width, - NULL); - - if (wide_separators) { - if (direction == GTK_TEXT_DIR_LTR) - arrow_rect.x -= separator_width; - else - arrow_rect.x += arrow_rect.width; - - gtk_paint_box(style, cr, - GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT, - gParts->comboBoxSeparatorWidget, "vseparator", - arrow_rect.x, arrow_rect.y, - separator_width, arrow_rect.height); - } else { - if (direction == GTK_TEXT_DIR_LTR) - arrow_rect.x -= XTHICKNESS(style); - else - arrow_rect.x += arrow_rect.width; - - gtk_paint_vline(style, cr, GTK_STATE_NORMAL, - gParts->comboBoxSeparatorWidget, "vseparator", - arrow_rect.y, arrow_rect.y + arrow_rect.height, - arrow_rect.x); - } - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_progressbar_paint(cairo_t* cr, GdkRectangle* rect, - GtkTextDirection direction) -{ - GtkStyle* style; - - ensure_progress_widget(); - gtk_widget_set_direction(gParts->progresWidget, direction); - - style = gtk_widget_get_style(gParts->progresWidget); - - gtk_paint_box(style, cr, GTK_STATE_NORMAL, GTK_SHADOW_IN, - gParts->progresWidget, "trough", rect->x, rect->y, - rect->width, rect->height); - - return MOZ_GTK_SUCCESS; -} - -static gint -moz_gtk_progress_chunk_paint(cairo_t* cr, GdkRectangle* rect, - GtkTextDirection direction) -{ - GtkStyle* style; - - ensure_progress_widget(); - gtk_widget_set_direction(gParts->progresWidget, direction); - - style = gtk_widget_get_style(gParts->progresWidget); - - gtk_paint_box(style, cr, GTK_STATE_PRELIGHT, GTK_SHADOW_OUT, - gParts->progresWidget, "bar", rect->x, rect->y, - rect->width, rect->height); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, - gint* right, gint* bottom, GtkTextDirection direction, - gboolean inhtml) -{ - GtkWidget* w; - GtkStyle *style; - - switch (widget) { - case MOZ_GTK_BUTTON: - { - GtkBorder inner_border; - gboolean interior_focus; - gint focus_width, focus_pad; - GtkStyle *style; - - ensure_button_widget(); - *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gParts->buttonWidget)); - - /* Don't add this padding in HTML, otherwise the buttons will - become too big and stuff the layout. */ - if (!inhtml) { - moz_gtk_widget_get_focus(gParts->buttonWidget, &interior_focus, &focus_width, &focus_pad); - moz_gtk_button_get_inner_border(gParts->buttonWidget, &inner_border); - *left += focus_width + focus_pad + inner_border.left; - *right += focus_width + focus_pad + inner_border.right; - *top += focus_width + focus_pad + inner_border.top; - *bottom += focus_width + focus_pad + inner_border.bottom; - } - - style = gtk_widget_get_style(gParts->buttonWidget); - *left += style->xthickness; - *right += style->xthickness; - *top += style->ythickness; - *bottom += style->ythickness; - return MOZ_GTK_SUCCESS; - } - case MOZ_GTK_ENTRY: - ensure_entry_widget(); - w = gParts->entryWidget; - break; - case MOZ_GTK_DROPDOWN: - { - /* We need to account for the arrow on the dropdown, so text - * doesn't come too close to the arrow, or in some cases spill - * into the arrow. */ - gboolean ignored_interior_focus, wide_separators; - gint focus_width, focus_pad, separator_width; - GtkRequisition arrow_req; - GtkStyle* style; - - ensure_combo_box_widgets(); - - *left = gtk_container_get_border_width(GTK_CONTAINER(gParts->comboBoxButtonWidget)); - - if (!inhtml) { - moz_gtk_widget_get_focus(gParts->comboBoxButtonWidget, - &ignored_interior_focus, - &focus_width, &focus_pad); - *left += focus_width + focus_pad; - } - - style = gtk_widget_get_style(gParts->comboBoxButtonWidget); - *top = *left + style->ythickness; - *left += style->xthickness; - - *right = *left; *bottom = *top; - - /* If there is no separator, don't try to count its width. */ - separator_width = 0; - if (gParts->comboBoxSeparatorWidget) { - gtk_widget_style_get(gParts->comboBoxSeparatorWidget, - "wide-separators", &wide_separators, - "separator-width", &separator_width, - NULL); - - if (!wide_separators) - separator_width = - XTHICKNESS(style); - } - - gtk_widget_get_preferred_size(gParts->comboBoxArrowWidget, &arrow_req, NULL); - if (direction == GTK_TEXT_DIR_RTL) - *left += separator_width + arrow_req.width; - else - *right += separator_width + arrow_req.width; - - return MOZ_GTK_SUCCESS; - } - case MOZ_GTK_PROGRESSBAR: - ensure_progress_widget(); - w = gParts->progresWidget; - break; - /* These widgets have no borders, since they are not containers. */ - case MOZ_GTK_CHECKBUTTON: - case MOZ_GTK_RADIOBUTTON: - case MOZ_GTK_SCROLLBAR_BUTTON: - case MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL: - case MOZ_GTK_SCROLLBAR_TRACK_VERTICAL: - case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL: - case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL: - case MOZ_GTK_PROGRESS_CHUNK: - *left = *top = *right = *bottom = 0; - return MOZ_GTK_SUCCESS; - default: - g_warning("Unsupported widget type: %d", widget); - return MOZ_GTK_UNKNOWN_WIDGET; - } - - style = gtk_widget_get_style(w); - *right = *left = XTHICKNESS(style); - *bottom = *top = YTHICKNESS(style); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_get_scrollbar_metrics(MozGtkScrollbarMetrics *metrics) -{ - ensure_scrollbar_widget(); - - gtk_widget_style_get (gParts->horizScrollbarWidget, - "slider_width", &metrics->slider_width, - "trough_border", &metrics->trough_border, - "stepper_size", &metrics->stepper_size, - "stepper_spacing", &metrics->stepper_spacing, - "trough_under_steppers", &metrics->trough_under_steppers, - "has_secondary_forward_stepper", &metrics->has_secondary_forward_stepper, - "has_secondary_backward_stepper", &metrics->has_secondary_backward_stepper, - NULL); - - metrics->min_slider_size = gtk_range_get_min_slider_size(GTK_RANGE(gParts->horizScrollbarWidget)); - - return MOZ_GTK_SUCCESS; -} - -gint -moz_gtk_widget_paint(GtkThemeWidgetType widget, cairo_t* cr, - GdkRectangle* rect, GtkWidgetState* state, - gint flags, GtkTextDirection direction) -{ - switch (widget) { - case MOZ_GTK_BUTTON: - if (state->depressed) { - ensure_toggle_button_widget(); - return moz_gtk_button_paint(cr, rect, state, - (GtkReliefStyle) flags, - gParts->toggleButtonWidget, direction); - } - ensure_button_widget(); - return moz_gtk_button_paint(cr, rect, state, - (GtkReliefStyle) flags, gParts->buttonWidget, - direction); - break; - case MOZ_GTK_CHECKBUTTON: - case MOZ_GTK_RADIOBUTTON: - return moz_gtk_toggle_paint(cr, rect, state, - !!(flags & MOZ_GTK_WIDGET_CHECKED), - !!(flags & MOZ_GTK_WIDGET_INCONSISTENT), - (widget == MOZ_GTK_RADIOBUTTON), - direction); - break; - case MOZ_GTK_SCROLLBAR_BUTTON: - return moz_gtk_scrollbar_button_paint(cr, rect, state, - (GtkScrollbarButtonFlags) flags, - direction); - break; - case MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL: - case MOZ_GTK_SCROLLBAR_TRACK_VERTICAL: - return moz_gtk_scrollbar_trough_paint(widget, cr, rect, - state, direction); - break; - case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL: - case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL: - return moz_gtk_scrollbar_thumb_paint(widget, cr, rect, - state, direction); - break; - case MOZ_GTK_SCROLLED_WINDOW: - return moz_gtk_scrolled_window_paint(cr, rect, state); - break; - case MOZ_GTK_ENTRY: - ensure_entry_widget(); - return moz_gtk_entry_paint(cr, rect, state, - gParts->entryWidget, direction); - break; - case MOZ_GTK_DROPDOWN: - return moz_gtk_combo_box_paint(cr, rect, state, - (gboolean) flags, direction); - break; - case MOZ_GTK_PROGRESSBAR: - return moz_gtk_progressbar_paint(cr, rect, direction); - break; - case MOZ_GTK_PROGRESS_CHUNK: - return moz_gtk_progress_chunk_paint(cr, rect, direction); - break; - default: - g_warning("Unknown widget type: %d", widget); - } - - return MOZ_GTK_UNKNOWN_WIDGET; -} - -GtkWidget* moz_gtk_get_scrollbar_widget(void) -{ - if (!is_initialized) - return NULL; - ensure_scrollbar_widget(); - return gParts->horizScrollbarWidget; -} - -gint -moz_gtk_shutdown() -{ - GtkWidgetClass *entry_class; - entry_class = g_type_class_peek(GTK_TYPE_ENTRY); - g_type_class_unref(entry_class); - - is_initialized = FALSE; - - return MOZ_GTK_SUCCESS; -} - -void moz_gtk_destroy_theme_parts_widgets(GtkThemeParts* parts) -{ - if (!parts) - return; - - if (parts->protoWindow) { - gtk_widget_destroy(parts->protoWindow); - parts->protoWindow = NULL; - } -} - -GtkWidget* moz_gtk_get_progress_widget() -{ - if (!is_initialized) - return NULL; - ensure_progress_widget(); - return gParts->progresWidget; -} - -#endif // GTK_API_VERSION_2 diff --git a/Source/WebCore/platform/gtk/gtkdrawing.h b/Source/WebCore/platform/gtk/gtkdrawing.h index 9d13a07..412a1f7 100644 --- a/Source/WebCore/platform/gtk/gtkdrawing.h +++ b/Source/WebCore/platform/gtk/gtkdrawing.h @@ -81,9 +81,7 @@ typedef struct { } MozGtkScrollbarMetrics; typedef struct _GtkThemeParts { -#ifdef GTK_API_VERSION_2 GdkColormap* colormap; -#endif // GTK_API_VERSION_2 GtkWidget* protoWindow; GtkWidget* protoLayout; GtkWidget* buttonWidget; @@ -205,18 +203,11 @@ void moz_gtk_destroy_theme_parts_widgets(GtkThemeParts* parts); * flags: widget-dependant flags; see the GtkThemeWidgetType definition. * direction: the text direction, to draw the widget correctly LTR and RTL. */ -#ifdef GTK_API_VERSION_2 gint moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable, GdkRectangle* rect, GdkRectangle* cliprect, GtkWidgetState* state, gint flags, GtkTextDirection direction); -#else -gint -moz_gtk_widget_paint(GtkThemeWidgetType widget, cairo_t* cr, - GdkRectangle* rect, GtkWidgetState* state, - gint flags, GtkTextDirection direction); -#endif /*** Widget metrics ***/ /** diff --git a/Source/WebCore/platform/haiku/DragDataHaiku.cpp b/Source/WebCore/platform/haiku/DragDataHaiku.cpp index 7c2dc9c..5069c6f 100644 --- a/Source/WebCore/platform/haiku/DragDataHaiku.cpp +++ b/Source/WebCore/platform/haiku/DragDataHaiku.cpp @@ -63,7 +63,7 @@ bool DragData::containsPlainText() const return false; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { notImplemented(); return String(); @@ -80,19 +80,19 @@ bool DragData::containsCompatibleContent() const return containsColor() || containsURL() || containsPlainText(); } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { notImplemented(); return false; } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { notImplemented(); return String(); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame*, PassRefPtr<Range>, bool, bool&) const { notImplemented(); return 0; diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp index 8491da9..17208b5 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -108,7 +108,7 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO #if !PLATFORM(SKIA) -RGBA32Buffer::RGBA32Buffer() +ImageFrame::ImageFrame() : m_hasAlpha(false) , m_status(FrameEmpty) , m_duration(0) @@ -117,7 +117,7 @@ RGBA32Buffer::RGBA32Buffer() { } -RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) +ImageFrame& ImageFrame::operator=(const ImageFrame& other) { if (this == &other) return *this; @@ -131,7 +131,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) return *this; } -void RGBA32Buffer::clear() +void ImageFrame::clear() { m_backingStore.clear(); m_bytes = 0; @@ -142,7 +142,7 @@ void RGBA32Buffer::clear() // later. } -void RGBA32Buffer::zeroFill() +void ImageFrame::zeroFill() { memset(m_bytes, 0, m_size.width() * m_size.height() * sizeof(PixelData)); m_hasAlpha = true; @@ -150,13 +150,13 @@ void RGBA32Buffer::zeroFill() #if !PLATFORM(CG) -void RGBA32Buffer::copyReferenceToBitmapData(const RGBA32Buffer& other) +void ImageFrame::copyReferenceToBitmapData(const ImageFrame& other) { ASSERT(this != &other); copyBitmapData(other); } -bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) +bool ImageFrame::copyBitmapData(const ImageFrame& other) { if (this == &other) return true; @@ -168,7 +168,7 @@ bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) return true; } -bool RGBA32Buffer::setSize(int newWidth, int newHeight) +bool ImageFrame::setSize(int newWidth, int newHeight) { // NOTE: This has no way to check for allocation failure if the requested // size was too big... @@ -184,32 +184,32 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight) #endif -bool RGBA32Buffer::hasAlpha() const +bool ImageFrame::hasAlpha() const { return m_hasAlpha; } -void RGBA32Buffer::setHasAlpha(bool alpha) +void ImageFrame::setHasAlpha(bool alpha) { m_hasAlpha = alpha; } -void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile) +void ImageFrame::setColorProfile(const ColorProfile& colorProfile) { m_colorProfile = colorProfile; } -void RGBA32Buffer::setStatus(FrameStatus status) +void ImageFrame::setStatus(FrameStatus status) { m_status = status; } -int RGBA32Buffer::width() const +int ImageFrame::width() const { return m_size.width(); } -int RGBA32Buffer::height() const +int ImageFrame::height() const { return m_size.height(); } diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h index c3d73c0..13069de 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h @@ -50,10 +50,10 @@ namespace WebCore { // FIXME: Do we want better encapsulation? typedef Vector<char> ColorProfile; - // The RGBA32Buffer object represents the decoded image data in RGBA32 + // The ImageFrame object represents the decoded image data in RGBA32 // format. This buffer is what all decoders write a single frame into. // Frames are then instantiated for drawing by being handed this buffer. - class RGBA32Buffer { + class ImageFrame { public: enum FrameStatus { FrameEmpty, FramePartial, FrameComplete }; enum FrameDisposalMethod { @@ -72,13 +72,13 @@ namespace WebCore { typedef unsigned PixelData; #endif - RGBA32Buffer(); + ImageFrame(); - RGBA32Buffer(const RGBA32Buffer& other) { operator=(other); } + ImageFrame(const ImageFrame& other) { operator=(other); } // For backends which refcount their data, this operator doesn't need to // create a new copy of the image data, only increase the ref count. - RGBA32Buffer& operator=(const RGBA32Buffer& other); + ImageFrame& operator=(const ImageFrame& other); // Deletes the pixel data entirely; used by ImageDecoder to save memory // when we no longer need to display a frame and only need its metadata. @@ -89,11 +89,11 @@ namespace WebCore { // Creates a new copy of the image data in |other|, so the two images // can be modified independently. Returns whether the copy succeeded. - bool copyBitmapData(const RGBA32Buffer&); + bool copyBitmapData(const ImageFrame&); // Creates a new reference to the image data in |other|. The two images // share a common backing store. - void copyReferenceToBitmapData(const RGBA32Buffer&); + void copyReferenceToBitmapData(const ImageFrame&); // Copies the pixel data at [(startX, startY), (endX, startY)) to the // same X-coordinates on each subsequent row up to but not including @@ -317,10 +317,10 @@ namespace WebCore { // The number of repetitions to perform for an animation loop. virtual int repetitionCount() const { return cAnimationNone; } - // Called to obtain the RGBA32Buffer full of decoded data for rendering. + // Called to obtain the ImageFrame full of decoded data for rendering. // The decoder plugin will decode as much of the frame as it can before // handing back the buffer. - virtual RGBA32Buffer* frameBufferAtIndex(size_t) = 0; + virtual ImageFrame* frameBufferAtIndex(size_t) = 0; // Whether or not the underlying image format even supports alpha // transparency. @@ -364,7 +364,7 @@ namespace WebCore { int scaledY(int origY, int searchStart = 0); RefPtr<SharedBuffer> m_data; // The encoded data. - Vector<RGBA32Buffer> m_frameBufferCache; + Vector<ImageFrame> m_frameBufferCache; ColorProfile m_colorProfile; bool m_scaled; Vector<int> m_scaledColumns; diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp b/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp index 220a1ed..0d0e8a7 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.cpp @@ -65,7 +65,7 @@ bool BMPImageDecoder::isSizeAvailable() return ImageDecoder::isSizeAvailable(); } -RGBA32Buffer* BMPImageDecoder::frameBufferAtIndex(size_t index) +ImageFrame* BMPImageDecoder::frameBufferAtIndex(size_t index) { if (index) return 0; @@ -75,8 +75,8 @@ RGBA32Buffer* BMPImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache.first().setPremultiplyAlpha(m_premultiplyAlpha); } - RGBA32Buffer* buffer = &m_frameBufferCache.first(); - if (buffer->status() != RGBA32Buffer::FrameComplete) + ImageFrame* buffer = &m_frameBufferCache.first(); + if (buffer->status() != ImageFrame::FrameComplete) decode(false); return buffer; } @@ -98,7 +98,7 @@ void BMPImageDecoder::decode(bool onlySize) setFailed(); // If we're done decoding the image, we don't need the BMPImageReader // anymore. (If we failed, |m_reader| has already been cleared.) - else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status() == RGBA32Buffer::FrameComplete)) + else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status() == ImageFrame::FrameComplete)) m_reader.clear(); } diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h b/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h index 5f4ed82..f5b9d5e 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageDecoder.h @@ -45,7 +45,7 @@ namespace WebCore { virtual String filenameExtension() const { return "bmp"; } virtual void setData(SharedBuffer*, bool allDataReceived); virtual bool isSizeAvailable(); - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid // accessing deleted memory, especially when calling this from inside // BMPImageReader! diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp index 93bedf3..1805bc7 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.cpp @@ -77,10 +77,10 @@ bool BMPImageReader::decodeBMP(bool onlySize) // Initialize the framebuffer if needed. ASSERT(m_buffer); // Parent should set this before asking us to decode! - if (m_buffer->status() == RGBA32Buffer::FrameEmpty) { + if (m_buffer->status() == ImageFrame::FrameEmpty) { if (!m_buffer->setSize(m_parent->size().width(), m_parent->size().height())) return m_parent->setFailed(); // Unable to allocate. - m_buffer->setStatus(RGBA32Buffer::FramePartial); + m_buffer->setStatus(ImageFrame::FramePartial); // setSize() calls eraseARGB(), which resets the alpha flag, so we force // it back to false here. We'll set it true below in all cases where // these 0s could actually show through. @@ -122,7 +122,7 @@ bool BMPImageReader::decodeBMP(bool onlySize) } // Done! - m_buffer->setStatus(RGBA32Buffer::FrameComplete); + m_buffer->setStatus(ImageFrame::FrameComplete); return true; } diff --git a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h index 0a6dc84..dfaa9ec 100644 --- a/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h +++ b/Source/WebCore/platform/image-decoders/bmp/BMPImageReader.h @@ -64,11 +64,11 @@ namespace WebCore { // |parent| is the decoder that owns us. // |startOffset| points to the start of the BMP within the file. - // |buffer| points at an empty RGBA32Buffer that we'll initialize and + // |buffer| points at an empty ImageFrame that we'll initialize and // fill with decoded data. BMPImageReader(ImageDecoder* parent, size_t decodedAndHeaderOffset, size_t imgDataOffset, bool usesAndMask); - void setBuffer(RGBA32Buffer* buffer) { m_buffer = buffer; } + void setBuffer(ImageFrame* buffer) { m_buffer = buffer; } void setData(SharedBuffer* data) { m_data = data; } // Does the actual decoding. If |onlySize| is true, decoding only @@ -274,7 +274,7 @@ namespace WebCore { ImageDecoder* m_parent; // The destination for the pixel data. - RGBA32Buffer* m_buffer; + ImageFrame* m_buffer; // The file to decode. RefPtr<SharedBuffer> m_data; diff --git a/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp b/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp index d741882..618c1d0 100644 --- a/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp +++ b/Source/WebCore/platform/image-decoders/cairo/ImageDecoderCairo.cpp @@ -30,7 +30,7 @@ namespace WebCore { -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { return cairo_image_surface_create_for_data( reinterpret_cast<unsigned char*>(const_cast<PixelData*>( diff --git a/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp b/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp index 03b4c8f..0b90107 100644 --- a/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp +++ b/Source/WebCore/platform/image-decoders/cg/ImageDecoderCG.cpp @@ -33,22 +33,22 @@ namespace WebCore { -static RGBA32Buffer::PixelData* getPtrAsPixelData(CFMutableDataRef data) +static ImageFrame::PixelData* getPtrAsPixelData(CFMutableDataRef data) { - return data ? reinterpret_cast<RGBA32Buffer::PixelData*>(CFDataGetMutableBytePtr(data)) : 0; + return data ? reinterpret_cast<ImageFrame::PixelData*>(CFDataGetMutableBytePtr(data)) : 0; } -void RGBA32Buffer::copyReferenceToBitmapData(const RGBA32Buffer& other) +void ImageFrame::copyReferenceToBitmapData(const ImageFrame& other) { ASSERT(this != &other); m_backingStore = other.m_backingStore; m_bytes = getPtrAsPixelData(m_backingStore.get()); - // FIXME: The rest of this function seems redundant with RGBA32Buffer::copyBitmapData. + // FIXME: The rest of this function seems redundant with ImageFrame::copyBitmapData. m_size = other.m_size; setHasAlpha(other.m_hasAlpha); } -bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) +bool ImageFrame::copyBitmapData(const ImageFrame& other) { if (this == &other) return true; @@ -60,7 +60,7 @@ bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) return true; } -bool RGBA32Buffer::setSize(int newWidth, int newHeight) +bool ImageFrame::setSize(int newWidth, int newHeight) { ASSERT(!m_backingStore); size_t backingStoreSize = newWidth * newHeight * sizeof(PixelData); @@ -91,7 +91,7 @@ static CGColorSpaceRef createColorSpace(const ColorProfile& colorProfile) #endif } -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, createColorSpace(m_colorProfile)); RetainPtr<CGDataProviderRef> dataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_backingStore.get())); diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index e92f264..e6de597 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -118,13 +118,13 @@ int GIFImageDecoder::repetitionCount() const return m_repetitionCount; } -RGBA32Buffer* GIFImageDecoder::frameBufferAtIndex(size_t index) +ImageFrame* GIFImageDecoder::frameBufferAtIndex(size_t index) { if (index >= frameCount()) return 0; - RGBA32Buffer& frame = m_frameBufferCache[index]; - if (frame.status() != RGBA32Buffer::FrameComplete) + ImageFrame& frame = m_frameBufferCache[index]; + if (frame.status() != ImageFrame::FrameComplete) decode(index + 1, GIFFullQuery); return &frame; } @@ -151,7 +151,7 @@ void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) // always use ImageSource::clear(true, ...) to completely free the memory in // this case. clearBeforeFrame = std::min(clearBeforeFrame, m_frameBufferCache.size() - 1); - const Vector<RGBA32Buffer>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame); + const Vector<ImageFrame>::iterator end(m_frameBufferCache.begin() + clearBeforeFrame); // We need to preserve frames such that: // * We don't clear |end| @@ -171,16 +171,16 @@ void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) // * If the frame is partial, we're decoding it, so don't clear it; if it // has a disposal method other than DisposeOverwritePrevious, stop // scanning, as we'll only need this frame when decoding the next one. - Vector<RGBA32Buffer>::iterator i(end); - for (; (i != m_frameBufferCache.begin()) && ((i->status() == RGBA32Buffer::FrameEmpty) || (i->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)); --i) { - if ((i->status() == RGBA32Buffer::FrameComplete) && (i != end)) + Vector<ImageFrame>::iterator i(end); + for (; (i != m_frameBufferCache.begin()) && ((i->status() == ImageFrame::FrameEmpty) || (i->disposalMethod() == ImageFrame::DisposeOverwritePrevious)); --i) { + if ((i->status() == ImageFrame::FrameComplete) && (i != end)) i->clear(); } // Now |i| holds the last frame we need to preserve; clear prior frames. - for (Vector<RGBA32Buffer>::iterator j(m_frameBufferCache.begin()); j != i; ++j) { - ASSERT(j->status() != RGBA32Buffer::FramePartial); - if (j->status() != RGBA32Buffer::FrameEmpty) + for (Vector<ImageFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j) { + ASSERT(j->status() != ImageFrame::FramePartial); + if (j->status() != ImageFrame::FrameEmpty) j->clear(); } } @@ -220,8 +220,8 @@ bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, unsigned char* rowBuff return true; // Initialize the frame if necessary. - RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; - if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) + ImageFrame& buffer = m_frameBufferCache[frameIndex]; + if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex)) return false; // Write one row's worth of data into the frame. @@ -251,15 +251,15 @@ bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, unsigned char* rowBuff return true; } -bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod) +bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, ImageFrame::FrameDisposalMethod disposalMethod) { // Initialize the frame if necessary. Some GIFs insert do-nothing frames, // in which case we never reach haveDecodedRow() before getting here. - RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; - if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex)) + ImageFrame& buffer = m_frameBufferCache[frameIndex]; + if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameIndex)) return false; // initFrameBuffer() has already called setFailed(). - buffer.setStatus(RGBA32Buffer::FrameComplete); + buffer.setStatus(ImageFrame::FrameComplete); buffer.setDuration(frameDuration); buffer.setDisposalMethod(disposalMethod); @@ -277,8 +277,8 @@ bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, // First skip over prior DisposeOverwritePrevious frames (since they // don't affect the start state of this frame) the same way we do in // initFrameBuffer(). - const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex]; - while (frameIndex && (prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwritePrevious)) + const ImageFrame* prevBuffer = &m_frameBufferCache[--frameIndex]; + while (frameIndex && (prevBuffer->disposalMethod() == ImageFrame::DisposeOverwritePrevious)) prevBuffer = &m_frameBufferCache[--frameIndex]; // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then @@ -289,7 +289,7 @@ bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, // The only remaining case is a DisposeOverwriteBgcolor frame. If // it had no alpha, and its rect is contained in the current frame's // rect, we know the current frame has no alpha. - if ((prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwriteBgcolor) && !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect())) + if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor) && !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect())) buffer.setHasAlpha(false); } } @@ -332,7 +332,7 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) if (frameRect.bottom() > size().height()) frameRect.setHeight(size().height() - frameReader->y_offset); - RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex]; + ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; int left = upperBoundScaledX(frameRect.x()); int right = lowerBoundScaledX(frameRect.right(), left); int top = upperBoundScaledY(frameRect.y()); @@ -352,15 +352,15 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) // the starting state of the previous frame, so skip over them. (If the // first frame specifies this method, it will get treated like // DisposeOverwriteBgcolor below and reset to a completely empty image.) - const RGBA32Buffer* prevBuffer = &m_frameBufferCache[--frameIndex]; - RGBA32Buffer::FrameDisposalMethod prevMethod = prevBuffer->disposalMethod(); - while (frameIndex && (prevMethod == RGBA32Buffer::DisposeOverwritePrevious)) { + const ImageFrame* prevBuffer = &m_frameBufferCache[--frameIndex]; + ImageFrame::FrameDisposalMethod prevMethod = prevBuffer->disposalMethod(); + while (frameIndex && (prevMethod == ImageFrame::DisposeOverwritePrevious)) { prevBuffer = &m_frameBufferCache[--frameIndex]; prevMethod = prevBuffer->disposalMethod(); } - ASSERT(prevBuffer->status() == RGBA32Buffer::FrameComplete); + ASSERT(prevBuffer->status() == ImageFrame::FrameComplete); - if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) || (prevMethod == RGBA32Buffer::DisposeKeep)) { + if ((prevMethod == ImageFrame::DisposeNotSpecified) || (prevMethod == ImageFrame::DisposeKeep)) { // Preserve the last frame as the starting state for this frame. if (!buffer->copyBitmapData(*prevBuffer)) return setFailed(); @@ -389,7 +389,7 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) } // Update our status to be partially complete. - buffer->setStatus(RGBA32Buffer::FramePartial); + buffer->setStatus(ImageFrame::FramePartial); // Reset the alpha pixel tracker for this frame. m_currentBufferSawAlpha = false; diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h index 64240d4..dd401b8 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h @@ -48,7 +48,7 @@ namespace WebCore { virtual bool setSize(int width, int height); virtual size_t frameCount(); virtual int repetitionCount() const; - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid // accessing deleted memory, especially when calling this from inside // GIFImageReader! @@ -58,7 +58,7 @@ namespace WebCore { // Callbacks from the GIF reader. void decodingHalted(unsigned bytesLeft); bool haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber, unsigned repeatCount, bool writeTransparentPixels); - bool frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod); + bool frameComplete(unsigned frameIndex, unsigned frameDuration, ImageFrame::FrameDisposalMethod disposalMethod); void gifComplete(); private: diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp b/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp index 1e033a3..420b355 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp @@ -638,11 +638,11 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len, } // NOTE: This relies on the values in the FrameDisposalMethod enum // matching those in the GIF spec! - frame_reader->disposal_method = (WebCore::RGBA32Buffer::FrameDisposalMethod)(((*q) >> 2) & 0x7); + frame_reader->disposal_method = (WebCore::ImageFrame::FrameDisposalMethod)(((*q) >> 2) & 0x7); // Some specs say 3rd bit (value 4), other specs say value 3 // Let's choose 3 (the more popular) if (frame_reader->disposal_method == 4) - frame_reader->disposal_method = WebCore::RGBA32Buffer::DisposeOverwritePrevious; + frame_reader->disposal_method = WebCore::ImageFrame::DisposeOverwritePrevious; frame_reader->delay_time = GETINT16(q + 1) * 10; } GETN(1, gif_consume_block); diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h b/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h index be5be19..b6eb943 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageReader.h @@ -101,7 +101,7 @@ struct GIFFrameReader { unsigned int x_offset, y_offset; /* With respect to "screen" origin */ unsigned int height, width; int tpixel; /* Index of transparent pixel */ - WebCore::RGBA32Buffer::FrameDisposalMethod disposal_method; /* Restore to background, leave in place, etc.*/ + WebCore::ImageFrame::FrameDisposalMethod disposal_method; /* Restore to background, leave in place, etc.*/ unsigned char *local_colormap; /* Per-image colormap */ int local_colormap_size; /* Size of local colormap array. */ @@ -130,7 +130,7 @@ struct GIFFrameReader { x_offset = y_offset = width = height = 0; tpixel = 0; - disposal_method = WebCore::RGBA32Buffer::DisposeNotSpecified; + disposal_method = WebCore::ImageFrame::DisposeNotSpecified; local_colormap = 0; local_colormap_size = 0; diff --git a/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp b/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp index 47302f7..21c0e1f 100644 --- a/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp +++ b/Source/WebCore/platform/image-decoders/haiku/ImageDecoderHaiku.cpp @@ -31,7 +31,7 @@ namespace WebCore { -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { int bytesPerRow = width() * sizeof(PixelData); OwnPtr<BBitmap> bitmap(new BBitmap(BRect(0, 0, width() - 1, height() - 1), 0, B_RGBA32, bytesPerRow)); diff --git a/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp index 92a7dcf..55e1dcb 100644 --- a/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.cpp @@ -109,14 +109,14 @@ size_t ICOImageDecoder::frameCount() return m_frameBufferCache.size(); } -RGBA32Buffer* ICOImageDecoder::frameBufferAtIndex(size_t index) +ImageFrame* ICOImageDecoder::frameBufferAtIndex(size_t index) { // Ensure |index| is valid. if (index >= frameCount()) return 0; - RGBA32Buffer* buffer = &m_frameBufferCache[index]; - if (buffer->status() != RGBA32Buffer::FrameComplete) + ImageFrame* buffer = &m_frameBufferCache[index]; + if (buffer->status() != ImageFrame::FrameComplete) decode(index, false); return buffer; } @@ -162,7 +162,7 @@ void ICOImageDecoder::decode(size_t index, bool onlySize) // If we're done decoding this frame, we don't need the BMPImageReader or // PNGImageDecoder anymore. (If we failed, these have already been // cleared.) - else if ((m_frameBufferCache.size() > index) && (m_frameBufferCache[index].status() == RGBA32Buffer::FrameComplete)) { + else if ((m_frameBufferCache.size() > index) && (m_frameBufferCache[index].status() == ImageFrame::FrameComplete)) { m_bmpReaders[index].clear(); m_pngDecoders[index].clear(); } diff --git a/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h b/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h index c2af6a3..31d91c8 100644 --- a/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/ico/ICOImageDecoder.h @@ -51,7 +51,7 @@ namespace WebCore { virtual IntSize frameSizeAtIndex(size_t) const; virtual bool setSize(unsigned width, unsigned height); virtual size_t frameCount(); - virtual RGBA32Buffer* frameBufferAtIndex(size_t); + virtual ImageFrame* frameBufferAtIndex(size_t); // CAUTION: setFailed() deletes all readers and decoders. Be careful to // avoid accessing deleted memory, especially when calling this from // inside BMPImageReader! diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 632d428..a255c25 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -425,7 +425,7 @@ bool JPEGImageDecoder::setSize(unsigned width, unsigned height) return true; } -RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index) +ImageFrame* JPEGImageDecoder::frameBufferAtIndex(size_t index) { if (index) return 0; @@ -435,8 +435,8 @@ RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); } - RGBA32Buffer& frame = m_frameBufferCache[0]; - if (frame.status() != RGBA32Buffer::FrameComplete) + ImageFrame& frame = m_frameBufferCache[0]; + if (frame.status() != ImageFrame::FrameComplete) decode(false); return &frame; } @@ -453,11 +453,11 @@ bool JPEGImageDecoder::outputScanlines() return false; // Initialize the framebuffer if needed. - RGBA32Buffer& buffer = m_frameBufferCache[0]; - if (buffer.status() == RGBA32Buffer::FrameEmpty) { + ImageFrame& buffer = m_frameBufferCache[0]; + if (buffer.status() == ImageFrame::FrameEmpty) { if (!buffer.setSize(scaledSize().width(), scaledSize().height())) return setFailed(); - buffer.setStatus(RGBA32Buffer::FramePartial); + buffer.setStatus(ImageFrame::FramePartial); buffer.setHasAlpha(false); buffer.setColorProfile(m_colorProfile); @@ -513,7 +513,7 @@ void JPEGImageDecoder::jpegComplete() // Hand back an appropriately sized buffer, even if the image ended up being // empty. - m_frameBufferCache[0].setStatus(RGBA32Buffer::FrameComplete); + m_frameBufferCache[0].setStatus(ImageFrame::FrameComplete); } void JPEGImageDecoder::decode(bool onlySize) @@ -530,7 +530,7 @@ void JPEGImageDecoder::decode(bool onlySize) setFailed(); // If we're done decoding the image, we don't need the JPEGImageReader // anymore. (If we failed, |m_reader| has already been cleared.) - else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) + else if (!m_frameBufferCache.isEmpty() && (m_frameBufferCache[0].status() == ImageFrame::FrameComplete)) m_reader.clear(); } diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h index 63f29ab..801f1ab 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h @@ -44,7 +44,7 @@ namespace WebCore { virtual String filenameExtension() const { return "jpg"; } virtual bool isSizeAvailable(); virtual bool setSize(unsigned width, unsigned height); - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); virtual bool supportsAlpha() const { return false; } // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid // accessing deleted memory, especially when calling this from inside diff --git a/Source/WebCore/platform/image-decoders/openvg/ImageDecoderOpenVG.cpp b/Source/WebCore/platform/image-decoders/openvg/ImageDecoderOpenVG.cpp index 061c5ab..d29317a 100644 --- a/Source/WebCore/platform/image-decoders/openvg/ImageDecoderOpenVG.cpp +++ b/Source/WebCore/platform/image-decoders/openvg/ImageDecoderOpenVG.cpp @@ -34,7 +34,7 @@ namespace WebCore { -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { static const VGImageFormat bufferFormat = VG_sARGB_8888_PRE; // Save memory by using 16-bit images for fully opaque images. diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 3fe4d3c..755d704 100644 --- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -197,7 +197,7 @@ bool PNGImageDecoder::setSize(unsigned width, unsigned height) return true; } -RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index) +ImageFrame* PNGImageDecoder::frameBufferAtIndex(size_t index) { if (index) return 0; @@ -207,8 +207,8 @@ RGBA32Buffer* PNGImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); } - RGBA32Buffer& frame = m_frameBufferCache[0]; - if (frame.status() != RGBA32Buffer::FrameComplete) + ImageFrame& frame = m_frameBufferCache[0]; + if (frame.status() != ImageFrame::FrameComplete) decode(false); return &frame; } @@ -330,13 +330,13 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, return; // Initialize the framebuffer if needed. - RGBA32Buffer& buffer = m_frameBufferCache[0]; - if (buffer.status() == RGBA32Buffer::FrameEmpty) { + ImageFrame& buffer = m_frameBufferCache[0]; + if (buffer.status() == ImageFrame::FrameEmpty) { if (!buffer.setSize(scaledSize().width(), scaledSize().height())) { longjmp(JMPBUF(m_reader->pngPtr()), 1); return; } - buffer.setStatus(RGBA32Buffer::FramePartial); + buffer.setStatus(ImageFrame::FramePartial); buffer.setHasAlpha(false); buffer.setColorProfile(m_colorProfile); @@ -410,7 +410,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, void PNGImageDecoder::pngComplete() { if (!m_frameBufferCache.isEmpty()) - m_frameBufferCache.first().setStatus(RGBA32Buffer::FrameComplete); + m_frameBufferCache.first().setStatus(ImageFrame::FrameComplete); } void PNGImageDecoder::decode(bool onlySize) diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h index 1e8902f..ec2e857 100644 --- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.h @@ -43,7 +43,7 @@ namespace WebCore { virtual String filenameExtension() const { return "png"; } virtual bool isSizeAvailable(); virtual bool setSize(unsigned width, unsigned height); - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); // CAUTION: setFailed() deletes |m_reader|. Be careful to avoid // accessing deleted memory, especially when calling this from inside // PNGImageReader! @@ -56,7 +56,7 @@ namespace WebCore { bool isComplete() const { - return !m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status() == RGBA32Buffer::FrameComplete); + return !m_frameBufferCache.isEmpty() && (m_frameBufferCache.first().status() == ImageFrame::FrameComplete); } private: diff --git a/Source/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp b/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp index 998234f..81c22cf 100644 --- a/Source/WebCore/platform/image-decoders/qt/RGBA32BufferQt.cpp +++ b/Source/WebCore/platform/image-decoders/qt/ImageFrameQt.cpp @@ -35,7 +35,7 @@ namespace WebCore { -RGBA32Buffer::RGBA32Buffer() +ImageFrame::ImageFrame() : m_hasAlpha(false) , m_size() , m_status(FrameEmpty) @@ -44,7 +44,7 @@ RGBA32Buffer::RGBA32Buffer() { } -RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) +ImageFrame& ImageFrame::operator=(const ImageFrame& other) { if (this == &other) return *this; @@ -57,7 +57,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) return *this; } -void RGBA32Buffer::clear() +void ImageFrame::clear() { m_pixmap = QPixmap(); m_image = QImage(); @@ -68,7 +68,7 @@ void RGBA32Buffer::clear() // other metadata out of this frame later. } -void RGBA32Buffer::zeroFill() +void ImageFrame::zeroFill() { if (m_pixmap.isNull() && !m_image.isNull()) { m_pixmap = QPixmap(m_image.width(), m_image.height()); @@ -77,7 +77,7 @@ void RGBA32Buffer::zeroFill() m_pixmap.fill(QColor(0, 0, 0, 0)); } -bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) +bool ImageFrame::copyBitmapData(const ImageFrame& other) { if (this == &other) return true; @@ -89,7 +89,7 @@ bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) return true; } -bool RGBA32Buffer::setSize(int newWidth, int newHeight) +bool ImageFrame::setSize(int newWidth, int newHeight) { // This function should only be called once, it will leak memory // otherwise. @@ -107,7 +107,7 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight) return true; } -QPixmap* RGBA32Buffer::asNewNativeImage() const +QPixmap* ImageFrame::asNewNativeImage() const { if (m_pixmap.isNull() && !m_image.isNull()) { m_pixmap = QPixmap::fromImage(m_image); @@ -116,28 +116,28 @@ QPixmap* RGBA32Buffer::asNewNativeImage() const return new QPixmap(m_pixmap); } -bool RGBA32Buffer::hasAlpha() const +bool ImageFrame::hasAlpha() const { return m_hasAlpha; } -void RGBA32Buffer::setHasAlpha(bool alpha) +void ImageFrame::setHasAlpha(bool alpha) { m_hasAlpha = alpha; } -void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile) +void ImageFrame::setColorProfile(const ColorProfile& colorProfile) { notImplemented(); } -void RGBA32Buffer::setStatus(FrameStatus status) +void ImageFrame::setStatus(FrameStatus status) { m_status = status; } // The image must not have format 8888 pre multiplied... -void RGBA32Buffer::setPixmap(const QPixmap& pixmap) +void ImageFrame::setPixmap(const QPixmap& pixmap) { m_pixmap = pixmap; m_image = QImage(); @@ -145,12 +145,12 @@ void RGBA32Buffer::setPixmap(const QPixmap& pixmap) m_hasAlpha = pixmap.hasAlphaChannel(); } -int RGBA32Buffer::width() const +int ImageFrame::width() const { return m_size.width(); } -int RGBA32Buffer::height() const +int ImageFrame::height() const { return m_size.height(); } diff --git a/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp b/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp index 50e2106..a1c8261 100644 --- a/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp +++ b/Source/WebCore/platform/image-decoders/skia/ImageDecoderSkia.cpp @@ -34,7 +34,7 @@ namespace WebCore { -RGBA32Buffer::RGBA32Buffer() +ImageFrame::ImageFrame() : m_status(FrameEmpty) , m_duration(0) , m_disposalMethod(DisposeNotSpecified) @@ -42,7 +42,7 @@ RGBA32Buffer::RGBA32Buffer() { } -RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) +ImageFrame& ImageFrame::operator=(const ImageFrame& other) { if (this == &other) return *this; @@ -59,7 +59,7 @@ RGBA32Buffer& RGBA32Buffer::operator=(const RGBA32Buffer& other) return *this; } -void RGBA32Buffer::clear() +void ImageFrame::clear() { m_bitmap.reset(); m_status = FrameEmpty; @@ -69,12 +69,12 @@ void RGBA32Buffer::clear() // other metadata out of this frame later. } -void RGBA32Buffer::zeroFill() +void ImageFrame::zeroFill() { m_bitmap.eraseARGB(0, 0, 0, 0); } -bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) +bool ImageFrame::copyBitmapData(const ImageFrame& other) { if (this == &other) return true; @@ -84,7 +84,7 @@ bool RGBA32Buffer::copyBitmapData(const RGBA32Buffer& other) return otherBitmap.copyTo(&m_bitmap, otherBitmap.config()); } -bool RGBA32Buffer::setSize(int newWidth, int newHeight) +bool ImageFrame::setSize(int newWidth, int newHeight) { // This function should only be called once, it will leak memory // otherwise. @@ -99,7 +99,7 @@ bool RGBA32Buffer::setSize(int newWidth, int newHeight) return true; } -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { #if PLATFORM(ANDROID) return new SkBitmapRef(m_bitmap); @@ -108,34 +108,34 @@ NativeImagePtr RGBA32Buffer::asNewNativeImage() const #endif } -bool RGBA32Buffer::hasAlpha() const +bool ImageFrame::hasAlpha() const { return !m_bitmap.isOpaque(); } -void RGBA32Buffer::setHasAlpha(bool alpha) +void ImageFrame::setHasAlpha(bool alpha) { m_bitmap.setIsOpaque(!alpha); } -void RGBA32Buffer::setColorProfile(const ColorProfile& colorProfile) +void ImageFrame::setColorProfile(const ColorProfile& colorProfile) { notImplemented(); } -void RGBA32Buffer::setStatus(FrameStatus status) +void ImageFrame::setStatus(FrameStatus status) { m_status = status; if (m_status == FrameComplete) m_bitmap.setDataComplete(); // Tell the bitmap it's done. } -int RGBA32Buffer::width() const +int ImageFrame::width() const { return m_bitmap.width(); } -int RGBA32Buffer::height() const +int ImageFrame::height() const { return m_bitmap.height(); } diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp index a988d9c..8045ada 100644 --- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp @@ -53,7 +53,7 @@ bool WEBPImageDecoder::isSizeAvailable() return ImageDecoder::isSizeAvailable(); } -RGBA32Buffer* WEBPImageDecoder::frameBufferAtIndex(size_t index) +ImageFrame* WEBPImageDecoder::frameBufferAtIndex(size_t index) { if (index) return 0; @@ -63,8 +63,8 @@ RGBA32Buffer* WEBPImageDecoder::frameBufferAtIndex(size_t index) m_frameBufferCache[0].setPremultiplyAlpha(m_premultiplyAlpha); } - RGBA32Buffer& frame = m_frameBufferCache[0]; - if (frame.status() != RGBA32Buffer::FrameComplete) + ImageFrame& frame = m_frameBufferCache[0]; + if (frame.status() != ImageFrame::FrameComplete) decode(false); return &frame; } @@ -96,8 +96,8 @@ bool WEBPImageDecoder::decode(bool onlySize) if (!isAllDataReceived()) return true; ASSERT(!m_frameBufferCache.isEmpty()); - RGBA32Buffer& buffer = m_frameBufferCache[0]; - if (buffer.status() == RGBA32Buffer::FrameEmpty) { + ImageFrame& buffer = m_frameBufferCache[0]; + if (buffer.status() == ImageFrame::FrameEmpty) { ASSERT(width == size().width()); ASSERT(height == size().height()); if (!buffer.setSize(width, height)) @@ -114,7 +114,7 @@ bool WEBPImageDecoder::decode(bool onlySize) for (int x = 0; x < width; ++x) buffer.setRGBA(x, y, src[bytesPerPixel * x + 2], src[bytesPerPixel * x + 1], src[bytesPerPixel * x + 0], 0xff); } - buffer.setStatus(RGBA32Buffer::FrameComplete); + buffer.setStatus(ImageFrame::FrameComplete); buffer.setHasAlpha(false); buffer.setRect(IntRect(IntPoint(), size())); return true; diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h index 6cf8870..cde1bbf 100644 --- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.h @@ -41,7 +41,7 @@ public: virtual ~WEBPImageDecoder(); virtual String filenameExtension() const { return "vp8"; } virtual bool isSizeAvailable(); - virtual RGBA32Buffer* frameBufferAtIndex(size_t index); + virtual ImageFrame* frameBufferAtIndex(size_t index); virtual bool supportsAlpha() const { return false; } private: diff --git a/Source/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp b/Source/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp index 966eb90..9314bbe 100644 --- a/Source/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp +++ b/Source/WebCore/platform/image-decoders/wx/ImageDecoderWx.cpp @@ -37,7 +37,7 @@ namespace WebCore { -NativeImagePtr RGBA32Buffer::asNewNativeImage() const +NativeImagePtr ImageFrame::asNewNativeImage() const { wxBitmap* bmp = new wxBitmap(width(), height(), 32); diff --git a/Source/WebCore/platform/image-encoders/skia/JPEGImageEncoder.cpp b/Source/WebCore/platform/image-encoders/skia/JPEGImageEncoder.cpp index b675ab5..be3c92a 100644 --- a/Source/WebCore/platform/image-encoders/skia/JPEGImageEncoder.cpp +++ b/Source/WebCore/platform/image-encoders/skia/JPEGImageEncoder.cpp @@ -79,23 +79,12 @@ static void handleError(j_common_ptr common) longjmp(*jumpBufferPtr, -1); } -// FIXME: is alpha unpremultiplication correct, or should the alpha channel -// be ignored? See bug http://webkit.org/b/40147. -void preMultipliedBGRAtoRGB(const SkPMColor* input, unsigned int pixels, unsigned char* output) +static void preMultipliedBGRAtoRGB(const SkPMColor* input, unsigned int pixels, unsigned char* output) { - static const SkUnPreMultiply::Scale* scale = SkUnPreMultiply::GetScaleTable(); - for (; pixels-- > 0; ++input) { - const unsigned alpha = SkGetPackedA32(*input); - if ((alpha != 0) && (alpha != 255)) { - *output++ = SkUnPreMultiply::ApplyScale(scale[alpha], SkGetPackedR32(*input)); - *output++ = SkUnPreMultiply::ApplyScale(scale[alpha], SkGetPackedG32(*input)); - *output++ = SkUnPreMultiply::ApplyScale(scale[alpha], SkGetPackedB32(*input)); - } else { - *output++ = SkGetPackedR32(*input); - *output++ = SkGetPackedG32(*input); - *output++ = SkGetPackedB32(*input); - } + *output++ = SkGetPackedR32(*input); + *output++ = SkGetPackedG32(*input); + *output++ = SkGetPackedB32(*input); } } diff --git a/Source/WebCore/platform/mac/DragDataMac.mm b/Source/WebCore/platform/mac/DragDataMac.mm index 9cb4836..64376b1 100644 --- a/Source/WebCore/platform/mac/DragDataMac.mm +++ b/Source/WebCore/platform/mac/DragDataMac.mm @@ -33,41 +33,52 @@ #import "DOMDocumentFragmentInternal.h" #import "MIMETypeRegistry.h" #import "Pasteboard.h" -#import "PasteboardHelper.h" +#import "Range.h" namespace WebCore { DragData::DragData(DragDataRef data, const IntPoint& clientPosition, const IntPoint& globalPosition, - DragOperation sourceOperationMask, PasteboardHelper* pasteboardHelper) + DragOperation sourceOperationMask, DragApplicationFlags flags) : m_clientPosition(clientPosition) , m_globalPosition(globalPosition) , m_platformDragData(data) , m_draggingSourceOperationMask(sourceOperationMask) - , m_pasteboardHelper(pasteboardHelper) + , m_applicationFlags(flags) + , m_pasteboard([m_platformDragData draggingPasteboard]) +{ +} + +DragData::DragData(const String& dragStorageName, const IntPoint& clientPosition, const IntPoint& globalPosition, + DragOperation sourceOperationMask, DragApplicationFlags flags) + : m_clientPosition(clientPosition) + , m_globalPosition(globalPosition) + , m_platformDragData(0) + , m_draggingSourceOperationMask(sourceOperationMask) + , m_applicationFlags(flags) + , m_pasteboard([NSPasteboard pasteboardWithName:dragStorageName]) { - ASSERT(pasteboardHelper); } bool DragData::canSmartReplace() const { //Need to call this so that the various Pasteboard type strings are intialised Pasteboard::generalPasteboard(); - return [[[m_platformDragData draggingPasteboard] types] containsObject:WebSmartPastePboardType]; + return [[m_pasteboard.get() types] containsObject:WebSmartPastePboardType]; } bool DragData::containsColor() const { - return [[[m_platformDragData draggingPasteboard] types] containsObject:NSColorPboardType]; + return [[m_pasteboard.get() types] containsObject:NSColorPboardType]; } bool DragData::containsFiles() const { - return [[[m_platformDragData draggingPasteboard] types] containsObject:NSFilenamesPboardType]; + return [[m_pasteboard.get() types] containsObject:NSFilenamesPboardType]; } void DragData::asFilenames(Vector<String>& result) const { - NSArray *filenames = [[m_platformDragData draggingPasteboard] propertyListForType:NSFilenamesPboardType]; + NSArray *filenames = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType]; NSEnumerator *fileEnumerator = [filenames objectEnumerator]; while (NSString *filename = [fileEnumerator nextObject]) @@ -76,19 +87,19 @@ void DragData::asFilenames(Vector<String>& result) const bool DragData::containsPlainText() const { - NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; - NSArray *types = [pasteboard types]; + NSArray *types = [m_pasteboard.get() types]; return [types containsObject:NSStringPboardType] || [types containsObject:NSRTFDPboardType] || [types containsObject:NSRTFPboardType] || [types containsObject:NSFilenamesPboardType] - || [NSURL URLFromPasteboard:pasteboard]; + || [NSURL URLFromPasteboard:m_pasteboard.get()]; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame *frame) const { - return m_pasteboardHelper->plainTextFromPasteboard([m_platformDragData draggingPasteboard]); + Pasteboard pasteboard(m_pasteboard.get()); + return pasteboard.plainText(frame); } Color DragData::asColor() const @@ -98,29 +109,50 @@ Color DragData::asColor() const (int)([color blueComponent] * 255.0 + 0.5), (int)([color alphaComponent] * 255.0 + 0.5)); } +static NSArray *insertablePasteboardTypes() +{ + static NSArray *types = nil; + if (!types) { + types = [[NSArray alloc] initWithObjects:WebArchivePboardType, NSHTMLPboardType, NSFilenamesPboardType, NSTIFFPboardType, NSPDFPboardType, +#if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) + NSPICTPboardType, +#endif + NSURLPboardType, NSRTFDPboardType, NSRTFPboardType, NSStringPboardType, NSColorPboardType, kUTTypePNG, nil]; + CFRetain(types); + } + return types; +} + bool DragData::containsCompatibleContent() const { - NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; - NSMutableSet *types = [NSMutableSet setWithArray:[pasteboard types]]; - [types intersectSet:[NSSet setWithArray:m_pasteboardHelper->insertablePasteboardTypes()]]; + NSMutableSet *types = [NSMutableSet setWithArray:[m_pasteboard.get() types]]; + [types intersectSet:[NSSet setWithArray:insertablePasteboardTypes()]]; return [types count] != 0; } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame* frame, FilenameConversionPolicy filenamePolicy) const { - return !asURL(filenamePolicy).isEmpty(); + return !asURL(frame, filenamePolicy).isEmpty(); } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame* frame, FilenameConversionPolicy filenamePolicy, String* title) const { // FIXME: Use filenamePolicy. (void)filenamePolicy; - return m_pasteboardHelper->urlFromPasteboard([m_platformDragData draggingPasteboard], title); + + if (title) { + if (NSString *URLTitleString = [[m_platformDragData draggingPasteboard] stringForType:WebURLNamePboardType]) + *title = URLTitleString; + } + Pasteboard pasteboard(m_pasteboard.get()); + return pasteboard.asURL(frame); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range> range, bool allowPlainText, bool& chosePlainText) const { - return core(m_pasteboardHelper->fragmentFromPasteboard([m_platformDragData draggingPasteboard])); + Pasteboard pasteboard(m_pasteboard.get()); + + return pasteboard.documentFragment(frame, range, allowPlainText, chosePlainText); } } // namespace WebCore diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm index 0625287..71e4046 100644 --- a/Source/WebCore/platform/mac/PasteboardMac.mm +++ b/Source/WebCore/platform/mac/PasteboardMac.mm @@ -191,7 +191,7 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, if ([types containsObject:NSStringPboardType]) { // Map to a plain old space because this is better for source code, other browsers do it, // and because HTML forces you to do this any time you want two spaces in a row. - String text = selectedRange->text(); + String text = frame->editor()->selectedText(); NSMutableString *s = [[[(NSString*)text copy] autorelease] mutableCopy]; NSString *NonBreakingSpaceString = [NSString stringWithCharacters:&noBreakSpace length:1]; @@ -436,7 +436,50 @@ static NSURL* uniqueURLWithRelativePart(NSString *relativePart) return URL; } + +NSURL *Pasteboard::getBestURL(Frame* frame) +{ + NSArray *types = [m_pasteboard.get() types]; + + // FIXME: using the editorClient to call into webkit, for now, since + // calling webkit_canonicalize from WebCore involves migrating a sizable amount of + // helper code that should either be done in a separate patch or figured out in another way. + + if ([types containsObject:NSURLPboardType]) { + NSURL *URLFromPasteboard = [NSURL URLFromPasteboard:m_pasteboard.get()]; + NSString *scheme = [URLFromPasteboard scheme]; + if ([scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"]) { + return frame->editor()->client()->canonicalizeURL(URLFromPasteboard); + } + } + + if ([types containsObject:NSStringPboardType]) { + NSString *URLString = [m_pasteboard.get() stringForType:NSStringPboardType]; + NSURL *URL = frame->editor()->client()->canonicalizeURLString(URLString); + if (URL) + return URL; + } + + if ([types containsObject:NSFilenamesPboardType]) { + NSArray *files = [m_pasteboard.get() propertyListForType:NSFilenamesPboardType]; + // FIXME: Maybe it makes more sense to allow multiple files and only use the first one? + if ([files count] == 1) { + NSString *file = [files objectAtIndex:0]; + BOOL isDirectory; + if ([[NSFileManager defaultManager] fileExistsAtPath:file isDirectory:&isDirectory] && isDirectory) + return nil; + return frame->editor()->client()->canonicalizeURL([NSURL fileURLWithPath:file]); + } + } + return nil; +} + +String Pasteboard::asURL(Frame* frame) +{ + return [getBestURL(frame) absoluteString]; +} + PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) { NSArray *types = [m_pasteboard.get() types]; diff --git a/Source/WebCore/platform/mac/ThemeMac.mm b/Source/WebCore/platform/mac/ThemeMac.mm index 75cbd36..e510ea7 100644 --- a/Source/WebCore/platform/mac/ThemeMac.mm +++ b/Source/WebCore/platform/mac/ThemeMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. + * Copyright (C) 2008, 2010, 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 @@ -52,6 +52,16 @@ using namespace std; return nil; } +- (NSRect)_focusRingVisibleRect +{ + return [self visibleRect]; +} + +- (NSView *)_focusRingClipAncestor +{ + return self; +} + @end // FIXME: Default buttons really should be more like push buttons and not like buttons. diff --git a/Source/WebCore/platform/mac/WheelEventMac.mm b/Source/WebCore/platform/mac/WheelEventMac.mm index d9663b9..d4fc698 100644 --- a/Source/WebCore/platform/mac/WheelEventMac.mm +++ b/Source/WebCore/platform/mac/WheelEventMac.mm @@ -29,9 +29,31 @@ #import "PlatformMouseEvent.h" #import "Scrollbar.h" #import "WebCoreSystemInterface.h" +#import <wtf/UnusedParam.h> namespace WebCore { +static PlatformWheelEventPhase phaseForEvent(NSEvent *event) +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + uint32_t phase = PlatformWheelEventPhaseNone; + if ([event momentumPhase] & NSEventPhaseBegan) + phase |= PlatformWheelEventPhaseBegan; + if ([event momentumPhase] & NSEventPhaseStationary) + phase |= PlatformWheelEventPhaseStationary; + if ([event momentumPhase] & NSEventPhaseChanged) + phase |= PlatformWheelEventPhaseChanged; + if ([event momentumPhase] & NSEventPhaseEnded) + phase |= PlatformWheelEventPhaseEnded; + if ([event momentumPhase] & NSEventPhaseCancelled) + phase |= PlatformWheelEventPhaseCancelled; + return static_cast<PlatformWheelEventPhase>(phase); +#else + UNUSED_PARAM(event); + return PlatformWheelEventPhaseNone; +#endif +} + PlatformWheelEvent::PlatformWheelEvent(NSEvent* event, NSView *windowView) : m_position(pointForEvent(event, windowView)) , m_globalPosition(globalPointForEvent(event)) @@ -41,9 +63,10 @@ PlatformWheelEvent::PlatformWheelEvent(NSEvent* event, NSView *windowView) , m_ctrlKey([event modifierFlags] & NSControlKeyMask) , m_altKey([event modifierFlags] & NSAlternateKeyMask) , m_metaKey([event modifierFlags] & NSCommandKeyMask) + , m_phase(phaseForEvent(event)) { BOOL continuous; - + wkGetWheelEventDeltas(event, &m_deltaX, &m_deltaY, &continuous); if (continuous) { m_wheelTicksX = m_deltaX / static_cast<float>(Scrollbar::pixelsPerLineStep()); diff --git a/Source/WebCore/platform/mac/WidgetMac.mm b/Source/WebCore/platform/mac/WidgetMac.mm index e8bb81d..f3c951a 100644 --- a/Source/WebCore/platform/mac/WidgetMac.mm +++ b/Source/WebCore/platform/mac/WidgetMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2005, 2006, 2008, 2010, 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 @@ -34,6 +34,7 @@ #import "Chrome.h" #import "Cursor.h" #import "Document.h" +#import "FloatConversion.h" #import "Font.h" #import "Frame.h" #import "GraphicsContext.h" @@ -170,25 +171,48 @@ void Widget::setFrameRect(const IntRect& rect) m_frame = rect; BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *v = getOuterView(); - if (!v) + NSView *outerView = getOuterView(); + if (!outerView) return; - NSRect visibleRect = [v visibleRect]; + // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary + // code, which can deref it. + RefPtr<Widget> protectedThis(this); + + NSRect visibleRect = [outerView visibleRect]; NSRect f = rect; - if (!NSEqualRects(f, [v frame])) { - [v setFrame:f]; - [v setNeedsDisplay:NO]; - } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [v respondsToSelector:@selector(visibleRectDidChange)]) - [v visibleRectDidChange]; + if (!NSEqualRects(f, [outerView frame])) { + [outerView setFrame:f]; + [outerView setNeedsDisplay:NO]; + } else if (!NSEqualRects(visibleRect, m_data->previousVisibleRect) && [outerView respondsToSelector:@selector(visibleRectDidChange)]) + [outerView visibleRectDidChange]; m_data->previousVisibleRect = visibleRect; END_BLOCK_OBJC_EXCEPTIONS; } -NSView* Widget::getOuterView() const +void Widget::setBoundsSize(const IntSize& size) { - NSView* view = platformWidget(); + NSSize nsSize = size; + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSView *outerView = getOuterView(); + if (!outerView) + return; + + // Take a reference to this Widget, because sending messages to outerView can invoke arbitrary + // code, which can deref it. + RefPtr<Widget> protectedThis(this); + if (!NSEqualSizes(nsSize, [outerView bounds].size)) { + [outerView setBoundsSize:nsSize]; + [outerView setNeedsDisplay:NO]; + } + END_BLOCK_OBJC_EXCEPTIONS; +} + +NSView *Widget::getOuterView() const +{ + NSView *view = platformWidget(); // If this widget's view is a WebCoreFrameScrollView then we // resize its containing view, a WebFrameView. @@ -205,11 +229,35 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) if (p->paintingDisabled()) return; NSView *view = getOuterView(); + + // Take a reference to this Widget, because sending messages to the views can invoke arbitrary + // code, which can deref it. + RefPtr<Widget> protectedThis(this); + + IntPoint transformOrigin = frameRect().location(); + AffineTransform widgetToViewTranform = makeMapBetweenRects(IntRect(IntPoint(), frameRect().size()), [view bounds]); + NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; if (currentContext == [[view window] graphicsContext] || ![currentContext isDrawingToScreen]) { // This is the common case of drawing into a window or printing. BEGIN_BLOCK_OBJC_EXCEPTIONS; - [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]]; + + CGContextRef context = (CGContextRef)[currentContext graphicsPort]; + + CGContextSaveGState(context); + CGContextTranslateCTM(context, transformOrigin.x(), transformOrigin.y()); + CGContextScaleCTM(context, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale())); + CGContextTranslateCTM(context, -transformOrigin.x(), -transformOrigin.y()); + + IntRect dirtyRect = r; + dirtyRect.move(-transformOrigin.x(), -transformOrigin.y()); + if (![view isFlipped]) + dirtyRect.setY([view bounds].size.height - dirtyRect.bottom()); + + [view displayRectIgnoringOpacity:dirtyRect]; + + CGContextRestoreGState(context); + END_BLOCK_OBJC_EXCEPTIONS; } else { // This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath @@ -234,6 +282,10 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) ASSERT(cgContext == [currentContext graphicsPort]); CGContextSaveGState(cgContext); + CGContextTranslateCTM(cgContext, transformOrigin.x(), transformOrigin.y()); + CGContextScaleCTM(cgContext, narrowPrecisionToFloat(widgetToViewTranform.xScale()), narrowPrecisionToFloat(widgetToViewTranform.yScale())); + CGContextTranslateCTM(cgContext, -transformOrigin.x(), -transformOrigin.y()); + NSRect viewFrame = [view frame]; NSRect viewBounds = [view bounds]; // Set up the translation and (flipped) orientation of the graphics context. In normal drawing, AppKit does it as it descends down @@ -241,13 +293,18 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) CGContextTranslateCTM(cgContext, viewFrame.origin.x - viewBounds.origin.x, viewFrame.origin.y + viewFrame.size.height + viewBounds.origin.y); CGContextScaleCTM(cgContext, 1, -1); + IntRect dirtyRect = r; + dirtyRect.move(-transformOrigin.x(), -transformOrigin.y()); + if (![view isFlipped]) + dirtyRect.setY([view bounds].size.height - dirtyRect.bottom()); + BEGIN_BLOCK_OBJC_EXCEPTIONS; { #ifdef BUILDING_ON_TIGER AutodrainedPool pool; #endif NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]; - [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:nsContext]; + [view displayRectIgnoringOpacity:dirtyRect inContext:nsContext]; } END_BLOCK_OBJC_EXCEPTIONS; @@ -261,6 +318,7 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) void Widget::setIsSelected(bool isSelected) { NSView *view = platformWidget(); + BEGIN_BLOCK_OBJC_EXCEPTIONS; if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)]) [view webPlugInSetIsSelected:isSelected]; diff --git a/Source/WebCore/platform/mock/SpeechInputClientMock.cpp b/Source/WebCore/platform/mock/SpeechInputClientMock.cpp index 16f2825..16a7c76 100644 --- a/Source/WebCore/platform/mock/SpeechInputClientMock.cpp +++ b/Source/WebCore/platform/mock/SpeechInputClientMock.cpp @@ -72,8 +72,8 @@ void SpeechInputClientMock::stopRecording(int requestId) void SpeechInputClientMock::cancelRecognition(int requestId) { - ASSERT(requestId == m_requestId); if (m_timer.isActive()) { + ASSERT(requestId == m_requestId); m_timer.stop(); m_recording = false; m_listener->didCompleteRecognition(m_requestId); @@ -107,15 +107,20 @@ void SpeechInputClientMock::timerFired(WebCore::Timer<SpeechInputClientMock>*) } else { bool noResultsFound = false; + // We take a copy of the requestId here so that if scripts destroyed the input element + // inside one of the callbacks below, we'll still know what this session's requestId was. + int requestId = m_requestId; + m_requestId = 0; + // Empty language case must be handled separately to avoid problems with HashMap and empty keys. if (m_language.isEmpty()) { if (!m_resultsForEmptyLanguage.isEmpty()) - m_listener->setRecognitionResult(m_requestId, m_resultsForEmptyLanguage); + m_listener->setRecognitionResult(requestId, m_resultsForEmptyLanguage); else noResultsFound = true; } else { if (m_recognitionResults.contains(m_language)) - m_listener->setRecognitionResult(m_requestId, m_recognitionResults.get(m_language)); + m_listener->setRecognitionResult(requestId, m_recognitionResults.get(m_language)); else noResultsFound = true; } @@ -128,11 +133,10 @@ void SpeechInputClientMock::timerFired(WebCore::Timer<SpeechInputClientMock>*) error.append("'"); SpeechInputResultArray results; results.append(SpeechInputResult::create(error, 1.0)); - m_listener->setRecognitionResult(m_requestId, results); + m_listener->setRecognitionResult(requestId, results); } - m_listener->didCompleteRecognition(m_requestId); - m_requestId = 0; + m_listener->didCompleteRecognition(requestId); } } diff --git a/Source/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/Source/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp index 959e74a..f3e7023 100644 --- a/Source/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp +++ b/Source/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp @@ -91,6 +91,6 @@ void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed) } // namespace WebCore -#endif - #include "moc_NetworkStateNotifierPrivate.cpp" + +#endif diff --git a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp index 0caeb05..e0d6e69 100644 --- a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp +++ b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp @@ -25,10 +25,6 @@ #include <QNetworkCookieJar> #include <QStringList> -// Use unused variables to be able to call qRegisterMetaType statically. -static int dummyStaticVar1 = qRegisterMetaType<QFutureInterface<bool> >("QFutureInterface<bool>"); -static int dummyStaticVar2 = qRegisterMetaType<QFutureInterface<QList<QNetworkCookie> > >("QFutureInterface<QList<QNetworkCookie> >"); - namespace WebCore { QtNAMThreadSafeProxy::QtNAMThreadSafeProxy(QNetworkAccessManager *manager) @@ -37,8 +33,8 @@ QtNAMThreadSafeProxy::QtNAMThreadSafeProxy(QNetworkAccessManager *manager) moveToThread(manager->thread()); connect(this, SIGNAL(localSetCookiesRequested(const QUrl&, const QString&)), SLOT(localSetCookies(const QUrl&, const QString&))); - connect(this, SIGNAL(localCookiesForUrlRequested(QFutureInterface<QList<QNetworkCookie> >, const QUrl&)), SLOT(localCookiesForUrl(QFutureInterface<QList<QNetworkCookie> >, const QUrl&))); - connect(this, SIGNAL(localWillLoadFromCacheRequested(QFutureInterface<bool>, const QUrl&)), SLOT(localWillLoadFromCache(QFutureInterface<bool>, const QUrl&))); + connect(this, SIGNAL(localCookiesForUrlRequested(const QUrl&, bool*, QList<QNetworkCookie>*)), SLOT(localCookiesForUrl(const QUrl&, bool*, QList<QNetworkCookie>*))); + connect(this, SIGNAL(localWillLoadFromCacheRequested(const QUrl&, bool*, bool*)), SLOT(localWillLoadFromCache(const QUrl&, bool*, bool*))); } void QtNAMThreadSafeProxy::localSetCookies(const QUrl& url, const QString& cookies) @@ -54,19 +50,23 @@ void QtNAMThreadSafeProxy::localSetCookies(const QUrl& url, const QString& cooki m_manager->cookieJar()->setCookiesFromUrl(cookieList, url); } -void QtNAMThreadSafeProxy::localCookiesForUrl(QFutureInterface<QList<QNetworkCookie> > fi, const QUrl& url) +void QtNAMThreadSafeProxy::localCookiesForUrl(const QUrl& url, bool* done, QList<QNetworkCookie>* result) { - fi.reportResult(m_manager->cookieJar()->cookiesForUrl(url)); - fi.reportFinished(); + QMutexLocker lock(&m_resultMutex); + *result = m_manager->cookieJar()->cookiesForUrl(url); + *done = true; + m_resultWaitCondition.wakeAll(); } -void QtNAMThreadSafeProxy::localWillLoadFromCache(QFutureInterface<bool> fi, const QUrl& url) +void QtNAMThreadSafeProxy::localWillLoadFromCache(const QUrl& url, bool* done, bool* result) { - bool retVal = false; + QMutexLocker lock(&m_resultMutex); if (m_manager->cache()) - retVal = m_manager->cache()->metaData(url).isValid(); - - fi.reportFinished(&retVal); + *result = m_manager->cache()->metaData(url).isValid(); + else + *result = false; + *done = true; + m_resultWaitCondition.wakeAll(); } QtNetworkReplyThreadSafeProxy::QtNetworkReplyThreadSafeProxy(QNetworkAccessManager *manager) diff --git a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h index a2fa4ee..ae963cf 100644 --- a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h +++ b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h @@ -19,11 +19,11 @@ #ifndef QtNAMThreadSafeProxy_h #define QtNAMThreadSafeProxy_h -#include <QFuture> #include <QMutex> #include <QNetworkCookie> #include <QNetworkReply> #include <QObject> +#include <QWaitCondition> QT_BEGIN_NAMESPACE class QNetworkAccessManager; @@ -43,34 +43,44 @@ public: emit localSetCookiesRequested(url, cookies); } - QFuture<QList<QNetworkCookie> > cookiesForUrl(const QUrl& url) + QList<QNetworkCookie> cookiesForUrl(const QUrl& url) { - QFutureInterface<QList<QNetworkCookie> > fi; - fi.reportStarted(); - emit localCookiesForUrlRequested(fi, url); - return fi.future(); + bool done = false; + QList<QNetworkCookie> result; + emit localCookiesForUrlRequested(url, &done, &result); + + QMutexLocker lock(&m_resultMutex); + while (!done) + m_resultWaitCondition.wait(&m_resultMutex); + return result; } - QFuture<bool> willLoadFromCache(const QUrl& url) + bool willLoadFromCache(const QUrl& url) { - QFutureInterface<bool> fi; - fi.reportStarted(); - emit localWillLoadFromCacheRequested(fi, url); - return fi.future(); + bool done = false; + bool result; + emit localWillLoadFromCacheRequested(url, &done, &result); + + QMutexLocker lock(&m_resultMutex); + while (!done) + m_resultWaitCondition.wait(&m_resultMutex); + return result; } signals: - void localSetCookiesRequested(const QUrl& url, const QString& cookies); - void localCookiesForUrlRequested(QFutureInterface<QList<QNetworkCookie> > fi, const QUrl& url); - void localWillLoadFromCacheRequested(QFutureInterface<bool> fi, const QUrl& url); + void localSetCookiesRequested(const QUrl&, const QString& cookies); + void localCookiesForUrlRequested(const QUrl&, bool* done, QList<QNetworkCookie>* result); + void localWillLoadFromCacheRequested(const QUrl&, bool* done, bool* result); private slots: - void localSetCookies(const QUrl& url, const QString& cookies); - void localCookiesForUrl(QFutureInterface<QList<QNetworkCookie> > fi, const QUrl& url); - void localWillLoadFromCache(QFutureInterface<bool> fi, const QUrl& url); + void localSetCookies(const QUrl&, const QString& cookies); + void localCookiesForUrl(const QUrl&, bool* done, QList<QNetworkCookie>* result); + void localWillLoadFromCache(const QUrl&, bool* done, bool* result); private: QNetworkAccessManager* m_manager; + QMutex m_resultMutex; + QWaitCondition m_resultWaitCondition; }; diff --git a/Source/WebCore/platform/network/soup/AuthenticationChallenge.h b/Source/WebCore/platform/network/soup/AuthenticationChallenge.h index 5177f1e..492d5c2 100644 --- a/Source/WebCore/platform/network/soup/AuthenticationChallenge.h +++ b/Source/WebCore/platform/network/soup/AuthenticationChallenge.h @@ -26,6 +26,7 @@ #define AuthenticationChallenge_h #include "AuthenticationChallengeBase.h" +#include "AuthenticationClient.h" namespace WebCore { @@ -39,6 +40,10 @@ public: : AuthenticationChallengeBase(protectionSpace, proposedCredential, previousFailureCount, response, error) { } + + AuthenticationClient* authenticationClient() const { return m_authenticationClient.get(); } + + RefPtr<AuthenticationClient> m_authenticationClient; }; } diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp index 8900b18..ebb6c5f 100644 --- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -215,6 +215,8 @@ static void restartedCallback(SoupMessage* msg, gpointer data) #endif } +static void contentSniffedCallback(SoupMessage*, const char*, GHashTable*, gpointer); + static void gotHeadersCallback(SoupMessage* msg, gpointer data) { // For 401, we will accumulate the resource body, and only use it @@ -235,9 +237,18 @@ static void gotHeadersCallback(SoupMessage* msg, gpointer data) // The content-sniffed callback will handle the response if WebCore // require us to sniff. - if (!handle || statusWillBeHandledBySoup(msg->status_code) || handle->shouldContentSniff()) + if (!handle || statusWillBeHandledBySoup(msg->status_code)) return; + if (handle->shouldContentSniff()) { + // Avoid MIME type sniffing if the response comes back as 304 Not Modified. + if (msg->status_code == SOUP_STATUS_NOT_MODIFIED) { + soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER); + g_signal_handlers_disconnect_by_func(msg, reinterpret_cast<gpointer>(contentSniffedCallback), handle.get()); + } else + return; + } + ResourceHandleInternal* d = handle->getInternal(); if (d->m_cancelled) return; diff --git a/Source/WebCore/platform/network/soup/cache/soup-http-input-stream.c b/Source/WebCore/platform/network/soup/cache/soup-http-input-stream.c index 195c458..2a5d995 100644 --- a/Source/WebCore/platform/network/soup/cache/soup-http-input-stream.c +++ b/Source/WebCore/platform/network/soup/cache/soup-http-input-stream.c @@ -267,7 +267,7 @@ webkit_soup_http_input_stream_got_chunk (SoupMessage *msg, SoupBuffer *chunk_buf g_warning ("webkit_soup_http_input_stream_got_chunk called again before previous chunk was processed"); /* Copy what we can into priv->caller_buffer */ - if (priv->caller_bufsize - priv->caller_nread > 0) { + if (priv->caller_bufsize > priv->caller_nread) { gsize nread = MIN (chunk_size, priv->caller_bufsize - priv->caller_nread); memcpy (priv->caller_buffer + priv->caller_nread, chunk, nread); diff --git a/Source/WebCore/platform/network/win/ProxyServerWin.cpp b/Source/WebCore/platform/network/win/ProxyServerWin.cpp new file mode 100644 index 0000000..c610e20 --- /dev/null +++ b/Source/WebCore/platform/network/win/ProxyServerWin.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2010 Brent Fulgham <bfulgham@webkit.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: + * 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 "config.h" +#include "ProxyServer.h" + +namespace WebCore { + +Vector<ProxyServer> proxyServersForURL(const KURL&, const NetworkingContext*) +{ + // FIXME: Implement. + return Vector<ProxyServer>(); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/qt/CookieJarQt.cpp b/Source/WebCore/platform/qt/CookieJarQt.cpp index e5d36ba..b7ff5d1 100644 --- a/Source/WebCore/platform/qt/CookieJarQt.cpp +++ b/Source/WebCore/platform/qt/CookieJarQt.cpp @@ -30,14 +30,13 @@ #include "Cookie.h" #include "Document.h" +#include "FrameLoaderClientQt.h" #include "KURL.h" -#include "QtNAMThreadSafeProxy.h" #include "NetworkingContext.h" #include "PlatformString.h" - -#include "qwebpage.h" +#include "QtNAMThreadSafeProxy.h" #include "qwebframe.h" -#include "FrameLoaderClientQt.h" +#include "qwebpage.h" #include <QNetworkAccessManager> #include <QNetworkCookie> #include <QStringList> @@ -49,10 +48,10 @@ static QNetworkAccessManager *networkAccessManager(const Document *document) { if (!document) return 0; - Frame *frame = document->frame(); + Frame* frame = document->frame(); if (!frame) return 0; - FrameLoader *loader = frame->loader(); + FrameLoader* loader = frame->loader(); if (!loader) return 0; return loader->networkingContext()->networkAccessManager(); @@ -115,7 +114,10 @@ String cookieRequestHeaderFieldValue(const Document* document, const KURL &url) bool cookiesEnabled(const Document* document) { - return networkAccessManager(document); + if (QNetworkAccessManager* manager = networkAccessManager(document)) + return !!manager->cookieJar(); + + return false; } bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) diff --git a/Source/WebCore/platform/qt/DragDataQt.cpp b/Source/WebCore/platform/qt/DragDataQt.cpp index 4033123..f68ad1d 100644 --- a/Source/WebCore/platform/qt/DragDataQt.cpp +++ b/Source/WebCore/platform/qt/DragDataQt.cpp @@ -28,6 +28,7 @@ #include "Document.h" #include "DocumentFragment.h" +#include "Frame.h" #include "markup.h" #include <QColor> @@ -80,7 +81,7 @@ bool DragData::containsPlainText() const return m_platformDragData->hasText() || m_platformDragData->hasUrls(); } -String DragData::asPlainText() const +String DragData::asPlainText(Frame* frame) const { if (!m_platformDragData) return String(); @@ -89,7 +90,7 @@ String DragData::asPlainText() const return text; // FIXME: Should handle rich text here - return asURL(DoNotConvertFilenames, 0); + return asURL(frame, DoNotConvertFilenames, 0); } Color DragData::asColor() const @@ -103,10 +104,10 @@ bool DragData::containsCompatibleContent() const { if (!m_platformDragData) return false; - return containsColor() || containsURL() || m_platformDragData->hasHtml() || m_platformDragData->hasText(); + return containsColor() || containsURL(0) || m_platformDragData->hasHtml() || m_platformDragData->hasText(); } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { // FIXME: Use filenamePolicy. if (!m_platformDragData) @@ -114,7 +115,7 @@ bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const return m_platformDragData->hasUrls(); } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String*) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String*) const { // FIXME: Use filenamePolicy. if (!m_platformDragData) @@ -127,10 +128,10 @@ String DragData::asURL(FilenameConversionPolicy filenamePolicy, String*) const return encodeWithURLEscapeSequences(urls.first().toString()); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const { if (m_platformDragData && m_platformDragData->hasHtml()) - return createFragmentFromMarkup(doc, m_platformDragData->html(), "", FragmentScriptingNotAllowed); + return createFragmentFromMarkup(frame->document(), m_platformDragData->html(), "", FragmentScriptingNotAllowed); return 0; } diff --git a/Source/WebCore/platform/qt/PasteboardQt.cpp b/Source/WebCore/platform/qt/PasteboardQt.cpp index 1c60da0..6865fd7 100644 --- a/Source/WebCore/platform/qt/PasteboardQt.cpp +++ b/Source/WebCore/platform/qt/PasteboardQt.cpp @@ -32,13 +32,12 @@ #include "Editor.h" #include "Frame.h" #include "Image.h" -#include "markup.h" #include "RenderImage.h" - -#include <qdebug.h> +#include "markup.h" +#include <qapplication.h> #include <qclipboard.h> +#include <qdebug.h> #include <qmimedata.h> -#include <qapplication.h> #include <qurl.h> #define methodDebug() qDebug() << "PasteboardQt: " << __FUNCTION__; @@ -75,8 +74,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, #endif #ifndef QT_NO_CLIPBOARD - QApplication::clipboard()->setMimeData(md, m_selectionMode ? - QClipboard::Selection : QClipboard::Clipboard); + QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); #endif if (canSmartCopyOrDelete) md->setData("application/vnd.qtwebkit.smartpaste", QByteArray()); @@ -94,8 +92,7 @@ bool Pasteboard::canSmartReplace() String Pasteboard::plainText(Frame*) { #ifndef QT_NO_CLIPBOARD - return QApplication::clipboard()->text(m_selectionMode ? - QClipboard::Selection : QClipboard::Clipboard); + return QApplication::clipboard()->text(m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); #else return String(); #endif @@ -136,22 +133,20 @@ void Pasteboard::writePlainText(const String& text) QString qtext = text; qtext.replace(QChar(0xa0), QLatin1Char(' ')); md->setText(qtext); - QApplication::clipboard()->setMimeData(md, m_selectionMode ? - QClipboard::Selection : QClipboard::Clipboard); + QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); #endif } -void Pasteboard::writeURL(const KURL& _url, const String&, Frame*) +void Pasteboard::writeURL(const KURL& url, const String&, Frame*) { - ASSERT(!_url.isEmpty()); + ASSERT(!url.isEmpty()); #ifndef QT_NO_CLIPBOARD QMimeData* md = new QMimeData; - QString url = _url.string(); - md->setText(url); - md->setUrls(QList<QUrl>() << QUrl(url)); - QApplication::clipboard()->setMimeData(md, m_selectionMode ? - QClipboard::Selection : QClipboard::Clipboard); + QString urlString = url.string(); + md->setText(urlString); + md->setUrls(QList<QUrl>() << url); + QApplication::clipboard()->setMimeData(md, m_selectionMode ? QClipboard::Selection : QClipboard::Clipboard); #endif } diff --git a/Source/WebCore/platform/qt/PlatformMouseEventQt.cpp b/Source/WebCore/platform/qt/PlatformMouseEventQt.cpp index a8956bf..125ae52 100644 --- a/Source/WebCore/platform/qt/PlatformMouseEventQt.cpp +++ b/Source/WebCore/platform/qt/PlatformMouseEventQt.cpp @@ -34,6 +34,7 @@ namespace WebCore { +#if !defined(QT_NO_GRAPHICSVIEW) PlatformMouseEvent::PlatformMouseEvent(QGraphicsSceneMouseEvent* event, int clickCount) { m_timestamp = WTF::currentTime(); @@ -69,6 +70,7 @@ PlatformMouseEvent::PlatformMouseEvent(QGraphicsSceneMouseEvent* event, int clic m_altKey = (event->modifiers() & Qt::AltModifier); m_metaKey = (event->modifiers() & Qt::MetaModifier); } +#endif // QT_NO_GRAPHICSVIEW PlatformMouseEvent::PlatformMouseEvent(QInputEvent* event, int clickCount) { diff --git a/Source/WebCore/platform/qt/RenderThemeQt.cpp b/Source/WebCore/platform/qt/RenderThemeQt.cpp index 2cc3625..8d5cfcd 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQt.cpp @@ -47,9 +47,11 @@ #include "QtMobileWebStyle.h" #endif #include "NotImplemented.h" +#include "PaintInfo.h" #include "Page.h" #include "QWebPageClient.h" #include "QtStyleOptionWebComboBox.h" +#include "qwebsettings.h" #include "RenderBox.h" #if ENABLE(PROGRESS_TAG) #include "RenderProgress.h" @@ -92,6 +94,15 @@ inline static void initStyleOption(QWidget *widget, QStyleOption& option) option.state = QStyle::State_Active | QStyle::State_Enabled; } } +// These values all match Safari/Win/Chromium +static const float defaultControlFontPixelSize = 13; +static const float defaultCancelButtonSize = 9; +static const float minCancelButtonSize = 5; +static const float maxCancelButtonSize = 21; +static const float defaultSearchFieldResultsDecorationSize = 13; +static const float minSearchFieldResultsDecorationSize = 9; +static const float maxSearchFieldResultsDecorationSize = 30; +static const float defaultSearchFieldResultsButtonWidth = 18; StylePainter::StylePainter(RenderThemeQt* theme, const PaintInfo& paintInfo) @@ -186,6 +197,7 @@ bool RenderThemeQt::isControlStyled(const RenderStyle* style, const BorderData& case PushButtonPart: case ButtonPart: case MenulistPart: + // FIXME: Need to add SearchFieldPart if it should be style-able. case TextFieldPart: case TextAreaPart: return true; @@ -201,6 +213,20 @@ int RenderThemeQt::popupInternalPaddingBottom(RenderStyle* style) const { return 1; } +#else +// Remove this when SearchFieldPart is style-able in RenderTheme::isControlStyled() +bool RenderThemeQt::isControlStyled(const RenderStyle* style, const BorderData& border, const FillLayer& fill, const Color& backgroundColor) const +{ + switch (style->appearance()) { + case SearchFieldPart: + // Test the style to see if the UA border and background match. + return (style->border() != border + || *style->backgroundLayers() != fill + || style->visitedDependentColor(CSSPropertyBackgroundColor) != backgroundColor); + default: + return RenderTheme::isControlStyled(style, border, fill, backgroundColor); + } +} #endif // for some widget painting, we need to fallback to Windows style @@ -413,6 +439,7 @@ void RenderThemeQt::computeSizeBasedOnStyle(RenderStyle* renderStyle) const switch (renderStyle->appearance()) { case TextAreaPart: + case SearchFieldPart: case TextFieldPart: { int padding = findFrameLineWidth(style); @@ -611,6 +638,11 @@ bool RenderThemeQt::paintButton(RenderObject* o, const PaintInfo& i, const IntRe void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, Element*) const { + // Resetting the style like this leads to differences like: + // - RenderTextControl {INPUT} at (2,2) size 168x25 [bgcolor=#FFFFFF] border: (2px inset #000000)] + // + RenderTextControl {INPUT} at (2,2) size 166x26 + // in layout tests when a CSS style is applied that doesn't affect background color, border or + // padding. Just worth keeping in mind! style->setBackgroundColor(Color::transparent); style->resetBorder(); style->resetPadding(); @@ -886,28 +918,73 @@ void RenderThemeQt::adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle* style bool RenderThemeQt::paintSearchField(RenderObject* o, const PaintInfo& pi, const IntRect& r) { - return true; + return paintTextField(o, pi, r); } void RenderThemeQt::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { - notImplemented(); - RenderTheme::adjustSearchFieldStyle(selector, style, e); + // Resetting the style like this leads to differences like: + // - RenderTextControl {INPUT} at (2,2) size 168x25 [bgcolor=#FFFFFF] border: (2px inset #000000)] + // + RenderTextControl {INPUT} at (2,2) size 166x26 + // in layout tests when a CSS style is applied that doesn't affect background color, border or + // padding. Just worth keeping in mind! + style->setBackgroundColor(Color::transparent); + style->resetBorder(); + style->resetPadding(); + computeSizeBasedOnStyle(style); } void RenderThemeQt::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const { - notImplemented(); - RenderTheme::adjustSearchFieldCancelButtonStyle(selector, style, e); + // Logic taken from RenderThemeChromium.cpp. + // Scale the button size based on the font size. + float fontScale = style->fontSize() / defaultControlFontPixelSize; + int cancelButtonSize = lroundf(qMin(qMax(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize)); + style->setWidth(Length(cancelButtonSize, Fixed)); + style->setHeight(Length(cancelButtonSize, Fixed)); +} + +// Function taken from RenderThemeChromium.cpp +IntRect RenderThemeQt::convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const +{ + // Compute an offset between the part renderer and the input renderer. + IntSize offsetFromInputRenderer = -(partRenderer->offsetFromAncestorContainer(inputRenderer)); + // Move the rect into partRenderer's coords. + partRect.move(offsetFromInputRenderer); + // Account for the local drawing offset. + partRect.move(localOffset.x(), localOffset.y()); + + return partRect; } bool RenderThemeQt::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& pi, const IntRect& r) { - notImplemented(); - return RenderTheme::paintSearchFieldCancelButton(o, pi, r); + // Logic copied from RenderThemeChromium.cpp. + + // Get the renderer of <input> element. + Node* input = o->node()->shadowAncestorNode(); + if (!input->renderer()->isBox()) + return false; + RenderBox* inputRenderBox = toRenderBox(input->renderer()); + IntRect inputContentBox = inputRenderBox->contentBoxRect(); + + // Make sure the scaled button stays square and will fit in its parent's box. + int cancelButtonSize = qMin(inputContentBox.width(), qMin(inputContentBox.height(), r.height())); + // Calculate cancel button's coordinates relative to the input element. + // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will + // be one pixel closer to the bottom of the field. This tends to look better with the text. + IntRect cancelButtonRect(o->offsetFromAncestorContainer(inputRenderBox).width(), + inputContentBox.y() + (inputContentBox.height() - cancelButtonSize + 1) / 2, + cancelButtonSize, cancelButtonSize); + IntRect paintingRect = convertToPaintingRect(inputRenderBox, o, cancelButtonRect, r); + static Image* cancelImage = Image::loadPlatformResource("searchCancelButton").releaseRef(); + static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelButtonPressed").releaseRef(); + pi.context->drawImage(isPressed(o) ? cancelPressedImage : cancelImage, + o->style()->colorSpace(), paintingRect); + return false; } void RenderThemeQt::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, @@ -1037,7 +1114,12 @@ ControlPart RenderThemeQt::initializeCommonQStyleOptions(QStyleOption& option, R String RenderThemeQt::extraMediaControlsStyleSheet() { - return String(mediaControlsQtUserAgentStyleSheet, sizeof(mediaControlsQtUserAgentStyleSheet)); + String result = String(mediaControlsQtUserAgentStyleSheet, sizeof(mediaControlsQtUserAgentStyleSheet)); + + if (m_page && m_page->chrome()->requiresFullscreenForVideoPlayback()) + result += String(mediaControlsQtFullscreenUserAgentStyleSheet, sizeof(mediaControlsQtFullscreenUserAgentStyleSheet)); + + return result; } // Helper class to transform the painter's world matrix to the object's content area, scaled to 0,0,100,100 diff --git a/Source/WebCore/platform/qt/RenderThemeQt.h b/Source/WebCore/platform/qt/RenderThemeQt.h index c28168a..6981641 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.h +++ b/Source/WebCore/platform/qt/RenderThemeQt.h @@ -81,8 +81,8 @@ public: virtual double caretBlinkInterval() const; -#if USE(QT_MOBILE_THEME) virtual bool isControlStyled(const RenderStyle*, const BorderData&, const FillLayer&, const Color& backgroundColor) const; +#if USE(QT_MOBILE_THEME) virtual int popupInternalPaddingBottom(RenderStyle*) const; #endif @@ -180,6 +180,8 @@ private: QStyle* fallbackStyle() const; + IntRect convertToPaintingRect(RenderObject* inputRenderer, const RenderObject* partRenderer, IntRect partRect, const IntRect& localOffset) const; + Page* m_page; #ifdef Q_WS_MAC diff --git a/Source/WebCore/platform/qt/WheelEventQt.cpp b/Source/WebCore/platform/qt/WheelEventQt.cpp index 57a7ebc..aa61d91 100644 --- a/Source/WebCore/platform/qt/WheelEventQt.cpp +++ b/Source/WebCore/platform/qt/WheelEventQt.cpp @@ -48,10 +48,10 @@ void PlatformWheelEvent::applyDelta(int delta, Qt::Orientation orientation) m_wheelTicksX = m_deltaX; m_wheelTicksY = m_deltaY; +#ifndef QT_NO_WHEELEVENT // Use the same single scroll step as QTextEdit // (in QTextEditPrivate::init [h,v]bar->setSingleStep) static const float cDefaultQtScrollStep = 20.f; -#ifndef QT_NO_WHEELEVENT m_deltaX *= (fullTick) ? QApplication::wheelScrollLines() * cDefaultQtScrollStep : 1; m_deltaY *= (fullTick) ? QApplication::wheelScrollLines() * cDefaultQtScrollStep : 1; #endif diff --git a/Source/WebCore/platform/win/DragDataWin.cpp b/Source/WebCore/platform/win/DragDataWin.cpp index 56345e2..906119d 100644 --- a/Source/WebCore/platform/win/DragDataWin.cpp +++ b/Source/WebCore/platform/win/DragDataWin.cpp @@ -27,6 +27,7 @@ #include "DragData.h" #include "ClipboardUtilitiesWin.h" +#include "Frame.h" #include "DocumentFragment.h" #include "PlatformString.h" #include "Markup.h" @@ -37,7 +38,7 @@ namespace WebCore { -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { return SUCCEEDED(m_platformDragData->QueryGetData(urlWFormat())) || SUCCEEDED(m_platformDragData->QueryGetData(urlFormat())) @@ -46,7 +47,7 @@ bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const || SUCCEEDED(m_platformDragData->QueryGetData(filenameFormat())))); } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { bool success; return getURL(m_platformDragData, filenamePolicy, success, title); @@ -89,7 +90,7 @@ bool DragData::containsPlainText() const || SUCCEEDED(m_platformDragData->QueryGetData(plainTextFormat())); } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { bool success; return getPlainText(m_platformDragData, success); @@ -107,13 +108,13 @@ bool DragData::canSmartReplace() const bool DragData::containsCompatibleContent() const { - return containsPlainText() || containsURL() + return containsPlainText() || containsURL(0) || containsHTML(m_platformDragData) || containsFilenames(m_platformDragData) || containsColor(); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const { /* * Order is richest format first. On OSX this is: @@ -126,11 +127,11 @@ PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const */ if (containsFilenames(m_platformDragData)) - if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(doc, m_platformDragData)) + if (PassRefPtr<DocumentFragment> fragment = fragmentFromFilenames(frame->document(), m_platformDragData)) return fragment; if (containsHTML(m_platformDragData)) - if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(doc, m_platformDragData)) + if (PassRefPtr<DocumentFragment> fragment = fragmentFromHTML(frame->document(), m_platformDragData)) return fragment; return 0; diff --git a/Source/WebCore/platform/win/WebCoreTextRenderer.h b/Source/WebCore/platform/win/WebCoreTextRenderer.h index 7efc1f3..6deef4a 100644 --- a/Source/WebCore/platform/win/WebCoreTextRenderer.h +++ b/Source/WebCore/platform/win/WebCoreTextRenderer.h @@ -23,6 +23,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef WebCoreTextRenderer_h +#define WebCoreTextRenderer_h + #include <wtf/Forward.h> namespace WebCore { @@ -43,3 +46,5 @@ namespace WebCore { bool WebCoreAlwaysUsesComplexTextCodePath(); } // namespace WebCore + +#endif // WebCoreTextRenderer_h diff --git a/Source/WebCore/platform/wince/DragDataWinCE.cpp b/Source/WebCore/platform/wince/DragDataWinCE.cpp index 5535ea9..8f531c7 100644 --- a/Source/WebCore/platform/wince/DragDataWinCE.cpp +++ b/Source/WebCore/platform/wince/DragDataWinCE.cpp @@ -23,15 +23,16 @@ #include "DocumentFragment.h" #include "PlatformString.h" +#include "Range.h" namespace WebCore { -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { return false; } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { return String(); } @@ -50,7 +51,7 @@ bool DragData::containsPlainText() const return false; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { return String(); } @@ -70,7 +71,7 @@ bool DragData::containsCompatibleContent() const return false; } -PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const { return 0; } diff --git a/Source/WebCore/platform/wx/DragDataWx.cpp b/Source/WebCore/platform/wx/DragDataWx.cpp index 35e3753..53b4219 100644 --- a/Source/WebCore/platform/wx/DragDataWx.cpp +++ b/Source/WebCore/platform/wx/DragDataWx.cpp @@ -55,7 +55,7 @@ bool DragData::containsPlainText() const return false; } -String DragData::asPlainText() const +String DragData::asPlainText(Frame*) const { return String(); } @@ -70,18 +70,18 @@ bool DragData::containsCompatibleContent() const return false; } -bool DragData::containsURL(FilenameConversionPolicy filenamePolicy) const +bool DragData::containsURL(Frame*, FilenameConversionPolicy filenamePolicy) const { return false; } -String DragData::asURL(FilenameConversionPolicy filenamePolicy, String* title) const +String DragData::asURL(Frame*, FilenameConversionPolicy filenamePolicy, String* title) const { return String(); } -PassRefPtr<DocumentFragment> DragData::asFragment(Document*) const +PassRefPtr<DocumentFragment> DragData::asFragment(Frame*, PassRefPtr<Range>, bool, bool&) const { return 0; } diff --git a/Source/WebCore/platform/wx/WidgetWx.cpp b/Source/WebCore/platform/wx/WidgetWx.cpp index 9de4c3d..7591a5b 100644 --- a/Source/WebCore/platform/wx/WidgetWx.cpp +++ b/Source/WebCore/platform/wx/WidgetWx.cpp @@ -80,6 +80,10 @@ IntRect Widget::frameRect() const void Widget::setFrameRect(const IntRect& rect) { + // Take a reference to this Widget, because calling functions of the PlatformWidget can invoke arbitrary + // code, which can deref it. + RefPtr<Widget> protectedThis(this); + if (PlatformWidget widget = platformWidget()) widget->SetSize(rect); |