diff options
Diffstat (limited to 'Source/WebCore/platform')
359 files changed, 7627 insertions, 5596 deletions
diff --git a/Source/WebCore/platform/ContextMenuItem.h b/Source/WebCore/platform/ContextMenuItem.h index 6595711..46a6987 100644 --- a/Source/WebCore/platform/ContextMenuItem.h +++ b/Source/WebCore/platform/ContextMenuItem.h @@ -65,7 +65,7 @@ namespace WebCore { ContextMenuItemTagOpenImageInNewWindow, ContextMenuItemTagDownloadImageToDisk, ContextMenuItemTagCopyImageToClipboard, -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) ContextMenuItemTagCopyImageUrlToClipboard, #endif ContextMenuItemTagOpenFrameInNewWindow, diff --git a/Source/WebCore/platform/CookieJar.h b/Source/WebCore/platform/CookieJar.h index 4793708..f21cfd4 100644 --- a/Source/WebCore/platform/CookieJar.h +++ b/Source/WebCore/platform/CookieJar.h @@ -27,6 +27,8 @@ #define CookieJar_h #include <wtf/Forward.h> +#include <wtf/HashSet.h> +#include <wtf/text/WTFString.h> #include <wtf/Vector.h> namespace WebCore { @@ -44,6 +46,10 @@ namespace WebCore { bool getRawCookies(const Document*, const KURL&, Vector<Cookie>&); void deleteCookie(const Document*, const KURL&, const String&); + void getHostnamesWithCookies(HashSet<String>& hostnames); + void deleteCookiesForHostname(const String& hostname); + void deleteAllCookies(); + } #endif diff --git a/Source/WebCore/platform/CookiesStrategy.h b/Source/WebCore/platform/CookiesStrategy.h new file mode 100644 index 0000000..15558c6 --- /dev/null +++ b/Source/WebCore/platform/CookiesStrategy.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CookiesStrategy_h +#define CookiesStrategy_h + +#if USE(PLATFORM_STRATEGIES) + +namespace WebCore { + +class CookiesStrategy { +public: + virtual void notifyCookiesChanged() = 0; + +protected: + virtual ~CookiesStrategy() { } +}; + +} // namespace WebCore + +#endif // USE(PLATFORM_STRATEGIES) + +#endif // CookiesStrategy_h diff --git a/Source/WebCore/platform/DeprecatedPtrList.h b/Source/WebCore/platform/DeprecatedPtrList.h deleted file mode 100644 index c07d173..0000000 --- a/Source/WebCore/platform/DeprecatedPtrList.h +++ /dev/null @@ -1,115 +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. - */ - -#ifndef DeprecatedPtrList_h -#define DeprecatedPtrList_h - -#include "DeprecatedPtrListImpl.h" -#include <wtf/FastAllocBase.h> - -namespace WebCore { - -template <class T> class DeprecatedPtrListIterator; - -template <class T> class DeprecatedPtrList { - WTF_MAKE_FAST_ALLOCATED; -public: - DeprecatedPtrList() : impl(deleteFunc), del_item(false) { } - ~DeprecatedPtrList() { impl.clear(del_item); } - - DeprecatedPtrList(const DeprecatedPtrList& l) : impl(l.impl), del_item(false) { } - DeprecatedPtrList& operator=(const DeprecatedPtrList &l) { impl.assign(l.impl, del_item); return *this; } - - bool isEmpty() const { return impl.isEmpty(); } - unsigned count() const { return impl.count(); } - void clear() { impl.clear(del_item); } - - T *at(unsigned n) { return (T *)impl.at(n); } - - bool insert(unsigned n, const T *item) { return impl.insert(n, item); } - bool remove() { return impl.remove(del_item); } - bool remove(unsigned n) { return impl.remove(n, del_item); } - bool remove(const T *item) { return impl.removeRef(item, del_item); } - bool removeFirst() { return impl.removeFirst(del_item); } - bool removeLast() { return impl.removeLast(del_item); } - bool removeRef(const T *item) { return impl.removeRef(item, del_item); } - - T *getFirst() const { return (T *)impl.getFirst(); } - T *getLast() const { return (T *)impl.getLast(); } - T *getNext() const { return (T *)impl.getNext(); } - T *getPrev() const { return (T *)impl.getPrev(); } - T *current() const { return (T *)impl.current(); } - T *first() { return (T *)impl.first(); } - T *last() { return (T *)impl.last(); } - T *next() { return (T *)impl.next(); } - T *prev() { return (T *)impl.prev(); } - T *take(unsigned n) { return (T *)impl.take(n); } - T *take() { return (T *)impl.take(); } - - void append(const T *item) { impl.append(item); } - void prepend(const T *item) { impl.prepend(item); } - - unsigned containsRef(const T *item) const { return impl.containsRef(item); } - int findRef(const T *item) { return impl.findRef(item); } - - typedef DeprecatedPtrListIterator<T> Iterator; - typedef DeprecatedPtrListIterator<T> ConstIterator; - ConstIterator begin() const { return ConstIterator(*this); } - ConstIterator end() const { ConstIterator itr(*this); itr.toLast(); ++itr; return itr; } - - bool autoDelete() const { return del_item; } - void setAutoDelete(bool autoDelete) { del_item = autoDelete; } - - private: - static void deleteFunc(void *item) { delete (T *)item; } - - friend class DeprecatedPtrListIterator<T>; - - DeprecatedPtrListImpl impl; - bool del_item; -}; - -template <class T> class DeprecatedPtrListIterator { -public: - DeprecatedPtrListIterator() { } - DeprecatedPtrListIterator(const DeprecatedPtrList<T> &l) : impl(l.impl) { } - - unsigned count() const { return impl.count(); } - T *toFirst() { return (T *)impl.toFirst(); } - T *toLast() { return (T *)impl.toLast(); } - T *current() const { return (T *)impl.current(); } - - operator T *() const { return (T *)impl.current(); } - T *operator*() const { return (T *)impl.current(); } - T *operator--() { return (T *)--impl; } - T *operator++() { return (T *)++impl; } - -private: - DeprecatedPtrListImplIterator impl; -}; - -} - -#endif diff --git a/Source/WebCore/platform/DeprecatedPtrListImpl.cpp b/Source/WebCore/platform/DeprecatedPtrListImpl.cpp deleted file mode 100644 index c633741..0000000 --- a/Source/WebCore/platform/DeprecatedPtrListImpl.cpp +++ /dev/null @@ -1,516 +0,0 @@ -/* - * Copyright (C) 2003, 2006 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 "DeprecatedPtrListImpl.h" - -#include <cstddef> -#include <algorithm> -#include <wtf/Assertions.h> -#include <wtf/FastAllocBase.h> -#include <wtf/Noncopyable.h> - -namespace WebCore { - -class DeprecatedListNode { - WTF_MAKE_NONCOPYABLE(DeprecatedListNode); WTF_MAKE_FAST_ALLOCATED; -public: - DeprecatedListNode(void *d) : data(d), next(0), prev(0) { } - - void *data; - DeprecatedListNode *next; - DeprecatedListNode *prev; -}; - - -static DeprecatedListNode *copyList(DeprecatedListNode *l, DeprecatedListNode *&tail) -{ - DeprecatedListNode *node = l; - DeprecatedListNode *copyHead = 0; - DeprecatedListNode *last = 0; - - while (node != 0) { - DeprecatedListNode *copy = new DeprecatedListNode(node->data); - if (last != 0) { - last->next = copy; - } else { - copyHead = copy; - } - - copy->prev = last; - - last = copy; - node = node->next; - } - - tail = last; - return copyHead; -} - - -DeprecatedPtrListImpl::DeprecatedPtrListImpl(void (*deleteFunc)(void *)) : - head(0), - tail(0), - cur(0), - nodeCount(0), - deleteItem(deleteFunc), - iterators(0) -{ -} - -DeprecatedPtrListImpl::DeprecatedPtrListImpl(const DeprecatedPtrListImpl &impl) : - cur(0), - nodeCount(impl.nodeCount), - deleteItem(impl.deleteItem), - iterators(0) -{ - head = copyList(impl.head, tail); -} - -DeprecatedPtrListImpl::~DeprecatedPtrListImpl() -{ - clear(false); - - DeprecatedPtrListImplIterator *next; - for (DeprecatedPtrListImplIterator *it = iterators; it; it = next) { - next = it->next; - it->list = 0; - ASSERT(!it->node); - it->next = 0; - it->prev = 0; - } -} - -void DeprecatedPtrListImpl::clear(bool deleteItems) -{ - DeprecatedListNode *next; - - for (DeprecatedListNode *node = head; node; node = next) { - next = node->next; - if (deleteItems) - deleteItem(node->data); - delete node; - } - - head = 0; - tail = 0; - cur = 0; - nodeCount = 0; - - for (DeprecatedPtrListImplIterator *it = iterators; it; it = it->next) - it->node = 0; -} - -void *DeprecatedPtrListImpl::at(unsigned n) -{ - DeprecatedListNode *node; - if (n >= nodeCount - 1) { - node = tail; - } else { - node = head; - for (unsigned i = 0; i < n && node; i++) { - node = node->next; - } - } - - cur = node; - return node ? node->data : 0; -} - -bool DeprecatedPtrListImpl::insert(unsigned n, const void *item) -{ - if (n > nodeCount) { - return false; - } - - DeprecatedListNode *node = new DeprecatedListNode(const_cast<void*>(item)); - - if (n == 0) { - // inserting at head - node->next = head; - if (head) { - head->prev = node; - } - head = node; - if (tail == 0) { - tail = node; - } - } else if (n == nodeCount) { - // inserting at tail - node->prev = tail; - if (tail) { - tail->next = node; - } - tail = node; - } else { - // general insertion - - // iterate to one node before the insertion point, can't be null - // since we know n > 0 and n < nodeCount - DeprecatedListNode *prevNode = head; - - for (unsigned i = 0; i < n - 1; i++) { - prevNode = prevNode->next; - } - node->prev = prevNode; - node->next = prevNode->next; - if (node->next) { - node->next->prev = node; - } - prevNode->next = node; - } - - nodeCount++; - cur = node; - return true; -} - -bool DeprecatedPtrListImpl::remove(bool shouldDeleteItem) -{ - DeprecatedListNode *node = cur; - if (node == 0) { - return false; - } - - if (node->prev == 0) { - head = node->next; - } else { - node->prev->next = node->next; - } - - if (node->next == 0) { - tail = node->prev; - } else { - node->next->prev = node->prev; - } - - if (node->next) { - cur = node->next; - } else { - cur = node->prev; - } - - for (DeprecatedPtrListImplIterator *it = iterators; it; it = it->next) { - if (it->node == node) { - it->node = cur; - } - } - - if (shouldDeleteItem) { - deleteItem(node->data); - } - delete node; - - nodeCount--; - - return true; -} - -bool DeprecatedPtrListImpl::remove(unsigned n, bool deleteItem) -{ - if (n >= nodeCount) { - return false; - } - - at(n); - return remove(deleteItem); -} - -bool DeprecatedPtrListImpl::removeFirst(bool deleteItem) -{ - return remove(0, deleteItem); -} - -bool DeprecatedPtrListImpl::removeLast(bool deleteItem) -{ - return remove(nodeCount - 1, deleteItem); -} - -bool DeprecatedPtrListImpl::removeRef(const void *item, bool deleteItem) -{ - DeprecatedListNode *node; - - node = head; - - while (node && item != node->data) { - node = node->next; - } - - if (node == 0) { - return false; - } - - cur = node; - - return remove(deleteItem); -} - -void *DeprecatedPtrListImpl::getFirst() const -{ - return head ? head->data : 0; -} - -void *DeprecatedPtrListImpl::getLast() const -{ - return tail ? tail->data : 0; -} - -void *DeprecatedPtrListImpl::getNext() const -{ - return cur && cur->next ? cur->next->data : 0; -} - -void *DeprecatedPtrListImpl::getPrev() const -{ - return cur && cur->prev ? cur->prev->data : 0; -} - -void *DeprecatedPtrListImpl::current() const -{ - if (cur) { - return cur->data; - } else { - return 0; - } -} - -void *DeprecatedPtrListImpl::first() -{ - cur = head; - return current(); -} - -void *DeprecatedPtrListImpl::last() -{ - cur = tail; - return current(); -} - -void *DeprecatedPtrListImpl::next() -{ - if (cur) { - cur = cur->next; - } - return current(); -} - -void *DeprecatedPtrListImpl::prev() -{ - if (cur) { - cur = cur->prev; - } - return current(); -} - -void *DeprecatedPtrListImpl::take(unsigned n) -{ - void *retval = at(n); - remove(false); - return retval; -} - -void *DeprecatedPtrListImpl::take() -{ - void *retval = current(); - remove(false); - return retval; -} - -void DeprecatedPtrListImpl::append(const void *item) -{ - insert(nodeCount, item); -} - -void DeprecatedPtrListImpl::prepend(const void *item) -{ - insert(0, item); -} - -unsigned DeprecatedPtrListImpl::containsRef(const void *item) const -{ - unsigned count = 0; - - for (DeprecatedListNode *node = head; node; node = node->next) { - if (item == node->data) { - ++count; - } - } - - return count; -} - -int DeprecatedPtrListImpl::findRef(const void *item) -{ - DeprecatedListNode *node = head; - int index = 0; - - while (node && item != node->data) { - node = node->next; - index++; - } - - cur = node; - - if (node == 0) { - return -1; - } - - return index; -} - -DeprecatedPtrListImpl &DeprecatedPtrListImpl::assign(const DeprecatedPtrListImpl &impl, bool deleteItems) -{ - clear(deleteItems); - DeprecatedPtrListImpl(impl).swap(*this); - return *this; -} - -void DeprecatedPtrListImpl::addIterator(DeprecatedPtrListImplIterator *iter) const -{ - iter->next = iterators; - iter->prev = 0; - - if (iterators) { - iterators->prev = iter; - } - iterators = iter; -} - -void DeprecatedPtrListImpl::removeIterator(DeprecatedPtrListImplIterator *iter) const -{ - if (iter->prev == 0) { - iterators = iter->next; - } else { - iter->prev->next = iter->next; - } - - if (iter->next) { - iter->next->prev = iter->prev; - } -} - -void DeprecatedPtrListImpl::swap(DeprecatedPtrListImpl &other) -{ - using std::swap; - - ASSERT(iterators == 0); - ASSERT(other.iterators == 0); - - swap(head, other.head); - swap(tail, other.tail); - swap(cur, other.cur); - swap(nodeCount, other.nodeCount); - swap(deleteItem, other.deleteItem); -} - - -DeprecatedPtrListImplIterator::DeprecatedPtrListImplIterator() : - list(0), - node(0) -{ -} - -DeprecatedPtrListImplIterator::DeprecatedPtrListImplIterator(const DeprecatedPtrListImpl &impl) : - list(&impl), - node(impl.head) -{ - impl.addIterator(this); -} - -DeprecatedPtrListImplIterator::~DeprecatedPtrListImplIterator() -{ - if (list) { - list->removeIterator(this); - } -} - -DeprecatedPtrListImplIterator::DeprecatedPtrListImplIterator(const DeprecatedPtrListImplIterator &impl) : - list(impl.list), - node(impl.node) -{ - if (list) { - list->addIterator(this); - } -} - -unsigned DeprecatedPtrListImplIterator::count() const -{ - return list == 0 ? 0 : list->count(); -} - -void *DeprecatedPtrListImplIterator::toFirst() -{ - if (list) { - node = list->head; - } - return current(); -} - -void *DeprecatedPtrListImplIterator::toLast() -{ - if (list) { - node = list->tail; - } - return current(); -} - -void *DeprecatedPtrListImplIterator::current() const -{ - return node == 0 ? 0 : node->data; -} - -void *DeprecatedPtrListImplIterator::operator--() -{ - if (node) { - node = node->prev; - } - return current(); -} - -void *DeprecatedPtrListImplIterator::operator++() -{ - if (node) { - node = node->next; - } - return current(); -} - -DeprecatedPtrListImplIterator &DeprecatedPtrListImplIterator::operator=(const DeprecatedPtrListImplIterator &impl) -{ - if (list) { - list->removeIterator(this); - } - - list = impl.list; - node = impl.node; - - if (list) { - list->addIterator(this); - } - - return *this; -} - -} diff --git a/Source/WebCore/platform/DeprecatedPtrListImpl.h b/Source/WebCore/platform/DeprecatedPtrListImpl.h deleted file mode 100644 index 5e4121b..0000000 --- a/Source/WebCore/platform/DeprecatedPtrListImpl.h +++ /dev/null @@ -1,122 +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. - */ - -#ifndef DeprecatedPtrListImpl_h -#define DeprecatedPtrListImpl_h - -namespace WebCore { - -class DeprecatedListNode; -class DeprecatedPtrListImplIterator; - -class DeprecatedPtrListImpl -{ -public: - - DeprecatedPtrListImpl(void (*deleteFunc)(void *)); - DeprecatedPtrListImpl(const DeprecatedPtrListImpl &impl); - ~DeprecatedPtrListImpl(); - - bool isEmpty() const { return nodeCount == 0; } - unsigned count() const { return nodeCount; } - void clear(bool deleteItems); - - void *at(unsigned n); - - bool insert(unsigned n, const void *item); - bool remove(bool deleteItem); - bool remove(unsigned n, bool deleteItem); - bool removeFirst(bool deleteItem); - bool removeLast(bool deleteItem); - bool removeRef(const void *item, bool deleteItem); - - void *getFirst() const; - void *getLast() const; - void *getNext() const; - void *getPrev() const; - void *current() const; - void *first(); - void *last(); - void *next(); - void *prev(); - void *take(unsigned n); - void *take(); - - void append(const void *item); - void prepend(const void *item); - - unsigned containsRef(const void *item) const; - int findRef(const void *item); - - DeprecatedPtrListImpl &assign(const DeprecatedPtrListImpl &impl, bool deleteItems); - - private: - DeprecatedPtrListImpl &operator =(const DeprecatedPtrListImpl &impl); - - void swap(DeprecatedPtrListImpl &impl); - - void addIterator(DeprecatedPtrListImplIterator *iter) const; - void removeIterator(DeprecatedPtrListImplIterator *iter) const; - - DeprecatedListNode *head; - DeprecatedListNode *tail; - DeprecatedListNode *cur; - unsigned nodeCount; - void (*deleteItem)(void *); - mutable DeprecatedPtrListImplIterator *iterators; - - friend class DeprecatedPtrListImplIterator; -}; - - -class DeprecatedPtrListImplIterator { -public: - DeprecatedPtrListImplIterator(); - DeprecatedPtrListImplIterator(const DeprecatedPtrListImpl &impl); - ~DeprecatedPtrListImplIterator(); - - DeprecatedPtrListImplIterator(const DeprecatedPtrListImplIterator &impl); - DeprecatedPtrListImplIterator &operator=(const DeprecatedPtrListImplIterator &impl); - - unsigned count() const; - void *toFirst(); - void *toLast(); - void *current() const; - - void *operator--(); - void *operator++(); - -private: - const DeprecatedPtrListImpl *list; - DeprecatedListNode *node; - DeprecatedPtrListImplIterator *next; - DeprecatedPtrListImplIterator *prev; - - friend class DeprecatedPtrListImpl; -}; - -} - -#endif diff --git a/Source/WebCore/platform/FileSystem.h b/Source/WebCore/platform/FileSystem.h index d923fe6..8b7d0f0 100644 --- a/Source/WebCore/platform/FileSystem.h +++ b/Source/WebCore/platform/FileSystem.h @@ -35,7 +35,7 @@ #include <wtf/Forward.h> #include <wtf/Vector.h> -#if PLATFORM(CF) +#if USE(CF) #include <wtf/RetainPtr.h> #endif @@ -47,7 +47,7 @@ #endif #endif -#if PLATFORM(CF) || (PLATFORM(QT) && defined(Q_WS_MAC)) +#if USE(CF) || (PLATFORM(QT) && defined(Q_WS_MAC)) typedef struct __CFBundle* CFBundleRef; typedef const struct __CFData* CFDataRef; #endif @@ -84,7 +84,7 @@ typedef void* PlatformModule; #endif #elif PLATFORM(GTK) typedef GModule* PlatformModule; -#elif PLATFORM(CF) +#elif USE(CF) typedef CFBundleRef PlatformModule; #else typedef void* PlatformModule; @@ -189,7 +189,7 @@ bool unloadModule(PlatformModule); // Encode a string for use within a file name. String encodeForFileName(const String&); -#if PLATFORM(CF) +#if USE(CF) RetainPtr<CFURLRef> pathAsURL(const String&); #endif diff --git a/Source/WebCore/platform/GeolocationService.h b/Source/WebCore/platform/GeolocationService.h index cf51b1e..27be6c3 100644 --- a/Source/WebCore/platform/GeolocationService.h +++ b/Source/WebCore/platform/GeolocationService.h @@ -83,3 +83,4 @@ private: } // namespace WebCore #endif // GeolocationService_h + diff --git a/Source/WebCore/platform/KURL.cpp b/Source/WebCore/platform/KURL.cpp index f6a66ef..0032f09 100644 --- a/Source/WebCore/platform/KURL.cpp +++ b/Source/WebCore/platform/KURL.cpp @@ -25,8 +25,6 @@ #include "config.h" -#if !USE(GOOGLEURL) - #include "KURL.h" #include "TextEncoding.h" @@ -54,6 +52,11 @@ namespace WebCore { typedef Vector<char, 512> CharBuffer; typedef Vector<UChar, 512> UCharBuffer; +static const unsigned maximumValidPortNumber = 0xFFFE; +static const unsigned invalidPortNumber = 0xFFFF; + +#if !USE(GOOGLEURL) + // FIXME: This file makes too much use of the + operator on String. // We either have to optimize that operator so it doesn't involve // so many allocations, or change this to use Vector<UChar> instead. @@ -215,9 +218,6 @@ static const unsigned char characterClassTable[256] = { /* 252 */ BadChar, /* 253 */ BadChar, /* 254 */ BadChar, /* 255 */ BadChar }; -static const unsigned maximumValidPortNumber = 0xFFFE; -static const unsigned invalidPortNumber = 0xFFFF; - static int copyPathRemovingDots(char* dst, const char* src, int srcStart, int srcEnd); static void encodeRelativeString(const String& rel, const TextEncoding&, CharBuffer& ouput); static String substituteBackslashes(const String&); @@ -342,6 +342,14 @@ KURL::KURL(const KURL& base, const String& relative, const TextEncoding& encodin init(base, relative, encoding.encodingForFormSubmission()); } +static bool shouldTrimFromURL(unsigned char c) +{ + // Browsers ignore leading/trailing whitespace and control + // characters from URLs. Note that c is an *unsigned* char here + // so this comparison should only catch control characters. + return c <= ' '; +} + void KURL::init(const KURL& base, const String& relative, const TextEncoding& encoding) { // Allow resolutions with a null or empty base URL, but not with any other invalid one. @@ -377,15 +385,15 @@ void KURL::init(const KURL& base, const String& relative, const TextEncoding& en len = strlen(str); } - // Get rid of leading whitespace. - while (*str == ' ') { + // Get rid of leading whitespace and control characters. + while (len && shouldTrimFromURL(*str)) { originalString = 0; str++; --len; } - // Get rid of trailing whitespace. - while (len && str[len - 1] == ' ') { + // Get rid of trailing whitespace and control characters. + while (len && shouldTrimFromURL(str[len - 1])) { originalString = 0; str[--len] = '\0'; } @@ -959,15 +967,6 @@ String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding) return String::adopt(result); } -bool KURL::isLocalFile() const -{ - // Including feed here might be a bad idea since drag and drop uses this check - // and including feed would allow feeds to potentially let someone's blog - // read the contents of the clipboard on a drag, even without a drop. - // Likewise with using the FrameLoader::shouldTreatURLAsLocal() function. - return protocolIs("file"); -} - // Caution: This function does not bounds check. static void appendEscapedChar(char*& buffer, unsigned char c) { @@ -1746,11 +1745,6 @@ bool protocolIs(const String& url, const char* protocol) } } -bool protocolIsJavaScript(const String& url) -{ - return protocolIs(url, "javascript"); -} - bool isValidProtocol(const String& protocol) { // RFC3986: ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) @@ -1766,6 +1760,44 @@ bool isValidProtocol(const String& protocol) return true; } +#ifndef NDEBUG +void KURL::print() const +{ + printf("%s\n", m_string.utf8().data()); +} +#endif + +#endif // !USE(GOOGLEURL) + +String KURL::strippedForUseAsReferrer() const +{ + KURL referrer(*this); + referrer.setUser(String()); + referrer.setPass(String()); + referrer.removeFragmentIdentifier(); + return referrer.string(); +} + +bool KURL::isLocalFile() const +{ + // Including feed here might be a bad idea since drag and drop uses this check + // and including feed would allow feeds to potentially let someone's blog + // read the contents of the clipboard on a drag, even without a drop. + // Likewise with using the FrameLoader::shouldTreatURLAsLocal() function. + return protocolIs("file"); +} + +bool protocolIsJavaScript(const String& url) +{ + return protocolIs(url, "javascript"); +} + +const KURL& blankURL() +{ + DEFINE_STATIC_LOCAL(KURL, staticBlankURL, (ParsedURLString, "about:blank")); + return staticBlankURL; +} + bool isDefaultPortForProtocol(unsigned short port, const String& protocol) { if (protocol.isEmpty()) @@ -1900,19 +1932,4 @@ String mimeTypeFromDataURL(const String& url) return ""; } -const KURL& blankURL() -{ - DEFINE_STATIC_LOCAL(KURL, staticBlankURL, (ParsedURLString, "about:blank")); - return staticBlankURL; -} - -#ifndef NDEBUG -void KURL::print() const -{ - printf("%s\n", m_string.utf8().data()); } -#endif - -} - -#endif // !USE(GOOGLEURL) diff --git a/Source/WebCore/platform/KURL.h b/Source/WebCore/platform/KURL.h index 521e7ca..be72824 100644 --- a/Source/WebCore/platform/KURL.h +++ b/Source/WebCore/platform/KURL.h @@ -30,7 +30,7 @@ #include "URLString.h" #include <wtf/HashMap.h> -#if PLATFORM(CF) +#if USE(CF) typedef const struct __CFURL* CFURLRef; #endif @@ -96,6 +96,8 @@ public: const url_parse::Parsed& parsed, bool isValid); #endif + String strippedForUseAsReferrer() const; + // FIXME: The above functions should be harmonized so that passing a // base of null or the empty string gives the same result as the // standard String constructor. @@ -190,7 +192,7 @@ public: unsigned pathAfterLastSlash() const; operator const String&() const { return string(); } -#if PLATFORM(CF) +#if USE(CF) KURL(CFURLRef); CFURLRef createCFURL() const; #endif diff --git a/Source/WebCore/platform/KURLGoogle.cpp b/Source/WebCore/platform/KURLGoogle.cpp index 0697b33..231c43d 100644 --- a/Source/WebCore/platform/KURLGoogle.cpp +++ b/Source/WebCore/platform/KURLGoogle.cpp @@ -381,7 +381,7 @@ KURL::KURL(const CString& canonicalSpec, m_url.setAscii(canonicalSpec); } -#if PLATFORM(CF) +#if USE(CF) KURL::KURL(CFURLRef) { notImplemented(); @@ -758,161 +758,6 @@ String KURL::prettyURL() const return m_url.string(); } -bool protocolIsJavaScript(const String& url) -{ - return protocolIs(url, "javascript"); -} - -// We copied the KURL version here on Dec 4, 2009 while doing a WebKit -// merge. -// -// FIXME Somehow share this with KURL? Like we'd theoretically merge with -// decodeURLEscapeSequences below? -bool isDefaultPortForProtocol(unsigned short port, const String& protocol) -{ - if (protocol.isEmpty()) - return false; - - typedef HashMap<String, unsigned, CaseFoldingHash> DefaultPortsMap; - DEFINE_STATIC_LOCAL(DefaultPortsMap, defaultPorts, ()); - if (defaultPorts.isEmpty()) { - defaultPorts.set("http", 80); - defaultPorts.set("https", 443); - defaultPorts.set("ftp", 21); - defaultPorts.set("ftps", 990); - } - return defaultPorts.get(protocol) == port; -} - -// We copied the KURL version here on Dec 4, 2009 while doing a WebKit -// merge. -// -// FIXME Somehow share this with KURL? Like we'd theoretically merge with -// decodeURLEscapeSequences below? -bool portAllowed(const KURL& url) -{ - unsigned short port = url.port(); - - // Since most URLs don't have a port, return early for the "no port" case. - if (!port) - return true; - - // This blocked port list matches the port blocking that Mozilla implements. - // See http://www.mozilla.org/projects/netlib/PortBanning.html for more information. - static const unsigned short blockedPortList[] = { - 1, // tcpmux - 7, // echo - 9, // discard - 11, // systat - 13, // daytime - 15, // netstat - 17, // qotd - 19, // chargen - 20, // FTP-data - 21, // FTP-control - 22, // SSH - 23, // telnet - 25, // SMTP - 37, // time - 42, // name - 43, // nicname - 53, // domain - 77, // priv-rjs - 79, // finger - 87, // ttylink - 95, // supdup - 101, // hostriame - 102, // iso-tsap - 103, // gppitnp - 104, // acr-nema - 109, // POP2 - 110, // POP3 - 111, // sunrpc - 113, // auth - 115, // SFTP - 117, // uucp-path - 119, // nntp - 123, // NTP - 135, // loc-srv / epmap - 139, // netbios - 143, // IMAP2 - 179, // BGP - 389, // LDAP - 465, // SMTP+SSL - 512, // print / exec - 513, // login - 514, // shell - 515, // printer - 526, // tempo - 530, // courier - 531, // Chat - 532, // netnews - 540, // UUCP - 556, // remotefs - 563, // NNTP+SSL - 587, // ESMTP - 601, // syslog-conn - 636, // LDAP+SSL - 993, // IMAP+SSL - 995, // POP3+SSL - 2049, // NFS - 3659, // apple-sasl / PasswordServer [Apple addition] - 4045, // lockd - 6000, // X11 - 6665, // Alternate IRC [Apple addition] - 6666, // Alternate IRC [Apple addition] - 6667, // Standard IRC [Apple addition] - 6668, // Alternate IRC [Apple addition] - 6669, // Alternate IRC [Apple addition] - invalidPortNumber, // Used to block all invalid port numbers - }; - const unsigned short* const blockedPortListEnd = blockedPortList + WTF_ARRAY_LENGTH(blockedPortList); - -#ifndef NDEBUG - // The port list must be sorted for binary_search to work. - static bool checkedPortList = false; - if (!checkedPortList) { - for (const unsigned short* p = blockedPortList; p != blockedPortListEnd - 1; ++p) - ASSERT(*p < *(p + 1)); - checkedPortList = true; - } -#endif - - // If the port is not in the blocked port list, allow it. - if (!binary_search(blockedPortList, blockedPortListEnd, port)) - return true; - - // Allow ports 21 and 22 for FTP URLs, as Mozilla does. - if ((port == 21 || port == 22) && url.protocolIs("ftp")) - return true; - - // Allow any port number in a file URL, since the port number is ignored. - if (url.protocolIs("file")) - return true; - - return false; -} - -// We copied the KURL version here on Sept 12, 2008 while doing a WebKit -// merge. -// -// FIXME Somehow share this with KURL? Like we'd theoretically merge with -// decodeURLEscapeSequences below? -String mimeTypeFromDataURL(const String& url) -{ - ASSERT(protocolIs(url, "data")); - int index = url.find(';'); - if (index == -1) - index = url.find(','); - if (index != -1) { - int len = index - 5; - if (len > 0) - return url.substring(5, len); - return "text/plain"; // Data URLs with no MIME type are considered text/plain. - } - return ""; -} - String decodeURLEscapeSequences(const String& str) { return decodeURLEscapeSequences(str, UTF8Encoding()); @@ -968,11 +813,6 @@ bool KURL::protocolIs(const char* protocol) const protocol); } -bool KURL::isLocalFile() const -{ - return protocolIs("file"); -} - // This is called to escape a URL string. It is only used externally when // constructing mailto: links to set the query section. Since our query setter // will automatically do the correct escaping, this function does not have to @@ -1075,12 +915,6 @@ unsigned KURL::pathAfterLastSlash() const return filename.begin; } -const KURL& blankURL() -{ - static KURL staticBlankURL(ParsedURLString, "about:blank"); - return staticBlankURL; -} - bool protocolIs(const String& url, const char* protocol) { // Do the comparison without making a new string object. diff --git a/Source/WebCore/platform/Length.cpp b/Source/WebCore/platform/Length.cpp index 323705a..2169d99 100644 --- a/Source/WebCore/platform/Length.cpp +++ b/Source/WebCore/platform/Length.cpp @@ -123,7 +123,7 @@ PassOwnArrayPtr<Length> newLengthArray(const String& string, int& len) RefPtr<StringImpl> str = string.impl()->simplifyWhiteSpace(); if (!str->length()) { len = 1; - return 0; + return nullptr; } len = countCharacter(str->characters(), str->length(), ',') + 1; diff --git a/Source/WebCore/platform/Length.h b/Source/WebCore/platform/Length.h index 1571944..886dfec 100644 --- a/Source/WebCore/platform/Length.h +++ b/Source/WebCore/platform/Length.h @@ -34,7 +34,7 @@ const int percentScaleFactor = 128; const int intMaxForLength = 0x7ffffff; // max value for a 28-bit int const int intMinForLength = (-0x7ffffff - 1); // min value for a 28-bit int -enum LengthType { Auto, Relative, Percent, Fixed, Static, Intrinsic, MinIntrinsic }; +enum LengthType { Auto, Relative, Percent, Fixed, Intrinsic, MinIntrinsic }; struct Length { WTF_MAKE_FAST_ALLOCATED; @@ -163,7 +163,6 @@ public: bool isRelative() const { return type() == Relative; } bool isPercent() const { return type() == Percent; } bool isFixed() const { return type() == Fixed; } - bool isStatic() const { return type() == Static; } bool isIntrinsicOrAuto() const { return type() == Auto || type() == MinIntrinsic || type() == Intrinsic; } Length blend(const Length& from, double progress) const diff --git a/Source/WebCore/platform/LocalizationStrategy.h b/Source/WebCore/platform/LocalizationStrategy.h index 3ed84d9..eba0e7c 100644 --- a/Source/WebCore/platform/LocalizationStrategy.h +++ b/Source/WebCore/platform/LocalizationStrategy.h @@ -43,6 +43,7 @@ public: virtual String submitButtonDefaultLabel() = 0; virtual String fileButtonChooseFileLabel() = 0; virtual String fileButtonNoFileSelectedLabel() = 0; + virtual String defaultDetailsSummaryText() = 0; #if PLATFORM(MAC) virtual String copyImageUnknownFileLabel() = 0; @@ -55,7 +56,7 @@ public: virtual String contextMenuItemTagOpenImageInNewWindow() = 0; virtual String contextMenuItemTagDownloadImageToDisk() = 0; virtual String contextMenuItemTagCopyImageToClipboard() = 0; -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) virtual String contextMenuItemTagCopyImageUrlToClipboard() = 0; #endif virtual String contextMenuItemTagOpenFrameInNewWindow() = 0; diff --git a/Source/WebCore/platform/LocalizedStrings.cpp b/Source/WebCore/platform/LocalizedStrings.cpp index 77144a9..9656dbe 100644 --- a/Source/WebCore/platform/LocalizedStrings.cpp +++ b/Source/WebCore/platform/LocalizedStrings.cpp @@ -66,6 +66,11 @@ String fileButtonNoFileSelectedLabel() return platformStrategies()->localizationStrategy()->fileButtonNoFileSelectedLabel(); } +String defaultDetailsSummaryText() +{ + return platformStrategies()->localizationStrategy()->defaultDetailsSummaryText(); +} + #if PLATFORM(MAC) String copyImageUnknownFileLabel() { @@ -104,7 +109,7 @@ String contextMenuItemTagCopyImageToClipboard() return platformStrategies()->localizationStrategy()->contextMenuItemTagCopyImageToClipboard(); } -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) String contextMenuItemTagCopyImageUrlToClipboard() { return platformStrategies()->localizationStrategy()->contextMenuItemTagCopyImageUrlToClipboard(); diff --git a/Source/WebCore/platform/LocalizedStrings.h b/Source/WebCore/platform/LocalizedStrings.h index 812300f..f22c975 100644 --- a/Source/WebCore/platform/LocalizedStrings.h +++ b/Source/WebCore/platform/LocalizedStrings.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006, 2009 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2003, 2006, 2009, 2011 Apple Inc. All rights reserved. * Copyright (C) 2010 Igalia S.L * * Redistribution and use in source and binary forms, with or without @@ -39,6 +39,7 @@ namespace WebCore { String submitButtonDefaultLabel(); String fileButtonChooseFileLabel(); String fileButtonNoFileSelectedLabel(); + String defaultDetailsSummaryText(); #if PLATFORM(MAC) String copyImageUnknownFileLabel(); @@ -51,7 +52,7 @@ namespace WebCore { String contextMenuItemTagOpenImageInNewWindow(); String contextMenuItemTagDownloadImageToDisk(); String contextMenuItemTagCopyImageToClipboard(); -#if PLATFORM(QT) +#if PLATFORM(QT) || PLATFORM(GTK) String contextMenuItemTagCopyImageUrlToClipboard(); #endif String contextMenuItemTagOpenFrameInNewWindow(); @@ -186,6 +187,10 @@ namespace WebCore { String validationMessageRangeOverflowText(const String& maximum); String validationMessageStepMismatchText(const String& base, const String& step); -} - +#if PLATFORM(MAC) + String localizedString(const char* key); #endif + +} // namespace WebCore + +#endif // LocalizedStrings_h diff --git a/Source/WebCore/platform/Pasteboard.h b/Source/WebCore/platform/Pasteboard.h index 50a9cb6..b5ab690 100644 --- a/Source/WebCore/platform/Pasteboard.h +++ b/Source/WebCore/platform/Pasteboard.h @@ -86,7 +86,7 @@ class Pasteboard { public: #if PLATFORM(MAC) //Helper functions to allow Clipboard to share code - static void writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame); + static void writeSelection(NSPasteboard*, NSArray* pasteboardTypes, Range* selectedRange, bool canSmartCopyOrDelete, Frame*); static void writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& url, const String& titleStr, Frame* frame); static void writePlainText(NSPasteboard* pasteboard, const String& text); diff --git a/Source/WebCore/platform/PlatformKeyboardEvent.h b/Source/WebCore/platform/PlatformKeyboardEvent.h index eb144f7..fcca8bd 100644 --- a/Source/WebCore/platform/PlatformKeyboardEvent.h +++ b/Source/WebCore/platform/PlatformKeyboardEvent.h @@ -175,6 +175,11 @@ namespace WebCore { #if PLATFORM(GTK) PlatformKeyboardEvent(GdkEventKey*); GdkEventKey* gdkEventKey() const; + + // Used by WebKit2 + static String keyIdentifierForGdkKeyCode(unsigned); + static int windowsKeyCodeForGdkKeyCode(unsigned); + static String singleCharacterString(unsigned); #endif #if PLATFORM(ANDROID) diff --git a/Source/WebCore/platform/PlatformStrategies.h b/Source/WebCore/platform/PlatformStrategies.h index c02ce00..bda7c90 100644 --- a/Source/WebCore/platform/PlatformStrategies.h +++ b/Source/WebCore/platform/PlatformStrategies.h @@ -30,12 +30,20 @@ namespace WebCore { +class CookiesStrategy; class PluginStrategy; class LocalizationStrategy; class VisitedLinkStrategy; class PlatformStrategies { public: + CookiesStrategy* cookiesStrategy() + { + if (!m_cookiesStrategy) + m_cookiesStrategy = createCookiesStrategy(); + return m_cookiesStrategy; + } + PluginStrategy* pluginStrategy() { if (!m_pluginStrategy) @@ -59,7 +67,8 @@ public: protected: PlatformStrategies() - : m_pluginStrategy(0) + : m_cookiesStrategy(0) + , m_pluginStrategy(0) , m_localizationStrategy(0) , m_visitedLinkStrategy(0) { @@ -70,10 +79,12 @@ protected: } private: + virtual CookiesStrategy* createCookiesStrategy() = 0; virtual PluginStrategy* createPluginStrategy() = 0; virtual LocalizationStrategy* createLocalizationStrategy() = 0; virtual VisitedLinkStrategy* createVisitedLinkStrategy() = 0; + CookiesStrategy* m_cookiesStrategy; PluginStrategy* m_pluginStrategy; LocalizationStrategy* m_localizationStrategy; VisitedLinkStrategy* m_visitedLinkStrategy; diff --git a/Source/WebCore/platform/PlatformTouchEvent.h b/Source/WebCore/platform/PlatformTouchEvent.h index 009e33b..080f2f9 100644 --- a/Source/WebCore/platform/PlatformTouchEvent.h +++ b/Source/WebCore/platform/PlatformTouchEvent.h @@ -66,6 +66,7 @@ public: , m_altKey(false) , m_shiftKey(false) , m_metaKey(false) + , m_timestamp(0) {} #if PLATFORM(QT) PlatformTouchEvent(QTouchEvent*); @@ -86,6 +87,9 @@ public: bool shiftKey() const { return m_shiftKey; } bool metaKey() const { return m_metaKey; } + // Time in seconds. + double timestamp() const { return m_timestamp; } + protected: TouchEventType m_type; Vector<PlatformTouchPoint> m_touchPoints; @@ -93,6 +97,7 @@ protected: bool m_altKey; bool m_shiftKey; bool m_metaKey; + double m_timestamp; }; } diff --git a/Source/WebCore/platform/PlatformWheelEvent.h b/Source/WebCore/platform/PlatformWheelEvent.h index 2698e6e..3765553 100644 --- a/Source/WebCore/platform/PlatformWheelEvent.h +++ b/Source/WebCore/platform/PlatformWheelEvent.h @@ -100,6 +100,7 @@ namespace WebCore { #if PLATFORM(MAC) , m_hasPreciseScrollingDeltas(false) , m_phase(PlatformWheelEventPhaseNone) + , m_momentumPhase(PlatformWheelEventPhaseNone) , m_timestamp(0) #endif { @@ -153,6 +154,7 @@ namespace WebCore { #endif PlatformWheelEventPhase phase() const { return m_phase; } + PlatformWheelEventPhase momentumPhase() const { return m_momentumPhase; } bool hasPreciseScrollingDeltas() const { return m_hasPreciseScrollingDeltas; } double timestamp() const { return m_timestamp; } #endif @@ -192,6 +194,7 @@ namespace WebCore { #if PLATFORM(MAC) bool m_hasPreciseScrollingDeltas; PlatformWheelEventPhase m_phase; + PlatformWheelEventPhase m_momentumPhase; double m_timestamp; #endif }; diff --git a/Source/WebCore/platform/RunLoopTimer.h b/Source/WebCore/platform/RunLoopTimer.h index f8c529f..867b159 100644 --- a/Source/WebCore/platform/RunLoopTimer.h +++ b/Source/WebCore/platform/RunLoopTimer.h @@ -56,7 +56,7 @@ public: virtual void fired() = 0; private: -#if PLATFORM(CF) +#if USE(CF) RetainPtr<CFRunLoopTimerRef> m_timer; #endif }; diff --git a/Source/WebCore/platform/ScrollView.cpp b/Source/WebCore/platform/ScrollView.cpp index cab58e4..baf2e32 100644 --- a/Source/WebCore/platform/ScrollView.cpp +++ b/Source/WebCore/platform/ScrollView.cpp @@ -92,10 +92,10 @@ void ScrollView::setHasHorizontalScrollbar(bool hasBar) if (hasBar && !m_horizontalScrollbar) { m_horizontalScrollbar = createScrollbar(HorizontalScrollbar); addChild(m_horizontalScrollbar.get()); - ScrollableArea::didAddHorizontalScrollbar(m_horizontalScrollbar.get()); + didAddHorizontalScrollbar(m_horizontalScrollbar.get()); m_horizontalScrollbar->styleChanged(); } else if (!hasBar && m_horizontalScrollbar) { - ScrollableArea::willRemoveHorizontalScrollbar(m_horizontalScrollbar.get()); + willRemoveHorizontalScrollbar(m_horizontalScrollbar.get()); removeChild(m_horizontalScrollbar.get()); m_horizontalScrollbar = 0; } @@ -112,10 +112,10 @@ void ScrollView::setHasVerticalScrollbar(bool hasBar) if (hasBar && !m_verticalScrollbar) { m_verticalScrollbar = createScrollbar(VerticalScrollbar); addChild(m_verticalScrollbar.get()); - ScrollableArea::didAddVerticalScrollbar(m_verticalScrollbar.get()); + didAddVerticalScrollbar(m_verticalScrollbar.get()); m_verticalScrollbar->styleChanged(); } else if (!hasBar && m_verticalScrollbar) { - ScrollableArea::willRemoveVerticalScrollbar(m_verticalScrollbar.get()); + willRemoveVerticalScrollbar(m_verticalScrollbar.get()); removeChild(m_verticalScrollbar.get()); m_verticalScrollbar = 0; } @@ -233,15 +233,14 @@ IntRect ScrollView::visibleContentRect(bool includeScrollbars) const if (paintsEntireContents()) return IntRect(IntPoint(0, 0), contentsSize()); - bool hasOverlayScrollbars = ScrollbarTheme::nativeTheme()->usesOverlayScrollbars(); - int verticalScrollbarWidth = verticalScrollbar() && !hasOverlayScrollbars && !includeScrollbars - ? verticalScrollbar()->width() : 0; - int horizontalScrollbarHeight = horizontalScrollbar() && !hasOverlayScrollbars && !includeScrollbars - ? horizontalScrollbar()->height() : 0; + int verticalScrollbarWidth = verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar() + && !includeScrollbars ? verticalScrollbar()->width() : 0; + int horizontalScrollbarHeight = horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar() + && !includeScrollbars ? horizontalScrollbar()->height() : 0; return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()), - IntSize(max(0, width() - verticalScrollbarWidth), - max(0, height() - horizontalScrollbarHeight))); + IntSize(max(0, m_boundsSize.width() - verticalScrollbarWidth), + max(0, m_boundsSize.height() - horizontalScrollbarHeight))); } #endif @@ -348,31 +347,6 @@ IntPoint ScrollView::adjustScrollPositionWithinRange(const IntPoint& scrollPoint return newScrollPosition; } -int ScrollView::scrollXForFixedPosition() const -{ - int x = scrollX(); - if (x < 0) - x = 0; - else if (x > contentsWidth() - visibleContentRect().width()) - x = contentsWidth() - visibleContentRect().width(); - return x; -} - -int ScrollView::scrollYForFixedPosition() const -{ - int y = scrollY(); - if (y < 0) - y = 0; - else if (y > contentsHeight() - visibleContentRect().height()) - y = contentsHeight() - visibleContentRect().height(); - return y; -} - -IntSize ScrollView::scrollOffsetForFixedPosition() const -{ - return IntSize(scrollXForFixedPosition(), scrollYForFixedPosition()); -} - int ScrollView::scrollSize(ScrollbarOrientation orientation) const { Scrollbar* scrollbar = ((orientation == HorizontalScrollbar) ? m_horizontalScrollbar : m_verticalScrollbar).get(); @@ -525,7 +499,7 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset) bool sendContentResizedNotification = false; IntSize docSize = contentsSize(); - IntSize frameSize = frameRect().size(); + IntSize frameSize = m_boundsSize; if (hScroll == ScrollbarAuto) { newHasHorizontalScrollbar = docSize.width() > visibleWidth(); @@ -590,8 +564,8 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset) int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1); IntRect oldRect(m_horizontalScrollbar->frameRect()); IntRect hBarRect = IntRect(0, - height() - m_horizontalScrollbar->height(), - width() - (m_verticalScrollbar ? m_verticalScrollbar->width() : 0), + m_boundsSize.height() - m_horizontalScrollbar->height(), + m_boundsSize.width() - (m_verticalScrollbar ? m_verticalScrollbar->width() : 0), m_horizontalScrollbar->height()); m_horizontalScrollbar->setFrameRect(hBarRect); if (!m_scrollbarsSuppressed && oldRect != m_horizontalScrollbar->frameRect()) @@ -610,10 +584,10 @@ void ScrollView::updateScrollbars(const IntSize& desiredOffset) m_verticalScrollbar->setEnabled(contentsHeight() > clientHeight); int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1); IntRect oldRect(m_verticalScrollbar->frameRect()); - IntRect vBarRect = IntRect(width() - m_verticalScrollbar->width(), + IntRect vBarRect = IntRect(m_boundsSize.width() - m_verticalScrollbar->width(), 0, m_verticalScrollbar->width(), - height() - (m_horizontalScrollbar ? m_horizontalScrollbar->height() : 0)); + m_boundsSize.height() - (m_horizontalScrollbar ? m_horizontalScrollbar->height() : 0)); m_verticalScrollbar->setFrameRect(vBarRect); if (!m_scrollbarsSuppressed && oldRect != m_verticalScrollbar->frameRect()) m_verticalScrollbar->invalidate(); @@ -653,7 +627,7 @@ void ScrollView::scrollContents(const IntSize& scrollDelta) // with the clip rect every time to keep it smooth. IntRect clipRect = windowClipRect(); IntRect scrollViewRect = convertToContainingWindow(IntRect(0, 0, visibleWidth(), visibleHeight())); - if (ScrollbarTheme::nativeTheme()->usesOverlayScrollbars()) { + if (hasOverlayScrollbars()) { int verticalScrollbarWidth = verticalScrollbar() ? verticalScrollbar()->width() : 0; int horizontalScrollbarHeight = horizontalScrollbar() ? horizontalScrollbar()->height() : 0; @@ -687,6 +661,15 @@ void ScrollView::scrollContents(const IntSize& scrollDelta) scrollContentsSlowPath(updateRect); } + // Invalidate the overhang areas if they are visible. + IntRect horizontalOverhangRect; + IntRect verticalOverhangRect; + calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect); + if (!horizontalOverhangRect.isEmpty()) + hostWindow()->invalidateContentsAndWindow(horizontalOverhangRect, false /*immediate*/); + if (!verticalOverhangRect.isEmpty()) + hostWindow()->invalidateContentsAndWindow(verticalOverhangRect, false /*immediate*/); + // This call will move children with native widgets (plugins) and invalidate them as well. frameRectsChanged(); @@ -849,19 +832,32 @@ void ScrollView::setFrameRect(const IntRect& newRect) return; Widget::setFrameRect(newRect); +} + +void ScrollView::setBoundsSize(const IntSize& newSize) +{ + if (newSize == m_boundsSize) + return; + + Widget::setBoundsSize(newSize); + m_boundsSize = newSize; if (platformWidget()) return; - - if (newRect.width() != oldRect.width() || newRect.height() != oldRect.height()) { - updateScrollbars(m_scrollOffset); - if (!m_useFixedLayout) - contentsResized(); - } + + updateScrollbars(m_scrollOffset); + if (!m_useFixedLayout) + contentsResized(); frameRectsChanged(); } +void ScrollView::setInitialBoundsSize(const IntSize& newSize) +{ + ASSERT(m_boundsSize.isZero()); + m_boundsSize = newSize; +} + void ScrollView::frameRectsChanged() { if (platformWidget()) @@ -896,21 +892,21 @@ IntRect ScrollView::scrollCornerRect() const { IntRect cornerRect; - if (ScrollbarTheme::nativeTheme()->usesOverlayScrollbars()) + if (hasOverlayScrollbars()) return cornerRect; - if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) { + if (m_horizontalScrollbar && m_boundsSize.width() - m_horizontalScrollbar->width() > 0) { cornerRect.unite(IntRect(m_horizontalScrollbar->width(), - height() - m_horizontalScrollbar->height(), - width() - m_horizontalScrollbar->width(), + m_boundsSize.height() - m_horizontalScrollbar->height(), + m_boundsSize.width() - m_horizontalScrollbar->width(), m_horizontalScrollbar->height())); } - if (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0) { - cornerRect.unite(IntRect(width() - m_verticalScrollbar->width(), + if (m_verticalScrollbar && m_boundsSize.height() - m_verticalScrollbar->height() > 0) { + cornerRect.unite(IntRect(m_boundsSize.width() - m_verticalScrollbar->width(), m_verticalScrollbar->height(), m_verticalScrollbar->width(), - height() - m_verticalScrollbar->height())); + m_boundsSize.height() - m_verticalScrollbar->height())); } return cornerRect; @@ -999,9 +995,10 @@ void ScrollView::paint(GraphicsContext* context, const IntRect& rect) void ScrollView::calculateOverhangAreasForPainting(IntRect& horizontalOverhangRect, IntRect& verticalOverhangRect) { - bool hasOverlayScrollbars = ScrollbarTheme::nativeTheme()->usesOverlayScrollbars(); - int verticalScrollbarWidth = (verticalScrollbar() && !hasOverlayScrollbars) ? verticalScrollbar()->width() : 0; - int horizontalScrollbarHeight = (horizontalScrollbar() && !hasOverlayScrollbars) ? horizontalScrollbar()->height() : 0; + int verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) + ? verticalScrollbar()->width() : 0; + int horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) + ? horizontalScrollbar()->height() : 0; if (scrollY() < 0) { horizontalOverhangRect = frameRect(); @@ -1070,8 +1067,8 @@ bool ScrollView::isPointInScrollbarCorner(const IntPoint& windowPoint) bool ScrollView::scrollbarCornerPresent() const { - return (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) || - (m_verticalScrollbar && height() - m_verticalScrollbar->height() > 0); + return (m_horizontalScrollbar && m_boundsSize.width() - m_horizontalScrollbar->width() > 0) || + (m_verticalScrollbar && m_boundsSize.height() - m_verticalScrollbar->height() > 0); } IntRect ScrollView::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& localRect) const @@ -1210,7 +1207,7 @@ void ScrollView::platformDestroy() #endif -#if !PLATFORM(WX) && !PLATFORM(GTK) && !PLATFORM(QT) && !PLATFORM(MAC) +#if !PLATFORM(WX) && !PLATFORM(QT) && !PLATFORM(MAC) void ScrollView::platformAddChild(Widget*) { diff --git a/Source/WebCore/platform/ScrollView.h b/Source/WebCore/platform/ScrollView.h index 7df735a..1d6fba5 100644 --- a/Source/WebCore/platform/ScrollView.h +++ b/Source/WebCore/platform/ScrollView.h @@ -180,11 +180,6 @@ public: int scrollX() const { return scrollPosition().x(); } int scrollY() const { return scrollPosition().y(); } - // Functions for querying the current scrolled position, negating the effects of overhang. - int scrollXForFixedPosition() const; - int scrollYForFixedPosition() const; - IntSize scrollOffsetForFixedPosition() const; - IntSize overhangAmount() const; // Functions for scrolling the view. @@ -234,6 +229,7 @@ public: // Widget override to update our scrollbars and notify our contents of the resize. virtual void setFrameRect(const IntRect&); + virtual void setBoundsSize(const IntSize&); // For platforms that need to hit test scrollbars from within the engine's event handlers (like Win32). Scrollbar* scrollbarAtPoint(const IntPoint& windowPoint); @@ -299,6 +295,9 @@ protected: virtual void contentsResized() = 0; virtual void visibleContentsResized() = 0; + IntSize boundsSize() const { return m_boundsSize; } + void setInitialBoundsSize(const IntSize&); + // These functions are used to create/destroy scrollbars. void setHasHorizontalScrollbar(bool); void setHasVerticalScrollbar(bool); @@ -368,6 +367,8 @@ private: // vertical-rl / rtl YES YES IntPoint m_scrollOrigin; + IntSize m_boundsSize; + void init(); void destroy(); diff --git a/Source/WebCore/platform/ScrollableArea.cpp b/Source/WebCore/platform/ScrollableArea.cpp index 00017bd..34cec9e 100644 --- a/Source/WebCore/platform/ScrollableArea.cpp +++ b/Source/WebCore/platform/ScrollableArea.cpp @@ -128,17 +128,26 @@ void ScrollableArea::setScrollOffsetFromAnimation(const IntPoint& offset) // Tell the derived class to scroll its contents. setScrollOffset(offset); - bool hasOverlayScrollbars = ScrollbarTheme::nativeTheme()->usesOverlayScrollbars(); + Scrollbar* verticalScrollbar = this->verticalScrollbar(); // Tell the scrollbars to update their thumb postions. if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) { horizontalScrollbar->offsetDidChange(); - if (hasOverlayScrollbars) - horizontalScrollbar->invalidate(); + if (horizontalScrollbar->isOverlayScrollbar()) { + if (!verticalScrollbar) + horizontalScrollbar->invalidate(); + else { + // If there is both a horizontalScrollbar and a verticalScrollbar, + // then we must also invalidate the corner between them. + IntRect boundsAndCorner = horizontalScrollbar->boundsRect(); + boundsAndCorner.setWidth(boundsAndCorner.width() + verticalScrollbar->width()); + horizontalScrollbar->invalidateRect(boundsAndCorner); + } + } } - if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) { + if (verticalScrollbar) { verticalScrollbar->offsetDidChange(); - if (hasOverlayScrollbars) + if (verticalScrollbar->isOverlayScrollbar()) verticalScrollbar->invalidate(); } } @@ -179,4 +188,10 @@ void ScrollableArea::willRemoveHorizontalScrollbar(Scrollbar* scrollbar) scrollAnimator()->willRemoveHorizontalScrollbar(scrollbar); } +bool ScrollableArea::hasOverlayScrollbars() const +{ + return (verticalScrollbar() && verticalScrollbar()->isOverlayScrollbar()) + || (horizontalScrollbar() && horizontalScrollbar()->isOverlayScrollbar()); +} + } // namespace WebCore diff --git a/Source/WebCore/platform/ScrollableArea.h b/Source/WebCore/platform/ScrollableArea.h index 9839abc..f1c1308 100644 --- a/Source/WebCore/platform/ScrollableArea.h +++ b/Source/WebCore/platform/ScrollableArea.h @@ -66,6 +66,8 @@ public: void didAddHorizontalScrollbar(Scrollbar*); void willRemoveHorizontalScrollbar(Scrollbar*); + bool hasOverlayScrollbars() const; + ScrollAnimator* scrollAnimator() const { return m_scrollAnimator.get(); } virtual int scrollSize(ScrollbarOrientation) const = 0; @@ -113,8 +115,6 @@ public: virtual IntPoint currentMousePosition() const { return IntPoint(); } virtual void didCompleteRubberBand(const IntSize&) const { ASSERT_NOT_REACHED(); } - virtual bool scrollbarWillRenderIntoCompositingLayer() const { return false; } - private: // NOTE: Only called from the ScrollAnimator. friend class ScrollAnimator; diff --git a/Source/WebCore/platform/Scrollbar.cpp b/Source/WebCore/platform/Scrollbar.cpp index 5d9a43d..ba00ab0 100644 --- a/Source/WebCore/platform/Scrollbar.cpp +++ b/Source/WebCore/platform/Scrollbar.cpp @@ -433,6 +433,11 @@ void Scrollbar::setEnabled(bool e) invalidate(); } +bool Scrollbar::isOverlayScrollbar() const +{ + return m_theme->usesOverlayScrollbars(); +} + bool Scrollbar::isWindowActive() const { return m_scrollableArea && m_scrollableArea->isActive(); diff --git a/Source/WebCore/platform/Scrollbar.h b/Source/WebCore/platform/Scrollbar.h index 5db191a..267eada 100644 --- a/Source/WebCore/platform/Scrollbar.h +++ b/Source/WebCore/platform/Scrollbar.h @@ -86,6 +86,8 @@ public: bool enabled() const { return m_enabled; } virtual void setEnabled(bool e); + virtual bool isOverlayScrollbar() const; + bool isWindowActive() const; // These methods are used for platform scrollbars to give :hover feedback. They will not get called diff --git a/Source/WebCore/platform/ScrollbarTheme.h b/Source/WebCore/platform/ScrollbarTheme.h index ef52b0d..f5a10b7 100644 --- a/Source/WebCore/platform/ScrollbarTheme.h +++ b/Source/WebCore/platform/ScrollbarTheme.h @@ -76,7 +76,8 @@ public: virtual void invalidatePart(Scrollbar*, ScrollbarPart) {} - virtual void paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect) { context->fillRect(cornerRect, Color::white, ColorSpaceDeviceRGB); } + virtual void paintScrollCorner(ScrollView*, GraphicsContext* context, const IntRect& cornerRect) { defaultPaintScrollCorner(context, cornerRect); } + static void defaultPaintScrollCorner(GraphicsContext* context, const IntRect& cornerRect) { context->fillRect(cornerRect, Color::white, ColorSpaceDeviceRGB); } virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&) { return false; } virtual bool shouldSnapBackToDragOrigin(Scrollbar*, const PlatformMouseEvent&) { return false; } diff --git a/Source/WebCore/platform/SharedBuffer.cpp b/Source/WebCore/platform/SharedBuffer.cpp index 35a7b7c..34553ec 100644 --- a/Source/WebCore/platform/SharedBuffer.cpp +++ b/Source/WebCore/platform/SharedBuffer.cpp @@ -239,7 +239,7 @@ unsigned SharedBuffer::getSomeData(const char*& someData, unsigned position) con return segment == segments - 1 ? segmentedSize - position : segmentSize - positionInSegment; } -#if !PLATFORM(CF) || PLATFORM(QT) +#if !USE(CF) || PLATFORM(QT) inline void SharedBuffer::clearPlatformData() { diff --git a/Source/WebCore/platform/SharedBuffer.h b/Source/WebCore/platform/SharedBuffer.h index 73afadf..dfde5a1 100644 --- a/Source/WebCore/platform/SharedBuffer.h +++ b/Source/WebCore/platform/SharedBuffer.h @@ -32,7 +32,7 @@ #include <wtf/RefCounted.h> #include <wtf/Vector.h> -#if PLATFORM(CF) +#if USE(CF) #include <wtf/RetainPtr.h> #endif @@ -72,7 +72,7 @@ public: NSData *createNSData(); static PassRefPtr<SharedBuffer> wrapNSData(NSData *data); #endif -#if PLATFORM(CF) +#if USE(CF) CFDataRef createCFData(); static PassRefPtr<SharedBuffer> wrapCFData(CFDataRef); #endif @@ -89,10 +89,6 @@ public: #endif unsigned size() const; - // Calling this function will force internal segmented buffers - // to be merged into a flat buffer. Use getSomeData() whenever possible - // for better performance. - const Vector<char>& buffer() const; bool isEmpty() const { return !size(); } @@ -127,6 +123,13 @@ private: SharedBuffer(const char*, int); SharedBuffer(const unsigned char*, int); + // Calling this function will force internal segmented buffers + // to be merged into a flat buffer. Use getSomeData() whenever possible + // for better performance. + // As well, be aware that this method does *not* return any purgeable + // memory, which can be a source of bugs. + const Vector<char>& buffer() const; + void clearPlatformData(); void maybeTransferPlatformData(); bool hasPlatformData() const; @@ -135,7 +138,7 @@ private: mutable Vector<char> m_buffer; mutable Vector<char*> m_segments; OwnPtr<PurgeableBuffer> m_purgeableBuffer; -#if PLATFORM(CF) +#if USE(CF) SharedBuffer(CFDataRef); RetainPtr<CFDataRef> m_cfData; #endif diff --git a/Source/WebCore/platform/Timer.h b/Source/WebCore/platform/Timer.h index c331e3d..3138345 100644 --- a/Source/WebCore/platform/Timer.h +++ b/Source/WebCore/platform/Timer.h @@ -52,7 +52,8 @@ public: double nextFireInterval() const; double repeatInterval() const { return m_repeatInterval; } - void augmentRepeatInterval(double delta) { setNextFireTime(m_nextFireTime + delta); m_repeatInterval += delta; } + void augmentFireInterval(double delta) { setNextFireTime(m_nextFireTime + delta); } + void augmentRepeatInterval(double delta) { augmentFireInterval(delta); m_repeatInterval += delta; } static void fireTimersInNestedEventLoop(); diff --git a/Source/WebCore/platform/UUID.cpp b/Source/WebCore/platform/UUID.cpp index c072f4a..7f59081 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) && PLATFORM(CF) +#elif OS(DARWIN) && USE(CF) #include <CoreFoundation/CoreFoundation.h> #elif OS(LINUX) && !PLATFORM(CHROMIUM) #include <stdio.h> -#elif (OS(LINUX) && PLATFORM(CHROMIUM)) || (OS(DARWIN) && !PLATFORM(CF)) +#elif (OS(LINUX) && PLATFORM(CHROMIUM)) || (OS(DARWIN) && !USE(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) && PLATFORM(CF) +#elif OS(DARWIN) && USE(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)) || (OS(DARWIN) && !PLATFORM(CF)) +#elif (OS(LINUX) && PLATFORM(CHROMIUM)) || (OS(DARWIN) && !USE(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.h b/Source/WebCore/platform/Widget.h index a6562ef..00b3912 100644 --- a/Source/WebCore/platform/Widget.h +++ b/Source/WebCore/platform/Widget.h @@ -162,8 +162,8 @@ public: virtual IntRect frameRect() const; IntRect boundsRect() const { return IntRect(0, 0, width(), height()); } - void resize(int w, int h) { setFrameRect(IntRect(x(), y(), w, h)); } - void resize(const IntSize& s) { setFrameRect(IntRect(pos(), s)); } + void resize(int w, int h) { setFrameRect(IntRect(x(), y(), w, h)); setBoundsSize(IntSize(w, h)); } + void resize(const IntSize& s) { setFrameRect(IntRect(pos(), s)); setBoundsSize(s); } void move(int x, int y) { setFrameRect(IntRect(x, y, width(), height())); } void move(const IntPoint& p) { setFrameRect(IntRect(p, size())); } diff --git a/Source/WebCore/platform/android/LocalizedStringsAndroid.cpp b/Source/WebCore/platform/android/LocalizedStringsAndroid.cpp index 18117f9..5a96cf6 100644 --- a/Source/WebCore/platform/android/LocalizedStringsAndroid.cpp +++ b/Source/WebCore/platform/android/LocalizedStringsAndroid.cpp @@ -386,6 +386,11 @@ String resetButtonDefaultLabel() PlatformBridge::ResetLabel)); } +String defaultDetailsSummaryText() +{ + return String("Details"); +} + String submitButtonDefaultLabel() { return *(PlatformBridge::globalLocalizedName( diff --git a/Source/WebCore/platform/android/PlatformTouchEventAndroid.cpp b/Source/WebCore/platform/android/PlatformTouchEventAndroid.cpp index 84af56d..ba3b086 100644 --- a/Source/WebCore/platform/android/PlatformTouchEventAndroid.cpp +++ b/Source/WebCore/platform/android/PlatformTouchEventAndroid.cpp @@ -25,6 +25,7 @@ #include "config.h" #include "PlatformTouchEvent.h" +#include <wtf/CurrentTime.h> #if ENABLE(TOUCH_EVENTS) @@ -41,6 +42,7 @@ enum AndroidMetaKeyState { PlatformTouchEvent::PlatformTouchEvent(const Vector<int>& ids, const Vector<IntPoint>& windowPoints, TouchEventType type, const Vector<PlatformTouchPoint::State>& states, int metaState) : m_type(type) , m_metaKey(false) + , m_timestamp(WTF::currentTime()) { m_touchPoints.reserveCapacity(windowPoints.size()); for (unsigned c = 0; c < windowPoints.size(); c++) diff --git a/Source/WebCore/platform/android/TemporaryLinkStubs.cpp b/Source/WebCore/platform/android/TemporaryLinkStubs.cpp index a046775..126400a 100644 --- a/Source/WebCore/platform/android/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/android/TemporaryLinkStubs.cpp @@ -488,4 +488,14 @@ void setCookieStoragePrivateBrowsingEnabled(bool) notImplemented(); } +void startObservingCookieChanges() +{ + notImplemented(); +} + +void stopObservingCookieChanges() +{ + notImplemented(); +} + } // namespace WebCore diff --git a/Source/WebCore/platform/animation/TimingFunction.h b/Source/WebCore/platform/animation/TimingFunction.h index 8ef2d8f..5ab3c1c 100644 --- a/Source/WebCore/platform/animation/TimingFunction.h +++ b/Source/WebCore/platform/animation/TimingFunction.h @@ -76,11 +76,16 @@ private: class CubicBezierTimingFunction : public TimingFunction { public: - static PassRefPtr<CubicBezierTimingFunction> create(double x1 = 0.25, double y1 = 0.1, double x2 = 0.25, double y2 = 1.0) + static PassRefPtr<CubicBezierTimingFunction> create(double x1, double y1, double x2, double y2) { return adoptRef(new CubicBezierTimingFunction(x1, y1, x2, y2)); } + static PassRefPtr<CubicBezierTimingFunction> create() + { + return adoptRef(new CubicBezierTimingFunction()); + } + ~CubicBezierTimingFunction() { } virtual bool operator==(const TimingFunction& other) @@ -97,8 +102,14 @@ public: double x2() const { return m_x2; } double y2() const { return m_y2; } + static const CubicBezierTimingFunction* defaultTimingFunction() + { + static const CubicBezierTimingFunction* dtf = create().leakRef(); + return dtf; + } + private: - CubicBezierTimingFunction(double x1, double y1, double x2, double y2) + CubicBezierTimingFunction(double x1 = 0.25, double y1 = 0.1, double x2 = 0.25, double y2 = 1.0) : TimingFunction(CubicBezierFunction) , m_x1(x1) , m_y1(y1) diff --git a/Source/WebCore/platform/brew/LocalizedStringsBrew.cpp b/Source/WebCore/platform/brew/LocalizedStringsBrew.cpp index 08e2002..c4dac1a 100644 --- a/Source/WebCore/platform/brew/LocalizedStringsBrew.cpp +++ b/Source/WebCore/platform/brew/LocalizedStringsBrew.cpp @@ -46,6 +46,11 @@ String resetButtonDefaultLabel() return "Reset"; } +String defaultDetailsSummaryText() +{ + return "Details"; +} + String searchableIndexIntroduction() { return "Searchable Index"; diff --git a/Source/WebCore/platform/brew/TemporaryLinkStubs.cpp b/Source/WebCore/platform/brew/TemporaryLinkStubs.cpp index d75c224..876189f 100644 --- a/Source/WebCore/platform/brew/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/brew/TemporaryLinkStubs.cpp @@ -36,5 +36,15 @@ void setCookieStoragePrivateBrowsingEnabled(bool) notImplemented(); } +void startObservingCookieChanges() +{ + notImplemented(); +} + +void stopObservingCookieChanges() +{ + notImplemented(); +} + } diff --git a/Source/WebCore/platform/cf/RunLoopTimerCF.cpp b/Source/WebCore/platform/cf/RunLoopTimerCF.cpp index e2754fb..f62299e 100644 --- a/Source/WebCore/platform/cf/RunLoopTimerCF.cpp +++ b/Source/WebCore/platform/cf/RunLoopTimerCF.cpp @@ -27,10 +27,11 @@ */ #include "config.h" -#include "RunLoopTimer.h" #if PLATFORM(MAC) && HAVE(RUNLOOP_TIMER) +#include "RunLoopTimer.h" + namespace WebCore { RunLoopTimerBase::~RunLoopTimerBase() diff --git a/Source/WebCore/platform/chromium/ChromiumDataObject.cpp b/Source/WebCore/platform/chromium/ChromiumDataObject.cpp index f5732df..c3632e6 100644 --- a/Source/WebCore/platform/chromium/ChromiumDataObject.cpp +++ b/Source/WebCore/platform/chromium/ChromiumDataObject.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Google Inc. All rights reserved. + * Copyright (c) 2008, 2009, Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,189 +31,235 @@ #include "config.h" #include "ChromiumDataObject.h" +#include "ClipboardMimeTypes.h" +#include "Pasteboard.h" +#include "PlatformBridge.h" + namespace WebCore { -ChromiumDataObject::ChromiumDataObject(PassRefPtr<ChromiumDataObjectLegacy> data) - : RefCounted<ChromiumDataObject>() - , m_legacyData(data) -{ -} +// Per RFC 2483, the line separator for "text/..." MIME types is CR-LF. +static char const* const textMIMETypeLineSeparator = "\r\n"; -ChromiumDataObject::ChromiumDataObject(PassRefPtr<ReadableDataObject> data) - : RefCounted<ChromiumDataObject>() - , m_readableData(data) +void ChromiumDataObject::clearData(const String& type) { -} + if (type == mimeTypeTextPlain) { + m_plainText = ""; + return; + } -ChromiumDataObject::ChromiumDataObject(PassRefPtr<WritableDataObject> data) - : RefCounted<ChromiumDataObject>() - , m_writableData(data) -{ -} + if (type == mimeTypeURL || type == mimeTypeTextURIList) { + m_uriList = ""; + m_url = KURL(); + m_urlTitle = ""; + return; + } -PassRefPtr<ChromiumDataObject> ChromiumDataObject::create(PassRefPtr<ChromiumDataObjectLegacy> data) -{ - return adoptRef(new ChromiumDataObject(data)); -} + if (type == mimeTypeTextHTML) { + m_textHtml = ""; + m_htmlBaseUrl = KURL(); + return; + } -PassRefPtr<ChromiumDataObject> ChromiumDataObject::createReadable(const Frame* frame, Clipboard::ClipboardType clipboardType) -{ - return adoptRef(new ChromiumDataObject(ReadableDataObject::create(frame, clipboardType))); -} - -PassRefPtr<ChromiumDataObject> ChromiumDataObject::createWritable(Clipboard::ClipboardType clipboardType) -{ - return adoptRef(new ChromiumDataObject(WritableDataObject::create(clipboardType))); -} - -void ChromiumDataObject::clearData(const String& type) -{ - if (m_legacyData) - m_legacyData->clearData(type); - else - m_writableData->clearData(type); + if (type == mimeTypeDownloadURL) { + m_downloadMetadata = ""; + return; + } } void ChromiumDataObject::clearAll() { - if (m_legacyData) - m_legacyData->clearAll(); - else - m_writableData->clearAll(); + clearAllExceptFiles(); + m_filenames.clear(); } void ChromiumDataObject::clearAllExceptFiles() { - if (m_legacyData) - m_legacyData->clearAllExceptFiles(); - else - m_writableData->clearAllExceptFiles(); + m_urlTitle = ""; + m_url = KURL(); + m_uriList = ""; + m_downloadMetadata = ""; + m_fileExtension = ""; + m_plainText = ""; + m_textHtml = ""; + m_htmlBaseUrl = KURL(); + m_fileContentFilename = ""; + if (m_fileContent) + m_fileContent->clear(); } bool ChromiumDataObject::hasData() const { - if (m_legacyData) - return m_legacyData->hasData(); - return m_readableData->hasData(); + return !m_url.isEmpty() + || !m_uriList.isEmpty() + || !m_downloadMetadata.isEmpty() + || !m_fileExtension.isEmpty() + || !m_filenames.isEmpty() + || !m_plainText.isEmpty() + || !m_textHtml.isEmpty() + || m_fileContent; } HashSet<String> ChromiumDataObject::types() const { - if (m_legacyData) - return m_legacyData->types(); - return m_readableData->types(); -} + if (m_clipboardType == Clipboard::CopyAndPaste) { + bool ignoredContainsFilenames; + return PlatformBridge::clipboardReadAvailableTypes(PasteboardPrivate::StandardBuffer, + &ignoredContainsFilenames); + } -String ChromiumDataObject::getData(const String& type, bool& success) -{ - if (m_legacyData) - return m_legacyData->getData(type, success); - return m_readableData->getData(type, success); -} + HashSet<String> results; -bool ChromiumDataObject::setData(const String& type, const String& data) -{ - if (m_legacyData) - return m_legacyData->setData(type, data); - return m_writableData->setData(type, data); -} + if (!m_plainText.isEmpty()) { + results.add(mimeTypeText); + results.add(mimeTypeTextPlain); + } -String ChromiumDataObject::urlTitle() const -{ - if (m_legacyData) - return m_legacyData->urlTitle(); - return m_readableData->urlTitle(); -} + if (m_url.isValid()) + results.add(mimeTypeURL); -void ChromiumDataObject::setUrlTitle(const String& urlTitle) -{ - if (m_legacyData) - m_legacyData->setUrlTitle(urlTitle); - else - m_writableData->setUrlTitle(urlTitle); -} + if (!m_uriList.isEmpty()) + results.add(mimeTypeTextURIList); -KURL ChromiumDataObject::htmlBaseUrl() const -{ - if (m_legacyData) - return m_legacyData->htmlBaseUrl(); - return m_readableData->htmlBaseUrl(); -} + if (!m_textHtml.isEmpty()) + results.add(mimeTypeTextHTML); -void ChromiumDataObject::setHtmlBaseUrl(const KURL& url) -{ - if (m_legacyData) - m_legacyData->setHtmlBaseUrl(url); - else - m_writableData->setHtmlBaseUrl(url); + return results; } -bool ChromiumDataObject::containsFilenames() const +String ChromiumDataObject::getData(const String& type, bool& success) { - if (m_legacyData) - return m_legacyData->containsFilenames(); - return m_readableData->containsFilenames(); -} + if (type == mimeTypeTextPlain) { + if (m_clipboardType == Clipboard::CopyAndPaste) { + PasteboardPrivate::ClipboardBuffer buffer = + Pasteboard::generalPasteboard()->isSelectionMode() ? + PasteboardPrivate::SelectionBuffer : + PasteboardPrivate::StandardBuffer; + String text = PlatformBridge::clipboardReadPlainText(buffer); + success = !text.isEmpty(); + return text; + } + success = !m_plainText.isEmpty(); + return m_plainText; + } -Vector<String> ChromiumDataObject::filenames() const -{ - if (m_legacyData) - return m_legacyData->filenames(); - return m_readableData->filenames(); -} + if (type == mimeTypeURL) { + success = !m_url.isEmpty(); + return m_url.string(); + } -void ChromiumDataObject::setFilenames(const Vector<String>& filenames) -{ - if (m_legacyData) - m_legacyData->setFilenames(filenames); - else - ASSERT_NOT_REACHED(); -} + if (type == mimeTypeTextURIList) { + success = !m_uriList.isEmpty(); + return m_uriList; + } -String ChromiumDataObject::fileExtension() const -{ - if (m_legacyData) - return m_legacyData->fileExtension(); - return m_writableData->fileExtension(); -} + if (type == mimeTypeTextHTML) { + if (m_clipboardType == Clipboard::CopyAndPaste) { + PasteboardPrivate::ClipboardBuffer buffer = + Pasteboard::generalPasteboard()->isSelectionMode() ? + PasteboardPrivate::SelectionBuffer : + PasteboardPrivate::StandardBuffer; + String htmlText; + KURL sourceURL; + PlatformBridge::clipboardReadHTML(buffer, &htmlText, &sourceURL); + success = !htmlText.isEmpty(); + return htmlText; + } + success = !m_textHtml.isEmpty(); + return m_textHtml; + } -void ChromiumDataObject::setFileExtension(const String& fileExtension) -{ - if (m_legacyData) - m_legacyData->setFileExtension(fileExtension); - else - m_writableData->setFileExtension(fileExtension); + if (type == mimeTypeDownloadURL) { + success = !m_downloadMetadata.isEmpty(); + return m_downloadMetadata; + } + + success = false; + return String(); } -String ChromiumDataObject::fileContentFilename() const +bool ChromiumDataObject::setData(const String& type, const String& data) { - if (m_legacyData) - return m_legacyData->fileContentFilename(); - return m_writableData->fileContentFilename(); + if (type == mimeTypeTextPlain) { + m_plainText = data; + return true; + } + + if (type == mimeTypeURL || type == mimeTypeTextURIList) { + m_url = KURL(); + Vector<String> uriList; + // Line separator is \r\n per RFC 2483 - however, for compatibility + // reasons we also allow just \n here. + data.split('\n', uriList); + // Process the input and copy the first valid URL into the url member. + // In case no URLs can be found, subsequent calls to getData("URL") + // will get an empty string. This is in line with the HTML5 spec (see + // "The DragEvent and DataTransfer interfaces"). + for (size_t i = 0; i < uriList.size(); ++i) { + String& line = uriList[i]; + line = line.stripWhiteSpace(); + if (line.isEmpty()) { + continue; + } + if (line[0] == '#') + continue; + KURL url = KURL(ParsedURLString, line); + if (url.isValid()) { + m_url = url; + break; + } + } + m_uriList = data; + return true; + } + + if (type == mimeTypeTextHTML) { + m_textHtml = data; + m_htmlBaseUrl = KURL(); + return true; + } + + if (type == mimeTypeDownloadURL) { + m_downloadMetadata = data; + return true; + } + + return false; } -void ChromiumDataObject::setFileContentFilename(const String& fileContentFilename) +bool ChromiumDataObject::containsFilenames() const { - if (m_legacyData) - m_legacyData->setFileContentFilename(fileContentFilename); - else - m_writableData->setFileContentFilename(fileContentFilename); + bool containsFilenames; + if (m_clipboardType == Clipboard::CopyAndPaste) { + HashSet<String> ignoredResults = + PlatformBridge::clipboardReadAvailableTypes(PasteboardPrivate::StandardBuffer, + &containsFilenames); + } else + containsFilenames = !m_filenames.isEmpty(); + return containsFilenames; } -PassRefPtr<SharedBuffer> ChromiumDataObject::fileContent() const +ChromiumDataObject::ChromiumDataObject(Clipboard::ClipboardType clipboardType) + : m_clipboardType(clipboardType) { - if (m_legacyData) - return m_legacyData->fileContent(); - return m_writableData->fileContent(); } -void ChromiumDataObject::setFileContent(PassRefPtr<SharedBuffer> fileContent) +ChromiumDataObject::ChromiumDataObject(const ChromiumDataObject& other) + : RefCounted<ChromiumDataObject>() + , m_clipboardType(other.m_clipboardType) + , m_urlTitle(other.m_urlTitle) + , m_downloadMetadata(other.m_downloadMetadata) + , m_fileExtension(other.m_fileExtension) + , m_filenames(other.m_filenames) + , m_plainText(other.m_plainText) + , m_textHtml(other.m_textHtml) + , m_htmlBaseUrl(other.m_htmlBaseUrl) + , m_fileContentFilename(other.m_fileContentFilename) + , m_url(other.m_url) + , m_uriList(other.m_uriList) { - if (m_legacyData) - m_legacyData->setFileContent(fileContent); - else - m_writableData->setFileContent(fileContent); + if (other.m_fileContent.get()) + m_fileContent = other.m_fileContent->copy(); } -} +} // namespace WebCore diff --git a/Source/WebCore/platform/chromium/ChromiumDataObject.h b/Source/WebCore/platform/chromium/ChromiumDataObject.h index 919c269..ee79bfe 100644 --- a/Source/WebCore/platform/chromium/ChromiumDataObject.h +++ b/Source/WebCore/platform/chromium/ChromiumDataObject.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Google Inc. All rights reserved. + * Copyright (c) 2008, 2009, Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,18 +31,31 @@ #ifndef ChromiumDataObject_h #define ChromiumDataObject_h -#include "ChromiumDataObjectLegacy.h" -#include "ReadableDataObject.h" -#include "WritableDataObject.h" +#include "Clipboard.h" +#include "KURL.h" +#include "PlatformString.h" +#include "SharedBuffer.h" +#include <wtf/HashSet.h> #include <wtf/RefPtr.h> +#include <wtf/Vector.h> +#include <wtf/text/StringHash.h> namespace WebCore { +// A data object for holding data that would be in a clipboard or moved +// during a drag-n-drop operation. This is the data that WebCore is aware +// of and is not specific to a platform. class ChromiumDataObject : public RefCounted<ChromiumDataObject> { public: - static PassRefPtr<ChromiumDataObject> create(PassRefPtr<ChromiumDataObjectLegacy> data); - static PassRefPtr<ChromiumDataObject> createReadable(const Frame*, Clipboard::ClipboardType); - static PassRefPtr<ChromiumDataObject> createWritable(Clipboard::ClipboardType); + static PassRefPtr<ChromiumDataObject> create(Clipboard::ClipboardType clipboardType) + { + return adoptRef(new ChromiumDataObject(clipboardType)); + } + + PassRefPtr<ChromiumDataObject> copy() const + { + return adoptRef(new ChromiumDataObject(*this)); + } void clearData(const String& type); void clearAll(); @@ -55,34 +68,53 @@ public: bool setData(const String& type, const String& data); // Special handlers for URL/HTML metadata. - String urlTitle() const; - void setUrlTitle(const String& urlTitle); - KURL htmlBaseUrl() const; - void setHtmlBaseUrl(const KURL& url); + String urlTitle() const { return m_urlTitle; } + void setUrlTitle(const String& urlTitle) { m_urlTitle = urlTitle; } + KURL htmlBaseUrl() const { return m_htmlBaseUrl; } + void setHtmlBaseUrl(const KURL& url) { m_htmlBaseUrl = url; } // Used to handle files being dragged in. bool containsFilenames() const; - Vector<String> filenames() const; - void setFilenames(const Vector<String>& filenames); + Vector<String> filenames() const { return m_filenames; } + void setFilenames(const Vector<String>& filenames) { m_filenames = filenames; } // Used to handle files (images) being dragged out. - String fileExtension() const; - void setFileExtension(const String& fileExtension); - String fileContentFilename() const; - void setFileContentFilename(const String& fileContentFilename); - PassRefPtr<SharedBuffer> fileContent() const; - void setFileContent(PassRefPtr<SharedBuffer> fileContent); + String fileExtension() const { return m_fileExtension; } + void setFileExtension(const String& fileExtension) { m_fileExtension = fileExtension; } + String fileContentFilename() const { return m_fileContentFilename; } + void setFileContentFilename(const String& fileContentFilename) { m_fileContentFilename = fileContentFilename; } + PassRefPtr<SharedBuffer> fileContent() const { return m_fileContent; } + void setFileContent(PassRefPtr<SharedBuffer> fileContent) { m_fileContent = fileContent; } private: - ChromiumDataObject(PassRefPtr<ChromiumDataObjectLegacy>); - ChromiumDataObject(PassRefPtr<ReadableDataObject>); - ChromiumDataObject(PassRefPtr<WritableDataObject>); + ChromiumDataObject(Clipboard::ClipboardType); + ChromiumDataObject(const ChromiumDataObject&); + + Clipboard::ClipboardType m_clipboardType; + + String m_urlTitle; + + String m_downloadMetadata; + + String m_fileExtension; + Vector<String> m_filenames; - RefPtr<ChromiumDataObjectLegacy> m_legacyData; - RefPtr<ReadableDataObject> m_readableData; - RefPtr<WritableDataObject> m_writableData; + String m_plainText; + + String m_textHtml; + KURL m_htmlBaseUrl; + + String m_fileContentFilename; + RefPtr<SharedBuffer> m_fileContent; + + // These two are linked. Setting m_url will set m_uriList to the same + // string value; setting m_uriList will cause its contents to be parsed + // according to RFC 2483 and the first URL found will be set in m_url. + KURL m_url; + String m_uriList; }; -} +} // namespace WebCore #endif + diff --git a/Source/WebCore/platform/chromium/ClipboardChromium.cpp b/Source/WebCore/platform/chromium/ClipboardChromium.cpp index d6ba2d2..7e58f03 100644 --- a/Source/WebCore/platform/chromium/ClipboardChromium.cpp +++ b/Source/WebCore/platform/chromium/ClipboardChromium.cpp @@ -85,16 +85,6 @@ PassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardT return adoptRef(new ClipboardChromium(clipboardType, dataObject, policy, frame)); } -PassRefPtr<ClipboardChromium> ClipboardChromium::create(ClipboardType clipboardType, - ClipboardAccessPolicy policy, Frame* frame) -{ - RefPtr<ChromiumDataObject> dataObject = - policy == ClipboardWritable ? - ChromiumDataObject::createWritable(clipboardType) : - ChromiumDataObject::createReadable(frame, clipboardType); - return adoptRef(new ClipboardChromium(clipboardType, dataObject, policy, frame)); -} - void ClipboardChromium::clearData(const String& type) { if (policy() != ClipboardWritable || !m_dataObject) @@ -142,6 +132,9 @@ HashSet<String> ClipboardChromium::types() const results = m_dataObject->types(); + if (m_dataObject->containsFilenames()) + results.add(mimeTypeFiles); + return results; } diff --git a/Source/WebCore/platform/chromium/ClipboardChromium.h b/Source/WebCore/platform/chromium/ClipboardChromium.h index d5ada14..d30a1c4 100644 --- a/Source/WebCore/platform/chromium/ClipboardChromium.h +++ b/Source/WebCore/platform/chromium/ClipboardChromium.h @@ -49,9 +49,6 @@ namespace WebCore { static PassRefPtr<ClipboardChromium> create( ClipboardType, PassRefPtr<ChromiumDataObject>, ClipboardAccessPolicy, Frame*); - static PassRefPtr<ClipboardChromium> create( - ClipboardType, ClipboardAccessPolicy, Frame*); - // Returns the file name (not including the extension). This removes any // invalid file system characters as well as making sure the // path + extension is not bigger than allowed by the file system. diff --git a/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp b/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp index f689e0e..27e68ff 100644 --- a/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp +++ b/Source/WebCore/platform/chromium/ClipboardMimeTypes.cpp @@ -40,5 +40,6 @@ const char mimeTypeTextHTML[] = "text/html"; const char mimeTypeURL[] = "url"; const char mimeTypeTextURIList[] = "text/uri-list"; const char mimeTypeDownloadURL[] = "downloadurl"; +const char mimeTypeFiles[] = "Files"; } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/ClipboardMimeTypes.h b/Source/WebCore/platform/chromium/ClipboardMimeTypes.h index 9bdccfe..31e2d3e 100644 --- a/Source/WebCore/platform/chromium/ClipboardMimeTypes.h +++ b/Source/WebCore/platform/chromium/ClipboardMimeTypes.h @@ -40,6 +40,7 @@ extern const char mimeTypeTextHTML[]; extern const char mimeTypeURL[]; extern const char mimeTypeTextURIList[]; extern const char mimeTypeDownloadURL[]; +extern const char mimeTypeFiles[]; } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/CursorChromium.cpp b/Source/WebCore/platform/chromium/CursorChromium.cpp index 0119f07..1f9d7cb 100644 --- a/Source/WebCore/platform/chromium/CursorChromium.cpp +++ b/Source/WebCore/platform/chromium/CursorChromium.cpp @@ -31,6 +31,8 @@ #include "config.h" #include "Cursor.h" +#include <wtf/Assertions.h> + namespace WebCore { Cursor::Cursor(const Cursor& other) @@ -306,12 +308,62 @@ const Cursor& zoomOutCursor() const Cursor& grabCursor() { - return pointerCursor(); + static const Cursor c(PlatformCursor::TypeGrab); + return c; } const Cursor& grabbingCursor() { - return pointerCursor(); + static const Cursor c(PlatformCursor::TypeGrabbing); + return c; } } // namespace WebCore + +#define COMPILE_ASSERT_MATCHING_ENUM(cursor_name, platform_cursor_name) \ + COMPILE_ASSERT(int(WebCore::Cursor::cursor_name) == int(WebCore::PlatformCursor::platform_cursor_name), mismatching_enums) + +COMPILE_ASSERT_MATCHING_ENUM(Pointer, TypePointer); +COMPILE_ASSERT_MATCHING_ENUM(Cross, TypeCross); +COMPILE_ASSERT_MATCHING_ENUM(Hand, TypeHand); +COMPILE_ASSERT_MATCHING_ENUM(IBeam, TypeIBeam); +COMPILE_ASSERT_MATCHING_ENUM(Wait, TypeWait); +COMPILE_ASSERT_MATCHING_ENUM(Help, TypeHelp); +COMPILE_ASSERT_MATCHING_ENUM(EastResize, TypeEastResize); +COMPILE_ASSERT_MATCHING_ENUM(NorthResize, TypeNorthResize); +COMPILE_ASSERT_MATCHING_ENUM(NorthEastResize, TypeNorthEastResize); +COMPILE_ASSERT_MATCHING_ENUM(NorthWestResize, TypeNorthWestResize); +COMPILE_ASSERT_MATCHING_ENUM(SouthResize, TypeSouthResize); +COMPILE_ASSERT_MATCHING_ENUM(SouthEastResize, TypeSouthEastResize); +COMPILE_ASSERT_MATCHING_ENUM(SouthWestResize, TypeSouthWestResize); +COMPILE_ASSERT_MATCHING_ENUM(WestResize, TypeWestResize); +COMPILE_ASSERT_MATCHING_ENUM(NorthSouthResize, TypeNorthSouthResize); +COMPILE_ASSERT_MATCHING_ENUM(EastWestResize, TypeEastWestResize); +COMPILE_ASSERT_MATCHING_ENUM(NorthEastSouthWestResize, TypeNorthEastSouthWestResize); +COMPILE_ASSERT_MATCHING_ENUM(NorthWestSouthEastResize, TypeNorthWestSouthEastResize); +COMPILE_ASSERT_MATCHING_ENUM(ColumnResize, TypeColumnResize); +COMPILE_ASSERT_MATCHING_ENUM(RowResize, TypeRowResize); +COMPILE_ASSERT_MATCHING_ENUM(MiddlePanning, TypeMiddlePanning); +COMPILE_ASSERT_MATCHING_ENUM(EastPanning, TypeEastPanning); +COMPILE_ASSERT_MATCHING_ENUM(NorthPanning, TypeNorthPanning); +COMPILE_ASSERT_MATCHING_ENUM(NorthEastPanning, TypeNorthEastPanning); +COMPILE_ASSERT_MATCHING_ENUM(NorthWestPanning, TypeNorthWestPanning); +COMPILE_ASSERT_MATCHING_ENUM(SouthPanning, TypeSouthPanning); +COMPILE_ASSERT_MATCHING_ENUM(SouthEastPanning, TypeSouthEastPanning); +COMPILE_ASSERT_MATCHING_ENUM(SouthWestPanning, TypeSouthWestPanning); +COMPILE_ASSERT_MATCHING_ENUM(WestPanning, TypeWestPanning); +COMPILE_ASSERT_MATCHING_ENUM(Move, TypeMove); +COMPILE_ASSERT_MATCHING_ENUM(VerticalText, TypeVerticalText); +COMPILE_ASSERT_MATCHING_ENUM(Cell, TypeCell); +COMPILE_ASSERT_MATCHING_ENUM(ContextMenu, TypeContextMenu); +COMPILE_ASSERT_MATCHING_ENUM(Alias, TypeAlias); +COMPILE_ASSERT_MATCHING_ENUM(Progress, TypeProgress); +COMPILE_ASSERT_MATCHING_ENUM(NoDrop, TypeNoDrop); +COMPILE_ASSERT_MATCHING_ENUM(Copy, TypeCopy); +COMPILE_ASSERT_MATCHING_ENUM(None, TypeNone); +COMPILE_ASSERT_MATCHING_ENUM(NotAllowed, TypeNotAllowed); +COMPILE_ASSERT_MATCHING_ENUM(ZoomIn, TypeZoomIn); +COMPILE_ASSERT_MATCHING_ENUM(ZoomOut, TypeZoomOut); +COMPILE_ASSERT_MATCHING_ENUM(Grab, TypeGrab); +COMPILE_ASSERT_MATCHING_ENUM(Grabbing, TypeGrabbing); +COMPILE_ASSERT_MATCHING_ENUM(Custom, TypeCustom); diff --git a/Source/WebCore/platform/chromium/FileChooserChromium.cpp b/Source/WebCore/platform/chromium/FileChooserChromium.cpp index 3d75b42..dcc7eb0 100644 --- a/Source/WebCore/platform/chromium/FileChooserChromium.cpp +++ b/Source/WebCore/platform/chromium/FileChooserChromium.cpp @@ -44,9 +44,9 @@ String FileChooser::basenameForWidth(const Font& font, int width) const else if (m_filenames.size() == 1) string = pathGetDisplayFileName(m_filenames[0]); else - return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false); + return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font); - return StringTruncator::centerTruncate(string, static_cast<float>(width), font, false); + return StringTruncator::centerTruncate(string, static_cast<float>(width), font); } } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/FramelessScrollView.cpp b/Source/WebCore/platform/chromium/FramelessScrollView.cpp index 3fbf2d6..b6a8f53 100644 --- a/Source/WebCore/platform/chromium/FramelessScrollView.cpp +++ b/Source/WebCore/platform/chromium/FramelessScrollView.cpp @@ -32,6 +32,7 @@ #include "FramelessScrollView.h" #include "FramelessScrollViewClient.h" +#include "ScrollbarTheme.h" namespace WebCore { @@ -72,10 +73,16 @@ IntRect FramelessScrollView::windowClipRect(bool clipToContents) const return contentsToWindow(visibleContentRect(!clipToContents)); } -void FramelessScrollView::paintContents(GraphicsContext*, const IntRect& damageRect) +void FramelessScrollView::paintContents(GraphicsContext*, const IntRect&) { } +void FramelessScrollView::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect) +{ + // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the ScrollView is a FrameView. + ScrollbarTheme::defaultPaintScrollCorner(context, cornerRect); +} + void FramelessScrollView::contentsResized() { } diff --git a/Source/WebCore/platform/chromium/FramelessScrollView.h b/Source/WebCore/platform/chromium/FramelessScrollView.h index 033d953..724829d 100644 --- a/Source/WebCore/platform/chromium/FramelessScrollView.h +++ b/Source/WebCore/platform/chromium/FramelessScrollView.h @@ -74,7 +74,8 @@ namespace WebCore { protected: // ScrollView protected methods: - virtual void paintContents(GraphicsContext*, const IntRect& damageRect); + virtual void paintContents(GraphicsContext*, const IntRect&); + virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect); virtual void contentsResized(); virtual void visibleContentsResized(); diff --git a/Source/WebCore/platform/chromium/PlatformBridge.h b/Source/WebCore/platform/chromium/PlatformBridge.h index 9a09b90..1c3ccbd 100644 --- a/Source/WebCore/platform/chromium/PlatformBridge.h +++ b/Source/WebCore/platform/chromium/PlatformBridge.h @@ -109,9 +109,9 @@ public: static void clipboardWriteData(const String& type, const String& data, const String& metadata); // Interface for handling copy and paste, drag and drop, and selection copy. - static HashSet<String> clipboardReadAvailableTypes(const Frame*, PasteboardPrivate::ClipboardBuffer, bool* containsFilenames); - static bool clipboardReadData(const Frame*, PasteboardPrivate::ClipboardBuffer, const String& type, String& data, String& metadata); - static Vector<String> clipboardReadFilenames(const Frame*, PasteboardPrivate::ClipboardBuffer); + static HashSet<String> clipboardReadAvailableTypes(PasteboardPrivate::ClipboardBuffer, bool* containsFilenames); + static bool clipboardReadData(PasteboardPrivate::ClipboardBuffer, const String& type, String& data, String& metadata); + static Vector<String> clipboardReadFilenames(PasteboardPrivate::ClipboardBuffer); // Cookies ------------------------------------------------------------ static void setCookies(const Document*, const KURL&, const String& value); @@ -150,7 +150,7 @@ public: #endif #if OS(LINUX) || OS(FREEBSD) static void getRenderStyleForStrike(const char* family, int sizeAndStyle, FontRenderStyle* result); - static String getFontFamilyForCharacters(const UChar*, size_t numCharacters); + static String getFontFamilyForCharacters(const UChar*, size_t numCharacters, const char* preferredLocale); #endif #if OS(DARWIN) static bool loadFont(NSFont* srcFont, ATSFontContainerRef* out); @@ -173,6 +173,8 @@ public: static PassRefPtr<IDBFactoryBackendInterface> idbFactory(); // Extracts keyPath from values and returns the corresponding keys. static void createIDBKeysFromSerializedValuesAndKeyPath(const Vector<RefPtr<SerializedScriptValue> >& values, const String& keyPath, Vector<RefPtr<IDBKey> >& keys); + // Injects key via keyPath into value. Returns true on success. + static PassRefPtr<SerializedScriptValue> injectIDBKeyIntoSerializedValue(PassRefPtr<IDBKey>, PassRefPtr<SerializedScriptValue>, const String& keyPath); // JavaScript --------------------------------------------------------- static void notifyJSOutOfMemory(Frame*); @@ -308,6 +310,7 @@ public: bool checked; bool indeterminate; // Whether the button state is indeterminate. bool isDefault; // Whether the button is default button. + bool hasBorder; unsigned backgroundColor; }; @@ -318,6 +321,8 @@ public: }; struct MenuListExtraParams { + bool hasBorder; + bool hasBorderRadius; int arrowX; int arrowY; unsigned backgroundColor; diff --git a/Source/WebCore/platform/chromium/PlatformCursor.h b/Source/WebCore/platform/chromium/PlatformCursor.h index 692c007..328cdb6 100644 --- a/Source/WebCore/platform/chromium/PlatformCursor.h +++ b/Source/WebCore/platform/chromium/PlatformCursor.h @@ -81,6 +81,8 @@ namespace WebCore { TypeNotAllowed, TypeZoomIn, TypeZoomOut, + TypeGrab, + TypeGrabbing, TypeCustom }; diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp index 59441d0..e83ebe4 100644 --- a/Source/WebCore/platform/chromium/PopupMenuChromium.cpp +++ b/Source/WebCore/platform/chromium/PopupMenuChromium.cpp @@ -328,7 +328,7 @@ PopupContainer::~PopupContainer() removeChild(m_listBox.get()); } -IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, int popupInitialY) +IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, const IntPoint& popupInitialCoordinate) { // Reset the max height to its default value, it will be recomputed below // if necessary. @@ -336,8 +336,8 @@ IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, in // Lay everything out to figure out our preferred size, then tell the view's // WidgetClient about it. It should assign us a client. - layout(); - + int rightOffset = layoutAndGetRightOffset(); + // Assume m_listBox size is already calculated. IntSize targetSize(m_listBox->width() + kBorderSize * 2, m_listBox->height() + kBorderSize * 2); @@ -348,9 +348,22 @@ IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, in // If the popup would extend past the bottom of the screen, open upwards // instead. FloatRect screen = screenAvailableRect(m_frameView.get()); - // Use this::x() for location because RTL position is considered - // in layout(). - widgetRect = chromeClient->windowToScreen(IntRect(x(), popupInitialY, targetSize.width(), targetSize.height())); + // Use popupInitialCoordinate.x() + rightOffset because RTL position + // needs to be considered. + widgetRect = chromeClient->windowToScreen(IntRect(popupInitialCoordinate.x() + rightOffset, popupInitialCoordinate.y(), targetSize.width(), targetSize.height())); + + // If we have multiple screens and the browser rect is in one screen, we have + // to clip the window width to the screen width. + FloatRect windowRect = chromeClient->windowRect(); + if (windowRect.x() >= screen.x() && windowRect.maxX() <= screen.maxX()) { + if (m_listBox->m_popupClient->menuStyle().textDirection() == RTL && widgetRect.x() < screen.x()) { + widgetRect.setWidth(widgetRect.maxX() - screen.x()); + widgetRect.setX(screen.x()); + } else if (widgetRect.maxX() > screen.maxX()) + widgetRect.setWidth(screen.maxX() - widgetRect.x()); + } + + // Calculate Y axis size. if (widgetRect.maxY() > static_cast<int>(screen.maxY())) { if (widgetRect.y() - widgetRect.height() - targetControlHeight > 0) { // There is enough room to open upwards. @@ -364,9 +377,13 @@ IntRect PopupContainer::layoutAndCalculateWidgetRect(int targetControlHeight, in m_listBox->setMaxHeight(spaceAbove); else m_listBox->setMaxHeight(spaceBelow); - layout(); - // Our size has changed, recompute the widgetRect. - widgetRect = chromeClient->windowToScreen(frameRect()); + layoutAndGetRightOffset(); + // Our height has changed, so recompute only Y axis of widgetRect. + // We don't have to recompute X axis, so we only replace Y axis + // in widgetRect. + IntRect frameInScreen = chromeClient->windowToScreen(frameRect()); + widgetRect.setY(frameInScreen.y()); + widgetRect.setHeight(frameInScreen.height()); // And move upwards if necessary. if (spaceAbove > spaceBelow) widgetRect.move(0, -(widgetRect.height() + targetControlHeight)); @@ -383,7 +400,7 @@ void PopupContainer::showPopup(FrameView* view) ChromeClientChromium* chromeClient = chromeClientChromium(); if (chromeClient) { IntRect popupRect = frameRect(); - chromeClient->popupOpened(this, layoutAndCalculateWidgetRect(popupRect.height(), popupRect.y()), false); + chromeClient->popupOpened(this, layoutAndCalculateWidgetRect(popupRect.height(), popupRect.location()), false); m_popupOpen = true; } @@ -412,7 +429,7 @@ void PopupContainer::notifyPopupHidden() chromeClientChromium()->popupClosed(this); } -void PopupContainer::layout() +int PopupContainer::layoutAndGetRightOffset() { m_listBox->layout(); @@ -429,12 +446,15 @@ void PopupContainer::layout() // of dropdown box should be aligned with the right edge of <select> element box, // and the dropdown box should be expanded to left if more space needed. PopupMenuClient* popupClient = m_listBox->m_popupClient; + int rightOffset = 0; if (popupClient) { bool rightAligned = m_listBox->m_popupClient->menuStyle().textDirection() == RTL; if (rightAligned) - move(x() + popupWidth - listBoxWidth, y()); + rightOffset = popupWidth - listBoxWidth; } invalidate(); + + return rightOffset; } bool PopupContainer::handleMouseDownEvent(const PlatformMouseEvent& event) @@ -520,7 +540,7 @@ ChromeClientChromium* PopupContainer::chromeClientChromium() return static_cast<ChromeClientChromium*>(m_frameView->frame()->page()->chrome()->client()); } -void PopupContainer::show(const IntRect& r, FrameView* v, int index) +void PopupContainer::showInRect(const IntRect& r, FrameView* v, int index) { // The rect is the size of the select box. It's usually larger than we need. // subtract border size so that usually the container will be displayed @@ -553,7 +573,7 @@ void PopupContainer::refresh(const IntRect& targetControlRect) listBox()->updateFromElement(); // Store the original height to check if we need to request the location. int originalHeight = height(); - IntRect widgetRect = layoutAndCalculateWidgetRect(targetControlRect.height(), location.y()); + IntRect widgetRect = layoutAndCalculateWidgetRect(targetControlRect.height(), location); if (originalHeight != widgetRect.height()) setFrameRect(widgetRect); @@ -1379,7 +1399,7 @@ void PopupMenuChromium::show(const IntRect& r, FrameView* v, int index) { if (!p.popup) p.popup = PopupContainer::create(client(), PopupContainer::Select, dropDownSettings); - p.popup->show(r, v, index); + p.popup->showInRect(r, v, index); } void PopupMenuChromium::hide() diff --git a/Source/WebCore/platform/chromium/PopupMenuChromium.h b/Source/WebCore/platform/chromium/PopupMenuChromium.h index 43b8b0e..3436650 100644 --- a/Source/WebCore/platform/chromium/PopupMenuChromium.h +++ b/Source/WebCore/platform/chromium/PopupMenuChromium.h @@ -133,7 +133,7 @@ public: // so WebViewImpl can create a PopupContainer. This method is used for // displaying auto complete popup menus on Mac Chromium, and for all // popups on other platforms. - void show(const IntRect&, FrameView*, int index); + void showInRect(const IntRect&, FrameView*, int index); // Hides the popup. void hidePopup(); @@ -141,8 +141,8 @@ public: // The popup was hidden. void notifyPopupHidden(); - // Compute size of widget and children. - void layout(); + // Compute size of widget and children. Return right offset for RTL. + int layoutAndGetRightOffset(); PopupListBox* listBox() const { return m_listBox.get(); } @@ -177,7 +177,7 @@ private: void paintBorder(GraphicsContext*, const IntRect&); // Layout and calculate popup widget size and location and returns it as IntRect. - IntRect layoutAndCalculateWidgetRect(int targetControlHeight, int popupInitialY); + 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/chromium/ReadableDataObject.cpp b/Source/WebCore/platform/chromium/ReadableDataObject.cpp index 484a1b3..dbf4739 100644 --- a/Source/WebCore/platform/chromium/ReadableDataObject.cpp +++ b/Source/WebCore/platform/chromium/ReadableDataObject.cpp @@ -43,14 +43,13 @@ static PasteboardPrivate::ClipboardBuffer clipboardBuffer(Clipboard::ClipboardTy return clipboardType == Clipboard::DragAndDrop ? PasteboardPrivate::DragBuffer : PasteboardPrivate::StandardBuffer; } -PassRefPtr<ReadableDataObject> ReadableDataObject::create(const Frame* frame, Clipboard::ClipboardType clipboardType) +PassRefPtr<ReadableDataObject> ReadableDataObject::create(Clipboard::ClipboardType clipboardType) { - return adoptRef(new ReadableDataObject(frame, clipboardType)); + return adoptRef(new ReadableDataObject(clipboardType)); } -ReadableDataObject::ReadableDataObject(const Frame* frame, Clipboard::ClipboardType clipboardType) - : m_frame(frame) - , m_clipboardType(clipboardType) +ReadableDataObject::ReadableDataObject(Clipboard::ClipboardType clipboardType) + : m_clipboardType(clipboardType) , m_containsFilenames(false) , m_isTypeCacheInitialized(false) { @@ -94,7 +93,7 @@ String ReadableDataObject::getData(const String& type, bool& succeeded) const return data; } succeeded = PlatformBridge::clipboardReadData( - m_frame, clipboardBuffer(m_clipboardType), type, data, ignoredMetadata); + clipboardBuffer(m_clipboardType), type, data, ignoredMetadata); return data; } @@ -103,7 +102,7 @@ String ReadableDataObject::urlTitle() const String ignoredData; String urlTitle; PlatformBridge::clipboardReadData( - m_frame, clipboardBuffer(m_clipboardType), mimeTypeTextURIList, ignoredData, urlTitle); + clipboardBuffer(m_clipboardType), mimeTypeTextURIList, ignoredData, urlTitle); return urlTitle; } @@ -112,7 +111,7 @@ KURL ReadableDataObject::htmlBaseUrl() const String ignoredData; String htmlBaseUrl; PlatformBridge::clipboardReadData( - m_frame, clipboardBuffer(m_clipboardType), mimeTypeTextHTML, ignoredData, htmlBaseUrl); + clipboardBuffer(m_clipboardType), mimeTypeTextHTML, ignoredData, htmlBaseUrl); return KURL(ParsedURLString, htmlBaseUrl); } @@ -124,7 +123,7 @@ bool ReadableDataObject::containsFilenames() const Vector<String> ReadableDataObject::filenames() const { - return PlatformBridge::clipboardReadFilenames(m_frame, clipboardBuffer(m_clipboardType)); + return PlatformBridge::clipboardReadFilenames(clipboardBuffer(m_clipboardType)); } void ReadableDataObject::ensureTypeCacheInitialized() const @@ -133,7 +132,7 @@ void ReadableDataObject::ensureTypeCacheInitialized() const return; m_types = PlatformBridge::clipboardReadAvailableTypes( - m_frame, clipboardBuffer(m_clipboardType), &m_containsFilenames); + clipboardBuffer(m_clipboardType), &m_containsFilenames); m_isTypeCacheInitialized = true; } diff --git a/Source/WebCore/platform/chromium/ReadableDataObject.h b/Source/WebCore/platform/chromium/ReadableDataObject.h index c6cc310..027e0ed 100644 --- a/Source/WebCore/platform/chromium/ReadableDataObject.h +++ b/Source/WebCore/platform/chromium/ReadableDataObject.h @@ -44,7 +44,7 @@ namespace WebCore { // browser to the renderer. class ReadableDataObject : public RefCounted<ReadableDataObject> { public: - static PassRefPtr<ReadableDataObject> create(const Frame*, Clipboard::ClipboardType); + static PassRefPtr<ReadableDataObject> create(Clipboard::ClipboardType); bool hasData() const; HashSet<String> types() const; @@ -57,14 +57,11 @@ public: Vector<String> filenames() const; private: - explicit ReadableDataObject(const Frame*, Clipboard::ClipboardType); + explicit ReadableDataObject(Clipboard::ClipboardType); // This isn't always const... but most of the time it is. void ensureTypeCacheInitialized() const; - // The owner frame. Used to send IPCs back to the correspdonging view via WebFrameClient. - const Frame* m_frame; - Clipboard::ClipboardType m_clipboardType; // To avoid making a lot of IPC calls for each drag event, we cache some diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp index 9e700c2..843fc3c 100644 --- a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp +++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.cpp @@ -137,13 +137,4 @@ void ScrollbarThemeChromium::paintTickmarks(GraphicsContext* context, Scrollbar* context->restore(); } -void ScrollbarThemeChromium::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect) -{ - // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the - // ScrollView is a FrameView (see FramelessScrollView), so we cannot let - // that code run. For FrameView's this is correct since we don't do custom - // scrollbar corner rendering, which ScrollbarThemeComposite supports. - ScrollbarTheme::paintScrollCorner(view, context, cornerRect); -} - } // namespace WebCore diff --git a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h index b53d4ae..1178125 100644 --- a/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h +++ b/Source/WebCore/platform/chromium/ScrollbarThemeChromium.h @@ -48,8 +48,6 @@ namespace WebCore { virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); virtual IntRect trackRect(Scrollbar*, bool painting = false); - virtual void paintScrollCorner(ScrollView*, GraphicsContext*, const IntRect&); - virtual void paintTrackBackground(GraphicsContext*, Scrollbar*, const IntRect&); virtual void paintTickmarks(GraphicsContext*, Scrollbar*, const IntRect&); diff --git a/Source/WebCore/platform/chromium/TemporaryLinkStubs.cpp b/Source/WebCore/platform/chromium/TemporaryLinkStubs.cpp index 3c747d0..3a85029 100644 --- a/Source/WebCore/platform/chromium/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/chromium/TemporaryLinkStubs.cpp @@ -54,4 +54,14 @@ void setCookieStoragePrivateBrowsingEnabled(bool) notImplemented(); } +void startObservingCookieChanges() +{ + notImplemented(); +} + +void stopObservingCookieChanges() +{ + notImplemented(); +} + } // namespace WebCore diff --git a/Source/WebCore/platform/efl/CookieJarEfl.cpp b/Source/WebCore/platform/efl/CookieJarEfl.cpp index 6c78dbd..261ab23 100644 --- a/Source/WebCore/platform/efl/CookieJarEfl.cpp +++ b/Source/WebCore/platform/efl/CookieJarEfl.cpp @@ -52,4 +52,19 @@ bool cookiesEnabled(const Document* document) return true; } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/efl/FileChooserEfl.cpp b/Source/WebCore/platform/efl/FileChooserEfl.cpp index c77fa9e..6e6436b 100644 --- a/Source/WebCore/platform/efl/FileChooserEfl.cpp +++ b/Source/WebCore/platform/efl/FileChooserEfl.cpp @@ -46,9 +46,9 @@ String FileChooser::basenameForWidth(const Font& font, int width) const else if (m_filenames.size() == 1) string = m_filenames[0]; else - return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false); + return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font); - return StringTruncator::centerTruncate(string, static_cast<float>(width), font, false); + return StringTruncator::centerTruncate(string, static_cast<float>(width), font); } } diff --git a/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp b/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp index 85dcdcb..7e852f4 100644 --- a/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp +++ b/Source/WebCore/platform/efl/LocalizedStringsEfl.cpp @@ -53,6 +53,11 @@ String resetButtonDefaultLabel() return String::fromUTF8("Reset"); } +String defaultDetailsSummaryText() +{ + return String::fromUTF8("Details"); +} + String searchableIndexIntroduction() { return String::fromUTF8("_Searchable Index"); diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.cpp b/Source/WebCore/platform/efl/RenderThemeEfl.cpp index 9102d17..3e8a646 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.cpp +++ b/Source/WebCore/platform/efl/RenderThemeEfl.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2008 Collabora Ltd. * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia * Copyright (C) 2009-2010 ProFUSION embedded systems - * Copyright (C) 2009-2010 Samsung Electronics + * Copyright (C) 2009-2011 Samsung Electronics * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -68,19 +68,19 @@ void RenderThemeEfl::adjustSizeConstraints(RenderStyle* style, FormType type) co style->setPaddingRight(desc->padding.right()); } -bool RenderThemeEfl::themePartCacheEntryReset(struct ThemePartCacheEntry* ce, FormType type) +bool RenderThemeEfl::themePartCacheEntryReset(struct ThemePartCacheEntry* entry, FormType type) { const char *file, *group; - ASSERT(ce); + ASSERT(entry); edje_object_file_get(m_edje, &file, 0); group = edjeGroupFromFormType(type); ASSERT(file); ASSERT(group); - if (!edje_object_file_set(ce->o, file, group)) { - Edje_Load_Error err = edje_object_load_error_get(ce->o); + if (!edje_object_file_set(entry->o, file, group)) { + Edje_Load_Error err = edje_object_load_error_get(entry->o); const char *errmsg = edje_load_error_str(err); EINA_LOG_ERR("Could not load '%s' from theme %s: %s", group, file, errmsg); @@ -89,21 +89,21 @@ bool RenderThemeEfl::themePartCacheEntryReset(struct ThemePartCacheEntry* ce, Fo return true; } -bool RenderThemeEfl::themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry* ce) +bool RenderThemeEfl::themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry* entry) { int w, h; cairo_status_t status; - ASSERT(ce); - ASSERT(ce->ee); + ASSERT(entry); + ASSERT(entry->ee); - ecore_evas_geometry_get(ce->ee, 0, 0, &w, &h); + ecore_evas_geometry_get(entry->ee, 0, 0, &w, &h); ASSERT(w > 0); ASSERT(h > 0); - ce->surface = cairo_image_surface_create_for_data((unsigned char *)ecore_evas_buffer_pixels_get(ce->ee), + entry->surface = cairo_image_surface_create_for_data((unsigned char *)ecore_evas_buffer_pixels_get(entry->ee), CAIRO_FORMAT_ARGB32, w, h, w * 4); - status = cairo_surface_status(ce->surface); + status = cairo_surface_status(entry->surface); if (status != CAIRO_STATUS_SUCCESS) { EINA_LOG_ERR("Could not create cairo surface: %s", cairo_status_to_string(status)); @@ -116,75 +116,75 @@ bool RenderThemeEfl::themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry // allocate a new entry and fill it with edje group struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartNew(FormType type, const IntSize& size) { - struct ThemePartCacheEntry *ce = new struct ThemePartCacheEntry; + struct ThemePartCacheEntry *entry = new struct ThemePartCacheEntry; - if (!ce) { + if (!entry) { EINA_LOG_ERR("could not allocate ThemePartCacheEntry."); return 0; } - ce->ee = ecore_evas_buffer_new(size.width(), size.height()); - if (!ce->ee) { + entry->ee = ecore_evas_buffer_new(size.width(), size.height()); + if (!entry->ee) { EINA_LOG_ERR("ecore_evas_buffer_new(%d, %d) failed.", size.width(), size.height()); - delete ce; + delete entry; return 0; } - ce->o = edje_object_add(ecore_evas_get(ce->ee)); - ASSERT(ce->o); - if (!themePartCacheEntryReset(ce, type)) { - evas_object_del(ce->o); - ecore_evas_free(ce->ee); - delete ce; + entry->o = edje_object_add(ecore_evas_get(entry->ee)); + ASSERT(entry->o); + if (!themePartCacheEntryReset(entry, type)) { + evas_object_del(entry->o); + ecore_evas_free(entry->ee); + delete entry; return 0; } - if (!themePartCacheEntrySurfaceCreate(ce)) { - evas_object_del(ce->o); - ecore_evas_free(ce->ee); - delete ce; + if (!themePartCacheEntrySurfaceCreate(entry)) { + evas_object_del(entry->o); + ecore_evas_free(entry->ee); + delete entry; return 0; } - evas_object_resize(ce->o, size.width(), size.height()); - evas_object_show(ce->o); + evas_object_resize(entry->o, size.width(), size.height()); + evas_object_show(entry->o); - ce->type = type; - ce->size = size; + entry->type = type; + entry->size = size; - m_partCache.prepend(ce); - return ce; + m_partCache.prepend(entry); + return entry; } // just change the edje group and return the same entry -struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartReset(FormType type, struct RenderThemeEfl::ThemePartCacheEntry* ce) +struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartReset(FormType type, struct RenderThemeEfl::ThemePartCacheEntry* entry) { - if (!themePartCacheEntryReset(ce, type)) { - ce->type = FormTypeLast; // invalidate - m_partCache.append(ce); + if (!themePartCacheEntryReset(entry, type)) { + entry->type = FormTypeLast; // invalidate + m_partCache.append(entry); return 0; } - ce->type = type; - m_partCache.prepend(ce); - return ce; + entry->type = type; + m_partCache.prepend(entry); + return entry; } // resize entry and reset it -struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartResizeAndReset(FormType type, const IntSize& size, struct RenderThemeEfl::ThemePartCacheEntry* ce) +struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartResizeAndReset(FormType type, const IntSize& size, struct RenderThemeEfl::ThemePartCacheEntry* entry) { - cairo_surface_finish(ce->surface); - ecore_evas_resize(ce->ee, size.width(), size.height()); - evas_object_resize(ce->o, size.width(), size.height()); + cairo_surface_finish(entry->surface); + ecore_evas_resize(entry->ee, size.width(), size.height()); + evas_object_resize(entry->o, size.width(), size.height()); - if (!themePartCacheEntrySurfaceCreate(ce)) { - evas_object_del(ce->o); - ecore_evas_free(ce->ee); - delete ce; + if (!themePartCacheEntrySurfaceCreate(entry)) { + evas_object_del(entry->o); + ecore_evas_free(entry->ee); + delete entry; return 0; } - return cacheThemePartReset(type, ce); + return cacheThemePartReset(type, entry); } // general purpose get (will create, reuse and all) @@ -197,11 +197,11 @@ struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartGet(Fo itr = m_partCache.begin(); end = m_partCache.end(); for (i = 0; itr != end; i++, itr++) { - struct ThemePartCacheEntry *ce = *itr; - if (ce->size == size) { - if (ce->type == type) - return ce; - ce_last_size = ce; + struct ThemePartCacheEntry *entry = *itr; + if (entry->size == size) { + if (entry->type == type) + return entry; + ce_last_size = entry; idxLastSize = i; } } @@ -214,9 +214,9 @@ struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartGet(Fo return cacheThemePartReset(type, ce_last_size); } - ThemePartCacheEntry* ce = m_partCache.last(); + ThemePartCacheEntry* entry = m_partCache.last(); m_partCache.removeLast(); - return cacheThemePartResizeAndReset(type, size, ce); + return cacheThemePartResizeAndReset(type, size, entry); } void RenderThemeEfl::cacheThemePartFlush() @@ -226,16 +226,16 @@ void RenderThemeEfl::cacheThemePartFlush() itr = m_partCache.begin(); end = m_partCache.end(); for (; itr != end; itr++) { - struct ThemePartCacheEntry *ce = *itr; - cairo_surface_finish(ce->surface); - evas_object_del(ce->o); - ecore_evas_free(ce->ee); - delete ce; + struct ThemePartCacheEntry *entry = *itr; + cairo_surface_finish(entry->surface); + evas_object_del(entry->o); + ecore_evas_free(entry->ee); + delete entry; } m_partCache.clear(); } -void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* o, ControlStates states) +void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, ControlStates states) { const char *signals[] = { // keep in sync with WebCore/platform/ThemeTypes.h "hovered", @@ -249,37 +249,37 @@ void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* o, ControlStates states "indeterminate" }; - edje_object_signal_emit(o, "reset", ""); + edje_object_signal_emit(object, "reset", ""); for (size_t i = 0; i < WTF_ARRAY_LENGTH(signals); ++i) { if (states & (1 << i)) - edje_object_signal_emit(o, signals[i], ""); + edje_object_signal_emit(object, signals[i], ""); } } -bool RenderThemeEfl::paintThemePart(RenderObject* o, FormType type, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintThemePart(RenderObject* object, FormType type, const PaintInfo& info, const IntRect& rect) { - ThemePartCacheEntry* ce; + ThemePartCacheEntry* entry; Eina_List* updates; cairo_t* cairo; ASSERT(m_canvas); ASSERT(m_edje); - ce = cacheThemePartGet(type, rect.size()); - ASSERT(ce); - if (!ce) + entry = cacheThemePartGet(type, rect.size()); + ASSERT(entry); + if (!entry) return false; - applyEdjeStateFromForm(ce->o, controlStatesForRenderer(o)); + applyEdjeStateFromForm(entry->o, controlStatesForRenderer(object)); - cairo = i.context->platformContext(); + cairo = info.context->platformContext(); ASSERT(cairo); // Currently, only sliders needs this message; if other widget ever needs special // treatment, move them to special functions. if (type == SliderVertical || type == SliderHorizontal) { - RenderSlider* renderSlider = toRenderSlider(o); + RenderSlider* renderSlider = toRenderSlider(object); Edje_Message_Float_Set* msg; int max, value; @@ -296,10 +296,10 @@ bool RenderThemeEfl::paintThemePart(RenderObject* o, FormType type, const PaintI msg->count = 2; msg->val[0] = static_cast<float>(value) / static_cast<float>(max); msg->val[1] = 0.1; - edje_object_message_send(ce->o, EDJE_MESSAGE_FLOAT_SET, 0, msg); + edje_object_message_send(entry->o, EDJE_MESSAGE_FLOAT_SET, 0, msg); #if ENABLE(PROGRESS_TAG) } else if (type == ProgressBar) { - RenderProgress* renderProgress = toRenderProgress(o); + RenderProgress* renderProgress = toRenderProgress(object); Edje_Message_Float_Set* msg; int max; double value; @@ -309,22 +309,22 @@ bool RenderThemeEfl::paintThemePart(RenderObject* o, FormType type, const PaintI value = renderProgress->position(); msg->count = 2; - if (o->style()->direction() == RTL) + if (object->style()->direction() == RTL) msg->val[0] = (1.0 - value) * max; else msg->val[0] = 0; msg->val[1] = value; - edje_object_message_send(ce->o, EDJE_MESSAGE_FLOAT_SET, 0, msg); + edje_object_message_send(entry->o, EDJE_MESSAGE_FLOAT_SET, 0, msg); #endif } - edje_object_calc_force(ce->o); - edje_object_message_signal_process(ce->o); - updates = evas_render_updates(ecore_evas_get(ce->ee)); + edje_object_calc_force(entry->o); + edje_object_message_signal_process(entry->o); + updates = evas_render_updates(ecore_evas_get(entry->ee)); evas_render_updates_free(updates); cairo_save(cairo); - cairo_set_source_surface(cairo, ce->surface, rect.x(), rect.y()); + cairo_set_source_surface(cairo, entry->surface, rect.x(), rect.y()); cairo_paint_with_alpha(cairo, 1.0); cairo_restore(cairo); @@ -345,77 +345,77 @@ PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) return fallback; } -static void renderThemeEflColorClassSelectionActive(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassSelectionActive(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa, br, bg, bb, ba; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) return; that->setActiveSelectionColor(fr, fg, fb, fa, br, bg, bb, ba); } -static void renderThemeEflColorClassSelectionInactive(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassSelectionInactive(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa, br, bg, bb, ba; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) return; that->setInactiveSelectionColor(fr, fg, fb, fa, br, bg, bb, ba); } -static void renderThemeEflColorClassFocusRing(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassFocusRing(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, 0, 0, 0, 0, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, 0, 0, 0, 0, 0, 0, 0, 0)) return; that->setFocusRingColor(fr, fg, fb, fa); } -static void renderThemeEflColorClassButtonText(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassButtonText(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa, br, bg, bb, ba; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) return; that->setButtonTextColor(fr, fg, fb, fa, br, bg, bb, ba); } -static void renderThemeEflColorClassComboText(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassComboText(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa, br, bg, bb, ba; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) return; that->setComboTextColor(fr, fg, fb, fa, br, bg, bb, ba); } -static void renderThemeEflColorClassEntryText(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassEntryText(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa, br, bg, bb, ba; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) return; that->setEntryTextColor(fr, fg, fb, fa, br, bg, bb, ba); } -static void renderThemeEflColorClassSearchText(void* data, Evas_Object* o, const char* signal, const char* source) +static void renderThemeEflColorClassSearchText(void* data, Evas_Object* object, const char* signal, const char* source) { RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data); int fr, fg, fb, fa, br, bg, bb, ba; - if (!edje_object_color_class_get(o, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) + if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0)) return; that->setSearchTextColor(fr, fg, fb, fa, br, bg, bb, ba); @@ -522,22 +522,22 @@ void RenderThemeEfl::applyPartDescriptionFallback(struct ThemePartDesc* desc) desc->padding = LengthBox(0, 0, 0, 0); } -void RenderThemeEfl::applyPartDescription(Evas_Object* o, struct ThemePartDesc* desc) +void RenderThemeEfl::applyPartDescription(Evas_Object* object, struct ThemePartDesc* desc) { Evas_Coord minw, minh, maxw, maxh; - edje_object_size_min_get(o, &minw, &minh); + edje_object_size_min_get(object, &minw, &minh); if (!minw && !minh) - edje_object_size_min_calc(o, &minw, &minh); + edje_object_size_min_calc(object, &minw, &minh); desc->min.setWidth(Length(minw, Fixed)); desc->min.setHeight(Length(minh, Fixed)); - edje_object_size_max_get(o, &maxw, &maxh); + edje_object_size_max_get(object, &maxw, &maxh); desc->max.setWidth(Length(maxw, Fixed)); desc->max.setHeight(Length(maxh, Fixed)); - if (!edje_object_part_exists(o, "text_confinement")) + if (!edje_object_part_exists(object, "text_confinement")) desc->padding = LengthBox(0, 0, 0, 0); else { Evas_Coord px, py, pw, ph; @@ -557,11 +557,11 @@ void RenderThemeEfl::applyPartDescription(Evas_Object* o, struct ThemePartDesc* if (maxh > 0 && oh > maxh) oh = maxh; - evas_object_move(o, ox, oy); - evas_object_resize(o, ow, oh); - edje_object_calc_force(o); - edje_object_message_signal_process(o); - edje_object_part_geometry_get(o, "text_confinement", &px, &py, &pw, &ph); + evas_object_move(object, ox, oy); + evas_object_resize(object, ow, oh); + edje_object_calc_force(object); + edje_object_message_signal_process(object); + edje_object_part_geometry_get(object, "text_confinement", &px, &py, &pw, &ph); t = py - oy; b = (oh + oy) - (ph + py); @@ -602,7 +602,7 @@ const char* RenderThemeEfl::edjeGroupFromFormType(FormType type) const void RenderThemeEfl::applyPartDescriptions() { - Evas_Object* o; + Evas_Object* object; unsigned int i; const char* file; @@ -612,8 +612,8 @@ void RenderThemeEfl::applyPartDescriptions() edje_object_file_get(m_edje, &file, 0); ASSERT(file); - o = edje_object_add(ecore_evas_get(m_canvas)); - if (!o) { + object = edje_object_add(ecore_evas_get(m_canvas)); + if (!object) { EINA_LOG_ERR("Could not create Edje object."); return; } @@ -622,17 +622,17 @@ void RenderThemeEfl::applyPartDescriptions() FormType type = static_cast<FormType>(i); const char* group = edjeGroupFromFormType(type); m_partDescs[i].type = type; - if (!edje_object_file_set(o, file, group)) { - Edje_Load_Error err = edje_object_load_error_get(o); + if (!edje_object_file_set(object, file, group)) { + Edje_Load_Error err = edje_object_load_error_get(object); const char* errmsg = edje_load_error_str(err); EINA_LOG_ERR("Could not set theme group '%s' of file '%s': %s", group, file, errmsg); applyPartDescriptionFallback(m_partDescs + i); } else - applyPartDescription(o, m_partDescs + i); + applyPartDescription(object, m_partDescs + i); } - evas_object_del(o); + evas_object_del(object); } void RenderThemeEfl::themeChanged() @@ -767,34 +767,34 @@ bool RenderThemeEfl::supportsFocusRing(const RenderStyle* style) const return supportsFocus(style->appearance()); } -bool RenderThemeEfl::controlSupportsTints(const RenderObject* o) const +bool RenderThemeEfl::controlSupportsTints(const RenderObject* object) const { - return isEnabled(o); + return isEnabled(object); } -int RenderThemeEfl::baselinePosition(const RenderObject* o) const +int RenderThemeEfl::baselinePosition(const RenderObject* object) const { - if (!o->isBox()) + if (!object->isBox()) return 0; - if (o->style()->appearance() == CheckboxPart - || o->style()->appearance() == RadioPart) - return toRenderBox(o)->marginTop() + toRenderBox(o)->height() - 3; + if (object->style()->appearance() == CheckboxPart + || object->style()->appearance() == RadioPart) + return toRenderBox(object)->marginTop() + toRenderBox(object)->height() - 3; - return RenderTheme::baselinePosition(o); + return RenderTheme::baselinePosition(object); } -bool RenderThemeEfl::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - if (o->style()->appearance() == SliderHorizontalPart) - return paintThemePart(o, SliderHorizontal, i, rect); - return paintThemePart(o, SliderVertical, i, rect); + if (object->style()->appearance() == SliderHorizontalPart) + return paintThemePart(object, SliderHorizontal, info, rect); + return paintThemePart(object, SliderVertical, info, rect); } -void RenderThemeEfl::adjustSliderTrackStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSliderTrackStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustSliderTrackStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSliderTrackStyle(selector, style, element); return; } @@ -808,20 +808,20 @@ void RenderThemeEfl::adjustSliderTrackStyle(CSSStyleSelector* selector, RenderSt style->setHeight(desc->min.height()); } -void RenderThemeEfl::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSliderThumbStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - adjustSliderTrackStyle(selector, style, e); + adjustSliderTrackStyle(selector, style, element); } -bool RenderThemeEfl::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintSliderTrack(o, i, rect); + return paintSliderTrack(object, info, rect); } -void RenderThemeEfl::adjustCheckboxStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustCheckboxStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustCheckboxStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustCheckboxStyle(selector, style, element); return; } adjustSizeConstraints(style, CheckBox); @@ -834,15 +834,15 @@ void RenderThemeEfl::adjustCheckboxStyle(CSSStyleSelector* selector, RenderStyle style->setHeight(desc->min.height()); } -bool RenderThemeEfl::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, CheckBox, i, rect); + return paintThemePart(object, CheckBox, info, rect); } -void RenderThemeEfl::adjustRadioStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustRadioStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustRadioStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustRadioStyle(selector, style, element); return; } adjustSizeConstraints(style, RadioButton); @@ -855,15 +855,15 @@ void RenderThemeEfl::adjustRadioStyle(CSSStyleSelector* selector, RenderStyle* s style->setHeight(desc->min.height()); } -bool RenderThemeEfl::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, RadioButton, i, rect); + return paintThemePart(object, RadioButton, info, rect); } -void RenderThemeEfl::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustButtonStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustButtonStyle(selector, style, element); return; } @@ -878,15 +878,15 @@ void RenderThemeEfl::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* } } -bool RenderThemeEfl::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, Button, i, rect); + return paintThemePart(object, Button, info, rect); } -void RenderThemeEfl::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustMenuListStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustMenuListStyle(selector, style, element); return; } adjustSizeConstraints(style, ComboBox); @@ -896,15 +896,15 @@ void RenderThemeEfl::adjustMenuListStyle(CSSStyleSelector* selector, RenderStyle style->setBackgroundColor(m_comboTextBackgroundColor); } -bool RenderThemeEfl::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, ComboBox, i, rect); + return paintThemePart(object, ComboBox, info, rect); } -void RenderThemeEfl::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustTextFieldStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustTextFieldStyle(selector, style, element); return; } adjustSizeConstraints(style, TextField); @@ -914,25 +914,25 @@ void RenderThemeEfl::adjustTextFieldStyle(CSSStyleSelector* selector, RenderStyl style->setBackgroundColor(m_entryTextBackgroundColor); } -bool RenderThemeEfl::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, TextField, i, rect); + return paintThemePart(object, TextField, info, rect); } -void RenderThemeEfl::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustTextAreaStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - adjustTextFieldStyle(selector, style, e); + adjustTextFieldStyle(selector, style, element); } -bool RenderThemeEfl::paintTextArea(RenderObject* o, const PaintInfo& i, const IntRect& r) +bool RenderThemeEfl::paintTextArea(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintTextField(o, i, r); + return paintTextField(object, info, rect); } -void RenderThemeEfl::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustSearchFieldDecorationStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldDecorationStyle(selector, style, element); return; } adjustSizeConstraints(style, SearchFieldDecoration); @@ -940,15 +940,15 @@ void RenderThemeEfl::adjustSearchFieldDecorationStyle(CSSStyleSelector* selector style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldDecoration(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldDecoration(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, SearchFieldDecoration, i, rect); + return paintThemePart(object, SearchFieldDecoration, info, rect); } -void RenderThemeEfl::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustSearchFieldResultsButtonStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldResultsButtonStyle(selector, style, element); return; } adjustSizeConstraints(style, SearchFieldResultsButton); @@ -956,15 +956,15 @@ void RenderThemeEfl::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldResultsButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, SearchFieldResultsButton, i, rect); + return paintThemePart(object, SearchFieldResultsButton, info, rect); } -void RenderThemeEfl::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustSearchFieldResultsDecorationStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldResultsDecorationStyle(selector, style, element); return; } adjustSizeConstraints(style, SearchFieldResultsDecoration); @@ -972,15 +972,15 @@ void RenderThemeEfl::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldResultsDecoration(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, SearchFieldResultsDecoration, i, rect); + return paintThemePart(object, SearchFieldResultsDecoration, info, rect); } -void RenderThemeEfl::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustSearchFieldCancelButtonStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldCancelButtonStyle(selector, style, element); return; } adjustSizeConstraints(style, SearchFieldCancelButton); @@ -988,15 +988,15 @@ void RenderThemeEfl::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select style->setWhiteSpace(PRE); } -bool RenderThemeEfl::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchFieldCancelButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, SearchFieldCancelButton, i, rect); + return paintThemePart(object, SearchFieldCancelButton, info, rect); } -void RenderThemeEfl::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const +void RenderThemeEfl::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { - if (!m_page && e && e->document()->page()) { - static_cast<RenderThemeEfl*>(e->document()->page()->theme())->adjustSearchFieldStyle(selector, style, e); + if (!m_page && element && element->document()->page()) { + static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldStyle(selector, style, element); return; } adjustSizeConstraints(style, SearchField); @@ -1006,9 +1006,9 @@ void RenderThemeEfl::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderSt style->setBackgroundColor(m_searchTextBackgroundColor); } -bool RenderThemeEfl::paintSearchField(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, SearchField, i, rect); + return paintThemePart(object, SearchField, info, rect); } void RenderThemeEfl::setDefaultFontSize(int size) @@ -1032,14 +1032,14 @@ void RenderThemeEfl::systemFont(int propId, FontDescription& fontDescription) co } #if ENABLE(PROGRESS_TAG) -void RenderThemeEfl::adjustProgressBarStyle(CSSStyleSelector*, RenderStyle* style, Element*) const +void RenderThemeEfl::adjustProgressBarStyle(CSSStyleSelector* selector, RenderStyle* style, Element* element) const { style->setBoxShadow(0); } -bool RenderThemeEfl::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& rect) +bool RenderThemeEfl::paintProgressBar(RenderObject* object, const PaintInfo& info, const IntRect& rect) { - return paintThemePart(o, ProgressBar, i, rect); + return paintThemePart(object, ProgressBar, info, rect); } #endif @@ -1056,67 +1056,67 @@ String RenderThemeEfl::formatMediaControlsCurrentTime(float currentTime, float d return String(); } -bool RenderThemeEfl::paintMediaFullscreenButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaMuteButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaMuteButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaPlayButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaPlayButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaSeekBackButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaSeekBackButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaSeekForwardButton(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaSeekForwardButton(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaSliderTrack(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeEfl::paintMediaSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaSliderThumb(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r) +bool RenderThemeEfl::paintMediaSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaVolumeSliderTrack(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaVolumeSliderThumb(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; } -bool RenderThemeEfl::paintMediaCurrentTime(RenderObject* renderObject, const PaintInfo& paintInfo, const IntRect& rect) +bool RenderThemeEfl::paintMediaCurrentTime(RenderObject* object, const PaintInfo& info, const IntRect& rect) { notImplemented(); return false; diff --git a/Source/WebCore/platform/efl/RenderThemeEfl.h b/Source/WebCore/platform/efl/RenderThemeEfl.h index d4887cf..9970096 100644 --- a/Source/WebCore/platform/efl/RenderThemeEfl.h +++ b/Source/WebCore/platform/efl/RenderThemeEfl.h @@ -101,7 +101,7 @@ public: void setEntryTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA); void setSearchTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA); - void adjustSizeConstraints(RenderStyle* style, FormType type) const; + void adjustSizeConstraints(RenderStyle*, FormType) const; // System fonts. @@ -146,7 +146,7 @@ public: virtual void adjustSliderThumbStyle(CSSStyleSelector*, RenderStyle*, Element*) const; virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&); - static void setDefaultFontSize(int size); + static void setDefaultFontSize(int fontsize); #if ENABLE(PROGRESS_TAG) virtual void adjustProgressBarStyle(CSSStyleSelector*, RenderStyle*, Element*) const; @@ -178,9 +178,9 @@ private: void createEdje(); void applyEdjeColors(); void applyPartDescriptions(); - const char* edjeGroupFromFormType(FormType type) const; - void applyEdjeStateFromForm(Evas_Object* o, ControlStates states); - bool paintThemePart(RenderObject* o, FormType type, const PaintInfo& i, const IntRect& rect); + const char* edjeGroupFromFormType(FormType) const; + void applyEdjeStateFromForm(Evas_Object*, ControlStates); + bool paintThemePart(RenderObject*, FormType, const PaintInfo&, const IntRect&); Page* m_page; Color m_activeSelectionBackgroundColor; @@ -205,8 +205,8 @@ private: LengthSize max; LengthBox padding; }; - void applyPartDescriptionFallback(struct ThemePartDesc* desc); - void applyPartDescription(Evas_Object* o, struct ThemePartDesc* desc); + void applyPartDescriptionFallback(struct ThemePartDesc*); + void applyPartDescription(Evas_Object*, struct ThemePartDesc*); struct ThemePartCacheEntry { FormType type; @@ -223,16 +223,16 @@ private: Vector<struct ThemePartCacheEntry *> m_partCache; // get (use, create or replace) entry from cache - struct ThemePartCacheEntry* cacheThemePartGet(FormType type, const IntSize& size); + struct ThemePartCacheEntry* cacheThemePartGet(FormType, const IntSize&); // flush cache, deleting all entries void cacheThemePartFlush(); // internal, used by cacheThemePartGet() - bool themePartCacheEntryReset(struct ThemePartCacheEntry* ce, FormType type); - bool themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry* ce); - struct ThemePartCacheEntry* cacheThemePartNew(FormType type, const IntSize& size); - struct ThemePartCacheEntry* cacheThemePartReset(FormType type, struct ThemePartCacheEntry* ce); - struct ThemePartCacheEntry* cacheThemePartResizeAndReset(FormType type, const IntSize& size, struct ThemePartCacheEntry* ce); + bool themePartCacheEntryReset(struct ThemePartCacheEntry*, FormType); + bool themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry*); + struct ThemePartCacheEntry* cacheThemePartNew(FormType, const IntSize&); + struct ThemePartCacheEntry* cacheThemePartReset(FormType, struct ThemePartCacheEntry*); + struct ThemePartCacheEntry* cacheThemePartResizeAndReset(FormType, const IntSize&, struct ThemePartCacheEntry*); }; } diff --git a/Source/WebCore/platform/efl/SystemTimeEfl.cpp b/Source/WebCore/platform/efl/SystemTimeEfl.cpp index ec6d662..668ec00 100644 --- a/Source/WebCore/platform/efl/SystemTimeEfl.cpp +++ b/Source/WebCore/platform/efl/SystemTimeEfl.cpp @@ -1,7 +1,5 @@ /* - * Copyright (C) 2008 INdT. All rights reserved. - * Copyright (C) 2009-2010 ProFUSION embedded systems - * Copyright (C) 2009-2010 Samsung Electronics + * 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 @@ -12,33 +10,27 @@ * 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 + * 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 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "SystemTime.h" #include "NotImplemented.h" -#include <Ecore.h> #include <limits> namespace WebCore { -double currentTime() -{ - return ecore_time_get(); -} - float userIdleTime() { notImplemented(); diff --git a/Source/WebCore/platform/efl/TemporaryLinkStubs.cpp b/Source/WebCore/platform/efl/TemporaryLinkStubs.cpp index 07ea2e6..be38565 100644 --- a/Source/WebCore/platform/efl/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/efl/TemporaryLinkStubs.cpp @@ -61,5 +61,15 @@ void setCookieStoragePrivateBrowsingEnabled(bool) notImplemented(); } +void startObservingCookieChanges() +{ + notImplemented(); +} + +void stopObservingCookieChanges() +{ + notImplemented(); +} + } diff --git a/Source/WebCore/platform/graphics/BitmapImage.cpp b/Source/WebCore/platform/graphics/BitmapImage.cpp index 1148aa6..6027f34 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.cpp +++ b/Source/WebCore/platform/graphics/BitmapImage.cpp @@ -60,6 +60,7 @@ BitmapImage::BitmapImage(ImageObserver* observer) , m_sizeAvailable(false) , m_hasUniformFrameSize(true) , m_decodedSize(0) + , m_decodedPropertiesSize(0) , m_haveFrameCount(false) , m_frameCount(0) { @@ -104,8 +105,12 @@ void BitmapImage::destroyMetadataAndNotify(int framesCleared) m_isSolidColor = false; invalidatePlatformData(); - const int deltaBytes = framesCleared * -frameBytes(m_size); + int deltaBytes = framesCleared * -frameBytes(m_size); m_decodedSize += deltaBytes; + if (framesCleared > 0) { + deltaBytes -= m_decodedPropertiesSize; + m_decodedPropertiesSize = 0; + } if (deltaBytes && imageObserver()) imageObserver()->decodedSizeChanged(this, deltaBytes); } @@ -132,18 +137,41 @@ void BitmapImage::cacheFrame(size_t index) if (frameSize != m_size) m_hasUniformFrameSize = false; if (m_frames[index].m_frame) { - const int deltaBytes = frameBytes(frameSize); + int deltaBytes = frameBytes(frameSize); m_decodedSize += deltaBytes; + // The fully-decoded frame will subsume the partially decoded data used + // to determine image properties. + deltaBytes -= m_decodedPropertiesSize; + m_decodedPropertiesSize = 0; if (imageObserver()) imageObserver()->decodedSizeChanged(this, deltaBytes); } } +void BitmapImage::didDecodeProperties() const +{ + if (m_decodedSize) + return; + size_t updatedSize = m_source.bytesDecodedToDetermineProperties(); + if (m_decodedPropertiesSize == updatedSize) + return; + int deltaBytes = updatedSize - m_decodedPropertiesSize; +#ifndef NDEBUG + bool overflow = updatedSize > m_decodedPropertiesSize && deltaBytes < 0; + bool underflow = updatedSize < m_decodedPropertiesSize && deltaBytes > 0; + ASSERT(!overflow && !underflow); +#endif + m_decodedPropertiesSize = updatedSize; + if (imageObserver()) + imageObserver()->decodedSizeChanged(this, deltaBytes); +} + IntSize BitmapImage::size() const { if (m_sizeAvailable && !m_haveSize) { m_size = m_source.size(); m_haveSize = true; + didDecodeProperties(); } return m_size; } @@ -152,12 +180,16 @@ IntSize BitmapImage::currentFrameSize() const { if (!m_currentFrame || m_hasUniformFrameSize) return size(); - return m_source.frameSizeAtIndex(m_currentFrame); + IntSize frameSize = m_source.frameSizeAtIndex(m_currentFrame); + didDecodeProperties(); + return frameSize; } bool BitmapImage::getHotSpot(IntPoint& hotSpot) const { - return m_source.getHotSpot(hotSpot); + bool result = m_source.getHotSpot(hotSpot); + didDecodeProperties(); + return result; } bool BitmapImage::dataChanged(bool allDataReceived) @@ -190,6 +222,7 @@ size_t BitmapImage::frameCount() if (!m_haveFrameCount) { m_haveFrameCount = true; m_frameCount = m_source.frameCount(); + didDecodeProperties(); } return m_frameCount; } @@ -200,6 +233,7 @@ bool BitmapImage::isSizeAvailable() return true; m_sizeAvailable = m_source.isSizeAvailable(); + didDecodeProperties(); return m_sizeAvailable; } @@ -256,6 +290,7 @@ int BitmapImage::repetitionCount(bool imageKnownToBeComplete) // decoder will default to cAnimationLoopOnce, and we'll try and read // the count again once the whole image is decoded. m_repetitionCount = m_source.repetitionCount(); + didDecodeProperties(); m_repetitionCountStatus = (imageKnownToBeComplete || m_repetitionCount == cAnimationNone) ? Certain : Uncertain; } return m_repetitionCount; diff --git a/Source/WebCore/platform/graphics/BitmapImage.h b/Source/WebCore/platform/graphics/BitmapImage.h index 93fc464..14a3094 100644 --- a/Source/WebCore/platform/graphics/BitmapImage.h +++ b/Source/WebCore/platform/graphics/BitmapImage.h @@ -215,6 +215,12 @@ protected: // Whether or not size is available yet. bool isSizeAvailable(); + // Called after asking the source for any information that may require + // decoding part of the image (e.g., the image size). We need to report + // the partially decoded data to our observer so it has an accurate + // account of the BitmapImage's memory usage. + void didDecodeProperties() const; + // Animation. int repetitionCount(bool imageKnownToBeComplete); // |imageKnownToBeComplete| should be set if the caller knows the entire image has been decoded. bool shouldAnimate(); @@ -281,6 +287,7 @@ protected: mutable bool m_hasUniformFrameSize; unsigned m_decodedSize; // The current size of all decoded frames. + mutable unsigned m_decodedPropertiesSize; // The size of data decoded by the source to determine image properties (e.g. size, frame count, etc). mutable bool m_haveFrameCount; size_t m_frameCount; diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp index fa7346e..a1c5cd7 100644 --- a/Source/WebCore/platform/graphics/Color.cpp +++ b/Source/WebCore/platform/graphics/Color.cpp @@ -180,19 +180,52 @@ Color::Color(const char* name) } } +static inline void appendHexNumber(UChar* destination, uint8_t number) +{ + static const char hexDigits[17] = "0123456789abcdef"; + + destination[0] = hexDigits[number >> 4]; + destination[1] = hexDigits[number & 0xF]; +} + String Color::serialized() const { - if (alpha() == 0xFF) - return String::format("#%02x%02x%02x", red(), green(), blue()); + DEFINE_STATIC_LOCAL(const String, commaSpace, (", ")); + DEFINE_STATIC_LOCAL(const String, rgbaParen, ("rgba(")); + DEFINE_STATIC_LOCAL(const String, zeroPointZero, ("0.0")); + + if (!hasAlpha()) { + UChar* characters; + String result = String::createUninitialized(7, characters); + characters[0] = '#'; + appendHexNumber(characters + 1, red()); + appendHexNumber(characters + 3, green()); + appendHexNumber(characters + 5, blue()); + return result; + } + + Vector<UChar> result; + result.reserveInitialCapacity(28); + + append(result, rgbaParen); + appendNumber(result, red()); + append(result, commaSpace); + appendNumber(result, green()); + append(result, commaSpace); + appendNumber(result, blue()); + append(result, commaSpace); // Match Gecko ("0.0" for zero, 5 decimals for anything else) if (!alpha()) - return String::format("rgba(%u, %u, %u, 0.0)", red(), green(), blue()); + append(result, zeroPointZero); + else + append(result, String::format("%.5f", alpha() / 255.0f)); - return String::format("rgba(%u, %u, %u, %.5f)", red(), green(), blue(), alpha() / 255.0f); + result.append(')'); + return String::adopt(result); } -String Color::name() const +String Color::nameForRenderTreeAsText() const { if (alpha() < 0xFF) return String::format("#%02X%02X%02X%02X", red(), green(), blue(), alpha()); diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h index 2a03238..05d9554 100644 --- a/Source/WebCore/platform/graphics/Color.h +++ b/Source/WebCore/platform/graphics/Color.h @@ -96,7 +96,10 @@ public: // - http://www.whatwg.org/specs/web-apps/current-work/#serialization-of-a-color String serialized() const; - String name() const; + // Returns the color serialized as either #RRGGBB or #RRGGBBAA + // The latter format is not a valid CSS color, and should only be seen in DRT dumps. + String nameForRenderTreeAsText() const; + void setNamedColor(const String&); bool isValid() const { return m_valid; } diff --git a/Source/WebCore/platform/graphics/Extensions3D.h b/Source/WebCore/platform/graphics/Extensions3D.h index 6d6efe5..5d5a5b7 100644 --- a/Source/WebCore/platform/graphics/Extensions3D.h +++ b/Source/WebCore/platform/graphics/Extensions3D.h @@ -26,6 +26,8 @@ #ifndef Extensions3D_h #define Extensions3D_h +#include "GraphicsTypes3D.h" + #include <wtf/text/WTFString.h> namespace WebCore { @@ -53,6 +55,7 @@ public: // GL_OES_texture_float // GL_OES_standard_derivatives // GL_OES_rgb8_rgba8 + // GL_OES_vertex_array_object // Takes full name of extension; for example, // "GL_EXT_texture_format_BGRA8888". @@ -92,6 +95,9 @@ public: // GL_OES_rgb8_rgba8 names RGB8_OES = 0x8051, RGBA8_OES = 0x8058, + + // GL_OES_vertex_array_object names + VERTEX_ARRAY_BINDING_OES = 0x85B5, }; // GL_ARB_robustness @@ -101,7 +107,13 @@ public: virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) = 0; // GL_ANGLE_framebuffer_multisample - virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) = 0; + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) = 0; + + // GL_OES_vertex_array_object + virtual Platform3DObject createVertexArrayOES() = 0; + virtual void deleteVertexArrayOES(Platform3DObject) = 0; + virtual GC3Dboolean isVertexArrayOES(Platform3DObject) = 0; + virtual void bindVertexArrayOES(Platform3DObject) = 0; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/FloatPoint.h b/Source/WebCore/platform/graphics/FloatPoint.h index 73a1bac..c4b2943 100644 --- a/Source/WebCore/platform/graphics/FloatPoint.h +++ b/Source/WebCore/platform/graphics/FloatPoint.h @@ -54,7 +54,7 @@ QT_END_NAMESPACE class BPoint; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkPoint; #endif @@ -130,7 +130,7 @@ public: operator BPoint() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) operator SkPoint() const; FloatPoint(const SkPoint&); #endif diff --git a/Source/WebCore/platform/graphics/FloatRect.h b/Source/WebCore/platform/graphics/FloatRect.h index 733f7cc..bd23476 100644 --- a/Source/WebCore/platform/graphics/FloatRect.h +++ b/Source/WebCore/platform/graphics/FloatRect.h @@ -55,7 +55,7 @@ class wxRect2DDouble; class BRect; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkRect; #endif @@ -163,7 +163,7 @@ public: operator BRect() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) FloatRect(const SkRect&); operator SkRect() const; #endif diff --git a/Source/WebCore/platform/graphics/Font.cpp b/Source/WebCore/platform/graphics/Font.cpp index 6bdddfc..ee85e45 100644 --- a/Source/WebCore/platform/graphics/Font.cpp +++ b/Source/WebCore/platform/graphics/Font.cpp @@ -39,17 +39,6 @@ using namespace Unicode; namespace WebCore { -const uint8_t Font::gRoundingHackCharacterTable[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*\t*/, 1 /*\n*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1 /*space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*-*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 /*?*/, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1 /*no-break space*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - Font::CodePath Font::s_codePath = Auto; // ============================================================================================ @@ -176,7 +165,7 @@ void Font::drawEmphasisMarks(GraphicsContext* context, const TextRun& run, const drawEmphasisMarksForComplexText(context, run, mark, point, from, to); } -float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const +float Font::width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, GlyphOverflow* glyphOverflow) const { #if ENABLE(SVG_FONTS) if (primaryFont()->isSVGFont()) @@ -194,7 +183,7 @@ float Font::floatWidth(const TextRun& run, HashSet<const SimpleFontData*>* fallb return floatWidthForComplexText(run, fallbackFonts, glyphOverflow); } -float Font::floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const +float Font::width(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const { #if !ENABLE(SVG_FONTS) UNUSED_PARAM(extraCharsAvailable); diff --git a/Source/WebCore/platform/graphics/Font.h b/Source/WebCore/platform/graphics/Font.h index 258240b..ce03aed 100644 --- a/Source/WebCore/platform/graphics/Font.h +++ b/Source/WebCore/platform/graphics/Font.h @@ -94,9 +94,8 @@ public: void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const; void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const; - int width(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const { return lroundf(floatWidth(run, fallbackFonts, glyphOverflow)); } - float floatWidth(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* glyphOverflow = 0) const; - float floatWidth(const TextRun& run, int extraCharsAvailable, int& charsConsumed, String& glyphName) const; + float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const; + float width(const TextRun&, int extraCharsAvailable, int& charsConsumed, String& glyphName) const; int offsetForPosition(const TextRun&, float position, bool includePartialGlyphs) const; FloatRect selectionRectForText(const TextRun&, const FloatPoint&, int h, int from = 0, int to = -1) const; @@ -129,8 +128,8 @@ public: // Metrics that we query the FontFallbackList for. const FontMetrics& fontMetrics() const { return primaryFont()->fontMetrics(); } - int spaceWidth() const { return (int)ceilf(primaryFont()->adjustedSpaceWidth() + m_letterSpacing); } - float tabWidth(const SimpleFontData& fontData) const { return 8 * ceilf(fontData.adjustedSpaceWidth() + letterSpacing()); } + float spaceWidth() const { return primaryFont()->spaceWidth() + m_letterSpacing; } + float tabWidth(const SimpleFontData& fontData) const { return 8 * fontData.spaceWidth() + letterSpacing(); } int emphasisMarkAscent(const AtomicString&) const; int emphasisMarkDescent(const AtomicString&) const; int emphasisMarkHeight(const AtomicString&) const; @@ -201,12 +200,6 @@ public: static CodePath codePath(); static CodePath s_codePath; - static const uint8_t gRoundingHackCharacterTable[256]; - static bool isRoundingHackCharacter(UChar32 c) - { - return (((c & ~0xFF) == 0 && gRoundingHackCharacterTable[c])); - } - FontSelector* fontSelector() const; static bool treatAsSpace(UChar c) { return c == ' ' || c == '\t' || c == '\n' || c == noBreakSpace; } static bool treatAsZeroWidthSpace(UChar c) { return c < 0x20 || (c >= 0x7F && c < 0xA0) || c == softHyphen || (c >= 0x200c && c <= 0x200f) || (c >= 0x202a && c <= 0x202e) || c == objectReplacementCharacter; } diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp index ca82ebd..5b508be 100644 --- a/Source/WebCore/platform/graphics/FontCache.cpp +++ b/Source/WebCore/platform/graphics/FontCache.cpp @@ -261,7 +261,7 @@ typedef HashMap<FontPlatformData, pair<SimpleFontData*, unsigned>, FontDataCache static FontDataCache* gFontDataCache = 0; const int cMaxInactiveFontData = 120; // Pretty Low Threshold -const float cTargetInactiveFontData = 100; +const int cTargetInactiveFontData = 100; static ListHashSet<const SimpleFontData*>* gInactiveFontData = 0; SimpleFontData* FontCache::getCachedFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName) diff --git a/Source/WebCore/platform/graphics/FontFastPath.cpp b/Source/WebCore/platform/graphics/FontFastPath.cpp index 034ac22..e62df61 100644 --- a/Source/WebCore/platform/graphics/FontFastPath.cpp +++ b/Source/WebCore/platform/graphics/FontFastPath.cpp @@ -297,9 +297,8 @@ float Font::getGlyphsAndAdvancesForSimpleText(const TextRun& run, int from, int float afterWidth = it.m_runWidthSoFar; if (run.rtl()) { - float finalRoundingWidth = it.m_finalRoundingWidth; it.advance(run.length()); - initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth; + initialAdvance = it.m_runWidthSoFar - afterWidth; } else initialAdvance = beforeWidth; diff --git a/Source/WebCore/platform/graphics/Gradient.cpp b/Source/WebCore/platform/graphics/Gradient.cpp index 6d0f535..f64fe6b 100644 --- a/Source/WebCore/platform/graphics/Gradient.cpp +++ b/Source/WebCore/platform/graphics/Gradient.cpp @@ -221,7 +221,11 @@ void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra setPlatformGradientSpaceTransform(gradientSpaceTransformation); } +<<<<<<< HEAD #if !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(CAIRO) +======= +#if !USE(SKIA) && !PLATFORM(CAIRO) +>>>>>>> WebKit at r80534 void Gradient::setPlatformGradientSpaceTransform(const AffineTransform&) { } diff --git a/Source/WebCore/platform/graphics/Gradient.h b/Source/WebCore/platform/graphics/Gradient.h index 790e8e1..432262d 100644 --- a/Source/WebCore/platform/graphics/Gradient.h +++ b/Source/WebCore/platform/graphics/Gradient.h @@ -57,11 +57,15 @@ typedef QGradient* PlatformGradient; #elif PLATFORM(CAIRO) typedef struct _cairo_pattern cairo_pattern_t; typedef cairo_pattern_t* PlatformGradient; +<<<<<<< HEAD #elif PLATFORM(SKIA) #if PLATFORM(ANDROID) #include "SkShader.h" typedef class PlatformGradientRec* PlatformGradient; #else +======= +#elif USE(SKIA) +>>>>>>> WebKit at r80534 class SkShader; typedef class SkShader* PlatformGradient; typedef class SkShader* PlatformPattern; diff --git a/Source/WebCore/platform/graphics/GraphicsContext.cpp b/Source/WebCore/platform/graphics/GraphicsContext.cpp index a0a7ea9..cb991b7 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.cpp +++ b/Source/WebCore/platform/graphics/GraphicsContext.cpp @@ -375,7 +375,7 @@ void GraphicsContext::drawImage(Image* image, ColorSpace styleColorSpace, const } #if !OS(WINCE) || PLATFORM(QT) -void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPoint& point, int from, int to) +void GraphicsContext::drawText(const Font& font, const TextRun& run, const FloatPoint& point, int from, int to) { if (paintingDisabled()) return; @@ -384,7 +384,7 @@ void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPo } #endif -void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const IntPoint& point, int from, int to) +void GraphicsContext::drawEmphasisMarks(const Font& font, const TextRun& run, const AtomicString& mark, const FloatPoint& point, int from, int to) { if (paintingDisabled()) return; @@ -422,13 +422,13 @@ void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const F bidiRun = bidiRun->next(); // FIXME: Have Font::drawText return the width of what it drew so that we don't have to re-measure here. if (bidiRun) - currPoint.move(font.floatWidth(subrun), 0.f); + currPoint.move(font.width(subrun), 0); } bidiResolver.deleteRuns(); } -void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const IntPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to) +void GraphicsContext::drawHighlightForText(const Font& font, const TextRun& run, const FloatPoint& point, int h, const Color& backgroundColor, ColorSpace colorSpace, int from, int to) { if (paintingDisabled()) return; @@ -550,6 +550,13 @@ void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorS image->draw(this, styleColorSpace, FloatRect(dest.location(), FloatSize(tw, th)), FloatRect(src.location(), FloatSize(tsw, tsh)), op, useLowQualityScale); } +#if !PLATFORM(QT) +void GraphicsContext::clip(const IntRect& rect) +{ + clip(FloatRect(rect)); +} +#endif + void GraphicsContext::addRoundedRectClip(const RoundedIntRect& rect) { if (paintingDisabled()) @@ -649,7 +656,11 @@ CompositeOperator GraphicsContext::compositeOperation() const return m_state.compositeOperator; } +<<<<<<< HEAD #if !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) +======= +#if !USE(SKIA) +>>>>>>> WebKit at r80534 void GraphicsContext::setPlatformFillGradient(Gradient*) { } @@ -667,7 +678,11 @@ void GraphicsContext::setPlatformStrokePattern(Pattern*) } #endif +<<<<<<< HEAD #if !PLATFORM(CG) && !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) +======= +#if !PLATFORM(CG) && !USE(SKIA) +>>>>>>> WebKit at r80534 // Implement this if you want to go ahead and push the drawing mode into your native context // immediately. void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) @@ -675,7 +690,11 @@ void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) } #endif +<<<<<<< HEAD #if !PLATFORM(QT) && !PLATFORM(CAIRO) && !(PLATFORM(SKIA) && !PLATFORM(ANDROID)) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG) +======= +#if !PLATFORM(QT) && !PLATFORM(CAIRO) && !USE(SKIA) && !PLATFORM(HAIKU) && !PLATFORM(OPENVG) +>>>>>>> WebKit at r80534 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle) { } @@ -687,7 +706,7 @@ void GraphicsContext::setPlatformShouldSmoothFonts(bool) } #endif -#if !PLATFORM(SKIA) +#if !USE(SKIA) void GraphicsContext::setSharedGraphicsContext3D(SharedGraphicsContext3D*, DrawingBuffer*, const IntSize&) { } diff --git a/Source/WebCore/platform/graphics/GraphicsContext.h b/Source/WebCore/platform/graphics/GraphicsContext.h index 21a9067..f69c340 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext.h +++ b/Source/WebCore/platform/graphics/GraphicsContext.h @@ -74,6 +74,7 @@ class wxWindowDC; #else typedef wxWindowDC PlatformGraphicsContext; #endif +<<<<<<< HEAD #elif PLATFORM(SKIA) #if PLATFORM(ANDROID) namespace WebCore { @@ -82,6 +83,9 @@ class PlatformGraphicsContext; class SkPaint; struct SkPoint; #else +======= +#elif USE(SKIA) +>>>>>>> WebKit at r80534 namespace WebCore { class PlatformContextSkia; } @@ -276,6 +280,9 @@ namespace WebCore { // Allow font smoothing (LCD antialiasing). Not part of the graphics state. void setAllowsFontSmoothing(bool); + + void setIsCALayerContext(bool); + bool isCALayerContext() const; #endif #if PLATFORM(ANDROID) @@ -356,6 +363,7 @@ namespace WebCore { void setImageInterpolationQuality(InterpolationQuality); InterpolationQuality imageInterpolationQuality() const; + void clip(const IntRect&); void clip(const FloatRect&); void addRoundedRectClip(const RoundedIntRect&); void addInnerRoundedRectClip(const IntRect&, int thickness); @@ -370,20 +378,20 @@ namespace WebCore { TextDrawingModeFlags textDrawingMode() const; void setTextDrawingMode(TextDrawingModeFlags); - void drawText(const Font&, const TextRun&, const IntPoint&, int from = 0, int to = -1); - void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const IntPoint&, int from = 0, int to = -1); + void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1); + void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1); void drawBidiText(const Font&, const TextRun&, const FloatPoint&); - void drawHighlightForText(const Font&, const TextRun&, const IntPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1); + void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1); FloatRect roundToDevicePixels(const FloatRect&); - void drawLineForText(const IntPoint&, int width, bool printing); + void drawLineForText(const FloatPoint&, float width, bool printing); enum TextCheckingLineStyle { TextCheckingSpellingLineStyle, TextCheckingGrammarLineStyle, TextCheckingReplacementLineStyle }; - void drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle); + void drawLineForTextChecking(const FloatPoint&, float width, TextCheckingLineStyle); bool paintingDisabled() const; void setPaintingDisabled(bool); @@ -435,6 +443,7 @@ namespace WebCore { void setURLForRect(const KURL&, const IntRect&); void concatCTM(const AffineTransform&); + void setCTM(const AffineTransform&); AffineTransform getCTM() const; #if OS(WINCE) && !PLATFORM(QT) @@ -516,6 +525,10 @@ namespace WebCore { ContextShadow* contextShadow(); #endif +#if PLATFORM(CAIRO) + void pushImageMask(cairo_surface_t*, const FloatRect&); +#endif + #if PLATFORM(GTK) void setGdkExposeEvent(GdkEventExpose*); GdkWindow* gdkWindow() const; diff --git a/Source/WebCore/platform/graphics/GraphicsContext3D.h b/Source/WebCore/platform/graphics/GraphicsContext3D.h index d6c1cec..a9db650 100644 --- a/Source/WebCore/platform/graphics/GraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/GraphicsContext3D.h @@ -28,6 +28,7 @@ #include "IntSize.h" #include "GraphicsLayer.h" +#include "GraphicsTypes3D.h" #include "PlatformString.h" #include <wtf/HashMap.h> @@ -42,25 +43,6 @@ #undef VERSION #endif -// GC3D types match the corresponding GL types as defined in OpenGL ES 2.0 -// header file gl2.h from khronos.org. -typedef unsigned int GC3Denum; -typedef unsigned char GC3Dboolean; -typedef unsigned int GC3Dbitfield; -typedef signed char GC3Dbyte; -typedef unsigned char GC3Dubyte; -typedef short GC3Dshort; -typedef unsigned short GC3Dushort; -typedef int GC3Dint; -typedef int GC3Dsizei; -typedef unsigned int GC3Duint; -typedef float GC3Dfloat; -typedef float GC3Dclampf; -typedef signed long int GC3Dintptr; -typedef signed long int GC3Dsizeiptr; - -typedef GC3Duint Platform3DObject; - #if PLATFORM(MAC) #include "ANGLEWebKitBridge.h" #include <OpenGL/OpenGL.h> diff --git a/Source/WebCore/platform/graphics/GraphicsLayer.cpp b/Source/WebCore/platform/graphics/GraphicsLayer.cpp index 84905a9..ca64065 100644 --- a/Source/WebCore/platform/graphics/GraphicsLayer.cpp +++ b/Source/WebCore/platform/graphics/GraphicsLayer.cpp @@ -470,7 +470,7 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent, LayerTreeAsTextBe if (m_backgroundColorSet) { writeIndent(ts, indent + 1); - ts << "(backgroundColor " << m_backgroundColor.name() << ")\n"; + ts << "(backgroundColor " << m_backgroundColor.nameForRenderTreeAsText() << ")\n"; } if (!m_transform.isIdentity()) { diff --git a/Source/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp b/Source/WebCore/platform/graphics/GraphicsTypes3D.h index 7cc6ceb..ad73336 100644 --- a/Source/WebCore/platform/network/android/NetworkStateNotifierAndroid.cpp +++ b/Source/WebCore/platform/graphics/GraphicsTypes3D.h @@ -1,54 +1,50 @@ /* - * Copyright 2009, The Android Open Source Project + * Copyright (C) 2011 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * * Redistributions of source code must retain the above copyright + * 1. 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 + * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * 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 THE COPYRIGHT OWNER OR + * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#include "NetworkStateNotifier.h" - -namespace WebCore { - -void NetworkStateNotifier::networkStateChange(bool online) -{ - if (m_isOnLine == online) - return; - - m_isOnLine = online; - - if (m_networkStateChangedFunction) - m_networkStateChangedFunction(); -} - -// TODO: Upstream to webkit.org -void NetworkStateNotifier::networkTypeChange(Connection::ConnectionType type) -{ - if (m_type == type) - return; - - m_type = type; - - if (m_networkStateChangedFunction) - m_networkStateChangedFunction(); -} - -} +#ifndef GraphicsTypes3D_h +#define GraphicsTypes3D_h + +#include <wtf/Forward.h> + +// GC3D types match the corresponding GL types as defined in OpenGL ES 2.0 +// header file gl2.h from khronos.org. +typedef unsigned int GC3Denum; +typedef unsigned char GC3Dboolean; +typedef unsigned int GC3Dbitfield; +typedef signed char GC3Dbyte; +typedef unsigned char GC3Dubyte; +typedef short GC3Dshort; +typedef unsigned short GC3Dushort; +typedef int GC3Dint; +typedef int GC3Dsizei; +typedef unsigned int GC3Duint; +typedef float GC3Dfloat; +typedef float GC3Dclampf; +typedef signed long int GC3Dintptr; +typedef signed long int GC3Dsizeiptr; + +typedef GC3Duint Platform3DObject; + +#endif diff --git a/Source/WebCore/platform/graphics/ImageSource.cpp b/Source/WebCore/platform/graphics/ImageSource.cpp index 984b7d2..f4495ed 100644 --- a/Source/WebCore/platform/graphics/ImageSource.cpp +++ b/Source/WebCore/platform/graphics/ImageSource.cpp @@ -115,6 +115,11 @@ bool ImageSource::getHotSpot(IntPoint&) const return false; } +size_t ImageSource::bytesDecodedToDetermineProperties() const +{ + return 0; +} + int ImageSource::repetitionCount() { return m_decoder ? m_decoder->repetitionCount() : cAnimationNone; diff --git a/Source/WebCore/platform/graphics/ImageSource.h b/Source/WebCore/platform/graphics/ImageSource.h index 70b2cf5..a5c12d6 100644 --- a/Source/WebCore/platform/graphics/ImageSource.h +++ b/Source/WebCore/platform/graphics/ImageSource.h @@ -46,12 +46,16 @@ QT_END_NAMESPACE #elif PLATFORM(CAIRO) struct _cairo_surface; typedef struct _cairo_surface cairo_surface_t; +<<<<<<< HEAD #elif PLATFORM(SKIA) #if PLATFORM(ANDROID) #include "SkString.h" class SkBitmapRef; class PrivateAndroidImageSourceRec; #else +======= +#elif USE(SKIA) +>>>>>>> WebKit at r80534 namespace WebCore { class NativeImageSkia; } @@ -109,7 +113,7 @@ typedef wxBitmap* NativeImagePtr; #endif #elif PLATFORM(CAIRO) typedef cairo_surface_t* NativeImagePtr; -#elif PLATFORM(SKIA) +#elif USE(SKIA) typedef WebCore::NativeImageSkia* NativeImagePtr; #elif PLATFORM(HAIKU) typedef BBitmap* NativeImagePtr; @@ -188,6 +192,8 @@ public: IntSize frameSizeAtIndex(size_t) const; bool getHotSpot(IntPoint&) const; + size_t bytesDecodedToDetermineProperties() const; + int repetitionCount(); size_t frameCount() const; diff --git a/Source/WebCore/platform/graphics/IntPoint.h b/Source/WebCore/platform/graphics/IntPoint.h index cd5e4d4..d27906b 100644 --- a/Source/WebCore/platform/graphics/IntPoint.h +++ b/Source/WebCore/platform/graphics/IntPoint.h @@ -68,7 +68,7 @@ class wxPoint; typedef struct _point AEEPoint; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkPoint; struct SkIPoint; #endif @@ -153,7 +153,7 @@ public: operator AEEPoint() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) IntPoint(const SkIPoint&); operator SkIPoint() const; operator SkPoint() const; diff --git a/Source/WebCore/platform/graphics/IntRect.h b/Source/WebCore/platform/graphics/IntRect.h index 3a2433d..c413e7a 100644 --- a/Source/WebCore/platform/graphics/IntRect.h +++ b/Source/WebCore/platform/graphics/IntRect.h @@ -64,7 +64,7 @@ typedef struct _Eina_Rectangle Eina_Rectangle; class wxRect; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) struct SkRect; struct SkIRect; #endif @@ -186,7 +186,7 @@ public: operator CGRect() const; #endif -#if PLATFORM(SKIA) +#if USE(SKIA) IntRect(const SkIRect&); operator SkRect() const; operator SkIRect() const; diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp index 8eed0d2..70576a5 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.cpp +++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -153,19 +153,27 @@ static MediaPlayerPrivateInterface* createNullMediaPlayer(MediaPlayer* player) struct MediaPlayerFactory { WTF_MAKE_NONCOPYABLE(MediaPlayerFactory); WTF_MAKE_FAST_ALLOCATED; public: - MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs) + MediaPlayerFactory(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsTypeAndCodecs, + MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite) : constructor(constructor) , getSupportedTypes(getSupportedTypes) - , supportsTypeAndCodecs(supportsTypeAndCodecs) + , supportsTypeAndCodecs(supportsTypeAndCodecs) + , getSitesInMediaCache(getSitesInMediaCache) + , clearMediaCache(clearMediaCache) + , clearMediaCacheForSite(clearMediaCacheForSite) + { } CreateMediaEnginePlayer constructor; MediaEngineSupportedTypes getSupportedTypes; MediaEngineSupportsType supportsTypeAndCodecs; + MediaEngineGetSitesInMediaCache getSitesInMediaCache; + MediaEngineClearMediaCache clearMediaCache; + MediaEngineClearMediaCacheForSite clearMediaCacheForSite; }; -static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType); +static void addMediaEngine(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite); static MediaPlayerFactory* bestMediaEngineForTypeAndCodecs(const String& type, const String& codecs, MediaPlayerFactory* current = 0); static MediaPlayerFactory* nextMediaEngine(MediaPlayerFactory* current); @@ -189,12 +197,14 @@ static Vector<MediaPlayerFactory*>& installedMediaEngines() return installedEngines; } -static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType) +static void addMediaEngine(CreateMediaEnginePlayer constructor, MediaEngineSupportedTypes getSupportedTypes, MediaEngineSupportsType supportsType, + MediaEngineGetSitesInMediaCache getSitesInMediaCache, MediaEngineClearMediaCache clearMediaCache, MediaEngineClearMediaCacheForSite clearMediaCacheForSite) { ASSERT(constructor); ASSERT(getSupportedTypes); ASSERT(supportsType); - installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType)); + + installedMediaEngines().append(new MediaPlayerFactory(constructor, getSupportedTypes, supportsType, getSitesInMediaCache, clearMediaCache, clearMediaCacheForSite)); } static const AtomicString& applicationOctetStream() @@ -281,6 +291,7 @@ MediaPlayer::MediaPlayer(MediaPlayerClient* client) , m_volume(1.0f) , m_muted(false) , m_preservesPitch(true) + , m_privateBrowsing(false) #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) , m_playerProxy(0) #endif @@ -354,6 +365,7 @@ void MediaPlayer::loadWithNextMediaEngine(MediaPlayerFactory* current) #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) m_private->setMediaPlayerProxy(m_playerProxy); #endif + m_private->setPrivateBrowsingMode(m_privateBrowsing); m_private->setPreload(m_preload); m_private->setPreservesPitch(preservesPitch()); } @@ -698,24 +710,24 @@ double MediaPlayer::maximumDurationToCacheMediaTime() const return m_private->maximumDurationToCacheMediaTime(); } -unsigned long MediaPlayer::decodedFrames() const +unsigned MediaPlayer::decodedFrameCount() const { - return m_private->decodedFrames(); + return m_private->decodedFrameCount(); } -unsigned long MediaPlayer::droppedFrames() const +unsigned MediaPlayer::droppedFrameCount() const { - return m_private->droppedFrames(); + return m_private->droppedFrameCount(); } -unsigned long MediaPlayer::audioBytesDecoded() const +unsigned MediaPlayer::audioDecodedByteCount() const { - return m_private->audioBytesDecoded(); + return m_private->audioDecodedByteCount(); } -unsigned long MediaPlayer::videoBytesDecoded() const +unsigned MediaPlayer::videoDecodedByteCount() const { - return m_private->videoBytesDecoded(); + return m_private->videoDecodedByteCount(); } void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*) @@ -724,6 +736,44 @@ void MediaPlayer::reloadTimerFired(Timer<MediaPlayer>*) loadWithNextMediaEngine(m_currentMediaEngine); } +void MediaPlayer::getSitesInMediaCache(Vector<String>& sites) +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + unsigned size = engines.size(); + for (unsigned i = 0; i < size; i++) { + if (!engines[i]->getSitesInMediaCache) + continue; + Vector<String> engineSites; + engines[i]->getSitesInMediaCache(engineSites); + sites.append(engineSites); + } +} + +void MediaPlayer::clearMediaCache() +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + unsigned size = engines.size(); + for (unsigned i = 0; i < size; i++) { + if (engines[i]->clearMediaCache) + engines[i]->clearMediaCache(); + } +} + +void MediaPlayer::clearMediaCacheForSite(const String& site) +{ + Vector<MediaPlayerFactory*>& engines = installedMediaEngines(); + unsigned size = engines.size(); + for (unsigned i = 0; i < size; i++) { + if (engines[i]->clearMediaCacheForSite) + engines[i]->clearMediaCacheForSite(site); + } +} + +void MediaPlayer::setPrivateBrowsingMode(bool privateBrowsingMode) +{ + m_privateBrowsing = privateBrowsingMode; + m_private->setPrivateBrowsingMode(m_privateBrowsing); +} // Client callbacks. void MediaPlayer::networkStateChanged() diff --git a/Source/WebCore/platform/graphics/MediaPlayer.h b/Source/WebCore/platform/graphics/MediaPlayer.h index 1112148..f41af01 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.h +++ b/Source/WebCore/platform/graphics/MediaPlayer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -159,11 +159,14 @@ public: } virtual ~MediaPlayer(); - // media engine support + // Media engine support. enum SupportsType { IsNotSupported, IsSupported, MayBeSupported }; static MediaPlayer::SupportsType supportsType(const ContentType&); static void getSupportedTypes(HashSet<String>&); static bool isAvailable(); + static void getSitesInMediaCache(Vector<String>&); + static void clearMediaCache(); + static void clearMediaCacheForSite(const String&); bool supportsFullscreen() const; bool supportsSave() const; @@ -287,10 +290,12 @@ public: double maximumDurationToCacheMediaTime() const; - unsigned long decodedFrames() const; - unsigned long droppedFrames() const; - unsigned long audioBytesDecoded() const; - unsigned long videoBytesDecoded() const; + unsigned decodedFrameCount() const; + unsigned droppedFrameCount() const; + unsigned audioDecodedByteCount() const; + unsigned videoDecodedByteCount() const; + + void setPrivateBrowsingMode(bool); private: MediaPlayer(MediaPlayerClient*); @@ -314,6 +319,7 @@ private: float m_volume; bool m_muted; bool m_preservesPitch; + bool m_privateBrowsing; #if ENABLE(PLUGIN_PROXY_FOR_VIDEO) WebMediaPlayerProxy* m_playerProxy; // not owned or used, passed to m_private #endif @@ -325,8 +331,12 @@ private: typedef MediaPlayerPrivateInterface* (*CreateMediaEnginePlayer)(MediaPlayer*); typedef void (*MediaEngineSupportedTypes)(HashSet<String>& types); typedef MediaPlayer::SupportsType (*MediaEngineSupportsType)(const String& type, const String& codecs); +typedef void (*MediaEngineGetSitesInMediaCache)(Vector<String>&); +typedef void (*MediaEngineClearMediaCache)(); +typedef void (*MediaEngineClearMediaCacheForSite)(const String&); -typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType); +typedef void (*MediaEngineRegistrar)(CreateMediaEnginePlayer, MediaEngineSupportedTypes, MediaEngineSupportsType, + MediaEngineGetSitesInMediaCache, MediaEngineClearMediaCache, MediaEngineClearMediaCacheForSite); } diff --git a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h index 04b2612..b4490bc 100644 --- a/Source/WebCore/platform/graphics/MediaPlayerPrivate.h +++ b/Source/WebCore/platform/graphics/MediaPlayerPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2009, 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 @@ -136,10 +136,16 @@ public: // it is OK to calculate movie time before refreshing the cached time. virtual double maximumDurationToCacheMediaTime() const { return 0; } - virtual unsigned long decodedFrames() const { return 0; } - virtual unsigned long droppedFrames() const { return 0; } - virtual unsigned long audioBytesDecoded() const { return 0; } - virtual unsigned long videoBytesDecoded() const { return 0; } + virtual unsigned decodedFrameCount() const { return 0; } + virtual unsigned droppedFrameCount() const { return 0; } + virtual unsigned audioDecodedByteCount() const { return 0; } + virtual unsigned videoDecodedByteCount() const { return 0; } + + void getSitesInMediaCache(Vector<String>&) { } + void clearMediaCache() { } + void clearMediaCacheForSite(const String&) { } + + virtual void setPrivateBrowsingMode(bool) { } }; } diff --git a/Source/WebCore/platform/graphics/Path.h b/Source/WebCore/platform/graphics/Path.h index 852d88e..31f2cd6 100644 --- a/Source/WebCore/platform/graphics/Path.h +++ b/Source/WebCore/platform/graphics/Path.h @@ -49,7 +49,7 @@ namespace WebCore { class CairoPath; } typedef WebCore::CairoPath PlatformPath; -#elif PLATFORM(SKIA) +#elif USE(SKIA) class SkPath; typedef SkPath PlatformPath; #elif PLATFORM(HAIKU) diff --git a/Source/WebCore/platform/graphics/Pattern.cpp b/Source/WebCore/platform/graphics/Pattern.cpp index 82d0a24..c2c3de0 100644 --- a/Source/WebCore/platform/graphics/Pattern.cpp +++ b/Source/WebCore/platform/graphics/Pattern.cpp @@ -35,7 +35,7 @@ Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY) : m_tileImage(image) , m_repeatX(repeatX) , m_repeatY(repeatY) -#if PLATFORM(SKIA) +#if USE(SKIA) , m_pattern(0) #endif { @@ -53,7 +53,7 @@ void Pattern::setPatternSpaceTransform(const AffineTransform& patternSpaceTransf setPlatformPatternSpaceTransform(); } -#if !PLATFORM(SKIA) +#if !USE(SKIA) void Pattern::platformDestroy() { } diff --git a/Source/WebCore/platform/graphics/Pattern.h b/Source/WebCore/platform/graphics/Pattern.h index e215f3d..c88f2fb 100644 --- a/Source/WebCore/platform/graphics/Pattern.h +++ b/Source/WebCore/platform/graphics/Pattern.h @@ -41,7 +41,7 @@ typedef CGPatternRef PlatformPatternPtr; #elif PLATFORM(CAIRO) #include <cairo.h> typedef cairo_pattern_t* PlatformPatternPtr; -#elif PLATFORM(SKIA) +#elif USE(SKIA) class SkShader; typedef SkShader* PlatformPatternPtr; #elif PLATFORM(QT) @@ -79,7 +79,7 @@ public: void platformDestroy(); // Pattern space is an abstract space that maps to the default user space by the transformation 'userSpaceTransformation' -#if PLATFORM(SKIA) +#if USE(SKIA) PlatformPatternPtr platformPattern(const AffineTransform& userSpaceTransformation); #else PlatformPatternPtr createPlatformPattern(const AffineTransform& userSpaceTransformation) const; diff --git a/Source/WebCore/platform/graphics/ShadowBlur.cpp b/Source/WebCore/platform/graphics/ShadowBlur.cpp index f61ecff..0df51a4 100644 --- a/Source/WebCore/platform/graphics/ShadowBlur.cpp +++ b/Source/WebCore/platform/graphics/ShadowBlur.cpp @@ -144,7 +144,6 @@ ShadowBlur::ShadowBlur(float radius, const FloatSize& offset, const Color& color // Instead of integer division, we use 17.15 for fixed-point division. static const int blurSumShift = 15; -static const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, int rowStride) { @@ -167,6 +166,7 @@ void ShadowBlur::blurLayerImage(unsigned char* imageData, const IntSize& size, i // However, shadows rendered according to that spec will extend a little further than m_blurRadius, // so we apply a fudge factor to bring the radius down slightly. float stdDev = m_blurRadius / 2; + const float gaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); const float fudgeFactor = 0.88f; diameter = max(2, static_cast<int>(floorf(stdDev * gaussianKernelFactor * fudgeFactor + 0.5f))); } diff --git a/Source/WebCore/platform/graphics/SimpleFontData.cpp b/Source/WebCore/platform/graphics/SimpleFontData.cpp index 2693609..aaab666 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.cpp +++ b/Source/WebCore/platform/graphics/SimpleFontData.cpp @@ -83,6 +83,15 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo float ascent = svgFontFaceElement->ascent() * scale; float descent = svgFontFaceElement->descent() * scale; float lineGap = 0.1f * size; + + SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement(); + if (!xHeight) { + // Fallback if x_heightAttr is not specified for the font element. + Vector<SVGGlyphIdentifier> letterXGlyphs; + associatedFontElement->getGlyphIdentifiersForString(String("x", 1), letterXGlyphs); + xHeight = letterXGlyphs.isEmpty() ? 2 * ascent / 3 : letterXGlyphs.first().horizontalAdvanceX * scale; + } + m_fontMetrics.setUnitsPerEm(unitsPerEm); m_fontMetrics.setAscent(ascent); m_fontMetrics.setDescent(descent); @@ -90,8 +99,6 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo m_fontMetrics.setLineSpacing(roundf(ascent) + roundf(descent) + roundf(lineGap)); m_fontMetrics.setXHeight(xHeight); - SVGFontElement* associatedFontElement = svgFontFaceElement->associatedFontElement(); - Vector<SVGGlyphIdentifier> spaceGlyphs; associatedFontElement->getGlyphIdentifiersForString(String(" ", 1), spaceGlyphs); m_spaceWidth = spaceGlyphs.isEmpty() ? xHeight : spaceGlyphs.first().horizontalAdvanceX * scale; @@ -108,7 +115,6 @@ SimpleFontData::SimpleFontData(PassOwnPtr<SVGFontData> svgFontData, int size, bo m_spaceGlyph = 0; m_zeroWidthSpaceGlyph = 0; determinePitch(); - m_adjustedSpaceWidth = roundf(m_spaceWidth); m_missingGlyphData.fontData = this; m_missingGlyphData.glyph = 0; } @@ -143,7 +149,6 @@ void SimpleFontData::platformGlyphInit() LOG_ERROR("Failed to get glyph page zero."); m_spaceGlyph = 0; m_spaceWidth = 0; - m_adjustedSpaceWidth = 0; determinePitch(); m_zeroWidthSpaceGlyph = 0; m_missingGlyphData.fontData = this; @@ -160,7 +165,6 @@ void SimpleFontData::platformGlyphInit() float width = widthForGlyph(m_spaceGlyph); m_spaceWidth = width; determinePitch(); - m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width); // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE. // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph. diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h index 07c2bd1..93d33bb 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.h +++ b/Source/WebCore/platform/graphics/SimpleFontData.h @@ -112,7 +112,6 @@ public: float platformWidthForGlyph(Glyph) const; float spaceWidth() const { return m_spaceWidth; } - float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; } #if PLATFORM(CG) || PLATFORM(CAIRO) || PLATFORM(WX) float syntheticBoldOffset() const { return m_syntheticBoldOffset; } @@ -230,7 +229,6 @@ private: Glyph m_spaceGlyph; float m_spaceWidth; - float m_adjustedSpaceWidth; Glyph m_zeroWidthSpaceGlyph; diff --git a/Source/WebCore/platform/graphics/StringTruncator.cpp b/Source/WebCore/platform/graphics/StringTruncator.cpp index 8468188..fa8f211 100644 --- a/Source/WebCore/platform/graphics/StringTruncator.cpp +++ b/Source/WebCore/platform/graphics/StringTruncator.cpp @@ -92,22 +92,20 @@ static unsigned rightTruncateToBuffer(const String& string, unsigned length, uns return truncatedLength; } -static float stringWidth(const Font& renderer, const UChar* characters, unsigned length, bool disableRoundingHacks) +static float stringWidth(const Font& renderer, const UChar* characters, unsigned length) { TextRun run(characters, length); - if (disableRoundingHacks) - run.disableRoundingHacks(); - return renderer.floatWidth(run); + return renderer.width(run); } -static String truncateString(const String& string, float maxWidth, const Font& font, TruncationFunction truncateToBuffer, bool disableRoundingHacks) +static String truncateString(const String& string, float maxWidth, const Font& font, TruncationFunction truncateToBuffer) { if (string.isEmpty()) return string; ASSERT(maxWidth >= 0); - float currentEllipsisWidth = stringWidth(font, &horizontalEllipsis, 1, disableRoundingHacks); + float currentEllipsisWidth = stringWidth(font, &horizontalEllipsis, 1); UChar stringBuffer[STRING_BUFFER_SIZE]; unsigned truncatedLength; @@ -123,7 +121,7 @@ static String truncateString(const String& string, float maxWidth, const Font& f truncatedLength = length; } - float width = stringWidth(font, stringBuffer, truncatedLength, disableRoundingHacks); + float width = stringWidth(font, stringBuffer, truncatedLength); if (width <= maxWidth) return string; @@ -159,7 +157,7 @@ static String truncateString(const String& string, float maxWidth, const Font& f truncatedLength = truncateToBuffer(string, length, keepCount, stringBuffer); - width = stringWidth(font, stringBuffer, truncatedLength, disableRoundingHacks); + width = stringWidth(font, stringBuffer, truncatedLength); if (width <= maxWidth) { keepCountForLargestKnownToFit = keepCount; widthForLargestKnownToFit = width; @@ -181,19 +179,19 @@ static String truncateString(const String& string, float maxWidth, const Font& f return String(stringBuffer, truncatedLength); } -String StringTruncator::centerTruncate(const String& string, float maxWidth, const Font& font, bool disableRoundingHacks) +String StringTruncator::centerTruncate(const String& string, float maxWidth, const Font& font) { - return truncateString(string, maxWidth, font, centerTruncateToBuffer, disableRoundingHacks); + return truncateString(string, maxWidth, font, centerTruncateToBuffer); } -String StringTruncator::rightTruncate(const String& string, float maxWidth, const Font& font, bool disableRoundingHacks) +String StringTruncator::rightTruncate(const String& string, float maxWidth, const Font& font) { - return truncateString(string, maxWidth, font, rightTruncateToBuffer, disableRoundingHacks); + return truncateString(string, maxWidth, font, rightTruncateToBuffer); } -float StringTruncator::width(const String& string, const Font& font, bool disableRoundingHacks) +float StringTruncator::width(const String& string, const Font& font) { - return stringWidth(font, string.characters(), string.length(), disableRoundingHacks); + return stringWidth(font, string.characters(), string.length()); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/StringTruncator.h b/Source/WebCore/platform/graphics/StringTruncator.h index 6791d38..89dc9ef 100644 --- a/Source/WebCore/platform/graphics/StringTruncator.h +++ b/Source/WebCore/platform/graphics/StringTruncator.h @@ -37,9 +37,9 @@ namespace WebCore { class StringTruncator { public: - static String centerTruncate(const String&, float maxWidth, const Font&, bool disableRoundingHacks = true); - static String rightTruncate(const String&, float maxWidth, const Font&, bool disableRoundingHacks = true); - static float width(const String&, const Font&, bool disableRoundingHacks = true); + static String centerTruncate(const String&, float maxWidth, const Font&); + static String rightTruncate(const String&, float maxWidth, const Font&); + static float width(const String&, const Font&); }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/TextRun.h b/Source/WebCore/platform/graphics/TextRun.h index ef434bd..4e0980b 100644 --- a/Source/WebCore/platform/graphics/TextRun.h +++ b/Source/WebCore/platform/graphics/TextRun.h @@ -38,8 +38,7 @@ public: ForbidTrailingExpansion }; - TextRun(const UChar* c, int len, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false, - bool applyRunRounding = true, bool applyWordRounding = true) + TextRun(const UChar* c, int len, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false) : m_characters(c) , m_len(len) , m_xpos(xpos) @@ -51,8 +50,6 @@ public: , m_allowTabs(allowTabs) , m_rtl(rtl) , m_directionalOverride(directionalOverride) - , m_applyRunRounding(applyRunRounding) - , m_applyWordRounding(applyWordRounding) , m_disableSpacing(false) #if ENABLE(SVG_FONTS) , m_referencingRenderObject(0) @@ -61,8 +58,7 @@ public: { } - TextRun(const String& s, bool allowTabs = false, int xpos = 0, int expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false, - bool applyRunRounding = true, bool applyWordRounding = true) + TextRun(const String& s, bool allowTabs = false, float xpos = 0, float expansion = 0, TrailingExpansionBehavior trailingExpansionBehavior = AllowTrailingExpansion, bool rtl = false, bool directionalOverride = false) : m_characters(s.characters()) , m_len(s.length()) , m_xpos(xpos) @@ -74,8 +70,6 @@ public: , m_allowTabs(allowTabs) , m_rtl(rtl) , m_directionalOverride(directionalOverride) - , m_applyRunRounding(applyRunRounding) - , m_applyWordRounding(applyWordRounding) , m_disableSpacing(false) #if ENABLE(SVG_FONTS) , m_referencingRenderObject(0) @@ -98,18 +92,15 @@ public: #endif bool allowTabs() const { return m_allowTabs; } - int xPos() const { return m_xpos; } - int expansion() const { return m_expansion; } + float xPos() const { return m_xpos; } + float expansion() const { return m_expansion; } bool allowsTrailingExpansion() const { return m_trailingExpansionBehavior == AllowTrailingExpansion; } bool rtl() const { return m_rtl; } bool ltr() const { return !m_rtl; } bool directionalOverride() const { return m_directionalOverride; } - bool applyRunRounding() const { return m_applyRunRounding; } - bool applyWordRounding() const { return m_applyWordRounding; } bool spacingDisabled() const { return m_disableSpacing; } void disableSpacing() { m_disableSpacing = true; } - void disableRoundingHacks() { m_applyRunRounding = m_applyWordRounding = false; } void setRTL(bool b) { m_rtl = b; } void setDirectionalOverride(bool override) { m_directionalOverride = override; } @@ -128,8 +119,8 @@ private: // m_xpos is the x position relative to the left start of the text line, not relative to the left // start of the containing block. In the case of right alignment or center alignment, left start of // the text line is not the same as left start of the containing block. - int m_xpos; - int m_expansion; + float m_xpos; + float m_expansion; TrailingExpansionBehavior m_trailingExpansionBehavior; #if ENABLE(SVG) float m_horizontalGlyphStretch; @@ -137,8 +128,6 @@ private: bool m_allowTabs; bool m_rtl; bool m_directionalOverride; - bool m_applyRunRounding; - bool m_applyWordRounding; bool m_disableSpacing; #if ENABLE(SVG_FONTS) diff --git a/Source/WebCore/platform/graphics/TiledBackingStore.cpp b/Source/WebCore/platform/graphics/TiledBackingStore.cpp index f6921ef..4d69334 100644 --- a/Source/WebCore/platform/graphics/TiledBackingStore.cpp +++ b/Source/WebCore/platform/graphics/TiledBackingStore.cpp @@ -213,15 +213,17 @@ void TiledBackingStore::createTiles() dropOverhangingTiles(); IntRect keepRect = visibleRect; - keepRect.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1.f)); - keepRect.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1.f)); + // Inflates to both sides, so divide inflate delta by 2 + keepRect.inflateX(visibleRect.width() * (m_keepAreaMultiplier.width() - 1.f) / 2); + keepRect.inflateY(visibleRect.height() * (m_keepAreaMultiplier.height() - 1.f) / 2); keepRect.intersect(contentsRect()); dropTilesOutsideRect(keepRect); IntRect coverRect = visibleRect; - coverRect.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1.f)); - coverRect.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1.f)); + // Inflates to both sides, so divide inflate delta by 2 + coverRect.inflateX(visibleRect.width() * (m_coverAreaMultiplier.width() - 1.f) / 2); + coverRect.inflateY(visibleRect.height() * (m_coverAreaMultiplier.height() - 1.f) / 2); coverRect.intersect(contentsRect()); // Search for the tile position closest to the viewport center that does not yet contain a tile. diff --git a/Source/WebCore/platform/graphics/WidthIterator.cpp b/Source/WebCore/platform/graphics/WidthIterator.cpp index a1a88da..27b0627 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.cpp +++ b/Source/WebCore/platform/graphics/WidthIterator.cpp @@ -48,7 +48,6 @@ WidthIterator::WidthIterator(const Font* font, const TextRun& run, HashSet<const , m_currentCharacter(0) , m_runWidthSoFar(0) , m_isAfterExpansion(true) - , m_finalRoundingWidth(0) , m_fallbackFonts(fallbackFonts) , m_accountForGlyphBounds(accountForGlyphBounds) , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) @@ -86,11 +85,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) bool rtl = m_run.rtl(); bool hasExtraSpacing = (m_font->letterSpacing() || m_font->wordSpacing() || m_expansion) && !m_run.spacingDisabled(); - float widthSinceLastRounding = m_runWidthSoFar; - m_runWidthSoFar = floorf(m_runWidthSoFar); - widthSinceLastRounding -= m_runWidthSoFar; - - float lastRoundingWidth = m_finalRoundingWidth; FloatRect bounds; const SimpleFontData* primaryFont = m_font->primaryFont(); @@ -136,7 +130,7 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) float width; if (c == '\t' && m_run.allowTabs()) { float tabWidth = m_font->tabWidth(*fontData); - width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar + widthSinceLastRounding, tabWidth); + width = tabWidth - fmodf(m_run.xPos() + m_runWidthSoFar, tabWidth); } else { width = fontData->widthForGlyph(glyph); @@ -144,13 +138,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) // SVG uses horizontalGlyphStretch(), when textLength is used to stretch/squeeze text. width *= m_run.horizontalGlyphStretch(); #endif - - // We special case spaces in two ways when applying word rounding. - // First, we round spaces to an adjusted width in all fonts. - // Second, in fixed-pitch fonts we ensure that all characters that - // match the width of the space character have the same width as the space character. - if (width == fontData->spaceWidth() && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding()) - width = fontData->adjustedSpaceWidth(); } if (fontData != lastFontData && width) { @@ -179,18 +166,15 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) // Distribute the run's total expansion evenly over all expansion opportunities in the run. if (m_expansion && (m_run.allowsTrailingExpansion() || (m_run.ltr() && currentCharacter + clusterLength < static_cast<size_t>(m_run.length())) || (m_run.rtl() && currentCharacter))) { - float previousExpansion = m_expansion; if (!treatAsSpace && !m_isAfterExpansion) { // Take the expansion opportunity before this ideograph. m_expansion -= m_expansionPerOpportunity; - int expansion = roundf(previousExpansion) - roundf(m_expansion); - m_runWidthSoFar += expansion; + m_runWidthSoFar += m_expansionPerOpportunity; if (glyphBuffer) - glyphBuffer->expandLastAdvance(expansion); - previousExpansion = m_expansion; + glyphBuffer->expandLastAdvance(m_expansionPerOpportunity); } m_expansion -= m_expansionPerOpportunity; - width += roundf(previousExpansion) - roundf(m_expansion); + width += m_expansionPerOpportunity; m_isAfterExpansion = true; } else m_isAfterExpansion = false; @@ -216,43 +200,10 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) cp += clusterLength; currentCharacter += clusterLength; - // Account for float/integer impedance mismatch between CG and KHTML. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // If we move KHTML to floats we can remove this (and related) hacks. - - float oldWidth = width; - - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so following words will start on an integer boundary. - if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(c)) { - width = ceilf(width); - - // Since widthSinceLastRounding can lose precision if we include measurements for - // preceding whitespace, we bypass it here. - m_runWidthSoFar += width; - - // Since this is a rounding hack character, we should have reset this sum on the previous - // iteration. - ASSERT(!widthSinceLastRounding); - } else { - // Check to see if the next character is a "rounding hack character", if so, adjust - // width so that the total run width will be on an integer boundary. - if ((m_run.applyWordRounding() && currentCharacter < m_run.length() && Font::isRoundingHackCharacter(*cp)) - || (m_run.applyRunRounding() && currentCharacter >= m_end)) { - float totalWidth = widthSinceLastRounding + width; - widthSinceLastRounding = ceilf(totalWidth); - width += widthSinceLastRounding - totalWidth; - m_runWidthSoFar += widthSinceLastRounding; - widthSinceLastRounding = 0; - } else - widthSinceLastRounding += width; - } + m_runWidthSoFar += width; if (glyphBuffer) - glyphBuffer->add(glyph, fontData, (rtl ? oldWidth + lastRoundingWidth : width)); - - lastRoundingWidth = width - oldWidth; + glyphBuffer->add(glyph, fontData, width); if (m_accountForGlyphBounds) { m_maxGlyphBoundingBoxY = max(m_maxGlyphBoundingBoxY, bounds.maxY()); @@ -262,8 +213,6 @@ void WidthIterator::advance(int offset, GlyphBuffer* glyphBuffer) } m_currentCharacter = currentCharacter; - m_runWidthSoFar += widthSinceLastRounding; - m_finalRoundingWidth = lastRoundingWidth; } bool WidthIterator::advanceOneCharacter(float& width, GlyphBuffer* glyphBuffer) diff --git a/Source/WebCore/platform/graphics/WidthIterator.h b/Source/WebCore/platform/graphics/WidthIterator.h index 2b4f051..8cb89cf 100644 --- a/Source/WebCore/platform/graphics/WidthIterator.h +++ b/Source/WebCore/platform/graphics/WidthIterator.h @@ -53,7 +53,6 @@ struct WidthIterator { float m_expansion; float m_expansionPerOpportunity; bool m_isAfterExpansion; - float m_finalRoundingWidth; private: UChar32 normalizeVoicingMarks(int currentCharacter); diff --git a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp index 2b4a39e..e9663a6 100644 --- a/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp +++ b/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp @@ -38,6 +38,7 @@ #include "ScaleTransformOperation.h" #include "SystemTime.h" #include "TranslateTransformOperation.h" +#include <QuartzCore/CATransform3D.h> #include <limits.h> #include <wtf/CurrentTime.h> #include <wtf/text/StringConcatenate.h> @@ -1680,8 +1681,8 @@ const TimingFunction* GraphicsLayerCA::timingFunctionForAnimationValue(const Ani return animValue->timingFunction(); if (anim->isTimingFunctionSet()) return anim->timingFunction().get(); - - return 0; + + return CubicBezierTimingFunction::defaultTimingFunction(); } bool GraphicsLayerCA::setAnimationEndpoints(const KeyframeValueList& valueList, const Animation* anim, PlatformCAAnimation* basicAnim) @@ -1759,23 +1760,29 @@ bool GraphicsLayerCA::setTransformAnimationEndpoints(const KeyframeValueList& va basicAnim->setToValue(toTransform); } else { if (isTransformTypeNumber(transformOpType)) { - float value; - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setFromValue(value); - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setToValue(value); + float fromValue; + getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue); + basicAnim->setFromValue(fromValue); + + float toValue; + getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue); + basicAnim->setToValue(toValue); } else if (isTransformTypeFloatPoint3D(transformOpType)) { - FloatPoint3D value; - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setFromValue(value); - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setToValue(value); + FloatPoint3D fromValue; + getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue); + basicAnim->setFromValue(fromValue); + + FloatPoint3D toValue; + getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue); + basicAnim->setToValue(toValue); } else { - TransformationMatrix value; - getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setFromValue(value); - getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, value); - basicAnim->setToValue(value); + TransformationMatrix fromValue; + getTransformFunctionValue(startValue->value()->at(functionIndex), transformOpType, boxSize, fromValue); + basicAnim->setFromValue(fromValue); + + TransformationMatrix toValue; + getTransformFunctionValue(endValue->value()->at(functionIndex), transformOpType, boxSize, toValue); + basicAnim->setToValue(toValue); } } diff --git a/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp b/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp index 27805e6..0ef5fd0 100644 --- a/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp +++ b/Source/WebCore/platform/graphics/ca/TransformationMatrixCA.cpp @@ -24,12 +24,12 @@ */ #include "config.h" +#include "TransformationMatrix.h" #if PLATFORM(CA) -#include "TransformationMatrix.h" - #include "FloatConversion.h" +#include <QuartzCore/CATransform3D.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm b/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm index 506bd40..c8ed948 100644 --- a/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm +++ b/Source/WebCore/platform/graphics/ca/mac/PlatformCAAnimationMac.mm @@ -135,9 +135,7 @@ static PlatformCAAnimation::ValueFunctionType fromCAValueFunctionType(NSString* static CAMediaTimingFunction* toCAMediaTimingFunction(const TimingFunction* timingFunction) { - if (!timingFunction) - return [CAMediaTimingFunction functionWithControlPoints:0.25f :0.1f :0.25f :0.1f]; - + ASSERT(timingFunction); if (timingFunction->isCubicBezierTimingFunction()) { const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction); return [CAMediaTimingFunction functionWithControlPoints:static_cast<float>(ctf->x1()) :static_cast<float>(ctf->y1()) @@ -145,8 +143,6 @@ static CAMediaTimingFunction* toCAMediaTimingFunction(const TimingFunction* timi } return [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; - - return 0; } PassRefPtr<PlatformCAAnimation> PlatformCAAnimation::create(AnimationType type, const String& keyPath) diff --git a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp index 9dc30ea..f2e1950 100644 --- a/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/ca/win/CACFLayerTreeHost.cpp @@ -35,6 +35,7 @@ #include "WKCACFViewLayerTreeHost.h" #include "WebCoreInstanceHandle.h" #include <limits.h> +#include <QuartzCore/CABase.h> #include <wtf/CurrentTime.h> #include <wtf/OwnArrayPtr.h> diff --git a/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp index 772244b..228e16e 100644 --- a/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp +++ b/Source/WebCore/platform/graphics/ca/win/LegacyCACFLayerTreeHost.cpp @@ -29,6 +29,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "PlatformCALayer.h" +#include <QuartzCore/CABase.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #ifndef NDEBUG diff --git a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp index 6e3011b..549f2f8 100644 --- a/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp +++ b/Source/WebCore/platform/graphics/ca/win/PlatformCAAnimationWin.cpp @@ -124,9 +124,7 @@ static PlatformCAAnimation::ValueFunctionType fromCACFValueFunctionType(CFString static RetainPtr<CACFTimingFunctionRef> toCACFTimingFunction(const TimingFunction* timingFunction) { - if (!timingFunction) - return RetainPtr<CACFTimingFunctionRef>(AdoptCF, CACFTimingFunctionCreate(0.25f, 0.1f, 0.25f, 0.1f)); - + ASSERT(timingFunction); if (timingFunction->isCubicBezierTimingFunction()) { const CubicBezierTimingFunction* ctf = static_cast<const CubicBezierTimingFunction*>(timingFunction); return RetainPtr<CACFTimingFunctionRef>(AdoptCF, CACFTimingFunctionCreate(static_cast<float>(ctf->x1()), static_cast<float>(ctf->y1()), static_cast<float>(ctf->x2()), static_cast<float>(ctf->y2()))); diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index cdbfc57..e69a7a5 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -4,7 +4,7 @@ * Copyright (C) 2008, 2009 Dirk Schulze <krit@webkit.org> * Copyright (C) 2008 Nuanti Ltd. * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org> - * Copyright (C) 2010 Igalia S.L. + * Copyright (C) 2010, 2011 Igalia S.L. * Copyright (C) Research In Motion Limited 2010. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,6 +38,7 @@ #include "CairoPath.h" #include "CairoUtilities.h" #include "ContextShadow.h" +#include "FloatConversion.h" #include "FloatRect.h" #include "Font.h" #include "GraphicsContextPlatformPrivateCairo.h" @@ -229,12 +230,19 @@ void GraphicsContext::savePlatformState() cairo_save(m_data->cr); m_data->save(); m_data->shadowStack.append(m_data->shadow); + m_data->maskImageStack.append(ImageMaskInformation()); } void GraphicsContext::restorePlatformState() { - cairo_restore(m_data->cr); - m_data->restore(); + cairo_t* cr = m_data->cr; + const ImageMaskInformation& maskInformation = m_data->maskImageStack.last(); + if (maskInformation.isValid()) { + const FloatRect& maskRect = maskInformation.maskRect(); + cairo_pop_group_to_source(cr); + cairo_mask_surface(cr, maskInformation.maskSurface(), maskRect.x(), maskRect.y()); + } + m_data->maskImageStack.removeLast(); if (m_data->shadowStack.isEmpty()) m_data->shadow = ContextShadow(); @@ -242,6 +250,9 @@ void GraphicsContext::restorePlatformState() m_data->shadow = m_data->shadowStack.last(); m_data->shadowStack.removeLast(); } + + cairo_restore(m_data->cr); + m_data->restore(); } // Draws a filled rectangle with a stroked border. @@ -701,20 +712,22 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int cairo_restore(cr); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing) { if (paintingDisabled()) return; - IntPoint endPoint = origin + IntSize(width, 0); - drawLine(origin, endPoint); + FloatPoint endPoint = origin + FloatSize(width, 0); + + // FIXME: Loss of precision here. Might consider rounding. + drawLine(IntPoint(origin.x(), origin.y()), IntPoint(endPoint.x(), endPoint.y())); } #if !PLATFORM(GTK) #include "DrawErrorUnderline.h" #endif -void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; @@ -754,16 +767,30 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect) x = round(x); y = round(y); cairo_device_to_user(cr, &x, &y); - result.setX(static_cast<float>(x)); - result.setY(static_cast<float>(y)); - x = frect.width(); - y = frect.height(); - cairo_user_to_device_distance(cr, &x, &y); - x = round(x); - y = round(y); - cairo_device_to_user_distance(cr, &x, &y); - result.setWidth(static_cast<float>(x)); - result.setHeight(static_cast<float>(y)); + result.setX(narrowPrecisionToFloat(x)); + result.setY(narrowPrecisionToFloat(y)); + + // We must ensure width and height are at least 1 (or -1) when + // we're given float values in the range between 0 and 1 (or -1 and 0). + double width = frect.width(); + double height = frect.height(); + cairo_user_to_device_distance(cr, &width, &height); + if (width > -1 && width < 0) + width = -1; + else if (width > 0 && width < 1) + width = 1; + else + width = round(width); + if (height > -1 && width < 0) + height = -1; + else if (height > 0 && height < 1) + height = 1; + else + height = round(height); + cairo_device_to_user_distance(cr, &width, &height); + result.setWidth(narrowPrecisionToFloat(width)); + result.setHeight(narrowPrecisionToFloat(height)); + return result; } @@ -838,6 +865,17 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->concatCTM(transform); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + + cairo_t* cr = m_data->cr; + const cairo_matrix_t matrix = cairo_matrix_t(transform); + cairo_set_matrix(cr, &matrix); + m_data->setCTM(transform); +} + void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { if (paintingDisabled()) @@ -1144,6 +1182,33 @@ InterpolationQuality GraphicsContext::imageInterpolationQuality() const return InterpolationDefault; } +void GraphicsContext::pushImageMask(cairo_surface_t* surface, const FloatRect& rect) +{ + // We must call savePlatformState at least once before we can use image masking, + // since we actually apply the mask in restorePlatformState. + ASSERT(!m_data->maskImageStack.isEmpty()); + m_data->maskImageStack.last().update(surface, rect); + + // Cairo doesn't support the notion of an image clip, so we push a group here + // and then paint it to the surface with an image mask (which is an immediate + // operation) during restorePlatformState. + + // We want to allow the clipped elements to composite with the surface as it + // is now, but they are isolated in another group. To make this work, we're + // going to blit the current surface contents onto the new group once we push it. + cairo_t* cr = m_data->cr; + cairo_surface_t* currentTarget = cairo_get_target(cr); + cairo_surface_flush(currentTarget); + + // Pushing a new group ensures that only things painted after this point are clipped. + cairo_push_group(cr); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + + cairo_set_source_surface(cr, currentTarget, 0, 0); + cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height()); + cairo_fill(cr); +} + } // namespace WebCore #endif // PLATFORM(CAIRO) diff --git a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h index a0dfc8c..924f69a 100644 --- a/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h +++ b/Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h @@ -31,6 +31,7 @@ #include "GraphicsContext.h" #include "ContextShadow.h" +#include "RefPtrCairo.h" #include <cairo.h> #include <math.h> #include <stdio.h> @@ -45,6 +46,25 @@ typedef struct _GdkExposeEvent GdkExposeEvent; namespace WebCore { +// In Cairo image masking is immediate, so to emulate image clipping we must save masking +// details as part of the context state and apply it during platform restore. +class ImageMaskInformation { +public: + void update(cairo_surface_t* maskSurface, const FloatRect& maskRect) + { + m_maskSurface = maskSurface; + m_maskRect = maskRect; + } + + bool isValid() const { return m_maskSurface; } + cairo_surface_t* maskSurface() const { return m_maskSurface.get(); } + const FloatRect& maskRect() const { return m_maskRect; } + +private: + RefPtr<cairo_surface_t> m_maskSurface; + FloatRect m_maskRect; +}; + class GraphicsContextPlatformPrivate { public: GraphicsContextPlatformPrivate() @@ -76,7 +96,7 @@ public: void rotate(float); void translate(float, float); void concatCTM(const AffineTransform&); - void concatCTM(const TransformationMatrix&); + void setCTM(const AffineTransform&); void beginTransparencyLayer() { m_transparencyCount++; } void endTransparencyLayer() { m_transparencyCount--; } void syncContext(PlatformGraphicsContext* cr); @@ -91,7 +111,7 @@ public: void rotate(float) {} void translate(float, float) {} void concatCTM(const AffineTransform&) {} - void concatCTM(const TransformationMatrix&) {} + void setCTM(const AffineTransform&) {} void beginTransparencyLayer() {} void endTransparencyLayer() {} void syncContext(PlatformGraphicsContext* cr) {} @@ -102,6 +122,7 @@ public: ContextShadow shadow; Vector<ContextShadow> shadowStack; + Vector<ImageMaskInformation> maskImageStack; #if PLATFORM(GTK) GdkEventExpose* expose; diff --git a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp index f7d6040..9ee8a94 100644 --- a/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp @@ -112,10 +112,9 @@ PassRefPtr<Image> ImageBuffer::copyImage() const return BitmapImage::create(copySurface(m_data.m_surface)); } -void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const +void ImageBuffer::clip(GraphicsContext* context, const FloatRect& maskRect) const { - notImplemented(); - // See https://bugs.webkit.org/show_bug.cgi?id=23526 for why this is unimplemented. + context->pushImageMask(m_data.m_surface, maskRect); } void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, diff --git a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp index 0113427..7a09a52 100644 --- a/Source/WebCore/platform/graphics/cairo/PathCairo.cpp +++ b/Source/WebCore/platform/graphics/cairo/PathCairo.cpp @@ -170,6 +170,11 @@ void Path::addArc(const FloatPoint& p, float r, float startAngle, float endAngle } } +static inline float areaOfTriangleFormedByPoints(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& p3) +{ + return p1.x() * (p2.y() - p3.y()) + p2.x() * (p3.y() - p1.y()) + p3.x() * (p1.y() - p2.y()); +} + void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) { if (isEmpty()) @@ -180,7 +185,11 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) double x0, y0; cairo_get_current_point(cr, &x0, &y0); FloatPoint p0(x0, y0); - if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || radius == 0.f) { + + // Draw only a straight line to p1 if any of the points are equal or the radius is zero + // or the points are collinear (triangle that the points form has area of zero value). + if ((p1.x() == p0.x() && p1.y() == p0.y()) || (p1.x() == p2.x() && p1.y() == p2.y()) || !radius + || !areaOfTriangleFormedByPoints(p0, p1, p2)) { cairo_line_to(cr, p1.x(), p1.y()); return; } diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 3591479..dbcab45 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -65,6 +65,11 @@ #endif +// Undocumented CGContextSetCTM function, available at least since 10.4. +extern "C" { + CG_EXTERN void CGContextSetCTM(CGContextRef, CGAffineTransform); +}; + using namespace std; namespace WebCore { @@ -603,12 +608,42 @@ void GraphicsContext::strokePath(const Path& path) CGContextAddPath(context, path.platformPath()); if (m_state.strokeGradient) { - CGContextSaveGState(context); - CGContextReplacePathWithStrokedPath(context); - CGContextClip(context); - CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform()); - m_state.strokeGradient->paint(this); - CGContextRestoreGState(context); + if (hasShadow()) { + FloatRect rect = path.boundingRect(); + float lineWidth = strokeThickness(); + float doubleLineWidth = lineWidth * 2; + float layerWidth = ceilf(rect.width() + doubleLineWidth); + float layerHeight = ceilf(rect.height() + doubleLineWidth); + + CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(layerWidth, layerHeight), 0); + CGContextRef layerContext = CGLayerGetContext(layer); + CGContextSetLineWidth(layerContext, lineWidth); + + // Compensate for the line width, otherwise the layer's top-left corner would be + // aligned with the rect's top-left corner. This would result in leaving pixels out of + // the layer on the left and top sides. + float translationX = lineWidth - rect.x(); + float translationY = lineWidth - rect.y(); + CGContextTranslateCTM(layerContext, translationX, translationY); + + CGContextAddPath(layerContext, path.platformPath()); + CGContextReplacePathWithStrokedPath(layerContext); + CGContextClip(layerContext); + CGContextConcatCTM(layerContext, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(layerContext); + + float destinationX = roundf(rect.x() - lineWidth); + float destinationY = roundf(rect.y() - lineWidth); + CGContextDrawLayerAtPoint(context, CGPointMake(destinationX, destinationY), layer); + CGLayerRelease(layer); + } else { + CGContextSaveGState(context); + CGContextReplacePathWithStrokedPath(context); + CGContextClip(context); + CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(this); + CGContextRestoreGState(context); + } return; } @@ -952,7 +987,7 @@ void GraphicsContext::clearRect(const FloatRect& r) CGContextClearRect(platformContext(), r); } -void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) +void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) { if (paintingDisabled()) return; @@ -960,19 +995,49 @@ void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth) CGContextRef context = platformContext(); if (m_state.strokeGradient) { - CGContextSaveGState(context); - setStrokeThickness(lineWidth); - CGContextAddRect(context, r); - CGContextReplacePathWithStrokedPath(context); - CGContextClip(context); - m_state.strokeGradient->paint(this); - CGContextRestoreGState(context); + if (hasShadow()) { + const float doubleLineWidth = lineWidth * 2; + const float layerWidth = ceilf(rect.width() + doubleLineWidth); + const float layerHeight = ceilf(rect.height() + doubleLineWidth); + CGLayerRef layer = CGLayerCreateWithContext(context, CGSizeMake(layerWidth, layerHeight), 0); + + CGContextRef layerContext = CGLayerGetContext(layer); + m_state.strokeThickness = lineWidth; + CGContextSetLineWidth(layerContext, lineWidth); + + // Compensate for the line width, otherwise the layer's top-left corner would be + // aligned with the rect's top-left corner. This would result in leaving pixels out of + // the layer on the left and top sides. + const float translationX = lineWidth - rect.x(); + const float translationY = lineWidth - rect.y(); + CGContextTranslateCTM(layerContext, translationX, translationY); + + CGContextAddRect(layerContext, rect); + CGContextReplacePathWithStrokedPath(layerContext); + CGContextClip(layerContext); + CGContextConcatCTM(layerContext, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(layerContext); + + const float destinationX = roundf(rect.x() - lineWidth); + const float destinationY = roundf(rect.y() - lineWidth); + CGContextDrawLayerAtPoint(context, CGPointMake(destinationX, destinationY), layer); + CGLayerRelease(layer); + } else { + CGContextSaveGState(context); + setStrokeThickness(lineWidth); + CGContextAddRect(context, rect); + CGContextReplacePathWithStrokedPath(context); + CGContextClip(context); + CGContextConcatCTM(context, m_state.strokeGradient->gradientSpaceTransform()); + m_state.strokeGradient->paint(this); + CGContextRestoreGState(context); + } return; } if (m_state.strokePattern) applyStrokePattern(); - CGContextStrokeRectWithWidth(context, r, lineWidth); + CGContextStrokeRectWithWidth(context, rect, lineWidth); } void GraphicsContext::setLineCap(LineCap cap) @@ -1085,6 +1150,15 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->m_userToDeviceTransformKnownToBeIdentity = false; } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + CGContextSetCTM(platformContext(), transform); + m_data->setCTM(transform); + m_data->m_userToDeviceTransformKnownToBeIdentity = false; +} + AffineTransform GraphicsContext::getCTM() const { CGAffineTransform t = CGContextGetCTM(platformContext()); @@ -1130,7 +1204,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); } -void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& point, float width, bool printing) { if (paintingDisabled()) return; @@ -1269,6 +1343,16 @@ void GraphicsContext::setAllowsFontSmoothing(bool allowsFontSmoothing) #endif } +void GraphicsContext::setIsCALayerContext(bool) +{ + m_data->m_isCALayerContext = true; +} + +bool GraphicsContext::isCALayerContext() const +{ + return m_data->m_isCALayerContext; +} + void GraphicsContext::setPlatformTextDrawingMode(TextDrawingModeFlags mode) { if (paintingDisabled()) diff --git a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h index d4fa32e..f9255df 100644 --- a/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h +++ b/Source/WebCore/platform/graphics/cg/GraphicsContextPlatformPrivateCG.h @@ -33,7 +33,7 @@ namespace WebCore { class GraphicsContextPlatformPrivate { public: - GraphicsContextPlatformPrivate(CGContextRef cgContext) + GraphicsContextPlatformPrivate(CGContextRef cgContext, bool isLayerContext = false) : m_cgContext(cgContext) #if PLATFORM(WIN) , m_hdc(0) @@ -41,6 +41,7 @@ public: , m_shouldIncludeChildWindows(false) #endif , m_userToDeviceTransformKnownToBeIdentity(false) + , m_isCALayerContext(isLayerContext) { } @@ -59,6 +60,7 @@ public: void rotate(float) {} void translate(float, float) {} void concatCTM(const AffineTransform&) {} + void setCTM(const AffineTransform&) {} void beginTransparencyLayer() {} void endTransparencyLayer() {} #endif @@ -74,6 +76,7 @@ public: void rotate(float); void translate(float, float); void concatCTM(const AffineTransform&); + void setCTM(const AffineTransform&); void beginTransparencyLayer() { m_transparencyCount++; } void endTransparencyLayer() { m_transparencyCount--; } @@ -84,6 +87,7 @@ public: RetainPtr<CGContextRef> m_cgContext; bool m_userToDeviceTransformKnownToBeIdentity; + bool m_isCALayerContext; }; } diff --git a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp index ab5907e..7c8e313 100644 --- a/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/Source/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -244,21 +244,21 @@ void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& src } } -void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const +void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect& rect) const { - CGContextRef platformContext = context->platformContext(); + CGContextRef platformContextToClip = contextToClip->platformContext(); RetainPtr<CGImageRef> image; if (!m_accelerateRendering) image.adoptCF(cgImage(m_size, m_data)); #if USE(IOSURFACE_CANVAS_BACKING_STORE) else - image.adoptCF(wkIOSurfaceContextCreateImage(platformContext)); + image.adoptCF(wkIOSurfaceContextCreateImage(context()->platformContext())); #endif - CGContextTranslateCTM(platformContext, rect.x(), rect.y() + rect.height()); - CGContextScaleCTM(platformContext, 1, -1); - CGContextClipToMask(platformContext, FloatRect(FloatPoint(), rect.size()), image.get()); - CGContextScaleCTM(platformContext, 1, -1); - CGContextTranslateCTM(platformContext, -rect.x(), -rect.y() - rect.height()); + CGContextTranslateCTM(platformContextToClip, rect.x(), rect.y() + rect.height()); + CGContextScaleCTM(platformContextToClip, 1, -1); + CGContextClipToMask(platformContextToClip, FloatRect(FloatPoint(), rect.size()), image.get()); + CGContextScaleCTM(platformContextToClip, 1, -1); + CGContextTranslateCTM(platformContextToClip, -rect.x(), -rect.y() - rect.height()); } template <Multiply multiplied> diff --git a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp index 4ed8684..068ea5b 100644 --- a/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp +++ b/Source/WebCore/platform/graphics/cg/ImageSourceCG.cpp @@ -40,7 +40,12 @@ using namespace std; namespace WebCore { -static const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); +const CFStringRef kCGImageSourceShouldPreferRGB32 = CFSTR("kCGImageSourceShouldPreferRGB32"); + +// kCGImagePropertyGIFUnclampedDelayTime is available in the ImageIO framework headers on some versions +// of SnowLeopard. It's not possible to detect whether the constant is available so we define our own here +// that won't conflict with ImageIO's version when it is available. +const CFStringRef WebCoreCGImagePropertyGIFUnclampedDelayTime = CFSTR("UnclampedDelayTime"); #if !PLATFORM(MAC) size_t sharedBufferGetBytesAtPosition(void* info, void* buffer, off_t position, size_t count) @@ -222,6 +227,17 @@ bool ImageSource::getHotSpot(IntPoint& hotSpot) const return true; } +size_t ImageSource::bytesDecodedToDetermineProperties() const +{ + // Measured by tracing malloc/calloc calls on Mac OS 10.6.6, x86_64. + // A non-zero value ensures cached images with no decoded frames still enter + // the live decoded resources list when the CGImageSource decodes image + // properties, allowing the cache to prune the partially decoded image. + // This value is likely to be inaccurate on other platforms, but the overall + // behavior is unchanged. + return 13088; +} + int ImageSource::repetitionCount() { int result = cAnimationLoopOnce; // No property means loop once. @@ -301,9 +317,13 @@ float ImageSource::frameDurationAtIndex(size_t index) if (properties) { CFDictionaryRef typeProperties = (CFDictionaryRef)CFDictionaryGetValue(properties.get(), kCGImagePropertyGIFDictionary); if (typeProperties) { - CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime); - if (num) + if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, WebCoreCGImagePropertyGIFUnclampedDelayTime)) { + // Use the unclamped frame delay if it exists. + CFNumberGetValue(num, kCFNumberFloatType, &duration); + } else if (CFNumberRef num = (CFNumberRef)CFDictionaryGetValue(typeProperties, kCGImagePropertyGIFDelayTime)) { + // Fall back to the clamped frame delay if the unclamped frame delay does not exist. CFNumberGetValue(num, kCFNumberFloatType, &duration); + } } } diff --git a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h index 44ef050..a14cb98 100644 --- a/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.h @@ -45,7 +45,7 @@ class Canvas2DLayerChromium : public CanvasLayerChromium { public: static PassRefPtr<Canvas2DLayerChromium> create(DrawingBuffer*, GraphicsLayerChromium* owner); virtual ~Canvas2DLayerChromium(); - virtual bool drawsContent() { return true; } + virtual bool drawsContent() const { return true; } virtual void updateContentsIfDirty(); void setTextureChanged(); diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp index 4aef25b..0264868 100644 --- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.cpp @@ -34,6 +34,7 @@ #include "CanvasLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" @@ -41,64 +42,11 @@ namespace WebCore { unsigned CanvasLayerChromium::m_shaderProgramId = 0; -CanvasLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_canvasShaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_initialized(false) -{ - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - - // Canvas layers need to be flipped vertically and their colors shouldn't be - // swizzled. - char fragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - - m_canvasShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - if (!m_canvasShaderProgram) { - LOG_ERROR("CanvasLayerChromium: Failed to create shader program"); - return; - } - - m_shaderSamplerLocation = m_context->getUniformLocation(m_canvasShaderProgram, "s_texture"); - m_shaderMatrixLocation = m_context->getUniformLocation(m_canvasShaderProgram, "matrix"); - m_shaderAlphaLocation = m_context->getUniformLocation(m_canvasShaderProgram, "alpha"); - ASSERT(m_shaderSamplerLocation != -1); - ASSERT(m_shaderMatrixLocation != -1); - ASSERT(m_shaderAlphaLocation != -1); - - m_initialized = true; -} - -CanvasLayerChromium::SharedValues::~SharedValues() -{ - if (m_canvasShaderProgram) - GLC(m_context, m_context->deleteProgram(m_canvasShaderProgram)); -} - CanvasLayerChromium::CanvasLayerChromium(GraphicsLayerChromium* owner) : LayerChromium(owner) , m_textureChanged(true) , m_textureId(0) + , m_premultipliedAlpha(true) { } @@ -109,17 +57,19 @@ CanvasLayerChromium::~CanvasLayerChromium() void CanvasLayerChromium::draw() { ASSERT(layerRenderer()); - const CanvasLayerChromium::SharedValues* sv = layerRenderer()->canvasLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const CanvasLayerChromium::Program* program = layerRenderer()->canvasLayerProgram(); + ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId)); - layerRenderer()->useShader(sv->canvasShaderProgram()); - GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); - + GC3Denum sfactor = m_premultipliedAlpha ? GraphicsContext3D::ONE : GraphicsContext3D::SRC_ALPHA; + GLC(context, context->blendFunc(sfactor, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } } diff --git a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h index 6520b55..ed3a06f 100644 --- a/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/CanvasLayerChromium.h @@ -45,30 +45,16 @@ public: virtual void draw(); - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - unsigned canvasShaderProgram() const { return m_canvasShaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_canvasShaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - bool m_initialized; - }; + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program; protected: explicit CanvasLayerChromium(GraphicsLayerChromium* owner); + + virtual const char* layerTypeAsString() const { return "CanvasLayer"; } + bool m_textureChanged; unsigned m_textureId; + bool m_premultipliedAlpha; private: static unsigned m_shaderProgramId; diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp index a38f6bd..78f93d5 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp @@ -34,97 +34,15 @@ #include "ContentLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include "LayerTexture.h" #include "RenderLayerBacking.h" - -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#include "SkColorPriv.h" -#include "skia/ext/platform_canvas.h" -#elif PLATFORM(CG) -#include <CoreGraphics/CGBitmapContext.h> -#endif +#include "TextStream.h" namespace WebCore { -ContentLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_contentShaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_initialized(false) -{ - // Shaders for drawing the layer contents. - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - -#if PLATFORM(SKIA) - // Color is in RGBA order. - char rgbaFragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor = texColor * alpha; \n" - "} \n"; -#endif - - // Color is in BGRA order. - char bgraFragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; \n" - "} \n"; - -#if PLATFORM(SKIA) - // Assuming the packing is either Skia default RGBA or Chromium default BGRA. - char* fragmentShaderString = SK_B32_SHIFT ? rgbaFragmentShaderString : bgraFragmentShaderString; -#else - char* fragmentShaderString = bgraFragmentShaderString; -#endif - m_contentShaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - if (!m_contentShaderProgram) { - LOG_ERROR("ContentLayerChromium: Failed to create shader program"); - return; - } - - m_shaderSamplerLocation = m_context->getUniformLocation(m_contentShaderProgram, "s_texture"); - m_shaderMatrixLocation = m_context->getUniformLocation(m_contentShaderProgram, "matrix"); - m_shaderAlphaLocation = m_context->getUniformLocation(m_contentShaderProgram, "alpha"); - ASSERT(m_shaderSamplerLocation != -1); - ASSERT(m_shaderMatrixLocation != -1); - ASSERT(m_shaderAlphaLocation != -1); - - m_initialized = true; -} - -ContentLayerChromium::SharedValues::~SharedValues() -{ - if (m_contentShaderProgram) - GLC(m_context, m_context->deleteProgram(m_contentShaderProgram)); -} - - PassRefPtr<ContentLayerChromium> ContentLayerChromium::create(GraphicsLayerChromium* owner) { return adoptRef(new ContentLayerChromium(owner)); @@ -154,9 +72,9 @@ bool ContentLayerChromium::requiresClippedUpdateRect() const // one of the layer's dimensions is larger than 2000 pixels or the size of // surface it's rendering into. This is a temporary measure until layer tiling is implemented. static const int maxLayerSize = 2000; - return (m_bounds.width() > max(maxLayerSize, m_targetRenderSurface->contentRect().width()) - || m_bounds.height() > max(maxLayerSize, m_targetRenderSurface->contentRect().height()) - || !layerRenderer()->checkTextureSize(m_bounds)); + return (bounds().width() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().width()) + || bounds().height() > max(maxLayerSize, ccLayerImpl()->targetRenderSurface()->contentRect().height()) + || !layerRenderer()->checkTextureSize(bounds())); } void ContentLayerChromium::updateContentsIfDirty() @@ -169,28 +87,25 @@ void ContentLayerChromium::updateContentsIfDirty() ASSERT(layerRenderer()); - void* pixels = 0; IntRect dirtyRect; - IntRect updateRect; - IntSize requiredTextureSize; - IntSize bitmapSize; - IntRect boundsRect(IntPoint(0, 0), m_bounds); + IntRect boundsRect(IntPoint(0, 0), bounds()); + IntPoint paintingOffset; // FIXME: Remove this test when tiled layers are implemented. if (requiresClippedUpdateRect()) { // A layer with 3D transforms could require an arbitrarily large number // of texels to be repainted, so ignore these layers until tiling is // implemented. - if (!drawTransform().isIdentityOrTranslation()) { + if (!ccLayerImpl()->drawTransform().isIdentityOrTranslation()) { m_skipsDraw = true; return; } // Calculate the region of this layer that is currently visible. - const IntRect clipRect = m_targetRenderSurface->contentRect(); + const IntRect clipRect = ccLayerImpl()->targetRenderSurface()->contentRect(); - TransformationMatrix layerOriginTransform = drawTransform(); - layerOriginTransform.translate3d(-0.5 * m_bounds.width(), -0.5 * m_bounds.height(), 0); + TransformationMatrix layerOriginTransform = ccLayerImpl()->drawTransform(); + layerOriginTransform.translate3d(-0.5 * bounds().width(), -0.5 * bounds().height(), 0); // For now we apply the large layer treatment only for layers that are either untransformed // or are purely translated. Their matrix is expected to be invertible. @@ -198,7 +113,7 @@ void ContentLayerChromium::updateContentsIfDirty() TransformationMatrix targetToLayerMatrix = layerOriginTransform.inverse(); IntRect visibleRectInLayerCoords = targetToLayerMatrix.mapRect(clipRect); - visibleRectInLayerCoords.intersect(IntRect(0, 0, m_bounds.width(), m_bounds.height())); + visibleRectInLayerCoords.intersect(IntRect(0, 0, bounds().width(), bounds().height())); // For normal layers, the center of the texture corresponds with the center of the layer. // In large layers the center of the texture is the center of the visible region so we have @@ -212,9 +127,13 @@ void ContentLayerChromium::updateContentsIfDirty() return; } - // If the visible portion of the layer is different from the last upload, or if our backing - // texture has been evicted, then the whole layer is considered dirty. - if (visibleRectInLayerCoords != m_visibleRectInLayerCoords || !m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA)) + // If we need to resize the upload buffer we have to repaint everything. + if (m_canvas.size() != visibleRectInLayerCoords.size()) { + resizeUploadBuffer(visibleRectInLayerCoords.size()); + m_dirtyRect = boundsRect; + } + // If the visible portion of the layer is different from the last upload. + if (visibleRectInLayerCoords != m_visibleRectInLayerCoords) m_dirtyRect = boundsRect; m_visibleRectInLayerCoords = visibleRectInLayerCoords; @@ -224,92 +143,52 @@ void ContentLayerChromium::updateContentsIfDirty() // What the rectangles mean: // dirtyRect: The region of this layer that will be updated. - // updateRect: The region of the layer's texture that will be uploaded into. - // requiredTextureSize: is the required size of this layer's texture. + // m_uploadUpdateRect: The region of the layer's texture that will be uploaded into. dirtyRect = visibleDirtyRectInLayerSpace; - updateRect = dirtyRect; + m_uploadUpdateRect = dirtyRect; IntSize visibleRectOffsetInLayerCoords(visibleRectInLayerCoords.x(), visibleRectInLayerCoords.y()); - updateRect.move(-visibleRectOffsetInLayerCoords); - requiredTextureSize = visibleRectInLayerCoords.size(); + paintingOffset = IntPoint(visibleRectOffsetInLayerCoords); + m_uploadUpdateRect.move(-visibleRectOffsetInLayerCoords); } else { dirtyRect = IntRect(m_dirtyRect); - requiredTextureSize = m_bounds; // If the texture needs to be reallocated then we must redraw the entire // contents of the layer. - if (!m_contentsTexture || !m_contentsTexture->isValid(requiredTextureSize, GraphicsContext3D::RGBA)) + if (m_canvas.size() != bounds()) { + resizeUploadBuffer(bounds()); dirtyRect = boundsRect; - else { + } else { // Clip the dirtyRect to the size of the layer to avoid drawing // outside the bounds of the backing texture. dirtyRect.intersect(boundsRect); } - updateRect = dirtyRect; + m_uploadUpdateRect = dirtyRect; } if (dirtyRect.isEmpty()) return; -#if PLATFORM(SKIA) - const SkBitmap* skiaBitmap = 0; - OwnPtr<skia::PlatformCanvas> canvas; - OwnPtr<PlatformContextSkia> skiaContext; - OwnPtr<GraphicsContext> graphicsContext; - - canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false)); - skiaContext.set(new PlatformContextSkia(canvas.get())); - - // This is needed to get text to show up correctly. - // FIXME: Does this take us down a very slow text rendering path? - skiaContext->setDrawingToImageBuffer(true); - - graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get()))); + PlatformCanvas::Painter painter(&m_canvas); + painter.context()->save(); + painter.context()->translate(-paintingOffset.x(), -paintingOffset.y()); + painter.context()->clearRect(dirtyRect); + painter.context()->clip(dirtyRect); - // Bring the canvas into the coordinate system of the paint rect. - canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y())); + m_owner->paintGraphicsLayerContents(*painter.context(), dirtyRect); + painter.context()->restore(); +} - m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect); - const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false); - skiaBitmap = &bitmap; - ASSERT(skiaBitmap); +void ContentLayerChromium::resizeUploadBuffer(const IntSize& size) +{ + m_canvas.resize(size); +} - SkAutoLockPixels lock(*skiaBitmap); - SkBitmap::Config skiaConfig = skiaBitmap->config(); - // FIXME: do we need to support more image configurations? - if (skiaConfig == SkBitmap::kARGB_8888_Config) { - pixels = skiaBitmap->getPixels(); - bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height()); - } -#elif PLATFORM(CG) - Vector<uint8_t> tempVector; - int rowBytes = 4 * dirtyRect.width(); - tempVector.resize(rowBytes * dirtyRect.height()); - memset(tempVector.data(), 0, tempVector.size()); - RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); - RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(), - dirtyRect.width(), dirtyRect.height(), 8, rowBytes, - colorSpace.get(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height()); - CGContextScaleCTM(contextCG.get(), 1, -1); - - GraphicsContext graphicsContext(contextCG.get()); - - // Translate the graphics context into the coordinate system of the dirty rect. - graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y()); - - m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect); - - pixels = tempVector.data(); - bitmapSize = dirtyRect.size(); -#else -#error "Need to implement for your platform." -#endif - - if (pixels) - updateTextureRect(pixels, requiredTextureSize, updateRect); +void ContentLayerChromium::updateTextureIfNeeded() +{ + PlatformCanvas::AutoLocker locker(&m_canvas); + updateTexture(locker.pixels(), m_canvas.size()); } -void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect) +void ContentLayerChromium::updateTexture(const uint8_t* pixels, const IntSize& size) { if (!pixels) return; @@ -318,15 +197,43 @@ void ContentLayerChromium::updateTextureRect(void* pixels, const IntSize& requir if (!m_contentsTexture) m_contentsTexture = LayerTexture::create(context, layerRenderer()->textureManager()); - if (!m_contentsTexture->reserve(requiredTextureSize, GraphicsContext3D::RGBA)) { + // If we have to allocate a new texture we have to upload the full contents. + if (!m_contentsTexture->isValid(size, GraphicsContext3D::RGBA)) + m_uploadUpdateRect = IntRect(IntPoint(0, 0), size); + + if (!m_contentsTexture->reserve(size, GraphicsContext3D::RGBA)) { m_skipsDraw = true; return; } - m_contentsTexture->bindTexture(); + IntRect srcRect = IntRect(IntPoint(0, 0), size); + if (requiresClippedUpdateRect()) + srcRect = m_visibleRectInLayerCoords; + + const size_t destStride = m_uploadUpdateRect.width() * 4; + const size_t srcStride = srcRect.width() * 4; + + const uint8_t* uploadPixels = pixels + srcStride * m_uploadUpdateRect.y(); + Vector<uint8_t> uploadBuffer; + if (srcStride != destStride || m_uploadUpdateRect.x()) { + uploadBuffer.resize(m_uploadUpdateRect.height() * destStride); + for (int row = 0; row < m_uploadUpdateRect.height(); ++row) { + size_t srcOffset = (m_uploadUpdateRect.y() + row) * srcStride + m_uploadUpdateRect.x() * 4; + ASSERT(srcOffset + destStride <= static_cast<size_t>(size.width() * size.height() * 4)); + size_t destOffset = row * destStride; + ASSERT(destOffset + destStride <= uploadBuffer.size()); + memcpy(uploadBuffer.data() + destOffset, pixels + srcOffset, destStride); + } + uploadPixels = uploadBuffer.data(); + } - GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, updateRect.x(), updateRect.y(), updateRect.width(), updateRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); + m_contentsTexture->bindTexture(); + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, + m_uploadUpdateRect.x(), m_uploadUpdateRect.y(), m_uploadUpdateRect.width(), m_uploadUpdateRect.height(), + GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, + uploadPixels)); + m_uploadUpdateRect = IntRect(); m_dirtyRect.setSize(FloatSize()); // Large layers always stay dirty, because they need to update when the content rect changes. m_contentsDirty = requiresClippedUpdateRect(); @@ -339,43 +246,59 @@ void ContentLayerChromium::draw() ASSERT(layerRenderer()); - const ContentLayerChromium::SharedValues* sv = layerRenderer()->contentLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const ContentLayerChromium::Program* program = layerRenderer()->contentLayerProgram(); + ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); bindContentsTexture(); - layerRenderer()->useShader(sv->contentShaderProgram()); - GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + GLC(context, context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); if (requiresClippedUpdateRect()) { - float m43 = drawTransform().m43(); + float m43 = ccLayerImpl()->drawTransform().m43(); TransformationMatrix transform; transform.translate3d(m_layerCenterInSurfaceCoords.x(), m_layerCenterInSurfaceCoords.y(), m43); drawTexturedQuad(context, layerRenderer()->projectionMatrix(), transform, m_visibleRectInLayerCoords.width(), - m_visibleRectInLayerCoords.height(), drawOpacity(), - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); + m_visibleRectInLayerCoords.height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } else { drawTexturedQuad(context, layerRenderer()->projectionMatrix(), - drawTransform(), m_bounds.width(), m_bounds.height(), - drawOpacity(), sv->shaderMatrixLocation(), - sv->shaderAlphaLocation()); + ccLayerImpl()->drawTransform(), bounds().width(), bounds().height(), + ccLayerImpl()->drawOpacity(), program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } unreserveContentsTexture(); } void ContentLayerChromium::unreserveContentsTexture() { - if (m_contentsTexture) + if (!m_skipsDraw && m_contentsTexture) m_contentsTexture->unreserve(); } void ContentLayerChromium::bindContentsTexture() { - if (m_contentsTexture) + updateTextureIfNeeded(); + + if (!m_skipsDraw && m_contentsTexture) m_contentsTexture->bindTexture(); } +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void ContentLayerChromium::dumpLayerProperties(TextStream& ts, int indent) const +{ + LayerChromium::dumpLayerProperties(ts, indent); + writeIndent(ts, indent); + ts << "skipsDraw: " << m_skipsDraw << "\n"; +} } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h index 3363518..6f070c2 100644 --- a/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.h @@ -35,6 +35,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "LayerChromium.h" +#include "PlatformCanvas.h" #include "TextureManager.h" namespace WebCore { @@ -54,43 +55,31 @@ public: virtual void bindContentsTexture(); virtual void draw(); - virtual bool drawsContent() { return m_owner && m_owner->drawsContent(); } - - // Stores values that are shared between instances of this class that are - // associated with the same LayerRendererChromium (and hence the same GL - // context). - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - unsigned contentShaderProgram() const { return m_contentShaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - int initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_contentShaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - int m_initialized; - }; + virtual bool drawsContent() const { return m_owner && m_owner->drawsContent(); } + + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderTexAlpha> Program; protected: explicit ContentLayerChromium(GraphicsLayerChromium* owner); - void updateTextureRect(void* pixels, const IntSize& requiredTextureSize, const IntRect& updateRect); - virtual void cleanupResources(); bool requiresClippedUpdateRect() const; + void resizeUploadBuffer(const IntSize&); + + virtual const char* layerTypeAsString() const { return "ContentLayer"; } + virtual void dumpLayerProperties(TextStream&, int indent) const; OwnPtr<LayerTexture> m_contentsTexture; bool m_skipsDraw; + // The portion of the upload buffer that has a pending update, in the coordinates of the texture. + IntRect m_uploadUpdateRect; + + virtual void updateTextureIfNeeded(); + void updateTexture(const uint8_t* pixels, const IntSize&); + private: + PlatformCanvas m_canvas; IntRect m_visibleRectInLayerCoords; FloatPoint m_layerCenterInSurfaceCoords; diff --git a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h index 92fb7b3..3b0fdbf 100644 --- a/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h +++ b/Source/WebCore/platform/graphics/chromium/Extensions3DChromium.h @@ -46,6 +46,10 @@ public: virtual int getGraphicsResetStatusARB(); virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + virtual Platform3DObject createVertexArrayOES(); + virtual void deleteVertexArrayOES(Platform3DObject); + virtual GC3Dboolean isVertexArrayOES(Platform3DObject); + virtual void bindVertexArrayOES(Platform3DObject); enum { // GL_CHROMIUM_map_sub (enums inherited from GL_ARB_vertex_buffer_object) diff --git a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp index a849a6c..bbe6d62 100644 --- a/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp +++ b/Source/WebCore/platform/graphics/chromium/FontCacheLinux.cpp @@ -43,6 +43,7 @@ #include "SkTypeface.h" #include "SkUtils.h" +#include <unicode/locid.h> #include <wtf/Assertions.h> #include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> @@ -57,7 +58,8 @@ const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) { - String family = PlatformBridge::getFontFamilyForCharacters(characters, length); + icu::Locale locale = icu::Locale::getDefault(); + String family = PlatformBridge::getFontFamilyForCharacters(characters, length, locale.getLanguage()); if (family.isEmpty()) return 0; diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp index 953ee2f..2ff6b8b 100644 --- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp +++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.cpp @@ -38,10 +38,12 @@ #include "GraphicsContext3D.h" #include "internal_glu.h" #include "IntRect.h" +#include "LoopBlinnPathProcessor.h" +#include "LoopBlinnSolidFillShader.h" #include "Path.h" #include "PlatformString.h" #include "SharedGraphicsContext3D.h" -#if PLATFORM(SKIA) +#if USE(SKIA) #include "SkPath.h" #endif #include "Texture.h" @@ -170,6 +172,7 @@ GLES2Canvas::GLES2Canvas(SharedGraphicsContext3D* context, DrawingBuffer* drawin , m_context(context) , m_drawingBuffer(drawingBuffer) , m_state(0) + , m_pathVertexBuffer(0) { m_flipMatrix.translate(-1.0f, 1.0f); m_flipMatrix.scale(2.0f / size.width(), -2.0f / size.height()); @@ -191,7 +194,7 @@ void GLES2Canvas::clearRect(const FloatRect& rect) { bindFramebuffer(); if (m_state->m_ctm.isIdentity() && !m_state->m_clippingEnabled) { - m_context->scissor(rect); + m_context->scissor(rect.x(), m_size.height() - rect.height() - rect.y(), rect.width(), rect.height()); m_context->enable(GraphicsContext3D::SCISSOR_TEST); m_context->clearColor(Color(RGBA32(0))); m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); @@ -263,6 +266,11 @@ void GLES2Canvas::concatCTM(const AffineTransform& affine) m_state->m_ctm *= affine; } +void GLES2Canvas::setCTM(const AffineTransform& affine) +{ + m_state->m_ctm = affine; +} + void GLES2Canvas::clipPath(const Path& path) { bindFramebuffer(); @@ -396,9 +404,9 @@ Texture* GLES2Canvas::getTexture(NativeImagePtr ptr) return m_context->getTexture(ptr); } -#if PLATFORM(SKIA) +#if USE(SKIA) // This is actually cross-platform code, but since its only caller is inside a -// PLATFORM(SKIA), it will cause a warning-as-error on Chrome/Mac. +// USE(SKIA), it will cause a warning-as-error on Chrome/Mac. static void interpolateQuadratic(DoubleVector* vertices, const FloatPoint& p0, const FloatPoint& p1, const FloatPoint& p2) { float tIncrement = 1.0f / pathTesselation, t = tIncrement; @@ -473,7 +481,7 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig checkGLError("createVertexBufferFromPath, createBuffer"); DoubleVector inVertices; WTF::Vector<size_t> contours; -#if PLATFORM(SKIA) +#if USE(SKIA) const SkPath* skPath = path.platformPath(); SkPoint pts[4]; SkPath::Iter iter(*skPath, true); @@ -548,28 +556,61 @@ void GLES2Canvas::createVertexBufferFromPath(const Path& path, int* count, unsig void GLES2Canvas::fillPath(const Path& path, const Color& color) { - int count; - unsigned vertexBuffer, indexBuffer; - createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer); - m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer); - checkGLError("bindBuffer"); - m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer); - checkGLError("bindBuffer"); + if (SharedGraphicsContext3D::useLoopBlinnForPathRendering()) { + bindFramebuffer(); + m_context->applyCompositeOperator(m_state->m_compositeOp); + + m_pathCache.clear(); + LoopBlinnPathProcessor processor; + processor.process(path, m_pathCache); + if (!m_pathVertexBuffer) + m_pathVertexBuffer = m_context->createBuffer(); + m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_pathVertexBuffer); + int byteSizeOfVertices = 2 * m_pathCache.numberOfVertices() * sizeof(float); + int byteSizeOfTexCoords = 3 * m_pathCache.numberOfVertices() * sizeof(float); + int byteSizeOfInteriorVertices = 2 * m_pathCache.numberOfInteriorVertices() * sizeof(float); + m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, + byteSizeOfVertices + byteSizeOfTexCoords + byteSizeOfInteriorVertices, + GraphicsContext3D::STATIC_DRAW); + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, 0, byteSizeOfVertices, m_pathCache.vertices()); + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices, byteSizeOfTexCoords, m_pathCache.texcoords()); + m_context->bufferSubData(GraphicsContext3D::ARRAY_BUFFER, byteSizeOfVertices + byteSizeOfTexCoords, byteSizeOfInteriorVertices, m_pathCache.interiorVertices()); + + AffineTransform matrix(m_flipMatrix); + matrix *= m_state->m_ctm; + + // Draw the exterior + m_context->useLoopBlinnExteriorProgram(0, byteSizeOfVertices, matrix, color); + m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfVertices()); + + // Draw the interior + m_context->useLoopBlinnInteriorProgram(byteSizeOfVertices + byteSizeOfTexCoords, matrix, color); + m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, m_pathCache.numberOfInteriorVertices()); + } else { + int count; + unsigned vertexBuffer, indexBuffer; + createVertexBufferFromPath(path, &count, &vertexBuffer, &indexBuffer); + m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, vertexBuffer); + checkGLError("bindBuffer"); + m_context->graphicsContext3D()->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, indexBuffer); + checkGLError("bindBuffer"); - AffineTransform matrix(m_flipMatrix); - matrix *= m_state->m_ctm; + AffineTransform matrix(m_flipMatrix); + matrix *= m_state->m_ctm; - m_context->useFillSolidProgram(matrix, color); - checkGLError("useFillSolidProgram"); + m_context->useFillSolidProgram(matrix, color); + checkGLError("useFillSolidProgram"); - m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0); - checkGLError("drawArrays"); + bindFramebuffer(); + m_context->graphicsContext3D()->drawElements(GraphicsContext3D::TRIANGLES, count, GraphicsContext3D::UNSIGNED_SHORT, 0); + checkGLError("drawArrays"); - m_context->graphicsContext3D()->deleteBuffer(vertexBuffer); - checkGLError("deleteBuffer"); + m_context->graphicsContext3D()->deleteBuffer(vertexBuffer); + checkGLError("deleteBuffer"); - m_context->graphicsContext3D()->deleteBuffer(indexBuffer); - checkGLError("deleteBuffer"); + m_context->graphicsContext3D()->deleteBuffer(indexBuffer); + checkGLError("deleteBuffer"); + } } void GLES2Canvas::beginStencilDraw() diff --git a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h index 605f86f..8887a16 100644 --- a/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h +++ b/Source/WebCore/platform/graphics/chromium/GLES2Canvas.h @@ -36,6 +36,7 @@ #include "ColorSpace.h" #include "GraphicsTypes.h" #include "ImageSource.h" +#include "LoopBlinnPathCache.h" #include "Texture.h" #include <wtf/HashMap.h> @@ -68,6 +69,7 @@ public: void rotate(float angleInRadians); void scale(const FloatSize&); void concatCTM(const AffineTransform&); + void setCTM(const AffineTransform&); void clipPath(const Path&); void clipOut(const Path&); @@ -113,6 +115,10 @@ private: StateVector m_stateStack; State* m_state; AffineTransform m_flipMatrix; + + // Members for GPU-accelerated path rendering. + LoopBlinnPathCache m_pathCache; + unsigned m_pathVertexBuffer; }; } diff --git a/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp b/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp new file mode 100644 index 0000000..a859aae --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/GeometryBinding.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "GeometryBinding.h" + +#include "GraphicsContext.h" +#include "GraphicsContext3D.h" +#include "LayerRendererChromium.h" + +namespace WebCore { + +GeometryBinding::GeometryBinding(GraphicsContext3D* context) + : m_context(context) + , m_quadVerticesVbo(0) + , m_quadElementsVbo(0) + , m_initialized(false) +{ + // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad. + float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, + -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, + 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, + 0.5f, 0.5f, 0.0f, 1.0f, 1.0f }; + uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad. + 0, 1, 2, 3}; // A line path for drawing the layer border. + + GLC(m_context, m_quadVerticesVbo = m_context->createBuffer()); + GLC(m_context, m_quadElementsVbo = m_context->createBuffer()); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo)); + GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW)); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo)); + GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW)); + + m_initialized = true; +} + +GeometryBinding::~GeometryBinding() +{ + GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo)); + GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo)); +} + +void GeometryBinding::prepareForDraw() +{ + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, quadVerticesVbo())); + GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, quadElementsVbo())); + unsigned offset = 0; + GLC(m_context, m_context->vertexAttribPointer(positionAttribLocation(), 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); + offset += 3 * sizeof(float); + GLC(m_context, m_context->vertexAttribPointer(texCoordAttribLocation(), 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); + GLC(m_context, m_context->enableVertexAttribArray(positionAttribLocation())); + GLC(m_context, m_context->enableVertexAttribArray(texCoordAttribLocation())); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/GeometryBinding.h b/Source/WebCore/platform/graphics/chromium/GeometryBinding.h new file mode 100644 index 0000000..ec19970 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/GeometryBinding.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GeometryBinding_h +#define GeometryBinding_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PlatformString.h" + +namespace WebCore { + +class GraphicsContext3D; + +class GeometryBinding { +public: + explicit GeometryBinding(GraphicsContext3D*); + ~GeometryBinding(); + + bool initialized() const { return m_initialized; } + + GraphicsContext3D* context() const { return m_context; } + unsigned quadVerticesVbo() const { return m_quadVerticesVbo; } + unsigned quadElementsVbo() const { return m_quadElementsVbo; } + + void prepareForDraw(); + + // All layer shaders share the same attribute locations for the vertex + // positions and texture coordinates. This allows switching shaders without + // rebinding attribute arrays. + static int positionAttribLocation() { return 0; } + static int texCoordAttribLocation() { return 1; } + +private: + GraphicsContext3D* m_context; + unsigned m_quadVerticesVbo; + unsigned m_quadElementsVbo; + bool m_initialized; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp index 488230c..067c54d 100644 --- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.cpp @@ -111,8 +111,20 @@ GraphicsLayerChromium::~GraphicsLayerChromium() void GraphicsLayerChromium::setName(const String& inName) { + m_nameBase = inName; String name = String::format("GraphicsLayerChromium(%p) GraphicsLayer(%p) ", m_layer.get(), this) + inName; GraphicsLayer::setName(name); + updateNames(); +} + +void GraphicsLayerChromium::updateNames() +{ + if (m_layer) + m_layer->setName("Layer for " + m_nameBase); + if (m_transformLayer) + m_transformLayer->setName("TransformLayer for " + m_nameBase); + if (m_contentsLayer) + m_contentsLayer->setName("ContentsLayer for " + m_nameBase); } bool GraphicsLayerChromium::setChildren(const Vector<GraphicsLayer*>& children) @@ -590,6 +602,7 @@ void GraphicsLayerChromium::updateLayerPreserves3D() } updateOpacityOnLayer(); + updateNames(); } void GraphicsLayerChromium::updateLayerDrawsContent() @@ -653,6 +666,7 @@ void GraphicsLayerChromium::setupContentsLayer(LayerChromium* contentsLayer) } } updateDebugIndicators(); + updateNames(); } // This function simply mimics the operation of GraphicsLayerCA diff --git a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h index 92c61fe..db8c6f7 100644 --- a/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/GraphicsLayerChromium.h @@ -107,6 +107,7 @@ private: LayerChromium* hostLayerForSublayers() const; LayerChromium* layerForSuperlayer() const; + void updateNames(); void updateSublayerList(); void updateLayerPosition(); void updateLayerSize(); @@ -127,6 +128,8 @@ private: void setupContentsLayer(LayerChromium*); LayerChromium* contentsLayer() const { return m_contentsLayer.get(); } + String m_nameBase; + RefPtr<LayerChromium> m_layer; RefPtr<LayerChromium> m_transformLayer; RefPtr<LayerChromium> m_contentsLayer; diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp index cd299c1..7c42366 100644 --- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp @@ -38,18 +38,6 @@ #include "LayerRendererChromium.h" #include "LayerTexture.h" -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#endif - -#if PLATFORM(CG) -#include <CoreGraphics/CGBitmapContext.h> -#include <CoreGraphics/CGContext.h> -#include <CoreGraphics/CGImage.h> -#include <wtf/RetainPtr.h> -#endif - namespace WebCore { PassRefPtr<ImageLayerChromium> ImageLayerChromium::create(GraphicsLayerChromium* owner) @@ -84,80 +72,17 @@ void ImageLayerChromium::updateContentsIfDirty() return; } - void* pixels = 0; - IntSize bitmapSize; - - NativeImagePtr nativeImage = m_contents->nativeImageForCurrentFrame(); - -#if PLATFORM(SKIA) - // The layer contains an Image. - NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage); - const SkBitmap* skiaBitmap = skiaImage; - bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height()); - ASSERT(skiaBitmap); -#elif PLATFORM(CG) - // NativeImagePtr is a CGImageRef on Mac OS X. - int width = CGImageGetWidth(nativeImage); - int height = CGImageGetHeight(nativeImage); - bitmapSize = IntSize(width, height); -#endif - - // Clip the dirty rect to the bitmap dimensions. - IntRect dirtyRect(m_dirtyRect); - dirtyRect.intersect(IntRect(IntPoint(0, 0), bitmapSize)); + m_decodedImage.updateFromImage(m_contents->nativeImageForCurrentFrame()); +} - if (!m_contentsTexture || !m_contentsTexture->isValid(bitmapSize, GraphicsContext3D::RGBA)) - dirtyRect = IntRect(IntPoint(0, 0), bitmapSize); - else if (!m_contentsDirty) { - m_contentsTexture->reserve(bitmapSize, GraphicsContext3D::RGBA); +void ImageLayerChromium::updateTextureIfNeeded() +{ + // FIXME: Remove this test when tiled layers are implemented. + if (requiresClippedUpdateRect()) { + ContentLayerChromium::updateTextureIfNeeded(); return; } - -#if PLATFORM(SKIA) - SkAutoLockPixels lock(*skiaBitmap); - SkBitmap::Config skiaConfig = skiaBitmap->config(); - // FIXME: do we need to support more image configurations? - if (skiaConfig == SkBitmap::kARGB_8888_Config) - pixels = skiaBitmap->getPixels(); -#elif PLATFORM(CG) - // FIXME: we should get rid of this temporary copy where possible. - int tempRowBytes = width * 4; - Vector<uint8_t> tempVector; - tempVector.resize(height * tempRowBytes); - // Note we do not zero this vector since we are going to - // completely overwrite its contents with the image below. - // Try to reuse the color space from the image to preserve its colors. - // Some images use a color space (such as indexed) unsupported by the bitmap context. - RetainPtr<CGColorSpaceRef> colorSpaceReleaser; - CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage); - CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); - switch (colorSpaceModel) { - case kCGColorSpaceModelMonochrome: - case kCGColorSpaceModelRGB: - case kCGColorSpaceModelCMYK: - case kCGColorSpaceModelLab: - case kCGColorSpaceModelDeviceN: - break; - default: - colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB()); - colorSpace = colorSpaceReleaser.get(); - break; - } - RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(tempVector.data(), - width, height, 8, tempRowBytes, - colorSpace, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy); - CGContextDrawImage(tempContext.get(), - CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)), - nativeImage); - pixels = tempVector.data(); -#else -#error "Need to implement for your platform." -#endif - - if (pixels) - updateTextureRect(pixels, bitmapSize, dirtyRect); + updateTexture(m_decodedImage.pixels(), m_decodedImage.size()); } } diff --git a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h index a5c1450..cc9064d 100644 --- a/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/ImageLayerChromium.h @@ -35,6 +35,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "ContentLayerChromium.h" +#include "PlatformImage.h" #if PLATFORM(CG) #include <wtf/RetainPtr.h> @@ -50,13 +51,19 @@ public: static PassRefPtr<ImageLayerChromium> create(GraphicsLayerChromium* owner = 0); virtual void updateContentsIfDirty(); - virtual bool drawsContent() { return m_contents; } + virtual bool drawsContent() const { return m_contents; } void setContents(Image* image); +protected: + virtual const char* layerTypeAsString() const { return "ImageLayer"; } + private: + virtual void updateTextureIfNeeded(); + ImageLayerChromium(GraphicsLayerChromium* owner); + PlatformImage m_decodedImage; RefPtr<Image> m_contents; }; diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp index 8d01d9b..95b7386 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -34,106 +34,24 @@ #include "LayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" -#if PLATFORM(SKIA) +#if USE(SKIA) #include "NativeImageSkia.h" #include "PlatformContextSkia.h" #endif #include "RenderLayerBacking.h" +#include "TextStream.h" #include "skia/ext/platform_canvas.h" -#include <wtf/text/WTFString.h> namespace WebCore { using namespace std; -const unsigned LayerChromium::s_positionAttribLocation = 0; -const unsigned LayerChromium::s_texCoordAttribLocation = 1; - -static unsigned loadShader(GraphicsContext3D* context, unsigned type, const char* shaderSource) -{ - unsigned shader = context->createShader(type); - if (!shader) - return 0; - String sourceString(shaderSource); - GLC(context, context->shaderSource(shader, sourceString)); - GLC(context, context->compileShader(shader)); - int compiled = 0; - GLC(context, context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled)); - if (!compiled) { - GLC(context, context->deleteShader(shader)); - return 0; - } - return shader; -} - -LayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_quadVerticesVbo(0) - , m_quadElementsVbo(0) - , m_maxTextureSize(0) - , m_borderShaderProgram(0) - , m_borderShaderMatrixLocation(-1) - , m_borderShaderColorLocation(-1) - , m_initialized(false) -{ - // Vertex positions and texture coordinates for the 4 corners of a 1x1 quad. - float vertices[] = { -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, - -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, - 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, - 0.5f, 0.5f, 0.0f, 1.0f, 1.0f }; - uint16_t indices[] = { 0, 1, 2, 0, 2, 3, // The two triangles that make up the layer quad. - 0, 1, 2, 3}; // A line path for drawing the layer border. - - GLC(m_context, m_quadVerticesVbo = m_context->createBuffer()); - GLC(m_context, m_quadElementsVbo = m_context->createBuffer()); - GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_quadVerticesVbo)); - GLC(m_context, m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(vertices), vertices, GraphicsContext3D::STATIC_DRAW)); - GLC(m_context, m_context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, m_quadElementsVbo)); - GLC(m_context, m_context->bufferData(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GraphicsContext3D::STATIC_DRAW)); - - // Get the max texture size supported by the system. - GLC(m_context, m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize)); - - // Shaders for drawing the debug borders around the layers. - char borderVertexShaderString[] = - "attribute vec4 a_position; \n" - "uniform mat4 matrix; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - "} \n"; - char borderFragmentShaderString[] = - "precision mediump float; \n" - "uniform vec4 color; \n" - "void main() \n" - "{ \n" - " gl_FragColor = vec4(color.xyz * color.w, color.w);\n" - "} \n"; - - m_borderShaderProgram = createShaderProgram(m_context, borderVertexShaderString, borderFragmentShaderString); - if (!m_borderShaderProgram) { - LOG_ERROR("ContentLayerChromium: Failed to create shader program"); - return; - } - - m_borderShaderMatrixLocation = m_context->getUniformLocation(m_borderShaderProgram, "matrix"); - m_borderShaderColorLocation = m_context->getUniformLocation(m_borderShaderProgram, "color"); - ASSERT(m_borderShaderMatrixLocation != -1); - ASSERT(m_borderShaderColorLocation != -1); - - m_initialized = true; -} - -LayerChromium::SharedValues::~SharedValues() -{ - GLC(m_context, m_context->deleteBuffer(m_quadVerticesVbo)); - GLC(m_context, m_context->deleteBuffer(m_quadElementsVbo)); - if (m_borderShaderProgram) - GLC(m_context, m_context->deleteProgram(m_borderShaderProgram)); -} - +#ifndef NDEBUG +static int s_nextLayerDebugID = 1; +#endif PassRefPtr<LayerChromium> LayerChromium::create(GraphicsLayerChromium* owner) { @@ -144,25 +62,22 @@ LayerChromium::LayerChromium(GraphicsLayerChromium* owner) : m_owner(owner) , m_contentsDirty(false) , m_maskLayer(0) - , m_targetRenderSurface(0) , m_superlayer(0) +#ifndef NDEBUG + , m_debugID(s_nextLayerDebugID++) +#endif , m_anchorPoint(0.5, 0.5) , m_backgroundColor(0, 0, 0, 0) - , m_borderColor(0, 0, 0, 0) , m_opacity(1.0) , m_zPosition(0.0) , m_anchorPointZ(0) - , m_borderWidth(0) , m_clearsContext(false) - , m_doubleSided(true) , m_hidden(false) , m_masksToBounds(false) , m_opaque(true) , m_geometryFlipped(false) , m_needsDisplayOnBoundsChange(false) - , m_drawDepth(0) - , m_layerRenderer(0) - , m_renderSurface(0) + , m_ccLayerImpl(CCLayerImpl::create(this)) , m_replicaLayer(0) { } @@ -179,8 +94,7 @@ LayerChromium::~LayerChromium() void LayerChromium::cleanupResources() { - if (m_renderSurface) - m_renderSurface->cleanupResources(); + m_ccLayerImpl->cleanupResources(); } void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer) @@ -192,55 +106,7 @@ void LayerChromium::setLayerRenderer(LayerRendererChromium* renderer) setNeedsDisplay(); } - m_layerRenderer = renderer; -} - -RenderSurfaceChromium* LayerChromium::createRenderSurface() -{ - m_renderSurface = new RenderSurfaceChromium(this); - return m_renderSurface.get(); -} - -unsigned LayerChromium::createShaderProgram(GraphicsContext3D* context, const char* vertexShaderSource, const char* fragmentShaderSource) -{ - unsigned vertexShader = loadShader(context, GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); - if (!vertexShader) { - LOG_ERROR("Failed to create vertex shader"); - return 0; - } - - unsigned fragmentShader = loadShader(context, GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); - if (!fragmentShader) { - GLC(context, context->deleteShader(vertexShader)); - LOG_ERROR("Failed to create fragment shader"); - return 0; - } - - unsigned programObject = context->createProgram(); - if (!programObject) { - LOG_ERROR("Failed to create shader program"); - return 0; - } - - GLC(context, context->attachShader(programObject, vertexShader)); - GLC(context, context->attachShader(programObject, fragmentShader)); - - // Bind the common attrib locations. - GLC(context, context->bindAttribLocation(programObject, s_positionAttribLocation, "a_position")); - GLC(context, context->bindAttribLocation(programObject, s_texCoordAttribLocation, "a_texCoord")); - - GLC(context, context->linkProgram(programObject)); - int linked = 0; - GLC(context, context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked)); - if (!linked) { - LOG_ERROR("Failed to link shader program"); - GLC(context, context->deleteProgram(programObject)); - return 0; - } - - GLC(context, context->deleteShader(vertexShader)); - GLC(context, context->deleteShader(fragmentShader)); - return programObject; + m_ccLayerImpl->setLayerRenderer(renderer); } void LayerChromium::setNeedsCommit() @@ -317,16 +183,15 @@ int LayerChromium::indexOfSublayer(const LayerChromium* reference) void LayerChromium::setBounds(const IntSize& size) { - if (m_bounds == size) + if (bounds() == size) return; - bool firstResize = !m_bounds.width() && !m_bounds.height() && size.width() && size.height(); + bool firstResize = !bounds().width() && !bounds().height() && size.width() && size.height(); - m_bounds = size; - m_backingStoreSize = size; + m_ccLayerImpl->setBounds(size); if (firstResize) - setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height())); + setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height())); else setNeedsCommit(); } @@ -337,7 +202,7 @@ void LayerChromium::setFrame(const FloatRect& rect) return; m_frame = rect; - setNeedsDisplay(FloatRect(0, 0, m_bounds.width(), m_bounds.height())); + setNeedsDisplay(FloatRect(0, 0, bounds().width(), bounds().height())); } const LayerChromium* LayerChromium::rootLayer() const @@ -372,6 +237,12 @@ LayerChromium* LayerChromium::superlayer() const return m_superlayer; } +void LayerChromium::setName(const String& name) +{ + m_name = name; + m_ccLayerImpl->setName(name); +} + void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect) { // Simply mark the contents as dirty. For non-root layers, the call to @@ -386,7 +257,7 @@ void LayerChromium::setNeedsDisplay(const FloatRect& dirtyRect) void LayerChromium::setNeedsDisplay() { m_dirtyRect.setLocation(FloatPoint()); - m_dirtyRect.setSize(m_bounds); + m_dirtyRect.setSize(bounds()); m_contentsDirty = true; setNeedsCommit(); } @@ -445,38 +316,7 @@ void LayerChromium::drawTexturedQuad(GraphicsContext3D* context, const Transform GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); } -void LayerChromium::drawDebugBorder() -{ - static float glMatrix[16]; - if (!borderColor().alpha()) - return; - - ASSERT(layerRenderer()); - const SharedValues* sv = layerRenderer()->layerSharedValues(); - ASSERT(sv && sv->initialized()); - layerRenderer()->useShader(sv->borderShaderProgram()); - TransformationMatrix renderMatrix = drawTransform(); - renderMatrix.scale3d(bounds().width(), bounds().height(), 1); - toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix); - GraphicsContext3D* context = layerRendererContext(); - GLC(context, context->uniformMatrix4fv(sv->borderShaderMatrixLocation(), false, &glMatrix[0], 1)); - - GLC(context, context->uniform4f(sv->borderShaderColorLocation(), borderColor().red() / 255.0, borderColor().green() / 255.0, borderColor().blue() / 255.0, 1)); - GLC(context, context->lineWidth(borderWidth())); - - // The indices for the line are stored in the same array as the triangle indices. - GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); -} - -const IntRect LayerChromium::getDrawRect() const -{ - // Form the matrix used by the shader to map the corners of the layer's - // bounds into the view space. - FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height()); - IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect)); - return mappedRect; -} // Returns true if any of the layer's descendants has drawable content. bool LayerChromium::descendantsDrawContent() @@ -501,19 +341,92 @@ bool LayerChromium::descendantsDrawContentRecursive() return false; } -// static -void LayerChromium::prepareForDraw(const SharedValues* sv) +String LayerChromium::layerTreeAsText() const +{ + TextStream ts; + dumpLayer(ts, 0); + return ts.release(); +} + +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void LayerChromium::dumpLayer(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); + ts << layerTypeAsString() << "(" << m_name << ")\n"; + dumpLayerProperties(ts, indent+2); + m_ccLayerImpl->dumpLayerProperties(ts, indent+2); + if (m_replicaLayer) { + writeIndent(ts, indent+2); + ts << "Replica:\n"; + m_replicaLayer->dumpLayer(ts, indent+3); + } + if (m_maskLayer) { + writeIndent(ts, indent+2); + ts << "Mask:\n"; + m_maskLayer->dumpLayer(ts, indent+3); + } + for (size_t i = 0; i < m_sublayers.size(); ++i) + m_sublayers[i]->dumpLayer(ts, indent+1); +} + +void LayerChromium::dumpLayerProperties(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); +#ifndef NDEBUG + ts << "debugID: " << debugID() << ", "; +#else +#endif + ts << "drawsContent: " << drawsContent() << "\n"; + +} + +// Begin calls that forward to the CCLayerImpl. +// ============================================== +// These exists just for debugging (via drawDebugBorder()). +void LayerChromium::setBorderColor(const Color& color) +{ + m_ccLayerImpl->setDebugBorderColor(color); + setNeedsCommit(); +} + +Color LayerChromium::borderColor() const +{ + return m_ccLayerImpl->debugBorderColor(); +} + +void LayerChromium::setBorderWidth(float width) +{ + m_ccLayerImpl->setDebugBorderWidth(width); + setNeedsCommit(); +} + +float LayerChromium::borderWidth() const +{ + return m_ccLayerImpl->debugBorderWidth(); +} + +LayerRendererChromium* LayerChromium::layerRenderer() const +{ + return m_ccLayerImpl->layerRenderer(); +} + +void LayerChromium::setDoubleSided(bool doubleSided) +{ + m_ccLayerImpl->setDoubleSided(doubleSided); + setNeedsCommit(); +} + +const IntSize& LayerChromium::bounds() const { - GraphicsContext3D* context = sv->context(); - GLC(context, context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, sv->quadVerticesVbo())); - GLC(context, context->bindBuffer(GraphicsContext3D::ELEMENT_ARRAY_BUFFER, sv->quadElementsVbo())); - unsigned offset = 0; - GLC(context, context->vertexAttribPointer(s_positionAttribLocation, 3, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); - offset += 3 * sizeof(float); - GLC(context, context->vertexAttribPointer(s_texCoordAttribLocation, 2, GraphicsContext3D::FLOAT, false, 5 * sizeof(float), offset)); - GLC(context, context->enableVertexAttribArray(s_positionAttribLocation)); - GLC(context, context->enableVertexAttribArray(s_texCoordAttribLocation)); + return m_ccLayerImpl->bounds(); } +// ============================================== +// End calls that forward to the CCLayerImpl. } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/LayerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerChromium.h index 5c7e2b1..29a2165 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerChromium.h @@ -38,13 +38,17 @@ #include "GraphicsContext.h" #include "GraphicsLayerChromium.h" #include "PlatformString.h" +#include "ProgramBinding.h" #include "RenderSurfaceChromium.h" +#include "ShaderChromium.h" #include "TransformationMatrix.h" + #include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/Vector.h> #include <wtf/text/StringHash.h> +#include <wtf/text/WTFString.h> namespace skia { @@ -53,13 +57,13 @@ class PlatformCanvas; namespace WebCore { +class CCLayerImpl; class GraphicsContext3D; class LayerRendererChromium; // Base class for composited layers. Special layer types are derived from // this class. class LayerChromium : public RefCounted<LayerChromium> { - friend class LayerRendererChromium; friend class LayerTilerChromium; public: static PassRefPtr<LayerChromium> create(GraphicsLayerChromium* owner = 0); @@ -85,21 +89,9 @@ public: void setBackgroundColor(const Color& color) { m_backgroundColor = color; setNeedsCommit(); } Color backgroundColor() const { return m_backgroundColor; } - void setBorderColor(const Color& color) { m_borderColor = color; setNeedsCommit(); } - Color borderColor() const { return m_borderColor; } - - void setBorderWidth(float width) { m_borderWidth = width; setNeedsCommit(); } - float borderWidth() const { return m_borderWidth; } - - void setBounds(const IntSize&); - IntSize bounds() const { return m_bounds; } - void setClearsContext(bool clears) { m_clearsContext = clears; setNeedsCommit(); } bool clearsContext() const { return m_clearsContext; } - void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; setNeedsCommit(); } - bool doubleSided() const { return m_doubleSided; } - void setFrame(const FloatRect&); FloatRect frame() const { return m_frame; } @@ -109,10 +101,11 @@ public: void setMasksToBounds(bool masksToBounds) { m_masksToBounds = masksToBounds; } bool masksToBounds() const { return m_masksToBounds; } - void setName(const String& name) { m_name = name; } - String name() const { return m_name; } + void setName(const String&); + const String& name() const { return m_name; } void setMaskLayer(LayerChromium* maskLayer) { m_maskLayer = maskLayer; } + CCLayerImpl* maskDrawLayer() const { return m_maskLayer ? m_maskLayer->ccLayerImpl() : 0; } LayerChromium* maskLayer() const { return m_maskLayer.get(); } void setNeedsDisplay(const FloatRect& dirtyRect); @@ -144,75 +137,60 @@ public: void setGeometryFlipped(bool flipped) { m_geometryFlipped = flipped; setNeedsCommit(); } bool geometryFlipped() const { return m_geometryFlipped; } - const TransformationMatrix& drawTransform() const { return m_drawTransform; } - float drawOpacity() const { return m_drawOpacity; } - bool preserves3D() { return m_owner && m_owner->preserves3D(); } // Derived types must override this method if they need to react to a change // in the LayerRendererChromium. virtual void setLayerRenderer(LayerRendererChromium*); + // Returns true if any of the layer's descendants has content to draw. + bool descendantsDrawContent(); + void setOwner(GraphicsLayerChromium* owner) { m_owner = owner; } void setReplicaLayer(LayerChromium* layer) { m_replicaLayer = layer; } LayerChromium* replicaLayer() { return m_replicaLayer; } - // Returns the rect containtaining this layer in the current view's coordinate system. - const IntRect getDrawRect() const; - // These methods typically need to be overwritten by derived classes. - virtual bool drawsContent() { return false; } + virtual bool drawsContent() const { return false; } virtual void updateContentsIfDirty() { } virtual void unreserveContentsTexture() { } virtual void bindContentsTexture() { } virtual void draw() { } + // These exists just for debugging (via drawDebugBorder()). + void setBorderColor(const Color&); + Color borderColor() const; + +#ifndef NDEBUG + int debugID() const { return m_debugID; } +#endif + void drawDebugBorder(); + String layerTreeAsText() const; + + void setBorderWidth(float); + float borderWidth() const; + + // Everything from here down in the public section will move to CCLayerImpl. - RenderSurfaceChromium* createRenderSurface(); - - // Stores values that are shared between instances of this class that are - // associated with the same LayerRendererChromium (and hence the same GL - // context). - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - GraphicsContext3D* context() const { return m_context; } - unsigned quadVerticesVbo() const { return m_quadVerticesVbo; } - unsigned quadElementsVbo() const { return m_quadElementsVbo; } - int maxTextureSize() const { return m_maxTextureSize; } - unsigned borderShaderProgram() const { return m_borderShaderProgram; } - int borderShaderMatrixLocation() const { return m_borderShaderMatrixLocation; } - int borderShaderColorLocation() const { return m_borderShaderColorLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_quadVerticesVbo; - unsigned m_quadElementsVbo; - int m_maxTextureSize; - unsigned m_borderShaderProgram; - int m_borderShaderMatrixLocation; - int m_borderShaderColorLocation; - bool m_initialized; - }; - - static void prepareForDraw(const SharedValues*); - - LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); } - - static unsigned createShaderProgram(GraphicsContext3D*, const char* vertexShaderSource, const char* fragmentShaderSource); + CCLayerImpl* ccLayerImpl() const { return m_ccLayerImpl.get(); } static void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& layerMatrix, float width, float height, float opacity, int matrixLocation, int alphaLocation); + // Begin calls that forward to the CCLayerImpl. + LayerRendererChromium* layerRenderer() const; + void setDoubleSided(bool); + void setBounds(const IntSize&); + const IntSize& bounds() const; + // End calls that forward to the CCLayerImpl. + + typedef ProgramBinding<VertexShaderPos, FragmentShaderColor> BorderProgram; protected: GraphicsLayerChromium* m_owner; - LayerChromium(GraphicsLayerChromium* owner); + explicit LayerChromium(GraphicsLayerChromium* owner); // This is called to clean up resources being held in the same context as // layerRendererContext(). Subclasses should override this method if they @@ -221,23 +199,18 @@ protected: GraphicsContext3D* layerRendererContext() const; - // Returns true if any of the layer's descendants has content to draw. - bool descendantsDrawContent(); - static void toGLMatrix(float*, const TransformationMatrix&); - IntSize m_bounds; + void dumpLayer(TextStream&, int indent) const; + + virtual const char* layerTypeAsString() const { return "LayerChromium"; } + virtual void dumpLayerProperties(TextStream&, int indent) const; + FloatRect m_dirtyRect; bool m_contentsDirty; RefPtr<LayerChromium> m_maskLayer; - // Render surface this layer draws into. This is a surface that can belong - // either to this layer (if m_targetRenderSurface == m_renderSurface) or - // to an ancestor of this layer. The target render surface determines the - // coordinate system the layer's transforms are relative to. - RenderSurfaceChromium* m_targetRenderSurface; - // All layer shaders share the same attribute locations for the vertex positions // and texture coordinates. This allows switching shaders without rebinding attribute // arrays. @@ -265,48 +238,30 @@ private: Vector<RefPtr<LayerChromium> > m_sublayers; LayerChromium* m_superlayer; +#ifndef NDEBUG + int m_debugID; +#endif + // Layer properties. - IntSize m_backingStoreSize; FloatPoint m_position; FloatPoint m_anchorPoint; Color m_backgroundColor; - Color m_borderColor; float m_opacity; float m_zPosition; float m_anchorPointZ; - float m_borderWidth; - float m_drawOpacity; bool m_clearsContext; - bool m_doubleSided; bool m_hidden; bool m_masksToBounds; bool m_opaque; bool m_geometryFlipped; bool m_needsDisplayOnBoundsChange; - // The global depth value of the center of the layer. This value is used - // to sort layers from back to front. - float m_drawDepth; - - // Points to the layer renderer that updates and draws this layer. - RefPtr<LayerRendererChromium> m_layerRenderer; - - FloatRect m_frame; TransformationMatrix m_transform; TransformationMatrix m_sublayerTransform; - TransformationMatrix m_drawTransform; - - // The scissor rectangle that should be used when this layer is drawn. - // Inherited by the parent layer and further restricted if this layer masks - // to bounds. - IntRect m_scissorRect; - // Render surface associated with this layer. The layer and its descendants - // will render to this surface. - OwnPtr<RenderSurfaceChromium> m_renderSurface; - - // Hierarchical bounding rect containing the layer and its descendants. - IntRect m_drawableContentRect; + FloatRect m_frame; + // For now, the LayerChromium directly owns its CCLayerImpl. + RefPtr<CCLayerImpl> m_ccLayerImpl; // Replica layer used for reflections. LayerChromium* m_replicaLayer; diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index f5548c9..e7b299f 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -34,14 +34,18 @@ #if USE(ACCELERATED_COMPOSITING) #include "LayerRendererChromium.h" +#include "cc/CCLayerImpl.h" #include "Canvas2DLayerChromium.h" +#include "GeometryBinding.h" #include "GraphicsContext3D.h" #include "LayerChromium.h" #include "LayerTexture.h" #include "NotImplemented.h" +#include "TextStream.h" #include "TextureManager.h" #include "WebGLLayerChromium.h" -#if PLATFORM(SKIA) +#include "cc/CCLayerImpl.h" +#if USE(SKIA) #include "NativeImageSkia.h" #include "PlatformContextSkia.h" #elif PLATFORM(CG) @@ -82,9 +86,9 @@ static bool isScaleOrTranslation(const TransformationMatrix& m) } -bool LayerRendererChromium::compareLayerZ(const LayerChromium* a, const LayerChromium* b) +bool LayerRendererChromium::compareLayerZ(const CCLayerImpl* a, const CCLayerImpl* b) { - return a->m_drawDepth < b->m_drawDepth; + return a->drawDepth() < b->drawDepth(); } PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<GraphicsContext3D> context) @@ -100,9 +104,7 @@ PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(PassRefPtr<Graph } LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> context) - : m_rootLayerTextureWidth(0) - , m_rootLayerTextureHeight(0) - , m_rootLayer(0) + : m_rootLayer(0) , m_scrollPosition(IntPoint(-1, -1)) , m_currentShader(0) , m_currentRenderSurface(0) @@ -112,12 +114,15 @@ LayerRendererChromium::LayerRendererChromium(PassRefPtr<GraphicsContext3D> conte , m_defaultRenderSurface(0) { m_hardwareCompositing = initializeSharedObjects(); - m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256)); + m_rootLayerTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels); ASSERT(m_rootLayerTiler); + + m_headsUpDisplay = CCHeadsUpDisplay::create(this); } LayerRendererChromium::~LayerRendererChromium() { + m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies. cleanupSharedObjects(); } @@ -172,71 +177,125 @@ void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect, co } } -void LayerRendererChromium::updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect) +void LayerRendererChromium::updateRootLayerContents(TilePaintInterface& tilePaint, const IntRect& visibleRect) { m_rootLayerTiler->update(tilePaint, visibleRect); - m_rootLayerTiler->draw(visibleRect); +} +void LayerRendererChromium::updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect) +{ if (visibleRect.width() > contentRect.width()) { IntRect verticalScrollbar = verticalScrollbarRect(visibleRect, contentRect); IntSize tileSize = verticalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize)); if (!m_verticalScrollbarTiler) - m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize); + m_verticalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels); else m_verticalScrollbarTiler->setTileSize(tileSize); m_verticalScrollbarTiler->setLayerPosition(verticalScrollbar.location()); m_verticalScrollbarTiler->update(scrollbarPaint, visibleRect); - m_verticalScrollbarTiler->draw(visibleRect); - } + } else + m_verticalScrollbarTiler.clear(); if (visibleRect.height() > contentRect.height()) { IntRect horizontalScrollbar = horizontalScrollbarRect(visibleRect, contentRect); IntSize tileSize = horizontalScrollbar.size().shrunkTo(IntSize(m_maxTextureSize, m_maxTextureSize)); if (!m_horizontalScrollbarTiler) - m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize); + m_horizontalScrollbarTiler = LayerTilerChromium::create(this, tileSize, LayerTilerChromium::NoBorderTexels); else m_horizontalScrollbarTiler->setTileSize(tileSize); m_horizontalScrollbarTiler->setLayerPosition(horizontalScrollbar.location()); m_horizontalScrollbarTiler->update(scrollbarPaint, visibleRect); - m_horizontalScrollbarTiler->draw(visibleRect); - } + } else + m_horizontalScrollbarTiler.clear(); +} + +void LayerRendererChromium::drawRootLayer() +{ + m_rootLayerTiler->draw(m_visibleRect); + + if (m_verticalScrollbarTiler) + m_verticalScrollbarTiler->draw(m_visibleRect); + + if (m_horizontalScrollbarTiler) + m_horizontalScrollbarTiler->draw(m_visibleRect); } -void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect& contentRect, - const IntPoint& scrollPosition, TilePaintInterface& tilePaint, - TilePaintInterface& scrollbarPaint) +void LayerRendererChromium::updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint) { ASSERT(m_hardwareCompositing); if (!m_rootLayer) return; - makeContextCurrent(); + updateRootLayerContents(tilePaint, visibleRect); + // Recheck that we still have a root layer. This may become null if + // compositing gets turned off during a paint operation. + if (!m_rootLayer) + return; + + updateRootLayerScrollbars(scrollbarPaint, visibleRect, contentRect); + + Vector<CCLayerImpl*> renderSurfaceLayerList; + updateLayers(visibleRect, contentRect, scrollPosition, renderSurfaceLayerList); + + drawLayers(renderSurfaceLayerList); +} + +void LayerRendererChromium::updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + Vector<CCLayerImpl*>& renderSurfaceLayerList) +{ + CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); + + if (!rootDrawLayer->renderSurface()) + rootDrawLayer->createRenderSurface(); + ASSERT(rootDrawLayer->renderSurface()); // If the size of the visible area has changed then allocate a new texture // to store the contents of the root layer and adjust the projection matrix // and viewport. - int visibleRectWidth = visibleRect.width(); - int visibleRectHeight = visibleRect.height(); - - if (!m_rootLayer->m_renderSurface) - m_rootLayer->createRenderSurface(); - m_rootLayer->m_renderSurface->m_contentRect = IntRect(0, 0, visibleRectWidth, visibleRectHeight); - if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) { - m_rootLayerTextureWidth = visibleRectWidth; - m_rootLayerTextureHeight = visibleRectHeight; + rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), visibleRect.size()); + if (visibleRect.size() != m_visibleRect.size()) { // Reset the current render surface to force an update of the viewport and // projection matrix next time useRenderSurface is called. m_currentRenderSurface = 0; } + m_visibleRect = visibleRect; + + m_scrollPosition = scrollPosition; + // Scissor out the scrollbars to avoid rendering on top of them. + IntRect rootScissorRect(contentRect); + // The scissorRect should not include the scroll offset. + rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y()); + rootDrawLayer->setScissorRect(rootScissorRect); + + m_defaultRenderSurface = rootDrawLayer->renderSurface(); + + renderSurfaceLayerList.append(rootDrawLayer); + + TransformationMatrix identityMatrix; + m_defaultRenderSurface->m_layerList.clear(); + // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state + // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw + // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the + // concept of a large content layer. + updatePropertiesAndRenderSurfaces(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList); + + updateContentsRecursive(m_rootLayer.get()); +} + +void LayerRendererChromium::drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList) +{ + CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); + makeContextCurrent(); // The GL viewport covers the entire visible area, including the scrollbars. - GLC(m_context.get(), m_context->viewport(0, 0, visibleRectWidth, visibleRectHeight)); + GLC(m_context.get(), m_context->viewport(0, 0, m_visibleRect.width(), m_visibleRect.height())); // Bind the common vertex attributes used for drawing all the layers. - LayerChromium::prepareForDraw(layerSharedValues()); + m_sharedGeometry->prepareForDraw(); // FIXME: These calls can be made once, when the compositor context is initialized. GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST)); @@ -245,11 +304,6 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType. GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); - m_scrollPosition = scrollPosition; - - ASSERT(m_rootLayer->m_renderSurface); - m_defaultRenderSurface = m_rootLayer->m_renderSurface.get(); - useRenderSurface(m_defaultRenderSurface); // Clear to blue to make it easier to spot unrendered regions. @@ -260,66 +314,49 @@ void LayerRendererChromium::drawLayers(const IntRect& visibleRect, const IntRect // zero alpha values on text glyphs. The root layer is always opaque. m_context->colorMask(true, true, true, false); - updateAndDrawRootLayer(tilePaint, scrollbarPaint, visibleRect, contentRect); + drawRootLayer(); // Re-enable color writes to layers, which may be partially transparent. m_context->colorMask(true, true, true, true); - // Recheck that we still have a root layer. This may become null if - // compositing gets turned off during a paint operation. - if (!m_rootLayer) - return; - - // Set the root visible/content rects --- used by subsequent drawLayers calls. - m_rootVisibleRect = visibleRect; - m_rootContentRect = contentRect; - - // Scissor out the scrollbars to avoid rendering on top of them. - IntRect rootScissorRect(contentRect); - // The scissorRect should not include the scroll offset. - rootScissorRect.move(-m_scrollPosition.x(), -m_scrollPosition.y()); - m_rootLayer->m_scissorRect = rootScissorRect; - - Vector<LayerChromium*> renderSurfaceLayerList; - renderSurfaceLayerList.append(m_rootLayer.get()); - - TransformationMatrix identityMatrix; - m_defaultRenderSurface->m_layerList.clear(); - updateLayersRecursive(m_rootLayer.get(), identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList); - - // The shader used to render layers returns pre-multiplied alpha colors - // so we need to send the blending mode appropriately. GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); - GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); // Update the contents of the render surfaces. We traverse the array from // back to front to guarantee that nested render surfaces get rendered in the // correct order. for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { - LayerChromium* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; - ASSERT(renderSurfaceLayer->m_renderSurface); + CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex]; + ASSERT(renderSurfaceLayer->renderSurface()); // Render surfaces whose drawable area has zero width or height // will have no layers associated with them and should be skipped. - if (!renderSurfaceLayer->m_renderSurface->m_layerList.size()) + if (!renderSurfaceLayer->renderSurface()->m_layerList.size()) continue; - if (useRenderSurface(renderSurfaceLayer->m_renderSurface.get())) { - if (renderSurfaceLayer != m_rootLayer) { + if (useRenderSurface(renderSurfaceLayer->renderSurface())) { + if (renderSurfaceLayer != rootDrawLayer) { GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0)); GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT)); GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); } - Vector<LayerChromium*>& layerList = renderSurfaceLayer->m_renderSurface->m_layerList; + Vector<CCLayerImpl*>& layerList = renderSurfaceLayer->renderSurface()->m_layerList; ASSERT(layerList.size()); for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) - drawLayer(layerList[layerIndex], renderSurfaceLayer->m_renderSurface.get()); + drawLayer(layerList[layerIndex], renderSurfaceLayer->renderSurface()); } } + if (m_headsUpDisplay->enabled()) { + GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); + GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); + GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); + useRenderSurface(m_defaultRenderSurface); + m_headsUpDisplay->draw(); + } + GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); } @@ -336,11 +373,15 @@ void LayerRendererChromium::present() // Note that currently this has the same effect as swapBuffers; we should // consider exposing a different entry point on GraphicsContext3D. m_context->prepareTexture(); + + m_headsUpDisplay->onPresent(); } void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) { m_rootLayer = layer; + if (m_rootLayer) + m_rootLayer->setLayerRenderer(this); m_rootLayerTiler->invalidateEntireLayer(); if (m_horizontalScrollbarTiler) m_horizontalScrollbarTiler->invalidateEntireLayer(); @@ -350,8 +391,7 @@ void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect) { - ASSERT(rect.maxX() <= rootLayerTextureSize().width() - && rect.maxY() <= rootLayerTextureSize().height()); + ASSERT(rect.maxX() <= visibleRectSize().width() && rect.maxY() <= visibleRectSize().height()); if (!pixels) return; @@ -404,9 +444,10 @@ bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const Transform // Recursively walks the layer tree starting at the given node and computes all the // necessary transformations, scissor rectangles, render surfaces, etc. -void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList) +void LayerRendererChromium::updatePropertiesAndRenderSurfaces(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList) { layer->setLayerRenderer(this); + CCLayerImpl* drawLayer = layer->ccLayerImpl(); // Compute the new matrix transformation that will be applied to this layer and // all its sublayers. It's important to remember that the layer's position @@ -459,25 +500,26 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // of their parent. bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform); bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D(); - bool useSurfaceForMasking = layer->maskLayer(); + bool useSurfaceForMasking = layer->maskDrawLayer(); bool useSurfaceForReflection = layer->replicaLayer(); if (((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawContent()) || useSurfaceForMasking || useSurfaceForReflection) { - RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get(); + RenderSurfaceChromium* renderSurface = drawLayer->renderSurface(); if (!renderSurface) - renderSurface = layer->createRenderSurface(); + renderSurface = drawLayer->createRenderSurface(); // The origin of the new surface is the upper left corner of the layer. - layer->m_drawTransform = TransformationMatrix(); - layer->m_drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0); + TransformationMatrix drawTransform; + drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0); + drawLayer->setDrawTransform(drawTransform); transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height()); // Layer's opacity will be applied when drawing the render surface. renderSurface->m_drawOpacity = layer->opacity(); - if (layer->superlayer()->preserves3D()) - renderSurface->m_drawOpacity *= layer->superlayer()->drawOpacity(); - layer->m_drawOpacity = 1; + if (layer->superlayer() && layer->superlayer()->preserves3D()) + renderSurface->m_drawOpacity *= drawLayer->superlayer()->drawOpacity(); + drawLayer->setDrawOpacity(1); TransformationMatrix layerOriginTransform = combinedTransform; layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0); @@ -485,69 +527,72 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr if (layerOriginTransform.isInvertible() && layer->superlayer()) { TransformationMatrix parentToLayer = layerOriginTransform.inverse(); - layer->m_scissorRect = parentToLayer.mapRect(layer->superlayer()->m_scissorRect); + drawLayer->setScissorRect(parentToLayer.mapRect(drawLayer->superlayer()->scissorRect())); } else - layer->m_scissorRect = IntRect(); + drawLayer->setScissorRect(IntRect()); // The render surface scissor rect is the scissor rect that needs to // be applied before drawing the render surface onto its containing // surface and is therefore expressed in the superlayer's coordinate system. - renderSurface->m_scissorRect = layer->superlayer()->m_scissorRect; + renderSurface->m_scissorRect = drawLayer->superlayer() ? drawLayer->superlayer()->scissorRect() : drawLayer->scissorRect(); renderSurface->m_layerList.clear(); - if (layer->maskLayer()) { - renderSurface->m_maskLayer = layer->maskLayer(); - layer->maskLayer()->setLayerRenderer(this); - layer->maskLayer()->m_targetRenderSurface = renderSurface; + if (layer->maskDrawLayer()) { + renderSurface->m_maskLayer = layer->maskDrawLayer(); + layer->maskDrawLayer()->setLayerRenderer(this); + layer->maskDrawLayer()->setTargetRenderSurface(renderSurface); } else renderSurface->m_maskLayer = 0; - if (layer->replicaLayer() && layer->replicaLayer()->maskLayer()) { - layer->replicaLayer()->maskLayer()->setLayerRenderer(this); - layer->replicaLayer()->maskLayer()->m_targetRenderSurface = renderSurface; + if (layer->replicaLayer() && layer->replicaLayer()->maskDrawLayer()) { + layer->replicaLayer()->maskDrawLayer()->setLayerRenderer(this); + layer->replicaLayer()->maskDrawLayer()->setTargetRenderSurface(renderSurface); } - renderSurfaceLayerList.append(layer); + renderSurfaceLayerList.append(drawLayer); } else { // DT = M[p] * LT - layer->m_drawTransform = combinedTransform; - transformedLayerRect = enclosingIntRect(layer->m_drawTransform.mapRect(layerRect)); + drawLayer->setDrawTransform(combinedTransform); + transformedLayerRect = enclosingIntRect(drawLayer->drawTransform().mapRect(layerRect)); - layer->m_drawOpacity = layer->opacity(); + drawLayer->setDrawOpacity(layer->opacity()); if (layer->superlayer()) { if (layer->superlayer()->preserves3D()) - layer->m_drawOpacity *= layer->superlayer()->m_drawOpacity; + drawLayer->setDrawOpacity(drawLayer->drawOpacity() * drawLayer->superlayer()->drawOpacity()); // Layers inherit the scissor rect from their superlayer. - layer->m_scissorRect = layer->superlayer()->m_scissorRect; + drawLayer->setScissorRect(drawLayer->superlayer()->scissorRect()); - layer->m_targetRenderSurface = layer->superlayer()->m_targetRenderSurface; + drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface()); } if (layer != m_rootLayer) - layer->m_renderSurface = 0; + drawLayer->clearRenderSurface(); - if (layer->masksToBounds()) - layer->m_scissorRect.intersect(transformedLayerRect); + if (layer->masksToBounds()) { + IntRect scissor = drawLayer->scissorRect(); + scissor.intersect(transformedLayerRect); + drawLayer->setScissorRect(scissor); + } } - if (layer->m_renderSurface) - layer->m_targetRenderSurface = layer->m_renderSurface.get(); + if (drawLayer->renderSurface()) + drawLayer->setTargetRenderSurface(drawLayer->renderSurface()); else { ASSERT(layer->superlayer()); - layer->m_targetRenderSurface = layer->superlayer()->m_targetRenderSurface; + drawLayer->setTargetRenderSurface(drawLayer->superlayer()->targetRenderSurface()); } - // m_drawableContentRect is always stored in the coordinate system of the + // drawableContentRect() is always stored in the coordinate system of the // RenderSurface the layer draws into. - if (layer->drawsContent()) - layer->m_drawableContentRect = transformedLayerRect; + if (drawLayer->drawsContent()) + drawLayer->setDrawableContentRect(transformedLayerRect); else - layer->m_drawableContentRect = IntRect(); + drawLayer->setDrawableContentRect(IntRect()); - TransformationMatrix sublayerMatrix = layer->m_drawTransform; + TransformationMatrix sublayerMatrix = drawLayer->drawTransform(); // Flatten to 2D if the layer doesn't preserve 3D. if (!layer->preserves3D()) { @@ -568,37 +613,46 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // M[s] = M * Tr[-center] sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0); - Vector<LayerChromium*>& descendants = (layer->m_renderSurface ? layer->m_renderSurface->m_layerList : layerList); - descendants.append(layer); + Vector<CCLayerImpl*>& descendants = (drawLayer->renderSurface() ? drawLayer->renderSurface()->m_layerList : layerList); + descendants.append(drawLayer); unsigned thisLayerIndex = descendants.size() - 1; const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers(); for (size_t i = 0; i < sublayers.size(); ++i) { - LayerChromium* sublayer = sublayers[i].get(); - updateLayersRecursive(sublayer, sublayerMatrix, renderSurfaceLayerList, descendants); - - if (sublayer->m_renderSurface) { - RenderSurfaceChromium* sublayerRenderSurface = sublayer->m_renderSurface.get(); - layer->m_drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect())); + CCLayerImpl* sublayer = sublayers[i]->ccLayerImpl(); + updatePropertiesAndRenderSurfaces(sublayers[i].get(), sublayerMatrix, renderSurfaceLayerList, descendants); + + if (sublayer->renderSurface()) { + RenderSurfaceChromium* sublayerRenderSurface = sublayer->renderSurface(); + IntRect drawableContentRect = drawLayer->drawableContentRect(); + drawableContentRect.unite(enclosingIntRect(sublayerRenderSurface->drawableContentRect())); + drawLayer->setDrawableContentRect(drawableContentRect); descendants.append(sublayer); - } else - layer->m_drawableContentRect.unite(sublayer->m_drawableContentRect); + } else { + IntRect drawableContentRect = drawLayer->drawableContentRect(); + drawableContentRect.unite(sublayer->drawableContentRect()); + drawLayer->setDrawableContentRect(drawableContentRect); + } } - if (layer->masksToBounds() || useSurfaceForMasking) - layer->m_drawableContentRect.intersect(transformedLayerRect); + if (layer->masksToBounds() || useSurfaceForMasking) { + IntRect drawableContentRect = drawLayer->drawableContentRect(); + drawableContentRect.intersect(transformedLayerRect); + drawLayer->setDrawableContentRect(drawableContentRect); + } - if (layer->m_renderSurface && layer != m_rootLayer) { - RenderSurfaceChromium* renderSurface = layer->m_renderSurface.get(); - renderSurface->m_contentRect = layer->m_drawableContentRect; + if (drawLayer->renderSurface() && layer != m_rootLayer) { + RenderSurfaceChromium* renderSurface = drawLayer->renderSurface(); + renderSurface->m_contentRect = drawLayer->drawableContentRect(); FloatPoint surfaceCenter = renderSurface->contentRectCenter(); // Restrict the RenderSurface size to the portion that's visible. FloatSize centerOffsetDueToClipping; + // Don't clip if the layer is reflected as the reflection shouldn't be // clipped. if (!layer->replicaLayer()) { - renderSurface->m_contentRect.intersect(layer->m_scissorRect); + renderSurface->m_contentRect.intersect(drawLayer->scissorRect()); FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter(); centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter; } @@ -613,7 +667,7 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // Since the layer starts a new render surface we need to adjust its // scissor rect to be expressed in the new surface's coordinate system. - layer->m_scissorRect = layer->m_drawableContentRect; + drawLayer->setScissorRect(drawLayer->drawableContentRect()); // Adjust the origin of the transform to be the center of the render surface. renderSurface->m_drawTransform = renderSurface->m_originTransform; @@ -631,14 +685,14 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr // Compute the depth value of the center of the layer which will be used when // sorting the layers for the preserves-3d property. - TransformationMatrix& layerDrawMatrix = layer->m_renderSurface ? layer->m_renderSurface->m_drawTransform : layer->m_drawTransform; + const TransformationMatrix& layerDrawMatrix = drawLayer->renderSurface() ? drawLayer->renderSurface()->m_drawTransform : drawLayer->drawTransform(); if (layer->superlayer()) { if (!layer->superlayer()->preserves3D()) - layer->m_drawDepth = layer->superlayer()->m_drawDepth; + drawLayer->setDrawDepth(drawLayer->superlayer()->drawDepth()); else - layer->m_drawDepth = layerDrawMatrix.m43(); + drawLayer->setDrawDepth(layerDrawMatrix.m43()); } else - layer->m_drawDepth = 0; + drawLayer->setDrawDepth(0); // If preserves-3d then sort all the descendants by the Z coordinate of their // center. If the preserves-3d property is also set on the superlayer then @@ -647,21 +701,50 @@ void LayerRendererChromium::updateLayersRecursive(LayerChromium* layer, const Tr std::stable_sort(&descendants.at(thisLayerIndex), descendants.end(), compareLayerZ); } +void LayerRendererChromium::updateContentsRecursive(LayerChromium* layer) +{ + const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers(); + for (size_t i = 0; i < sublayers.size(); ++i) + updateContentsRecursive(sublayers[i].get()); + + if (layer->drawsContent()) + layer->updateContentsIfDirty(); + if (layer->maskLayer() && layer->maskLayer()->drawsContent()) + layer->maskLayer()->updateContentsIfDirty(); + if (layer->replicaLayer() && layer->replicaLayer()->drawsContent()) + layer->replicaLayer()->updateContentsIfDirty(); + if (layer->replicaLayer() && layer->replicaLayer()->maskLayer() && layer->replicaLayer()->maskLayer()->drawsContent()) + layer->replicaLayer()->maskLayer()->updateContentsIfDirty(); +} + void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen) { + if (m_compositeOffscreen == compositeOffscreen) + return; + m_compositeOffscreen = compositeOffscreen; - if (!m_rootLayer) { - m_compositeOffscreen = false; - return; - } + if (!m_compositeOffscreen && m_rootLayer) + m_rootLayer->ccLayerImpl()->clearRenderSurface(); +} + +LayerTexture* LayerRendererChromium::getOffscreenLayerTexture() +{ + return m_compositeOffscreen ? m_rootLayer->ccLayerImpl()->renderSurface()->m_contentsTexture.get() : 0; +} +void LayerRendererChromium::copyOffscreenTextureToDisplay() +{ if (m_compositeOffscreen) { - // Need to explicitly set a LayerRendererChromium for the layer with the offscreen texture, - // or else the call to prepareContentsTexture() in useRenderSurface() will fail. - m_rootLayer->setLayerRenderer(this); - } else - m_rootLayer->m_renderSurface.clear(); + makeContextCurrent(); + + useRenderSurface(0); + m_defaultRenderSurface->m_drawTransform.makeIdentity(); + m_defaultRenderSurface->m_drawTransform.translate3d(0.5 * m_defaultRenderSurface->m_contentRect.width(), + 0.5 * m_defaultRenderSurface->m_contentRect.height(), 0); + m_defaultRenderSurface->m_drawOpacity = 1; + m_defaultRenderSurface->draw(); + } } bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurface) @@ -671,9 +754,12 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac m_currentRenderSurface = renderSurface; - if (renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) { + if ((renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) || (!renderSurface && m_compositeOffscreen)) { GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0)); - setDrawViewportRect(renderSurface->m_contentRect, true); + if (renderSurface) + setDrawViewportRect(renderSurface->m_contentRect, true); + else + setDrawViewportRect(m_defaultRenderSurface->m_contentRect, true); return true; } @@ -695,36 +781,32 @@ bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurfac return true; } -void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromium* targetSurface) +void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface) { - if (layer->m_renderSurface && layer->m_renderSurface != targetSurface) { - layer->m_renderSurface->draw(); + if (layer->renderSurface() && layer->renderSurface() != targetSurface) { + layer->renderSurface()->draw(); return; } - if (layer->m_bounds.isEmpty()) + if (layer->bounds().isEmpty()) return; - setScissorToRect(layer->m_scissorRect); + setScissorToRect(layer->scissorRect()); // Check if the layer falls within the visible bounds of the page. IntRect layerRect = layer->getDrawRect(); - bool isLayerVisible = layer->m_scissorRect.intersects(layerRect); + bool isLayerVisible = layer->scissorRect().intersects(layerRect); if (!isLayerVisible) return; // FIXME: Need to take into account the commulative render surface transforms all the way from // the default render surface in order to determine visibility. - TransformationMatrix combinedDrawMatrix = (layer->m_renderSurface ? layer->m_renderSurface->drawTransform().multiply(layer->m_drawTransform) : layer->m_drawTransform); + TransformationMatrix combinedDrawMatrix = (layer->renderSurface() ? layer->renderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform()); if (!layer->doubleSided() && combinedDrawMatrix.m33() < 0) return; - if (layer->drawsContent()) { - // Update the contents of the layer if necessary. - layer->updateContentsIfDirty(); - m_context->makeContextCurrent(); + if (layer->drawsContent()) layer->draw(); - } // Draw the debug border if there is one. layer->drawDebugBorder(); @@ -734,9 +816,11 @@ void LayerRendererChromium::drawLayer(LayerChromium* layer, RenderSurfaceChromiu // scissorRect has its origin at the top left corner of the current visible rect. void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect) { + IntRect contentRect = (m_currentRenderSurface ? m_currentRenderSurface->m_contentRect : m_defaultRenderSurface->m_contentRect); + // The scissor coordinates must be supplied in viewport space so we need to offset // by the relative position of the top left corner of the current render surface. - int scissorX = scissorRect.x() - m_currentRenderSurface->m_contentRect.x(); + int scissorX = scissorRect.x() - contentRect.x(); // When rendering to the default render surface we're rendering upside down so the top // of the GL scissor is the bottom of our layer. // But, if rendering to offscreen texture, we reverse our sense of 'upside down'. @@ -744,7 +828,7 @@ void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect) if (m_currentRenderSurface == m_defaultRenderSurface && !m_compositeOffscreen) scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.maxY() - m_currentRenderSurface->m_contentRect.y()); else - scissorY = scissorRect.y() - m_currentRenderSurface->m_contentRect.y(); + scissorY = scissorRect.y() - contentRect.y(); GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height())); } @@ -793,15 +877,23 @@ bool LayerRendererChromium::initializeSharedObjects() // Create an FBO for doing offscreen rendering. GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer()); - m_layerSharedValues = adoptPtr(new LayerChromium::SharedValues(m_context.get())); - m_contentLayerSharedValues = adoptPtr(new ContentLayerChromium::SharedValues(m_context.get())); - m_canvasLayerSharedValues = adoptPtr(new CanvasLayerChromium::SharedValues(m_context.get())); - m_videoLayerSharedValues = adoptPtr(new VideoLayerChromium::SharedValues(m_context.get())); - m_pluginLayerSharedValues = adoptPtr(new PluginLayerChromium::SharedValues(m_context.get())); - m_renderSurfaceSharedValues = adoptPtr(new RenderSurfaceChromium::SharedValues(m_context.get())); - - if (!m_layerSharedValues->initialized() || !m_contentLayerSharedValues->initialized() || !m_canvasLayerSharedValues->initialized() - || !m_videoLayerSharedValues->initialized() || !m_pluginLayerSharedValues->initialized() || !m_renderSurfaceSharedValues->initialized()) { + m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get())); + m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get())); + m_contentLayerProgram = adoptPtr(new ContentLayerChromium::Program(m_context.get())); + m_canvasLayerProgram = adoptPtr(new CanvasLayerChromium::Program(m_context.get())); + m_videoLayerRGBAProgram = adoptPtr(new VideoLayerChromium::RGBAProgram(m_context.get())); + m_videoLayerYUVProgram = adoptPtr(new VideoLayerChromium::YUVProgram(m_context.get())); + m_pluginLayerProgram = adoptPtr(new PluginLayerChromium::Program(m_context.get())); + m_renderSurfaceProgram = adoptPtr(new RenderSurfaceChromium::Program(m_context.get())); + m_renderSurfaceMaskProgram = adoptPtr(new RenderSurfaceChromium::MaskProgram(m_context.get())); + m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get())); + + if (!m_sharedGeometry->initialized() || !m_borderProgram->initialized() + || !m_contentLayerProgram->initialized() || !m_canvasLayerProgram->initialized() + || !m_videoLayerRGBAProgram->initialized() || !m_videoLayerYUVProgram->initialized() + || !m_pluginLayerProgram->initialized() || !m_renderSurfaceProgram->initialized() + || !m_renderSurfaceMaskProgram->initialized() || !m_tilerProgram->initialized()) { + LOG_ERROR("Compositor failed to initialize shaders. Falling back to software."); cleanupSharedObjects(); return false; } @@ -814,12 +906,16 @@ void LayerRendererChromium::cleanupSharedObjects() { makeContextCurrent(); - m_layerSharedValues.clear(); - m_contentLayerSharedValues.clear(); - m_canvasLayerSharedValues.clear(); - m_videoLayerSharedValues.clear(); - m_pluginLayerSharedValues.clear(); - m_renderSurfaceSharedValues.clear(); + m_sharedGeometry.clear(); + m_borderProgram.clear(); + m_contentLayerProgram.clear(); + m_canvasLayerProgram.clear(); + m_videoLayerRGBAProgram.clear(); + m_videoLayerYUVProgram.clear(); + m_pluginLayerProgram.clear(); + m_renderSurfaceProgram.clear(); + m_renderSurfaceMaskProgram.clear(); + m_tilerProgram.clear(); if (m_offscreenFramebufferId) GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId)); @@ -831,6 +927,26 @@ void LayerRendererChromium::cleanupSharedObjects() m_textureManager.clear(); } +String LayerRendererChromium::layerTreeAsText() const +{ + TextStream ts; + if (m_rootLayer.get()) { + ts << m_rootLayer->layerTreeAsText(); + ts << "RenderSurfaces:\n"; + dumpRenderSurfaces(ts, 1, m_rootLayer.get()); + } + return ts.release(); +} + +void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const +{ + if (layer->ccLayerImpl()->renderSurface()) + layer->ccLayerImpl()->renderSurface()->dumpSurface(ts, indent); + + for (size_t i = 0; i < layer->getSublayers().size(); ++i) + dumpRenderSurfaces(ts, indent, layer->getSublayers()[i].get()); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h index 3d3e784..7e8850a 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.h @@ -43,6 +43,7 @@ #include "RenderSurfaceChromium.h" #include "SkBitmap.h" #include "VideoLayerChromium.h" +#include "cc/CCHeadsUpDisplay.h" #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> @@ -57,7 +58,10 @@ namespace WebCore { +class CCLayerImpl; +class GeometryBinding; class GraphicsContext3D; +class CCHeadsUpDisplay; // Class that handles drawing of composited render layers using GL. class LayerRendererChromium : public RefCounted<LayerRendererChromium> { @@ -71,9 +75,8 @@ public: void invalidateRootLayerRect(const IntRect& dirtyRect, const IntRect& visibleRect, const IntRect& contentRect); // updates and draws the current layers onto the backbuffer - void drawLayers(const IntRect& visibleRect, const IntRect& contentRect, - const IntPoint& scrollPosition, TilePaintInterface& tilePaint, - TilePaintInterface& scrollbarPaint); + void updateAndDrawLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + TilePaintInterface&, TilePaintInterface& scrollbarPaint); // waits for rendering to finish void finish(); @@ -81,6 +84,8 @@ public: // puts backbuffer onscreen void present(); + IntSize visibleRectSize() const { return m_visibleRect.size(); } + void setRootLayer(PassRefPtr<LayerChromium> layer); LayerChromium* rootLayer() { return m_rootLayer.get(); } void transferRootLayer(LayerRendererChromium* other) { other->m_rootLayer = m_rootLayer.release(); } @@ -88,12 +93,9 @@ public: bool hardwareCompositing() const { return m_hardwareCompositing; } void setCompositeOffscreen(bool); - bool isCompositingOffscreen() { return m_compositeOffscreen; } - LayerTexture* getOffscreenLayerTexture() { return m_compositeOffscreen ? m_rootLayer->m_renderSurface->m_contentsTexture.get() : 0; } - - void setRootLayerCanvasSize(const IntSize&); - - GraphicsContext* rootLayerGraphicsContext() const { return m_rootLayerGraphicsContext.get(); } + bool isCompositingOffscreen() const { return m_compositeOffscreen; } + LayerTexture* getOffscreenLayerTexture(); + void copyOffscreenTextureToDisplay(); unsigned createLayerTexture(); void deleteLayerTexture(unsigned); @@ -106,30 +108,43 @@ public: bool checkTextureSize(const IntSize&); - const LayerChromium::SharedValues* layerSharedValues() const { return m_layerSharedValues.get(); } - const ContentLayerChromium::SharedValues* contentLayerSharedValues() const { return m_contentLayerSharedValues.get(); } - const CanvasLayerChromium::SharedValues* canvasLayerSharedValues() const { return m_canvasLayerSharedValues.get(); } - const VideoLayerChromium::SharedValues* videoLayerSharedValues() const { return m_videoLayerSharedValues.get(); } - const PluginLayerChromium::SharedValues* pluginLayerSharedValues() const { return m_pluginLayerSharedValues.get(); } - const RenderSurfaceChromium::SharedValues* renderSurfaceSharedValues() const { return m_renderSurfaceSharedValues.get(); } + const GeometryBinding* sharedGeometry() const { return m_sharedGeometry.get(); } + const LayerChromium::BorderProgram* borderProgram() const { return m_borderProgram.get(); } + const ContentLayerChromium::Program* contentLayerProgram() const { return m_contentLayerProgram.get(); } + const CanvasLayerChromium::Program* canvasLayerProgram() const { return m_canvasLayerProgram.get(); } + const VideoLayerChromium::RGBAProgram* videoLayerRGBAProgram() const { return m_videoLayerRGBAProgram.get(); } + const VideoLayerChromium::YUVProgram* videoLayerYUVProgram() const { return m_videoLayerYUVProgram.get(); } + const PluginLayerChromium::Program* pluginLayerProgram() const { return m_pluginLayerProgram.get(); } + const RenderSurfaceChromium::Program* renderSurfaceProgram() const { return m_renderSurfaceProgram.get(); } + const RenderSurfaceChromium::MaskProgram* renderSurfaceMaskProgram() const { return m_renderSurfaceMaskProgram.get(); } + const LayerTilerChromium::Program* tilerProgram() const { return m_tilerProgram.get(); } void resizeOnscreenContent(const IntSize&); - IntSize rootLayerTextureSize() const { return IntSize(m_rootLayerTextureWidth, m_rootLayerTextureHeight); } - IntRect rootLayerContentRect() const { return m_rootContentRect; } void getFramebufferPixels(void *pixels, const IntRect& rect); TextureManager* textureManager() const { return m_textureManager.get(); } + CCHeadsUpDisplay* headsUpDisplay() { return m_headsUpDisplay.get(); } + void setScissorToRect(const IntRect&); + String layerTreeAsText() const; + private: explicit LayerRendererChromium(PassRefPtr<GraphicsContext3D> graphicsContext3D); - void updateLayersRecursive(LayerChromium* layer, const TransformationMatrix& parentMatrix, Vector<LayerChromium*>& renderSurfaceLayerList, Vector<LayerChromium*>& layerList); - void drawLayer(LayerChromium*, RenderSurfaceChromium*); + void updateLayers(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition, + Vector<CCLayerImpl*>& renderSurfaceLayerList); + void updateRootLayerContents(TilePaintInterface&, const IntRect& visibleRect); + void updateRootLayerScrollbars(TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect); + void updatePropertiesAndRenderSurfaces(LayerChromium*, const TransformationMatrix& parentMatrix, Vector<CCLayerImpl*>& renderSurfaceLayerList, Vector<CCLayerImpl*>& layerList); + void updateContentsRecursive(LayerChromium*); - void updateAndDrawRootLayer(TilePaintInterface& tilePaint, TilePaintInterface& scrollbarPaint, const IntRect& visibleRect, const IntRect& contentRect); + void drawLayers(const Vector<CCLayerImpl*>& renderSurfaceLayerList); + void drawLayer(CCLayerImpl*, RenderSurfaceChromium*); + + void drawRootLayer(); bool isLayerVisible(LayerChromium*, const TransformationMatrix&, const IntRect& visibleRect); @@ -139,7 +154,9 @@ private: bool makeContextCurrent(); - static bool compareLayerZ(const LayerChromium*, const LayerChromium*); + static bool compareLayerZ(const CCLayerImpl*, const CCLayerImpl*); + + void dumpRenderSurfaces(TextStream&, int indent, LayerChromium*) const; bool initializeSharedObjects(); void cleanupSharedObjects(); @@ -147,8 +164,7 @@ private: static IntRect verticalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect); static IntRect horizontalScrollbarRect(const IntRect& visibleRect, const IntRect& contentRect); - int m_rootLayerTextureWidth; - int m_rootLayerTextureHeight; + IntRect m_visibleRect; TransformationMatrix m_projectionMatrix; @@ -166,7 +182,7 @@ private: unsigned m_offscreenFramebufferId; bool m_compositeOffscreen; -#if PLATFORM(SKIA) +#if USE(SKIA) OwnPtr<skia::PlatformCanvas> m_rootLayerCanvas; OwnPtr<PlatformContextSkia> m_rootLayerSkiaContext; OwnPtr<GraphicsContext> m_rootLayerGraphicsContext; @@ -176,11 +192,6 @@ private: OwnPtr<GraphicsContext> m_rootLayerGraphicsContext; #endif - IntSize m_rootLayerCanvasSize; - - IntRect m_rootVisibleRect; - IntRect m_rootContentRect; - // Maximum texture dimensions supported. int m_maxTextureSize; @@ -188,15 +199,21 @@ private: // associated with this instance of the compositor. Since there can be // multiple instances of the compositor running in the same renderer process // we cannot store these values in static variables. - OwnPtr<LayerChromium::SharedValues> m_layerSharedValues; - OwnPtr<ContentLayerChromium::SharedValues> m_contentLayerSharedValues; - OwnPtr<CanvasLayerChromium::SharedValues> m_canvasLayerSharedValues; - OwnPtr<VideoLayerChromium::SharedValues> m_videoLayerSharedValues; - OwnPtr<PluginLayerChromium::SharedValues> m_pluginLayerSharedValues; - OwnPtr<RenderSurfaceChromium::SharedValues> m_renderSurfaceSharedValues; + OwnPtr<GeometryBinding> m_sharedGeometry; + OwnPtr<LayerChromium::BorderProgram> m_borderProgram; + OwnPtr<ContentLayerChromium::Program> m_contentLayerProgram; + OwnPtr<CanvasLayerChromium::Program> m_canvasLayerProgram; + OwnPtr<VideoLayerChromium::RGBAProgram> m_videoLayerRGBAProgram; + OwnPtr<VideoLayerChromium::YUVProgram> m_videoLayerYUVProgram; + OwnPtr<PluginLayerChromium::Program> m_pluginLayerProgram; + OwnPtr<RenderSurfaceChromium::Program> m_renderSurfaceProgram; + OwnPtr<RenderSurfaceChromium::MaskProgram> m_renderSurfaceMaskProgram; + OwnPtr<LayerTilerChromium::Program> m_tilerProgram; OwnPtr<TextureManager> m_textureManager; + OwnPtr<CCHeadsUpDisplay> m_headsUpDisplay; + RefPtr<GraphicsContext3D> m_context; RenderSurfaceChromium* m_defaultRenderSurface; diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp index e28c084..86592a6 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.cpp @@ -35,27 +35,23 @@ #include "LayerRendererChromium.h" #include "LayerTexture.h" -#if PLATFORM(SKIA) -#include "NativeImageSkia.h" -#include "PlatformContextSkia.h" -#elif PLATFORM(CG) -#include <CoreGraphics/CGBitmapContext.h> -#endif - #include <wtf/PassOwnArrayPtr.h> +using namespace std; + namespace WebCore { -PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize) +PassOwnPtr<LayerTilerChromium> LayerTilerChromium::create(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border) { if (!layerRenderer || tileSize.isEmpty()) return 0; - return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize)); + return adoptPtr(new LayerTilerChromium(layerRenderer, tileSize, border)); } -LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize) +LayerTilerChromium::LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize, BorderTexelOption border) : m_skipsDraw(false) + , m_tilingData(max(tileSize.width(), tileSize.height()), 0, 0, border == HasBorderTexels) , m_layerRenderer(layerRenderer) { setTileSize(tileSize); @@ -81,6 +77,7 @@ void LayerTilerChromium::setTileSize(const IntSize& size) m_tileSize = size; m_tilePixels = adoptArrayPtr(new uint8_t[m_tileSize.width() * m_tileSize.height() * 4]); + m_tilingData.setMaxTextureSize(max(size.width(), size.height())); } void LayerTilerChromium::reset() @@ -88,8 +85,7 @@ void LayerTilerChromium::reset() m_tiles.clear(); m_unusedTiles.clear(); - m_layerSize = IntSize(); - m_layerTileSize = IntSize(); + m_tilingData.setTotalSize(0, 0); m_lastUpdateLayerRect = IntRect(); } @@ -143,10 +139,10 @@ void LayerTilerChromium::contentRectToTileIndices(const IntRect& contentRect, in { const IntRect layerRect = contentRectToLayerRect(contentRect); - left = layerRect.x() / m_tileSize.width(); - top = layerRect.y() / m_tileSize.height(); - right = (layerRect.maxX() - 1) / m_tileSize.width(); - bottom = (layerRect.maxY() - 1) / m_tileSize.height(); + left = m_tilingData.tileXIndexFromSrcCoord(layerRect.x()); + top = m_tilingData.tileYIndexFromSrcCoord(layerRect.y()); + right = m_tilingData.tileXIndexFromSrcCoord(layerRect.maxX() - 1); + bottom = m_tilingData.tileYIndexFromSrcCoord(layerRect.maxY() - 1); } IntRect LayerTilerChromium::contentRectToLayerRect(const IntRect& contentRect) const @@ -169,22 +165,32 @@ IntRect LayerTilerChromium::layerRectToContentRect(const IntRect& layerRect) con int LayerTilerChromium::tileIndex(int i, int j) const { - ASSERT(i >= 0 && j >= 0 && i < m_layerTileSize.width() && j < m_layerTileSize.height()); - return i + j * m_layerTileSize.width(); + return m_tilingData.tileIndex(i, j); } IntRect LayerTilerChromium::tileContentRect(int i, int j) const { - IntPoint anchor(m_layerPosition.x() + i * m_tileSize.width(), m_layerPosition.y() + j * m_tileSize.height()); - IntRect tile(anchor, m_tileSize); - return tile; + IntRect contentRect = tileLayerRect(i, j); + contentRect.move(m_layerPosition.x(), m_layerPosition.y()); + return contentRect; } IntRect LayerTilerChromium::tileLayerRect(int i, int j) const { - IntPoint anchor(i * m_tileSize.width(), j * m_tileSize.height()); - IntRect tile(anchor, m_tileSize); - return tile; + const int index = m_tilingData.tileIndex(i, j); + IntRect layerRect = m_tilingData.tileBoundsWithBorder(index); + layerRect.setSize(m_tileSize); + return layerRect; +} + +IntSize LayerTilerChromium::layerSize() const +{ + return IntSize(m_tilingData.totalSizeX(), m_tilingData.totalSizeY()); +} + +IntSize LayerTilerChromium::layerTileSize() const +{ + return IntSize(m_tilingData.numTilesX(), m_tilingData.numTilesY()); } void LayerTilerChromium::invalidateRect(const IntRect& contentRect) @@ -220,8 +226,7 @@ void LayerTilerChromium::invalidateEntireLayer() } m_tiles.clear(); - m_layerSize = IntSize(); - m_layerTileSize = IntSize(); + m_tilingData.setTotalSize(0, 0); m_lastUpdateLayerRect = IntRect(); } @@ -258,55 +263,26 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont return; const IntRect paintRect = layerRectToContentRect(dirtyLayerRect); - GraphicsContext3D* context = layerRendererContext(); -#if PLATFORM(SKIA) - OwnPtr<skia::PlatformCanvas> canvas(new skia::PlatformCanvas(paintRect.width(), paintRect.height(), false)); - OwnPtr<PlatformContextSkia> skiaContext(new PlatformContextSkia(canvas.get())); - OwnPtr<GraphicsContext> graphicsContext(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get()))); - - // Bring the canvas into the coordinate system of the paint rect. - canvas->translate(static_cast<SkScalar>(-paintRect.x()), static_cast<SkScalar>(-paintRect.y())); - painter.paint(*graphicsContext, paintRect); + m_canvas.resize(paintRect.size()); + PlatformCanvas::Painter canvasPainter(&m_canvas); + canvasPainter.context()->translate(-paintRect.x(), -paintRect.y()); + painter.paint(*canvasPainter.context(), paintRect); - // Get the contents of the updated rect. - const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false); - ASSERT(bitmap.width() == paintRect.width() && bitmap.height() == paintRect.height()); - if (bitmap.width() != paintRect.width() || bitmap.height() != paintRect.height()) - CRASH(); - uint8_t* paintPixels = static_cast<uint8_t*>(bitmap.getPixels()); - if (!paintPixels) - CRASH(); -#elif PLATFORM(CG) - Vector<uint8_t> canvasPixels; - int rowBytes = 4 * paintRect.width(); - canvasPixels.resize(rowBytes * paintRect.height()); - memset(canvasPixels.data(), 0, canvasPixels.size()); - RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); - RetainPtr<CGContextRef> m_cgContext; - m_cgContext.adoptCF(CGBitmapContextCreate(canvasPixels.data(), - paintRect.width(), paintRect.height(), 8, rowBytes, - colorSpace.get(), - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); - CGContextTranslateCTM(m_cgContext.get(), 0, paintRect.height()); - CGContextScaleCTM(m_cgContext.get(), 1, -1); - OwnPtr<GraphicsContext> m_graphicsContext(new GraphicsContext(m_cgContext.get())); - - // Bring the CoreGraphics context into the coordinate system of the paint rect. - CGContextTranslateCTM(m_cgContext.get(), -paintRect.x(), -paintRect.y()); - painter.paint(*m_graphicsContext, paintRect); - - // Get the contents of the updated rect. - ASSERT(static_cast<int>(CGBitmapContextGetWidth(m_cgContext.get())) == paintRect.width() && static_cast<int>(CGBitmapContextGetHeight(m_cgContext.get())) == paintRect.height()); - uint8_t* paintPixels = static_cast<uint8_t*>(canvasPixels.data()); -#else -#error "Need to implement for your platform." -#endif + PlatformCanvas::AutoLocker locker(&m_canvas); + updateFromPixels(paintRect, locker.pixels()); +} +void LayerTilerChromium::updateFromPixels(const IntRect& paintRect, const uint8_t* paintPixels) +{ // Painting could cause compositing to get turned off, which may cause the tiler to become invalidated mid-update. if (!m_tiles.size()) return; + GraphicsContext3D* context = layerRendererContext(); + + int left, top, right, bottom; + contentRectToTileIndices(paintRect, left, top, right, bottom); for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { Tile* tile = m_tiles[tileIndex(i, j)].get(); @@ -346,7 +322,7 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont if (paintOffset.y() + destRect.height() > paintRect.height()) CRASH(); - uint8_t* pixelSource; + const uint8_t* pixelSource; if (paintRect.width() == sourceRect.width() && !paintOffset.x()) pixelSource = &paintPixels[4 * paintOffset.y() * paintRect.width()]; else { @@ -361,6 +337,9 @@ void LayerTilerChromium::update(TilePaintInterface& painter, const IntRect& cont } tile->texture()->bindTexture(); + GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST)); + GLC(context, context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::NEAREST)); + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, destRect.x(), destRect.y(), destRect.width(), destRect.height(), GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixelSource)); tile->clearDirty(); @@ -378,26 +357,38 @@ void LayerTilerChromium::draw(const IntRect& contentRect) if (m_skipsDraw || !m_tiles.size()) return; - // We reuse the shader program used by ContentLayerChromium. GraphicsContext3D* context = layerRendererContext(); - const ContentLayerChromium::SharedValues* contentLayerValues = layerRenderer()->contentLayerSharedValues(); - layerRenderer()->useShader(contentLayerValues->contentShaderProgram()); - GLC(context, context->uniform1i(contentLayerValues->shaderSamplerLocation(), 0)); + const LayerTilerChromium::Program* program = layerRenderer()->tilerProgram(); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); int left, top, right, bottom; contentRectToTileIndices(contentRect, left, top, right, bottom); for (int j = top; j <= bottom; ++j) { for (int i = left; i <= right; ++i) { - Tile* tile = m_tiles[tileIndex(i, j)].get(); + const int index = tileIndex(i, j); + Tile* tile = m_tiles[index].get(); ASSERT(tile); tile->texture()->bindTexture(); TransformationMatrix tileMatrix; - IntRect tileRect = tileContentRect(i, j); + + // Don't use tileContentRect here, as that contains the full + // rect with border texels which shouldn't be drawn. + IntRect tileRect = m_tilingData.tileBounds(index); + tileRect.move(m_layerPosition.x(), m_layerPosition.y()); tileMatrix.translate3d(tileRect.x() - contentRect.x() + tileRect.width() / 2.0, tileRect.y() - contentRect.y() + tileRect.height() / 2.0, 0); - LayerChromium::drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, m_tileSize.width(), m_tileSize.height(), 1, contentLayerValues->shaderMatrixLocation(), contentLayerValues->shaderAlphaLocation()); + IntPoint texOffset = m_tilingData.textureOffset(i, j); + float tileWidth = static_cast<float>(m_tileSize.width()); + float tileHeight = static_cast<float>(m_tileSize.height()); + float texTranslateX = texOffset.x() / tileWidth; + float texTranslateY = texOffset.y() / tileHeight; + float texScaleX = tileRect.width() / tileWidth; + float texScaleY = tileRect.height() / tileHeight; + + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), tileMatrix, tileRect.width(), tileRect.height(), 1, texTranslateX, texTranslateY, texScaleX, texScaleY, program); tile->texture()->unreserve(); } @@ -406,36 +397,63 @@ void LayerTilerChromium::draw(const IntRect& contentRect) void LayerTilerChromium::resizeLayer(const IntSize& size) { - if (m_layerSize == size) + if (layerSize() == size) return; - int width = (size.width() + m_tileSize.width() - 1) / m_tileSize.width(); - int height = (size.height() + m_tileSize.height() - 1) / m_tileSize.height(); + const IntSize oldTileSize = layerTileSize(); + m_tilingData.setTotalSize(size.width(), size.height()); + const IntSize newTileSize = layerTileSize(); + + if (oldTileSize == newTileSize) + return; - if (height && (width > INT_MAX / height)) + if (newTileSize.height() && (newTileSize.width() > INT_MAX / newTileSize.height())) CRASH(); Vector<OwnPtr<Tile> > newTiles; - newTiles.resize(width * height); - for (int j = 0; j < m_layerTileSize.height(); ++j) - for (int i = 0; i < m_layerTileSize.width(); ++i) - newTiles[i + j * width].swap(m_tiles[i + j * m_layerTileSize.width()]); - + newTiles.resize(newTileSize.width() * newTileSize.height()); + for (int j = 0; j < oldTileSize.height(); ++j) + for (int i = 0; i < oldTileSize.width(); ++i) + newTiles[i + j * newTileSize.width()].swap(m_tiles[i + j * oldTileSize.width()]); m_tiles.swap(newTiles); - m_layerSize = size; - m_layerTileSize = IntSize(width, height); } void LayerTilerChromium::growLayerToContain(const IntRect& contentRect) { // Grow the tile array to contain this content rect. IntRect layerRect = contentRectToLayerRect(contentRect); - IntSize layerSize = IntSize(layerRect.maxX(), layerRect.maxY()); + IntSize rectSize = IntSize(layerRect.maxX(), layerRect.maxY()); - IntSize newSize = layerSize.expandedTo(m_layerSize); + IntSize newSize = rectSize.expandedTo(layerSize()); resizeLayer(newSize); } +void LayerTilerChromium::drawTexturedQuad(GraphicsContext3D* context, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix, + float width, float height, float opacity, + float texTranslateX, float texTranslateY, + float texScaleX, float texScaleY, + const LayerTilerChromium::Program* program) +{ + static float glMatrix[16]; + + TransformationMatrix renderMatrix = drawMatrix; + + // Apply a scaling factor to size the quad from 1x1 to its intended size. + renderMatrix.scale3d(width, height, 1); + + // Apply the projection matrix before sending the transform over to the shader. + LayerChromium::toGLMatrix(&glMatrix[0], projectionMatrix * renderMatrix); + + GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1)); + + GLC(context, context->uniform1f(program->fragmentShader().alphaLocation(), opacity)); + + GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), + texTranslateX, texTranslateY, texScaleX, texScaleY)); + + GLC(context, context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0)); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h index e09693d..bdb35a5 100644 --- a/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/LayerTilerChromium.h @@ -31,6 +31,8 @@ #include "LayerChromium.h" #include "LayerTexture.h" +#include "PlatformCanvas.h" +#include "TilingData.h" #include <wtf/OwnArrayPtr.h> namespace WebCore { @@ -46,13 +48,16 @@ public: class LayerTilerChromium { WTF_MAKE_NONCOPYABLE(LayerTilerChromium); public: - static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium* layerRenderer, const IntSize& tileSize); + enum BorderTexelOption { HasBorderTexels, NoBorderTexels }; + + static PassOwnPtr<LayerTilerChromium> create(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption); ~LayerTilerChromium(); void invalidateRect(const IntRect& contentRect); void invalidateEntireLayer(); void update(TilePaintInterface& painter, const IntRect& contentRect); + void updateFromPixels(const IntRect& paintRect, const uint8_t* pixels); void draw(const IntRect& contentRect); // Set position of this tiled layer in content space. @@ -60,8 +65,10 @@ public: // Change the tile size. This may invalidate all the existing tiles. void setTileSize(const IntSize& size); + typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderTexAlpha> Program; + private: - LayerTilerChromium(LayerRendererChromium* layerRenderer, const IntSize& tileSize); + LayerTilerChromium(LayerRendererChromium*, const IntSize& tileSize, BorderTexelOption); class Tile { WTF_MAKE_NONCOPYABLE(Tile); @@ -79,6 +86,12 @@ private: OwnPtr<LayerTexture> m_tex; }; + void drawTexturedQuad(GraphicsContext3D*, const TransformationMatrix& projectionMatrix, const TransformationMatrix& drawMatrix, + float width, float height, float opacity, + float texTranslateX, float texTranslateY, + float texScaleX, float texScaleY, + const LayerTilerChromium::Program*); + void resizeLayer(const IntSize& size); // Grow layer size to contain this rectangle. void growLayerToContain(const IntRect& contentRect); @@ -100,9 +113,10 @@ private: // Returns the bounds in layer space for a given tile location. IntRect tileLayerRect(int i, int j) const; + IntSize layerSize() const; + IntSize layerTileSize() const; + IntSize m_tileSize; - IntSize m_layerSize; - IntSize m_layerTileSize; IntRect m_lastUpdateLayerRect; IntPoint m_layerPosition; @@ -113,9 +127,13 @@ private: // Linear array of unused tiles. Vector<OwnPtr<Tile> > m_unusedTiles; + PlatformCanvas m_canvas; + // Cache a tile-sized pixel buffer to draw into. OwnArrayPtr<uint8_t> m_tilePixels; + TilingData m_tilingData; + LayerRendererChromium* m_layerRenderer; }; diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp new file mode 100644 index 0000000..29589f4 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "PlatformCanvas.h" + +#include "GraphicsContext.h" + +#if USE(SKIA) +#include "NativeImageSkia.h" +#include "PlatformContextSkia.h" +#include "SkColorPriv.h" +#include "skia/ext/platform_canvas.h" +#elif PLATFORM(CG) +#include <CoreGraphics/CGBitmapContext.h> +#endif + +namespace WebCore { + +PlatformCanvas::PlatformCanvas() +{ +} + +PlatformCanvas::~PlatformCanvas() +{ +} + +void PlatformCanvas::resize(const IntSize& size) +{ + m_size = size; +#if USE(SKIA) + m_skiaCanvas = new skia::PlatformCanvas(size.width(), size.height(), false); +#elif PLATFORM(CG) + size_t bufferSize = size.width() * size.height() * 4; + m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]); + memset(m_pixelData.get(), 0, bufferSize); +#endif +} + +PlatformCanvas::AutoLocker::AutoLocker(PlatformCanvas* canvas) + : m_canvas(canvas) + , m_pixels(0) +{ +#if USE(SKIA) + if (m_canvas->m_skiaCanvas) { + m_bitmap = &m_canvas->m_skiaCanvas->getDevice()->accessBitmap(false); + m_bitmap->lockPixels(); + + if (m_bitmap->config() == SkBitmap::kARGB_8888_Config) + m_pixels = static_cast<uint8_t*>(m_bitmap->getPixels()); + } else + m_bitmap = 0; +#elif PLATFORM(CG) + m_pixels = &canvas->m_pixelData[0]; +#endif +} + +PlatformCanvas::AutoLocker::~AutoLocker() +{ +#if USE(SKIA) + if (m_bitmap) + m_bitmap->unlockPixels(); +#endif +} + +PlatformCanvas::Painter::Painter(PlatformCanvas* canvas) +{ +#if USE(SKIA) + m_skiaContext = adoptPtr(new PlatformContextSkia(canvas->m_skiaCanvas.get())); + + // This is needed to get text to show up correctly. + m_skiaContext->setDrawingToImageBuffer(true); + + m_context = adoptPtr(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(m_skiaContext.get()))); +#elif PLATFORM(CG) + + m_colorSpace = CGColorSpaceCreateDeviceRGB(); + size_t rowBytes = canvas->size().width() * 4; + m_contextCG = CGBitmapContextCreate(canvas->m_pixelData.get(), + canvas->size().width(), canvas->size().height(), 8, rowBytes, + m_colorSpace.get(), + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); + CGContextTranslateCTM(m_contextCG.get(), 0, canvas->size().height()); + CGContextScaleCTM(m_contextCG.get(), 1, -1); + m_context = adoptPtr(new GraphicsContext(m_contextCG.get())); +#endif +} + +PlatformCanvas::Painter::~Painter() +{ +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h new file mode 100644 index 0000000..262fdd0 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformCanvas.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PlatformCanvas_h +#define PlatformCanvas_h + +#include "IntSize.h" +#include <stdint.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnPtr.h> + +#if PLATFORM(CG) +#include <CoreGraphics/CGColorSpace.h> +#include <CoreGraphics/CGContext.h> +#include <wtf/OwnArrayPtr.h> +#include <wtf/RetainPtr.h> +#endif + +#if USE(SKIA) +namespace skia { class PlatformCanvas; } +class SkBitmap; +#endif + +namespace WebCore { + +class GraphicsContext; + +#if USE(SKIA) +class PlatformContextSkia; +#endif + +// A 2D buffer of pixels with an associated GraphicsContext. +class PlatformCanvas { + WTF_MAKE_NONCOPYABLE(PlatformCanvas); +public: + PlatformCanvas(); + ~PlatformCanvas(); + + // Scoped lock class to get temporary access to this canvas's pixels. + class AutoLocker { + WTF_MAKE_NONCOPYABLE(AutoLocker); + public: + explicit AutoLocker(PlatformCanvas*); + ~AutoLocker(); + + const uint8_t* pixels() const { return m_pixels; } + private: + PlatformCanvas* m_canvas; +#if USE(SKIA) + const SkBitmap* m_bitmap; +#endif + uint8_t* m_pixels; + }; + + // Scoped lock class to get temporary access to paint into this canvas. + class Painter { + WTF_MAKE_NONCOPYABLE(Painter); + public: + explicit Painter(PlatformCanvas*); + ~Painter(); + + GraphicsContext* context() const { return m_context.get(); } + private: + OwnPtr<GraphicsContext> m_context; +#if USE(SKIA) + OwnPtr<PlatformContextSkia> m_skiaContext; +#elif PLATFORM(CG) + RetainPtr<CGColorSpaceRef> m_colorSpace; + RetainPtr<CGContextRef> m_contextCG; +#endif + }; + + void resize(const IntSize&); + IntSize size() const { return m_size; } + +private: +#if USE(SKIA) + OwnPtr<skia::PlatformCanvas> m_skiaCanvas; +#elif PLATFORM(CG) + OwnArrayPtr<uint8_t> m_pixelData; +#endif + IntSize m_size; +}; + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp new file mode 100644 index 0000000..62cf4f8 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "PlatformImage.h" + +#if USE(SKIA) +#include "NativeImageSkia.h" +#include "PlatformContextSkia.h" +#elif PLATFORM(CG) +#include <CoreGraphics/CGBitmapContext.h> +#include <CoreGraphics/CGContext.h> +#include <CoreGraphics/CGImage.h> +#include <wtf/RetainPtr.h> +#else +#error "Need to implement for your platform" +#endif + +namespace WebCore { + +PlatformImage::PlatformImage() +{ +} + +void PlatformImage::updateFromImage(NativeImagePtr nativeImage) +{ +#if USE(SKIA) + // The layer contains an Image. + NativeImageSkia* skiaImage = static_cast<NativeImageSkia*>(nativeImage); + const SkBitmap* skiaBitmap = skiaImage; + + IntSize bitmapSize(skiaBitmap->width(), skiaBitmap->height()); + ASSERT(skiaBitmap); +#elif PLATFORM(CG) + // NativeImagePtr is a CGImageRef on Mac OS X. + int width = CGImageGetWidth(nativeImage); + int height = CGImageGetHeight(nativeImage); + IntSize bitmapSize(width, height); +#endif + + size_t bufferSize = bitmapSize.width() * bitmapSize.height() * 4; + if (m_size != bitmapSize) { + m_pixelData = adoptArrayPtr(new uint8_t[bufferSize]); + memset(m_pixelData.get(), 0, bufferSize); + m_size = bitmapSize; + } + +#if USE(SKIA) + SkAutoLockPixels lock(*skiaBitmap); + // FIXME: do we need to support more image configurations? + ASSERT(skiaBitmap->config()== SkBitmap::kARGB_8888_Config); + skiaBitmap->copyPixelsTo(m_pixelData.get(), bufferSize); +#elif PLATFORM(CG) + // FIXME: we should get rid of this temporary copy where possible. + int tempRowBytes = width * 4; + // Note we do not zero this vector since we are going to + // completely overwrite its contents with the image below. + // Try to reuse the color space from the image to preserve its colors. + // Some images use a color space (such as indexed) unsupported by the bitmap context. + RetainPtr<CGColorSpaceRef> colorSpaceReleaser; + CGColorSpaceRef colorSpace = CGImageGetColorSpace(nativeImage); + CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); + switch (colorSpaceModel) { + case kCGColorSpaceModelMonochrome: + case kCGColorSpaceModelRGB: + case kCGColorSpaceModelCMYK: + case kCGColorSpaceModelLab: + case kCGColorSpaceModelDeviceN: + break; + default: + colorSpaceReleaser.adoptCF(CGColorSpaceCreateDeviceRGB()); + colorSpace = colorSpaceReleaser.get(); + break; + } + RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(m_pixelData.get(), + width, height, 8, tempRowBytes, + colorSpace, + kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + CGContextSetBlendMode(tempContext.get(), kCGBlendModeCopy); + CGContextDrawImage(tempContext.get(), + CGRectMake(0, 0, static_cast<CGFloat>(width), static_cast<CGFloat>(height)), + nativeImage); +#else +#error "Need to implement for your platform." +#endif +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/PlatformImage.h b/Source/WebCore/platform/graphics/chromium/PlatformImage.h new file mode 100644 index 0000000..12f77b6 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/PlatformImage.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PlatformImage_h +#define PlatformImage_h + +#include "ImageSource.h" +#include "IntSize.h" +#include <stdint.h> +#include <wtf/Noncopyable.h> +#include <wtf/OwnArrayPtr.h> + +namespace WebCore { + +class PlatformImage { + WTF_MAKE_NONCOPYABLE(PlatformImage); +public: + PlatformImage(); + + void updateFromImage(NativeImagePtr); + const uint8_t* pixels() const { return m_pixelData ? &m_pixelData[0] : 0; } + IntSize size() const { return m_size; } + +private: + OwnArrayPtr<uint8_t> m_pixelData; + IntSize m_size; +}; + +} // namespace WebCore + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp index 878c142..5d595ad 100644 --- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.cpp @@ -29,64 +29,13 @@ #include "PluginLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" #include <GLES2/gl2.h> namespace WebCore { -PluginLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_shaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_initialized(false) -{ - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - - char fragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, v_texCoord.y)); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - - m_shaderProgram = createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - if (!m_shaderProgram) { - LOG_ERROR("PluginLayerChromium: Failed to create shader program"); - return; - } - - m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture"); - m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix"); - m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha"); - ASSERT(m_shaderSamplerLocation != -1); - ASSERT(m_shaderMatrixLocation != -1); - ASSERT(m_shaderAlphaLocation != -1); - - m_initialized = true; -} - -PluginLayerChromium::SharedValues::~SharedValues() -{ - if (m_shaderProgram) - GLC(m_context, m_context->deleteProgram(m_shaderProgram)); -} - PassRefPtr<PluginLayerChromium> PluginLayerChromium::create(GraphicsLayerChromium* owner) { return adoptRef(new PluginLayerChromium(owner)); @@ -109,8 +58,8 @@ void PluginLayerChromium::updateContentsIfDirty() void PluginLayerChromium::draw() { ASSERT(layerRenderer()); - const PluginLayerChromium::SharedValues* sv = layerRenderer()->pluginLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const PluginLayerChromium::Program* program = layerRenderer()->pluginLayerProgram(); + ASSERT(program && program->initialized()); GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GL_TEXTURE0)); GLC(context, context->bindTexture(GL_TEXTURE_2D, m_textureId)); @@ -122,11 +71,12 @@ void PluginLayerChromium::draw() GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GLC(context, context->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - layerRenderer()->useShader(sv->shaderProgram()); - GLC(context, context->uniform1i(sv->shaderSamplerLocation(), 0)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->shaderMatrixLocation(), sv->shaderAlphaLocation()); + layerRenderer()->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } } diff --git a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h index 853b328..8d66f5f 100644 --- a/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/PluginLayerChromium.h @@ -37,31 +37,16 @@ namespace WebCore { class PluginLayerChromium : public LayerChromium { public: static PassRefPtr<PluginLayerChromium> create(GraphicsLayerChromium* owner = 0); - virtual bool drawsContent() { return true; } + virtual bool drawsContent() const { return true; } virtual void updateContentsIfDirty(); virtual void draw(); void setTextureId(unsigned textureId); - class SharedValues { - public: - SharedValues(GraphicsContext3D* context); - ~SharedValues(); + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexFlipAlpha> Program; - unsigned shaderProgram() const { return m_shaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - unsigned m_shaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - bool m_initialized; - }; +protected: + virtual const char* layerTypeAsString() const { return "PluginLayer"; } private: PluginLayerChromium(GraphicsLayerChromium* owner); diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp new file mode 100644 index 0000000..6be00ef --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "ProgramBinding.h" + +#include "GeometryBinding.h" +#include "GraphicsContext.h" +#include "GraphicsContext3D.h" +#include "LayerRendererChromium.h" + +namespace WebCore { + +ProgramBindingBase::ProgramBindingBase(GraphicsContext3D* context) + : m_context(context) + , m_program(0) + , m_initialized(false) +{ +} + +ProgramBindingBase::~ProgramBindingBase() +{ + if (m_program) + GLC(m_context, m_context->deleteProgram(m_program)); +} + +bool ProgramBindingBase::init(const String& vertexShader, const String& fragmentShader) +{ + m_program = createShaderProgram(vertexShader, fragmentShader); + if (!m_program) { + LOG_ERROR("Failed to create shader program"); + return false; + } + return true; +} + +unsigned ProgramBindingBase::loadShader(unsigned type, const String& shaderSource) +{ + unsigned shader = m_context->createShader(type); + if (!shader) + return 0; + String sourceString(shaderSource); + GLC(m_context, m_context->shaderSource(shader, sourceString)); + GLC(m_context, m_context->compileShader(shader)); + int compiled = 0; + GLC(m_context, m_context->getShaderiv(shader, GraphicsContext3D::COMPILE_STATUS, &compiled)); + if (!compiled) { + GLC(m_context, m_context->deleteShader(shader)); + return 0; + } + return shader; +} + +unsigned ProgramBindingBase::createShaderProgram(const String& vertexShaderSource, const String& fragmentShaderSource) +{ + unsigned vertexShader = loadShader(GraphicsContext3D::VERTEX_SHADER, vertexShaderSource); + if (!vertexShader) { + LOG_ERROR("Failed to create vertex shader"); + return 0; + } + + unsigned fragmentShader = loadShader(GraphicsContext3D::FRAGMENT_SHADER, fragmentShaderSource); + if (!fragmentShader) { + GLC(m_context, m_context->deleteShader(vertexShader)); + LOG_ERROR("Failed to create fragment shader"); + return 0; + } + + unsigned programObject = m_context->createProgram(); + if (!programObject) { + LOG_ERROR("Failed to create shader program"); + return 0; + } + + GLC(m_context, m_context->attachShader(programObject, vertexShader)); + GLC(m_context, m_context->attachShader(programObject, fragmentShader)); + + // Bind the common attrib locations. + GLC(m_context, m_context->bindAttribLocation(programObject, GeometryBinding::positionAttribLocation(), "a_position")); + GLC(m_context, m_context->bindAttribLocation(programObject, GeometryBinding::texCoordAttribLocation(), "a_texCoord")); + + GLC(m_context, m_context->linkProgram(programObject)); + int linked = 0; + GLC(m_context, m_context->getProgramiv(programObject, GraphicsContext3D::LINK_STATUS, &linked)); + if (!linked) { + LOG_ERROR("Failed to link shader program"); + GLC(m_context, m_context->deleteProgram(programObject)); + return 0; + } + + GLC(m_context, m_context->deleteShader(vertexShader)); + GLC(m_context, m_context->deleteShader(fragmentShader)); + return programObject; +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ProgramBinding.h b/Source/WebCore/platform/graphics/chromium/ProgramBinding.h new file mode 100644 index 0000000..c6bf605 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ProgramBinding.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ProgramBinding_h +#define ProgramBinding_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PlatformString.h" + +namespace WebCore { + +class GraphicsContext3D; + +class ProgramBindingBase { +public: + explicit ProgramBindingBase(GraphicsContext3D*); + ~ProgramBindingBase(); + + bool init(const String& vertexShader, const String& fragmentShader); + + unsigned program() const { return m_program; } + bool initialized() const { return m_initialized; } + +protected: + + unsigned loadShader(unsigned type, const String& shaderSource); + unsigned createShaderProgram(const String& vertexShaderSource, const String& fragmentShaderSource); + + GraphicsContext3D* m_context; + unsigned m_program; + bool m_initialized; +}; + +template<class VertexShader, class FragmentShader> +class ProgramBinding : public ProgramBindingBase { +public: + explicit ProgramBinding(GraphicsContext3D* context) + : ProgramBindingBase(context) + { + if (!ProgramBindingBase::init(m_vertexShader.getShaderString(), m_fragmentShader.getShaderString())) + return; + if (!m_vertexShader.init(m_context, m_program)) + return; + if (!m_fragmentShader.init(m_context, m_program)) + return; + m_initialized = true; + } + + const VertexShader& vertexShader() const { return m_vertexShader; } + const FragmentShader& fragmentShader() const { return m_fragmentShader; } + +private: + + VertexShader m_vertexShader; + FragmentShader m_fragmentShader; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp index b3ce9d7..ca42d0b 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.cpp @@ -29,98 +29,17 @@ #include "RenderSurfaceChromium.h" +#include "cc/CCLayerImpl.h" #include "GraphicsContext3D.h" +#include "LayerChromium.h" #include "LayerRendererChromium.h" #include "LayerTexture.h" +#include "TextStream.h" +#include <wtf/text/CString.h> namespace WebCore { -RenderSurfaceChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_shaderProgram(0) - , m_maskShaderProgram(0) - , m_shaderSamplerLocation(-1) - , m_shaderMatrixLocation(-1) - , m_shaderAlphaLocation(-1) - , m_maskShaderSamplerLocation(-1) - , m_maskShaderMaskSamplerLocation(-1) - , m_maskShaderMatrixLocation(-1) - , m_maskShaderAlphaLocation(-1) - , m_initialized(false) -{ - char vertexShaderString[] = - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = a_texCoord; \n" - "} \n"; - char fragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - char fragmentShaderWithMaskString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D s_texture; \n" - "uniform sampler2D s_mask; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(s_texture, v_texCoord); \n" - " vec4 maskColor = texture2D(s_mask, v_texCoord); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; \n" - "} \n"; - - m_shaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderString); - m_maskShaderProgram = LayerChromium::createShaderProgram(m_context, vertexShaderString, fragmentShaderWithMaskString); - if (!m_shaderProgram || !m_maskShaderProgram) { - LOG_ERROR("RenderSurfaceChromium: Failed to create shader program"); - return; - } - - GLC(m_context, m_shaderSamplerLocation = m_context->getUniformLocation(m_shaderProgram, "s_texture")); - GLC(m_context, m_shaderMatrixLocation = m_context->getUniformLocation(m_shaderProgram, "matrix")); - GLC(m_context, m_shaderAlphaLocation = m_context->getUniformLocation(m_shaderProgram, "alpha")); - - GLC(m_context, m_maskShaderSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_texture")); - GLC(m_context, m_maskShaderMaskSamplerLocation = m_context->getUniformLocation(m_maskShaderProgram, "s_mask")); - GLC(m_context, m_maskShaderMatrixLocation = m_context->getUniformLocation(m_maskShaderProgram, "matrix")); - GLC(m_context, m_maskShaderAlphaLocation = m_context->getUniformLocation(m_maskShaderProgram, "alpha")); - - if (m_shaderSamplerLocation == -1 || m_shaderMatrixLocation == -1 || m_shaderAlphaLocation == -1 - || m_maskShaderSamplerLocation == -1 || m_maskShaderMaskSamplerLocation == -1 || m_maskShaderMatrixLocation == -1 || m_maskShaderAlphaLocation == -1) { - LOG_ERROR("Failed to initialize render surface shaders."); - return; - } - - GLC(m_context, m_context->useProgram(m_shaderProgram)); - GLC(m_context, m_context->uniform1i(m_shaderSamplerLocation, 0)); - GLC(m_context, m_context->useProgram(m_maskShaderProgram)); - GLC(m_context, m_context->uniform1i(m_maskShaderSamplerLocation, 0)); - GLC(m_context, m_context->uniform1i(m_maskShaderMaskSamplerLocation, 1)); - GLC(m_context, m_context->useProgram(0)); - m_initialized = true; -} - -RenderSurfaceChromium::SharedValues::~SharedValues() -{ - if (m_shaderProgram) - GLC(m_context, m_context->deleteProgram(m_shaderProgram)); - if (m_maskShaderProgram) - GLC(m_context, m_context->deleteProgram(m_maskShaderProgram)); -} - -RenderSurfaceChromium::RenderSurfaceChromium(LayerChromium* owningLayer) +RenderSurfaceChromium::RenderSurfaceChromium(CCLayerImpl* owningLayer) : m_owningLayer(owningLayer) , m_maskLayer(0) , m_skipsDraw(false) @@ -179,36 +98,39 @@ bool RenderSurfaceChromium::prepareContentsTexture() return true; } -void RenderSurfaceChromium::drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform) +void RenderSurfaceChromium::drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform) { GraphicsContext3D* context3D = layerRenderer()->context(); int shaderMatrixLocation = -1; int shaderAlphaLocation = -1; - const RenderSurfaceChromium::SharedValues* sv = layerRenderer()->renderSurfaceSharedValues(); - ASSERT(sv && sv->initialized()); + const RenderSurfaceChromium::Program* program = layerRenderer()->renderSurfaceProgram(); + const RenderSurfaceChromium::MaskProgram* maskProgram = layerRenderer()->renderSurfaceMaskProgram(); + ASSERT(program && program->initialized()); bool useMask = false; if (maskLayer && maskLayer->drawsContent()) { - maskLayer->updateContentsIfDirty(); if (!maskLayer->bounds().isEmpty()) { context3D->makeContextCurrent(); - layerRenderer()->useShader(sv->maskShaderProgram()); + layerRenderer()->useShader(maskProgram->program()); GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); + GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().samplerLocation(), 0)); m_contentsTexture->bindTexture(); GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE1)); + GLC(context3D, context3D->uniform1i(maskProgram->fragmentShader().maskSamplerLocation(), 1)); maskLayer->bindContentsTexture(); GLC(context3D, context3D->activeTexture(GraphicsContext3D::TEXTURE0)); - shaderMatrixLocation = sv->maskShaderMatrixLocation(); - shaderAlphaLocation = sv->maskShaderAlphaLocation(); + shaderMatrixLocation = maskProgram->vertexShader().matrixLocation(); + shaderAlphaLocation = maskProgram->fragmentShader().alphaLocation(); useMask = true; } } if (!useMask) { - layerRenderer()->useShader(sv->shaderProgram()); + layerRenderer()->useShader(program->program()); m_contentsTexture->bindTexture(); - shaderMatrixLocation = sv->shaderMatrixLocation(); - shaderAlphaLocation = sv->shaderAlphaLocation(); + GLC(context3D, context3D->uniform1i(program->fragmentShader().samplerLocation(), 0)); + shaderMatrixLocation = program->vertexShader().matrixLocation(); + shaderAlphaLocation = program->fragmentShader().alphaLocation(); } LayerChromium::drawTexturedQuad(layerRenderer()->context(), layerRenderer()->projectionMatrix(), drawTransform, @@ -231,7 +153,7 @@ void RenderSurfaceChromium::draw() // both the layer and its reflection). The solution is to introduce yet another RenderSurface // to draw the layer and its reflection in. For now we only apply a separate reflection // mask if the contents don't have a mask of their own. - LayerChromium* replicaMaskLayer = m_maskLayer; + CCLayerImpl* replicaMaskLayer = m_maskLayer; if (!m_maskLayer && m_owningLayer->replicaLayer()) replicaMaskLayer = m_owningLayer->replicaLayer()->maskLayer(); @@ -244,5 +166,29 @@ void RenderSurfaceChromium::draw() drawSurface(m_maskLayer, m_drawTransform); } +String RenderSurfaceChromium::name() const +{ +#ifndef NDEBUG + return String::format("RenderSurface(id=%i,owner=%s)", m_owningLayer->debugID(), m_owningLayer->name().utf8().data()); +#else + return String::format("RenderSurface(owner=%s)", m_owningLayer->name().utf8().data()); +#endif +} + +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void RenderSurfaceChromium::dumpSurface(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); + ts << name() << "\n"; + + writeIndent(ts, indent+1); + ts << "contentRect: (" << m_contentRect.x() << ", " << m_contentRect.y() << ", " << m_contentRect.width() << ", " << m_contentRect.height() << "\n"; +} + } #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h index b1f6a5c..6400c63 100644 --- a/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h +++ b/Source/WebCore/platform/graphics/chromium/RenderSurfaceChromium.h @@ -31,13 +31,15 @@ #include "FloatRect.h" #include "IntRect.h" +#include "ProgramBinding.h" +#include "ShaderChromium.h" #include "TextureManager.h" #include "TransformationMatrix.h" #include <wtf/Noncopyable.h> namespace WebCore { -class LayerChromium; +class CCLayerImpl; class LayerRendererChromium; class LayerTexture; @@ -45,13 +47,16 @@ class RenderSurfaceChromium { WTF_MAKE_NONCOPYABLE(RenderSurfaceChromium); friend class LayerRendererChromium; public: - explicit RenderSurfaceChromium(LayerChromium*); + explicit RenderSurfaceChromium(CCLayerImpl*); ~RenderSurfaceChromium(); bool prepareContentsTexture(); void cleanupResources(); void draw(); + String name() const; + void dumpSurface(TextStream&, int indent) const; + FloatPoint contentRectCenter() const { return FloatRect(m_contentRect).center(); } IntRect contentRect() const { return m_contentRect; } @@ -60,56 +65,26 @@ public: TransformationMatrix drawTransform() const { return m_drawTransform; } - // Stores values that are shared between instances of this class that are - // associated with the same LayerRendererChromium (and hence the same GL - // context). - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - - unsigned shaderProgram() const { return m_shaderProgram; } - unsigned maskShaderProgram() const { return m_maskShaderProgram; } - int shaderSamplerLocation() const { return m_shaderSamplerLocation; } - int shaderMatrixLocation() const { return m_shaderMatrixLocation; } - int shaderAlphaLocation() const { return m_shaderAlphaLocation; } - int maskShaderSamplerLocation() const { return m_maskShaderSamplerLocation; } - int maskShaderMaskSamplerLocation() const { return m_maskShaderMaskSamplerLocation; } - int maskShaderMatrixLocation() const { return m_maskShaderMatrixLocation; } - int maskShaderAlphaLocation() const { return m_maskShaderAlphaLocation; } - bool initialized() const { return m_initialized; } - - private: - GraphicsContext3D* m_context; - - unsigned m_shaderProgram; - unsigned m_maskShaderProgram; - int m_shaderSamplerLocation; - int m_shaderMatrixLocation; - int m_shaderAlphaLocation; - int m_maskShaderSamplerLocation; - int m_maskShaderMaskSamplerLocation; - int m_maskShaderMatrixLocation; - int m_maskShaderAlphaLocation; - bool m_initialized; - }; + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexAlpha> Program; + typedef ProgramBinding<VertexShaderPosTex, FragmentShaderRGBATexAlphaMask> MaskProgram; private: LayerRendererChromium* layerRenderer(); - void drawSurface(LayerChromium* maskLayer, const TransformationMatrix& drawTransform); + void drawSurface(CCLayerImpl* maskLayer, const TransformationMatrix& drawTransform); - LayerChromium* m_owningLayer; - LayerChromium* m_maskLayer; + CCLayerImpl* m_owningLayer; + CCLayerImpl* m_maskLayer; IntRect m_contentRect; bool m_skipsDraw; + OwnPtr<LayerTexture> m_contentsTexture; float m_drawOpacity; TransformationMatrix m_drawTransform; TransformationMatrix m_replicaDrawTransform; TransformationMatrix m_originTransform; IntRect m_scissorRect; - Vector<LayerChromium*> m_layerList; + Vector<CCLayerImpl*> m_layerList; }; } diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp new file mode 100644 index 0000000..49b3462 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "ShaderChromium.h" + +#include "GraphicsContext.h" +#include "GraphicsContext3D.h" + +#define SHADER0(Src) #Src +#define SHADER(Src) SHADER0(Src) + +namespace WebCore { + +VertexShaderPosTex::VertexShaderPosTex() + : m_matrixLocation(-1) +{ +} + +bool VertexShaderPosTex::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + return m_matrixLocation != -1; +} + +String VertexShaderPosTex::getShaderString() const +{ + return SHADER( + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + varying vec2 v_texCoord; + void main() + { + gl_Position = matrix * a_position; + v_texCoord = a_texCoord; + } + ); +} + +VertexShaderPosTexYUVStretch::VertexShaderPosTexYUVStretch() + : m_matrixLocation(-1) + , m_yWidthScaleFactorLocation(-1) + , m_uvWidthScaleFactorLocation(-1) +{ +} + +bool VertexShaderPosTexYUVStretch::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + m_yWidthScaleFactorLocation = context->getUniformLocation(program, "y_widthScaleFactor"); + m_uvWidthScaleFactorLocation = context->getUniformLocation(program, "uv_widthScaleFactor"); + return m_matrixLocation != -1 && m_yWidthScaleFactorLocation != -1 && m_uvWidthScaleFactorLocation != -1; +} + +String VertexShaderPosTexYUVStretch::getShaderString() const +{ + return SHADER( + precision mediump float; + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + varying vec2 y_texCoord; + varying vec2 uv_texCoord; + uniform float y_widthScaleFactor; + uniform float uv_widthScaleFactor; + void main() + { + gl_Position = matrix * a_position; + y_texCoord = vec2(y_widthScaleFactor * a_texCoord.x, a_texCoord.y); + uv_texCoord = vec2(uv_widthScaleFactor * a_texCoord.x, a_texCoord.y); + } + ); +} + +VertexShaderPos::VertexShaderPos() + : m_matrixLocation(-1) +{ +} + +bool VertexShaderPos::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + return m_matrixLocation != -1; +} + +String VertexShaderPos::getShaderString() const +{ + return SHADER( + attribute vec4 a_position; + uniform mat4 matrix; + void main() + { + gl_Position = matrix * a_position; + } + ); +} + +VertexShaderPosTexTransform::VertexShaderPosTexTransform() + : m_matrixLocation(-1) + , m_texTransformLocation(-1) +{ +} + +bool VertexShaderPosTexTransform::init(GraphicsContext3D* context, unsigned program) +{ + m_matrixLocation = context->getUniformLocation(program, "matrix"); + m_texTransformLocation = context->getUniformLocation(program, "texTransform"); + return m_matrixLocation != -1 && m_texTransformLocation != -1; +} + +String VertexShaderPosTexTransform::getShaderString() const +{ + return SHADER( + attribute vec4 a_position; + attribute vec2 a_texCoord; + uniform mat4 matrix; + uniform vec4 texTransform; + varying vec2 v_texCoord; + void main() + { + gl_Position = matrix * a_position; + v_texCoord = a_texCoord * texTransform.zw + texTransform.xy; + } + ); +} + +FragmentTexAlphaBinding::FragmentTexAlphaBinding() + : m_samplerLocation(-1) + , m_alphaLocation(-1) +{ +} + +bool FragmentTexAlphaBinding::init(GraphicsContext3D* context, unsigned program) +{ + m_samplerLocation = context->getUniformLocation(program, "s_texture"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + + return m_samplerLocation != -1 && m_alphaLocation != -1; +} + +String FragmentShaderRGBATexFlipAlpha::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, vec2(v_texCoord.x, 1.0 - v_texCoord.y)); + gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; + } + ); +} + +String FragmentShaderRGBATexAlpha::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, v_texCoord); + gl_FragColor = texColor * alpha; + } + ); +} + +String FragmentShaderBGRATexAlpha::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, v_texCoord); + gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha; + } + ); +} + +FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask() + : m_samplerLocation(-1) + , m_maskSamplerLocation(-1) + , m_alphaLocation(-1) +{ +} + +bool FragmentShaderRGBATexAlphaMask::init(GraphicsContext3D* context, unsigned program) +{ + m_samplerLocation = context->getUniformLocation(program, "s_texture"); + m_maskSamplerLocation = context->getUniformLocation(program, "s_mask"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + + return m_samplerLocation != -1 && m_maskSamplerLocation != -1 && m_alphaLocation != -1; +} + +String FragmentShaderRGBATexAlphaMask::getShaderString() const +{ + return SHADER( + precision mediump float; + varying vec2 v_texCoord; + uniform sampler2D s_texture; + uniform sampler2D s_mask; + uniform float alpha; + void main() + { + vec4 texColor = texture2D(s_texture, v_texCoord); + vec4 maskColor = texture2D(s_mask, v_texCoord); + gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha * maskColor.w; + } + ); +} + +FragmentShaderYUVVideo::FragmentShaderYUVVideo() + : m_yTextureLocation(-1) + , m_uTextureLocation(-1) + , m_vTextureLocation(-1) + , m_alphaLocation(-1) + , m_ccMatrixLocation(-1) + , m_signAdjLocation(-1) +{ +} + +bool FragmentShaderYUVVideo::init(GraphicsContext3D* context, unsigned program) +{ + m_yTextureLocation = context->getUniformLocation(program, "y_texture"); + m_uTextureLocation = context->getUniformLocation(program, "u_texture"); + m_vTextureLocation = context->getUniformLocation(program, "v_texture"); + m_alphaLocation = context->getUniformLocation(program, "alpha"); + m_ccMatrixLocation = context->getUniformLocation(program, "cc_matrix"); + m_signAdjLocation = context->getUniformLocation(program, "adj"); + + return m_yTextureLocation != -1 && m_uTextureLocation != -1 && m_vTextureLocation != -1 + && m_alphaLocation != -1 && m_ccMatrixLocation != -1 && m_signAdjLocation != -1; +} + +String FragmentShaderYUVVideo::getShaderString() const +{ + return SHADER( + precision mediump float; + precision mediump int; + varying vec2 y_texCoord; + varying vec2 uv_texCoord; + uniform sampler2D y_texture; + uniform sampler2D u_texture; + uniform sampler2D v_texture; + uniform float alpha; + uniform float adj; + uniform mat3 cc_matrix; + void main() + { + float y = texture2D(y_texture, y_texCoord).x; + float u = texture2D(u_texture, uv_texCoord).x - adj; + float v = texture2D(v_texture, uv_texCoord).x - adj; + vec3 rgb = cc_matrix * vec3(y, u, v); + gl_FragColor = vec4(rgb, float(1)) * alpha; + } + ); +} + +FragmentShaderColor::FragmentShaderColor() + : m_colorLocation(-1) +{ +} + +bool FragmentShaderColor::init(GraphicsContext3D* context, unsigned program) +{ + m_colorLocation = context->getUniformLocation(program, "color"); + return m_colorLocation != -1; +} + +String FragmentShaderColor::getShaderString() const +{ + return SHADER( + precision mediump float; + uniform vec4 color; + void main() + { + gl_FragColor = vec4(color.xyz * color.w, color.w); + } + ); +} + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/ShaderChromium.h b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h new file mode 100644 index 0000000..758c62b --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/ShaderChromium.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ShaderChromium_h +#define ShaderChromium_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "PlatformString.h" + +#if USE(SKIA) +#include "SkColorPriv.h" +#endif + +namespace WebCore { + +class GraphicsContext3D; + +class VertexShaderPosTex { +public: + VertexShaderPosTex(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + +private: + int m_matrixLocation; +}; + +class VertexShaderPosTexYUVStretch { +public: + VertexShaderPosTexYUVStretch(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + int yWidthScaleFactorLocation() const { return m_yWidthScaleFactorLocation; } + int uvWidthScaleFactorLocation() const { return m_uvWidthScaleFactorLocation; } + +private: + int m_matrixLocation; + int m_yWidthScaleFactorLocation; + int m_uvWidthScaleFactorLocation; +}; + +class VertexShaderPos { +public: + VertexShaderPos(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + +private: + int m_matrixLocation; +}; + +class VertexShaderPosTexTransform { +public: + VertexShaderPosTexTransform(); + + bool init(GraphicsContext3D*, unsigned program); + String getShaderString() const; + + int matrixLocation() const { return m_matrixLocation; } + int texTransformLocation() const { return m_texTransformLocation; } + +private: + int m_matrixLocation; + int m_texTransformLocation; +}; + +class FragmentTexAlphaBinding { +public: + FragmentTexAlphaBinding(); + + bool init(GraphicsContext3D*, unsigned program); + int alphaLocation() const { return m_alphaLocation; } + int samplerLocation() const { return m_samplerLocation; } + +private: + int m_samplerLocation; + int m_alphaLocation; +}; + +class FragmentShaderRGBATexFlipAlpha : public FragmentTexAlphaBinding { +public: + String getShaderString() const; +}; + +class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding { +public: + String getShaderString() const; +}; + +class FragmentShaderBGRATexAlpha : public FragmentTexAlphaBinding { +public: + String getShaderString() const; +}; + +class FragmentShaderRGBATexAlphaMask { +public: + FragmentShaderRGBATexAlphaMask(); + String getShaderString() const; + + bool init(GraphicsContext3D*, unsigned program); + int alphaLocation() const { return m_alphaLocation; } + int samplerLocation() const { return m_samplerLocation; } + int maskSamplerLocation() const { return m_maskSamplerLocation; } + +private: + int m_samplerLocation; + int m_maskSamplerLocation; + int m_alphaLocation; +}; + +#if USE(SKIA) && SK_B32_SHIFT +typedef FragmentShaderRGBATexAlpha FragmentShaderTexAlpha; +#else +typedef FragmentShaderBGRATexAlpha FragmentShaderTexAlpha; +#endif + +class FragmentShaderYUVVideo { +public: + FragmentShaderYUVVideo(); + String getShaderString() const; + + bool init(GraphicsContext3D*, unsigned program); + + int yTextureLocation() const { return m_yTextureLocation; } + int uTextureLocation() const { return m_uTextureLocation; } + int vTextureLocation() const { return m_vTextureLocation; } + int alphaLocation() const { return m_alphaLocation; } + int ccMatrixLocation() const { return m_ccMatrixLocation; } + int signAdjLocation() const { return m_signAdjLocation; } + +private: + int m_yTextureLocation; + int m_uTextureLocation; + int m_vTextureLocation; + int m_alphaLocation; + int m_ccMatrixLocation; + int m_signAdjLocation; +}; + +class FragmentShaderColor { +public: + FragmentShaderColor(); + String getShaderString() const; + + bool init(GraphicsContext3D*, unsigned program); + int colorLocation() const { return m_colorLocation; } + +private: + int m_colorLocation; +}; + +} // namespace WebCore + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp index c4ad958..13cdb89 100644 --- a/Source/WebCore/platform/graphics/chromium/TextureManager.cpp +++ b/Source/WebCore/platform/graphics/chromium/TextureManager.cpp @@ -152,7 +152,7 @@ unsigned TextureManager::requestTexture(TextureToken token, IntSize size, unsign if (memoryRequiredBytes > m_memoryLimitBytes || !reduceMemoryToLimit(m_memoryLimitBytes - memoryRequiredBytes)) return 0; - unsigned textureId = m_context->createTexture(); + unsigned textureId; GLC(m_context.get(), textureId = m_context->createTexture()); GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); // Do basic linear filtering on resize. diff --git a/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h b/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h index e176b0c..ab669d1 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h +++ b/Source/WebCore/platform/graphics/chromium/VideoFrameChromium.h @@ -69,12 +69,15 @@ public: virtual SurfaceType surfaceType() const = 0; virtual Format format() const = 0; virtual unsigned width() const = 0; + virtual unsigned width(unsigned plane) const = 0; virtual unsigned height() const = 0; + virtual unsigned height(unsigned plane) const = 0; virtual unsigned planes() const = 0; virtual int stride(unsigned plane) const = 0; virtual const void* data(unsigned plane) const = 0; virtual unsigned texture(unsigned plane) const = 0; virtual const IntSize requiredTextureSize(unsigned plane) const = 0; + virtual bool hasPaddingBytes(unsigned plane) const = 0; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp index 41cd180..5d7a6e7 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp @@ -33,6 +33,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "VideoLayerChromium.h" +#include "cc/CCLayerImpl.h" #include "Extensions3DChromium.h" #include "GraphicsContext3D.h" #include "LayerRendererChromium.h" @@ -51,125 +52,6 @@ const float VideoLayerChromium::yuv2RGB[9] = { 1.403f, -.714f, 0.f, }; -VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) - : m_context(context) - , m_yuvShaderProgram(0) - , m_rgbaShaderProgram(0) - , m_yuvShaderMatrixLocation(0) - , m_yuvWidthScaleFactorLocation(0) - , m_rgbaShaderMatrixLocation(0) - , m_rgbaWidthScaleFactorLocation(0) - , m_ccMatrixLocation(0) - , m_signAdjLocation(0) - , m_yTextureLocation(0) - , m_uTextureLocation(0) - , m_vTextureLocation(0) - , m_rgbaTextureLocation(0) - , m_yuvAlphaLocation(0) - , m_rgbaAlphaLocation(0) - , m_initialized(false) -{ - // Frame textures are allocated based on stride width, not visible frame - // width, such that there is a guarantee that the frame rows line up - // properly and are not shifted by (stride - width) pixels. To hide the - // "padding" pixels between the edge of the visible frame width and the end - // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much - // of the width of the texture should be shown when drawing the texture onto - // the vertices. - char vertexShaderString[] = - "precision mediump float; \n" - "attribute vec4 a_position; \n" - "attribute vec2 a_texCoord; \n" - "uniform mat4 matrix; \n" - "varying vec2 v_texCoord; \n" - "uniform float widthScaleFactor; \n" - "void main() \n" - "{ \n" - " gl_Position = matrix * a_position; \n" - " v_texCoord = vec2(widthScaleFactor * a_texCoord.x, a_texCoord.y); \n" - "} \n"; - - char yuvFragmentShaderString[] = - "precision mediump float; \n" - "precision mediump int; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D y_texture; \n" - "uniform sampler2D u_texture; \n" - "uniform sampler2D v_texture; \n" - "uniform float alpha; \n" - "uniform float adj; \n" - "uniform mat3 cc_matrix; \n" - "void main() \n" - "{ \n" - " float y = texture2D(y_texture, v_texCoord).x; \n" - " float u = texture2D(u_texture, v_texCoord).x - adj; \n" - " float v = texture2D(v_texture, v_texCoord).x - adj; \n" - " vec3 rgb = cc_matrix * vec3(y, u, v); \n" - " gl_FragColor = vec4(rgb, float(1)) * alpha; \n" - "} \n"; - - char rgbaFragmentShaderString[] = - "precision mediump float; \n" - "varying vec2 v_texCoord; \n" - "uniform sampler2D rgba_texture; \n" - "uniform float alpha; \n" - "void main() \n" - "{ \n" - " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, float(1) - v_texCoord.y)); \n" - " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) * alpha; \n" - "} \n"; - - m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgbaFragmentShaderString); - if (!m_rgbaShaderProgram) { - LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program"); - return; - } - - m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvFragmentShaderString); - if (!m_yuvShaderProgram) { - LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program"); - return; - } - - m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "matrix"); - m_yuvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProgram, "widthScaleFactor"); - m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_texture"); - m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_texture"); - m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_texture"); - m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_matrix"); - m_signAdjLocation = m_context->getUniformLocation(m_yuvShaderProgram, "adj"); - m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alpha"); - - ASSERT(m_yuvShaderMatrixLocation != -1); - ASSERT(m_yuvWidthScaleFactorLocation != -1); - ASSERT(m_yTextureLocation != -1); - ASSERT(m_uTextureLocation != -1); - ASSERT(m_vTextureLocation != -1); - ASSERT(m_ccMatrixLocation != -1); - ASSERT(m_signAdjLocation != -1); - ASSERT(m_yuvAlphaLocation != -1); - - m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "matrix"); - m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "rgba_texture"); - m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "widthScaleFactor"); - m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "alpha"); - - ASSERT(m_rgbaShaderMatrixLocation != -1); - ASSERT(m_rgbaTextureLocation != -1); - ASSERT(m_rgbaWidthScaleFactorLocation != -1); - ASSERT(m_rgbaAlphaLocation != -1); - - m_initialized = true; -} - -VideoLayerChromium::SharedValues::~SharedValues() -{ - if (m_yuvShaderProgram) - GLC(m_context, m_context->deleteProgram(m_yuvShaderProgram)); - if (m_rgbaShaderProgram) - GLC(m_context, m_context->deleteProgram(m_rgbaShaderProgram)); -} - PassRefPtr<VideoLayerChromium> VideoLayerChromium::create(GraphicsLayerChromium* owner, VideoFrameProvider* provider) { @@ -297,9 +179,27 @@ bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, Vi if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[plane]) { allocateTexture(context, m_textures[plane], planeTextureSize, textureFormat); m_textureSizes[plane] = planeTextureSize; - m_frameSizes[plane] = IntSize(frame->width(), frame->height()); + int frameWidth = frame->width(plane); + int frameHeight = frame->height(plane); + // When there are dead pixels at the edge of the texture, decrease + // the frame width by 1 to prevent the rightmost pixels from + // interpolating with the dead pixels. + if (frame->hasPaddingBytes(plane)) + --frameWidth; + m_frameSizes[plane] = IntSize(frameWidth, frameHeight); } } + + // In YV12, every 2x2 square of Y values corresponds to one U and + // one V value. If we decrease the width of the UV plane, we must decrease the + // width of the Y texture by 2 for proper alignment. This must happen + // always, even if Y's texture does not have padding bytes. + if (frame->format() == VideoFrameChromium::YV12) { + int yPlaneOriginalWidth = frame->width(VideoFrameChromium::yPlane); + if (frame->hasPaddingBytes(VideoFrameChromium::uPlane)) + m_frameSizes[VideoFrameChromium::yPlane].setWidth(yPlaneOriginalWidth - 2); + } + return true; } @@ -318,9 +218,10 @@ void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text memcpy(mem, data, dimensions.width() * dimensions.height()); GLC(context, static_cast<Extensions3DChromium*>(context->getExtensions())->unmapTexSubImage2DCHROMIUM(mem)); } else { - // FIXME: We should have some sort of code to handle the case when - // mapTexSubImage2D fails. - m_skipsDraw = true; + // If mapTexSubImage2DCHROMIUM fails, then do the slower texSubImage2D + // upload. This does twice the copies as mapTexSubImage2DCHROMIUM, one + // in the command buffer and another to the texture. + GLC(context, context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, dimensions.width(), dimensions.height(), format, GraphicsContext3D::UNSIGNED_BYTE, data)); } } @@ -330,16 +231,18 @@ void VideoLayerChromium::draw() return; ASSERT(layerRenderer()); - const VideoLayerChromium::SharedValues* sv = layerRenderer()->videoLayerSharedValues(); - ASSERT(sv && sv->initialized()); + const RGBAProgram* rgbaProgram = layerRenderer()->videoLayerRGBAProgram(); + ASSERT(rgbaProgram && rgbaProgram->initialized()); + const YUVProgram* yuvProgram = layerRenderer()->videoLayerYUVProgram(); + ASSERT(yuvProgram && yuvProgram->initialized()); switch (m_frameFormat) { case VideoFrameChromium::YV12: case VideoFrameChromium::YV16: - drawYUV(sv); + drawYUV(yuvProgram); break; case VideoFrameChromium::RGBA: - drawRGBA(sv); + drawRGBA(rgbaProgram); break; default: // FIXME: Implement other paths. @@ -359,7 +262,7 @@ void VideoLayerChromium::releaseCurrentFrame() resetFrameParameters(); } -void VideoLayerChromium::drawYUV(const SharedValues* sv) +void VideoLayerChromium::drawYUV(const VideoLayerChromium::YUVProgram* program) { GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1)); @@ -369,49 +272,57 @@ void VideoLayerChromium::drawYUV(const SharedValues* sv) GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::vPlane])); - layerRenderer()->useShader(sv->yuvShaderProgram()); - unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); - unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); - float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; - GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScaleFactor)); + layerRenderer()->useShader(program->program()); + unsigned yFrameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); + unsigned yTextureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); + // Arbitrarily take the u sizes because u and v dimensions are identical. + unsigned uvFrameWidth = m_frameSizes[VideoFrameChromium::uPlane].width(); + unsigned uvTextureWidth = m_textureSizes[VideoFrameChromium::uPlane].width(); + + float yWidthScaleFactor = static_cast<float>(yFrameWidth) / yTextureWidth; + float uvWidthScaleFactor = static_cast<float>(uvFrameWidth) / uvTextureWidth; + GLC(context, context->uniform1f(program->vertexShader().yWidthScaleFactorLocation(), yWidthScaleFactor)); + GLC(context, context->uniform1f(program->vertexShader().uvWidthScaleFactorLocation(), uvWidthScaleFactor)); - GLC(context, context->uniform1i(sv->yTextureLocation(), 1)); - GLC(context, context->uniform1i(sv->uTextureLocation(), 2)); - GLC(context, context->uniform1i(sv->vTextureLocation(), 3)); + GLC(context, context->uniform1i(program->fragmentShader().yTextureLocation(), 1)); + GLC(context, context->uniform1i(program->fragmentShader().uTextureLocation(), 2)); + GLC(context, context->uniform1i(program->fragmentShader().vTextureLocation(), 3)); // This value of 0.5 maps to 128. It is used in the YUV to RGB conversion // formula to turn unsigned u and v values to signed u and v values. // This is loaded as a uniform because certain drivers have problems // reading literal float values. - GLC(context, context->uniform1f(sv->signAdjLocation(), 0.5)); + GLC(context, context->uniform1f(program->fragmentShader().signAdjLocation(), 0.5)); - GLC(context, context->uniformMatrix3fv(sv->ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); + GLC(context, context->uniformMatrix3fv(program->fragmentShader().ccMatrixLocation(), 0, const_cast<float*>(yuv2RGB), 1)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->yuvShaderMatrixLocation(), sv->yuvAlphaLocation()); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); // Reset active texture back to texture 0. GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); } -void VideoLayerChromium::drawRGBA(const SharedValues* sv) +void VideoLayerChromium::drawRGBA(const VideoLayerChromium::RGBAProgram* program) { GraphicsContext3D* context = layerRendererContext(); GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[VideoFrameChromium::rgbPlane])); - layerRenderer()->useShader(sv->rgbaShaderProgram()); + layerRenderer()->useShader(program->program()); unsigned frameWidth = m_frameSizes[VideoFrameChromium::rgbPlane].width(); unsigned textureWidth = m_textureSizes[VideoFrameChromium::rgbPlane].width(); float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; - GLC(context, context->uniform1f(sv->rgbaWidthScaleFactorLocation(), widthScaleFactor)); + GLC(context, context->uniform4f(program->vertexShader().texTransformLocation(), 0, 0, widthScaleFactor, 1)); - GLC(context, context->uniform1i(sv->rgbaTextureLocation(), 0)); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); - drawTexturedQuad(context, layerRenderer()->projectionMatrix(), drawTransform(), - bounds().width(), bounds().height(), drawOpacity(), - sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation()); + drawTexturedQuad(context, layerRenderer()->projectionMatrix(), ccLayerImpl()->drawTransform(), + bounds().width(), bounds().height(), ccLayerImpl()->drawOpacity(), + program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); } void VideoLayerChromium::resetFrameParameters() diff --git a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h index ac3bca9..2170e13 100644 --- a/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/VideoLayerChromium.h @@ -46,53 +46,19 @@ public: VideoFrameProvider* = 0); virtual ~VideoLayerChromium(); virtual void updateContentsIfDirty(); - virtual bool drawsContent() { return true; } + virtual bool drawsContent() const { return true; } virtual void draw(); // This function is called by VideoFrameProvider. When this method is called // putCurrentFrame() must be called to return the frame currently held. void releaseCurrentFrame(); - class SharedValues { - public: - explicit SharedValues(GraphicsContext3D*); - ~SharedValues(); - unsigned yuvShaderProgram() const { return m_yuvShaderProgram; } - unsigned rgbaShaderProgram() const { return m_rgbaShaderProgram; } - int yuvShaderMatrixLocation() const { return m_yuvShaderMatrixLocation; } - int rgbaShaderMatrixLocation() const { return m_rgbaShaderMatrixLocation; } - int yuvWidthScaleFactorLocation() const { return m_yuvWidthScaleFactorLocation; } - int rgbaWidthScaleFactorLocation() const { return m_rgbaWidthScaleFactorLocation; } - int yTextureLocation() const { return m_yTextureLocation; } - int uTextureLocation() const { return m_uTextureLocation; } - int vTextureLocation() const { return m_vTextureLocation; } - int yuvAlphaLocation() const { return m_yuvAlphaLocation; } - int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; } - int rgbaTextureLocation() const { return m_rgbaTextureLocation; } - int ccMatrixLocation() const { return m_ccMatrixLocation; } - int signAdjLocation() const { return m_signAdjLocation; } - bool initialized() const { return m_initialized; } - private: - GraphicsContext3D* m_context; - unsigned m_yuvShaderProgram; - unsigned m_rgbaShaderProgram; - int m_yuvShaderMatrixLocation; - int m_yuvWidthScaleFactorLocation; - int m_rgbaShaderMatrixLocation; - int m_rgbaWidthScaleFactorLocation; - int m_ccMatrixLocation; - int m_signAdjLocation; - int m_yTextureLocation; - int m_uTextureLocation; - int m_vTextureLocation; - int m_rgbaTextureLocation; - int m_yuvAlphaLocation; - int m_rgbaAlphaLocation; - bool m_initialized; - }; + typedef ProgramBinding<VertexShaderPosTexTransform, FragmentShaderRGBATexFlipAlpha> RGBAProgram; + typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo> YUVProgram; protected: virtual void cleanupResources(); + virtual const char* layerTypeAsString() const { return "VideoLayer"; } private: VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameProvider*); @@ -103,8 +69,8 @@ private: void updateRGBAContents(GraphicsContext3D*, const VideoFrameChromium*); void allocateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat); void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data); - void drawYUV(const SharedValues*); - void drawRGBA(const SharedValues*); + void drawYUV(const YUVProgram*); + void drawRGBA(const RGBAProgram*); void resetFrameParameters(); void saveCurrentFrame(VideoFrameChromium*); diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp index 5b34bb9..e83d045 100644 --- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp +++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp @@ -82,6 +82,7 @@ void WebGLLayerChromium::setContext(const GraphicsContext3D* context) if (textureId != m_textureId) m_textureChanged = true; m_textureId = textureId; + m_premultipliedAlpha = m_context->getContextAttributes().premultipliedAlpha; } } diff --git a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h index c67cc2c..70be876 100644 --- a/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h +++ b/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.h @@ -44,11 +44,14 @@ class GraphicsContext3D; class WebGLLayerChromium : public CanvasLayerChromium { public: static PassRefPtr<WebGLLayerChromium> create(GraphicsLayerChromium* owner = 0); - virtual bool drawsContent() { return m_context; } + virtual bool drawsContent() const { return m_context; } virtual void updateContentsIfDirty(); void setContext(const GraphicsContext3D* context); +protected: + virtual const char* layerTypeAsString() const { return "WebGLLayer"; } + private: explicit WebGLLayerChromium(GraphicsLayerChromium* owner); GraphicsContext3D* m_context; diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp new file mode 100644 index 0000000..604ef61 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.cpp @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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" + +#if USE(ACCELERATED_COMPOSITING) +#include "CCHeadsUpDisplay.h" + +#include "CurrentTime.h" +#include "Font.h" +#include "FontDescription.h" +#include "GraphicsContext3D.h" +#include "LayerChromium.h" +#include "LayerTexture.h" +#include "TextRun.h" +#include "TextStream.h" +#include "TextureManager.h" +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +using namespace std; + +CCHeadsUpDisplay::CCHeadsUpDisplay(LayerRendererChromium* owner) + : m_currentFrameNumber(0) + , m_layerRenderer(owner) + , m_showFPSCounter(false) + , m_showPlatformLayerTree(false) +{ + m_presentTimeHistoryInSec[0] = currentTime(); + m_presentTimeHistoryInSec[1] = m_presentTimeHistoryInSec[0]; +} + +CCHeadsUpDisplay::~CCHeadsUpDisplay() +{ +} + +void CCHeadsUpDisplay::draw() +{ + GraphicsContext3D* context = m_layerRenderer->context(); + if (!m_hudTexture) + m_hudTexture = LayerTexture::create(context, m_layerRenderer->textureManager()); + + // Use a fullscreen texture only if we need to... + IntSize hudSize; + if (m_showPlatformLayerTree) { + hudSize.setWidth(min(2048, m_layerRenderer->visibleRectSize().width())); + hudSize.setHeight(min(2048, m_layerRenderer->visibleRectSize().height())); + } else { + hudSize.setWidth(512); + hudSize.setHeight(128); + } + + m_hudTexture->reserve(hudSize, GraphicsContext3D::RGBA); + + // Render pixels into the texture. + PlatformCanvas canvas; + canvas.resize(hudSize); + { + PlatformCanvas::Painter painter(&canvas); + drawHudContents(painter.context(), hudSize); + } + + // Upload to GL. + { + PlatformCanvas::AutoLocker locker(&canvas); + + m_hudTexture->bindTexture(); + GLC(context.get(), context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, canvas.size().width(), canvas.size().height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, locker.pixels())); + } + + // Draw the HUD onto the default render surface. + const ContentLayerChromium::Program* program = m_layerRenderer->contentLayerProgram(); + ASSERT(program && program->initialized()); + GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE0)); + m_hudTexture->bindTexture(); + m_layerRenderer->useShader(program->program()); + GLC(context, context->uniform1i(program->fragmentShader().samplerLocation(), 0)); + + TransformationMatrix matrix; + matrix.translate3d(hudSize.width() * 0.5, hudSize.height() * 0.5, 0); + LayerChromium::drawTexturedQuad(context, m_layerRenderer->projectionMatrix(), + matrix, hudSize.width(), hudSize.height(), + 1.0f, program->vertexShader().matrixLocation(), + program->fragmentShader().alphaLocation()); + + m_hudTexture->unreserve(); +} + +void CCHeadsUpDisplay::drawHudContents(GraphicsContext* ctx, const IntSize& hudSize) +{ + FontDescription mediumFontDesc; + mediumFontDesc.setGenericFamily(FontDescription::MonospaceFamily); + mediumFontDesc.setComputedSize(12); + Font mediumFont(mediumFontDesc, 0, 0); + mediumFont.update(0); + + FontDescription smallFontDesc; + smallFontDesc.setGenericFamily(FontDescription::MonospaceFamily); + smallFontDesc.setComputedSize(10); + Font smallFont(smallFontDesc, 0, 0); + smallFont.update(0); + + // We haven't finished rendering yet, so we don't now the "current" present time. + // So, consider the *last two* present times and use those as our present time. + double secForLastFrame = m_presentTimeHistoryInSec[(m_currentFrameNumber - 1) % 2] - m_presentTimeHistoryInSec[m_currentFrameNumber % 2]; + + int y = 14; + + if (m_showPlatformLayerTree) { + ctx->setFillColor(Color(0, 0, 0, 192), ColorSpaceDeviceRGB); + ctx->fillRect(FloatRect(0, 0, hudSize.width(), hudSize.height())); + } + + // Draw fps. + String topLine = ""; + if (secForLastFrame > 0 && m_showFPSCounter) { + double fps = 1.0 / secForLastFrame; + topLine += String::format("FPS: %3.1f", fps); + } + if (topLine.length()) { + ctx->setFillColor(Color(0, 0, 0, 255), ColorSpaceDeviceRGB); + TextRun run(topLine); + ctx->fillRect(FloatRect(2, 2, mediumFont.width(run) + 2.0f, 15)); + ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB); + ctx->drawText(mediumFont, run, IntPoint(3, y)); + y = 26; + } + + // Draw layer tree, if enabled. + if (m_showPlatformLayerTree) { + ctx->setFillColor(Color(255, 0, 0), ColorSpaceDeviceRGB); + Vector<String> lines; + m_layerRenderer->layerTreeAsText().split('\n', lines); + for (size_t i = 0; i < lines.size(); ++i) { + ctx->drawText(smallFont, TextRun(lines[i]), IntPoint(2, y)); + y += 12; + } + } +} + +void CCHeadsUpDisplay::onPresent() +{ + m_presentTimeHistoryInSec[m_currentFrameNumber % 2] = currentTime(); + m_currentFrameNumber += 1; +} + +} + +#endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h new file mode 100644 index 0000000..dbac22a --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCHeadsUpDisplay.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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. + */ + +#ifndef CCHeadsUpDisplay_h +#define CCHeadsUpDisplay_h + +#if USE(ACCELERATED_COMPOSITING) + +#include "LayerRendererChromium.h" + +namespace WebCore { + +class GeometryBinding; +class GraphicsContext3D; + +// Class that handles drawing of composited render layers using GL. +class CCHeadsUpDisplay { + WTF_MAKE_NONCOPYABLE(CCHeadsUpDisplay); +public: + static PassOwnPtr<CCHeadsUpDisplay> create(LayerRendererChromium* owner) + { + return adoptPtr(new CCHeadsUpDisplay(owner)); + } + + ~CCHeadsUpDisplay(); + + void onPresent(); + + void setShowFPSCounter(bool enable) { m_showFPSCounter = enable; } + bool showFPSCounter() const { return m_showFPSCounter; } + + void setShowPlatformLayerTree(bool enable) { m_showPlatformLayerTree = enable; } + bool showPlatformLayerTree() const { return m_showPlatformLayerTree; } + + bool enabled() const { return true || m_showPlatformLayerTree || m_showFPSCounter; } + void draw(); + +private: + explicit CCHeadsUpDisplay(LayerRendererChromium* owner); + void drawHudContents(GraphicsContext*, const IntSize& hudSize); + + int m_currentFrameNumber; + + OwnPtr<LayerTexture> m_hudTexture; + + LayerRendererChromium* m_layerRenderer; + + double m_presentTimeHistoryInSec[2]; + + bool m_showFPSCounter; + bool m_showPlatformLayerTree; +}; + +} + +#endif // USE(ACCELERATED_COMPOSITING) + +#endif diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp new file mode 100644 index 0000000..a0ad0fb --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#if USE(ACCELERATED_COMPOSITING) + +#include "cc/CCLayerImpl.h" + +#include "GraphicsContext3D.h" +#include "LayerChromium.h" // FIXME: temporary and bad +#include "LayerRendererChromium.h" +#include "RenderSurfaceChromium.h" +#include <wtf/text/WTFString.h> + +namespace { +void toGLMatrix(float* flattened, const WebCore::TransformationMatrix& m) +{ + flattened[0] = m.m11(); + flattened[1] = m.m12(); + flattened[2] = m.m13(); + flattened[3] = m.m14(); + flattened[4] = m.m21(); + flattened[5] = m.m22(); + flattened[6] = m.m23(); + flattened[7] = m.m24(); + flattened[8] = m.m31(); + flattened[9] = m.m32(); + flattened[10] = m.m33(); + flattened[11] = m.m34(); + flattened[12] = m.m41(); + flattened[13] = m.m42(); + flattened[14] = m.m43(); + flattened[15] = m.m44(); +} +} + + +namespace WebCore { + +CCLayerImpl::CCLayerImpl(LayerChromium* owner) + : m_owner(owner) +#ifndef NDEBUG + , m_debugID(owner->debugID()) +#endif + , m_targetRenderSurface(0) + , m_drawDepth(0) + , m_drawOpacity(0) + , m_doubleSided(true) + , m_debugBorderColor(0, 0, 0, 0) + , m_debugBorderWidth(0) + , m_renderSurface(0) + , m_layerRenderer(0) +{ +} + +CCLayerImpl::~CCLayerImpl() +{ +} + +// These are pseudo-structural hacks until we get real tree syncing up in this piece. +CCLayerImpl* CCLayerImpl::superlayer() const +{ + return m_owner->superlayer() ? m_owner->superlayer()->ccLayerImpl() : 0; +} + +CCLayerImpl* CCLayerImpl::maskLayer() const +{ + return m_owner->maskLayer() ? m_owner->maskLayer()->ccLayerImpl() : 0; +} + +CCLayerImpl* CCLayerImpl::replicaLayer() const +{ + return m_owner->replicaLayer() ? m_owner->replicaLayer()->ccLayerImpl() : 0; +} + +void CCLayerImpl::setLayerRenderer(LayerRendererChromium* renderer) +{ + m_layerRenderer = renderer; +} + +RenderSurfaceChromium* CCLayerImpl::createRenderSurface() +{ + m_renderSurface = new RenderSurfaceChromium(this); + return m_renderSurface.get(); +} + +// These belong on CCLayerImpl, but should be subclased by each type and not defer to the LayerChromium subtypes. +bool CCLayerImpl::drawsContent() const +{ + return m_owner->drawsContent(); +} + +void CCLayerImpl::draw() +{ + return m_owner->draw(); +} + +void CCLayerImpl::unreserveContentsTexture() +{ + m_owner->unreserveContentsTexture(); +} + +void CCLayerImpl::bindContentsTexture() +{ + m_owner->bindContentsTexture(); +} + +void CCLayerImpl::cleanupResources() +{ + if (renderSurface()) + renderSurface()->cleanupResources(); +} + +const IntRect CCLayerImpl::getDrawRect() const +{ + // Form the matrix used by the shader to map the corners of the layer's + // bounds into the view space. + FloatRect layerRect(-0.5 * bounds().width(), -0.5 * bounds().height(), bounds().width(), bounds().height()); + IntRect mappedRect = enclosingIntRect(drawTransform().mapRect(layerRect)); + return mappedRect; +} + +void CCLayerImpl::drawDebugBorder() +{ + static float glMatrix[16]; + if (!debugBorderColor().alpha()) + return; + + ASSERT(layerRenderer()); + const LayerChromium::BorderProgram* program = layerRenderer()->borderProgram(); + ASSERT(program && program->initialized()); + layerRenderer()->useShader(program->program()); + TransformationMatrix renderMatrix = drawTransform(); + renderMatrix.scale3d(bounds().width(), bounds().height(), 1); + toGLMatrix(&glMatrix[0], layerRenderer()->projectionMatrix() * renderMatrix); + GraphicsContext3D* context = layerRenderer()->context(); + GLC(context, context->uniformMatrix4fv(program->vertexShader().matrixLocation(), false, &glMatrix[0], 1)); + + GLC(context, context->uniform4f(program->fragmentShader().colorLocation(), debugBorderColor().red() / 255.0, debugBorderColor().green() / 255.0, debugBorderColor().blue() / 255.0, 1)); + + GLC(context, context->lineWidth(debugBorderWidth())); + + // The indices for the line are stored in the same array as the triangle indices. + GLC(context, context->drawElements(GraphicsContext3D::LINE_LOOP, 4, GraphicsContext3D::UNSIGNED_SHORT, 6 * sizeof(unsigned short))); +} + +static void writeIndent(TextStream& ts, int indent) +{ + for (int i = 0; i != indent; ++i) + ts << " "; +} + +void CCLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const +{ + writeIndent(ts, indent); + ts << "bounds: " << bounds().width() << ", " << bounds().height() << "\n"; + + if (m_targetRenderSurface) { + writeIndent(ts, indent); + ts << "targetRenderSurface: " << m_targetRenderSurface->name() << "\n"; + } + + writeIndent(ts, indent); + ts << "drawTransform: "; + ts << m_drawTransform.m11() << ", " << m_drawTransform.m12() << ", " << m_drawTransform.m13() << ", " << m_drawTransform.m14() << ", "; + ts << m_drawTransform.m21() << ", " << m_drawTransform.m22() << ", " << m_drawTransform.m23() << ", " << m_drawTransform.m24() << ", "; + ts << m_drawTransform.m31() << ", " << m_drawTransform.m32() << ", " << m_drawTransform.m33() << ", " << m_drawTransform.m34() << ", "; + ts << m_drawTransform.m41() << ", " << m_drawTransform.m42() << ", " << m_drawTransform.m43() << ", " << m_drawTransform.m44() << "\n"; +} + +} + +#endif // USE(ACCELERATED_COMPOSITING) + diff --git a/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h new file mode 100644 index 0000000..6892976 --- /dev/null +++ b/Source/WebCore/platform/graphics/chromium/cc/CCLayerImpl.h @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef CCLayerImpl_h +#define CCLayerImpl_h + +#include "Color.h" +#include "FloatRect.h" +#include "IntRect.h" +#include "TextStream.h" +#include "TransformationMatrix.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class LayerChromium; +class LayerRendererChromium; +class RenderSurfaceChromium; + +class CCLayerImpl : public RefCounted<CCLayerImpl> { +public: + static PassRefPtr<CCLayerImpl> create(LayerChromium* owner) + { + return adoptRef(new CCLayerImpl(owner)); + } + // When this class gets subclasses, remember to add 'virtual' here. + ~CCLayerImpl(); + +#ifndef NDEBUG + int debugID() const { return m_debugID; } +#endif + + CCLayerImpl* superlayer() const; + CCLayerImpl* maskLayer() const; + CCLayerImpl* replicaLayer() const; + + void draw(); + bool drawsContent() const; + void unreserveContentsTexture(); + void bindContentsTexture(); + + void cleanupResources(); + + void setName(const String& name) { m_name = name; } + const String& name() const { return m_name; } + + // Debug layer border - visual effect only, do not change geometry/clipping/etc. + void setDebugBorderColor(Color c) { m_debugBorderColor = c; } + Color debugBorderColor() const { return m_debugBorderColor; } + void setDebugBorderWidth(float width) { m_debugBorderWidth = width; } + float debugBorderWidth() const { return m_debugBorderWidth; } + + void drawDebugBorder(); + + void setLayerRenderer(LayerRendererChromium*); + LayerRendererChromium* layerRenderer() const { return m_layerRenderer.get(); } + + RenderSurfaceChromium* createRenderSurface(); + + RenderSurfaceChromium* renderSurface() const { return m_renderSurface.get(); } + void clearRenderSurface() { m_renderSurface.clear(); } + float drawDepth() const { return m_drawDepth; } + void setDrawDepth(float depth) { m_drawDepth = depth; } + float drawOpacity() const { return m_drawOpacity; } + void setDrawOpacity(float opacity) { m_drawOpacity = opacity; } + const IntRect& scissorRect() const { return m_scissorRect; } + void setScissorRect(const IntRect& rect) { m_scissorRect = rect; } + RenderSurfaceChromium* targetRenderSurface() const { return m_targetRenderSurface; } + void setTargetRenderSurface(RenderSurfaceChromium* surface) { m_targetRenderSurface = surface; } + + bool doubleSided() const { return m_doubleSided; } + void setDoubleSided(bool doubleSided) { m_doubleSided = doubleSided; } + const IntSize& bounds() const { return m_bounds; } + void setBounds(const IntSize& bounds) { m_bounds = bounds; } + + // Returns the rect containtaining this layer in the current view's coordinate system. + const IntRect getDrawRect() const; + + const TransformationMatrix& drawTransform() const { return m_drawTransform; } + void setDrawTransform(const TransformationMatrix& matrix) { m_drawTransform = matrix; } + const IntRect& drawableContentRect() const { return m_drawableContentRect; } + void setDrawableContentRect(const IntRect& rect) { m_drawableContentRect = rect; } + + virtual void dumpLayerProperties(TextStream&, int indent) const; + +private: + // For now, CCLayers are owned directly by a LayerChromium. + LayerChromium* m_owner; + explicit CCLayerImpl(LayerChromium*); + + // Debugging. +#ifndef NDEBUG + int m_debugID; +#endif + + String m_name; + + // Render surface this layer draws into. This is a surface that can belong + // either to this layer (if m_targetRenderSurface == m_renderSurface) or + // to an ancestor of this layer. The target render surface determines the + // coordinate system the layer's transforms are relative to. + RenderSurfaceChromium* m_targetRenderSurface; + + // The global depth value of the center of the layer. This value is used + // to sort layers from back to front. + float m_drawDepth; + float m_drawOpacity; + + // Whether the "back" of this layer should draw. + bool m_doubleSided; + + // Debug borders. + Color m_debugBorderColor; + float m_debugBorderWidth; + + TransformationMatrix m_drawTransform; + + IntSize m_bounds; + + // The scissor rectangle that should be used when this layer is drawn. + // Inherited by the parent layer and further restricted if this layer masks + // to bounds. + IntRect m_scissorRect; + + // Render surface associated with this layer. The layer and its descendants + // will render to this surface. + OwnPtr<RenderSurfaceChromium> m_renderSurface; + + // Hierarchical bounding rect containing the layer and its descendants. + IntRect m_drawableContentRect; + + // Points to the layer renderer that updates and draws this layer. + RefPtr<LayerRendererChromium> m_layerRenderer; +}; + +} + +#endif // CCLayerImpl_h + diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp index ac68266..e5db03e 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp @@ -53,9 +53,12 @@ BlendModeType FEBlend::blendMode() const return m_mode; } -void FEBlend::setBlendMode(BlendModeType mode) +bool FEBlend::setBlendMode(BlendModeType mode) { + if (m_mode == mode) + return false; m_mode = mode; + return true; } static unsigned char unknown(unsigned char, unsigned char, unsigned char, unsigned char) diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.h b/Source/WebCore/platform/graphics/filters/FEBlend.h index 4c59578..def33be 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.h +++ b/Source/WebCore/platform/graphics/filters/FEBlend.h @@ -43,7 +43,7 @@ public: static PassRefPtr<FEBlend> create(Filter*, BlendModeType); BlendModeType blendMode() const; - void setBlendMode(BlendModeType); + bool setBlendMode(BlendModeType); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp index 33c4467..f324830 100644 --- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -52,9 +52,12 @@ ColorMatrixType FEColorMatrix::type() const return m_type; } -void FEColorMatrix::setType(ColorMatrixType type) +bool FEColorMatrix::setType(ColorMatrixType type) { + if (m_type == type) + return false; m_type = type; + return true; } const Vector<float>& FEColorMatrix::values() const @@ -62,9 +65,12 @@ const Vector<float>& FEColorMatrix::values() const return m_values; } -void FEColorMatrix::setValues(const Vector<float> &values) +bool FEColorMatrix::setValues(const Vector<float> &values) { + if (m_values == values) + return false; m_values = values; + return true; } inline void matrix(double& red, double& green, double& blue, double& alpha, const Vector<float>& values) diff --git a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h index a3ced7e..5bdfa74 100644 --- a/Source/WebCore/platform/graphics/filters/FEColorMatrix.h +++ b/Source/WebCore/platform/graphics/filters/FEColorMatrix.h @@ -43,10 +43,10 @@ public: static PassRefPtr<FEColorMatrix> create(Filter*, ColorMatrixType, const Vector<float>&); ColorMatrixType type() const; - void setType(ColorMatrixType); + bool setType(ColorMatrixType); const Vector<float>& values() const; - void setValues(const Vector<float>&); + bool setValues(const Vector<float>&); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.cpp b/Source/WebCore/platform/graphics/filters/FEComposite.cpp index bc7fa80..eead000 100644 --- a/Source/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/Source/WebCore/platform/graphics/filters/FEComposite.cpp @@ -55,9 +55,12 @@ CompositeOperationType FEComposite::operation() const return m_type; } -void FEComposite::setOperation(CompositeOperationType type) +bool FEComposite::setOperation(CompositeOperationType type) { + if (m_type == type) + return false; m_type = type; + return true; } float FEComposite::k1() const @@ -65,9 +68,12 @@ float FEComposite::k1() const return m_k1; } -void FEComposite::setK1(float k1) +bool FEComposite::setK1(float k1) { + if (m_k1 == k1) + return false; m_k1 = k1; + return true; } float FEComposite::k2() const @@ -75,9 +81,12 @@ float FEComposite::k2() const return m_k2; } -void FEComposite::setK2(float k2) +bool FEComposite::setK2(float k2) { + if (m_k2 == k2) + return false; m_k2 = k2; + return true; } float FEComposite::k3() const @@ -85,9 +94,12 @@ float FEComposite::k3() const return m_k3; } -void FEComposite::setK3(float k3) +bool FEComposite::setK3(float k3) { + if (m_k3 == k3) + return false; m_k3 = k3; + return true; } float FEComposite::k4() const @@ -95,9 +107,12 @@ float FEComposite::k4() const return m_k4; } -void FEComposite::setK4(float k4) +bool FEComposite::setK4(float k4) { + if (m_k4 == k4) + return false; m_k4 = k4; + return true; } template <int b1, int b2, int b3, int b4> diff --git a/Source/WebCore/platform/graphics/filters/FEComposite.h b/Source/WebCore/platform/graphics/filters/FEComposite.h index b846902..481c6a7 100644 --- a/Source/WebCore/platform/graphics/filters/FEComposite.h +++ b/Source/WebCore/platform/graphics/filters/FEComposite.h @@ -45,19 +45,19 @@ public: static PassRefPtr<FEComposite> create(Filter*, const CompositeOperationType&, float, float, float, float); CompositeOperationType operation() const; - void setOperation(CompositeOperationType); + bool setOperation(CompositeOperationType); float k1() const; - void setK1(float); + bool setK1(float); float k2() const; - void setK2(float); + bool setK2(float); float k3() const; - void setK3(float); + bool setK3(float); float k4() const; - void setK4(float); + bool setK4(float); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp index 0483626..a1f8dfd 100644 --- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp +++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp @@ -63,7 +63,7 @@ IntSize FEConvolveMatrix::kernelSize() const return m_kernelSize; } -void FEConvolveMatrix::setKernelSize(IntSize kernelSize) +void FEConvolveMatrix::setKernelSize(const IntSize& kernelSize) { m_kernelSize = kernelSize; } @@ -83,9 +83,12 @@ float FEConvolveMatrix::divisor() const return m_divisor; } -void FEConvolveMatrix::setDivisor(float divisor) +bool FEConvolveMatrix::setDivisor(float divisor) { - m_divisor = divisor; + if (m_divisor == divisor) + return false; + m_divisor = divisor; + return true; } float FEConvolveMatrix::bias() const @@ -93,9 +96,12 @@ float FEConvolveMatrix::bias() const return m_bias; } -void FEConvolveMatrix::setBias(float bias) +bool FEConvolveMatrix::setBias(float bias) { - m_bias = bias; + if (m_bias == bias) + return false; + m_bias = bias; + return true; } IntPoint FEConvolveMatrix::targetOffset() const @@ -103,19 +109,25 @@ IntPoint FEConvolveMatrix::targetOffset() const return m_targetOffset; } -void FEConvolveMatrix::setTargetOffset(IntPoint targetOffset) +bool FEConvolveMatrix::setTargetOffset(const IntPoint& targetOffset) { - m_targetOffset = targetOffset; + if (m_targetOffset == targetOffset) + return false; + m_targetOffset = targetOffset; + return true; } EdgeModeType FEConvolveMatrix::edgeMode() const { - return m_edgeMode; + return m_edgeMode; } -void FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode) +bool FEConvolveMatrix::setEdgeMode(EdgeModeType edgeMode) { - m_edgeMode = edgeMode; + if (m_edgeMode == edgeMode) + return false; + m_edgeMode = edgeMode; + return true; } FloatPoint FEConvolveMatrix::kernelUnitLength() const @@ -123,9 +135,12 @@ FloatPoint FEConvolveMatrix::kernelUnitLength() const return m_kernelUnitLength; } -void FEConvolveMatrix::setKernelUnitLength(FloatPoint kernelUnitLength) +bool FEConvolveMatrix::setKernelUnitLength(const FloatPoint& kernelUnitLength) { - m_kernelUnitLength = kernelUnitLength; + if (m_kernelUnitLength == kernelUnitLength) + return false; + m_kernelUnitLength = kernelUnitLength; + return true; } bool FEConvolveMatrix::preserveAlpha() const @@ -133,9 +148,12 @@ bool FEConvolveMatrix::preserveAlpha() const return m_preserveAlpha; } -void FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha) +bool FEConvolveMatrix::setPreserveAlpha(bool preserveAlpha) { - m_preserveAlpha = preserveAlpha; + if (m_preserveAlpha == preserveAlpha) + return false; + m_preserveAlpha = preserveAlpha; + return true; } /* diff --git a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h index 05d1199..5dc8873 100644 --- a/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h +++ b/Source/WebCore/platform/graphics/filters/FEConvolveMatrix.h @@ -49,28 +49,28 @@ public: bool, const Vector<float>&); IntSize kernelSize() const; - void setKernelSize(IntSize); + void setKernelSize(const IntSize&); const Vector<float>& kernel() const; void setKernel(const Vector<float>&); float divisor() const; - void setDivisor(float); + bool setDivisor(float); float bias() const; - void setBias(float); + bool setBias(float); IntPoint targetOffset() const; - void setTargetOffset(IntPoint); + bool setTargetOffset(const IntPoint&); EdgeModeType edgeMode() const; - void setEdgeMode(EdgeModeType); + bool setEdgeMode(EdgeModeType); FloatPoint kernelUnitLength() const; - void setKernelUnitLength(FloatPoint); + bool setKernelUnitLength(const FloatPoint&); bool preserveAlpha() const; - void setPreserveAlpha(bool); + bool setPreserveAlpha(bool); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp index 88c87b7..b632233 100644 --- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp +++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.cpp @@ -54,9 +54,12 @@ ChannelSelectorType FEDisplacementMap::xChannelSelector() const return m_xChannelSelector; } -void FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector) +bool FEDisplacementMap::setXChannelSelector(const ChannelSelectorType xChannelSelector) { + if (m_xChannelSelector == xChannelSelector) + return false; m_xChannelSelector = xChannelSelector; + return true; } ChannelSelectorType FEDisplacementMap::yChannelSelector() const @@ -64,9 +67,12 @@ ChannelSelectorType FEDisplacementMap::yChannelSelector() const return m_yChannelSelector; } -void FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector) +bool FEDisplacementMap::setYChannelSelector(const ChannelSelectorType yChannelSelector) { + if (m_yChannelSelector == yChannelSelector) + return false; m_yChannelSelector = yChannelSelector; + return true; } float FEDisplacementMap::scale() const @@ -74,9 +80,12 @@ float FEDisplacementMap::scale() const return m_scale; } -void FEDisplacementMap::setScale(float scale) +bool FEDisplacementMap::setScale(float scale) { + if (m_scale == scale) + return false; m_scale = scale; + return true; } void FEDisplacementMap::apply() diff --git a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h index ffb8f0e..9b7dda8 100644 --- a/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h +++ b/Source/WebCore/platform/graphics/filters/FEDisplacementMap.h @@ -42,13 +42,13 @@ public: static PassRefPtr<FEDisplacementMap> create(Filter*, ChannelSelectorType xChannelSelector, ChannelSelectorType yChannelSelector, float); ChannelSelectorType xChannelSelector() const; - void setXChannelSelector(const ChannelSelectorType); + bool setXChannelSelector(const ChannelSelectorType); ChannelSelectorType yChannelSelector() const; - void setYChannelSelector(const ChannelSelectorType); + bool setYChannelSelector(const ChannelSelectorType); float scale() const; - void setScale(float scale); + bool setScale(float); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FEFlood.cpp b/Source/WebCore/platform/graphics/filters/FEFlood.cpp index 0e0e94c..3c48cf9 100644 --- a/Source/WebCore/platform/graphics/filters/FEFlood.cpp +++ b/Source/WebCore/platform/graphics/filters/FEFlood.cpp @@ -85,7 +85,7 @@ TextStream& FEFlood::externalRepresentation(TextStream& ts, int indent) const writeIndent(ts, indent); ts << "[feFlood"; FilterEffect::externalRepresentation(ts); - ts << " flood-color=\"" << floodColor().name() << "\" " + ts << " flood-color=\"" << floodColor().nameForRenderTreeAsText() << "\" " << "flood-opacity=\"" << floodOpacity() << "\"]\n"; return ts; } diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp index 1eb554b..aa01570 100644 --- a/Source/WebCore/platform/graphics/filters/FEMorphology.cpp +++ b/Source/WebCore/platform/graphics/filters/FEMorphology.cpp @@ -56,9 +56,12 @@ MorphologyOperatorType FEMorphology::morphologyOperator() const return m_type; } -void FEMorphology::setMorphologyOperator(MorphologyOperatorType type) +bool FEMorphology::setMorphologyOperator(MorphologyOperatorType type) { + if (m_type == type) + return false; m_type = type; + return true; } float FEMorphology::radiusX() const @@ -66,9 +69,12 @@ float FEMorphology::radiusX() const return m_radiusX; } -void FEMorphology::setRadiusX(float radiusX) +bool FEMorphology::setRadiusX(float radiusX) { + if (m_radiusX == radiusX) + return false; m_radiusX = radiusX; + return true; } float FEMorphology::radiusY() const @@ -86,9 +92,12 @@ void FEMorphology::determineAbsolutePaintRect() setAbsolutePaintRect(enclosingIntRect(paintRect)); } -void FEMorphology::setRadiusY(float radiusY) +bool FEMorphology::setRadiusY(float radiusY) { + if (m_radiusY == radiusY) + return false; m_radiusY = radiusY; + return true; } void FEMorphology::apply() diff --git a/Source/WebCore/platform/graphics/filters/FEMorphology.h b/Source/WebCore/platform/graphics/filters/FEMorphology.h index 683e7d0..74c3b5a 100644 --- a/Source/WebCore/platform/graphics/filters/FEMorphology.h +++ b/Source/WebCore/platform/graphics/filters/FEMorphology.h @@ -38,13 +38,13 @@ class FEMorphology : public FilterEffect { public: static PassRefPtr<FEMorphology> create(Filter*, MorphologyOperatorType, float radiusX, float radiusY); MorphologyOperatorType morphologyOperator() const; - void setMorphologyOperator(MorphologyOperatorType); + bool setMorphologyOperator(MorphologyOperatorType); float radiusX() const; - void setRadiusX(float); + bool setRadiusX(float); float radiusY() const; - void setRadiusY(float); + bool setRadiusY(float); virtual void apply(); virtual void dump(); diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp index 36a6b72..a20eb8c 100644 --- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp +++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.cpp @@ -64,9 +64,12 @@ float FESpecularLighting::surfaceScale() const return m_surfaceScale; } -void FESpecularLighting::setSurfaceScale(float surfaceScale) +bool FESpecularLighting::setSurfaceScale(float surfaceScale) { + if (m_surfaceScale == surfaceScale) + return false; m_surfaceScale = surfaceScale; + return true; } float FESpecularLighting::specularConstant() const @@ -74,9 +77,12 @@ float FESpecularLighting::specularConstant() const return m_specularConstant; } -void FESpecularLighting::setSpecularConstant(float specularConstant) +bool FESpecularLighting::setSpecularConstant(float specularConstant) { + if (m_specularConstant == specularConstant) + return false; m_specularConstant = specularConstant; + return true; } float FESpecularLighting::specularExponent() const @@ -84,9 +90,12 @@ float FESpecularLighting::specularExponent() const return m_specularExponent; } -void FESpecularLighting::setSpecularExponent(float specularExponent) +bool FESpecularLighting::setSpecularExponent(float specularExponent) { + if (m_specularExponent == specularExponent) + return false; m_specularExponent = specularExponent; + return true; } float FESpecularLighting::kernelUnitLengthX() const @@ -94,9 +103,12 @@ float FESpecularLighting::kernelUnitLengthX() const return m_kernelUnitLengthX; } -void FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX) +bool FESpecularLighting::setKernelUnitLengthX(float kernelUnitLengthX) { + if (m_kernelUnitLengthX == kernelUnitLengthX) + return false; m_kernelUnitLengthX = kernelUnitLengthX; + return true; } float FESpecularLighting::kernelUnitLengthY() const @@ -104,9 +116,12 @@ float FESpecularLighting::kernelUnitLengthY() const return m_kernelUnitLengthY; } -void FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY) +bool FESpecularLighting::setKernelUnitLengthY(float kernelUnitLengthY) { + if (m_kernelUnitLengthY == kernelUnitLengthY) + return false; m_kernelUnitLengthY = kernelUnitLengthY; + return true; } const LightSource* FESpecularLighting::lightSource() const diff --git a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h index b3ccfbc..9d3ea2d 100644 --- a/Source/WebCore/platform/graphics/filters/FESpecularLighting.h +++ b/Source/WebCore/platform/graphics/filters/FESpecularLighting.h @@ -37,19 +37,19 @@ public: void setLightingColor(const Color&); float surfaceScale() const; - void setSurfaceScale(float); + bool setSurfaceScale(float); float specularConstant() const; - void setSpecularConstant(float); + bool setSpecularConstant(float); float specularExponent() const; - void setSpecularExponent(float); + bool setSpecularExponent(float); float kernelUnitLengthX() const; - void setKernelUnitLengthX(float); + bool setKernelUnitLengthX(float); float kernelUnitLengthY() const; - void setKernelUnitLengthY(float); + bool setKernelUnitLengthY(float); const LightSource* lightSource() const; void setLightSource(PassRefPtr<LightSource>); diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp index 068acee..63060e1 100644 --- a/Source/WebCore/platform/graphics/filters/FETurbulence.cpp +++ b/Source/WebCore/platform/graphics/filters/FETurbulence.cpp @@ -49,7 +49,7 @@ static const int s_randAmplitude = 16807; // 7**5; primitive root of m static const int s_randQ = 127773; // m / a static const int s_randR = 2836; // m % a -FETurbulence::FETurbulence(Filter* filter, TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) +FETurbulence::FETurbulence(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) : FilterEffect(filter) , m_type(type) , m_baseFrequencyX(baseFrequencyX) @@ -60,19 +60,22 @@ FETurbulence::FETurbulence(Filter* filter, TurbulanceType type, float baseFreque { } -PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulanceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) +PassRefPtr<FETurbulence> FETurbulence::create(Filter* filter, TurbulenceType type, float baseFrequencyX, float baseFrequencyY, int numOctaves, float seed, bool stitchTiles) { return adoptRef(new FETurbulence(filter, type, baseFrequencyX, baseFrequencyY, numOctaves, seed, stitchTiles)); } -TurbulanceType FETurbulence::type() const +TurbulenceType FETurbulence::type() const { return m_type; } -void FETurbulence::setType(TurbulanceType type) +bool FETurbulence::setType(TurbulenceType type) { + if (m_type == type) + return false; m_type = type; + return true; } float FETurbulence::baseFrequencyY() const @@ -80,9 +83,12 @@ float FETurbulence::baseFrequencyY() const return m_baseFrequencyY; } -void FETurbulence::setBaseFrequencyY(float baseFrequencyY) +bool FETurbulence::setBaseFrequencyY(float baseFrequencyY) { + if (m_baseFrequencyY == baseFrequencyY) + return false; m_baseFrequencyY = baseFrequencyY; + return true; } float FETurbulence::baseFrequencyX() const @@ -90,9 +96,12 @@ float FETurbulence::baseFrequencyX() const return m_baseFrequencyX; } -void FETurbulence::setBaseFrequencyX(float baseFrequencyX) +bool FETurbulence::setBaseFrequencyX(float baseFrequencyX) { - m_baseFrequencyX = baseFrequencyX; + if (m_baseFrequencyX == baseFrequencyX) + return false; + m_baseFrequencyX = baseFrequencyX; + return true; } float FETurbulence::seed() const @@ -100,9 +109,12 @@ float FETurbulence::seed() const return m_seed; } -void FETurbulence::setSeed(float seed) +bool FETurbulence::setSeed(float seed) { + if (m_seed == seed) + return false; m_seed = seed; + return true; } int FETurbulence::numOctaves() const @@ -110,9 +122,12 @@ int FETurbulence::numOctaves() const return m_numOctaves; } -void FETurbulence::setNumOctaves(bool numOctaves) +bool FETurbulence::setNumOctaves(int numOctaves) { + if (m_numOctaves == numOctaves) + return false; m_numOctaves = numOctaves; + return true; } bool FETurbulence::stitchTiles() const @@ -120,9 +135,12 @@ bool FETurbulence::stitchTiles() const return m_stitchTiles; } -void FETurbulence::setStitchTiles(bool stitch) +bool FETurbulence::setStitchTiles(bool stitch) { + if (m_stitchTiles == stitch) + return false; m_stitchTiles = stitch; + return true; } // The turbulence calculation code is an adapted version of what appears in the SVG 1.1 specification: @@ -353,7 +371,7 @@ void FETurbulence::dump() { } -static TextStream& operator<<(TextStream& ts, const TurbulanceType& type) +static TextStream& operator<<(TextStream& ts, const TurbulenceType& type) { switch (type) { case FETURBULENCE_TYPE_UNKNOWN: diff --git a/Source/WebCore/platform/graphics/filters/FETurbulence.h b/Source/WebCore/platform/graphics/filters/FETurbulence.h index 1bad123..dfeb220 100644 --- a/Source/WebCore/platform/graphics/filters/FETurbulence.h +++ b/Source/WebCore/platform/graphics/filters/FETurbulence.h @@ -30,7 +30,7 @@ namespace WebCore { -enum TurbulanceType { +enum TurbulenceType { FETURBULENCE_TYPE_UNKNOWN = 0, FETURBULENCE_TYPE_FRACTALNOISE = 1, FETURBULENCE_TYPE_TURBULENCE = 2 @@ -38,25 +38,25 @@ enum TurbulanceType { class FETurbulence : public FilterEffect { public: - static PassRefPtr<FETurbulence> create(Filter*, TurbulanceType, float, float, int, float, bool); + static PassRefPtr<FETurbulence> create(Filter*, TurbulenceType, float, float, int, float, bool); - TurbulanceType type() const; - void setType(TurbulanceType); + TurbulenceType type() const; + bool setType(TurbulenceType); float baseFrequencyY() const; - void setBaseFrequencyY(float); + bool setBaseFrequencyY(float); float baseFrequencyX() const; - void setBaseFrequencyX(float); + bool setBaseFrequencyX(float); float seed() const; - void setSeed(float); + bool setSeed(float); int numOctaves() const; - void setNumOctaves(bool); + bool setNumOctaves(int); bool stitchTiles() const; - void setStitchTiles(bool); + bool setStitchTiles(bool); virtual void apply(); virtual void dump(); @@ -84,13 +84,13 @@ private: inline long random(); }; - FETurbulence(Filter*, TurbulanceType, float, float, int, float, bool); + FETurbulence(Filter*, TurbulenceType, float, float, int, float, bool); inline void initPaint(PaintingData&); float noise2D(PaintingData&, const FloatPoint&); unsigned char calculateTurbulenceValueForPoint(PaintingData&, const FloatPoint&); - TurbulanceType m_type; + TurbulenceType m_type; float m_baseFrequencyX; float m_baseFrequencyY; int m_numOctaves; diff --git a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp index 1430124..b27bead 100644 --- a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp @@ -142,6 +142,33 @@ static String getFamilyNameStringFromFontDescriptionAndFamily(const FontDescript } } +int fontWeightToFontconfigWeight(FontWeight weight) +{ + switch (weight) { + case FontWeight100: + return FC_WEIGHT_THIN; + case FontWeight200: + return FC_WEIGHT_ULTRALIGHT; + case FontWeight300: + return FC_WEIGHT_LIGHT; + case FontWeight400: + return FC_WEIGHT_REGULAR; + case FontWeight500: + return FC_WEIGHT_MEDIUM; + case FontWeight600: + return FC_WEIGHT_SEMIBOLD; + case FontWeight700: + return FC_WEIGHT_BOLD; + case FontWeight800: + return FC_WEIGHT_EXTRABOLD; + case FontWeight900: + return FC_WEIGHT_ULTRABLACK; + default: + ASSERT_NOT_REACHED(); + return FC_WEIGHT_REGULAR; + } +} + FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm) @@ -155,8 +182,7 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD bool italic = fontDescription.italic(); if (!FcPatternAddInteger(pattern.get(), FC_SLANT, italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN)) return 0; - bool bold = fontDescription.weight() >= FontWeightBold; - if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL)) + if (!FcPatternAddInteger(pattern.get(), FC_WEIGHT, fontWeightToFontconfigWeight(fontDescription.weight()))) return 0; if (!FcPatternAddDouble(pattern.get(), FC_PIXEL_SIZE, fontDescription.computedPixelSize())) return 0; diff --git a/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp index 7340e76..fbc7ac9 100644 --- a/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp @@ -31,7 +31,7 @@ #include <cairo.h> #include <fontconfig/fcfreetype.h> -#if !PLATFORM(EFL) || ENABLE(GLIB_SUPPORT) +#if !PLATFORM(EFL) #include <gdk/gdk.h> #endif @@ -100,17 +100,16 @@ void setCairoFontOptionsFromFontConfigPattern(cairo_font_options_t* options, FcP cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE); } -static const cairo_font_options_t* getDefaultFontOptions() +static cairo_font_options_t* getDefaultFontOptions() { - static const cairo_font_options_t* options = cairo_font_options_create(); -#if PLATFORM(GTK) || ENABLE(GLIB_SUPPORT) +#if PLATFORM(GTK) if (GdkScreen* screen = gdk_screen_get_default()) { const cairo_font_options_t* screenOptions = gdk_screen_get_font_options(screen); if (screenOptions) - options = screenOptions; + return cairo_font_options_copy(screenOptions); } #endif - return options; + return cairo_font_options_create(); } FontPlatformData::FontPlatformData(FcPattern* pattern, const FontDescription& fontDescription) @@ -242,7 +241,7 @@ String FontPlatformData::description() const void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace) { - cairo_font_options_t* options = cairo_font_options_copy(getDefaultFontOptions()); + cairo_font_options_t* options = getDefaultFontOptions(); cairo_matrix_t ctm; cairo_matrix_init_identity(&ctm); diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h index 1bd67b8..8b7181b 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnClassifier.h @@ -30,6 +30,7 @@ #ifndef LoopBlinnClassifier_h #define LoopBlinnClassifier_h +#include <wtf/Noncopyable.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h b/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h index d01e6c9..aa2294e 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnLocalTriangulator.h @@ -30,6 +30,7 @@ #include "FloatPoint3D.h" #include "LoopBlinnConstants.h" #include <wtf/Assertions.h> +#include <wtf/Noncopyable.h> namespace WebCore { diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp index e84ddbf..5439885 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnPathProcessor.cpp @@ -43,7 +43,7 @@ #include <wtf/Assertions.h> #include <wtf/FastMalloc.h> -#if PLATFORM(SKIA) +#if USE(SKIA) #include "SkGeometry.h" #include "SkPath.h" #include "SkScalar.h" @@ -612,7 +612,7 @@ void LoopBlinnPathProcessor::buildContours(const Path& path) { // Clear out the contours m_contours.clear(); -#if PLATFORM(SKIA) +#if USE(SKIA) SkPath::Iter iter(*path.platformPath(), false); SkPoint points[4]; SkPath::Verb verb; @@ -700,7 +700,7 @@ void LoopBlinnPathProcessor::buildContours(const Path& path) break; } } while (verb != SkPath::kDone_Verb); -#else // !PLATFORM(SKIA) +#else // !USE(SKIA) // Must port to your platform. ASSERT_NOT_REACHED(); #endif diff --git a/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp index 43a97ef..57b728f 100644 --- a/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp +++ b/Source/WebCore/platform/graphics/gpu/LoopBlinnSolidFillShader.cpp @@ -27,6 +27,7 @@ #include "LoopBlinnSolidFillShader.h" +#include "Color.h" #include "GraphicsContext3D.h" namespace WebCore { diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp index 9c59077..ea8bc71 100644 --- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp +++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp @@ -39,6 +39,7 @@ #include "Extensions3D.h" #include "FloatRect.h" #include "IntSize.h" +#include "LoopBlinnSolidFillShader.h" #include "SolidFillShader.h" #include "TexShader.h" @@ -53,7 +54,7 @@ PassRefPtr<SharedGraphicsContext3D> SharedGraphicsContext3D::create(HostWindow* GraphicsContext3D::Attributes attr; attr.depth = false; attr.stencil = true; - attr.antialias = false; + attr.antialias = useLoopBlinnForPathRendering(); attr.canRecoverFromContextLoss = false; // Canvas contexts can not handle lost contexts. RefPtr<GraphicsContext3D> context = GraphicsContext3D::create(attr, hostWindow); if (!context) @@ -73,6 +74,7 @@ SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> c , m_quadVertices(0) , m_solidFillShader(solidFillShader) , m_texShader(texShader) + , m_oesStandardDerivativesSupported(false) { allContexts()->add(this); Extensions3D* extensions = m_context->getExtensions(); @@ -81,6 +83,9 @@ SharedGraphicsContext3D::SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D> c extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888"); extensions->ensureEnabled("GL_EXT_read_format_bgra"); } + m_oesStandardDerivativesSupported = extensions->supports("GL_OES_standard_derivatives"); + if (m_oesStandardDerivativesSupported) + extensions->ensureEnabled("GL_OES_standard_derivatives"); } SharedGraphicsContext3D::~SharedGraphicsContext3D() @@ -94,9 +99,9 @@ void SharedGraphicsContext3D::makeContextCurrent() m_context->makeContextCurrent(); } -void SharedGraphicsContext3D::scissor(const FloatRect& rect) +void SharedGraphicsContext3D::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height) { - m_context->scissor(rect.x(), rect.y(), rect.width(), rect.height()); + m_context->scissor(x, y, width, height); } void SharedGraphicsContext3D::enable(GC3Denum capacity) @@ -141,6 +146,11 @@ void SharedGraphicsContext3D::flush() m_context->flush(); } +Platform3DObject SharedGraphicsContext3D::createBuffer() +{ + return m_context->createBuffer(); +} + Platform3DObject SharedGraphicsContext3D::createFramebuffer() { return m_context->createFramebuffer(); @@ -324,11 +334,31 @@ void SharedGraphicsContext3D::setActiveTexture(GC3Denum textureUnit) m_context->activeTexture(textureUnit); } +void SharedGraphicsContext3D::bindBuffer(GC3Denum target, Platform3DObject buffer) +{ + m_context->bindBuffer(target, buffer); +} + void SharedGraphicsContext3D::bindTexture(GC3Denum target, Platform3DObject texture) { m_context->bindTexture(target, texture); } +void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3Denum usage) +{ + m_context->bufferData(target, size, usage); +} + +void SharedGraphicsContext3D::bufferData(GC3Denum target, GC3Dsizeiptr size, const void* data, GC3Denum usage) +{ + m_context->bufferData(target, size, data, usage); +} + +void SharedGraphicsContext3D::bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr size, const void* data) +{ + m_context->bufferSubData(target, offset, size, data); +} + void SharedGraphicsContext3D::useFillSolidProgram(const AffineTransform& transform, const Color& color) { m_solidFillShader->use(transform, color); @@ -354,6 +384,33 @@ bool SharedGraphicsContext3D::paintsIntoCanvasBuffer() const return m_context->paintsIntoCanvasBuffer(); } +bool SharedGraphicsContext3D::useLoopBlinnForPathRendering() +{ + return false; +} + +void SharedGraphicsContext3D::useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform& transform, const Color& color) +{ + if (!m_loopBlinnInteriorShader) { + m_loopBlinnInteriorShader = LoopBlinnSolidFillShader::create(m_context.get(), + LoopBlinnShader::Interior, + Shader::NotAntialiased); + } + ASSERT(m_loopBlinnInteriorShader); + m_loopBlinnInteriorShader->use(vertexOffset, 0, transform, color); +} + +void SharedGraphicsContext3D::useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform& transform, const Color& color) +{ + if (!m_loopBlinnExteriorShader) { + m_loopBlinnExteriorShader = LoopBlinnSolidFillShader::create(m_context.get(), + LoopBlinnShader::Exterior, + m_oesStandardDerivativesSupported ? Shader::Antialiased : Shader::NotAntialiased); + } + ASSERT(m_loopBlinnExteriorShader); + m_loopBlinnExteriorShader->use(vertexOffset, klmOffset, transform, color); +} + } // namespace WebCore #endif diff --git a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h index 1e032d7..707fd24 100644 --- a/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h +++ b/Source/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.h @@ -49,6 +49,7 @@ class Color; class FloatRect; class HostWindow; class IntSize; +class LoopBlinnSolidFillShader; class SolidFillShader; class TexShader; @@ -61,9 +62,13 @@ public: // Functions that delegate directly to GraphicsContext3D, with caching void makeContextCurrent(); + void bindBuffer(GC3Denum target, Platform3DObject); void bindFramebuffer(Platform3DObject framebuffer); + void bufferData(GC3Denum target, GC3Dsizeiptr, GC3Denum usage); + void bufferData(GC3Denum target, GC3Dsizeiptr, const void* data, GC3Denum usage); + void bufferSubData(GC3Denum target, GC3Dintptr offset, GC3Dsizeiptr, const void* data); void setViewport(const IntSize&); - void scissor(const FloatRect&); + void scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height); void enable(GC3Denum capacity); void disable(GC3Denum capacity); void clearColor(const Color&); @@ -73,6 +78,7 @@ public: void getIntegerv(GC3Denum pname, GC3Dint* value); void flush(); + Platform3DObject createBuffer(); Platform3DObject createFramebuffer(); Platform3DObject createTexture(); @@ -117,6 +123,11 @@ public: GraphicsContext3D* graphicsContext3D() const { return m_context.get(); } + // Members for GPU-accelerated path rendering. + static bool useLoopBlinnForPathRendering(); + void useLoopBlinnInteriorProgram(unsigned vertexOffset, const AffineTransform&, const Color&); + void useLoopBlinnExteriorProgram(unsigned vertexOffset, unsigned klmOffset, const AffineTransform&, const Color&); + private: SharedGraphicsContext3D(PassRefPtr<GraphicsContext3D>, PassOwnPtr<SolidFillShader>, PassOwnPtr<TexShader>); @@ -133,6 +144,12 @@ private: OwnPtr<TexShader> m_texShader; TextureHashMap m_textures; + + // Members for GPU-accelerated path rendering. + // FIXME: support more kinds of fill types for paths. + OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnInteriorShader; + OwnPtr<LoopBlinnSolidFillShader> m_loopBlinnExteriorShader; + bool m_oesStandardDerivativesSupported; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.cpp b/Source/WebCore/platform/graphics/gpu/TilingData.cpp index e7c4e4c..dd540b3 100644 --- a/Source/WebCore/platform/graphics/gpu/TilingData.cpp +++ b/Source/WebCore/platform/graphics/gpu/TilingData.cpp @@ -44,7 +44,8 @@ namespace WebCore { static int computeNumTiles(int maxTextureSize, int totalSize, int borderTexels) { - return max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels)); + int numTiles = max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels)); + return totalSize > 0 ? numTiles : 0; } TilingData::TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels) @@ -53,8 +54,20 @@ TilingData::TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool , m_totalSizeY(totalSizeY) , m_borderTexels(hasBorderTexels ? 1 : 0) { - m_numTilesX = computeNumTiles(maxTextureSize, m_totalSizeX, m_borderTexels); - m_numTilesY = computeNumTiles(maxTextureSize, m_totalSizeY, m_borderTexels); + recomputeNumTiles(); +} + +void TilingData::setTotalSize(int totalSizeX, int totalSizeY) +{ + m_totalSizeX = totalSizeX; + m_totalSizeY = totalSizeY; + recomputeNumTiles(); +} + +void TilingData::setMaxTextureSize(int maxTextureSize) +{ + m_maxTextureSize = m_maxTextureSize; + recomputeNumTiles(); } int TilingData::tileXIndexFromSrcCoord(int srcPos) const @@ -142,9 +155,6 @@ int TilingData::tileSizeX(int xIndex) const { ASSERT(xIndex >= 0 && xIndex < numTilesX()); - int size = maxTextureSize(); - size = min(size, totalSizeX()); - if (!xIndex && m_numTilesX == 1) return m_totalSizeX; if (!xIndex && m_numTilesX > 1) @@ -162,9 +172,6 @@ int TilingData::tileSizeY(int yIndex) const { ASSERT(yIndex >= 0 && yIndex < numTilesY()); - int size = maxTextureSize(); - size = min(size, totalSizeY()); - if (!yIndex && m_numTilesY == 1) return m_totalSizeY; if (!yIndex && m_numTilesY > 1) @@ -222,6 +229,20 @@ void TilingData::intersectDrawQuad(const FloatRect& srcRect, const FloatRect& ds srcRectIntersectedNormH * dstRect.height()); } +IntPoint TilingData::textureOffset(int xIndex, int yIndex) const +{ + int left = (!xIndex || m_numTilesX == 1) ? 0 : m_borderTexels; + int top = (!yIndex || m_numTilesY == 1) ? 0 : m_borderTexels; + + return IntPoint(left, top); +} + +void TilingData::recomputeNumTiles() +{ + m_numTilesX = computeNumTiles(m_maxTextureSize, m_totalSizeX, m_borderTexels); + m_numTilesY = computeNumTiles(m_maxTextureSize, m_totalSizeY, m_borderTexels); +} + } #endif diff --git a/Source/WebCore/platform/graphics/gpu/TilingData.h b/Source/WebCore/platform/graphics/gpu/TilingData.h index d1140bd..2989eae 100644 --- a/Source/WebCore/platform/graphics/gpu/TilingData.h +++ b/Source/WebCore/platform/graphics/gpu/TilingData.h @@ -37,11 +37,14 @@ namespace WebCore { class FloatRect; class IntRect; +class IntPoint; class TilingData { WTF_MAKE_NONCOPYABLE(TilingData); public: TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels); + void setTotalSize(int totalSizeX, int totalSizeY); + void setMaxTextureSize(int); int maxTextureSize() const { return m_maxTextureSize; } int totalSizeX() const { return m_totalSizeX; } int totalSizeY() const { return m_totalSizeY; } @@ -70,9 +73,13 @@ public: // in texel units, returns adjusted data to render just the one tile. void intersectDrawQuad(const FloatRect& srcRect, const FloatRect& dstRect, int tile, FloatRect* newSrc, FloatRect* newDst) const; + // Difference between tileBound's and tileBoundWithBorder's location(). + IntPoint textureOffset(int xIndex, int yIndex) const; + private: TilingData() : m_maxTextureSize(0), m_totalSizeX(0), m_totalSizeY(0) {} void assertTile(int tile) const { ASSERT(tile >= 0 && tile < numTiles()); } + void recomputeNumTiles(); int m_maxTextureSize; int m_totalSizeX; diff --git a/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp b/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp new file mode 100644 index 0000000..b8c3b3d --- /dev/null +++ b/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011 Andrew Wason (rectalogic@rectalogic.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 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 ENABLE(ACCELERATED_2D_CANVAS) || ENABLE(WEBGL) + +#include "DrawingBuffer.h" + +namespace WebCore { + +DrawingBuffer::DrawingBuffer(GraphicsContext3D* context, + const IntSize& size, + bool multisampleExtensionSupported, + bool packedDepthStencilExtensionSupported) + : m_context(context) + , m_size(-1, -1) + , m_multisampleExtensionSupported(multisampleExtensionSupported) + , m_packedDepthStencilExtensionSupported(packedDepthStencilExtensionSupported) + , m_fbo(context->createFramebuffer()) + , m_colorBuffer(0) + , m_depthStencilBuffer(0) + , m_depthBuffer(0) + , m_stencilBuffer(0) + , m_multisampleFBO(0) + , m_multisampleColorBuffer(0) +{ + ASSERT(m_fbo); + if (!m_fbo) { + clear(); + return; + } + + // create a texture to render into + m_colorBuffer = context->createTexture(); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer); + context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); + context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); + context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0); + + // Create the FBO + m_fbo = context->createFramebuffer(); + ASSERT(m_fbo); + if (!m_fbo) { + clear(); + return; + } + + createSecondaryBuffers(); + reset(size); +} + +DrawingBuffer::~DrawingBuffer() +{ + clear(); +} + +void DrawingBuffer::didReset() +{ +} + +#if USE(ACCELERATED_COMPOSITING) +PlatformLayer* DrawingBuffer::platformLayer() +{ + return 0; +} +#endif + +Platform3DObject DrawingBuffer::platformColorBuffer() const +{ + return m_colorBuffer; +} + +} + +#endif diff --git a/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp new file mode 100644 index 0000000..91b65d8 --- /dev/null +++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.cpp @@ -0,0 +1,42 @@ +/* + * 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 Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "config.h" +#include "GRefPtrGStreamer.h" + +#if USE(GSTREAMER) +#include <gst/gstelement.h> + +namespace WTF { + +template <> GstElement* refGPtr<GstElement>(GstElement* ptr) +{ + if (ptr) + gst_object_ref(ptr); + return ptr; +} + +template <> void derefGPtr<GstElement>(GstElement* ptr) +{ + if (ptr) + gst_object_unref(ptr); +} + +} +#endif // USE(GSTREAMER) diff --git a/Source/WebCore/platform/graphics/wince/ColorWinCE.cpp b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h index 820b9d2..fdc6f30 100644 --- a/Source/WebCore/platform/graphics/wince/ColorWinCE.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/GRefPtrGStreamer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2008 Torch Mobile, Inc. + * 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 @@ -15,24 +15,22 @@ * 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 "Color.h" +#ifndef GRefPtrGStreamer_h +#define GRefPtrGStreamer_h +#if USE(GSTREAMER) -#include "NotImplemented.h" +#include "GRefPtr.h" -namespace WebCore { +typedef struct _GstElement GstElement; -Color focusRingColor() -{ - return Color(0, 0, 0); -} +namespace WTF { + +template<> GstElement* refGPtr<GstElement>(GstElement* ptr); +template<> void derefGPtr<GstElement>(GstElement* ptr); -void setFocusRingColorChangeFunction(void (*)()) -{ - notImplemented(); } -} // namespace WebCore +#endif // USE(GSTREAMER) +#endif diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp index 69bdeab..3763ef7 100644 --- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp @@ -46,6 +46,7 @@ #include "WebKitWebSourceGStreamer.h" #include <GOwnPtr.h> #include <gst/gst.h> +#include <gst/interfaces/streamvolume.h> #include <gst/video/video.h> #include <limits> #include <math.h> @@ -271,7 +272,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateGStreamer::create(MediaPlayer* pl void MediaPlayerPrivateGStreamer::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } static bool gstInitialized = false; @@ -640,7 +641,8 @@ void MediaPlayerPrivateGStreamer::setVolume(float volume) if (!m_playBin) return; - g_object_set(m_playBin, "volume", static_cast<double>(volume), NULL); + gst_stream_volume_set_volume(GST_STREAM_VOLUME(m_playBin), GST_STREAM_VOLUME_FORMAT_CUBIC, + static_cast<double>(volume)); } void MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange() @@ -650,7 +652,11 @@ void MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange() if (!m_player || !m_playBin) return; double volume; - g_object_get(m_playBin, "volume", &volume, NULL); + volume = gst_stream_volume_get_volume(GST_STREAM_VOLUME(m_playBin), GST_STREAM_VOLUME_FORMAT_CUBIC); + // get_volume() can return values superior to 1.0 if the user + // applies software user gain via third party application (GNOME + // volume control for instance). + volume = CLAMP(volume, 0.0, 1.0); m_player->volumeChanged(static_cast<float>(volume)); } @@ -1561,7 +1567,7 @@ void MediaPlayerPrivateGStreamer::createGSTPlayBin() g_signal_connect(bus, "message", G_CALLBACK(mediaPlayerPrivateMessageCallback), this); gst_object_unref(bus); - g_object_set(m_playBin, "mute", m_player->muted(), "volume", m_player->volume(), NULL); + g_object_set(m_playBin, "mute", m_player->muted(), NULL); g_signal_connect(m_playBin, "notify::volume", G_CALLBACK(mediaPlayerPrivateVolumeChangedCallback), this); g_signal_connect(m_playBin, "notify::source", G_CALLBACK(mediaPlayerPrivateSourceChangedCallback), this); diff --git a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp index 36b49df..86e3e7a 100644 --- a/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp +++ b/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp @@ -23,6 +23,7 @@ #include "Document.h" #include "GOwnPtr.h" #include "GRefPtr.h" +#include "GRefPtrGStreamer.h" #include "NetworkingContext.h" #include "Noncopyable.h" #include "NotImplemented.h" @@ -93,7 +94,8 @@ enum { PROP_IRADIO_NAME, PROP_IRADIO_GENRE, PROP_IRADIO_URL, - PROP_IRADIO_TITLE + PROP_IRADIO_TITLE, + PROP_LOCATION }; static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE("src", @@ -118,6 +120,8 @@ static void webKitWebSrcEnoughDataCb(GstAppSrc* appsrc, gpointer userData); static gboolean webKitWebSrcSeekDataCb(GstAppSrc* appsrc, guint64 offset, gpointer userData); static void webKitWebSrcStop(WebKitWebSrc* src, bool seeking); +static gboolean webKitWebSrcSetUri(GstURIHandler*, const gchar*); +static const gchar* webKitWebSrcGetUri(GstURIHandler*); static GstAppSrcCallbacks appsrcCallbacks = { webKitWebSrcNeedDataCb, @@ -203,6 +207,16 @@ static void webkit_web_src_class_init(WebKitWebSrcClass* klass) 0, (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS))); + + /* Allows setting the uri using the 'location' property, which is used + * for example by gst_element_make_from_uri() */ + g_object_class_install_property(oklass, + PROP_LOCATION, + g_param_spec_string("location", + "location", + "Location to read from", + 0, + (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); eklass->change_state = webKitWebSrcChangeState; g_type_class_add_private(klass, sizeof(WebKitWebSrcPrivate)); @@ -288,6 +302,9 @@ static void webKitWebSrcSetProperty(GObject* object, guint propID, const GValue* case PROP_IRADIO_MODE: priv->iradioMode = g_value_get_boolean(value); break; + case PROP_LOCATION: + webKitWebSrcSetUri(reinterpret_cast<GstURIHandler*>(src), g_value_get_string(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec); break; @@ -315,6 +332,9 @@ static void webKitWebSrcGetProperty(GObject* object, guint propID, GValue* value case PROP_IRADIO_TITLE: g_value_set_string(value, priv->iradioTitle); break; + case PROP_LOCATION: + g_value_set_string(value, webKitWebSrcGetUri(reinterpret_cast<GstURIHandler*>(src))); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propID, pspec); break; @@ -481,7 +501,8 @@ static GstStateChangeReturn webKitWebSrcChangeState(GstElement* element, GstStat static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query) { - WebKitWebSrc* src = WEBKIT_WEB_SRC(gst_pad_get_parent(pad)); + GRefPtr<GstElement> src = adoptGRef(gst_pad_get_parent_element(pad)); + WebKitWebSrc* webkitSrc = WEBKIT_WEB_SRC(src.get()); gboolean result = FALSE; switch (GST_QUERY_TYPE(query)) { @@ -491,13 +512,19 @@ static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query) gst_query_parse_duration(query, &format, NULL); - GST_DEBUG_OBJECT(src, "duration query in format %s", gst_format_get_name(format)); - if ((format == GST_FORMAT_BYTES) && (src->priv->size > 0)) { - gst_query_set_duration(query, format, src->priv->size); + GST_DEBUG_OBJECT(webkitSrc, "duration query in format %s", gst_format_get_name(format)); + if ((format == GST_FORMAT_BYTES) && (webkitSrc->priv->size > 0)) { + gst_query_set_duration(query, format, webkitSrc->priv->size); result = TRUE; } break; } + case GST_QUERY_URI: + { + gst_query_set_uri(query, webkitSrc->priv->uri); + result = TRUE; + break; + } default: break; } @@ -505,7 +532,6 @@ static gboolean webKitWebSrcQuery(GstPad* pad, GstQuery* query) if (!result) result = gst_pad_query_default(pad, query); - gst_object_unref(src); return result; } diff --git a/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp b/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp index a9ac186..7d08c36 100644 --- a/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp +++ b/Source/WebCore/platform/graphics/haiku/ColorHaiku.cpp @@ -30,7 +30,6 @@ #include <InterfaceDefs.h> - namespace WebCore { Color::Color(const rgb_color& color) @@ -44,11 +43,4 @@ Color::operator rgb_color() const return make_color(red(), green(), blue(), alpha()); } - -Color focusRingColor() -{ - return Color(keyboard_navigation_color()); -} - } // namespace WebCore - diff --git a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp index 4e17f94..b3f6c06 100644 --- a/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp +++ b/Source/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp @@ -443,6 +443,14 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) notImplemented(); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + void GraphicsContext::setPlatformShouldAntialias(bool enable) { if (paintingDisabled()) diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp index 1fe3d28..1a56664 100644 --- a/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp +++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.cpp @@ -49,13 +49,6 @@ static inline CGFloat roundCGFloat(CGFloat f) return static_cast<CGFloat>(round(f)); } -static inline CGFloat ceilCGFloat(CGFloat f) -{ - if (sizeof(CGFloat) == sizeof(float)) - return ceilf(static_cast<float>(f)); - return static_cast<CGFloat>(ceil(f)); -} - ComplexTextController::ComplexTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection, HashSet<const SimpleFontData*>* fallbackFonts, bool forTextEmphasis) : m_font(*font) , m_run(run) @@ -69,7 +62,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru , m_currentRun(0) , m_glyphInCurrentRun(0) , m_characterInCurrentGlyph(0) - , m_finalRoundingWidth(0) , m_expansion(run.expansion()) , m_afterExpansion(true) , m_fallbackFonts(fallbackFonts) @@ -77,7 +69,6 @@ ComplexTextController::ComplexTextController(const Font* font, const TextRun& ru , m_maxGlyphBoundingBoxX(numeric_limits<float>::min()) , m_minGlyphBoundingBoxY(numeric_limits<float>::max()) , m_maxGlyphBoundingBoxY(numeric_limits<float>::min()) - , m_lastRoundingGlyph(0) { if (!m_expansion) m_expansionPerOpportunity = 0; @@ -413,13 +404,11 @@ void ComplexTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer) m_currentRun++; m_glyphInCurrentRun = 0; } - if (!ltr && m_numGlyphsSoFar == m_adjustedAdvances.size()) - m_runWidthSoFar += m_finalRoundingWidth; } void ComplexTextController::adjustGlyphsAndAdvances() { - CGFloat widthSinceLastRounding = 0; + CGFloat widthSinceLastCommit = 0; size_t runCount = m_complexTextRuns.size(); bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_expansion) && !m_run.spacingDisabled(); for (size_t r = 0; r < runCount; ++r) { @@ -431,9 +420,8 @@ void ComplexTextController::adjustGlyphsAndAdvances() const CGSize* advances = complexTextRun.advances(); bool lastRun = r + 1 == runCount; - const UChar* cp = complexTextRun.characters(); - CGFloat roundedSpaceWidth = roundCGFloat(fontData->spaceWidth()); bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances(); + const UChar* cp = complexTextRun.characters(); CGPoint glyphOrigin = CGPointZero; CFIndex lastCharacterIndex = m_run.ltr() ? numeric_limits<CFIndex>::min() : numeric_limits<CFIndex>::max(); bool isMonotonic = true; @@ -463,7 +451,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() if (ch == '\t' && m_run.allowTabs()) { float tabWidth = m_font.tabWidth(*fontData); - advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastRounding, tabWidth); + advance.width = tabWidth - fmodf(m_run.xPos() + m_totalWidth + widthSinceLastCommit, tabWidth); } else if (ch == zeroWidthSpace || (Font::treatAsZeroWidthSpace(ch) && !treatAsSpace)) { advance.width = 0; glyph = fontData->spaceGlyph(); @@ -475,13 +463,6 @@ void ComplexTextController::adjustGlyphsAndAdvances() advance.width += fontData->syntheticBoldOffset(); - // We special case spaces in two ways when applying word rounding. - // First, we round spaces to an adjusted width in all fonts. - // Second, in fixed-pitch fonts we ensure that all glyphs that - // match the width of the space glyph have the same width as the space glyph. - if (roundedAdvanceWidth == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && m_run.applyWordRounding()) - advance.width = fontData->adjustedSpaceWidth(); - if (hasExtraSpacing) { // If we're a glyph with an advance, go ahead and add in letter-spacing. // That way we weed out zero width lurkers. This behavior matches the fast text code path. @@ -492,17 +473,14 @@ void ComplexTextController::adjustGlyphsAndAdvances() if (treatAsSpace || Font::isCJKIdeographOrSymbol(ch)) { // Distribute the run's total expansion evenly over all expansion opportunities in the run. if (m_expansion && (!lastGlyph || m_run.allowsTrailingExpansion())) { - float previousExpansion = m_expansion; if (!treatAsSpace && !m_afterExpansion) { // Take the expansion opportunity before this ideograph. m_expansion -= m_expansionPerOpportunity; - int expansion = roundf(previousExpansion) - roundf(m_expansion); - m_totalWidth += expansion; - m_adjustedAdvances.last().width += expansion; - previousExpansion = m_expansion; + m_totalWidth += m_expansionPerOpportunity; + m_adjustedAdvances.last().width += m_expansionPerOpportunity; } m_expansion -= m_expansionPerOpportunity; - advance.width += roundf(previousExpansion) - roundf(m_expansion); + advance.width += m_expansionPerOpportunity; m_afterExpansion = true; } else m_afterExpansion = false; @@ -514,33 +492,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() m_afterExpansion = false; } - // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so the following words will start on an integer boundary. - if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(ch)) - advance.width = ceilCGFloat(advance.width); - - // Check to see if the next character is a "rounding hack character", if so, adjust the - // width so that the total run width will be on an integer boundary. - if ((m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh)) || (m_run.applyRunRounding() && lastGlyph)) { - CGFloat totalWidth = widthSinceLastRounding + advance.width; - widthSinceLastRounding = ceilCGFloat(totalWidth); - CGFloat extraWidth = widthSinceLastRounding - totalWidth; - if (m_run.ltr()) - advance.width += extraWidth; - else { - if (m_lastRoundingGlyph) - m_adjustedAdvances[m_lastRoundingGlyph - 1].width += extraWidth; - else - m_finalRoundingWidth = extraWidth; - m_lastRoundingGlyph = m_adjustedAdvances.size() + 1; - } - m_totalWidth += widthSinceLastRounding; - widthSinceLastRounding = 0; - } else - widthSinceLastRounding += advance.width; + widthSinceLastCommit += advance.width; // FIXME: Combining marks should receive a text emphasis mark if they are combine with a space. if (m_forTextEmphasis && (!Font::canReceiveTextEmphasis(ch) || (U_GET_GC_MASK(ch) & U_GC_M_MASK))) @@ -564,7 +516,7 @@ void ComplexTextController::adjustGlyphsAndAdvances() if (!isMonotonic) complexTextRun.setIsNonMonotonic(); } - m_totalWidth += widthSinceLastRounding; + m_totalWidth += widthSinceLastCommit; } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/mac/ComplexTextController.h b/Source/WebCore/platform/graphics/mac/ComplexTextController.h index 63f93a2..7373bfe 100644 --- a/Source/WebCore/platform/graphics/mac/ComplexTextController.h +++ b/Source/WebCore/platform/graphics/mac/ComplexTextController.h @@ -60,9 +60,6 @@ public: float totalWidth() const { return m_totalWidth; } - // Extra width to the left of the leftmost glyph. - float finalRoundingWidth() const { return m_finalRoundingWidth; } - float minGlyphBoundingBoxX() const { return m_minGlyphBoundingBoxX; } float maxGlyphBoundingBoxX() const { return m_maxGlyphBoundingBoxX; } float minGlyphBoundingBoxY() const { return m_minGlyphBoundingBoxY; } @@ -176,7 +173,6 @@ private: size_t m_currentRun; unsigned m_glyphInCurrentRun; unsigned m_characterInCurrentGlyph; - float m_finalRoundingWidth; float m_expansion; float m_expansionPerOpportunity; bool m_afterExpansion; @@ -187,8 +183,6 @@ private: float m_maxGlyphBoundingBoxX; float m_minGlyphBoundingBoxY; float m_maxGlyphBoundingBoxY; - - unsigned m_lastRoundingGlyph; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp index 865051d..eed49a5 100644 --- a/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp +++ b/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp @@ -71,7 +71,7 @@ float Font::getGlyphsAndAdvancesForComplexText(const TextRun& run, int from, int float afterWidth = controller.runWidthSoFar(); if (run.rtl()) { - initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth; + initialAdvance = controller.totalWidth() - afterWidth; for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end) glyphBuffer.swap(i, end); } else diff --git a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp index 8b04ffa..fe2b33a 100644 --- a/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp +++ b/Source/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp @@ -83,6 +83,11 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b Vector<CGGlyph, 512> glyphVector; Vector<CFIndex, 512> indexVector; bool done = false; + + // For the CGFont comparison in the loop, use the CGFont that Core Text assigns to the CTFont. This may + // be non-CFEqual to fontData->platformData().cgFont(). + RetainPtr<CGFontRef> cgFont(AdoptCF, CTFontCopyGraphicsFont(fontData->platformData().ctFont(), 0)); + for (CFIndex r = 0; r < runCount && !done ; ++r) { // CTLine could map characters over multiple fonts using its own font fallback list. // We need to pick runs that use the exact font we need, i.e., fontData->platformData().ctFont(). @@ -93,7 +98,7 @@ bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned b CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(attributes, kCTFontAttributeName)); RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont, 0)); // Use CGFont here as CFEqual for CTFont counts all attributes for font. - if (CFEqual(fontData->platformData().cgFont(), runCGFont.get())) { + if (CFEqual(cgFont.get(), runCGFont.get())) { // This run uses the font we want. Extract glyphs. CFIndex glyphCount = CTRunGetGlyphCount(ctRun); const CGGlyph* glyphs = CTRunGetGlyphsPtr(ctRun); diff --git a/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm index 6a4fa03..2383006 100644 --- a/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm +++ b/Source/WebCore/platform/graphics/mac/GraphicsContextMac.mm @@ -112,14 +112,14 @@ static NSColor* createPatternColor(NSString* name, NSColor* defaultColor, bool& } // WebKit on Mac is a standard platform component, so it must use the standard platform artwork for underline. -void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& point, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; // These are the same for misspelling or bad grammar. int patternHeight = cMisspellingLineThickness; - int patternWidth = cMisspellingLinePatternWidth; + float patternWidth = cMisspellingLinePatternWidth; bool usingDot; NSColor *patternColor; @@ -165,7 +165,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, // space between adjacent misspelled words was underlined. if (usingDot) { // allow slightly more considering that the pattern ends with a transparent pixel - int widthMod = width % patternWidth; + float widthMod = fmodf(width, patternWidth); if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) width -= widthMod; } diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h index 95ab456..80bc94e 100644 --- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h +++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -177,6 +177,8 @@ private: virtual double maximumDurationToCacheMediaTime() const { return 5; } + virtual void setPrivateBrowsingMode(bool); + MediaPlayer* m_player; RetainPtr<QTMovie> m_qtMovie; RetainPtr<QTMovieView> m_qtMovieView; @@ -203,6 +205,7 @@ private: bool m_videoFrameHasDrawn; bool m_delayingLoad; bool m_isAllowedToRender; + bool m_privateBrowsing; #if DRAW_FRAME_RATE int m_frameCountWhilePlaying; double m_timeStartedPlaying; diff --git a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm index 8b1fb92..ecb7d9f 100644 --- a/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ b/Source/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -200,7 +200,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateQTKit::create(MediaPlayer* player void MediaPlayerPrivateQTKit::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player) @@ -224,6 +224,7 @@ MediaPlayerPrivateQTKit::MediaPlayerPrivateQTKit(MediaPlayer* player) , m_hasUnsupportedTracks(false) , m_videoFrameHasDrawn(false) , m_isAllowedToRender(false) + , m_privateBrowsing(false) #if DRAW_FRAME_RATE , m_frameCountWhilePlaying(0) , m_timeStartedPlaying(0) @@ -250,6 +251,7 @@ void MediaPlayerPrivateQTKit::createQTMovie(const String& url) [NSNumber numberWithBool:YES], QTSecurityPolicyNoCrossSiteAttribute, [NSNumber numberWithBool:NO], QTMovieAskUnresolvedDataRefsAttribute, [NSNumber numberWithBool:NO], QTMovieLoopsAttribute, + [NSNumber numberWithBool:!m_privateBrowsing], @"QTMovieAllowPersistentCacheAttribute", #ifndef BUILDING_ON_TIGER QTMovieApertureModeClean, QTMovieApertureModeAttribute, #endif @@ -552,14 +554,14 @@ MediaPlayerPrivateQTKit::MediaRenderingMode MediaPlayerPrivateQTKit::preferredRe if (!m_player->frameView() || !m_qtMovie) return MediaRenderingNone; - if (m_player->inMediaDocument() || !QTVideoRendererClass()) - return MediaRenderingMovieView; - #if USE(ACCELERATED_COMPOSITING) if (supportsAcceleratedRendering() && m_player->mediaPlayerClient()->mediaPlayerRenderingCanBeAccelerated(m_player)) return MediaRenderingMovieLayer; #endif + if (!QTVideoRendererClass()) + return MediaRenderingMovieView; + return MediaRenderingSoftwareRenderer; } @@ -1528,9 +1530,7 @@ void MediaPlayerPrivateQTKit::sawUnsupportedTracks() #if USE(ACCELERATED_COMPOSITING) bool MediaPlayerPrivateQTKit::supportsAcceleratedRendering() const { - // Also don't claim to support accelerated rendering when in the media document, as we will then render - // via QTMovieView which is already accelerated. - return isReadyForVideoSetup() && getQTMovieLayerClass() != Nil && !m_player->inMediaDocument(); + return isReadyForVideoSetup() && getQTMovieLayerClass() != Nil; } void MediaPlayerPrivateQTKit::acceleratedRenderingStateChanged() @@ -1577,6 +1577,15 @@ float MediaPlayerPrivateQTKit::mediaTimeForTimeValue(float timeValue) const return static_cast<float>(qttime.timeValue) / qttime.timeScale; } +void MediaPlayerPrivateQTKit::setPrivateBrowsingMode(bool privateBrowsing) +{ + m_privateBrowsing = privateBrowsing; + if (!m_qtMovie) + return; + [m_qtMovie.get() setAttribute:[NSNumber numberWithBool:!privateBrowsing] forKey:@"QTMovieAllowPersistentCacheAttribute"]; +} + + } // namespace WebCore @implementation WebCoreMovieObserver diff --git a/Source/WebCore/platform/graphics/mac/WebLayer.mm b/Source/WebCore/platform/graphics/mac/WebLayer.mm index 06ea9be..414a75f 100644 --- a/Source/WebCore/platform/graphics/mac/WebLayer.mm +++ b/Source/WebCore/platform/graphics/mac/WebLayer.mm @@ -61,6 +61,7 @@ void drawLayerContents(CGContextRef context, CALayer *layer, WebCore::PlatformCA [NSGraphicsContext setCurrentContext:layerContext]; GraphicsContext graphicsContext(context); + graphicsContext.setIsCALayerContext(true); if (!layerContents->platformCALayerContentsOpaque()) { // Turn off font smoothing to improve the appearance of text rendered onto a transparent background. diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp index df45147..e09534e 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.cpp @@ -87,6 +87,10 @@ bool Extensions3DOpenGL::supports(const String& name) // GL_OES_texture_half_float as available. if (name == "GL_OES_texture_float" || name == "GL_OES_texture_half_float") return m_availableExtensions.contains("GL_ARB_texture_float"); + + // GL_OES_vertex_array_object + if (name == "GL_OES_vertex_array_object") + return m_availableExtensions.contains("GL_APPLE_vertex_array_object"); // Desktop GL always supports the standard derivative functions if (name == "GL_OES_standard_derivatives") @@ -127,6 +131,53 @@ void Extensions3DOpenGL::renderbufferStorageMultisample(unsigned long target, un ::glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height); } +Platform3DObject Extensions3DOpenGL::createVertexArrayOES() +{ + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + GLuint array = 0; + glGenVertexArraysAPPLE(1, &array); + return array; +#else + return 0; +#endif +} + +void Extensions3DOpenGL::deleteVertexArrayOES(Platform3DObject array) +{ + if (!array) + return; + + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + glDeleteVertexArraysAPPLE(1, &array); +#endif +} + +GC3Dboolean Extensions3DOpenGL::isVertexArrayOES(Platform3DObject array) +{ + if (!array) + return GL_FALSE; + + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + return glIsVertexArrayAPPLE(array); +#else + return GL_FALSE; +#endif +} + +void Extensions3DOpenGL::bindVertexArrayOES(Platform3DObject array) +{ + if (!array) + return; + + m_context->makeContextCurrent(); +#if defined GL_APPLE_vertex_array_object && GL_APPLE_vertex_array_object + glBindVertexArrayAPPLE(array); +#endif +} + } // namespace WebCore #endif // ENABLE(WEBGL) diff --git a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h index 1941a42..9188507 100644 --- a/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h +++ b/Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h @@ -43,7 +43,12 @@ public: virtual void ensureEnabled(const String&); virtual int getGraphicsResetStatusARB(); virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); - virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + + virtual Platform3DObject createVertexArrayOES(); + virtual void deleteVertexArrayOES(Platform3DObject); + virtual GC3Dboolean isVertexArrayOES(Platform3DObject); + virtual void bindVertexArrayOES(Platform3DObject); private: // This class only needs to be instantiated by GraphicsContext3D implementations. diff --git a/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp b/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp index 6466a9c..75dbadb 100644 --- a/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp +++ b/Source/WebCore/platform/graphics/openvg/GraphicsContextOpenVG.cpp @@ -458,6 +458,14 @@ void GraphicsContext::concatCTM(const AffineTransform& transformation) m_data->concatTransformation(transformation); } +void GraphicsContext::setCTM(const AffineTransform& transformation) +{ + if (paintingDisabled()) + return; + + m_data->setTransformation(transformation); +} + void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect) { notImplemented(); diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp index 5238d46..dcea72f 100644 --- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.cpp @@ -56,6 +56,32 @@ int Extensions3DQt::getGraphicsResetStatusARB() return GraphicsContext3D::NO_ERROR; } +void Extensions3DQt::blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter) +{ +} + +void Extensions3DQt::renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height) +{ +} + +Platform3DObject Extensions3DQt::createVertexArrayOES() +{ + return 0; +} + +void Extensions3DQt::deleteVertexArrayOES(Platform3DObject) +{ +} + +GC3Dboolean Extensions3DQt::isVertexArrayOES(Platform3DObject) +{ + return GL_FALSE; +} + +void Extensions3DQt::bindVertexArrayOES(Platform3DObject) +{ +} + } // namespace WebCore #endif // ENABLE(WEBGL) diff --git a/Source/WebCore/platform/graphics/qt/Extensions3DQt.h b/Source/WebCore/platform/graphics/qt/Extensions3DQt.h index ae4b375..c67fbed 100644 --- a/Source/WebCore/platform/graphics/qt/Extensions3DQt.h +++ b/Source/WebCore/platform/graphics/qt/Extensions3DQt.h @@ -38,6 +38,12 @@ public: virtual bool supports(const String&); virtual void ensureEnabled(const String&); virtual int getGraphicsResetStatusARB(); + virtual void blitFramebuffer(long srcX0, long srcY0, long srcX1, long srcY1, long dstX0, long dstY0, long dstX1, long dstY1, unsigned long mask, unsigned long filter); + virtual void renderbufferStorageMultisample(unsigned long target, unsigned long samples, unsigned long internalformat, unsigned long width, unsigned long height); + virtual Platform3DObject createVertexArrayOES(); + virtual void deleteVertexArrayOES(Platform3DObject); + virtual GC3Dboolean isVertexArrayOES(Platform3DObject); + virtual void bindVertexArrayOES(Platform3DObject); private: // This class only needs to be instantiated by GraphicsContext3D implementations. diff --git a/Source/WebCore/platform/graphics/qt/FontPlatformData.h b/Source/WebCore/platform/graphics/qt/FontPlatformData.h index f268370..32e8a2d 100644 --- a/Source/WebCore/platform/graphics/qt/FontPlatformData.h +++ b/Source/WebCore/platform/graphics/qt/FontPlatformData.h @@ -24,142 +24,120 @@ #ifndef FontPlatformData_h #define FontPlatformData_h -#include <wtf/Forward.h> #include "FontDescription.h" #include "FontOrientation.h" #include <QFont> #include <QHash> +#include <wtf/Forward.h> +#include <wtf/RefCounted.h> namespace WebCore { -class FontPlatformDataPrivate { +class FontPlatformDataPrivate : public RefCounted<FontPlatformDataPrivate> { WTF_MAKE_NONCOPYABLE(FontPlatformDataPrivate); WTF_MAKE_FAST_ALLOCATED; public: FontPlatformDataPrivate() - : refCount(1) - , size(font.pixelSize()) + : size(font.pixelSize()) , bold(font.bold()) , oblique(false) - {} + , isDeletedValue(false) + { } FontPlatformDataPrivate(const float size, const bool bold, const bool oblique) - : refCount(1) - , size(size) + : size(size) , bold(bold) , oblique(oblique) - {} + , isDeletedValue(false) + { } FontPlatformDataPrivate(const QFont& font) - : refCount(1) - , font(font) + : font(font) , size(font.pixelSize()) , bold(font.bold()) , oblique(false) - {} - unsigned refCount; + , isDeletedValue(false) + { } + FontPlatformDataPrivate(WTF::HashTableDeletedValueType) + : isDeletedValue(true) + { } + QFont font; float size; bool bold : 1; bool oblique : 1; + bool isDeletedValue : 1; }; - - class FontPlatformData { WTF_MAKE_FAST_ALLOCATED; public: - FontPlatformData() { } FontPlatformData(float size, bool bold, bool oblique); - FontPlatformData(const FontPlatformData &); FontPlatformData(const FontDescription&, const AtomicString& familyName, int wordSpacing = 0, int letterSpacing = 0); FontPlatformData(const QFont& font) - : m_data(new FontPlatformDataPrivate(font)) - {} + : m_data(adoptRef(new FontPlatformDataPrivate(font))) + { } FontPlatformData(WTF::HashTableDeletedValueType) - : m_data(reinterpret_cast<FontPlatformDataPrivate*>(-1)) - {} - - ~FontPlatformData(); + : m_data(adoptRef(new FontPlatformDataPrivate())) + { + m_data->isDeletedValue = true; + } - FontPlatformData& operator=(const FontPlatformData&); bool operator==(const FontPlatformData&) const; bool isHashTableDeletedValue() const { - return m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1); - } - - static inline QFont::Weight toQFontWeight(FontWeight fontWeight) - { - switch (fontWeight) { - case FontWeight100: - case FontWeight200: - return QFont::Light; // QFont::Light == Weight of 25 - case FontWeight600: - return QFont::DemiBold; // QFont::DemiBold == Weight of 63 - case FontWeight700: - case FontWeight800: - return QFont::Bold; // QFont::Bold == Weight of 75 - case FontWeight900: - return QFont::Black; // QFont::Black == Weight of 87 - case FontWeight300: - case FontWeight400: - case FontWeight500: - default: - return QFont::Normal; // QFont::Normal == Weight of 50 - } + return m_data && m_data->isDeletedValue; } QFont font() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font; - return QFont(); + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return QFont(); + return m_data->font; } float size() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->size; - return 0.0f; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return 0; + return m_data->size; } QString family() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font.family(); - return QString(); + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return QString(); + return m_data->font.family(); } bool bold() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->bold; - return false; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return false; + return m_data->bold; } bool italic() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font.italic(); - return false; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return false; + return m_data->font.italic(); } bool smallCaps() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) - return m_data->font.capitalization() == QFont::SmallCaps; - return false; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return false; + return m_data->font.capitalization() == QFont::SmallCaps; } int pixelSize() const { - Q_ASSERT(m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)); - if (m_data) { - // WebKit allows font size zero but QFont does not. - if (!m_data->size) - return m_data->size; - return m_data->font.pixelSize(); - } - return 0; + Q_ASSERT(!isHashTableDeletedValue()); + if (!m_data) + return 0; + // WebCore allows a font size of zero, but QFont does not. + if (!m_data->size) + return 0; + return m_data->font.pixelSize(); } FontOrientation orientation() const { return Horizontal; } // FIXME: Implement. @@ -170,7 +148,7 @@ public: String description() const; #endif private: - FontPlatformDataPrivate* m_data; + RefPtr<FontPlatformDataPrivate> m_data; }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp b/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp index 4c9eb32..185ae85 100644 --- a/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/FontPlatformDataQt.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2008 Holger Hans Peter Freyther Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/ + Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -26,6 +27,27 @@ namespace WebCore { +static inline QFont::Weight toQFontWeight(FontWeight fontWeight) +{ + switch (fontWeight) { + case FontWeight100: + case FontWeight200: + return QFont::Light; // QFont::Light == Weight of 25 + case FontWeight600: + return QFont::DemiBold; // QFont::DemiBold == Weight of 63 + case FontWeight700: + case FontWeight800: + return QFont::Bold; // QFont::Bold == Weight of 75 + case FontWeight900: + return QFont::Black; // QFont::Black == Weight of 87 + case FontWeight300: + case FontWeight400: + case FontWeight500: + default: + return QFont::Normal; // QFont::Normal == Weight of 50 + } +} + static inline bool isEmptyValue(const float size, const bool bold, const bool oblique) { // this is the empty value by definition of the trait FontDataCacheKeyTraits @@ -34,20 +56,12 @@ static inline bool isEmptyValue(const float size, const bool bold, const bool ob FontPlatformData::FontPlatformData(float size, bool bold, bool oblique) { - if (isEmptyValue(size, bold, oblique)) - m_data = 0; - else - m_data = new FontPlatformDataPrivate(size, bold, oblique); -} - -FontPlatformData::FontPlatformData(const FontPlatformData &other) : m_data(other.m_data) -{ - if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) - ++m_data->refCount; + if (!isEmptyValue(size, bold, oblique)) + m_data = adoptRef(new FontPlatformDataPrivate(size, bold, oblique)); } FontPlatformData::FontPlatformData(const FontDescription& description, const AtomicString& familyName, int wordSpacing, int letterSpacing) - : m_data(new FontPlatformDataPrivate()) + : m_data(adoptRef(new FontPlatformDataPrivate())) { QFont& font = m_data->font; int requestedSize = qRound(description.computedPixelSize()); @@ -70,38 +84,13 @@ FontPlatformData::FontPlatformData(const FontDescription& description, const Ato m_data->size = (!requestedSize) ? requestedSize : font.pixelSize(); } -FontPlatformData::~FontPlatformData() -{ - if (!m_data || m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) - return; - --m_data->refCount; - if (!m_data->refCount) - delete m_data; -} - -FontPlatformData& FontPlatformData::operator=(const FontPlatformData& other) -{ - if (m_data == other.m_data) - return *this; - if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) { - --m_data->refCount; - if (!m_data->refCount) - delete m_data; - } - m_data = other.m_data; - if (m_data && m_data != reinterpret_cast<FontPlatformDataPrivate*>(-1)) - ++m_data->refCount; - return *this; -} - bool FontPlatformData::operator==(const FontPlatformData& other) const { if (m_data == other.m_data) return true; - if (!m_data || !other.m_data - || m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1) || other.m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) - return false; + if (!m_data || !other.m_data || m_data->isDeletedValue || other.m_data->isDeletedValue) + return false; const bool equals = (m_data->size == other.m_data->size && m_data->bold == other.m_data->bold @@ -114,7 +103,7 @@ unsigned FontPlatformData::hash() const { if (!m_data) return 0; - if (m_data == reinterpret_cast<FontPlatformDataPrivate*>(-1)) + if (m_data->isDeletedValue) return 1; return qHash(m_data->font.toString()) ^ qHash(*reinterpret_cast<quint32*>(&m_data->size)) diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index 8b87f5f..b849214 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -252,7 +252,7 @@ public: GLuint m_currentFbo; GLuint m_depthBuffer; QImage m_pixels; - ListHashSet<unsigned long> m_syntheticErrors; + ListHashSet<unsigned int> m_syntheticErrors; OwnPtr<Extensions3DQt> m_extensions; @@ -277,24 +277,6 @@ bool GraphicsContext3D::isGLES2Compliant() const #endif } -// Even with underlying GLES2 driver, the below flags should still be set to -// false if extentions exist (and they almost always do). -bool GraphicsContext3D::isGLES2NPOTStrict() const -{ - return false; -} - -bool GraphicsContext3D::isErrorGeneratedOnOutOfBoundsAccesses() const -{ - return false; -} - -int GraphicsContext3D::getGraphicsResetStatusARB() -{ - return NO_ERROR; -} - - GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) : m_attrs(attrs) , m_hostWindow(hostWindow) @@ -499,12 +481,12 @@ void* GraphicsContext3DInternal::getProcAddress(const String& proc) return 0; } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) +PassRefPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow, GraphicsContext3D::RenderStyle renderStyle) { // This implementation doesn't currently support rendering directly to the HostWindow. if (renderStyle == RenderDirectlyToHostWindow) return 0; - OwnPtr<GraphicsContext3D> context(new GraphicsContext3D(attrs, hostWindow, false)); + RefPtr<GraphicsContext3D> context = adoptRef(new GraphicsContext3D(attrs, hostWindow, false)); return context->m_internal ? context.release() : 0; } @@ -1038,7 +1020,7 @@ GC3Dboolean GraphicsContext3D::isTexture(Platform3DObject texture) return glIsTexture(texture); } -void GraphicsContext3D::lineWidth(double width) +void GraphicsContext3D::lineWidth(GC3Dfloat width) { m_internal->m_glWidget->makeCurrent(); glLineWidth(static_cast<float>(width)); @@ -1489,7 +1471,7 @@ void GraphicsContext3D::getUniformiv(Platform3DObject program, GC3Dint location, m_internal->getUniformiv(program, location, value); } -long GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) +GC3Dint GraphicsContext3D::getUniformLocation(Platform3DObject program, const String& name) { ASSERT(program); @@ -1620,7 +1602,7 @@ Extensions3D* GraphicsContext3D::getExtensions() { if (!m_internal->m_extensions) m_internal->m_extensions = adoptPtr(new Extensions3DQt); - return m_internal->m_extensions; + return m_internal->m_extensions.get(); } bool GraphicsContext3D::getImageData(Image* image, @@ -1637,13 +1619,13 @@ bool GraphicsContext3D::getImageData(Image* image, if (!nativePixmap) return false; - AlphaOp neededAlphaOp = kAlphaDoNothing; + AlphaOp neededAlphaOp = AlphaDoNothing; if (!premultiplyAlpha) // FIXME: must fetch the image data before the premultiplication step - neededAlphaOp = kAlphaDoUnmultiply; + neededAlphaOp = AlphaDoUnmultiply; QImage nativeImage = nativePixmap->toImage().convertToFormat(QImage::Format_ARGB32); outputVector.resize(nativeImage.byteCount()); - return packPixels(nativeImage.rgbSwapped().bits(), kSourceFormatRGBA8, image->width(), image->height(), 0, + return packPixels(nativeImage.rgbSwapped().bits(), SourceFormatRGBA8, image->width(), image->height(), 0, format, type, neededAlphaOp, outputVector.data()); } diff --git a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index bf2826c..9742755 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -555,8 +555,17 @@ void GraphicsContext::strokePath(const Path& path) boundingRect.inflate(pen.miterLimit() + pen.widthF()); QPainter* shadowPainter = shadow->beginShadowLayer(this, boundingRect); if (shadowPainter) { - shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255); - shadowPainter->strokePath(platformPath, pen); + if (m_state.strokeGradient) { + QBrush brush(*m_state.strokeGradient->platformGradient()); + brush.setTransform(m_state.strokeGradient->gradientSpaceTransform()); + QPen shadowPen(pen); + shadowPen.setBrush(brush); + shadowPainter->setOpacity(static_cast<qreal>(shadow->m_color.alpha()) / 255); + shadowPainter->strokePath(platformPath, shadowPen); + } else { + shadowPainter->setOpacity(static_cast<qreal>(m_data->shadow.m_color.alpha()) / 255); + shadowPainter->strokePath(platformPath, pen); + } shadow->endShadowLayer(this); } } else { @@ -769,6 +778,14 @@ ContextShadow* GraphicsContext::contextShadow() return &m_data->shadow; } +void GraphicsContext::clip(const IntRect& rect) +{ + if (paintingDisabled()) + return; + + m_data->p()->setClipRect(rect, Qt::IntersectClip); +} + void GraphicsContext::clip(const FloatRect& rect) { if (paintingDisabled()) @@ -846,13 +863,13 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int drawFocusRingForPath(m_data->p(), path, color, m_data->antiAliasingForRectsAndLines); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool) { if (paintingDisabled()) return; - IntPoint startPoint = origin; - IntPoint endPoint = origin + IntSize(width, 0); + FloatPoint startPoint = origin; + FloatPoint endPoint = origin + FloatSize(width, 0); // If paintengine type is X11 to avoid artifacts // like bug https://bugs.webkit.org/show_bug.cgi?id=42248 @@ -872,10 +889,11 @@ void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool) } #endif // defined(Q_WS_X11) - drawLine(startPoint, endPoint); + // FIXME: Loss of precision here. Might consider rounding. + drawLine(IntPoint(startPoint.x(), startPoint.y()), IntPoint(endPoint.x(), endPoint.y())); } -void GraphicsContext::drawLineForTextChecking(const IntPoint&, int, TextCheckingLineStyle) +void GraphicsContext::drawLineForTextChecking(const FloatPoint&, float, TextCheckingLineStyle) { if (paintingDisabled()) return; @@ -1204,6 +1222,14 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->p()->setWorldTransform(transform, true); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + + m_data->p()->setWorldTransform(transform); +} + void GraphicsContext::setURLForRect(const KURL&, const IntRect&) { notImplemented(); diff --git a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index 0d7aa45..f3cfc47 100644 --- a/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/Source/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -54,7 +54,6 @@ #define GRAPHICS_LAYER_TILING_THRESHOLD 2000 #endif - #define QT_DEBUG_RECACHE 0 #define QT_DEBUG_CACHEDUMP 0 @@ -62,6 +61,8 @@ namespace WebCore { +static const int gMinimumPixmapCacheLimit = 2048; + #ifndef QT_NO_GRAPHICSEFFECT class MaskEffectQt : public QGraphicsEffect { public: @@ -207,6 +208,10 @@ public: virtual Color tiledBackingStoreBackgroundColor() const; #endif + static bool allowAcceleratedCompositingCache() { return QPixmapCache::cacheLimit() > gMinimumPixmapCacheLimit; } + + void drawLayerContent(QPainter*, const QRect&); + public slots: // We need to notify the client (ie. the layer compositor) when the animation actually starts. void notifyAnimationStarted(); @@ -381,6 +386,15 @@ const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const return this; } + +void GraphicsLayerQtImpl::drawLayerContent(QPainter* painter, const QRect& clipRect) +{ + painter->setClipRect(clipRect, Qt::IntersectClip); + painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + GraphicsContext gc(painter); + m_layer->paintGraphicsLayerContents(gc, clipRect); +} + QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) { if (!m_layer->drawsContent() || m_size.isEmpty() || !m_size.isValid()) @@ -630,12 +644,16 @@ void GraphicsLayerQtImpl::paint(QPainter* painter, const QStyleOptionGraphicsIte switch (m_currentContent.contentType) { case HTMLContentType: if (m_state.drawsContent) { - QPixmap backingStore; - // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). - if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) - backingStore = recache(QRegion(m_state.contentsRect)); - const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); - painter->drawPixmap(0, 0, backingStore); + if (!allowAcceleratedCompositingCache()) + drawLayerContent(painter, option->exposedRect.toRect()); + else { + QPixmap backingStore; + // We might need to recache, in case we try to paint and the cache was purged (e.g. if it was full). + if (!QPixmapCache::find(m_backingStore.key, &backingStore) || backingStore.size() != m_size.toSize()) + backingStore = recache(QRegion(m_state.contentsRect)); + const QRectF bounds(0, 0, m_backingStore.size.width(), m_backingStore.size.height()); + painter->drawPixmap(0, 0, backingStore); + } } break; case PixmapContentType: @@ -837,7 +855,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform // Recache now: all the content is ready and we don't want to wait until the paint event. // We only need to do this for HTML content, there's no point in caching directly composited // content like images or solid rectangles. - if (m_pendingContent.contentType == HTMLContentType) + if (m_pendingContent.contentType == HTMLContentType && allowAcceleratedCompositingCache()) recache(m_pendingContent.regionToUpdate); #endif update(m_pendingContent.regionToUpdate.boundingRect()); diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp index fab4db1..547dabc 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp @@ -126,7 +126,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivatePhonon::create(MediaPlayer* playe void MediaPlayerPrivatePhonon::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index caf9c2d..001d45b 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -24,7 +24,6 @@ #include "GraphicsContext.h" #include "HTMLMediaElement.h" #include "HTMLVideoElement.h" -#include "QtNAMThreadSafeProxy.h" #include "NetworkingContext.h" #include "NotImplemented.h" #include "RenderVideo.h" @@ -66,7 +65,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateQt::create(MediaPlayer* player) void MediaPlayerPrivateQt::registerMediaEngine(MediaEngineRegistrar registrar) { - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } void MediaPlayerPrivateQt::getSupportedTypes(HashSet<String> &supported) @@ -106,6 +105,7 @@ MediaPlayerPrivateQt::MediaPlayerPrivateQt(MediaPlayer* player) , m_composited(false) , m_queuedSeek(-1) , m_preload(MediaPlayer::Auto) + , m_suppressNextPlaybackChanged(false) { m_mediaPlayer->setVideoOutput(m_videoItem); m_videoScene->addItem(m_videoItem); @@ -187,7 +187,8 @@ void MediaPlayerPrivateQt::commitLoad(const String& url) m_webCorePlayer->readyStateChanged(); } - const QUrl rUrl = QUrl(QString(url)); + KURL kUrl(ParsedURLString, url); + const QUrl rUrl = kUrl; const QString scheme = rUrl.scheme().toLower(); // Grab the client media element @@ -209,8 +210,8 @@ void MediaPlayerPrivateQt::commitLoad(const String& url) if (manager) { // Set the cookies - QtNAMThreadSafeProxy managerProxy(manager); - QList<QNetworkCookie> cookies = managerProxy.cookiesForUrl(rUrl); + QNetworkCookieJar* jar = manager->cookieJar(); + QList<QNetworkCookie> cookies = jar->cookiesForUrl(rUrl); // Don't set the header if there are no cookies. // This prevents a warning from being emitted. @@ -239,6 +240,9 @@ void MediaPlayerPrivateQt::commitLoad(const String& url) m_mediaPlayer->setMuted(element->muted()); m_mediaPlayer->setVolume(static_cast<int>(element->volume() * 100.0)); + // Don't send PlaybackChanged notification for pre-roll. + m_suppressNextPlaybackChanged = true; + // Setting a media source will start loading the media, but we need // to pre-roll as well to get video size-hints and buffer-status if (element->paused()) @@ -445,6 +449,11 @@ void MediaPlayerPrivateQt::stateChanged(QMediaPlayer::State state) m_mediaPlayer->setPosition(m_queuedSeek); m_queuedSeek = -1; } + + if (!m_suppressNextPlaybackChanged) + m_webCorePlayer->playbackStateChanged(); + else + m_suppressNextPlaybackChanged = false; } void MediaPlayerPrivateQt::nativeSizeChanged(const QSizeF& size) diff --git a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h index e4133db..81cdd79 100644 --- a/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h +++ b/Source/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h @@ -157,6 +157,7 @@ private: MediaPlayer::Preload m_preload; bool m_delayingLoad; String m_mediaUrl; + bool m_suppressNextPlaybackChanged; }; } diff --git a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp index 9e43558..5d0b302 100644 --- a/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp +++ b/Source/WebCore/platform/graphics/qt/SimpleFontDataQt.cpp @@ -61,7 +61,6 @@ void SimpleFontData::platformGlyphInit() if (!m_platformData.size()) return; m_spaceGlyph = 0; - m_adjustedSpaceWidth = m_spaceWidth; determinePitch(); m_missingGlyphData.fontData = this; m_missingGlyphData.glyph = 0; diff --git a/Source/WebCore/platform/graphics/skia/GradientSkia.cpp b/Source/WebCore/platform/graphics/skia/GradientSkia.cpp index a636d10..2aadc08 100644 --- a/Source/WebCore/platform/graphics/skia/GradientSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/GradientSkia.cpp @@ -110,23 +110,14 @@ static void fillStops(const Gradient::ColorStop* stopData, } } -static inline bool compareStops(const Gradient::ColorStop& a, const Gradient::ColorStop& b) -{ - return a.stop < b.stop; -} - SkShader* Gradient::platformGradient() { if (m_gradient) return m_gradient; - // FIXME: This and compareStops() are also in Gradient.cpp and - // CSSGradientValue.cpp; probably should refactor in WebKit. - if (!m_stopsSorted) { - if (m_stops.size()) - std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); - m_stopsSorted = true; - } + sortStopsIfNecessary(); + ASSERT(m_stopsSorted); + size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); @@ -167,17 +158,23 @@ SkShader* Gradient::platformGradient() SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; m_gradient = SkGradientShader::CreateTwoPointRadial(m_p0, radius0, m_p1, radius1, colors, pos, static_cast<int>(countUsed), tile); } + + if (aspectRatio() != 1) { + // CSS3 elliptical gradients: apply the elliptical scaling at the + // gradient center point. + m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); + m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); + m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); + ASSERT(m_p0 == m_p1); + } } else { SkPoint pts[2] = { m_p0, m_p1 }; - m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, - static_cast<int>(countUsed), tile); + m_gradient = SkGradientShader::CreateLinear(pts, colors, pos, static_cast<int>(countUsed), tile); } ASSERT(m_gradient); - SkMatrix matrix = m_gradientSpaceTransformation; m_gradient->setLocalMatrix(matrix); - return m_gradient; } diff --git a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 9f2ed32..00afd07 100644 --- a/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -436,6 +436,17 @@ void GraphicsContext::concatCTM(const AffineTransform& affine) platformContext()->canvas()->concat(affine); } +void GraphicsContext::setCTM(const AffineTransform& affine) +{ + if (paintingDisabled()) + return; + + if (platformContext()->useGPU()) + platformContext()->gpuCanvas()->setCTM(affine); + + platformContext()->canvas()->setMatrix(affine); +} + void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias) @@ -595,7 +606,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint); } -void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& pt, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; @@ -644,8 +655,8 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex } // Offset it vertically by 1 so that there's some space under the text. - SkScalar originX = SkIntToScalar(pt.x()); - SkScalar originY = SkIntToScalar(pt.y()) + 1; + SkScalar originX = WebCoreFloatToSkScalar(pt.x()); + SkScalar originY = WebCoreFloatToSkScalar(pt.y()) + 1; // Make a shader for the bitmap with an origin of the box we'll draw. This // shader is refcounted and will have an initial refcount of 1. @@ -667,13 +678,13 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, Tex SkRect rect; rect.set(originX, originY, - originX + SkIntToScalar(width), + originX + WebCoreFloatToSkScalar(width), originY + SkIntToScalar(misspellBitmap->height())); platformContext()->canvas()->drawRect(rect, paint); } -void GraphicsContext::drawLineForText(const IntPoint& pt, - int width, +void GraphicsContext::drawLineForText(const FloatPoint& pt, + float width, bool printing) { if (paintingDisabled()) @@ -686,9 +697,9 @@ void GraphicsContext::drawLineForText(const IntPoint& pt, int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); SkRect r; - r.fLeft = SkIntToScalar(pt.x()); - r.fTop = SkIntToScalar(pt.y()); - r.fRight = r.fLeft + SkIntToScalar(width); + r.fLeft = WebCoreFloatToSkScalar(pt.x()); + r.fTop = WebCoreFloatToSkScalar(pt.y()); + r.fRight = r.fLeft + WebCoreFloatToSkScalar(width); r.fBottom = r.fTop + SkIntToScalar(thickness); SkPaint paint; @@ -720,6 +731,7 @@ void GraphicsContext::fillPath(const Path& pathToFill) if (paintingDisabled()) return; + // FIXME: add support to GLES2Canvas for more than just solid fills. if (platformContext()->useGPU() && platformContext()->canAccelerate()) { platformContext()->prepareForHardwareDraw(); platformContext()->gpuCanvas()->fillPath(pathToFill); @@ -857,43 +869,7 @@ AffineTransform GraphicsContext::getCTM() const FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect) { - // This logic is copied from GraphicsContextCG, eseidel 5/05/08 - - // It is not enough just to round to pixels in device space. The rotation - // part of the affine transform matrix to device space can mess with this - // conversion if we have a rotating image like the hands of the world clock - // widget. We just need the scale, so we get the affine transform matrix and - // extract the scale. - - const SkMatrix& deviceMatrix = platformContext()->canvas()->getTotalMatrix(); - if (deviceMatrix.isIdentity()) - return rect; - - float deviceScaleX = sqrtf(square(deviceMatrix.getScaleX()) - + square(deviceMatrix.getSkewY())); - float deviceScaleY = sqrtf(square(deviceMatrix.getSkewX()) - + square(deviceMatrix.getScaleY())); - - FloatPoint deviceOrigin(rect.x() * deviceScaleX, rect.y() * deviceScaleY); - FloatPoint deviceLowerRight((rect.x() + rect.width()) * deviceScaleX, - (rect.y() + rect.height()) * deviceScaleY); - - deviceOrigin.setX(roundf(deviceOrigin.x())); - deviceOrigin.setY(roundf(deviceOrigin.y())); - deviceLowerRight.setX(roundf(deviceLowerRight.x())); - deviceLowerRight.setY(roundf(deviceLowerRight.y())); - - // Don't let the height or width round to 0 unless either was originally 0 - if (deviceOrigin.y() == deviceLowerRight.y() && rect.height()) - deviceLowerRight.move(0, 1); - if (deviceOrigin.x() == deviceLowerRight.x() && rect.width()) - deviceLowerRight.move(1, 0); - - FloatPoint roundedOrigin(deviceOrigin.x() / deviceScaleX, - deviceOrigin.y() / deviceScaleY); - FloatPoint roundedLowerRight(deviceLowerRight.x() / deviceScaleX, - deviceLowerRight.y() / deviceScaleY); - return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); + return rect; } void GraphicsContext::scale(const FloatSize& size) diff --git a/Source/WebCore/platform/graphics/skia/PathSkia.cpp b/Source/WebCore/platform/graphics/skia/PathSkia.cpp index 6318c21..0344086 100644 --- a/Source/WebCore/platform/graphics/skia/PathSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/PathSkia.cpp @@ -144,7 +144,8 @@ void Path::addArc(const FloatPoint& p, float r, float sa, float ea, bool anticlo // Move to the start position (0 sweep means we add a single point). m_path->arcTo(oval, startDegrees, 0, false); // Draw the circle. - m_path->addOval(oval); + m_path->addOval(oval, anticlockwise ? + SkPath::kCCW_Direction : SkPath::kCW_Direction); // Force a moveTo the end position. m_path->arcTo(oval, startDegrees + sweepDegrees, 0, true); } else { diff --git a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index 5e08b3c..eac5e4a 100644 --- a/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp @@ -688,7 +688,7 @@ void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths) paint.setStyle(SkPaint::kFill_Style); for (size_t i = paths.size() - 1; i < paths.size(); --i) { - paths[i].setFillType(SkPath::kInverseWinding_FillType); + paths[i].toggleInverseFillType(); m_canvas->drawPath(paths[i], paint); } @@ -821,7 +821,7 @@ void PlatformContextSkia::syncSoftwareCanvas() const if (!m_useGPU) { #if ENABLE(SKIA_GPU) if (m_gpuCanvas) - m_gpuCanvas->bindFramebuffer(); + m_gpuCanvas->context()->makeContextCurrent(); #endif return; } diff --git a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp index 5046c50..54aa35e 100644 --- a/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp +++ b/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp @@ -38,10 +38,17 @@ #include "SkCanvas.h" #include "SkPaint.h" #include "SkShader.h" +#include "SkTemplates.h" +#include "SkTypeface.h" #include <wtf/ListHashSet.h> #include <wtf/Vector.h> +#if ENABLE(SKIA_TEXT) +// FIXME: a future role of skia will have this in a proper header +extern SkTypeface* SkCreateTypefaceFromLOGFONT(const LOGFONT&); +#endif + namespace WebCore { struct CachedOutlineKey { @@ -273,6 +280,23 @@ static bool skiaDrawText(HFONT hfont, const GOFFSET* offsets, int numGlyphs) { +#if ENABLE(SKIA_TEXT) + SkASSERT(sizeof(WORD) == sizeof(uint16_t)); + + // Reserve space for 64 glyphs on the stack. If numGlyphs is larger, the array + // will dynamically allocate it space for numGlyph glyphs. + static const size_t kLocalGlyphMax = 64; + SkAutoSTArray<kLocalGlyphMax, SkPoint> posStorage(numGlyphs); + SkPoint* pos = posStorage.get(); + SkScalar x = point.fX; + SkScalar y = point.fY; + for (int i = 0; i < numGlyphs; i++) { + pos[i].set(x + (offsets ? offsets[i].du : 0), + y + (offsets ? offsets[i].dv : 0)); + x += SkIntToScalar(advances[i]); + } + canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, *paint); +#else float x = point.fX, y = point.fY; for (int i = 0; i < numGlyphs; i++) { @@ -292,10 +316,31 @@ static bool skiaDrawText(HFONT hfont, x += advances[i]; } - +#endif return true; } +#if ENABLE(SKIA_TEXT) +static void setupPaintForFont(HFONT hfont, SkPaint* paint) +{ + // FIXME: + // Much of this logic could also happen in + // FontCustomPlatformData::fontPlatformData and be cached, + // allowing us to avoid talking to GDI at this point. + // + LOGFONT info; + GetObject(hfont, sizeof(info), &info); + int size = info.lfHeight; + if (size < 0) + size = -size; // We don't let GDI dpi-scale us (see SkFontHost_win.cpp). + paint->setTextSize(SkIntToScalar(size)); + + SkTypeface* face = SkCreateTypefaceFromLOGFONT(info); + paint->setTypeface(face); + SkSafeUnref(face); +} +#endif + bool paintSkiaText(GraphicsContext* context, HFONT hfont, int numGlyphs, @@ -314,6 +359,10 @@ bool paintSkiaText(GraphicsContext* context, SkPaint paint; platformContext->setupPaintForFilling(&paint); paint.setFlags(SkPaint::kAntiAlias_Flag); +#if ENABLE(SKIA_TEXT) + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + setupPaintForFont(hfont, &paint); +#endif bool didFill = false; if ((textMode & TextModeFill) && SkColorGetA(paint.getColor())) { diff --git a/Source/WebCore/platform/graphics/transforms/AffineTransform.h b/Source/WebCore/platform/graphics/transforms/AffineTransform.h index 3e3995f..14431aa 100644 --- a/Source/WebCore/platform/graphics/transforms/AffineTransform.h +++ b/Source/WebCore/platform/graphics/transforms/AffineTransform.h @@ -40,7 +40,7 @@ #include "VGUtils.h" #elif PLATFORM(QT) #include <QTransform> -#elif PLATFORM(SKIA) +#elif USE(SKIA) #include <SkMatrix.h> #elif PLATFORM(WX) && USE(WXGC) #include <wx/graphics.h> @@ -165,7 +165,7 @@ public: operator VGMatrix() const; #elif PLATFORM(QT) operator QTransform() const; -#elif PLATFORM(SKIA) +#elif USE(SKIA) operator SkMatrix() const; #elif PLATFORM(WX) && USE(WXGC) operator wxGraphicsMatrix() const; diff --git a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h index fa27c0e..adda46b 100644 --- a/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h +++ b/Source/WebCore/platform/graphics/transforms/TransformationMatrix.h @@ -32,17 +32,17 @@ #include <wtf/FastAllocBase.h> #if PLATFORM(CA) -#include <QuartzCore/CATransform3D.h> +typedef struct CATransform3D CATransform3D; #endif #if PLATFORM(CG) -#include <CoreGraphics/CGAffineTransform.h> +typedef struct CGAffineTransform CGAffineTransform; #elif PLATFORM(CAIRO) #include <cairo.h> #elif PLATFORM(OPENVG) #include "VGUtils.h" #elif PLATFORM(QT) #include <QTransform> -#elif PLATFORM(SKIA) +#elif USE(SKIA) #include <SkMatrix.h> #elif PLATFORM(WX) && USE(WXGC) #include <wx/graphics.h> @@ -321,7 +321,7 @@ public: operator VGMatrix() const; #elif PLATFORM(QT) operator QTransform() const; -#elif PLATFORM(SKIA) +#elif USE(SKIA) operator SkMatrix() const; #elif PLATFORM(WX) && USE(WXGC) operator wxGraphicsMatrix() const; diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp index d3c6b58..d0bd4e9 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextCGWin.cpp @@ -184,7 +184,7 @@ static const Color& grammarPatternColor() { return grammarColor; } -void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& point, float width, TextCheckingLineStyle style) { if (paintingDisabled()) return; @@ -204,7 +204,7 @@ void GraphicsContext::drawLineForTextChecking(const IntPoint& point, int width, // bounds (e.g. when at the edge of a view) and could make it appear that the // space between adjacent misspelled words was underlined. // allow slightly more considering that the pattern ends with a transparent pixel - int widthMod = width % patternWidth; + float widthMod = fmodf(width, patternWidth); if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) width -= widthMod; diff --git a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp index bb22024..f2850e4 100644 --- a/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp +++ b/Source/WebCore/platform/graphics/win/GraphicsContextWin.cpp @@ -197,4 +197,13 @@ void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform) ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); } +void GraphicsContextPlatformPrivate::setCTM(const AffineTransform& transform) +{ + if (!m_hdc) + return; + + XFORM xform = transform.toTransformationMatrix(); + SetWorldTransform(m_hdc, &xform); +} + } diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index d47de2b..40fe1d1 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -46,7 +46,9 @@ #include "TimeRanges.h" #include "Timer.h" #include <AssertMacros.h> +#include <CoreGraphics/CGAffineTransform.h> #include <CoreGraphics/CGContext.h> +#include <QuartzCore/CATransform3D.h> #include <Wininet.h> #include <wtf/CurrentTime.h> #include <wtf/HashSet.h> @@ -151,7 +153,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivateQuickTimeVisualContext::create(Me void MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualContext(MediaPlayer* player) @@ -175,6 +177,7 @@ MediaPlayerPrivateQuickTimeVisualContext::MediaPlayerPrivateQuickTimeVisualConte #endif , m_visualContextClient(new MediaPlayerPrivateQuickTimeVisualContext::VisualContextClient(this)) , m_delayingLoad(false) + , m_privateBrowsing(false) , m_preload(MediaPlayer::Auto) { } @@ -1244,6 +1247,13 @@ void MediaPlayerPrivateQuickTimeVisualContext::acceleratedRenderingStateChanged( setUpVideoRendering(); } +void MediaPlayerPrivateQuickTimeVisualContext::setPrivateBrowsingMode(bool privateBrowsing) +{ + m_privateBrowsing = privateBrowsing; + if (m_movie) + m_movie->setPrivateBrowsingMode(m_privateBrowsing); +} + #endif diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h index a12d79e..0dc97cd 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -30,6 +30,7 @@ #include "MediaPlayerPrivate.h" #include "Timer.h" +#include <CoreGraphics/CGAffineTransform.h> #include <wtf/Forward.h> #include <wtf/OwnPtr.h> #include <wtf/RetainPtr.h> @@ -153,6 +154,8 @@ private: void visualContextTimerFired(Timer<MediaPlayerPrivateQuickTimeVisualContext>*); void retrieveCurrentImage(); + virtual void setPrivateBrowsingMode(bool); + class MovieClient; friend class MovieClient; OwnPtr<MovieClient> m_movieClient; @@ -196,6 +199,7 @@ private: bool m_newFrameAvailable; bool m_delayingLoad; String m_movieURL; + bool m_privateBrowsing; MediaPlayer::Preload m_preload; #if DRAW_FRAME_RATE double m_frameCountWhilePlaying; diff --git a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp index 07b7621..5156cd3 100644 --- a/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp +++ b/Source/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp @@ -40,6 +40,9 @@ #include "SoftLinking.h" #include "TimeRanges.h" #include "Timer.h" +#include <CoreGraphics/CGColorSpace.h> +#include <CoreGraphics/CGContext.h> +#include <CoreGraphics/CGImage.h> #include <Wininet.h> #include <wtf/CurrentTime.h> #include <wtf/HashSet.h> @@ -76,7 +79,7 @@ MediaPlayerPrivateInterface* MediaPlayerPrivate::create(MediaPlayer* player) void MediaPlayerPrivate::registerMediaEngine(MediaEngineRegistrar registrar) { if (isAvailable()) - registrar(create, getSupportedTypes, supportsType); + registrar(create, getSupportedTypes, supportsType, 0, 0, 0); } MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) diff --git a/Source/WebCore/platform/graphics/win/QTMovie.cpp b/Source/WebCore/platform/graphics/win/QTMovie.cpp index 4cd8161..05fbb86 100644 --- a/Source/WebCore/platform/graphics/win/QTMovie.cpp +++ b/Source/WebCore/platform/graphics/win/QTMovie.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved. + * Copyright (C) 2007, 2008, 2009, 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 @@ -96,6 +96,7 @@ public: CFURLRef m_currentURL; float m_timeToRestore; float m_rateToRestore; + bool m_privateBrowsing; #if !ASSERT_DISABLED bool m_scaleCached; #endif @@ -121,6 +122,7 @@ QTMoviePrivate::QTMoviePrivate() , m_timeToRestore(-1.0f) , m_rateToRestore(-1.0f) , m_disabled(false) + , m_privateBrowsing(false) #if !ASSERT_DISABLED , m_scaleCached(false) #endif @@ -466,8 +468,8 @@ void QTMovie::load(CFURLRef url, bool preservesPitch) m_private->m_loadState = 0; } - // Define a property array for NewMovieFromProperties. 8 should be enough for our needs. - QTNewMoviePropertyElement movieProps[8]; + // Define a property array for NewMovieFromProperties. + QTNewMoviePropertyElement movieProps[9]; ItemCount moviePropCount = 0; bool boolTrue = true; @@ -550,6 +552,14 @@ void QTMovie::load(CFURLRef url, bool preservesPitch) movieProps[moviePropCount].propStatus = 0; moviePropCount++; + bool allowCaching = !m_private->m_privateBrowsing; + movieProps[moviePropCount].propClass = kQTPropertyClass_MovieInstantiation; + movieProps[moviePropCount].propID = 'pers'; + movieProps[moviePropCount].propValueSize = sizeof(allowCaching); + movieProps[moviePropCount].propValueAddress = &allowCaching; + movieProps[moviePropCount].propStatus = 0; + moviePropCount++; + ASSERT(moviePropCount <= WTF_ARRAY_LENGTH(movieProps)); m_private->m_loadError = NewMovieFromProperties(moviePropCount, movieProps, 0, 0, &m_private->m_movie); @@ -846,6 +856,14 @@ void QTMovie::resetTransform() m_private->cacheMovieScale(); } +void QTMovie::setPrivateBrowsingMode(bool privateBrowsing) +{ + m_private->m_privateBrowsing = privateBrowsing; + if (m_private->m_movie) { + bool allowCaching = !m_private->m_privateBrowsing; + QTSetMovieProperty(m_private->m_movie, 'cach', 'pers', sizeof(allowCaching), &allowCaching); + } +} bool QTMovie::initializeQuickTime() { diff --git a/Source/WebCore/platform/graphics/win/QTMovie.h b/Source/WebCore/platform/graphics/win/QTMovie.h index 5e4c4e7..e97d16d 100644 --- a/Source/WebCore/platform/graphics/win/QTMovie.h +++ b/Source/WebCore/platform/graphics/win/QTMovie.h @@ -117,6 +117,8 @@ public: long timeScale() const; + void setPrivateBrowsingMode(bool); + private: QTMoviePrivate* m_private; friend class QTMoviePrivate; diff --git a/Source/WebCore/platform/graphics/win/UniscribeController.cpp b/Source/WebCore/platform/graphics/win/UniscribeController.cpp index ebbed51..a850882 100644 --- a/Source/WebCore/platform/graphics/win/UniscribeController.cpp +++ b/Source/WebCore/platform/graphics/win/UniscribeController.cpp @@ -261,18 +261,13 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S return true; // Convert all chars that should be treated as spaces to use the space glyph. - // We also create a map that allows us to quickly go from space glyphs or rounding - // hack glyphs back to their corresponding characters. + // We also create a map that allows us to quickly go from space glyphs back to their corresponding characters. Vector<int> spaceCharacters(glyphs.size()); spaceCharacters.fill(-1); - Vector<int> roundingHackCharacters(glyphs.size()); - roundingHackCharacters.fill(-1); - Vector<int> roundingHackWordBoundaries(glyphs.size()); - roundingHackWordBoundaries.fill(-1); const float cLogicalScale = fontData->platformData().useGDI() ? 1.0f : 32.0f; unsigned logicalSpaceWidth = fontData->spaceWidth() * cLogicalScale; - float roundedSpaceWidth = roundf(fontData->spaceWidth()); + float spaceWidth = fontData->spaceWidth(); for (int k = 0; k < len; k++) { UChar ch = *(str + k); @@ -286,21 +281,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S if (treatAsSpace) spaceCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos; } - - if (Font::isRoundingHackCharacter(ch)) - roundingHackCharacters[clusters[k]] = m_currentCharacter + k + item.iCharPos; - - int boundary = k + m_currentCharacter + item.iCharPos; - if (boundary < m_run.length()) { - // When at the last character in the str, don't look one past the end for a rounding hack character. - // Instead look ahead to the first character of next item, if there is a next one. - if (k + 1 == len) { - if (i + 2 < m_items.size() // Check for at least 2 items remaining. The last item is a terminating item containing no characters. - && Font::isRoundingHackCharacter(*(cp + m_items[i + 1].iCharPos))) - roundingHackWordBoundaries[clusters[k]] = boundary; - } else if (Font::isRoundingHackCharacter(*(str + k + 1))) - roundingHackWordBoundaries[clusters[k]] = boundary; - } } // Populate our glyph buffer with this information. @@ -324,14 +304,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S advance += fontData->syntheticBoldOffset(); - // We special case spaces in two ways when applying word rounding. - // First, we round spaces to an adjusted width in all fonts. - // Second, in fixed-pitch fonts we ensure that all glyphs that - // match the width of the space glyph have the same width as the space glyph. - if (roundedAdvance == roundedSpaceWidth && (fontData->pitch() == FixedPitch || glyph == fontData->spaceGlyph()) && - m_run.applyWordRounding()) - advance = fontData->adjustedSpaceWidth(); - if (hasExtraSpacing) { // If we're a glyph with an advance, go ahead and add in letter-spacing. // That way we weed out zero width lurkers. This behavior matches the fast text code path. @@ -350,9 +322,8 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S advance += m_padding; m_padding = 0; } else { - float previousPadding = m_padding; m_padding -= m_padPerSpace; - advance += roundf(previousPadding) - roundf(m_padding); + advance += m_padPerSpace; } } @@ -362,25 +333,6 @@ bool UniscribeController::shapeAndPlaceItem(const UChar* cp, unsigned i, const S } } - // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so the following words will start on an integer boundary. - int roundingHackIndex = roundingHackCharacters[k]; - if (m_run.applyWordRounding() && roundingHackIndex != -1) - advance = ceilf(advance); - - // Check to see if the next character is a "rounding hack character", if so, adjust the - // width so that the total run width will be on an integer boundary. - int position = m_currentCharacter + len; - bool lastGlyph = (k == glyphs.size() - 1) && (m_run.rtl() ? i == 0 : i == m_items.size() - 2) && (position >= m_end); - if ((m_run.applyWordRounding() && roundingHackWordBoundaries[k] != -1) || - (m_run.applyRunRounding() && lastGlyph)) { - float totalWidth = m_runWidthSoFar + advance; - advance += ceilf(totalWidth) - totalWidth; - } - m_runWidthSoFar += advance; // FIXME: We need to take the GOFFSETS for combining glyphs and store them in the glyph buffer diff --git a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp index c3e6ce4..cd35ccb 100644 --- a/Source/WebCore/platform/graphics/wince/FontWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/FontWinCE.cpp @@ -88,9 +88,7 @@ TextRunComponent::TextRunComponent(const UChar *start, int length, const TextRun : m_textRun(start, length, parentTextRun.allowTabs(), 0, 0 , parentTextRun.allowsTrailingExpansion() ? TextRun::AllowTrailingExpansion : TextRun::ForbidTrailingExpansion , parentTextRun.rtl() - , parentTextRun.directionalOverride() - , parentTextRun.applyRunRounding() - , parentTextRun.applyWordRounding()) + , parentTextRun.directionalOverride()) , m_offset(o) , m_spaces(0) { diff --git a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp index 7b1c27b..19683df 100644 --- a/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp +++ b/Source/WebCore/platform/graphics/wince/GraphicsContextWinCE.cpp @@ -206,11 +206,16 @@ public: m_transform.rotate(rad2deg(radians)); } - void concatCTM(const AffineTransform& transform) + void concatCTM(const AffineTransform& transform) { m_transform *= transform; } + void setCTM(const AffineTransform& transform) + { + m_transform = transform; + } + IntRect mapRect(const IntRect& rect) const { return m_transform.mapRect(rect); @@ -1016,18 +1021,18 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int DrawFocusRect(dc, &rect); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing) { if (paintingDisabled()) return; StrokeStyle oldStyle = strokeStyle(); setStrokeStyle(SolidStroke); - drawLine(origin, origin + IntSize(width, 0)); + drawLine(roundedIntPoint(origin), roundedIntPoint(origin + FloatSize(width, 0))); setStrokeStyle(oldStyle); } -void GraphicsContext::drawLineForTextChecking(const IntPoint&, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint&, float width, TextCheckingLineStyle style) { notImplemented(); } @@ -1124,6 +1129,11 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) m_data->concatCTM(transform); } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + m_data->setCTM(transform); +} + AffineTransform& GraphicsContext::affineTransform() { return m_data->m_transform; @@ -1520,7 +1530,7 @@ static inline bool isCharVisible(UChar c) return c && c != zeroWidthSpace; } -void GraphicsContext::drawText(const Font& font, const TextRun& run, const IntPoint& point, int from, int to) +void GraphicsContext::drawText(const Font& font, const TextRun& run, const FloatPoint& point, int from, int to) { if (paintingDisabled() || !fillColor().alpha() || !m_data->m_opacity) return; diff --git a/Source/WebCore/platform/graphics/wx/FontWx.cpp b/Source/WebCore/platform/graphics/wx/FontWx.cpp index c48f3c7..782d328 100644 --- a/Source/WebCore/platform/graphics/wx/FontWx.cpp +++ b/Source/WebCore/platform/graphics/wx/FontWx.cpp @@ -139,7 +139,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F controller.advance(run.length()); startX += controller.runWidthSoFar() - afterWidth; #else - startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth; + startX += controller.totalWidth() - afterWidth; for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end) glyphBuffer.swap(i, end); #endif diff --git a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index 991be79..47f3211 100644 --- a/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/Source/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -336,17 +336,17 @@ void GraphicsContext::clipPath(const Path&, WindRule) notImplemented(); } -void GraphicsContext::drawLineForText(const IntPoint& origin, int width, bool printing) +void GraphicsContext::drawLineForText(const FloatPoint& origin, float width, bool printing) { if (paintingDisabled()) return; - IntPoint endPoint = origin + IntSize(width, 0); + FloatPoint endPoint = origin + FloatSize(width, 0); m_data->context->SetPen(wxPen(strokeColor(), strokeThickness(), wxSOLID)); m_data->context->DrawLine(origin.x(), origin.y(), endPoint.x(), endPoint.y()); } -void GraphicsContext::drawLineForTextChecking(const IntPoint& origin, int width, TextCheckingLineStyle style) +void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float width, TextCheckingLineStyle style) { switch (style) { case TextCheckingSpellingLineStyle: @@ -494,6 +494,19 @@ void GraphicsContext::concatCTM(const AffineTransform& transform) return; } +void GraphicsContext::setCTM(const AffineTransform& transform) +{ + if (paintingDisabled()) + return; + +#if USE(WXGC) + wxGraphicsContext* gc = m_data->context->GetGraphicsContext(); + if (gc) + gc->SetTransform(transform); +#endif + return; +} + void GraphicsContext::setPlatformShouldAntialias(bool enable) { if (paintingDisabled()) diff --git a/Source/WebCore/platform/gtk/ClipboardGtk.cpp b/Source/WebCore/platform/gtk/ClipboardGtk.cpp index eb7248b..24580ea 100644 --- a/Source/WebCore/platform/gtk/ClipboardGtk.cpp +++ b/Source/WebCore/platform/gtk/ClipboardGtk.cpp @@ -83,7 +83,7 @@ static ClipboardDataType dataObjectTypeFromHTMLClipboardType(const String& rawTy String type(rawType.stripWhiteSpace()); // Two special cases for IE compatibility - if (type == "Text") + if (type == "Text" || type == "text") return ClipboardDataTypeText; if (type == "URL") return ClipboardDataTypeURL; @@ -201,6 +201,7 @@ HashSet<String> ClipboardGtk::types() const if (m_dataObject->hasText()) { types.add("text/plain"); types.add("Text"); + types.add("text"); } if (m_dataObject->hasMarkup()) diff --git a/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp b/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp index fee7a14..bdd3962 100644 --- a/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp +++ b/Source/WebCore/platform/gtk/ContextMenuItemGtk.cpp @@ -107,6 +107,7 @@ static const char* gtkStockIDFromContextMenuAction(const ContextMenuAction& acti return GTK_STOCK_SELECT_COLOR; case ContextMenuItemTagToggleMediaControls: case ContextMenuItemTagToggleMediaLoop: + case ContextMenuItemTagCopyImageUrlToClipboard: // No icon for this. return 0; case ContextMenuItemTagEnterVideoFullscreen: diff --git a/Source/WebCore/platform/gtk/FileChooserGtk.cpp b/Source/WebCore/platform/gtk/FileChooserGtk.cpp index 54763d4..b4bdf3f 100644 --- a/Source/WebCore/platform/gtk/FileChooserGtk.cpp +++ b/Source/WebCore/platform/gtk/FileChooserGtk.cpp @@ -60,8 +60,8 @@ String FileChooser::basenameForWidth(const Font& font, int width) const gchar* systemBasename = g_path_get_basename(systemFilename.data()); stringByAdoptingFileSystemRepresentation(systemBasename, string); } else if (m_filenames.size() > 1) - return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false); + return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font); - return StringTruncator::centerTruncate(string, width, font, false); + return StringTruncator::centerTruncate(string, width, font); } } diff --git a/Source/WebCore/platform/gtk/KeyEventGtk.cpp b/Source/WebCore/platform/gtk/KeyEventGtk.cpp index 5a034d6..d010b37 100644 --- a/Source/WebCore/platform/gtk/KeyEventGtk.cpp +++ b/Source/WebCore/platform/gtk/KeyEventGtk.cpp @@ -43,7 +43,7 @@ namespace WebCore { // FIXME: This is incomplete. We should change this to mirror // more like what Firefox does, and generate these switch statements // at build time. -static String keyIdentifierForGdkKeyCode(guint keyCode) +String PlatformKeyboardEvent::keyIdentifierForGdkKeyCode(unsigned keyCode) { switch (keyCode) { case GDK_Menu: @@ -149,7 +149,7 @@ static String keyIdentifierForGdkKeyCode(guint keyCode) } } -static int windowsKeyCodeForKeyEvent(unsigned int keycode) +int PlatformKeyboardEvent::windowsKeyCodeForGdkKeyCode(unsigned keycode) { switch (keycode) { case GDK_KP_0: @@ -516,7 +516,7 @@ static int windowsKeyCodeForKeyEvent(unsigned int keycode) } -static String singleCharacterString(guint val) +String PlatformKeyboardEvent::singleCharacterString(unsigned val) { switch (val) { case GDK_ISO_Enter: @@ -552,7 +552,7 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(GdkEventKey* event) , m_unmodifiedText(singleCharacterString(event->keyval)) , m_keyIdentifier(keyIdentifierForGdkKeyCode(event->keyval)) , m_autoRepeat(false) - , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(event->keyval)) + , m_windowsVirtualKeyCode(windowsKeyCodeForGdkKeyCode(event->keyval)) , m_nativeVirtualKeyCode(event->keyval) , m_isKeypad(event->keyval >= GDK_KP_Space && event->keyval <= GDK_KP_9) , m_shiftKey((event->state & GDK_SHIFT_MASK) || (event->keyval == GDK_3270_BackTab)) @@ -588,11 +588,13 @@ bool PlatformKeyboardEvent::currentCapsLockState() void PlatformKeyboardEvent::getCurrentModifierState(bool& shiftKey, bool& ctrlKey, bool& altKey, bool& metaKey) { - notImplemented(); - shiftKey = false; - ctrlKey = false; - altKey = false; - metaKey = false; + GdkModifierType state; + gtk_get_current_event_state(&state); + + shiftKey = state & GDK_SHIFT_MASK; + ctrlKey = state & GDK_CONTROL_MASK; + altKey = state & GDK_MOD1_MASK; + metaKey = state & GDK_META_MASK; } GdkEventKey* PlatformKeyboardEvent::gdkEventKey() const diff --git a/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp b/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp index 65e8852..eab0ac6 100644 --- a/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp +++ b/Source/WebCore/platform/gtk/LocalizedStringsGtk.cpp @@ -66,6 +66,11 @@ String resetButtonDefaultLabel() return String::fromUTF8(_("Reset")); } +String defaultDetailsSummaryText() +{ + return String::fromUTF8(_("Details")); +} + String searchableIndexIntroduction() { return String::fromUTF8(_("This is a searchable index. Enter search keywords: ")); @@ -111,6 +116,11 @@ String contextMenuItemTagCopyImageToClipboard() return String::fromUTF8(_("Cop_y Image")); } +String contextMenuItemTagCopyImageUrlToClipboard() +{ + return String::fromUTF8(_("Copy Image _Address")); +} + String contextMenuItemTagOpenVideoInNewWindow() { return String::fromUTF8(_("Open _Video in New Window")); diff --git a/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp b/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp index d1571a5..d8cdb79 100644 --- a/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp +++ b/Source/WebCore/platform/gtk/MainFrameScrollbarGtk.cpp @@ -60,6 +60,8 @@ MainFrameScrollbarGtk::~MainFrameScrollbarGtk() void MainFrameScrollbarGtk::attachAdjustment(GtkAdjustment* adjustment) { + if (m_adjustment.get() == adjustment) + return; if (m_adjustment) detachAdjustment(); @@ -67,9 +69,9 @@ void MainFrameScrollbarGtk::attachAdjustment(GtkAdjustment* adjustment) if (!m_adjustment) return; - g_signal_connect(m_adjustment.get(), "value-changed", G_CALLBACK(MainFrameScrollbarGtk::gtkValueChanged), this); updateThumbProportion(); updateThumbPosition(); + g_signal_connect(m_adjustment.get(), "value-changed", G_CALLBACK(MainFrameScrollbarGtk::gtkValueChanged), this); } void MainFrameScrollbarGtk::detachAdjustment() @@ -109,7 +111,17 @@ void MainFrameScrollbarGtk::updateThumbProportion() void MainFrameScrollbarGtk::gtkValueChanged(GtkAdjustment*, MainFrameScrollbarGtk* that) { - that->scrollableArea()->scrollToOffsetWithoutAnimation(that->orientation(), static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get()))); + // If we've been removed from our parent, we no longer get to control the WebCore + // scrollbar. If this is the case, deactivate this signal handler. WebCore will + // create a fresh MainFrameScrollbar when the scrollbar reappears. + if (!that->parent()) { + that->detachAdjustment(); + return; + } + + int newValue = static_cast<int>(gtk_adjustment_get_value(that->m_adjustment.get())); + if (newValue != that->value()) + that->scrollableArea()->scrollToOffsetWithoutAnimation(that->orientation(), newValue); } void MainFrameScrollbarGtk::paint(GraphicsContext* context, const IntRect& rect) diff --git a/Source/WebCore/platform/gtk/ScrollViewGtk.cpp b/Source/WebCore/platform/gtk/ScrollViewGtk.cpp index a8c7562..c5f32f3 100644 --- a/Source/WebCore/platform/gtk/ScrollViewGtk.cpp +++ b/Source/WebCore/platform/gtk/ScrollViewGtk.cpp @@ -162,14 +162,6 @@ void ScrollView::setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj, boo setVerticalAdjustment(vadj, resetValues); } -void ScrollView::platformAddChild(Widget* child) -{ -} - -void ScrollView::platformRemoveChild(Widget* child) -{ -} - IntRect ScrollView::visibleContentRect(bool includeScrollbars) const { // If we are an interior frame scrollbar or are in some sort of transition @@ -177,8 +169,8 @@ IntRect ScrollView::visibleContentRect(bool includeScrollbars) const // scrollbar width should be. if (parent() || !hostWindow() || !hostWindow()->platformPageClient()) { return IntRect(IntPoint(m_scrollOffset.width(), m_scrollOffset.height()), - IntSize(max(0, width() - (verticalScrollbar() && !includeScrollbars ? verticalScrollbar()->width() : 0)), - max(0, height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0)))); + IntSize(max(0, m_boundsSize.width() - (verticalScrollbar() && !includeScrollbars ? verticalScrollbar()->width() : 0)), + max(0, m_boundsSize.height() - (horizontalScrollbar() && !includeScrollbars ? horizontalScrollbar()->height() : 0)))); } // We don't have a parent, so we are the main frame and thus have diff --git a/Source/WebCore/platform/gtk/TemporaryLinkStubs.cpp b/Source/WebCore/platform/gtk/TemporaryLinkStubs.cpp index 5c27080..eee07ce 100644 --- a/Source/WebCore/platform/gtk/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/gtk/TemporaryLinkStubs.cpp @@ -48,5 +48,7 @@ void getSupportedKeySizes(Vector<String>&) { notImplemented(); } String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String &challengeString, const KURL &url) { return String(); } float userIdleTime() { notImplemented(); return FLT_MAX; } // return an arbitrarily high userIdleTime so that releasing pages from the page cache isn't postponed void setCookieStoragePrivateBrowsingEnabled(bool) { notImplemented(); } +void startObservingCookieChanges() { notImplemented(); } +void stopObservingCookieChanges() { notImplemented(); } } diff --git a/Source/WebCore/platform/gtk/WidgetGtk.cpp b/Source/WebCore/platform/gtk/WidgetGtk.cpp index ee1005c..f251772 100644 --- a/Source/WebCore/platform/gtk/WidgetGtk.cpp +++ b/Source/WebCore/platform/gtk/WidgetGtk.cpp @@ -67,19 +67,10 @@ static GdkWindow* gdkWindow(PlatformWidget widget) void Widget::setCursor(const Cursor& cursor) { - GdkCursor* platformCursor = cursor.platformCursor().get(); - - // http://bugs.webkit.org/show_bug.cgi?id=16388 - // [GTK] Widget::setCursor() gets called frequently - // - // gdk_window_set_cursor() in certain GDK backends seems to be an - // expensive operation, so avoid it if possible. - - if (platformCursor == lastSetCursor) + ScrollView* view = root(); + if (!view) return; - - gdk_window_set_cursor(gdkWindow(platformWidget()) ? gdkWindow(platformWidget()) : gtk_widget_get_window(GTK_WIDGET(root()->hostWindow()->platformPageClient())), platformCursor); - lastSetCursor = platformCursor; + view->hostWindow()->setCursor(cursor); } void Widget::show() diff --git a/Source/WebCore/platform/haiku/CookieJarHaiku.cpp b/Source/WebCore/platform/haiku/CookieJarHaiku.cpp index 471ac59..962846b 100644 --- a/Source/WebCore/platform/haiku/CookieJarHaiku.cpp +++ b/Source/WebCore/platform/haiku/CookieJarHaiku.cpp @@ -75,5 +75,20 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } // namespace WebCore diff --git a/Source/WebCore/platform/haiku/LocalizedStringsHaiku.cpp b/Source/WebCore/platform/haiku/LocalizedStringsHaiku.cpp index 5587fa2..63b9b91 100644 --- a/Source/WebCore/platform/haiku/LocalizedStringsHaiku.cpp +++ b/Source/WebCore/platform/haiku/LocalizedStringsHaiku.cpp @@ -48,6 +48,11 @@ String resetButtonDefaultLabel() return "Reset"; } +String defaultDetailsSummaryText() +{ + return "Details"; +} + String defaultLanguage() { return "en"; diff --git a/Source/WebCore/platform/haiku/TemporaryLinkStubs.cpp b/Source/WebCore/platform/haiku/TemporaryLinkStubs.cpp index 58ab873..5ecb4f3 100644 --- a/Source/WebCore/platform/haiku/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/haiku/TemporaryLinkStubs.cpp @@ -82,5 +82,15 @@ void setCookieStoragePrivateBrowsingEnabled(bool) notImplemented(); } +void startObservingCookieChanges() +{ + notImplemented(); +} + +void stopObservingCookieChanges() +{ + notImplemented(); +} + } // namespace WebCore diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp index 840ab98..e59d461 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.cpp @@ -130,7 +130,7 @@ ImageDecoder* ImageDecoder::create(const SharedBuffer& data, ImageSource::AlphaO } #endif // !OS(ANDROID) -#if !PLATFORM(SKIA) +#if !USE(SKIA) ImageFrame::ImageFrame() : m_hasAlpha(false) diff --git a/Source/WebCore/platform/image-decoders/ImageDecoder.h b/Source/WebCore/platform/image-decoders/ImageDecoder.h index e07f4f2..2a307c5 100644 --- a/Source/WebCore/platform/image-decoders/ImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/ImageDecoder.h @@ -23,7 +23,7 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef ImageDecoder_h @@ -37,7 +37,7 @@ #include <wtf/RefPtr.h> #include <wtf/Vector.h> -#if PLATFORM(SKIA) +#if USE(SKIA) #include "NativeImageSkia.h" #include "SkColorPriv.h" #elif PLATFORM(QT) @@ -65,7 +65,7 @@ namespace WebCore { DisposeOverwritePrevious, // Clear frame to previous framebuffer // contents }; -#if PLATFORM(SKIA) || PLATFORM(QT) +#if USE(SKIA) || PLATFORM(QT) typedef uint32_t PixelData; #else typedef unsigned PixelData; @@ -158,7 +158,7 @@ namespace WebCore { inline PixelData* getAddr(int x, int y) { -#if PLATFORM(SKIA) +#if USE(SKIA) return m_bitmap.getAddr32(x, y); #elif PLATFORM(QT) m_image = m_pixmap.toImage(); @@ -180,15 +180,18 @@ namespace WebCore { g = static_cast<unsigned>(g * alphaPercent); b = static_cast<unsigned>(b * alphaPercent); } -#if PLATFORM(SKIA) - *dest = SkPackARGB32(a, r, g, b); +#if USE(SKIA) + // we are sure to call the NoCheck version, since we may + // deliberately pass non-premultiplied values, and we don't want + // an assert. + *dest = SkPackARGB32NoCheck(a, r, g, b); #else *dest = (a << 24 | r << 16 | g << 8 | b); #endif } } -#if PLATFORM(SKIA) +#if USE(SKIA) NativeImageSkia m_bitmap; #elif PLATFORM(QT) mutable QPixmap m_pixmap; diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp index 7e334a9..e350605 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -61,9 +61,9 @@ bool GIFImageDecoder::isSizeAvailable() return ImageDecoder::isSizeAvailable(); } -bool GIFImageDecoder::setSize(int width, int height) +bool GIFImageDecoder::setSize(unsigned width, unsigned height) { - if (ImageDecoder::isSizeAvailable() && size().width() == width && size().height() == height) + if (ImageDecoder::isSizeAvailable() && size() == IntSize(width, height)) return true; if (!ImageDecoder::setSize(width, height)) diff --git a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h index dd401b8..15bd99f 100644 --- a/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h +++ b/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.h @@ -45,7 +45,7 @@ namespace WebCore { virtual String filenameExtension() const { return "gif"; } virtual void setData(SharedBuffer* data, bool allDataReceived); virtual bool isSizeAvailable(); - virtual bool setSize(int width, int height); + virtual bool setSize(unsigned width, unsigned height); virtual size_t frameCount(); virtual int repetitionCount() const; virtual ImageFrame* frameBufferAtIndex(size_t index); diff --git a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 1434c65..471ab98 100644 --- a/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -179,7 +179,7 @@ public: m_bytesToSkip = std::max(numBytes - bytesToSkip, static_cast<long>(0)); } - bool decode(const Vector<char>& data, bool onlySize) + bool decode(const SharedBuffer& data, bool onlySize) { m_decodingSizeOnly = onlySize; @@ -532,7 +532,7 @@ void JPEGImageDecoder::decode(bool onlySize) // If we couldn't decode the image but we've received all the data, decoding // has failed. - if (!m_reader->decode(m_data->buffer(), onlySize) && isAllDataReceived()) + if (!m_reader->decode(*m_data, onlySize) && isAllDataReceived()) setFailed(); // If we're done decoding the image, we don't need the JPEGImageReader // anymore. (If we failed, |m_reader| has already been cleared.) diff --git a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp index 3db00f6..060c62a 100644 --- a/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/webp/WEBPImageDecoder.cpp @@ -79,9 +79,9 @@ bool WEBPImageDecoder::decode(bool onlySize) if (failed()) return false; - const size_t dataSize = m_data->buffer().size(); + const size_t dataSize = m_data->size(); const uint8_t* dataBytes = - reinterpret_cast<const uint8_t*>(m_data->buffer().data()); + reinterpret_cast<const uint8_t*>(m_data->data()); int width, height; if (dataSize < sizeOfHeader) return true; diff --git a/Source/WebCore/platform/image-encoders/JPEGImageEncoder.cpp b/Source/WebCore/platform/image-encoders/JPEGImageEncoder.cpp index d707aa8..a4ee4fd 100644 --- a/Source/WebCore/platform/image-encoders/JPEGImageEncoder.cpp +++ b/Source/WebCore/platform/image-encoders/JPEGImageEncoder.cpp @@ -65,7 +65,7 @@ static void jpegInitializeDestination(j_compress_ptr compressData) static boolean jpegEmptyOutputBuffer(j_compress_ptr compressData) { JPEGDestinationManager* dest = static_cast<JPEGDestinationManager*>(compressData->dest); - dest->m_dump.append(dest->m_buffer.data(), dest->m_buffer.size() - dest->free_in_buffer); + dest->m_dump.append(dest->m_buffer.data(), dest->m_buffer.size()); dest->next_output_byte = reinterpret_cast<JOCTET*>(dest->m_buffer.data()); dest->free_in_buffer = dest->m_buffer.size(); return TRUE; diff --git a/Source/WebCore/platform/mac/ClipboardMac.mm b/Source/WebCore/platform/mac/ClipboardMac.mm index 10d196a..a41982a 100644 --- a/Source/WebCore/platform/mac/ClipboardMac.mm +++ b/Source/WebCore/platform/mac/ClipboardMac.mm @@ -370,7 +370,7 @@ void ClipboardMac::writeRange(Range* range, Frame* frame) { ASSERT(range); ASSERT(frame); - Pasteboard::writeSelection(m_pasteboard.get(), range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame); + Pasteboard::writeSelection(m_pasteboard.get(), 0, range, frame->editor()->smartInsertDeleteEnabled() && frame->selection()->granularity() == WordGranularity, frame); } void ClipboardMac::writePlainText(const String& text) diff --git a/Source/WebCore/platform/mac/CookieJar.mm b/Source/WebCore/platform/mac/CookieJar.mm index df24b03..e788949 100644 --- a/Source/WebCore/platform/mac/CookieJar.mm +++ b/Source/WebCore/platform/mac/CookieJar.mm @@ -28,8 +28,10 @@ #import "BlockExceptions.h" #import "Cookie.h" +#import "CookieStorage.h" #import "Document.h" #import "KURL.h" +#import "WebCoreSystemInterface.h" #import <wtf/RetainPtr.h> #ifdef BUILDING_ON_TIGER @@ -79,7 +81,14 @@ String cookies(const Document*, const KURL& url) BEGIN_BLOCK_OBJC_EXCEPTIONS; NSURL *cookieURL = url; - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + NSArray *cookies; +#if USE(CFURLSTORAGESESSIONS) + if (CFHTTPCookieStorageRef cookieStorage = privateBrowsingCookieStorage().get()) + cookies = wkHTTPCookiesForURL(cookieStorage, cookieURL); + else +#endif + cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + return [[NSHTTPCookie requestHeaderFieldsWithCookies:filterCookies(cookies).get()] objectForKey:@"Cookie"]; END_BLOCK_OBJC_EXCEPTIONS; @@ -91,7 +100,14 @@ String cookieRequestHeaderFieldValue(const Document*, const KURL& url) BEGIN_BLOCK_OBJC_EXCEPTIONS; NSURL *cookieURL = url; - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + NSArray *cookies; +#if USE(CFURLSTORAGESESSIONS) + if (CFHTTPCookieStorageRef cookieStorage = privateBrowsingCookieStorage().get()) + cookies = wkHTTPCookiesForURL(cookieStorage, cookieURL); + else +#endif + cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + return [[NSHTTPCookie requestHeaderFieldsWithCookies:cookies] objectForKey:@"Cookie"]; END_BLOCK_OBJC_EXCEPTIONS; @@ -112,8 +128,14 @@ void setCookies(Document* document, const KURL& url, const String& cookieStr) String cookieString = cookieStr.contains('=') ? cookieStr : cookieStr + "="; NSURL *cookieURL = url; - NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary dictionaryWithObject:cookieString forKey:@"Set-Cookie"] forURL:cookieURL]; - [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:filterCookies(cookies).get() forURL:cookieURL mainDocumentURL:document->firstPartyForCookies()]; + RetainPtr<NSArray> filteredCookies = filterCookies([NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary dictionaryWithObject:cookieString forKey:@"Set-Cookie"] forURL:cookieURL]); + +#if USE(CFURLSTORAGESESSIONS) + if (CFHTTPCookieStorageRef cookieStorage = privateBrowsingCookieStorage().get()) + wkSetHTTPCookiesForURL(cookieStorage, filteredCookies.get(), cookieURL, document->firstPartyForCookies()); + else +#endif + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:filteredCookies.get() forURL:cookieURL mainDocumentURL:document->firstPartyForCookies()]; END_BLOCK_OBJC_EXCEPTIONS; } @@ -122,7 +144,14 @@ bool cookiesEnabled(const Document*) { BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSHTTPCookieAcceptPolicy cookieAcceptPolicy = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy]; + NSHTTPCookieAcceptPolicy cookieAcceptPolicy; +#if USE(CFURLSTORAGESESSIONS) + if (CFHTTPCookieStorageRef cookieStorage = privateBrowsingCookieStorage().get()) + cookieAcceptPolicy = wkGetHTTPCookieAcceptPolicy(cookieStorage); + else +#endif + cookieAcceptPolicy = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookieAcceptPolicy]; + return cookieAcceptPolicy == NSHTTPCookieAcceptPolicyAlways || cookieAcceptPolicy == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; END_BLOCK_OBJC_EXCEPTIONS; @@ -135,7 +164,13 @@ bool getRawCookies(const Document*, const KURL& url, Vector<Cookie>& rawCookies) BEGIN_BLOCK_OBJC_EXCEPTIONS; NSURL *cookieURL = url; - NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; + NSArray *cookies; +#if USE(CFURLSTORAGESESSIONS) + if (CFHTTPCookieStorageRef cookieStorage = privateBrowsingCookieStorage().get()) + cookies = wkHTTPCookiesForURL(cookieStorage, cookieURL); + else +#endif + cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; NSUInteger count = [cookies count]; rawCookies.reserveCapacity(count); @@ -162,14 +197,27 @@ void deleteCookie(const Document*, const KURL& url, const String& cookieName) NSURL *cookieURL = url; NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - NSArray *cookies = [cookieStorage cookiesForURL:cookieURL]; + NSArray *cookies; +#if USE(CFURLSTORAGESESSIONS) + CFHTTPCookieStorageRef cfCookieStorage = privateBrowsingCookieStorage().get(); + if (cfCookieStorage) + cookies = wkHTTPCookiesForURL(cfCookieStorage, cookieURL); + else +#endif + cookies = [cookieStorage cookiesForURL:cookieURL]; + NSString *cookieNameString = (NSString *) cookieName; NSUInteger count = [cookies count]; for (NSUInteger i = 0; i < count; ++i) { NSHTTPCookie *cookie = (NSHTTPCookie *)[cookies objectAtIndex:i]; if ([[cookie name] isEqualToString:cookieNameString]) { - [cookieStorage deleteCookie:cookie]; +#if USE(CFURLSTORAGESESSIONS) + if (cfCookieStorage) + wkDeleteHTTPCookie(cfCookieStorage, cookie); + else +#endif + [cookieStorage deleteCookie:cookie]; break; } } @@ -177,4 +225,49 @@ void deleteCookie(const Document*, const KURL& url, const String& cookieName) END_BLOCK_OBJC_EXCEPTIONS; } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray *cookies = [cookieStorage cookies]; + + for (NSHTTPCookie* cookie in cookies) + hostnames.add([cookie domain]); + + END_BLOCK_OBJC_EXCEPTIONS; +} + +void deleteCookiesForHostname(const String& hostname) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray *cookies = [cookieStorage cookies]; + if (!cookies) + return; + + for (NSHTTPCookie* cookie in cookies) { + if (hostname == String([cookie domain])) + [cookieStorage deleteCookie:cookie]; + } + + END_BLOCK_OBJC_EXCEPTIONS; +} + +void deleteAllCookies() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + NSArray *cookies = [cookieStorage cookies]; + if (!cookies) + return; + + for (NSHTTPCookie* cookie in cookies) + [cookieStorage deleteCookie:cookie]; + + END_BLOCK_OBJC_EXCEPTIONS; +} + } diff --git a/Source/WebCore/platform/mac/DragImageMac.mm b/Source/WebCore/platform/mac/DragImageMac.mm index fc58173..8f60fd4 100644 --- a/Source/WebCore/platform/mac/DragImageMac.mm +++ b/Source/WebCore/platform/mac/DragImageMac.mm @@ -158,8 +158,7 @@ static float widthWithFont(NSString *string, NSFont *font) if (canUseFastRenderer(buffer.data(), length)) { Font webCoreFont(FontPlatformData(font, [font pointSize]), ![[NSGraphicsContext currentContext] isDrawingToScreen]); TextRun run(buffer.data(), length); - run.disableRoundingHacks(); - return webCoreFont.floatWidth(run); + return webCoreFont.width(run); } return [string sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]].width; @@ -197,8 +196,7 @@ static void drawAtPoint(NSString *string, NSPoint point, NSFont *font, NSColor * Font webCoreFont(FontPlatformData(font, [font pointSize]), ![nsContext isDrawingToScreen], Antialiased); TextRun run(buffer.data(), length); - run.disableRoundingHacks(); - + CGFloat red; CGFloat green; CGFloat blue; diff --git a/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h b/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h index 04bf236..b73177b 100644 --- a/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h +++ b/Source/WebCore/platform/mac/EmptyProtocolDefinitions.h @@ -23,9 +23,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef EmptyProtocolDefinitions_h -#define EmptyProtocolDefinitions_h - #if defined(__OBJC__) #define EMPTY_PROTOCOL(NAME) \ @@ -50,5 +47,3 @@ EMPTY_PROTOCOL(NSURLDownloadDelegate) #undef EMPTY_PROTOCOL #endif /* defined(__OBJC__) */ - -#endif /* EmptyProtocolDefinitions_h */ diff --git a/Source/WebCore/platform/mac/FileChooserMac.mm b/Source/WebCore/platform/mac/FileChooserMac.mm index 03532ff..d9c2426 100644 --- a/Source/WebCore/platform/mac/FileChooserMac.mm +++ b/Source/WebCore/platform/mac/FileChooserMac.mm @@ -47,9 +47,9 @@ String FileChooser::basenameForWidth(const Font& font, int width) const else if (m_filenames.size() == 1) strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(m_filenames[0])]; else - return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false); + return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font); - return StringTruncator::centerTruncate(strToTruncate, width, font, false); + return StringTruncator::centerTruncate(strToTruncate, width, font); } } diff --git a/Source/WebCore/platform/mac/FileSystemMac.mm b/Source/WebCore/platform/mac/FileSystemMac.mm index bbeb76a..8cdd382 100644 --- a/Source/WebCore/platform/mac/FileSystemMac.mm +++ b/Source/WebCore/platform/mac/FileSystemMac.mm @@ -32,6 +32,7 @@ #import "PlatformString.h" #import <wtf/RetainPtr.h> #import <wtf/text/CString.h> +#import <wtf/UnusedParam.h> namespace WebCore { diff --git a/Source/WebCore/platform/mac/LocalizedStringsMac.mm b/Source/WebCore/platform/mac/LocalizedStringsMac.mm new file mode 100644 index 0000000..2dc44e9 --- /dev/null +++ b/Source/WebCore/platform/mac/LocalizedStringsMac.mm @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "LocalizedStrings.h" + +#import <wtf/Assertions.h> +#import <wtf/RetainPtr.h> +#import <wtf/Threading.h> +#import <wtf/text/WTFString.h> + +namespace WebCore { + +String localizedString(const char* key) +{ + static NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.apple.WebCore"]; + + ASSERT(isMainThread()); + + RetainPtr<CFStringRef> keyString(AdoptCF, CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingUTF8, kCFAllocatorNull)); + NSString *notFound = @"localized string not found"; + NSString *result = [bundle localizedStringForKey:(NSString *)keyString.get() value:notFound table:nil]; + + ASSERT_WITH_MESSAGE(result != notFound, "could not find localizable string %s in bundle", key); + return result; +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/mac/PasteboardMac.mm b/Source/WebCore/platform/mac/PasteboardMac.mm index 65180a0..8c6610a 100644 --- a/Source/WebCore/platform/mac/PasteboardMac.mm +++ b/Source/WebCore/platform/mac/PasteboardMac.mm @@ -34,6 +34,7 @@ #import "Editor.h" #import "EditorClient.h" #import "Frame.h" +#import "FrameView.h" #import "FrameLoaderClient.h" #import "HitTestResult.h" #import "HTMLAnchorElement.h" @@ -56,7 +57,6 @@ @interface NSAttributedString (AppKitSecretsIKnowAbout) - (id)_initWithDOMRange:(DOMRange *)domRange; @end - namespace WebCore { // FIXME: It's not great to have these both here and in WebKit. @@ -138,21 +138,22 @@ static NSAttributedString *stripAttachmentCharacters(NSAttributedString *string) return result; } -void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) +void Pasteboard::writeSelection(NSPasteboard* pasteboard, NSArray* pasteboardTypes, Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) { if (!WebArchivePboardType) Pasteboard::generalPasteboard(); // Initializes pasteboard types. ASSERT(selectedRange); - NSAttributedString *attributedString = [[[NSAttributedString alloc] initWithString:selectedRange->text()] autorelease]; - + // Using different API for WebKit and WebKit2. + // FIXME - We need to have a way to create the NSAttributedString for WebKit2 that doesn't require accessing the WebFrame. + NSAttributedString *attributedString = (frame->view()->platformWidget()) ? [[[NSAttributedString alloc] _initWithDOMRange:kit(selectedRange)] autorelease] : [[[NSAttributedString alloc] initWithString:selectedRange->text()] autorelease]; #ifdef BUILDING_ON_TIGER // 4930197: Mail overrides [WebHTMLView pasteboardTypesForSelection] in order to add another type to the pasteboard // after WebKit does. On Tiger we must call this function so that Mail code will be executed, meaning that // we can't call WebCore::Pasteboard's method for setting types. UNUSED_PARAM(canSmartCopyOrDelete); - NSArray *types = frame->editor()->client()->pasteboardTypesForSelection(frame); + NSArray *types = pasteboardTypes ? pasteboardTypes : frame->editor()->client()->pasteboardTypesForSelection(frame); // Don't write RTFD to the pasteboard when the copied attributed string has no attachments. NSMutableArray *mutableTypes = nil; if (![attributedString containsAttachments]) { @@ -162,7 +163,7 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, } [pasteboard declareTypes:types owner:nil]; #else - NSArray *types = selectionPasteboardTypes(canSmartCopyOrDelete, [attributedString containsAttachments]); + NSArray *types = pasteboardTypes ? pasteboardTypes : selectionPasteboardTypes(canSmartCopyOrDelete, [attributedString containsAttachments]); [pasteboard declareTypes:types owner:nil]; frame->editor()->client()->didSetSelectionTypesForPasteboard(); #endif @@ -214,7 +215,7 @@ void Pasteboard::writePlainText(NSPasteboard* pasteboard, const String& text) void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, Frame* frame) { - Pasteboard::writeSelection(m_pasteboard.get(), selectedRange, canSmartCopyOrDelete, frame); + Pasteboard::writeSelection(m_pasteboard.get(), 0, selectedRange, canSmartCopyOrDelete, frame); } void Pasteboard::writePlainText(const String& text) diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.h b/Source/WebCore/platform/mac/ScrollAnimatorMac.h index 3f7612a..2bafbf5 100644 --- a/Source/WebCore/platform/mac/ScrollAnimatorMac.h +++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.h @@ -70,7 +70,10 @@ public: void immediateScrollToPoint(const FloatPoint& newPosition); void immediateScrollByDeltaX(float deltaX); void immediateScrollByDeltaY(float deltaY); - + + void setIsDrawingIntoLayer(bool b) { m_drawingIntoLayer = b; } + bool isDrawingIntoLayer() const { return m_drawingIntoLayer; } + private: RetainPtr<id> m_scrollAnimationHelper; RetainPtr<ScrollAnimationHelperDelegate> m_scrollAnimationHelperDelegate; @@ -114,6 +117,7 @@ private: bool m_inScrollGesture; bool m_momentumScrollInProgress; bool m_ignoreMomentumScrolls; + CFTimeInterval m_lastMomemtumScrollTimestamp; FloatSize m_overflowScrollDelta; FloatSize m_stretchScrollForce; @@ -126,6 +130,7 @@ private: FloatSize m_origVelocity; Timer<ScrollAnimatorMac> m_snapRubberBandTimer; #endif + bool m_drawingIntoLayer; }; } // namespace WebCore diff --git a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm index c1154d5..67c0904 100644 --- a/Source/WebCore/platform/mac/ScrollAnimatorMac.mm +++ b/Source/WebCore/platform/mac/ScrollAnimatorMac.mm @@ -357,7 +357,7 @@ static NSSize abs(NSSize size) { if (!_animator) return nil; - if (!_animator->scrollableArea()->scrollbarWillRenderIntoCompositingLayer()) + if (!_animator->isDrawingIntoLayer()) return nil; // FIXME: This should attempt to return an actual layer. @@ -459,6 +459,7 @@ ScrollAnimatorMac::ScrollAnimatorMac(ScrollableArea* scrollableArea) , m_startTime(0) , m_snapRubberBandTimer(this, &ScrollAnimatorMac::snapRubberBandTimerFired) #endif + , m_drawingIntoLayer(false) { m_scrollAnimationHelperDelegate.adoptNS([[ScrollAnimationHelperDelegate alloc] initWithScrollAnimator:this]); m_scrollAnimationHelper.adoptNS([[NSClassFromString(@"NSScrollAnimationHelper") alloc] initWithDelegate:m_scrollAnimationHelperDelegate.get()]); @@ -726,9 +727,9 @@ void ScrollAnimatorMac::handleWheelEvent(PlatformWheelEvent& wheelEvent) wheelEvent.accept(); - bool isMometumScrollEvent = (wheelEvent.phase() != PlatformWheelEventPhaseNone); + bool isMometumScrollEvent = (wheelEvent.momentumPhase() != PlatformWheelEventPhaseNone); if (m_ignoreMomentumScrolls && (isMometumScrollEvent || m_snapRubberBandTimer.isActive())) { - if (wheelEvent.phase() == PlatformWheelEventPhaseEnded) + if (wheelEvent.momentumPhase() == PlatformWheelEventPhaseEnded) m_ignoreMomentumScrolls = false; return; } @@ -819,7 +820,7 @@ void ScrollAnimatorMac::smoothScrollWithEvent(PlatformWheelEvent& wheelEvent) isHorizontallyStretched = stretchAmount.width(); isVerticallyStretched = stretchAmount.height(); - PlatformWheelEventPhase phase = wheelEvent.phase(); + PlatformWheelEventPhase phase = wheelEvent.momentumPhase(); // If we are starting momentum scrolling then do some setup. if (!m_momentumScrollInProgress && (phase == PlatformWheelEventPhaseBegan || phase == PlatformWheelEventPhaseChanged)) diff --git a/Source/WebCore/platform/mac/ScrollbarThemeMac.mm b/Source/WebCore/platform/mac/ScrollbarThemeMac.mm index c35dfa0..5a3796d 100644 --- a/Source/WebCore/platform/mac/ScrollbarThemeMac.mm +++ b/Source/WebCore/platform/mac/ScrollbarThemeMac.mm @@ -54,12 +54,11 @@ static ScrollbarPainterMap* scrollbarMap() static ScrollbarPainterMap* map = new ScrollbarPainterMap; return map; } - + } @interface ScrollbarPrefsObserver : NSObject { - } + (void)registerAsObserver; @@ -167,7 +166,6 @@ void ScrollbarThemeMac::registerScrollbar(Scrollbar* scrollbar) void ScrollbarThemeMac::unregisterScrollbar(Scrollbar* scrollbar) { - scrollbarMap()->remove(scrollbar); } @@ -429,23 +427,25 @@ static int scrollbarPartToHIPressedState(ScrollbarPart part) bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& damageRect) { #if USE(WK_SCROLLBAR_PAINTER) - float value = 0.0f; - float totalSize = 0.0f; + float value = 0; + float overhang = 0; if (scrollbar->currentPos() < 0) { // Scrolled past the top. - value = 0.0f; - totalSize = scrollbar->totalSize() - scrollbar->currentPos(); + value = 0; + overhang = -scrollbar->currentPos(); } else if (scrollbar->visibleSize() + scrollbar->currentPos() > scrollbar->totalSize()) { // Scrolled past the bottom. - value = 1.0f; - totalSize = scrollbar->visibleSize() + scrollbar->currentPos(); + value = 1; + overhang = scrollbar->currentPos() + scrollbar->visibleSize() - scrollbar->totalSize(); } else { // Within the bounds of the scrollable area. value = scrollbar->currentPos() / scrollbar->maximum(); - totalSize = scrollbar->totalSize(); } + ScrollAnimatorMac* scrollAnimator = static_cast<ScrollAnimatorMac*>(scrollbar->scrollableArea()->scrollAnimator()); + scrollAnimator->setIsDrawingIntoLayer(context->isCALayerContext()); + context->save(); context->clip(damageRect); context->translate(scrollbar->frameRect().x(), scrollbar->frameRect().y()); @@ -453,8 +453,11 @@ bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, co wkScrollbarPainterPaint(scrollbarMap()->get(scrollbar).get(), scrollbar->enabled(), value, - static_cast<CGFloat>(scrollbar->visibleSize()) / totalSize, + (static_cast<CGFloat>(scrollbar->visibleSize()) - overhang) / scrollbar->totalSize(), scrollbar->frameRect()); + + scrollAnimator->setIsDrawingIntoLayer(false); + context->restore(); return true; #endif @@ -510,14 +513,14 @@ bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, co IntRect bufferRect(scrollbar->frameRect()); bufferRect.intersect(damageRect); - bufferRect.move(-scrollbar->frameRect().x(), -scrollbar->frameRect().y()); OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(bufferRect.size()); if (!imageBuffer) return true; - + + imageBuffer->context()->translate(scrollbar->frameRect().x() - bufferRect.x(), scrollbar->frameRect().y() - bufferRect.y()); HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal); - context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, scrollbar->frameRect().location()); + context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, bufferRect.location()); } return true; diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.h b/Source/WebCore/platform/mac/WebCoreSystemInterface.h index e6d6cf6..df65ff2 100644 --- a/Source/WebCore/platform/mac/WebCoreSystemInterface.h +++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.h @@ -50,11 +50,13 @@ typedef struct _NSRect NSRect; @class NSDate; @class NSEvent; @class NSFont; +@class NSHTTPCookie; @class NSImage; @class NSMenu; @class NSMutableURLRequest; @class NSString; @class NSTextFieldCell; +@class NSURL; @class NSURLConnection; @class NSURLRequest; @class NSURLResponse; @@ -68,10 +70,12 @@ class NSData; class NSDate; class NSEvent; class NSFont; +class NSHTTPCookie; class NSImage; class NSMenu; class NSMutableArray; class NSMutableURLRequest; +class NSURL; class NSURLRequest; class NSString; class NSTextFieldCell; @@ -235,6 +239,17 @@ extern CFTypeRef (*wkCreateAXTextMarker)(const void *bytes, size_t len); extern BOOL (*wkGetBytesFromAXTextMarker)(CFTypeRef textMarker, void *bytes, size_t length); extern AXUIElementRef (*wkCreateAXUIElementRef)(id element); +typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; +extern CFURLStorageSessionRef (*wkCreatePrivateStorageSession)(CFStringRef); +extern NSURLRequest* (*wkCopyRequestWithStorageSession)(CFURLStorageSessionRef, NSURLRequest*); + +typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; +extern CFHTTPCookieStorageRef (*wkCreatePrivateInMemoryHTTPCookieStorage)(CFURLStorageSessionRef); +extern unsigned (*wkGetHTTPCookieAcceptPolicy)(CFHTTPCookieStorageRef); +extern NSArray *(*wkHTTPCookiesForURL)(CFHTTPCookieStorageRef, NSURL *); +extern void (*wkSetHTTPCookiesForURL)(CFHTTPCookieStorageRef, NSArray *, NSURL *, NSURL *); +extern void (*wkDeleteHTTPCookie)(CFHTTPCookieStorageRef, NSHTTPCookie *); + } #endif diff --git a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm index 24bdcb1..50ac236 100644 --- a/Source/WebCore/platform/mac/WebCoreSystemInterface.mm +++ b/Source/WebCore/platform/mac/WebCoreSystemInterface.mm @@ -172,3 +172,10 @@ CFTypeRef (*wkCreateAXTextMarker)(const void *bytes, size_t len); BOOL (*wkGetBytesFromAXTextMarker)(CFTypeRef textMarker, void *bytes, size_t length); AXUIElementRef (*wkCreateAXUIElementRef)(id element); +CFURLStorageSessionRef (*wkCreatePrivateStorageSession)(CFStringRef); +NSURLRequest* (*wkCopyRequestWithStorageSession)(CFURLStorageSessionRef, NSURLRequest*); +CFHTTPCookieStorageRef (*wkCreatePrivateInMemoryHTTPCookieStorage)(CFURLStorageSessionRef); +unsigned (*wkGetHTTPCookieAcceptPolicy)(CFHTTPCookieStorageRef); +NSArray *(*wkHTTPCookiesForURL)(CFHTTPCookieStorageRef, NSURL *); +void (*wkSetHTTPCookiesForURL)(CFHTTPCookieStorageRef, NSArray *, NSURL *, NSURL *); +void (*wkDeleteHTTPCookie)(CFHTTPCookieStorageRef, NSHTTPCookie *); diff --git a/Source/WebCore/platform/mac/WheelEventMac.mm b/Source/WebCore/platform/mac/WheelEventMac.mm index 74265d1..4e9a8b7 100644 --- a/Source/WebCore/platform/mac/WheelEventMac.mm +++ b/Source/WebCore/platform/mac/WheelEventMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2010 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2010, 2011 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 @@ -33,7 +33,7 @@ namespace WebCore { -static PlatformWheelEventPhase phaseForEvent(NSEvent *event) +static PlatformWheelEventPhase momentumPhaseForEvent(NSEvent *event) { #if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) uint32_t phase = PlatformWheelEventPhaseNone; @@ -54,6 +54,27 @@ static PlatformWheelEventPhase phaseForEvent(NSEvent *event) #endif } +static PlatformWheelEventPhase phaseForEvent(NSEvent *event) +{ +#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) + uint32_t phase = PlatformWheelEventPhaseNone; + if ([event phase] & NSEventPhaseBegan) + phase |= PlatformWheelEventPhaseBegan; + if ([event phase] & NSEventPhaseStationary) + phase |= PlatformWheelEventPhaseStationary; + if ([event phase] & NSEventPhaseChanged) + phase |= PlatformWheelEventPhaseChanged; + if ([event phase] & NSEventPhaseEnded) + phase |= PlatformWheelEventPhaseEnded; + if ([event phase] & 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)) @@ -64,10 +85,10 @@ PlatformWheelEvent::PlatformWheelEvent(NSEvent* event, NSView *windowView) , m_altKey([event modifierFlags] & NSAlternateKeyMask) , m_metaKey([event modifierFlags] & NSCommandKeyMask) , m_phase(phaseForEvent(event)) + , m_momentumPhase(momentumPhaseForEvent(event)) , m_timestamp([event timestamp]) { 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/network/CookieStorage.h b/Source/WebCore/platform/network/CookieStorage.h index 56ca5dc..67bb4d5 100644 --- a/Source/WebCore/platform/network/CookieStorage.h +++ b/Source/WebCore/platform/network/CookieStorage.h @@ -26,9 +26,20 @@ #ifndef CookieStorage_h #define CookieStorage_h +#include <wtf/RetainPtr.h> + +typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; + namespace WebCore { + +#if USE(CFURLSTORAGESESSIONS) && PLATFORM(MAC) +RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage(); +#endif + void setCookieStoragePrivateBrowsingEnabled(bool); +void startObservingCookieChanges(); +void stopObservingCookieChanges(); } diff --git a/Source/WebCore/platform/network/NetworkStateNotifier.cpp b/Source/WebCore/platform/network/NetworkStateNotifier.cpp index 7638478..d0e00f1 100644 --- a/Source/WebCore/platform/network/NetworkStateNotifier.cpp +++ b/Source/WebCore/platform/network/NetworkStateNotifier.cpp @@ -20,7 +20,7 @@ * 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. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -35,15 +35,28 @@ namespace WebCore { NetworkStateNotifier& networkStateNotifier() { AtomicallyInitializedStatic(NetworkStateNotifier*, networkStateNotifier = new NetworkStateNotifier); - + return *networkStateNotifier; } void NetworkStateNotifier::setNetworkStateChangedFunction(void(*function)()) { ASSERT(!m_networkStateChangedFunction); - + m_networkStateChangedFunction = function; } - + +#if PLATFORM(ANDROID) || PLATFORM(CHROMIUM) +void NetworkStateNotifier::setOnLine(bool onLine) +{ + if (m_isOnLine == onLine) + return; + + m_isOnLine = onLine; + + if (m_networkStateChangedFunction) + m_networkStateChangedFunction(); +} +#endif // PLATFORM(ANDROID) || PLATFORM(CHROMIM) + } diff --git a/Source/WebCore/platform/network/NetworkStateNotifier.h b/Source/WebCore/platform/network/NetworkStateNotifier.h index 08ab0bd..116bbb4 100644 --- a/Source/WebCore/platform/network/NetworkStateNotifier.h +++ b/Source/WebCore/platform/network/NetworkStateNotifier.h @@ -41,10 +41,6 @@ typedef const struct __CFArray * CFArrayRef; typedef const struct __SCDynamicStore * SCDynamicStoreRef; -#elif PLATFORM(CHROMIUM) - -#include "NetworkStateNotifierPrivate.h" - #elif PLATFORM(WIN) #include <windows.h> @@ -71,19 +67,29 @@ class NetworkStateNotifier { public: NetworkStateNotifier(); void setNetworkStateChangedFunction(void (*)()); - + bool onLine() const { return m_isOnLine; } #if (PLATFORM(QT) && ENABLE(QT_BEARER)) void setNetworkAccessAllowed(bool); +#elif PLATFORM(ANDROID) || PLATFORM(CHROMIUM) + void setOnLine(bool); #endif #if PLATFORM(ANDROID) + void networkStateChange(bool online) { setOnLine(online); } +#endif + +<<<<<<< HEAD +#if PLATFORM(ANDROID) // TODO: Upstream to webkit.org Connection::ConnectionType type() const { return m_type; } #endif private: +======= +private: +>>>>>>> WebKit at r80534 bool m_isOnLine; #if PLATFORM(ANDROID) // TODO: Upstream to webkit.org @@ -105,11 +111,12 @@ private: static void CALLBACK addrChangeCallback(void*, BOOLEAN timedOut); static void callAddressChanged(void*); void addressChanged(); - + void registerForAddressChange(); HANDLE m_waitHandle; OVERLAPPED m_overlapped; +<<<<<<< HEAD #elif PLATFORM(CHROMIUM) NetworkStateNotifierPrivate p; @@ -119,13 +126,15 @@ public: // TODO: Upstream to webkit.org void networkTypeChange(Connection::ConnectionType type); +======= +>>>>>>> WebKit at r80534 #elif PLATFORM(QT) && ENABLE(QT_BEARER) friend class NetworkStateNotifierPrivate; NetworkStateNotifierPrivate* p; #endif }; -#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(CHROMIUM) && !(PLATFORM(QT) && ENABLE(QT_BEARER)) +#if !PLATFORM(MAC) && !PLATFORM(WIN) && !(PLATFORM(QT) && ENABLE(QT_BEARER)) inline NetworkStateNotifier::NetworkStateNotifier() : m_isOnLine(true) @@ -134,7 +143,7 @@ inline NetworkStateNotifier::NetworkStateNotifier() , m_type(Connection::UNKNOWN) #endif , m_networkStateChangedFunction(0) -{ +{ } inline void NetworkStateNotifier::updateState() { } @@ -142,7 +151,7 @@ inline void NetworkStateNotifier::updateState() { } #endif NetworkStateNotifier& networkStateNotifier(); - + }; #endif // NetworkStateNotifier_h diff --git a/Source/WebCore/platform/network/ResourceHandle.cpp b/Source/WebCore/platform/network/ResourceHandle.cpp index 9910ac1..d901984 100644 --- a/Source/WebCore/platform/network/ResourceHandle.cpp +++ b/Source/WebCore/platform/network/ResourceHandle.cpp @@ -33,6 +33,7 @@ #include "ResourceHandleClient.h" #include "Timer.h" #include <algorithm> +#include <wtf/text/CString.h> namespace WebCore { @@ -185,4 +186,46 @@ void ResourceHandle::cacheMetadata(const ResourceResponse&, const Vector<char>&) // Optionally implemented by platform. } +#if USE(CFURLSTORAGESESSIONS) + +static RetainPtr<CFURLStorageSessionRef>& privateStorageSession() +{ + DEFINE_STATIC_LOCAL(RetainPtr<CFURLStorageSessionRef>, storageSession, ()); + return storageSession; +} + +static String& privateBrowsingStorageSessionIdentifierBase() +{ + DEFINE_STATIC_LOCAL(String, base, ()); + return base; +} + +void ResourceHandle::setPrivateBrowsingEnabled(bool enabled) +{ + if (!enabled) { + privateStorageSession() = nullptr; + return; + } + + if (privateStorageSession()) + return; + + String base = privateBrowsingStorageSessionIdentifierBase().isNull() ? privateBrowsingStorageSessionIdentifierDefaultBase() : privateBrowsingStorageSessionIdentifierBase(); + RetainPtr<CFStringRef> cfIdentifier(AdoptCF, String::format("%s.PrivateBrowsing", base.utf8().data()).createCFString()); + + privateStorageSession() = createPrivateBrowsingStorageSession(cfIdentifier.get()); +} + +CFURLStorageSessionRef ResourceHandle::privateBrowsingStorageSession() +{ + return privateStorageSession().get(); +} + +void ResourceHandle::setPrivateBrowsingStorageSessionIdentifierBase(const String& identifier) +{ + privateBrowsingStorageSessionIdentifierBase() = identifier; +} + +#endif // USE(CFURLSTORAGESESSIONS) + } // namespace WebCore diff --git a/Source/WebCore/platform/network/ResourceHandle.h b/Source/WebCore/platform/network/ResourceHandle.h index c2a0b8e..f21f963 100644 --- a/Source/WebCore/platform/network/ResourceHandle.h +++ b/Source/WebCore/platform/network/ResourceHandle.h @@ -37,7 +37,7 @@ typedef struct _SoupSession SoupSession; #endif -#if PLATFORM(CF) +#if USE(CF) typedef const struct __CFData * CFDataRef; #endif @@ -71,6 +71,10 @@ typedef int CFHTTPCookieStorageAcceptPolicy; typedef struct OpaqueCFHTTPCookieStorage* CFHTTPCookieStorageRef; #endif +#if USE(CFURLSTORAGESESSIONS) +typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; +#endif + namespace WebCore { class AuthenticationChallenge; @@ -140,7 +144,7 @@ public: #if PLATFORM(WIN) && USE(CURL) static void setHostAllowsAnyHTTPSCertificate(const String&); #endif -#if PLATFORM(WIN) && USE(CURL) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CURL) && USE(CF) static void setClientCertificate(const String& host, CFDataRef); #endif @@ -190,6 +194,12 @@ public: void fireFailure(Timer<ResourceHandle>*); +#if USE(CFURLSTORAGESESSIONS) + static void setPrivateBrowsingEnabled(bool); + static CFURLStorageSessionRef privateBrowsingStorageSession(); + static void setPrivateBrowsingStorageSessionIdentifierBase(const String&); +#endif + using RefCounted<ResourceHandle>::ref; using RefCounted<ResourceHandle>::deref; @@ -214,10 +224,15 @@ private: #if PLATFORM(MAC) void createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff); -#elif PLATFORM(CF) +#elif USE(CF) void createCFURLConnection(bool shouldUseCredentialStorage, bool shouldContentSniff); #endif +#if USE(CFURLSTORAGESESSIONS) + static RetainPtr<CFURLStorageSessionRef> createPrivateBrowsingStorageSession(CFStringRef identifier); + static String privateBrowsingStorageSessionIdentifierDefaultBase(); +#endif + friend class ResourceHandleInternal; OwnPtr<ResourceHandleInternal> d; }; diff --git a/Source/WebCore/platform/network/ResourceHandleInternal.h b/Source/WebCore/platform/network/ResourceHandleInternal.h index 5512062..b622801 100644 --- a/Source/WebCore/platform/network/ResourceHandleInternal.h +++ b/Source/WebCore/platform/network/ResourceHandleInternal.h @@ -114,7 +114,6 @@ namespace WebCore { #if USE(SOUP) , m_cancelled(false) , m_buffer(0) - , m_total(0) , m_bodySize(0) , m_bodyDataSent(0) , m_idleHandler(0) @@ -194,7 +193,6 @@ namespace WebCore { GRefPtr<GInputStream> m_inputStream; GRefPtr<GCancellable> m_cancellable; char* m_buffer; - gsize m_total; unsigned long m_bodySize; unsigned long m_bodyDataSent; guint m_idleHandler; diff --git a/Source/WebCore/platform/network/ResourceRequestBase.cpp b/Source/WebCore/platform/network/ResourceRequestBase.cpp index ba58461..6a554fe 100644 --- a/Source/WebCore/platform/network/ResourceRequestBase.cpp +++ b/Source/WebCore/platform/network/ResourceRequestBase.cpp @@ -32,6 +32,13 @@ using namespace std; namespace WebCore { +#if !PLATFORM(MAC) || USE(CFNETWORK) +double ResourceRequestBase::s_defaultTimeoutInterval = INT_MAX; +#else +// Will use NSURLRequest default timeout unless set to a non-zero value with setDefaultTimeoutInterval(). +double ResourceRequestBase::s_defaultTimeoutInterval = 0; +#endif + inline const ResourceRequest& ResourceRequestBase::asResourceRequest() const { return *static_cast<const ResourceRequest*>(this); @@ -408,11 +415,22 @@ bool ResourceRequestBase::isConditional() const m_httpHeaderFields.contains("If-Unmodified-Since")); } +double ResourceRequestBase::defaultTimeoutInterval() +{ + return s_defaultTimeoutInterval; +} + +void ResourceRequestBase::setDefaultTimeoutInterval(double timeoutInterval) +{ + s_defaultTimeoutInterval = timeoutInterval; +} + void ResourceRequestBase::updatePlatformRequest() const { if (m_platformRequestUpdated) return; - + + ASSERT(m_resourceRequestUpdated); const_cast<ResourceRequest&>(asResourceRequest()).doUpdatePlatformRequest(); m_platformRequestUpdated = true; } @@ -422,6 +440,7 @@ void ResourceRequestBase::updateResourceRequest() const if (m_resourceRequestUpdated) return; + ASSERT(m_platformRequestUpdated); const_cast<ResourceRequest&>(asResourceRequest()).doUpdateResourceRequest(); m_resourceRequestUpdated = true; } diff --git a/Source/WebCore/platform/network/ResourceRequestBase.h b/Source/WebCore/platform/network/ResourceRequestBase.h index 9cc9148..ec7e32a 100644 --- a/Source/WebCore/platform/network/ResourceRequestBase.h +++ b/Source/WebCore/platform/network/ResourceRequestBase.h @@ -44,8 +44,6 @@ namespace WebCore { ReturnCacheDataDontLoad, // results of a post - allow stale data and only use cache }; - const int unspecifiedTimeoutInterval = INT_MAX; - class ResourceRequest; struct CrossThreadResourceRequestData; @@ -85,7 +83,7 @@ namespace WebCore { ResourceRequestCachePolicy cachePolicy() const; void setCachePolicy(ResourceRequestCachePolicy cachePolicy); - double timeoutInterval() const; + double timeoutInterval() const; // May return 0 when using platform default. void setTimeoutInterval(double timeoutInterval); const KURL& firstPartyForCookies() const; @@ -148,9 +146,13 @@ namespace WebCore { void setReportRawHeaders(bool reportRawHeaders) { m_reportRawHeaders = reportRawHeaders; } // What this request is for. + // FIXME: This should be moved out of ResourceRequestBase, <https://bugs.webkit.org/show_bug.cgi?id=48483>. TargetType targetType() const { return m_targetType; } void setTargetType(TargetType type) { m_targetType = type; } + static double defaultTimeoutInterval(); // May return 0 when using platform default. + static void setDefaultTimeoutInterval(double); + static bool compare(const ResourceRequest&, const ResourceRequest&); protected: @@ -169,7 +171,7 @@ namespace WebCore { ResourceRequestBase(const KURL& url, ResourceRequestCachePolicy policy) : m_url(url) , m_cachePolicy(policy) - , m_timeoutInterval(unspecifiedTimeoutInterval) + , m_timeoutInterval(s_defaultTimeoutInterval) , m_httpMethod("GET") , m_allowCookies(true) , m_resourceRequestUpdated(true) @@ -191,7 +193,7 @@ namespace WebCore { KURL m_url; ResourceRequestCachePolicy m_cachePolicy; - double m_timeoutInterval; + double m_timeoutInterval; // 0 is a magic value for platform default on platforms that have one. KURL m_firstPartyForCookies; String m_httpMethod; HTTPHeaderMap m_httpHeaderFields; @@ -208,6 +210,8 @@ namespace WebCore { private: const ResourceRequest& asResourceRequest() const; + + static double s_defaultTimeoutInterval; }; bool equalIgnoringHeaderFields(const ResourceRequestBase&, const ResourceRequestBase&); @@ -236,7 +240,7 @@ namespace WebCore { unsigned initializeMaximumHTTPConnectionCountPerHost(); -#if PLATFORM(CF) +#if USE(CF) bool isHTTPPipeliningEnabled(); bool shouldForceHTTPPipeliningPriorityHigh(); #else diff --git a/Source/WebCore/platform/network/android/CookieJarAndroid.cpp b/Source/WebCore/platform/network/android/CookieJarAndroid.cpp index f3b343e..d0a4217 100644 --- a/Source/WebCore/platform/network/android/CookieJarAndroid.cpp +++ b/Source/WebCore/platform/network/android/CookieJarAndroid.cpp @@ -52,4 +52,19 @@ bool cookiesEnabled(const Document* document) return PlatformBridge::cookiesEnabled(document); } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/network/cf/AuthenticationCF.cpp b/Source/WebCore/platform/network/cf/AuthenticationCF.cpp index 5168a48..3932a2b 100644 --- a/Source/WebCore/platform/network/cf/AuthenticationCF.cpp +++ b/Source/WebCore/platform/network/cf/AuthenticationCF.cpp @@ -33,6 +33,10 @@ #include "Credential.h" #include "ProtectionSpace.h" +// This header must come before all other CFNetwork headers to work around a CFNetwork bug. It can +// be removed entirely once <rdar://problem/9042114> is fixed. +#include <CFNetwork/CFURLConnectionPriv.h> + #include <CFNetwork/CFURLAuthChallengePriv.h> #include <CFNetwork/CFURLCredentialPriv.h> #include <CFNetwork/CFURLProtectionSpacePriv.h> diff --git a/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp b/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp index c6d513a..71c5e25 100644 --- a/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp +++ b/Source/WebCore/platform/network/cf/CookieJarCFNet.cpp @@ -233,6 +233,52 @@ void deleteCookie(const Document*, const KURL& url, const String& name) } } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + if (!cookieStorage) + return; + + RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookies(cookieStorage)); + if (!cookiesCF) + return; + + CFIndex count = CFArrayGetCount(cookiesCF.get()); + for (CFIndex i = 0; i < count; ++i) { + CFHTTPCookieRef cookie = static_cast<CFHTTPCookieRef>(const_cast<void *>(CFArrayGetValueAtIndex(cookiesCF.get(), i))); + RetainPtr<CFStringRef> domain = cookieDomain(cookie); + hostnames.add(domain.get()); + } +} + +void deleteCookiesForHostname(const String& hostname) +{ + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + if (!cookieStorage) + return; + + RetainPtr<CFArrayRef> cookiesCF(AdoptCF, CFHTTPCookieStorageCopyCookies(cookieStorage)); + if (!cookiesCF) + return; + + CFIndex count = CFArrayGetCount(cookiesCF.get()); + for (CFIndex i = count - 1; i >=0; i--) { + CFHTTPCookieRef cookie = static_cast<CFHTTPCookieRef>(const_cast<void *>(CFArrayGetValueAtIndex(cookiesCF.get(), i))); + RetainPtr<CFStringRef> domain = cookieDomain(cookie); + if (String(domain.get()) == hostname) + CFHTTPCookieStorageDeleteCookie(cookieStorage, cookie); + } +} + +void deleteAllCookies() +{ + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + if (!cookieStorage) + return; + + CFHTTPCookieStorageDeleteAllCookies(cookieStorage); +} + } // namespace WebCore #endif // USE(CFNETWORK) diff --git a/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp b/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp index 3deb688..c2a5691 100644 --- a/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp +++ b/Source/WebCore/platform/network/cf/CookieStorageCFNet.cpp @@ -28,21 +28,32 @@ #if USE(CFNETWORK) +#include "LoaderRunLoopCF.h" +#include "ResourceHandle.h" #include <CFNetwork/CFHTTPCookiesPriv.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #include <wtf/MainThread.h> #include <wtf/RetainPtr.h> +#if USE(PLATFORM_STRATEGIES) +#include "CookiesStrategy.h" +#include "PlatformStrategies.h" +#endif + namespace WebCore { -static RetainPtr<CFHTTPCookieStorageRef> s_cookieStorage; +static RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage() +{ + DEFINE_STATIC_LOCAL(RetainPtr<CFHTTPCookieStorageRef>, cookieStorage, ()); + return cookieStorage; +} CFHTTPCookieStorageRef currentCookieStorage() { ASSERT(isMainThread()); - if (s_cookieStorage) - return s_cookieStorage.get(); + if (CFHTTPCookieStorageRef privateCookieStorage = privateBrowsingCookieStorage().get()) + return privateCookieStorage; return wkGetDefaultHTTPCookieStorage(); } @@ -50,17 +61,76 @@ void setCurrentCookieStorage(CFHTTPCookieStorageRef cookieStorage) { ASSERT(isMainThread()); - s_cookieStorage = cookieStorage; + privateBrowsingCookieStorage().adoptCF(cookieStorage); } void setCookieStoragePrivateBrowsingEnabled(bool enabled) { ASSERT(isMainThread()); - if (enabled) - s_cookieStorage.adoptCF(wkCreatePrivateHTTPCookieStorage()); - else - s_cookieStorage = 0; + if (!enabled) { + privateBrowsingCookieStorage() = nullptr; + return; + } + +#if USE(CFURLSTORAGESESSIONS) + privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(ResourceHandle::privateBrowsingStorageSession())); +#else + privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(0)); +#endif +} + +static void notifyCookiesChangedOnMainThread(void* context) +{ + ASSERT(isMainThread()); + +#if USE(PLATFORM_STRATEGIES) + platformStrategies()->cookiesStrategy()->notifyCookiesChanged(); +#endif +} + +static void notifyCookiesChanged(CFHTTPCookieStorageRef inStorage, void *context) +{ + callOnMainThread(notifyCookiesChangedOnMainThread, 0); +} + +static inline CFRunLoopRef cookieStorageObserverRunLoop() +{ + // We're using the loader run loop because we need a CFRunLoop to + // call the CFNetwork cookie storage APIs with. Re-using the loader + // run loop is less overhead than starting a new thread to just listen + // for changes in cookies. + + // FIXME: The loaderRunLoop function name should be a little more generic. + return loaderRunLoop(); +} + +void startObservingCookieChanges() +{ + ASSERT(isMainThread()); + + CFRunLoopRef runLoop = cookieStorageObserverRunLoop(); + ASSERT(runLoop); + + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + ASSERT(cookieStorage); + + CFHTTPCookieStorageScheduleWithRunLoop(cookieStorage, runLoop, kCFRunLoopCommonModes); + CFHTTPCookieStorageAddObserver(cookieStorage, runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0); +} + +void stopObservingCookieChanges() +{ + ASSERT(isMainThread()); + + CFRunLoopRef runLoop = cookieStorageObserverRunLoop(); + ASSERT(runLoop); + + CFHTTPCookieStorageRef cookieStorage = currentCookieStorage(); + ASSERT(cookieStorage); + + CFHTTPCookieStorageRemoveObserver(cookieStorage, runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0); + CFHTTPCookieStorageUnscheduleFromRunLoop(cookieStorage, runLoop, kCFRunLoopCommonModes); } } // namespace WebCore diff --git a/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp b/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp index 8bc8f08..b342fe3 100644 --- a/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp +++ b/Source/WebCore/platform/network/cf/FormDataStreamCFNet.cpp @@ -53,260 +53,6 @@ typedef CFReadStreamCallBacks WCReadStreamCallBacks; namespace WebCore { -static HashMap<CFReadStreamRef, RefPtr<FormData> >& getStreamFormDatas() -{ - static HashMap<CFReadStreamRef, RefPtr<FormData> > streamFormDatas; - return streamFormDatas; -} - -static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context); - -struct FormStreamFields { - CFMutableSetRef scheduledRunLoopPairs; - Vector<FormDataElement> remainingElements; // in reverse order - CFReadStreamRef currentStream; - char* currentData; - CFReadStreamRef formStream; -}; - -struct SchedulePair { - CFRunLoopRef runLoop; - CFStringRef mode; -}; - -static const void* pairRetain(CFAllocatorRef alloc, const void* value) -{ - const SchedulePair* pair = static_cast<const SchedulePair*>(value); - - SchedulePair* result = new SchedulePair; - CFRetain(pair->runLoop); - result->runLoop = pair->runLoop; - result->mode = CFStringCreateCopy(alloc, pair->mode); - return result; -} - -static void pairRelease(CFAllocatorRef alloc, const void* value) -{ - const SchedulePair* pair = static_cast<const SchedulePair*>(value); - - CFRelease(pair->runLoop); - CFRelease(pair->mode); - delete pair; -} - -static Boolean pairEqual(const void* a, const void* b) -{ - const SchedulePair* pairA = static_cast<const SchedulePair*>(a); - const SchedulePair* pairB = static_cast<const SchedulePair*>(b); - - return pairA->runLoop == pairB->runLoop && CFEqual(pairA->mode, pairB->mode); -} - -static CFHashCode pairHash(const void* value) -{ - const SchedulePair* pair = static_cast<const SchedulePair*>(value); - - return (CFHashCode)pair->runLoop ^ CFHash(pair->mode); -} - -static void closeCurrentStream(FormStreamFields *form) -{ - if (form->currentStream) { - CFReadStreamClose(form->currentStream); - CFReadStreamSetClient(form->currentStream, kCFStreamEventNone, NULL, NULL); - CFRelease(form->currentStream); - form->currentStream = NULL; - } - if (form->currentData) { - fastFree(form->currentData); - form->currentData = 0; - } -} - -static void scheduleWithPair(const void* value, void* context) -{ - const SchedulePair* pair = static_cast<const SchedulePair*>(value); - CFReadStreamRef stream = (CFReadStreamRef)context; - - CFReadStreamScheduleWithRunLoop(stream, pair->runLoop, pair->mode); -} - -static void advanceCurrentStream(FormStreamFields *form) -{ - closeCurrentStream(form); - - if (form->remainingElements.isEmpty()) - return; - - // Create the new stream. - FormDataElement& nextInput = form->remainingElements.last(); - if (nextInput.m_type == FormDataElement::data) { - size_t size = nextInput.m_data.size(); - char* data = nextInput.m_data.releaseBuffer(); - form->currentStream = CFReadStreamCreateWithBytesNoCopy(0, reinterpret_cast<const UInt8*>(data), size, kCFAllocatorNull); - form->currentData = data; - } else - form->currentStream = CFReadStreamCreateWithFile(0, pathAsURL(nextInput.m_filename).get()); - form->remainingElements.removeLast(); - - // Set up the callback. - CFStreamClientContext context = { 0, form, NULL, NULL, NULL }; - CFReadStreamSetClient(form->currentStream, kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, - formEventCallback, &context); - - // Schedule with the current set of run loops. - CFSetApplyFunction(form->scheduledRunLoopPairs, scheduleWithPair, form->currentStream); -} - -static void openNextStream(FormStreamFields* form) -{ - // Skip over any streams we can't open. - // For some purposes we might want to return an error, but the current CFURLConnection - // can't really do anything useful with an error at this point, so this is better. - advanceCurrentStream(form); - while (form->currentStream && !CFReadStreamOpen(form->currentStream)) - advanceCurrentStream(form); -} - -static void* formCreate(CFReadStreamRef stream, void* context) -{ - FormData* formData = static_cast<FormData*>(context); - - CFSetCallBacks runLoopAndModeCallBacks = { 0, pairRetain, pairRelease, NULL, pairEqual, pairHash }; - - FormStreamFields* newInfo = new FormStreamFields; - newInfo->scheduledRunLoopPairs = CFSetCreateMutable(0, 0, &runLoopAndModeCallBacks); - newInfo->currentStream = NULL; - newInfo->currentData = 0; - newInfo->formStream = stream; // Don't retain. That would create a reference cycle. - - // Append in reverse order since we remove elements from the end. - size_t size = formData->elements().size(); - newInfo->remainingElements.reserveCapacity(size); - for (size_t i = 0; i < size; ++i) - newInfo->remainingElements.append(formData->elements()[size - i - 1]); - - getStreamFormDatas().set(stream, adoptRef(formData)); - - return newInfo; -} - -static void formFinalize(CFReadStreamRef stream, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - getStreamFormDatas().remove(stream); - - closeCurrentStream(form); - CFRelease(form->scheduledRunLoopPairs); - delete form; -} - -static Boolean formOpen(CFReadStreamRef stream, CFStreamError* error, Boolean* openComplete, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - openNextStream(form); - - *openComplete = TRUE; - error->error = 0; - return TRUE; -} - -static CFIndex formRead(CFReadStreamRef stream, UInt8* buffer, CFIndex bufferLength, CFStreamError* error, Boolean* atEOF, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - while (form->currentStream) { - CFIndex bytesRead = CFReadStreamRead(form->currentStream, buffer, bufferLength); - if (bytesRead < 0) { - *error = CFReadStreamGetError(form->currentStream); - return -1; - } - if (bytesRead > 0) { - error->error = 0; - *atEOF = FALSE; - return bytesRead; - } - openNextStream(form); - } - - error->error = 0; - *atEOF = TRUE; - return 0; -} - -static Boolean formCanRead(CFReadStreamRef stream, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - while (form->currentStream && CFReadStreamGetStatus(form->currentStream) == kCFStreamStatusAtEnd) { - openNextStream(form); - } - if (!form->currentStream) { - CFReadStreamSignalEvent(stream, kCFStreamEventEndEncountered, 0); - return FALSE; - } - return CFReadStreamHasBytesAvailable(form->currentStream); -} - -static void formClose(CFReadStreamRef stream, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - closeCurrentStream(form); -} - -static void formSchedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - if (form->currentStream) - CFReadStreamScheduleWithRunLoop(form->currentStream, runLoop, runLoopMode); - SchedulePair pair = { runLoop, runLoopMode }; - CFSetAddValue(form->scheduledRunLoopPairs, &pair); -} - -static void formUnschedule(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - if (form->currentStream) - CFReadStreamUnscheduleFromRunLoop(form->currentStream, runLoop, runLoopMode); - SchedulePair pair = { runLoop, runLoopMode }; - CFSetRemoveValue(form->scheduledRunLoopPairs, &pair); -} - -static void formEventCallback(CFReadStreamRef stream, CFStreamEventType type, void* context) -{ - FormStreamFields* form = static_cast<FormStreamFields*>(context); - - switch (type) { - case kCFStreamEventHasBytesAvailable: - CFReadStreamSignalEvent(form->formStream, kCFStreamEventHasBytesAvailable, 0); - break; - case kCFStreamEventErrorOccurred: { - CFStreamError readStreamError = CFReadStreamGetError(stream); - CFReadStreamSignalEvent(form->formStream, kCFStreamEventErrorOccurred, &readStreamError); - break; - } - case kCFStreamEventEndEncountered: - openNextStream(form); - if (!form->currentStream) - CFReadStreamSignalEvent(form->formStream, kCFStreamEventEndEncountered, 0); - break; - case kCFStreamEventNone: - LOG_ERROR("unexpected kCFStreamEventNone"); - break; - case kCFStreamEventOpenCompleted: - LOG_ERROR("unexpected kCFStreamEventOpenCompleted"); - break; - case kCFStreamEventCanAcceptBytes: - LOG_ERROR("unexpected kCFStreamEventCanAcceptBytes"); - break; - } -} - void setHTTPBody(CFMutableURLRequestRef request, PassRefPtr<FormData> formData) { if (!formData) { diff --git a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp index 52b100f..f840b04 100644 --- a/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp +++ b/Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp @@ -334,6 +334,11 @@ CFArrayRef arrayFromFormData(const FormData& d) static CFURLRequestRef makeFinalRequest(const ResourceRequest& request, bool shouldContentSniff) { CFMutableURLRequestRef newRequest = CFURLRequestCreateMutableCopy(kCFAllocatorDefault, request.cfURLRequest()); + +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = ResourceHandle::privateBrowsingStorageSession()) + wkSetRequestStorageSession(storageSession, newRequest); +#endif if (!shouldContentSniff) wkSetCFURLRequestShouldContentSniff(newRequest, false); @@ -481,6 +486,11 @@ void ResourceHandle::willSendRequest(ResourceRequest& request, const ResourceRes if (!protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) request.clearHTTPAuthorization(); +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = privateBrowsingStorageSession()) + request.setStorageSession(storageSession); +#endif + client()->willSendRequest(this, request, redirectResponse); } @@ -716,6 +726,20 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame) return cached; } +#if USE(CFURLSTORAGESESSIONS) + +RetainPtr<CFURLStorageSessionRef> ResourceHandle::createPrivateBrowsingStorageSession(CFStringRef identifier) +{ + return RetainPtr<CFURLStorageSessionRef>(AdoptCF, wkCreatePrivateStorageSession(identifier)); +} + +String ResourceHandle::privateBrowsingStorageSessionIdentifierDefaultBase() +{ + return String(reinterpret_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleIdentifierKey))); +} + +#endif + void WebCoreSynchronousLoaderClient::willSendRequest(ResourceHandle* handle, ResourceRequest& request, const ResourceResponse& /*redirectResponse*/) { // FIXME: This needs to be fixed to follow the redirect correctly even for cross-domain requests. diff --git a/Source/WebCore/platform/network/cf/ResourceRequest.h b/Source/WebCore/platform/network/cf/ResourceRequest.h index 172ebe1..2da5026 100644 --- a/Source/WebCore/platform/network/cf/ResourceRequest.h +++ b/Source/WebCore/platform/network/cf/ResourceRequest.h @@ -40,6 +40,10 @@ class NSURLRequest; #endif #endif +#if USE(CFURLSTORAGESESSIONS) +typedef const struct __CFURLStorageSession* CFURLStorageSessionRef; +#endif + namespace WebCore { class ResourceRequest : public ResourceRequestBase { @@ -80,6 +84,10 @@ namespace WebCore { NSURLRequest* nsURLRequest() const; #endif +#if USE(CFURLSTORAGESESSIONS) + void setStorageSession(CFURLStorageSessionRef); +#endif + private: friend class ResourceRequestBase; diff --git a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp index 7a1dfd5..fdccc11 100644 --- a/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp +++ b/Source/WebCore/platform/network/cf/ResourceRequestCFNet.cpp @@ -195,6 +195,17 @@ void ResourceRequest::doUpdateResourceRequest() m_httpBody = httpBodyFromRequest(m_cfRequest.get()); } +#if USE(CFURLSTORAGESESSIONS) + +void ResourceRequest::setStorageSession(CFURLStorageSessionRef storageSession) +{ + CFMutableURLRequestRef cfRequest = CFURLRequestCreateMutableCopy(0, m_cfRequest.get()); + wkSetRequestStorageSession(storageSession, cfRequest); + m_cfRequest.adoptCF(cfRequest); +} + +#endif + #endif // USE(CFNETWORK) unsigned initializeMaximumHTTPConnectionCountPerHost() diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandle.h b/Source/WebCore/platform/network/cf/SocketStreamHandle.h index fbda3bc..5c1c6ff 100644 --- a/Source/WebCore/platform/network/cf/SocketStreamHandle.h +++ b/Source/WebCore/platform/network/cf/SocketStreamHandle.h @@ -72,6 +72,7 @@ private: #endif bool shouldUseSSL() const { return m_url.protocolIs("wss"); } + unsigned short port() const; void addCONNECTCredentials(CFHTTPMessageRef response); diff --git a/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp b/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp index 06454a7..d5b1743 100644 --- a/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp +++ b/Source/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp @@ -69,9 +69,6 @@ SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient ASSERT(url.protocolIs("ws") || url.protocolIs("wss")); - if (!m_url.port()) - m_url.setPort(shouldUseSSL() ? 443 : 80); - KURL httpsURL(KURL(), "https://" + m_url.host()); m_httpsURL.adoptCF(httpsURL.createCFURL()); @@ -318,7 +315,7 @@ void SocketStreamHandle::createStreams() // Creating streams to final destination, not to proxy. CFReadStreamRef readStream = 0; CFWriteStreamRef writeStream = 0; - CFStreamCreatePairWithSocketToHost(0, host.get(), m_url.port(), &readStream, &writeStream); + CFStreamCreatePairWithSocketToHost(0, host.get(), port(), &readStream, &writeStream); m_readStream.adoptCF(readStream); m_writeStream.adoptCF(writeStream); @@ -673,4 +670,13 @@ void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&) { } +unsigned short SocketStreamHandle::port() const +{ + if (unsigned short urlPort = m_url.port()) + return urlPort; + if (shouldUseSSL()) + return 443; + return 80; +} + } // namespace WebCore diff --git a/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp b/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp index 2f2489b..779fe45 100644 --- a/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp +++ b/Source/WebCore/platform/network/chromium/CookieJarChromium.cpp @@ -67,4 +67,19 @@ void deleteCookie(const Document* document, const KURL& url, const String& cooki return PlatformBridge::deleteCookie(document, url, cookieName); } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } // namespace WebCore diff --git a/Source/WebCore/platform/network/chromium/NetworkStateNotifierPrivate.h b/Source/WebCore/platform/network/chromium/NetworkStateNotifierPrivate.h deleted file mode 100644 index 7628d59..0000000 --- a/Source/WebCore/platform/network/chromium/NetworkStateNotifierPrivate.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2008, 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 NetworkStateNotifierPrivate_h -#define NetworkStateNotifierPrivate_h - -namespace WebCore { - - struct NetworkStateNotifierPrivate {}; - -} // namespace WebCore - -#endif diff --git a/Source/WebCore/platform/network/chromium/ResourceResponse.cpp b/Source/WebCore/platform/network/chromium/ResourceResponse.cpp index fc8ac62..58c8dd0 100644 --- a/Source/WebCore/platform/network/chromium/ResourceResponse.cpp +++ b/Source/WebCore/platform/network/chromium/ResourceResponse.cpp @@ -32,14 +32,14 @@ PassOwnPtr<CrossThreadResourceResponseData> ResourceResponse::doPlatformCopyData { data->m_appCacheID = m_appCacheID; data->m_appCacheManifestURL = m_appCacheManifestURL.copy(); - data->m_isContentFiltered = m_isContentFiltered; data->m_isMultipartPayload = m_isMultipartPayload; data->m_wasFetchedViaSPDY = m_wasFetchedViaSPDY; data->m_wasNpnNegotiated = m_wasNpnNegotiated; data->m_wasAlternateProtocolAvailable = m_wasAlternateProtocolAvailable; data->m_wasFetchedViaProxy = m_wasFetchedViaProxy; data->m_responseTime = m_responseTime; - data->m_socketAddress = m_socketAddress; + data->m_remoteIPAddress = m_remoteIPAddress; + data->m_remotePort = m_remotePort; data->m_downloadFilePath = m_downloadFilePath; return data; } @@ -48,14 +48,14 @@ void ResourceResponse::doPlatformAdopt(PassOwnPtr<CrossThreadResourceResponseDat { m_appCacheID = data->m_appCacheID; m_appCacheManifestURL = data->m_appCacheManifestURL.copy(); - m_isContentFiltered = data->m_isContentFiltered; m_isMultipartPayload = data->m_isMultipartPayload; m_wasFetchedViaSPDY = data->m_wasFetchedViaSPDY; m_wasNpnNegotiated = data->m_wasNpnNegotiated; m_wasAlternateProtocolAvailable = data->m_wasAlternateProtocolAvailable; m_wasFetchedViaProxy = data->m_wasFetchedViaProxy; m_responseTime = data->m_responseTime; - m_socketAddress = data->m_socketAddress; + m_remoteIPAddress = data->m_remoteIPAddress; + m_remotePort = data->m_remotePort; m_downloadFilePath = data->m_downloadFilePath; } diff --git a/Source/WebCore/platform/network/chromium/ResourceResponse.h b/Source/WebCore/platform/network/chromium/ResourceResponse.h index 35f13d1..777e1dd 100644 --- a/Source/WebCore/platform/network/chromium/ResourceResponse.h +++ b/Source/WebCore/platform/network/chromium/ResourceResponse.h @@ -37,26 +37,26 @@ namespace WebCore { public: ResourceResponse() : m_appCacheID(0) - , m_isContentFiltered(false) , m_isMultipartPayload(false) , m_wasFetchedViaSPDY(false) , m_wasNpnNegotiated(false) , m_wasAlternateProtocolAvailable(false) , m_wasFetchedViaProxy(false) , m_responseTime(0) + , m_remotePort(0) { } ResourceResponse(const KURL& url, const String& mimeType, long long expectedLength, const String& textEncodingName, const String& filename) : ResourceResponseBase(url, mimeType, expectedLength, textEncodingName, filename) , m_appCacheID(0) - , m_isContentFiltered(false) , m_isMultipartPayload(false) , m_wasFetchedViaSPDY(false) , m_wasNpnNegotiated(false) , m_wasAlternateProtocolAvailable(false) , m_wasFetchedViaProxy(false) , m_responseTime(0) + , m_remotePort(0) { } @@ -69,9 +69,6 @@ namespace WebCore { const KURL& appCacheManifestURL() const { return m_appCacheManifestURL; } void setAppCacheManifestURL(const KURL& url) { m_appCacheManifestURL = url; } - bool isContentFiltered() const { return m_isContentFiltered; } - void setIsContentFiltered(bool value) { m_isContentFiltered = value; } - bool wasFetchedViaSPDY() const { return m_wasFetchedViaSPDY; } void setWasFetchedViaSPDY(bool value) { m_wasFetchedViaSPDY = value; } @@ -96,8 +93,11 @@ namespace WebCore { double responseTime() const { return m_responseTime; } void setResponseTime(double responseTime) { m_responseTime = responseTime; } - const String& socketAddress() const { return m_socketAddress; } - void setSocketAddress(const String& value) { m_socketAddress = value; } + const String& remoteIPAddress() const { return m_remoteIPAddress; } + void setRemoteIPAddress(const String& value) { m_remoteIPAddress = value; } + + unsigned short remotePort() const { return m_remotePort; } + void setRemotePort(unsigned short value) { m_remotePort = value; } const String& downloadFilePath() const { return m_downloadFilePath; } void setDownloadFilePath(const String& downloadFilePath) { m_downloadFilePath = downloadFilePath; } @@ -126,10 +126,6 @@ namespace WebCore { // Note: only valid for main resource responses. KURL m_appCacheManifestURL; - // Whether the contents for this response has been altered/blocked (usually - // for security reasons. - bool m_isContentFiltered; - // Set to true if this is part of a multipart response. bool m_isMultipartPayload; @@ -150,9 +146,11 @@ namespace WebCore { // responses, this time could be "far" in the past. double m_responseTime; - // Remote address of the socket which fetched this resource, for presenting - // to inquisitive users. Can be "ipv4:port", "[ipv6]:port", or empty. - String m_socketAddress; + // Remote IP address of the socket which fetched this resource. + String m_remoteIPAddress; + + // Remote port number of the socket which fetched this resource. + unsigned short m_remotePort; // The path to the downloaded file. String m_downloadFilePath; @@ -161,14 +159,14 @@ namespace WebCore { struct CrossThreadResourceResponseData : public CrossThreadResourceResponseDataBase { long long m_appCacheID; KURL m_appCacheManifestURL; - bool m_isContentFiltered; bool m_isMultipartPayload; bool m_wasFetchedViaSPDY; bool m_wasNpnNegotiated; bool m_wasAlternateProtocolAvailable; bool m_wasFetchedViaProxy; double m_responseTime; - String m_socketAddress; + String m_remoteIPAddress; + unsigned short m_remotePort; String m_downloadFilePath; }; diff --git a/Source/WebCore/platform/network/curl/CookieJarCurl.cpp b/Source/WebCore/platform/network/curl/CookieJarCurl.cpp index 36495d0..57102a7 100644 --- a/Source/WebCore/platform/network/curl/CookieJarCurl.cpp +++ b/Source/WebCore/platform/network/curl/CookieJarCurl.cpp @@ -68,4 +68,19 @@ void setCookieStoragePrivateBrowsingEnabled(bool enabled) } #endif +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/wince/FileChooserWinCE.cpp b/Source/WebCore/platform/network/curl/DownloadBundle.h index 955e68a..cf90908 100644 --- a/Source/WebCore/platform/wince/FileChooserWinCE.cpp +++ b/Source/WebCore/platform/network/curl/DownloadBundle.h @@ -1,6 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. + * Copyright (C) 2011 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,37 +23,21 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" -#include "FileChooser.h" +#ifndef DownloadBundle_h +#define DownloadBundle_h -#include "Chrome.h" -#include "ChromeClient.h" -#include "Document.h" -#include "Frame.h" -#include "Icon.h" -#include "LocalizedStrings.h" -#include "Page.h" -#include "StringTruncator.h" +#include <wtf/Forward.h> -namespace WebCore { - -String pathGetFileName(const String& path); - -String FileChooser::basenameForWidth(const Font& font, int width) const -{ - if (width <= 0) - return String(); +typedef const struct __CFData* CFDataRef; - String string; - if (m_filenames.isEmpty()) - string = fileButtonNoFileSelectedLabel(); - else if (m_filenames.size() == 1) { - String tmpFilename = m_filenames[0]; - string = pathGetFileName(tmpFilename); - } else - return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font, false); +namespace WebCore { +namespace DownloadBundle { - return StringTruncator::centerTruncate(string, width, font, false); -} +bool appendResumeData(CFDataRef resumeData, const String& bundlePath); +CFDataRef extractResumeData(const String& bundlePath); +const String& fileExtension(); +} // namespace DownloadBundle } // namespace WebCore + +#endif // DownloadBundle_h diff --git a/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp b/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp index f360f86..1d276aa 100644 --- a/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp +++ b/Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp @@ -34,7 +34,7 @@ #include "ResourceHandleManager.h" #include "SharedBuffer.h" -#if PLATFORM(WIN) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CF) #include <wtf/PassRefPtr.h> #include <wtf/RetainPtr.h> #endif @@ -124,7 +124,7 @@ bool ResourceHandle::supportsBufferedData() return false; } -#if PLATFORM(WIN) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CF) static HashSet<String>& allowsAnyHTTPSCertificateHosts() { static HashSet<String> hosts; @@ -138,7 +138,7 @@ void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host) } #endif -#if PLATFORM(WIN) && PLATFORM(CF) +#if PLATFORM(WIN) && USE(CF) // FIXME: The CFDataRef will need to be something else when // building without static HashMap<String, RetainPtr<CFDataRef> >& clientCerts() diff --git a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp index 2e4259c..f0fd403 100644 --- a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp +++ b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp @@ -44,7 +44,7 @@ #include <errno.h> #include <stdio.h> -#if PLATFORM(CF) +#if USE(CF) #include <wtf/RetainPtr.h> #endif #include <wtf/Threading.h> @@ -66,7 +66,7 @@ static const bool ignoreSSLErrors = getenv("WEBKIT_IGNORE_SSL_ERRORS"); static CString certificatePath() { -#if PLATFORM(CF) +#if USE(CF) CFBundleRef webKitBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebKit")); if (webKitBundle) { RetainPtr<CFURLRef> certURLRef(AdoptCF, CFBundleCopyResourceURL(webKitBundle, CFSTR("cacert"), CFSTR("pem"), CFSTR("certificates"))); diff --git a/Source/WebCore/platform/network/mac/AuthenticationMac.mm b/Source/WebCore/platform/network/mac/AuthenticationMac.mm index a187187..efa42d9 100644 --- a/Source/WebCore/platform/network/mac/AuthenticationMac.mm +++ b/Source/WebCore/platform/network/mac/AuthenticationMac.mm @@ -31,7 +31,6 @@ #import "AuthenticationClient.h" #import "Credential.h" #import "ProtectionSpace.h" -#import <wtf/UnusedParam.h> #import <Foundation/NSURLAuthenticationChallenge.h> #import <Foundation/NSURLCredential.h> @@ -87,20 +86,6 @@ using namespace WebCore; m_client->receivedCancellation(core(challenge)); } -- (void)performDefaultHandlingForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge -{ - // FIXME: <rdar://problem/8995483> Determine what, if anything, we should do here. - ASSERT_NOT_REACHED(); - UNUSED_PARAM(challenge); -} - -- (void)rejectProtectionSpaceAndContinueWithChallenge:(NSURLAuthenticationChallenge *)challenge -{ - // FIXME: <rdar://problem/8995483> Determine what, if anything, we should do here. - ASSERT_NOT_REACHED(); - UNUSED_PARAM(challenge); -} - @end namespace WebCore { diff --git a/Source/WebCore/platform/network/mac/CookieStorageMac.mm b/Source/WebCore/platform/network/mac/CookieStorageMac.mm index ab26f7b..db64aae 100644 --- a/Source/WebCore/platform/network/mac/CookieStorageMac.mm +++ b/Source/WebCore/platform/network/mac/CookieStorageMac.mm @@ -26,13 +26,98 @@ #include "config.h" #include "CookieStorage.h" +#import "ResourceHandle.h" #import "WebCoreSystemInterface.h" +#import <wtf/RetainPtr.h> +#import <wtf/UnusedParam.h> + +#if USE(PLATFORM_STRATEGIES) +#include "CookiesStrategy.h" +#include "PlatformStrategies.h" +#endif + +using namespace WebCore; + +@interface CookieStorageObjCAdapter : NSObject +-(void)notifyCookiesChangedOnMainThread; +-(void)cookiesChangedNotificationHandler:(NSNotification *)notification; +-(void)startListeningForCookieChangeNotifications; +-(void)stopListeningForCookieChangeNotifications; +@end + +@implementation CookieStorageObjCAdapter + +-(void)notifyCookiesChangedOnMainThread +{ +#if USE(PLATFORM_STRATEGIES) + platformStrategies()->cookiesStrategy()->notifyCookiesChanged(); +#endif +} + +-(void)cookiesChangedNotificationHandler:(NSNotification *)notification +{ + UNUSED_PARAM(notification); + + [self performSelectorOnMainThread:@selector(notifyCookiesChangedOnMainThread) withObject:nil waitUntilDone:FALSE]; +} + +-(void)startListeningForCookieChangeNotifications +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cookiesChangedNotificationHandler:) name:NSHTTPCookieManagerCookiesChangedNotification object:[NSHTTPCookieStorage sharedHTTPCookieStorage]]; +} + +-(void)stopListeningForCookieChangeNotifications +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:NSHTTPCookieManagerCookiesChangedNotification object:nil]; +} + +@end namespace WebCore { +#if USE(CFURLSTORAGESESSIONS) + +RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage() +{ + DEFINE_STATIC_LOCAL(RetainPtr<CFHTTPCookieStorageRef>, cookieStorage, ()); + return cookieStorage; +} + +#endif + void setCookieStoragePrivateBrowsingEnabled(bool enabled) { +#if USE(CFURLSTORAGESESSIONS) + if (enabled && privateBrowsingCookieStorage()) + return; + + if (enabled && ResourceHandle::privateBrowsingStorageSession()) { + privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(ResourceHandle::privateBrowsingStorageSession())); + + // FIXME: When Private Browsing is enabled, the Private Browsing Cookie Storage should be + // observed for changes, not the default Cookie Storage. + + return; + } + + privateBrowsingCookieStorage() = nullptr; +#endif wkSetCookieStoragePrivateBrowsingEnabled(enabled); } +static CookieStorageObjCAdapter *cookieStorageAdapter; + +void startObservingCookieChanges() +{ + if (!cookieStorageAdapter) + cookieStorageAdapter = [[CookieStorageObjCAdapter alloc] init]; + [cookieStorageAdapter startListeningForCookieChangeNotifications]; +} + +void stopObservingCookieChanges() +{ + ASSERT(cookieStorageAdapter); + [cookieStorageAdapter stopListeningForCookieChangeNotifications]; +} + } diff --git a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm index 2d687c0..96d561d 100644 --- a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm +++ b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm @@ -33,6 +33,7 @@ #import "Base64.h" #import "BlobRegistry.h" #import "BlockExceptions.h" +#import "CookieStorage.h" #import "CredentialStorage.h" #import "CachedResourceLoader.h" #import "EmptyProtocolDefinitions.h" @@ -186,6 +187,35 @@ bool ResourceHandle::didSendBodyDataDelegateExists() return NSFoundationVersionNumber > MaxFoundationVersionWithoutdidSendBodyDataDelegate; } +static bool shouldRelaxThirdPartyCookiePolicy(const KURL& url) +{ + // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. + + NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; + + NSHTTPCookieAcceptPolicy cookieAcceptPolicy; +#if USE(CFURLSTORAGESESSIONS) + CFHTTPCookieStorageRef cfPrivateBrowsingStorage = privateBrowsingCookieStorage().get(); + if (cfPrivateBrowsingStorage) + cookieAcceptPolicy = wkGetHTTPCookieAcceptPolicy(cfPrivateBrowsingStorage); + else +#endif + cookieAcceptPolicy = [sharedStorage cookieAcceptPolicy]; + + if (cookieAcceptPolicy != NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain) + return false; + + NSArray *cookies; +#if USE(CFURLSTORAGESESSIONS) + if (cfPrivateBrowsingStorage) + cookies = wkHTTPCookiesForURL(cfPrivateBrowsingStorage, url); + else +#endif + cookies = [sharedStorage cookiesForURL:url]; + + return [cookies count]; +} + void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredentialStorage, bool shouldContentSniff) { // Credentials for ftp can only be passed in URL, the connection:didReceiveAuthenticationChallenge: delegate call won't be made. @@ -200,9 +230,7 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential firstRequest().setURL(urlWithCredentials); } - // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. - NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain && [[sharedStorage cookiesForURL:firstRequest().url()] count]) + if (shouldRelaxThirdPartyCookiePolicy(firstRequest().url())) firstRequest().setFirstPartyForCookies(firstRequest().url()); #if !defined(BUILDING_ON_TIGER) @@ -239,6 +267,11 @@ void ResourceHandle::createNSURLConnection(id delegate, bool shouldUseCredential static bool supportsSettingConnectionProperties = [NSURLConnection instancesRespondToSelector:@selector(_initWithRequest:delegate:usesCache:maxContentLength:startImmediately:connectionProperties:)]; #endif +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = privateBrowsingStorageSession()) + nsRequest = [wkCopyRequestWithStorageSession(storageSession, nsRequest) autorelease]; +#endif + if (supportsSettingConnectionProperties) { NSDictionary *sessionID = shouldUseCredentialStorage ? [NSDictionary dictionary] : [NSDictionary dictionaryWithObject:@"WebKitPrivateSession" forKey:@"_kCFURLConnectionSessionID"]; NSDictionary *propertyDictionary = [NSDictionary dictionaryWithObject:sessionID forKey:@"kCFURLConnectionSocketStreamProperties"]; @@ -506,9 +539,7 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const UNUSED_PARAM(context); NSURLRequest *firstRequest = request.nsURLRequest(); - // If a URL already has cookies, then we'll relax the 3rd party cookie policy and accept new cookies. - NSHTTPCookieStorage *sharedStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; - if ([sharedStorage cookieAcceptPolicy] == NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain && [[sharedStorage cookiesForURL:[firstRequest URL]] count]) { + if (shouldRelaxThirdPartyCookiePolicy([firstRequest URL])) { NSMutableURLRequest *mutableRequest = [[firstRequest mutableCopy] autorelease]; [mutableRequest setMainDocumentURL:[mutableRequest URL]]; firstRequest = mutableRequest; @@ -552,6 +583,11 @@ void ResourceHandle::willSendRequest(ResourceRequest& request, const ResourceRes if (!protocolHostAndPortAreEqual(request.url(), redirectResponse.url())) request.clearHTTPAuthorization(); +#if USE(CFURLSTORAGESESSIONS) + if (CFURLStorageSessionRef storageSession = privateBrowsingStorageSession()) + request.setStorageSession(storageSession); +#endif + client()->willSendRequest(this, request, redirectResponse); } @@ -693,6 +729,20 @@ void ResourceHandle::receivedCancellation(const AuthenticationChallenge& challen client()->receivedCancellation(this, challenge); } +#if USE(CFURLSTORAGESESSIONS) + +RetainPtr<CFURLStorageSessionRef> ResourceHandle::createPrivateBrowsingStorageSession(CFStringRef identifier) +{ + return RetainPtr<CFURLStorageSessionRef>(AdoptCF, wkCreatePrivateStorageSession(identifier)); +} + +String ResourceHandle::privateBrowsingStorageSessionIdentifierDefaultBase() +{ + return String([[NSBundle mainBundle] bundleIdentifier]); +} + +#endif + } // namespace WebCore @implementation WebCoreResourceHandleAsDelegate diff --git a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm index 640d237..8446782 100644 --- a/Source/WebCore/platform/network/mac/ResourceRequestMac.mm +++ b/Source/WebCore/platform/network/mac/ResourceRequestMac.mm @@ -40,11 +40,12 @@ typedef unsigned NSUInteger; #endif -@interface NSURLRequest (WebCoreContentDispositionEncoding) +@interface NSURLRequest (WebNSURLRequestDetails) - (NSArray *)contentDispositionEncodingFallbackArray; ++ (void)setDefaultTimeoutInterval:(NSTimeInterval)seconds; @end -@interface NSMutableURLRequest (WebCoreContentDispositionEncoding) +@interface NSMutableURLRequest (WebMutableNSURLRequestDetails) - (void)setContentDispositionEncodingFallbackArray:(NSArray *)theEncodingFallbackArray; @end @@ -126,8 +127,12 @@ void ResourceRequest::doUpdatePlatformRequest() #endif [nsRequest setCachePolicy:(NSURLRequestCachePolicy)cachePolicy()]; - if (timeoutInterval() != unspecifiedTimeoutInterval) - [nsRequest setTimeoutInterval:timeoutInterval()]; + + double timeoutInterval = ResourceRequestBase::timeoutInterval(); + if (timeoutInterval) + [nsRequest setTimeoutInterval:timeoutInterval]; + // Otherwise, respect NSURLRequest default timeout. + [nsRequest setMainDocumentURL:firstPartyForCookies()]; if (!httpMethod().isEmpty()) [nsRequest setHTTPMethod:httpMethod()]; @@ -169,6 +174,15 @@ void ResourceRequest::applyWebArchiveHackForMail() [NSURLProtocol setProperty:@"" forKey:@"WebDataRequest" inRequest:(NSMutableURLRequest *)nsURLRequest()]; } +#if USE(CFURLSTORAGESESSIONS) + +void ResourceRequest::setStorageSession(CFURLStorageSessionRef storageSession) +{ + m_nsRequest = wkCopyRequestWithStorageSession(storageSession, m_nsRequest.get()); +} + +#endif + } // namespace WebCore #endif // !USE(CFNETWORK) diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 98fd68d..61fe96c 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -23,7 +23,6 @@ #include "HTTPParsers.h" #include "MIMETypeRegistry.h" -#include "QtNAMThreadSafeProxy.h" #include "ResourceHandle.h" #include "ResourceHandleClient.h" #include "ResourceHandleInternal.h" @@ -47,19 +46,22 @@ // It is fixed in Qt 4.6.3. See https://bugs.webkit.org/show_bug.cgi?id=32113 // and https://bugs.webkit.org/show_bug.cgi?id=36755 #if QT_VERSION > QT_VERSION_CHECK(4, 6, 2) -#define SIGNAL_CONN Qt::AutoConnection +#define SIGNAL_CONN Qt::DirectConnection #else #define SIGNAL_CONN Qt::QueuedConnection #endif +// In Qt 4.8, the attribute for sending a request synchronously will be made public, +// for now, use this hackish solution for setting the internal attribute. +const QNetworkRequest::Attribute gSynchronousNetworkRequestAttribute = static_cast<QNetworkRequest::Attribute>(QNetworkRequest::HttpPipeliningWasUsedAttribute + 7); + static const int gMaxRecursionLimit = 10; namespace WebCore { // Take a deep copy of the FormDataElement -FormDataIODevice::FormDataIODevice(FormData* data, QObject* parent) - : QIODevice(parent) - , m_formElements(data ? data->elements() : Vector<FormDataElement>()) +FormDataIODevice::FormDataIODevice(FormData* data) + : m_formElements(data ? data->elements() : Vector<FormDataElement>()) , m_currentFile(0) , m_currentDelta(0) , m_fileSize(0) @@ -194,9 +196,6 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load , m_shouldForwardData(false) , m_redirectionTries(gMaxRecursionLimit) { - // Make this a direct function call once we require 4.6.1+. - connect(this, SIGNAL(processQueuedItems()), this, SLOT(sendQueuedItems()), SIGNAL_CONN); - const ResourceRequest &r = m_resourceHandle->firstRequest(); if (r.httpMethod() == "GET") @@ -223,14 +222,14 @@ QNetworkReplyHandler::QNetworkReplyHandler(ResourceHandle* handle, LoadMode load m_request = r.toNetworkRequest(originatingObject); - if (m_loadMode == LoadNormal) + if (m_loadMode == LoadSynchronously) + m_request.setAttribute(gSynchronousNetworkRequestAttribute, true); + + if (m_loadMode == LoadNormal || m_loadMode == LoadSynchronously) start(); -} -QNetworkReplyHandler::~QNetworkReplyHandler() -{ - if (m_reply) - m_reply->deleteLater(); + if (m_loadMode == LoadSynchronously) + m_loadMode = LoadNormal; } void QNetworkReplyHandler::setLoadMode(LoadMode mode) @@ -242,20 +241,9 @@ void QNetworkReplyHandler::setLoadMode(LoadMode mode) case LoadNormal: m_loadMode = LoadResuming; emit processQueuedItems(); - - // sendQueuedItems() may cause m_reply to be set to 0 due to the finish() call causing - // the ResourceHandle instance that owns this QNetworkReplyHandler to be destroyed. - if (m_reply) { - // Restart forwarding only after processQueuedItems to make sure - // our buffered data was handled before any incoming data. - m_reply->setForwardingDefered(false); - } break; case LoadDeferred: - if (m_reply) { - m_loadMode = LoadDeferred; - m_reply->setForwardingDefered(true); - } + m_loadMode = LoadDeferred; break; case LoadResuming: Q_ASSERT(0); // should never happen @@ -267,30 +255,31 @@ void QNetworkReplyHandler::abort() { m_resourceHandle = 0; if (m_reply) { - QtNetworkReplyThreadSafeProxy* reply = release(); + QNetworkReply* reply = release(); reply->abort(); reply->deleteLater(); } deleteLater(); } -QtNetworkReplyThreadSafeProxy* QNetworkReplyHandler::release() +QNetworkReply* QNetworkReplyHandler::release() { - QtNetworkReplyThreadSafeProxy* reply = m_reply; + QNetworkReply* reply = m_reply; if (m_reply) { disconnect(m_reply, 0, this, 0); // We have queued connections to the QNetworkReply. Make sure any // posted meta call events that were the result of a signal emission // don't reach the slots in our instance. QCoreApplication::removePostedEvents(this, QEvent::MetaCall); + m_reply->setParent(0); m_reply = 0; } return reply; } -static bool ignoreHttpError(QtNetworkReplyThreadSafeProxy* reply, bool receivedData) +static bool ignoreHttpError(QNetworkReply* reply, bool receivedData) { - int httpStatusCode = reply->httpStatusCode(); + int httpStatusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpStatusCode == 401 || httpStatusCode == 407) return true; @@ -326,10 +315,10 @@ void QNetworkReplyHandler::finish() client->didFinishLoading(m_resourceHandle, 0); else { QUrl url = m_reply->url(); - int httpStatusCode = m_reply->httpStatusCode(); + int httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (httpStatusCode) { - ResourceError error("HTTP", httpStatusCode, url.toString(), QString::fromAscii(m_reply->httpReasonPhrase())); + ResourceError error("HTTP", httpStatusCode, url.toString(), m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString()); client->didFail(m_resourceHandle, error); } else { ResourceError error("QtNetwork", m_reply->error(), url.toString(), m_reply->errorString()); @@ -370,7 +359,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() if (!client) return; - WTF::String contentType = m_reply->contentTypeHeader(); + WTF::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); WTF::String encoding = extractCharsetFromMediaType(contentType); WTF::String mimeType = extractMIMETypeFromMediaType(contentType); @@ -381,7 +370,7 @@ void QNetworkReplyHandler::sendResponseIfNeeded() KURL url(m_reply->url()); ResourceResponse response(url, mimeType.lower(), - m_reply->contentLengthHeader(), + m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(), encoding, String()); if (url.isLocalFile()) { @@ -390,10 +379,10 @@ void QNetworkReplyHandler::sendResponseIfNeeded() } // The status code is equal to 0 for protocols not in the HTTP family. - int statusCode = m_reply->httpStatusCode(); + int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); if (url.protocolInHTTPFamily()) { - String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->contentDispositionHeader())); + String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromAscii(m_reply->rawHeader("Content-Disposition"))); if (!suggestedFilename.isEmpty()) response.setSuggestedFilename(suggestedFilename); @@ -401,15 +390,19 @@ void QNetworkReplyHandler::sendResponseIfNeeded() response.setSuggestedFilename(url.lastPathComponent()); response.setHTTPStatusCode(statusCode); - response.setHTTPStatusText(m_reply->httpReasonPhrase().constData()); + response.setHTTPStatusText(m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray().constData()); // Add remaining headers. - foreach (const QtNetworkReplyThreadSafeProxy::RawHeaderPair& pair, m_reply->rawHeaderPairs()) { +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + foreach (const QNetworkReply::RawHeaderPair& pair, m_reply->rawHeaderPairs()) response.setHTTPHeaderField(QString::fromAscii(pair.first), QString::fromAscii(pair.second)); - } +#else + foreach (const QByteArray& headerName, m_reply->rawHeaderList()) + response.setHTTPHeaderField(QString::fromAscii(headerName), QString::fromAscii(m_reply->rawHeader(headerName))); +#endif } - QUrl redirection = m_reply->redirectionTarget(); + QUrl redirection = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); if (redirection.isValid()) { QUrl newUrl = m_reply->url().resolved(redirection); @@ -454,15 +447,13 @@ void QNetworkReplyHandler::sendResponseIfNeeded() client->didReceiveResponse(m_resourceHandle, response); } -void QNetworkReplyHandler::forwardData(const QByteArray &data) +void QNetworkReplyHandler::forwardData() { m_shouldForwardData = (m_loadMode != LoadNormal); - if (m_shouldForwardData) { - m_bufferedData += data; + if (m_shouldForwardData) return; - } - if (!data.isEmpty()) + if (m_reply->bytesAvailable()) m_responseContainsData = true; sendResponseIfNeeded(); @@ -474,6 +465,8 @@ void QNetworkReplyHandler::forwardData(const QByteArray &data) if (!m_resourceHandle) return; + QByteArray data = m_reply->read(m_reply->bytesAvailable()); + ResourceHandleClient* client = m_resourceHandle->client(); if (!client) return; @@ -516,53 +509,41 @@ void QNetworkReplyHandler::start() && (!url.toLocalFile().isEmpty() || url.scheme() == QLatin1String("data"))) m_method = QNetworkAccessManager::GetOperation; - m_reply = new QtNetworkReplyThreadSafeProxy(manager); - connect(m_reply, SIGNAL(finished()), this, SLOT(finish()), SIGNAL_CONN); - - // For http(s) we know that the headers are complete upon metaDataChanged() emission, so we - // can send the response as early as possible - if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) - connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(sendResponseIfNeeded()), SIGNAL_CONN); - - connect(m_reply, SIGNAL(dataReceived(const QByteArray&)), this, SLOT(forwardData(const QByteArray&)), SIGNAL_CONN); - - if (m_resourceHandle->firstRequest().reportUploadProgress()) - connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(uploadProgress(qint64, qint64)), SIGNAL_CONN); - switch (m_method) { case QNetworkAccessManager::GetOperation: - m_reply->get(m_request); + m_reply = manager->get(m_request); break; case QNetworkAccessManager::PostOperation: { - FormDataIODevice* postDevice = new FormDataIODevice(d->m_firstRequest.httpBody(), this); + FormDataIODevice* postDevice = new FormDataIODevice(d->m_firstRequest.httpBody()); // We may be uploading files so prevent QNR from buffering data m_request.setHeader(QNetworkRequest::ContentLengthHeader, postDevice->getFormDataSize()); m_request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, QVariant(true)); - m_reply->post(m_request, postDevice); + m_reply = manager->post(m_request, postDevice); + postDevice->setParent(m_reply); break; } case QNetworkAccessManager::HeadOperation: - m_reply->head(m_request); + m_reply = manager->head(m_request); break; case QNetworkAccessManager::PutOperation: { - FormDataIODevice* putDevice = new FormDataIODevice(d->m_firstRequest.httpBody(), this); + FormDataIODevice* putDevice = new FormDataIODevice(d->m_firstRequest.httpBody()); // We may be uploading files so prevent QNR from buffering data m_request.setHeader(QNetworkRequest::ContentLengthHeader, putDevice->getFormDataSize()); m_request.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, QVariant(true)); - m_reply->put(m_request, putDevice); + m_reply = manager->put(m_request, putDevice); + putDevice->setParent(m_reply); break; } case QNetworkAccessManager::DeleteOperation: { - m_reply->deleteResource(m_request); + m_reply = manager->deleteResource(m_request); break; } #if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) case QNetworkAccessManager::CustomOperation: - m_reply->sendCustomRequest(m_request, m_resourceHandle->firstRequest().httpMethod().latin1().data()); + m_reply = manager->sendCustomRequest(m_request, m_resourceHandle->firstRequest().httpMethod().latin1().data()); break; #endif case QNetworkAccessManager::UnknownOperation: { - m_reply->deleteLater(); m_reply = 0; ResourceHandleClient* client = m_resourceHandle->client(); if (client) { @@ -574,6 +555,34 @@ void QNetworkReplyHandler::start() return; } } + + m_reply->setParent(this); + + if (m_loadMode == LoadSynchronously && m_reply->isFinished()) { + // If supported, a synchronous request will be finished at this point, no need to hook up the signals. + return; + } + + connect(m_reply, SIGNAL(finished()), + this, SLOT(finish()), SIGNAL_CONN); + + // For http(s) we know that the headers are complete upon metaDataChanged() emission, so we + // can send the response as early as possible + if (scheme == QLatin1String("http") || scheme == QLatin1String("https")) + connect(m_reply, SIGNAL(metaDataChanged()), + this, SLOT(sendResponseIfNeeded()), SIGNAL_CONN); + + connect(m_reply, SIGNAL(readyRead()), + this, SLOT(forwardData()), SIGNAL_CONN); + + if (m_resourceHandle->firstRequest().reportUploadProgress()) { + connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)), + this, SLOT(uploadProgress(qint64, qint64)), SIGNAL_CONN); + } + + // Make this a direct function call once we require 4.6.1+. + connect(this, SIGNAL(processQueuedItems()), + this, SLOT(sendQueuedItems()), SIGNAL_CONN); } void QNetworkReplyHandler::resetState() @@ -599,10 +608,8 @@ void QNetworkReplyHandler::sendQueuedItems() if (m_shouldSendResponse) sendResponseIfNeeded(); - if (m_shouldForwardData) { - forwardData(m_bufferedData); - m_bufferedData.clear(); - } + if (m_shouldForwardData) + forwardData(); if (m_shouldFinish) finish(); diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h index 11638b3..8c9bd08 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h @@ -23,7 +23,6 @@ #include <QNetworkRequest> #include <QNetworkAccessManager> -#include <QNetworkReply> #include "FormData.h" @@ -35,7 +34,6 @@ QT_END_NAMESPACE namespace WebCore { class ResourceHandle; -class QtNetworkReplyThreadSafeProxy; class QNetworkReplyHandler : public QObject { @@ -44,24 +42,26 @@ public: enum LoadMode { LoadNormal, LoadDeferred, - LoadResuming + LoadResuming, + LoadSynchronously }; QNetworkReplyHandler(ResourceHandle *handle, LoadMode); - ~QNetworkReplyHandler(); void setLoadMode(LoadMode); + QNetworkReply* reply() const { return m_reply; } + void abort(); - QtNetworkReplyThreadSafeProxy* release(); + QNetworkReply* release(); signals: void processQueuedItems(); -private slots: +public slots: void finish(); void sendResponseIfNeeded(); - void forwardData(const QByteArray &data); + void forwardData(); void sendQueuedItems(); void uploadProgress(qint64 bytesSent, qint64 bytesTotal); @@ -70,7 +70,7 @@ private: void resetState(); String httpMethod() const; - QtNetworkReplyThreadSafeProxy* m_reply; + QNetworkReply* m_reply; ResourceHandle* m_resourceHandle; bool m_redirected; bool m_responseSent; @@ -85,7 +85,6 @@ private: bool m_shouldSendResponse; bool m_shouldForwardData; int m_redirectionTries; - QByteArray m_bufferedData; }; // Self destructing QIODevice for FormData @@ -96,7 +95,7 @@ private: class FormDataIODevice : public QIODevice { Q_OBJECT public: - FormDataIODevice(FormData*, QObject* parent = 0); + FormDataIODevice(FormData*); ~FormDataIODevice(); bool isSequential() const; diff --git a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp deleted file mode 100644 index a98b4f4..0000000 --- a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.cpp +++ /dev/null @@ -1,210 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - - 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 "QtNAMThreadSafeProxy.h" - -#include "Assertions.h" -#include <QAbstractNetworkCache> -#include <QNetworkAccessManager> -#include <QNetworkCookieJar> -#include <QStringList> - -namespace WebCore { - -QtNAMThreadSafeProxy::QtNAMThreadSafeProxy(QNetworkAccessManager *manager) - : m_manager(manager) -{ - moveToThread(manager->thread()); - - connect(this, SIGNAL(localSetCookiesRequested(const QUrl&, const QString&)), SLOT(localSetCookies(const QUrl&, const QString&))); - 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*))); - connect(this, SIGNAL(hasCookieJarRequested(bool*, bool*)), SLOT(hasCookieJar(bool*, bool*))); -} - -bool QtNAMThreadSafeProxy::hasCookieJar() -{ - bool result; - bool done = false; - emit hasCookieJarRequested(&done, &result); - QMutexLocker lock(&m_resultMutex); - while (!done) - m_resultWaitCondition.wait(&m_resultMutex); - return result; -} - -void QtNAMThreadSafeProxy::localSetCookies(const QUrl& url, const QString& cookies) -{ - QList<QNetworkCookie> cookieList = QNetworkCookie::parseCookies(cookies.toAscii()); - QList<QNetworkCookie>::Iterator it = cookieList.begin(); - while (it != cookieList.end()) { - if (it->isHttpOnly()) - it = cookieList.erase(it); - else - ++it; - } - m_manager->cookieJar()->setCookiesFromUrl(cookieList, url); -} - -void QtNAMThreadSafeProxy::localCookiesForUrl(const QUrl& url, bool* done, QList<QNetworkCookie>* result) -{ - QMutexLocker lock(&m_resultMutex); - *result = m_manager->cookieJar()->cookiesForUrl(url); - *done = true; - m_resultWaitCondition.wakeAll(); -} - -void QtNAMThreadSafeProxy::localWillLoadFromCache(const QUrl& url, bool* done, bool* result) -{ - QMutexLocker lock(&m_resultMutex); - if (m_manager->cache()) - *result = m_manager->cache()->metaData(url).isValid(); - else - *result = false; - *done = true; - m_resultWaitCondition.wakeAll(); -} - -void QtNAMThreadSafeProxy::hasCookieJar(bool* done, bool* result) -{ - QMutexLocker lock(&m_resultMutex); - *result = !!m_manager->cookieJar(); - *done = true; - m_resultWaitCondition.wakeAll(); -} - -QtNetworkReplyThreadSafeProxy::QtNetworkReplyThreadSafeProxy(QNetworkAccessManager *manager) - : m_manager(manager) - , m_reply(0) - , m_forwardingDefered(false) - , m_contentLengthHeader(0) - , m_error(QNetworkReply::NoError) - , m_httpStatusCode(0) -{ - moveToThread(manager->thread()); - - // This might be unnecessarily heavy to do for each request while we could have the same wrapper for the manager instead - connect(this, SIGNAL(localGetRequested(const QNetworkRequest&)), SLOT(localGet(const QNetworkRequest&))); - connect(this, SIGNAL(localPostRequested(const QNetworkRequest&, QIODevice*)), SLOT(localPost(const QNetworkRequest&, QIODevice*))); - connect(this, SIGNAL(localHeadRequested(const QNetworkRequest&)), SLOT(localHead(const QNetworkRequest&))); - connect(this, SIGNAL(localPutRequested(const QNetworkRequest&, QIODevice*)), SLOT(localPut(const QNetworkRequest&, QIODevice*))); - connect(this, SIGNAL(localDeleteResourceRequested(const QNetworkRequest&)), SLOT(localDeleteResource(const QNetworkRequest&))); - connect(this, SIGNAL(localCustomRequestRequested(const QNetworkRequest&, const QByteArray&)), SLOT(localCustomRequest(const QNetworkRequest&, const QByteArray&))); - connect(this, SIGNAL(localAbortRequested()), SLOT(localAbort())); - connect(this, SIGNAL(localSetForwardingDeferedRequested(bool)), SLOT(localSetForwardingDefered(bool))); -} - -QtNetworkReplyThreadSafeProxy::~QtNetworkReplyThreadSafeProxy() -{ - delete m_reply; -} - -void QtNetworkReplyThreadSafeProxy::localGet(const QNetworkRequest& request) -{ - localSetReply(m_manager->get(request)); -} - -void QtNetworkReplyThreadSafeProxy::localPost(const QNetworkRequest& request, QIODevice* data) -{ - localSetReply(m_manager->post(request, data)); -} - -void QtNetworkReplyThreadSafeProxy::localHead(const QNetworkRequest& request) -{ - localSetReply(m_manager->head(request)); -} - -void QtNetworkReplyThreadSafeProxy::localPut(const QNetworkRequest& request, QIODevice* data) -{ - localSetReply(m_manager->put(request, data)); -} - -void QtNetworkReplyThreadSafeProxy::localDeleteResource(const QNetworkRequest& request) -{ - localSetReply(m_manager->deleteResource(request)); -} - -void QtNetworkReplyThreadSafeProxy::localCustomRequest(const QNetworkRequest& request, const QByteArray& verb) -{ -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - localSetReply(m_manager->sendCustomRequest(request, verb)); -#endif -} - -void QtNetworkReplyThreadSafeProxy::localAbort() -{ - if (m_reply) - m_reply->abort(); -} - -void QtNetworkReplyThreadSafeProxy::localForwardData() -{ - if (m_reply->bytesAvailable()) { - QByteArray data = m_reply->read(m_reply->bytesAvailable()); - emit dataReceived(data); - } -} - -void QtNetworkReplyThreadSafeProxy::localSetForwardingDefered(bool forwardingDefered) -{ - if (m_forwardingDefered && !forwardingDefered) - localForwardData(); - m_forwardingDefered = forwardingDefered; -} - -void QtNetworkReplyThreadSafeProxy::localMirrorMembers() -{ - ASSERT(m_reply); - QMutexLocker lock(&m_mirroredMembersMutex); - - m_contentDispositionHeader = m_reply->rawHeader("Content-Disposition"); - m_contentLengthHeader = m_reply->header(QNetworkRequest::ContentLengthHeader).toLongLong(); - m_contentTypeHeader = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); - m_error = m_reply->error(); - m_errorString = m_reply->errorString(); - m_httpReasonPhrase = m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray(); - m_httpStatusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - m_url = m_reply->url(); - m_redirectionTarget = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - m_rawHeaderPairs = m_reply->rawHeaderPairs(); -#else - m_rawHeaderPairs.clear(); - foreach (const QByteArray& headerName, m_reply->rawHeaderList()) - m_rawHeaderPairs.append(RawHeaderPair(headerName, m_reply->rawHeader(headerName))); -#endif -} - -void QtNetworkReplyThreadSafeProxy::localSetReply(QNetworkReply *reply) -{ - ASSERT(!m_reply); - m_reply = reply; - m_reply->setParent(0); - connect(m_reply, SIGNAL(readyRead()), this, SLOT(localForwardData())); - // Make sure localMirrorMembers() is called before the outward signal - connect(m_reply, SIGNAL(finished()), this, SLOT(localMirrorMembers()), Qt::DirectConnection); - connect(m_reply, SIGNAL(finished()), this, SIGNAL(finished())); - // Make sure localMirrorMembers() is called before the outward signal - connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(localMirrorMembers()), Qt::DirectConnection); - connect(m_reply, SIGNAL(metaDataChanged()), this, SIGNAL(metaDataChanged())); - connect(m_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SIGNAL(uploadProgress(qint64, qint64))); -} - - -} diff --git a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h b/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h deleted file mode 100644 index 4906fe2..0000000 --- a/Source/WebCore/platform/network/qt/QtNAMThreadSafeProxy.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef QtNAMThreadSafeProxy_h -#define QtNAMThreadSafeProxy_h - -#include <QMutex> -#include <QNetworkCookie> -#include <QNetworkReply> -#include <QObject> -#include <QWaitCondition> - -QT_BEGIN_NAMESPACE -class QNetworkAccessManager; -class QNetworkRequest; -class QUrl; -QT_END_NAMESPACE - -namespace WebCore { - -class QtNAMThreadSafeProxy : public QObject { - Q_OBJECT -public: - QtNAMThreadSafeProxy(QNetworkAccessManager *manager); - - void setCookies(const QUrl& url, const QString& cookies) - { - emit localSetCookiesRequested(url, cookies); - } - - QList<QNetworkCookie> cookiesForUrl(const QUrl& url) - { - bool done = false; - QList<QNetworkCookie> result; - emit localCookiesForUrlRequested(url, &done, &result); - - QMutexLocker lock(&m_resultMutex); - while (!done) - m_resultWaitCondition.wait(&m_resultMutex); - return result; - } - - bool willLoadFromCache(const QUrl& url) - { - bool done = false; - bool result; - emit localWillLoadFromCacheRequested(url, &done, &result); - - QMutexLocker lock(&m_resultMutex); - while (!done) - m_resultWaitCondition.wait(&m_resultMutex); - return result; - } - - bool hasCookieJar(); - -signals: - void localSetCookiesRequested(const QUrl&, const QString& cookies); - void localCookiesForUrlRequested(const QUrl&, bool* done, QList<QNetworkCookie>* result); - void localWillLoadFromCacheRequested(const QUrl&, bool* done, bool* result); - void hasCookieJarRequested(bool* done, bool* result); - -private slots: - void localSetCookies(const QUrl&, const QString& cookies); - void localCookiesForUrl(const QUrl&, bool* done, QList<QNetworkCookie>* result); - void localWillLoadFromCache(const QUrl&, bool* done, bool* result); - void hasCookieJar(bool* done, bool* result); - -private: - QNetworkAccessManager* m_manager; - QMutex m_resultMutex; - QWaitCondition m_resultWaitCondition; -}; - - -class QtNetworkReplyThreadSafeProxy : public QObject { - Q_OBJECT -public: - typedef QPair<QByteArray, QByteArray> RawHeaderPair; - QtNetworkReplyThreadSafeProxy(QNetworkAccessManager *manager); - ~QtNetworkReplyThreadSafeProxy(); - void abort() - { - emit localAbortRequested(); - } - void setForwardingDefered(bool forwardingDefered) - { - emit localSetForwardingDeferedRequested(forwardingDefered); - } - - QByteArray contentDispositionHeader() { QMutexLocker lock(&m_mirroredMembersMutex); return m_contentDispositionHeader; } - qlonglong contentLengthHeader() { QMutexLocker lock(&m_mirroredMembersMutex); return m_contentLengthHeader; } - QString contentTypeHeader() { QMutexLocker lock(&m_mirroredMembersMutex); return m_contentTypeHeader; } - QNetworkReply::NetworkError error() { QMutexLocker lock(&m_mirroredMembersMutex); return m_error; } - QString errorString() { QMutexLocker lock(&m_mirroredMembersMutex); return m_errorString; } - QByteArray httpReasonPhrase() { QMutexLocker lock(&m_mirroredMembersMutex); return m_httpReasonPhrase; } - int httpStatusCode() { QMutexLocker lock(&m_mirroredMembersMutex); return m_httpStatusCode; } - QUrl url() { QMutexLocker lock(&m_mirroredMembersMutex); return m_url; } - QUrl redirectionTarget() { QMutexLocker lock(&m_mirroredMembersMutex); return m_redirectionTarget; } - QList<RawHeaderPair> rawHeaderPairs() { QMutexLocker lock(&m_mirroredMembersMutex); return m_rawHeaderPairs; } - - QNetworkReply* reply() - { - // Careful, acccessing the reply accross threads might be hazardous to your health - return m_reply; - } -public: - void get(const QNetworkRequest &request) - { - emit localGetRequested(request); - } - void post(const QNetworkRequest &request, QIODevice* data) - { - emit localPostRequested(request, data); - } - void head(const QNetworkRequest &request) - { - emit localHeadRequested(request); - } - void put(const QNetworkRequest &request, QIODevice* data) - { - emit localPutRequested(request, data); - } - void deleteResource(const QNetworkRequest &request) - { - emit localDeleteResourceRequested(request); - } -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - void sendCustomRequest(const QNetworkRequest &request, const QByteArray& verb) - { - emit localCustomRequestRequested(request, verb); - } -#endif - -signals: - void localGetRequested(const QNetworkRequest& request); - void localPostRequested(const QNetworkRequest& request, QIODevice* data); - void localHeadRequested(const QNetworkRequest& request); - void localPutRequested(const QNetworkRequest& request, QIODevice* data); - void localDeleteResourceRequested(const QNetworkRequest& request); - void localCustomRequestRequested(const QNetworkRequest& request, const QByteArray& verb); - void localAbortRequested(); - void localSetForwardingDeferedRequested(bool forwardingDefered); - - void finished(); - void readyRead(); - void metaDataChanged(); - void uploadProgress(qint64 bytesSent, qint64 bytesTotal); - void dataReceived(const QByteArray &data); - -private slots: - void localGet(const QNetworkRequest& request); - void localPost(const QNetworkRequest& request, QIODevice* data); - void localHead(const QNetworkRequest& request); - void localPut(const QNetworkRequest& request, QIODevice* data); - void localDeleteResource(const QNetworkRequest& request); - void localCustomRequest(const QNetworkRequest& request, const QByteArray& verb); - void localAbort(); - void localForwardData(); - void localSetForwardingDefered(bool forwardingDefered); - void localMirrorMembers(); - -private: - void localSetReply(QNetworkReply *reply); - - QNetworkAccessManager *m_manager; - QNetworkReply *m_reply; - bool m_forwardingDefered; - - // Mirrored members - QMutex m_mirroredMembersMutex; - QByteArray m_contentDispositionHeader; - qlonglong m_contentLengthHeader; - QString m_contentTypeHeader; - QNetworkReply::NetworkError m_error; - QString m_errorString; - QByteArray m_httpReasonPhrase; - int m_httpStatusCode; - QUrl m_url; - QUrl m_redirectionTarget; - QList<RawHeaderPair> m_rawHeaderPairs; -}; - -} - - -#endif // QtNAMThreadSafeProxy_h diff --git a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp index 56125b7..cd17660 100644 --- a/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp +++ b/Source/WebCore/platform/network/qt/ResourceHandleQt.cpp @@ -35,7 +35,6 @@ #include "Frame.h" #include "FrameNetworkingContext.h" #include "FrameLoaderClientQt.h" -#include "QtNAMThreadSafeProxy.h" #include "NotImplemented.h" #include "Page.h" #include "QNetworkReplyHandler.h" @@ -70,14 +69,18 @@ public: ResourceError resourceError() const { return m_error; } Vector<char> data() const { return m_data; } + void setReplyFinished(bool finished) { m_replyFinished = finished; } + private: ResourceResponse m_response; ResourceError m_error; Vector<char> m_data; QEventLoop m_eventLoop; + bool m_replyFinished; }; WebCoreSynchronousLoader::WebCoreSynchronousLoader() + : m_replyFinished(false) { } @@ -93,13 +96,15 @@ void WebCoreSynchronousLoader::didReceiveData(ResourceHandle*, const char* data, void WebCoreSynchronousLoader::didFinishLoading(ResourceHandle*, double) { - m_eventLoop.exit(); + if (!m_replyFinished) + m_eventLoop.exit(); } void WebCoreSynchronousLoader::didFail(ResourceHandle*, const ResourceError& error) { m_error = error; - m_eventLoop.exit(); + if (!m_replyFinished) + m_eventLoop.exit(); } void WebCoreSynchronousLoader::waitForCompletion() @@ -157,13 +162,20 @@ bool ResourceHandle::willLoadFromCache(ResourceRequest& request, Frame* frame) if (!frame) return false; + QNetworkAccessManager* manager = 0; + QAbstractNetworkCache* cache = 0; if (frame->loader()->networkingContext()) { - QNetworkAccessManager* manager = frame->loader()->networkingContext()->networkAccessManager(); - QtNAMThreadSafeProxy managerProxy(manager); - if (managerProxy.willLoadFromCache(request.url())) { - request.setCachePolicy(ReturnCacheDataDontLoad); - return true; - } + manager = frame->loader()->networkingContext()->networkAccessManager(); + cache = manager->cache(); + } + + if (!cache) + return false; + + QNetworkCacheMetaData data = cache->metaData(request.url()); + if (data.isValid()) { + request.setCachePolicy(ReturnCacheDataDontLoad); + return true; } return false; @@ -195,9 +207,17 @@ void ResourceHandle::loadResourceSynchronously(NetworkingContext* context, const d->m_firstRequest.setURL(urlWithCredentials); } d->m_context = context; - d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::LoadNormal); + d->m_job = new QNetworkReplyHandler(handle.get(), QNetworkReplyHandler::LoadSynchronously); + + QNetworkReply* reply = d->m_job->reply(); + // When using synchronous calls, we are finished when reaching this point. + if (reply->isFinished()) { + syncLoader.setReplyFinished(true); + d->m_job->forwardData(); + d->m_job->finish(); + } else + syncLoader.waitForCompletion(); - syncLoader.waitForCompletion(); error = syncLoader.resourceError(); data = syncLoader.data(); response = syncLoader.resourceResponse(); diff --git a/Source/WebCore/platform/network/soup/CookieJarSoup.cpp b/Source/WebCore/platform/network/soup/CookieJarSoup.cpp index e2c2f05..f73a616 100644 --- a/Source/WebCore/platform/network/soup/CookieJarSoup.cpp +++ b/Source/WebCore/platform/network/soup/CookieJarSoup.cpp @@ -122,4 +122,19 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp index 3b1f157..d410fa3 100644 --- a/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp +++ b/Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp @@ -171,9 +171,11 @@ static void ensureSessionIsInitialized(SoupSession* session) g_object_unref(logger); } - SoupRequester* requester = soup_requester_new(); - soup_session_add_feature(session, SOUP_SESSION_FEATURE(requester)); - g_object_unref(requester); + if (!soup_session_get_feature(session, SOUP_TYPE_REQUESTER)) { + SoupRequester* requester = soup_requester_new(); + soup_session_add_feature(session, SOUP_SESSION_FEATURE(requester)); + g_object_unref(requester); + } g_object_set(session, SOUP_SESSION_MAX_CONNS, maxConnections, @@ -362,7 +364,7 @@ static void gotChunkCallback(SoupMessage* msg, SoupBuffer* chunk, gpointer data) ASSERT(!d->m_response.isNull()); - client->didReceiveData(handle.get(), chunk->data, chunk->length, false); + client->didReceiveData(handle.get(), chunk->data, chunk->length, chunk->length); } static SoupSession* createSoupSession() @@ -453,7 +455,7 @@ static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer use // response_body->data as libsoup always creates the // SoupBuffer for the body even if the length is 0 if (!d->m_cancelled && soupMsg->response_body->length) - client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, true); + client->didReceiveData(handle.get(), soupMsg->response_body->data, soupMsg->response_body->length, soupMsg->response_body->length); } // didReceiveData above might have cancelled it @@ -473,7 +475,6 @@ static void sendRequestCallback(GObject* source, GAsyncResult* res, gpointer use d->m_inputStream = adoptGRef(in); d->m_buffer = static_cast<char*>(g_slice_alloc0(READ_BUFFER_SIZE)); - d->m_total = 0; // readCallback needs it g_object_set_data(G_OBJECT(d->m_inputStream.get()), "webkit-resource", handle.get()); @@ -698,10 +699,14 @@ void ResourceHandle::platformSetDefersLoading(bool defersLoading) if (!d->m_soupMessage) return; + SoupMessage* soupMessage = d->m_soupMessage.get(); + if (soupMessage->status_code != SOUP_STATUS_NONE) + return; + if (defersLoading) - soup_session_pause_message(defaultSession(), d->m_soupMessage.get()); + soup_session_pause_message(defaultSession(), soupMessage); else - soup_session_unpause_message(defaultSession(), d->m_soupMessage.get()); + soup_session_unpause_message(defaultSession(), soupMessage); } bool ResourceHandle::loadsBlocked() @@ -783,13 +788,12 @@ static void readCallback(GObject* source, GAsyncResult* asyncResult, gpointer da // It's mandatory to have sent a response before sending data ASSERT(!d->m_response.isNull()); - d->m_total += bytesRead; if (G_LIKELY(!convertToUTF16)) - client->didReceiveData(handle.get(), d->m_buffer, bytesRead, d->m_total); + client->didReceiveData(handle.get(), d->m_buffer, bytesRead, bytesRead); else { // We have to convert it to UTF-16 due to limitations in KURL String data = String::fromUTF8(d->m_buffer, bytesRead); - client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), 0); + client->didReceiveData(handle.get(), reinterpret_cast<const char*>(data.characters()), data.length() * sizeof(UChar), bytesRead); } // didReceiveData may cancel the load, which may release the last reference. diff --git a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp index 5016bf1..a684790 100644 --- a/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp +++ b/Source/WebCore/platform/network/soup/ResourceRequestSoup.cpp @@ -89,13 +89,14 @@ void ResourceRequest::updateFromSoupMessage(SoupMessage* soupMessage) m_httpMethod = String::fromUTF8(soupMessage->method); + m_httpHeaderFields.clear(); SoupMessageHeadersIter headersIter; const char* headerName; const char* headerValue; - soup_message_headers_iter_init(&headersIter, soupMessage->request_headers); - while (soup_message_headers_iter_next(&headersIter, &headerName, &headerValue)) + while (soup_message_headers_iter_next(&headersIter, &headerName, &headerValue)) { m_httpHeaderFields.set(String::fromUTF8(headerName), String::fromUTF8(headerValue)); + } if (soupMessage->request_body->data) m_httpBody = FormData::create(soupMessage->request_body->data, soupMessage->request_body->length); diff --git a/Source/WebCore/platform/network/win/CookieJarWin.cpp b/Source/WebCore/platform/network/win/CookieJarWin.cpp index a2afbc6..2820010 100644 --- a/Source/WebCore/platform/network/win/CookieJarWin.cpp +++ b/Source/WebCore/platform/network/win/CookieJarWin.cpp @@ -86,4 +86,19 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } diff --git a/Source/WebCore/platform/wince/TemporaryLinkStubs.cpp b/Source/WebCore/platform/network/win/CookieStorageWin.cpp index dbd62dc..c1ec33d 100644 --- a/Source/WebCore/platform/wince/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/network/win/CookieStorageWin.cpp @@ -23,8 +23,8 @@ */ #include "config.h" - #include "CookieStorage.h" + #include "NotImplemented.h" namespace WebCore { diff --git a/Source/WebCore/platform/qt/CookieJarQt.cpp b/Source/WebCore/platform/qt/CookieJarQt.cpp index e5a2dcd..db4a42a 100644 --- a/Source/WebCore/platform/qt/CookieJarQt.cpp +++ b/Source/WebCore/platform/qt/CookieJarQt.cpp @@ -34,7 +34,6 @@ #include "KURL.h" #include "NetworkingContext.h" #include "PlatformString.h" -#include "QtNAMThreadSafeProxy.h" #include "qwebframe.h" #include "qwebpage.h" #include <QNetworkAccessManager> @@ -43,8 +42,7 @@ namespace WebCore { - -static QNetworkAccessManager *networkAccessManager(const Document *document) +static QNetworkCookieJar *cookieJar(const Document *document) { if (!document) return 0; @@ -54,30 +52,38 @@ static QNetworkAccessManager *networkAccessManager(const Document *document) FrameLoader* loader = frame->loader(); if (!loader) return 0; - return loader->networkingContext()->networkAccessManager(); + QNetworkAccessManager* manager = loader->networkingContext()->networkAccessManager(); + QNetworkCookieJar* jar = manager->cookieJar(); + return jar; } void setCookies(Document* document, const KURL& url, const String& value) { - QNetworkAccessManager* manager = networkAccessManager(document); - if (!manager) + QUrl u(url); + QUrl p(document->firstPartyForCookies()); + QNetworkCookieJar* jar = cookieJar(document); + if (!jar) return; - // Create the manipulator on the heap to let it live until the - // async request is picked by the other thread's event loop. - QtNAMThreadSafeProxy* managerProxy = new QtNAMThreadSafeProxy(manager); - managerProxy->setCookies(url, value); - managerProxy->deleteLater(); + QList<QNetworkCookie> cookies = QNetworkCookie::parseCookies(QString(value).toAscii()); + QList<QNetworkCookie>::Iterator it = cookies.begin(); + while (it != cookies.end()) { + if (it->isHttpOnly()) + it = cookies.erase(it); + else + ++it; + } + jar->setCookiesFromUrl(cookies, u); } String cookies(const Document* document, const KURL& url) { - QNetworkAccessManager* manager = networkAccessManager(document); - if (!manager) + QUrl u(url); + QNetworkCookieJar* jar = cookieJar(document); + if (!jar) return String(); - QtNAMThreadSafeProxy managerProxy(manager); - QList<QNetworkCookie> cookies = managerProxy.cookiesForUrl(url); + QList<QNetworkCookie> cookies = jar->cookiesForUrl(u); if (cookies.isEmpty()) return String(); @@ -94,12 +100,12 @@ String cookies(const Document* document, const KURL& url) String cookieRequestHeaderFieldValue(const Document* document, const KURL &url) { - QNetworkAccessManager* manager = networkAccessManager(document); - if (!manager) + QUrl u(url); + QNetworkCookieJar* jar = cookieJar(document); + if (!jar) return String(); - QtNAMThreadSafeProxy managerProxy(manager); - QList<QNetworkCookie> cookies = managerProxy.cookiesForUrl(url); + QList<QNetworkCookie> cookies = jar->cookiesForUrl(u); if (cookies.isEmpty()) return String(); @@ -114,12 +120,8 @@ String cookieRequestHeaderFieldValue(const Document* document, const KURL &url) bool cookiesEnabled(const Document* document) { - QNetworkAccessManager* manager = networkAccessManager(document); - if (!manager) - return false; - - QtNAMThreadSafeProxy managerProxy(manager); - return managerProxy.hasCookieJar(); + QNetworkCookieJar* jar = cookieJar(document); + return jar; } bool getRawCookies(const Document*, const KURL&, Vector<Cookie>& rawCookies) @@ -134,6 +136,21 @@ void deleteCookie(const Document*, const KURL&, const String&) // FIXME: Not yet implemented } +void getHostnamesWithCookies(HashSet<String>& hostnames) +{ + // FIXME: Not yet implemented +} + +void deleteCookiesForHostname(const String& hostname) +{ + // FIXME: Not yet implemented +} + +void deleteAllCookies() +{ + // FIXME: Not yet implemented +} + } // vim: ts=4 sw=4 et diff --git a/Source/WebCore/platform/qt/GeolocationServiceQt.cpp b/Source/WebCore/platform/qt/GeolocationServiceQt.cpp deleted file mode 100644 index f4379b2..0000000 --- a/Source/WebCore/platform/qt/GeolocationServiceQt.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - * - * 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 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 "GeolocationServiceQt.h" - -#include "Geolocation.h" -#include "Geoposition.h" -#include "PositionError.h" -#include "PositionOptions.h" - -using namespace QtMobility; - -namespace WebCore { - -GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceQt::create; - -GeolocationService* GeolocationServiceQt::create(GeolocationServiceClient* client) -{ - return new GeolocationServiceQt(client); -} - -GeolocationServiceQt::GeolocationServiceQt(GeolocationServiceClient* client) - : GeolocationService(client) - , m_lastPosition(0) - , m_lastError(0) -{ - m_location = QGeoPositionInfoSource::createDefaultSource(this); - - if (m_location) - connect(m_location, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo))); -} - -GeolocationServiceQt::~GeolocationServiceQt() -{ - delete m_location; -} - -void GeolocationServiceQt::positionUpdated(const QGeoPositionInfo &geoPosition) -{ - if (!geoPosition.isValid()) - errorOccurred(); - - QGeoCoordinate coord = geoPosition.coordinate(); - double latitude = coord.latitude(); - double longitude = coord.longitude(); - bool providesAltitude = (geoPosition.coordinate().type() == QGeoCoordinate::Coordinate3D); - double altitude = coord.altitude(); - - double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy); - - bool providesAltitudeAccuracy = geoPosition.hasAttribute(QGeoPositionInfo::VerticalAccuracy); - double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy); - - bool providesHeading = geoPosition.hasAttribute(QGeoPositionInfo::Direction); - double heading = geoPosition.attribute(QGeoPositionInfo::Direction); - - bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed); - double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed); - - RefPtr<Coordinates> coordinates = Coordinates::create(latitude, longitude, providesAltitude, altitude, - accuracy, providesAltitudeAccuracy, altitudeAccuracy, - providesHeading, heading, providesSpeed, speed); - -#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) - m_lastPosition = Geoposition::create(coordinates.release(), geoPosition.timestamp().toMSecsSinceEpoch()); -#else - QDateTime timestamp = geoPosition.timestamp(); - m_lastPosition = Geoposition::create(coordinates.release(), (timestamp.toTime_t() * 1000.00) + timestamp.time().msec()); -#endif - positionChanged(); -} - -bool GeolocationServiceQt::startUpdating(PositionOptions*) -{ - m_lastPosition = 0; - - if (!m_location) - return false; - - // TODO: handle enableHighAccuracy() - - m_location->startUpdates(); - return true; -} - -void GeolocationServiceQt::stopUpdating() -{ - if (m_location) - m_location->stopUpdates(); -} - -} // namespace WebCore diff --git a/Source/WebCore/platform/qt/GeolocationServiceQt.h b/Source/WebCore/platform/qt/GeolocationServiceQt.h deleted file mode 100644 index 2525e47..0000000 --- a/Source/WebCore/platform/qt/GeolocationServiceQt.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) - * - * 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 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 GeolocationServiceQt_h -#define GeolocationServiceQt_h - -#include "GeolocationService.h" -#include <QGeoPositionInfoSource> -#include <wtf/RefPtr.h> - -// FIXME: Remove usage of "using namespace" in a header file. -// There is bug in qtMobility signal names are not full qualified when used with namespace -// QtMobility namespace in slots throws up error and its required to be fixed in qtmobility. -using namespace QtMobility; - -namespace WebCore { - -// This class provides a implementation of a GeolocationService for qtWebkit. -// It uses QtMobility (v1.0.0) location service to get positions -class GeolocationServiceQt : public QObject, GeolocationService { - Q_OBJECT - -public: - static GeolocationService* create(GeolocationServiceClient*); - - GeolocationServiceQt(GeolocationServiceClient*); - virtual ~GeolocationServiceQt(); - - virtual bool startUpdating(PositionOptions*); - virtual void stopUpdating(); - - virtual Geoposition* lastPosition() const { return m_lastPosition.get(); } - virtual PositionError* lastError() const { return m_lastError.get(); } - -public Q_SLOTS: - // QGeoPositionInfoSource - void positionUpdated(const QGeoPositionInfo&); - -private: - RefPtr<Geoposition> m_lastPosition; - RefPtr<PositionError> m_lastError; - - QtMobility::QGeoPositionInfoSource* m_location; -}; - -} // namespace WebCore - -#endif // GeolocationServiceQt_h diff --git a/Source/WebCore/platform/qt/PlatformTouchEventQt.cpp b/Source/WebCore/platform/qt/PlatformTouchEventQt.cpp index 338e9d4..91b6a51 100644 --- a/Source/WebCore/platform/qt/PlatformTouchEventQt.cpp +++ b/Source/WebCore/platform/qt/PlatformTouchEventQt.cpp @@ -22,6 +22,7 @@ #include "config.h" #include "PlatformTouchEvent.h" +#include <wtf/CurrentTime.h> #if ENABLE(TOUCH_EVENTS) @@ -42,6 +43,7 @@ PlatformTouchEvent::PlatformTouchEvent(QTouchEvent* event) m_altKey = (event->modifiers() & Qt::AltModifier); m_shiftKey = (event->modifiers() & Qt::ShiftModifier); m_metaKey = (event->modifiers() & Qt::MetaModifier); + m_timestamp = WTF::currentTime(); } } diff --git a/Source/WebCore/platform/qt/RenderThemeQt.cpp b/Source/WebCore/platform/qt/RenderThemeQt.cpp index d4688cf..ca8c6dd 100644 --- a/Source/WebCore/platform/qt/RenderThemeQt.cpp +++ b/Source/WebCore/platform/qt/RenderThemeQt.cpp @@ -66,6 +66,7 @@ #include <QColor> #include <QFile> #include <QLineEdit> +#include <QMacStyle> #include <QPainter> #include <QPushButton> #include <QStyleFactory> @@ -380,30 +381,35 @@ void RenderThemeQt::adjustRepaintRect(const RenderObject* o, IntRect& rect) Color RenderThemeQt::platformActiveSelectionBackgroundColor() const { QPalette pal = QApplication::palette(); + setPaletteFromPageClientIfExists(pal); return pal.brush(QPalette::Active, QPalette::Highlight).color(); } Color RenderThemeQt::platformInactiveSelectionBackgroundColor() const { QPalette pal = QApplication::palette(); + setPaletteFromPageClientIfExists(pal); return pal.brush(QPalette::Inactive, QPalette::Highlight).color(); } Color RenderThemeQt::platformActiveSelectionForegroundColor() const { QPalette pal = QApplication::palette(); + setPaletteFromPageClientIfExists(pal); return pal.brush(QPalette::Active, QPalette::HighlightedText).color(); } Color RenderThemeQt::platformInactiveSelectionForegroundColor() const { QPalette pal = QApplication::palette(); + setPaletteFromPageClientIfExists(pal); return pal.brush(QPalette::Inactive, QPalette::HighlightedText).color(); } Color RenderThemeQt::platformFocusRingColor() const { QPalette pal = QApplication::palette(); + setPaletteFromPageClientIfExists(pal); return pal.brush(QPalette::Active, QPalette::Highlight).color(); } @@ -547,9 +553,6 @@ void RenderThemeQt::adjustButtonStyle(CSSStyleSelector* selector, RenderStyle* s } #endif - // White-space is locked to pre - style->setWhiteSpace(PRE); - FontDescription fontDescription = style->fontDescription(); fontDescription.setIsAbsoluteSize(true); @@ -704,15 +707,17 @@ void RenderThemeQt::adjustMenuListStyle(CSSStyleSelector*, RenderStyle* style, E void RenderThemeQt::setPopupPadding(RenderStyle* style) const { - const int padding = 8; - style->setPaddingLeft(Length(padding, Fixed)); + const int paddingLeft = 4; + const int paddingRight = style->width().isFixed() || style->width().isPercent() ? 5 : 8; + + style->setPaddingLeft(Length(paddingLeft, Fixed)); QStyleOptionComboBox opt; int w = qStyle()->pixelMetric(QStyle::PM_ButtonIconSize, &opt, 0); - style->setPaddingRight(Length(padding + w, Fixed)); + style->setPaddingRight(Length(paddingRight + w, Fixed)); style->setPaddingTop(Length(2, Fixed)); - style->setPaddingBottom(Length(0, Fixed)); + style->setPaddingBottom(Length(2, Fixed)); } @@ -726,10 +731,20 @@ bool RenderThemeQt::paintMenuList(RenderObject* o, const PaintInfo& i, const Int initStyleOption(p.widget, opt); initializeCommonQStyleOptions(opt, o); - const QPoint topLeft = r.location(); + IntRect rect = r; + +#if defined(Q_WS_MAC) && !defined(QT_NO_STYLE_MAC) + // QMacStyle makes the combo boxes a little bit smaller to leave space for the focus rect. + // Because of it, the combo button is drawn at a point to the left of where it was expect to be and may end up + // overlapped with the text. This will force QMacStyle to draw the combo box with the expected width. + if (qobject_cast<QMacStyle*>(p.style)) + rect.inflateX(3); +#endif + + const QPoint topLeft = rect.location(); p.painter->translate(topLeft); opt.rect.moveTo(QPoint(0, 0)); - opt.rect.setSize(r.size()); + opt.rect.setSize(rect.size()); p.drawComplexControl(QStyle::CC_ComboBox, opt); p.painter->translate(-topLeft); diff --git a/Source/WebCore/platform/qt/SharedTimerQt.cpp b/Source/WebCore/platform/qt/SharedTimerQt.cpp index 8a6bd81..5075395 100644 --- a/Source/WebCore/platform/qt/SharedTimerQt.cpp +++ b/Source/WebCore/platform/qt/SharedTimerQt.cpp @@ -68,8 +68,12 @@ SharedTimerQt::SharedTimerQt() SharedTimerQt::~SharedTimerQt() { - if (m_timer.isActive()) - (m_timerFunction)(); + if (m_timer.isActive()) { + if (m_timerFunction) { + (m_timerFunction)(); + m_timerFunction = 0; + } + } } void SharedTimerQt::destroy() diff --git a/Source/WebCore/platform/qt/TemporaryLinkStubsQt.cpp b/Source/WebCore/platform/qt/TemporaryLinkStubsQt.cpp index a46b82c..12c54f2 100644 --- a/Source/WebCore/platform/qt/TemporaryLinkStubsQt.cpp +++ b/Source/WebCore/platform/qt/TemporaryLinkStubsQt.cpp @@ -128,6 +128,16 @@ void setCookieStoragePrivateBrowsingEnabled(bool) notImplemented(); } +void startObservingCookieChanges() +{ + notImplemented(); +} + +void stopObservingCookieChanges() +{ + notImplemented(); +} + } // vim: ts=4 sw=4 et diff --git a/Source/WebCore/platform/text/BidiResolver.h b/Source/WebCore/platform/text/BidiResolver.h index 72d163c..07e9274 100644 --- a/Source/WebCore/platform/text/BidiResolver.h +++ b/Source/WebCore/platform/text/BidiResolver.h @@ -126,6 +126,12 @@ struct BidiCharacterRun { BidiCharacterRun* m_next; }; +enum VisualDirectionOverride { + NoVisualOverride, + VisualLeftToRightOverride, + VisualRightToLeftOverride +}; + template <class Iterator, class Run> class BidiResolver { WTF_MAKE_NONCOPYABLE(BidiResolver); public : @@ -163,7 +169,7 @@ public : void embed(WTF::Unicode::Direction); bool commitExplicitEmbedding(); - void createBidiRunsForLine(const Iterator& end, bool visualOrder = false, bool hardLineBreak = false); + void createBidiRunsForLine(const Iterator& end, VisualDirectionOverride = NoVisualOverride, bool hardLineBreak = false); Run* firstRun() const { return m_firstRun; } Run* lastRun() const { return m_lastRun; } @@ -514,12 +520,28 @@ void BidiResolver<Iterator, Run>::reverseRuns(unsigned start, unsigned end) } template <class Iterator, class Run> -void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, bool visualOrder, bool hardLineBreak) +void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, VisualDirectionOverride override, bool hardLineBreak) { using namespace WTF::Unicode; ASSERT(m_direction == OtherNeutral); + if (override != NoVisualOverride) { + emptyRun = false; + sor = current; + eor = Iterator(); + while (current != end && !current.atEnd()) { + eor = current; + increment(); + } + m_direction = override == VisualLeftToRightOverride ? LeftToRight : RightToLeft; + appendRun(); + m_logicallyLastRun = m_lastRun; + if (override == VisualRightToLeftOverride) + reverseRuns(0, runCount() - 1); + return; + } + emptyRun = true; eor = Iterator(); @@ -916,49 +938,45 @@ void BidiResolver<Iterator, Run>::createBidiRunsForLine(const Iterator& end, boo m_logicallyLastRun = m_lastRun; // reorder line according to run structure... - // do not reverse for visually ordered web sites - if (!visualOrder) { - - // first find highest and lowest levels - unsigned char levelLow = 128; - unsigned char levelHigh = 0; - Run* r = firstRun(); - while (r) { - if (r->m_level > levelHigh) - levelHigh = r->m_level; - if (r->m_level < levelLow) - levelLow = r->m_level; - r = r->next(); - } + // first find highest and lowest levels + unsigned char levelLow = 128; + unsigned char levelHigh = 0; + Run* r = firstRun(); + while (r) { + if (r->m_level > levelHigh) + levelHigh = r->m_level; + if (r->m_level < levelLow) + levelLow = r->m_level; + r = r->next(); + } - // implements reordering of the line (L2 according to Bidi spec): - // L2. From the highest level found in the text to the lowest odd level on each line, - // reverse any contiguous sequence of characters that are at that level or higher. + // implements reordering of the line (L2 according to Bidi spec): + // L2. From the highest level found in the text to the lowest odd level on each line, + // reverse any contiguous sequence of characters that are at that level or higher. - // reversing is only done up to the lowest odd level - if (!(levelLow % 2)) - levelLow++; + // reversing is only done up to the lowest odd level + if (!(levelLow % 2)) + levelLow++; - unsigned count = runCount() - 1; + unsigned count = runCount() - 1; - while (levelHigh >= levelLow) { - unsigned i = 0; - Run* currRun = firstRun(); - while (i < count) { - while (i < count && currRun && currRun->m_level < levelHigh) { - i++; - currRun = currRun->next(); - } - unsigned start = i; - while (i <= count && currRun && currRun->m_level >= levelHigh) { - i++; - currRun = currRun->next(); - } - unsigned end = i - 1; - reverseRuns(start, end); + while (levelHigh >= levelLow) { + unsigned i = 0; + Run* currRun = firstRun(); + while (i < count) { + while (i < count && currRun && currRun->m_level < levelHigh) { + i++; + currRun = currRun->next(); + } + unsigned start = i; + while (i <= count && currRun && currRun->m_level >= levelHigh) { + i++; + currRun = currRun->next(); } - levelHigh--; + unsigned end = i - 1; + reverseRuns(start, end); } + levelHigh--; } endOfLine = Iterator(); } diff --git a/Source/WebCore/platform/text/LocalizedNumber.h b/Source/WebCore/platform/text/LocalizedNumber.h index 45873b8..d70541f 100644 --- a/Source/WebCore/platform/text/LocalizedNumber.h +++ b/Source/WebCore/platform/text/LocalizedNumber.h @@ -49,11 +49,6 @@ double parseLocalizedNumber(const String&); // return an empty string. String formatLocalizedNumber(double); -// Returns true if the input character can be used to represent a -// number in the browser locale. For example, this should return true for 0-9 . -// , + - for en-US locale. -bool isLocalizedNumberCharacter(UChar32); - } // namespace WebCore #endif // LocalizedNumber_h diff --git a/Source/WebCore/platform/text/LocalizedNumberICU.cpp b/Source/WebCore/platform/text/LocalizedNumberICU.cpp new file mode 100644 index 0000000..189151e --- /dev/null +++ b/Source/WebCore/platform/text/LocalizedNumberICU.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "LocalizedNumber.h" + +#include <limits> +#include <unicode/numfmt.h> +#include <unicode/parsepos.h> +#include <wtf/PassOwnPtr.h> + +using namespace std; + +namespace WebCore { + +static PassOwnPtr<NumberFormat> createFormatterForCurrentLocale() +{ + UErrorCode status = U_ZERO_ERROR; + OwnPtr<NumberFormat> formatter = adoptPtr(NumberFormat::createInstance(status)); + return U_SUCCESS(status) ? formatter.release() : 0; +} + +// This might return 0. +static NumberFormat* numberFormatter() +{ + ASSERT(isMainThread()); + static NumberFormat* formatter = createFormatterForCurrentLocale().leakPtr(); + return formatter; +} + +double parseLocalizedNumber(const String& numberString) +{ + if (numberString.isEmpty()) + return numeric_limits<double>::quiet_NaN(); + NumberFormat* formatter = numberFormatter(); + if (!formatter) + return numeric_limits<double>::quiet_NaN(); + UnicodeString numberUnicodeString(numberString.characters(), numberString.length()); + Formattable result; + ParsePosition position(0); + formatter->parse(numberUnicodeString, result, position); + if (position.getIndex() != numberUnicodeString.length()) + return numeric_limits<double>::quiet_NaN(); + UErrorCode status = U_ZERO_ERROR; + double numericResult = result.getDouble(status); + return U_SUCCESS(status) ? numericResult : numeric_limits<double>::quiet_NaN(); +} + +String formatLocalizedNumber(double number) +{ + NumberFormat* formatter = numberFormatter(); + if (!formatter) + return String(); + UnicodeString result; + formatter->format(number, result); + return String(result.getBuffer(), result.length()); +} + +} // namespace WebCore diff --git a/Source/WebCore/platform/text/LocalizedNumberNone.cpp b/Source/WebCore/platform/text/LocalizedNumberNone.cpp index 6f017e9..729f2f1 100644 --- a/Source/WebCore/platform/text/LocalizedNumberNone.cpp +++ b/Source/WebCore/platform/text/LocalizedNumberNone.cpp @@ -47,9 +47,4 @@ String formatLocalizedNumber(double) return String(); } -bool isLocalizedNumberCharacter(UChar32) -{ - return false; -} - } // namespace WebCore diff --git a/Source/WebCore/platform/text/SegmentedString.cpp b/Source/WebCore/platform/text/SegmentedString.cpp index 7c859dc..1515fe8 100644 --- a/Source/WebCore/platform/text/SegmentedString.cpp +++ b/Source/WebCore/platform/text/SegmentedString.cpp @@ -22,12 +22,11 @@ namespace WebCore { -SegmentedString::SegmentedString(const SegmentedString &other) +SegmentedString::SegmentedString(const SegmentedString& other) : m_pushedChar1(other.m_pushedChar1) , m_pushedChar2(other.m_pushedChar2) , m_currentString(other.m_currentString) , m_substrings(other.m_substrings) - , m_composite(other.m_composite) , m_closed(other.m_closed) { if (other.m_currentChar == &other.m_pushedChar1) @@ -38,13 +37,12 @@ SegmentedString::SegmentedString(const SegmentedString &other) m_currentChar = other.m_currentChar; } -const SegmentedString& SegmentedString::operator=(const SegmentedString &other) +const SegmentedString& SegmentedString::operator=(const SegmentedString& other) { m_pushedChar1 = other.m_pushedChar1; m_pushedChar2 = other.m_pushedChar2; m_currentString = other.m_currentString; m_substrings = other.m_substrings; - m_composite = other.m_composite; if (other.m_currentChar == &other.m_pushedChar1) m_currentChar = &m_pushedChar1; else if (other.m_currentChar == &other.m_pushedChar2) @@ -67,7 +65,7 @@ unsigned SegmentedString::length() const if (m_pushedChar2) ++length; } - if (m_composite) { + if (isComposite()) { Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); for (; it != e; ++it) @@ -79,7 +77,7 @@ unsigned SegmentedString::length() const void SegmentedString::setExcludeLineNumbers() { m_currentString.setExcludeLineNumbers(); - if (m_composite) { + if (isComposite()) { Deque<SegmentedSubstring>::iterator it = m_substrings.begin(); Deque<SegmentedSubstring>::iterator e = m_substrings.end(); for (; it != e; ++it) @@ -94,44 +92,42 @@ void SegmentedString::clear() m_currentChar = 0; m_currentString.clear(); m_substrings.clear(); - m_composite = false; m_closed = false; } -void SegmentedString::append(const SegmentedSubstring &s) +void SegmentedString::append(const SegmentedSubstring& s) { ASSERT(!m_closed); - if (s.m_length) { - if (!m_currentString.m_length) { - m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); - m_currentString = s; - } else { - m_substrings.append(s); - m_composite = true; - } - } + if (!s.m_length) + return; + + if (!m_currentString.m_length) { + m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); + m_currentString = s; + } else + m_substrings.append(s); } -void SegmentedString::prepend(const SegmentedSubstring &s) +void SegmentedString::prepend(const SegmentedSubstring& s) { ASSERT(!escaped()); ASSERT(!s.numberOfCharactersConsumed()); - if (s.m_length) { - // FIXME: We're assuming that the prepend were originally consumed by - // this SegmentedString. We're also ASSERTing that s is a fresh - // SegmentedSubstring. These assumptions are sufficient for our - // current use, but we might need to handle the more elaborate - // cases in the future. - m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); - m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length; - if (!m_currentString.m_length) - m_currentString = s; - else { - // Shift our m_currentString into our list. - m_substrings.prepend(m_currentString); - m_currentString = s; - m_composite = true; - } + if (!s.m_length) + return; + + // FIXME: We're assuming that the prepend were originally consumed by + // this SegmentedString. We're also ASSERTing that s is a fresh + // SegmentedSubstring. These assumptions are sufficient for our + // current use, but we might need to handle the more elaborate + // cases in the future. + m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); + m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length; + if (!m_currentString.m_length) + m_currentString = s; + else { + // Shift our m_currentString into our list. + m_substrings.prepend(m_currentString); + m_currentString = s; } } @@ -142,12 +138,12 @@ void SegmentedString::close() m_closed = true; } -void SegmentedString::append(const SegmentedString &s) +void SegmentedString::append(const SegmentedString& s) { ASSERT(!m_closed); ASSERT(!s.escaped()); append(s.m_currentString); - if (s.m_composite) { + if (s.isComposite()) { Deque<SegmentedSubstring>::const_iterator it = s.m_substrings.begin(); Deque<SegmentedSubstring>::const_iterator e = s.m_substrings.end(); for (; it != e; ++it) @@ -156,11 +152,11 @@ void SegmentedString::append(const SegmentedString &s) m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current; } -void SegmentedString::prepend(const SegmentedString &s) +void SegmentedString::prepend(const SegmentedString& s) { ASSERT(!escaped()); ASSERT(!s.escaped()); - if (s.m_composite) { + if (s.isComposite()) { Deque<SegmentedSubstring>::const_reverse_iterator it = s.m_substrings.rbegin(); Deque<SegmentedSubstring>::const_reverse_iterator e = s.m_substrings.rend(); for (; it != e; ++it) @@ -172,18 +168,15 @@ void SegmentedString::prepend(const SegmentedString &s) void SegmentedString::advanceSubstring() { - if (m_composite) { + if (isComposite()) { m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed(); m_currentString = m_substrings.takeFirst(); // If we've previously consumed some characters of the non-current // string, we now account for those characters as part of the current // string, not as part of "prior to current string." m_numberOfCharactersConsumedPriorToCurrentString -= m_currentString.numberOfCharactersConsumed(); - if (m_substrings.isEmpty()) - m_composite = false; - } else { + } else m_currentString.clear(); - } } String SegmentedString::toString() const @@ -195,7 +188,7 @@ String SegmentedString::toString() const result.append(m_pushedChar2); } m_currentString.appendTo(result); - if (m_composite) { + if (isComposite()) { Deque<SegmentedSubstring>::const_iterator it = m_substrings.begin(); Deque<SegmentedSubstring>::const_iterator e = m_substrings.end(); for (; it != e; ++it) diff --git a/Source/WebCore/platform/text/SegmentedString.h b/Source/WebCore/platform/text/SegmentedString.h index 3784b50..4831166 100644 --- a/Source/WebCore/platform/text/SegmentedString.h +++ b/Source/WebCore/platform/text/SegmentedString.h @@ -30,7 +30,13 @@ class SegmentedString; class SegmentedSubstring { public: - SegmentedSubstring() : m_length(0), m_current(0), m_doNotExcludeLineNumbers(true) {} + SegmentedSubstring() + : m_length(0) + , m_current(0) + , m_doNotExcludeLineNumbers(true) + { + } + SegmentedSubstring(const String& str) : m_length(str.length()) , m_current(str.isEmpty() ? 0 : str.characters()) @@ -55,9 +61,8 @@ public: str = m_string; else str.append(m_string); - } else { + } else str.append(String(m_current, m_length)); - } } public: @@ -78,7 +83,6 @@ public: , m_numberOfCharactersConsumedPriorToCurrentString(0) , m_numberOfCharactersConsumedPriorToCurrentLine(0) , m_currentLine(0) - , m_composite(false) , m_closed(false) { } @@ -91,7 +95,6 @@ public: , m_numberOfCharactersConsumedPriorToCurrentString(0) , m_numberOfCharactersConsumedPriorToCurrentLine(0) , m_currentLine(0) - , m_composite(false) , m_closed(false) { } @@ -267,6 +270,8 @@ private: return result; } + bool isComposite() const { return !m_substrings.isEmpty(); } + UChar m_pushedChar1; UChar m_pushedChar2; SegmentedSubstring m_currentString; @@ -275,7 +280,6 @@ private: int m_numberOfCharactersConsumedPriorToCurrentLine; int m_currentLine; Deque<SegmentedSubstring> m_substrings; - bool m_composite; bool m_closed; }; diff --git a/Source/WebCore/platform/text/TextBreakIterator.h b/Source/WebCore/platform/text/TextBreakIterator.h index 17cf5f0..e4cba77 100644 --- a/Source/WebCore/platform/text/TextBreakIterator.h +++ b/Source/WebCore/platform/text/TextBreakIterator.h @@ -28,7 +28,7 @@ namespace WebCore { class TextBreakIterator; - // Note: The returned iterator is good only until you get another iterator. + // Note: The returned iterator is good only until you get another iterator, with the exception of acquireLineBreakIterator. // Iterates over "extended grapheme clusters", as defined in UAX #29. // Note that platform implementations may be less sophisticated - e.g. ICU prior to @@ -43,7 +43,8 @@ namespace WebCore { TextBreakIterator* cursorMovementIterator(const UChar*, int length); TextBreakIterator* wordBreakIterator(const UChar*, int length); - TextBreakIterator* lineBreakIterator(const UChar*, int length); + TextBreakIterator* acquireLineBreakIterator(const UChar*, int length); + void releaseLineBreakIterator(TextBreakIterator*); TextBreakIterator* sentenceBreakIterator(const UChar*, int length); int textBreakFirst(TextBreakIterator*); @@ -57,6 +58,47 @@ namespace WebCore { const int TextBreakDone = -1; +class LazyLineBreakIterator { +public: + LazyLineBreakIterator(const UChar* string = 0, int length = 0) + : m_string(string) + , m_length(length) + , m_iterator(0) + { + } + + ~LazyLineBreakIterator() + { + if (m_iterator) + releaseLineBreakIterator(m_iterator); + } + + const UChar* string() const { return m_string; } + int length() const { return m_length; } + + TextBreakIterator* get() + { + if (!m_iterator) + m_iterator = acquireLineBreakIterator(m_string, m_length); + return m_iterator; + } + + void reset(const UChar* string, int length) + { + if (m_iterator) + releaseLineBreakIterator(m_iterator); + + m_string = string; + m_length = length; + m_iterator = 0; + } + +private: + const UChar* m_string; + int m_length; + TextBreakIterator* m_iterator; +}; + } #endif diff --git a/Source/WebCore/platform/text/TextBreakIteratorICU.cpp b/Source/WebCore/platform/text/TextBreakIteratorICU.cpp index f5575ee..3be2d88 100644 --- a/Source/WebCore/platform/text/TextBreakIteratorICU.cpp +++ b/Source/WebCore/platform/text/TextBreakIteratorICU.cpp @@ -27,6 +27,8 @@ #include <unicode/ubrk.h> #include <wtf/Assertions.h> +using namespace std; + namespace WebCore { static TextBreakIterator* setUpIterator(bool& createdIterator, TextBreakIterator*& iterator, @@ -68,12 +70,34 @@ TextBreakIterator* wordBreakIterator(const UChar* string, int length) staticWordBreakIterator, UBRK_WORD, string, length); } -TextBreakIterator* lineBreakIterator(const UChar* string, int length) +static bool createdLineBreakIterator = false; +static TextBreakIterator* staticLineBreakIterator; + +TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) +{ + TextBreakIterator* lineBreakIterator = 0; + if (!createdLineBreakIterator || staticLineBreakIterator) { + setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length); + swap(staticLineBreakIterator, lineBreakIterator); + } + + if (!lineBreakIterator) { + bool createdNewLineBreakIterator = false; + setUpIterator(createdNewLineBreakIterator, lineBreakIterator, UBRK_LINE, string, length); + } + + return lineBreakIterator; +} + +void releaseLineBreakIterator(TextBreakIterator* iterator) { - static bool createdLineBreakIterator = false; - static TextBreakIterator* staticLineBreakIterator; - return setUpIterator(createdLineBreakIterator, - staticLineBreakIterator, UBRK_LINE, string, length); + ASSERT(createdLineBreakIterator); + ASSERT(iterator); + + if (!staticLineBreakIterator) + staticLineBreakIterator = iterator; + else + ubrk_close(reinterpret_cast<UBreakIterator*>(iterator)); } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) diff --git a/Source/WebCore/platform/text/TextCheckerClient.h b/Source/WebCore/platform/text/TextCheckerClient.h new file mode 100644 index 0000000..acaa02c --- /dev/null +++ b/Source/WebCore/platform/text/TextCheckerClient.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY 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 TextCheckerClient_h +#define TextCheckerClient_h + +#include <wtf/Forward.h> +#include <wtf/Vector.h> +#include <wtf/text/WTFString.h> + +namespace WebCore { + +class SpellChecker; + +struct GrammarDetail { + int location; + int length; + Vector<String> guesses; + String userDescription; +}; + +enum TextCheckingType { + TextCheckingTypeSpelling = 1 << 1, + TextCheckingTypeGrammar = 1 << 2, + TextCheckingTypeLink = 1 << 5, + TextCheckingTypeQuote = 1 << 6, + TextCheckingTypeDash = 1 << 7, + TextCheckingTypeReplacement = 1 << 8, + TextCheckingTypeCorrection = 1 << 9 +}; + +struct TextCheckingResult { + TextCheckingType type; + int location; + int length; + Vector<GrammarDetail> details; + String replacement; +}; + +class TextCheckerClient { +public: + virtual ~TextCheckerClient() {} + + virtual void ignoreWordInSpellDocument(const String&) = 0; + virtual void learnWord(const String&) = 0; + virtual void checkSpellingOfString(const UChar*, int length, int* misspellingLocation, int* misspellingLength) = 0; + virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord) = 0; + virtual void checkGrammarOfString(const UChar*, int length, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0; +#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) + virtual void checkTextOfParagraph(const UChar* text, int length, uint64_t checkingTypes, Vector<TextCheckingResult>& results) = 0; +#endif + + // For spellcheckers that support multiple languages, it's often important to be able to identify the language in order to + // provide more accurate correction suggestions. Caller can pass in more text in "context" to aid such spellcheckers on language + // identification. Noramlly it's the text surrounding the "word" for which we are getting correction suggestions. + virtual void getGuessesForWord(const String& word, const String& context, Vector<String>& guesses) = 0; + virtual void requestCheckingOfString(SpellChecker*, int, const String&) = 0; +}; + +} + +#endif // TextCheckerClient_h diff --git a/Source/WebCore/platform/text/TextCodecASCIIFastPath.h b/Source/WebCore/platform/text/TextCodecASCIIFastPath.h new file mode 100644 index 0000000..c41a0b3 --- /dev/null +++ b/Source/WebCore/platform/text/TextCodecASCIIFastPath.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + * + * 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 TextCodecASCIIFastPath_h +#define TextCodecASCIIFastPath_h + +#include <stdint.h> + +namespace WebCore { + +// Assuming that a pointer is the size of a "machine word", then +// uintptr_t is an integer type that is also a machine word. +typedef uintptr_t MachineWord; + +// This constant has type uintptr_t since we will use it to align +// pointers. Not because MachineWord is uintptr_t. +const uintptr_t machineWordAlignmentMask = sizeof(MachineWord) - 1; + +template<size_t size> struct NonASCIIMask; +template<> struct NonASCIIMask<4> { + static unsigned value() { return 0x80808080U; } +}; +template<> struct NonASCIIMask<8> { + static unsigned long long value() { return 0x8080808080808080ULL; } +}; + +template<size_t size> struct UCharByteFiller; +template<> struct UCharByteFiller<4> { + static void copy(UChar* destination, const uint8_t* source) + { + destination[0] = source[0]; + destination[1] = source[1]; + destination[2] = source[2]; + destination[3] = source[3]; + } +}; +template<> struct UCharByteFiller<8> { + static void copy(UChar* destination, const uint8_t* source) + { + destination[0] = source[0]; + destination[1] = source[1]; + destination[2] = source[2]; + destination[3] = source[3]; + destination[4] = source[4]; + destination[5] = source[5]; + destination[6] = source[6]; + destination[7] = source[7]; + } +}; + +inline bool isAllASCII(MachineWord word) +{ + return !(word & NonASCIIMask<sizeof(MachineWord)>::value()); +} + +inline void copyASCIIMachineWord(UChar* destination, const uint8_t* source) +{ + UCharByteFiller<sizeof(MachineWord)>::copy(destination, source); +} + +inline bool isAlignedToMachineWord(const void* pointer) +{ + return !(reinterpret_cast<uintptr_t>(pointer) & machineWordAlignmentMask); +} + +template<typename T> inline T* alignToMachineWord(T* pointer) +{ + return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(pointer) & ~machineWordAlignmentMask); +} + +} // namespace WebCore + +#endif // TextCodecASCIIFastPath_h diff --git a/Source/WebCore/platform/text/TextCodecICU.cpp b/Source/WebCore/platform/text/TextCodecICU.cpp index 92a158a..d07b50e 100644 --- a/Source/WebCore/platform/text/TextCodecICU.cpp +++ b/Source/WebCore/platform/text/TextCodecICU.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> * * Redistribution and use in source and binary forms, with or without @@ -27,15 +27,13 @@ #include "config.h" #include "TextCodecICU.h" -#include "PlatformString.h" #include "ThreadGlobalData.h" #include <unicode/ucnv.h> #include <unicode/ucnv_cb.h> #include <wtf/Assertions.h> -#include <wtf/text/CString.h> -#include <wtf/PassOwnPtr.h> #include <wtf/StringExtras.h> #include <wtf/Threading.h> +#include <wtf/text/CString.h> #include <wtf/unicode/CharacterNames.h> using std::min; @@ -55,22 +53,12 @@ static UConverter*& cachedConverterICU() return threadGlobalData().cachedConverterICU().converter; } -static PassOwnPtr<TextCodec> newTextCodecICU(const TextEncoding& encoding, const void*) -{ - return new TextCodecICU(encoding); -} - -void TextCodecICU::registerBaseEncodingNames(EncodingNameRegistrar registrar) +PassOwnPtr<TextCodec> TextCodecICU::create(const TextEncoding& encoding, const void*) { - registrar("UTF-8", "UTF-8"); + return adoptPtr(new TextCodecICU(encoding)); } -void TextCodecICU::registerBaseCodecs(TextCodecRegistrar registrar) -{ - registrar("UTF-8", newTextCodecICU, 0); -} - -void TextCodecICU::registerExtendedEncodingNames(EncodingNameRegistrar registrar) +void TextCodecICU::registerEncodingNames(EncodingNameRegistrar registrar) { // We register Hebrew with logical ordering using a separate name. // Otherwise, this would share the same canonical name as the @@ -143,9 +131,6 @@ void TextCodecICU::registerExtendedEncodingNames(EncodingNameRegistrar registrar registrar("csISO88598I", "ISO-8859-8-I"); registrar("koi", "KOI8-R"); registrar("logical", "ISO-8859-8-I"); - registrar("unicode11utf8", "UTF-8"); - registrar("unicode20utf8", "UTF-8"); - registrar("x-unicode20utf8", "UTF-8"); registrar("visual", "ISO-8859-8"); registrar("winarabic", "windows-1256"); registrar("winbaltic", "windows-1257"); @@ -163,8 +148,14 @@ void TextCodecICU::registerExtendedEncodingNames(EncodingNameRegistrar registrar registrar("x-euc", "EUC-JP"); registrar("x-windows-949", "windows-949"); registrar("x-uhc", "windows-949"); - registrar("utf8", "UTF-8"); registrar("shift-jis", "Shift_JIS"); +#if !USE(BUILTIN_UTF8_CODEC) + registrar("unicode11utf8", "UTF-8"); + registrar("unicode20utf8", "UTF-8"); + registrar("x-unicode20utf8", "UTF-8"); + registrar("utf8", "UTF-8"); + registrar("UTF-8", "UTF-8"); +#endif // These aliases are present in modern versions of ICU, but use different codecs, and have no standard names. // They are not present in ICU 3.2. @@ -190,10 +181,10 @@ void TextCodecICU::registerExtendedEncodingNames(EncodingNameRegistrar registrar // and because older versions of ICU don't support ISO-8859-16 encoding at all. } -void TextCodecICU::registerExtendedCodecs(TextCodecRegistrar registrar) +void TextCodecICU::registerCodecs(TextCodecRegistrar registrar) { // See comment above in registerEncodingNames. - registrar("ISO-8859-8-I", newTextCodecICU, 0); + registrar("ISO-8859-8-I", create, 0); int32_t numEncodings = ucnv_countAvailable(); for (int32_t i = 0; i < numEncodings; ++i) { @@ -206,7 +197,7 @@ void TextCodecICU::registerExtendedCodecs(TextCodecRegistrar registrar) if (!U_SUCCESS(error) || !standardName) continue; } - registrar(standardName, newTextCodecICU, 0); + registrar(standardName, create, 0); } } @@ -300,6 +291,7 @@ public: ASSERT(err == U_ZERO_ERROR); } } + private: UConverter* m_converter; bool m_shouldStopOnEncodingErrors; @@ -354,28 +346,26 @@ String TextCodecICU::decode(const char* bytes, size_t length, bool flush, bool s } // We need to apply these fallbacks ourselves as they are not currently supported by ICU and -// they were provided by the old TEC encoding path -// Needed to fix <rdar://problem/4708689> -static UChar getGbkEscape(UChar32 codePoint) +// they were provided by the old TEC encoding path. Needed to fix <rdar://problem/4708689>. +static UChar fallbackForGBK(UChar32 character) { - switch (codePoint) { - case 0x01F9: - return 0xE7C8; - case 0x1E3F: - return 0xE7C7; - case 0x22EF: - return 0x2026; - case 0x301C: - return 0xFF5E; - default: - return 0; + switch (character) { + case 0x01F9: + return 0xE7C8; + case 0x1E3F: + return 0xE7C7; + case 0x22EF: + return 0x2026; + case 0x301C: + return 0xFF5E; } + return 0; } // Invalid character handler when writing escaped entities for unrepresentable // characters. See the declaration of TextCodec::encode for more. static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, - UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) + UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { if (reason == UCNV_UNASSIGNED) { *err = U_ZERO_ERROR; @@ -389,10 +379,10 @@ static void urlEscapedEntityCallback(const void* context, UConverterFromUnicodeA // Substitutes special GBK characters, escaping all other unassigned entities. static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, - UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) + UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { UChar outChar; - if (reason == UCNV_UNASSIGNED && (outChar = getGbkEscape(codePoint))) { + if (reason == UCNV_UNASSIGNED && (outChar = fallbackForGBK(codePoint))) { const UChar* source = &outChar; *err = U_ZERO_ERROR; ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); @@ -403,10 +393,10 @@ static void gbkCallbackEscape(const void* context, UConverterFromUnicodeArgs* fr // Combines both gbkUrlEscapedEntityCallback and GBK character substitution. static void gbkUrlEscapedEntityCallack(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, - UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) + UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { if (reason == UCNV_UNASSIGNED) { - if (UChar outChar = getGbkEscape(codePoint)) { + if (UChar outChar = fallbackForGBK(codePoint)) { const UChar* source = &outChar; *err = U_ZERO_ERROR; ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); @@ -419,10 +409,10 @@ static void gbkUrlEscapedEntityCallack(const void* context, UConverterFromUnicod } static void gbkCallbackSubstitute(const void* context, UConverterFromUnicodeArgs* fromUArgs, const UChar* codeUnits, int32_t length, - UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) + UChar32 codePoint, UConverterCallbackReason reason, UErrorCode* err) { UChar outChar; - if (reason == UCNV_UNASSIGNED && (outChar = getGbkEscape(codePoint))) { + if (reason == UCNV_UNASSIGNED && (outChar = fallbackForGBK(codePoint))) { const UChar* source = &outChar; *err = U_ZERO_ERROR; ucnv_cbFromUWriteUChars(fromUArgs, &source, source + 1, 0, err); @@ -486,5 +476,4 @@ CString TextCodecICU::encode(const UChar* characters, size_t length, Unencodable return CString(result.data(), size); } - } // namespace WebCore diff --git a/Source/WebCore/platform/text/TextCodecICU.h b/Source/WebCore/platform/text/TextCodecICU.h index bf517f7..f02c36d 100644 --- a/Source/WebCore/platform/text/TextCodecICU.h +++ b/Source/WebCore/platform/text/TextCodecICU.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2011 Apple Inc. All rights reserved. * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> * * Redistribution and use in source and binary forms, with or without @@ -29,7 +29,6 @@ #include "TextCodec.h" #include "TextEncoding.h" - #include <unicode/utypes.h> typedef struct UConverter UConverter; @@ -38,19 +37,18 @@ namespace WebCore { class TextCodecICU : public TextCodec { public: - static void registerBaseEncodingNames(EncodingNameRegistrar); - static void registerBaseCodecs(TextCodecRegistrar); + static void registerEncodingNames(EncodingNameRegistrar); + static void registerCodecs(TextCodecRegistrar); - static void registerExtendedEncodingNames(EncodingNameRegistrar); - static void registerExtendedCodecs(TextCodecRegistrar); + virtual ~TextCodecICU(); + private: TextCodecICU(const TextEncoding&); - virtual ~TextCodecICU(); + static PassOwnPtr<TextCodec> create(const TextEncoding&, const void*); virtual String decode(const char*, size_t length, bool flush, bool stopOnError, bool& sawError); virtual CString encode(const UChar*, size_t length, UnencodableHandling); - private: void createICUConverter() const; void releaseICUConverter() const; bool needsGBKFallbacks() const { return m_needsGBKFallbacks; } @@ -67,13 +65,12 @@ namespace WebCore { }; struct ICUConverterWrapper { - ICUConverterWrapper() - : converter(0) - { - } + ICUConverterWrapper() : converter(0) { } ~ICUConverterWrapper(); UConverter* converter; + + WTF_MAKE_NONCOPYABLE(ICUConverterWrapper); }; } // namespace WebCore diff --git a/Source/WebCore/platform/text/TextCodecLatin1.cpp b/Source/WebCore/platform/text/TextCodecLatin1.cpp index 2a217c5..d1c633b 100644 --- a/Source/WebCore/platform/text/TextCodecLatin1.cpp +++ b/Source/WebCore/platform/text/TextCodecLatin1.cpp @@ -27,7 +27,7 @@ #include "TextCodecLatin1.h" #include "PlatformString.h" -#include <stdio.h> +#include "TextCodecASCIIFastPath.h" #include <wtf/text/CString.h> #include <wtf/text/StringBuffer.h> #include <wtf/PassOwnPtr.h> @@ -116,76 +116,42 @@ void TextCodecLatin1::registerCodecs(TextCodecRegistrar registrar) registrar("US-ASCII", newStreamingTextDecoderWindowsLatin1, 0); } -template<size_t size> struct NonASCIIMask; -template<> struct NonASCIIMask<4> { - static unsigned value() { return 0x80808080U; } -}; -template<> struct NonASCIIMask<8> { - static unsigned long long value() { return 0x8080808080808080ULL; } -}; - -template<size_t size> struct UCharByteFiller; -template<> struct UCharByteFiller<4> { - static void copy(UChar* dest, const unsigned char* src) - { - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; - dest[3] = src[3]; - } -}; -template<> struct UCharByteFiller<8> { - static void copy(UChar* dest, const unsigned char* src) - { - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; - dest[3] = src[3]; - dest[4] = src[4]; - dest[5] = src[5]; - dest[6] = src[6]; - dest[7] = src[7]; - } -}; - String TextCodecLatin1::decode(const char* bytes, size_t length, bool, bool, bool&) { UChar* characters; String result = String::createUninitialized(length, characters); - const unsigned char* src = reinterpret_cast<const unsigned char*>(bytes); - const unsigned char* end = reinterpret_cast<const unsigned char*>(bytes + length); - const unsigned char* alignedEnd = reinterpret_cast<const unsigned char*>(reinterpret_cast<ptrdiff_t>(end) & ~(sizeof(uintptr_t) - 1)); - UChar* dest = characters; + const uint8_t* source = reinterpret_cast<const uint8_t*>(bytes); + const uint8_t* end = reinterpret_cast<const uint8_t*>(bytes + length); + const uint8_t* alignedEnd = alignToMachineWord(end); + UChar* destination = characters; - while (src < end) { - if (*src < 0x80) { - // Fast path for values < 0x80 (most Latin-1 text will be ASCII) - // Wait until we're at a properly aligned address, then read full CPU words. - if (!(reinterpret_cast<ptrdiff_t>(src) & (sizeof(uintptr_t) - 1))) { - while (src < alignedEnd) { - uintptr_t chunk = *reinterpret_cast_ptr<const uintptr_t*>(src); + while (source < end) { + if (isASCII(*source)) { + // Fast path for ASCII. Most Latin-1 text will be ASCII. + if (isAlignedToMachineWord(source)) { + while (source < alignedEnd) { + MachineWord chunk = *reinterpret_cast_ptr<const MachineWord*>(source); - if (chunk & NonASCIIMask<sizeof(uintptr_t)>::value()) + if (!isAllASCII(chunk)) goto useLookupTable; - UCharByteFiller<sizeof(uintptr_t)>::copy(dest, src); - - src += sizeof(uintptr_t); - dest += sizeof(uintptr_t); + copyASCIIMachineWord(destination, source); + source += sizeof(MachineWord); + destination += sizeof(MachineWord); } - if (src == end) + if (source == end) break; } - *dest = *src; + *destination = *source; } else { useLookupTable: - *dest = table[*src]; + *destination = table[*source]; } - ++src; - ++dest; + ++source; + ++destination; } return result; diff --git a/Source/WebCore/platform/text/TextCodecUTF8.cpp b/Source/WebCore/platform/text/TextCodecUTF8.cpp index 8944d68..5f82092 100644 --- a/Source/WebCore/platform/text/TextCodecUTF8.cpp +++ b/Source/WebCore/platform/text/TextCodecUTF8.cpp @@ -26,64 +26,17 @@ #include "config.h" #include "TextCodecUTF8.h" +#include "TextCodecASCIIFastPath.h" #include <wtf/text/CString.h> #include <wtf/text/StringBuffer.h> -#include <wtf/unicode/UTF8.h> +#include <wtf/unicode/CharacterNames.h> using namespace WTF::Unicode; using namespace std; namespace WebCore { -// Assuming that a pointer is the size of a "machine word", then -// uintptr_t is an integer type that is also a machine word. -typedef uintptr_t MachineWord; - -// This constant has type uintptr_t since we will use it to align -// pointers. Not because MachineWord is uintptr_t. -const uintptr_t machineWordAlignmentMask = sizeof(MachineWord) - 1; - -template<size_t size> struct NonASCIIMask; -template<> struct NonASCIIMask<4> { - static unsigned value() { return 0x80808080U; } -}; -template<> struct NonASCIIMask<8> { - static unsigned long long value() { return 0x8080808080808080ULL; } -}; - -template<size_t size> struct UCharByteFiller; -template<> struct UCharByteFiller<4> { - static void copy(UChar* destination, const uint8_t* source) - { - destination[0] = source[0]; - destination[1] = source[1]; - destination[2] = source[2]; - destination[3] = source[3]; - } -}; -template<> struct UCharByteFiller<8> { - static void copy(UChar* destination, const uint8_t* source) - { - destination[0] = source[0]; - destination[1] = source[1]; - destination[2] = source[2]; - destination[3] = source[3]; - destination[4] = source[4]; - destination[5] = source[5]; - destination[6] = source[6]; - destination[7] = source[7]; - } -}; - -static inline bool isAlignedToMachineWord(const void* pointer) -{ - return !(reinterpret_cast<uintptr_t>(pointer) & machineWordAlignmentMask); -} - -template<typename T> static inline T* alignToMachineWord(T* pointer) -{ - return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(pointer) & ~machineWordAlignmentMask); -} +const int nonCharacter = -1; PassOwnPtr<TextCodec> TextCodecUTF8::create(const TextEncoding&, const void*) { @@ -93,6 +46,15 @@ PassOwnPtr<TextCodec> TextCodecUTF8::create(const TextEncoding&, const void*) void TextCodecUTF8::registerEncodingNames(EncodingNameRegistrar registrar) { registrar("UTF-8", "UTF-8"); + + // Additional aliases that originally were present in the encoding + // table in WebKit on Macintosh, and subsequently added by + // TextCodecICU. Perhaps we can prove some are not used on the web + // and remove them. + registrar("unicode11utf8", "UTF-8"); + registrar("unicode20utf8", "UTF-8"); + registrar("utf8", "UTF-8"); + registrar("x-unicode20utf8", "UTF-8"); } void TextCodecUTF8::registerCodecs(TextCodecRegistrar registrar) @@ -100,27 +62,38 @@ void TextCodecUTF8::registerCodecs(TextCodecRegistrar registrar) registrar("UTF-8", create, 0); } -static inline int nonASCIISequenceLength(unsigned char firstByte) +static inline int nonASCIISequenceLength(uint8_t firstByte) { - ASSERT(!isASCII(firstByte)); - switch (firstByte >> 4) { - case 0xF: - return 4; - case 0xE: - return 3; - } - return 2; + static const uint8_t lengths[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + return lengths[firstByte]; } -static inline int decodeNonASCIISequence(const unsigned char* sequence, unsigned length) +static inline int decodeNonASCIISequence(const uint8_t* sequence, unsigned length) { ASSERT(!isASCII(sequence[0])); if (length == 2) { ASSERT(sequence[0] <= 0xDF); if (sequence[0] < 0xC2) - return -1; + return nonCharacter; if (sequence[1] < 0x80 || sequence[1] > 0xBF) - return -1; + return nonCharacter; return ((sequence[0] << 6) + sequence[1]) - 0x00003080; } if (length == 3) { @@ -128,18 +101,18 @@ static inline int decodeNonASCIISequence(const unsigned char* sequence, unsigned switch (sequence[0]) { case 0xE0: if (sequence[1] < 0xA0 || sequence[1] > 0xBF) - return -1; + return nonCharacter; break; case 0xED: if (sequence[1] < 0x80 || sequence[1] > 0x9F) - return -1; + return nonCharacter; break; default: if (sequence[1] < 0x80 || sequence[1] > 0xBF) - return -1; + return nonCharacter; } if (sequence[2] < 0x80 || sequence[2] > 0xBF) - return -1; + return nonCharacter; return ((sequence[0] << 12) + (sequence[1] << 6) + sequence[2]) - 0x000E2080; } ASSERT(length == 4); @@ -147,109 +120,176 @@ static inline int decodeNonASCIISequence(const unsigned char* sequence, unsigned switch (sequence[0]) { case 0xF0: if (sequence[1] < 0x90 || sequence[1] > 0xBF) - return -1; + return nonCharacter; break; case 0xF4: if (sequence[1] < 0x80 || sequence[1] > 0x8F) - return -1; + return nonCharacter; break; default: if (sequence[1] < 0x80 || sequence[1] > 0xBF) - return -1; + return nonCharacter; } if (sequence[2] < 0x80 || sequence[2] > 0xBF) - return -1; + return nonCharacter; if (sequence[3] < 0x80 || sequence[3] > 0xBF) - return -1; + return nonCharacter; return ((sequence[0] << 18) + (sequence[1] << 12) + (sequence[2] << 6) + sequence[3]) - 0x03C82080; } +static inline UChar* appendCharacter(UChar* destination, int character) +{ + ASSERT(character != nonCharacter); + ASSERT(!U_IS_SURROGATE(character)); + if (U_IS_BMP(character)) + *destination++ = character; + else { + *destination++ = U16_LEAD(character); + *destination++ = U16_TRAIL(character); + } + return destination; +} + +void TextCodecUTF8::consumePartialSequenceByte() +{ + --m_partialSequenceSize; + memmove(m_partialSequence, m_partialSequence + 1, m_partialSequenceSize); +} + +void TextCodecUTF8::handleError(UChar*& destination, bool stopOnError, bool& sawError) +{ + sawError = true; + if (stopOnError) + return; + // Each error generates a replacement character and consumes one byte. + *destination++ = replacementCharacter; + consumePartialSequenceByte(); +} + +void TextCodecUTF8::handlePartialSequence(UChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool stopOnError, bool& sawError) +{ + ASSERT(m_partialSequenceSize); + do { + if (isASCII(m_partialSequence[0])) { + *destination++ = m_partialSequence[0]; + consumePartialSequenceByte(); + continue; + } + int count = nonASCIISequenceLength(m_partialSequence[0]); + if (!count) { + handleError(destination, stopOnError, sawError); + if (stopOnError) + return; + continue; + } + if (count > m_partialSequenceSize) { + if (count - m_partialSequenceSize > end - source) { + if (!flush) { + // The new data is not enough to complete the sequence, so + // add it to the existing partial sequence. + memcpy(m_partialSequence + m_partialSequenceSize, source, end - source); + m_partialSequenceSize += end - source; + return; + } + // An incomplete partial sequence at the end is an error. + handleError(destination, stopOnError, sawError); + if (stopOnError) + return; + continue; + } + memcpy(m_partialSequence + m_partialSequenceSize, source, count - m_partialSequenceSize); + source += count - m_partialSequenceSize; + m_partialSequenceSize = count; + } + int character = decodeNonASCIISequence(m_partialSequence, count); + if (character == nonCharacter) { + handleError(destination, stopOnError, sawError); + if (stopOnError) + return; + continue; + } + m_partialSequenceSize -= count; + destination = appendCharacter(destination, character); + } while (m_partialSequenceSize); +} + String TextCodecUTF8::decode(const char* bytes, size_t length, bool flush, bool stopOnError, bool& sawError) { - StringBuffer buffer(length); + // Each input byte might turn into a character. + // That includes all bytes in the partial-sequence buffer because + // each byte in an invalid sequence will turn into a replacement character. + StringBuffer buffer(m_partialSequenceSize + length); const uint8_t* source = reinterpret_cast<const uint8_t*>(bytes); const uint8_t* end = source + length; const uint8_t* alignedEnd = alignToMachineWord(end); UChar* destination = buffer.characters(); - int count; - int character; - - if (m_partialSequenceSize) { - count = nonASCIISequenceLength(m_partialSequence[0]); - ASSERT(count > m_partialSequenceSize); - if (count - m_partialSequenceSize > end - source) { - memcpy(m_partialSequence + m_partialSequenceSize, source, end - source); - m_partialSequenceSize += end - source; - source = end; - } else { - uint8_t completeSequence[U8_MAX_LENGTH]; - memcpy(completeSequence, m_partialSequence, m_partialSequenceSize); - memcpy(completeSequence + m_partialSequenceSize, source, count - m_partialSequenceSize); - source += count - m_partialSequenceSize; - m_partialSequenceSize = 0; - character = decodeNonASCIISequence(completeSequence, count); - goto decodedNonASCII; + do { + if (m_partialSequenceSize) { + // Explicitly copy destination and source pointers to avoid taking pointers to the + // local variables, which may harm code generation by disabling some optimizations + // in some compilers. + UChar* destinationForHandlePartialSequence = destination; + const uint8_t* sourceForHandlePartialSequence = source; + handlePartialSequence(destinationForHandlePartialSequence, sourceForHandlePartialSequence, end, flush, stopOnError, sawError); + destination = destinationForHandlePartialSequence; + source = sourceForHandlePartialSequence; + if (m_partialSequenceSize) + break; } - } - while (source < end) { - if (isASCII(*source)) { - // Fast path for ASCII. Most UTF-8 text will be ASCII. - if (isAlignedToMachineWord(source)) { - while (source < alignedEnd) { - MachineWord chunk = *reinterpret_cast_ptr<const MachineWord*>(source); - if (chunk & NonASCIIMask<sizeof(MachineWord)>::value()) { - if (isASCII(*source)) + while (source < end) { + if (isASCII(*source)) { + // Fast path for ASCII. Most UTF-8 text will be ASCII. + if (isAlignedToMachineWord(source)) { + while (source < alignedEnd) { + MachineWord chunk = *reinterpret_cast_ptr<const MachineWord*>(source); + if (!isAllASCII(chunk)) break; - goto nonASCII; + copyASCIIMachineWord(destination, source); + source += sizeof(MachineWord); + destination += sizeof(MachineWord); } - UCharByteFiller<sizeof(MachineWord)>::copy(destination, source); - source += sizeof(MachineWord); - destination += sizeof(MachineWord); + if (source == end) + break; + if (!isASCII(*source)) + continue; } - if (source == end) - break; - } - *destination++ = *source++; - } else { -nonASCII: - count = nonASCIISequenceLength(*source); - ASSERT(count >= 2); - ASSERT(count <= 4); - if (count > end - source) { - ASSERT(end - source <= static_cast<ptrdiff_t>(sizeof(m_partialSequence))); - ASSERT(!m_partialSequenceSize); - m_partialSequenceSize = end - source; - memcpy(m_partialSequence, source, m_partialSequenceSize); - break; + *destination++ = *source++; + continue; } - character = decodeNonASCIISequence(source, count); - source += count; -decodedNonASCII: - if (character < 0) { - if (stopOnError) { - sawError = true; + int count = nonASCIISequenceLength(*source); + int character; + if (!count) + character = nonCharacter; + else { + if (count > end - source) { + ASSERT(end - source < static_cast<ptrdiff_t>(sizeof(m_partialSequence))); + ASSERT(!m_partialSequenceSize); + m_partialSequenceSize = end - source; + memcpy(m_partialSequence, source, m_partialSequenceSize); + source = end; break; } - } else { - ASSERT(!U_IS_SURROGATE(character)); - if (U_IS_BMP(character)) - *destination++ = character; - else { - *destination++ = U16_LEAD(character); - *destination++ = U16_TRAIL(character); - } + character = decodeNonASCIISequence(source, count); } + if (character == nonCharacter) { + sawError = true; + if (stopOnError) + break; + // Each error generates a replacement character and consumes one byte. + *destination++ = replacementCharacter; + ++source; + continue; + } + source += count; + destination = appendCharacter(destination, character); } - } + } while (flush && m_partialSequenceSize); buffer.shrink(destination - buffer.characters()); - if (flush && m_partialSequenceSize) - sawError = true; - return String::adopt(buffer); } diff --git a/Source/WebCore/platform/text/TextCodecUTF8.h b/Source/WebCore/platform/text/TextCodecUTF8.h index f3b6b7a..39fd753 100644 --- a/Source/WebCore/platform/text/TextCodecUTF8.h +++ b/Source/WebCore/platform/text/TextCodecUTF8.h @@ -35,15 +35,19 @@ public: static void registerEncodingNames(EncodingNameRegistrar); static void registerCodecs(TextCodecRegistrar); - virtual String decode(const char*, size_t length, bool flush, bool stopOnError, bool& sawError); - virtual CString encode(const UChar*, size_t length, UnencodableHandling); - private: static PassOwnPtr<TextCodec> create(const TextEncoding&, const void*); TextCodecUTF8() : m_partialSequenceSize(0) { } + virtual String decode(const char*, size_t length, bool flush, bool stopOnError, bool& sawError); + virtual CString encode(const UChar*, size_t length, UnencodableHandling); + + void handlePartialSequence(UChar*& destination, const uint8_t*& source, const uint8_t* end, bool flush, bool stopOnError, bool& sawError); + void handleError(UChar*& destination, bool stopOnError, bool& sawError); + void consumePartialSequenceByte(); + int m_partialSequenceSize; - char m_partialSequence[U8_MAX_LENGTH - 1]; + uint8_t m_partialSequence[U8_MAX_LENGTH]; }; diff --git a/Source/WebCore/platform/text/TextEncodingRegistry.cpp b/Source/WebCore/platform/text/TextEncodingRegistry.cpp index 1dc09ee..f604227 100644 --- a/Source/WebCore/platform/text/TextEncodingRegistry.cpp +++ b/Source/WebCore/platform/text/TextEncodingRegistry.cpp @@ -58,6 +58,9 @@ #include "TextCodecWinCE.h" #endif +#include <wtf/CurrentTime.h> +#include <wtf/text/CString.h> + using namespace WTF; namespace WebCore { @@ -220,31 +223,22 @@ static void buildBaseTextCodecMaps() TextCodecLatin1::registerEncodingNames(addToTextEncodingNameMap); TextCodecLatin1::registerCodecs(addToTextCodecMap); +#if USE(BUILTIN_UTF8_CODEC) + TextCodecUTF8::registerEncodingNames(addToTextEncodingNameMap); + TextCodecUTF8::registerCodecs(addToTextCodecMap); +#endif + TextCodecUTF16::registerEncodingNames(addToTextEncodingNameMap); TextCodecUTF16::registerCodecs(addToTextCodecMap); TextCodecUserDefined::registerEncodingNames(addToTextEncodingNameMap); TextCodecUserDefined::registerCodecs(addToTextCodecMap); -#if USE(ICU_UNICODE) - TextCodecICU::registerBaseEncodingNames(addToTextEncodingNameMap); - TextCodecICU::registerBaseCodecs(addToTextCodecMap); -#endif - #if USE(GLIB_UNICODE) + // FIXME: This is not needed. The code above covers all the base codecs. TextCodecGtk::registerBaseEncodingNames(addToTextEncodingNameMap); TextCodecGtk::registerBaseCodecs(addToTextCodecMap); #endif - -#if USE(BREWMP_UNICODE) - TextCodecBrew::registerBaseEncodingNames(addToTextEncodingNameMap); - TextCodecBrew::registerBaseCodecs(addToTextCodecMap); -#endif - -#if OS(WINCE) && !PLATFORM(QT) - TextCodecWinCE::registerBaseEncodingNames(addToTextEncodingNameMap); - TextCodecWinCE::registerBaseCodecs(addToTextCodecMap); -#endif } static void addEncodingName(HashSet<const char*>* set, const char* name) @@ -303,8 +297,8 @@ bool shouldShowBackslashAsCurrencySymbolIn(const char* canonicalEncodingName) static void extendTextCodecMaps() { #if USE(ICU_UNICODE) - TextCodecICU::registerExtendedEncodingNames(addToTextEncodingNameMap); - TextCodecICU::registerExtendedCodecs(addToTextCodecMap); + TextCodecICU::registerEncodingNames(addToTextEncodingNameMap); + TextCodecICU::registerCodecs(addToTextCodecMap); #endif #if USE(QT4_UNICODE) diff --git a/Source/WebCore/platform/text/brew/TextBreakIteratorBrew.cpp b/Source/WebCore/platform/text/brew/TextBreakIteratorBrew.cpp index 7f46e4f..3bc1c8a 100644 --- a/Source/WebCore/platform/text/brew/TextBreakIteratorBrew.cpp +++ b/Source/WebCore/platform/text/brew/TextBreakIteratorBrew.cpp @@ -26,6 +26,7 @@ #include <wtf/StdLibExtras.h> #include <wtf/unicode/Unicode.h> +using namespace std; using namespace WTF::Unicode; namespace WebCore { @@ -260,11 +261,32 @@ TextBreakIterator* characterBreakIterator(const UChar* string, int length) return &iterator; } -TextBreakIterator* lineBreakIterator(const UChar* string, int length) +static TextBreakIterator* staticLineBreakIterator; + +TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) { - DEFINE_STATIC_LOCAL(LineBreakIterator , iterator, ()); - iterator.reset(string, length); - return &iterator; + TextBreakIterator* lineBreakIterator = 0; + if (staticLineBreakIterator) { + staticLineBreakIterator->reset(string, length); + swap(staticLineBreakIterator, lineBreakIterator); + } + + if (!lineBreakIterator && string && length) { + lineBreakIterator = new LineBreakIterator; + lineBreakIterator->reset(string, length); + } + + return lineBreakIterator; +} + +void releaseLineBreakIterator(TextBreakIterator* iterator) +{ + ASSERT(iterator); + + if (!staticLineBreakIterator) + staticLineBreakIterator = iterator; + else + delete iterator; } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) diff --git a/Source/WebCore/platform/text/brew/TextCodecBrew.cpp b/Source/WebCore/platform/text/brew/TextCodecBrew.cpp index 1f32298..aa94980 100644 --- a/Source/WebCore/platform/text/brew/TextCodecBrew.cpp +++ b/Source/WebCore/platform/text/brew/TextCodecBrew.cpp @@ -43,16 +43,6 @@ static PassOwnPtr<TextCodec> newTextCodecBrew(const TextEncoding& encoding, cons return new TextCodecBrew(encoding); } -void TextCodecBrew::registerBaseEncodingNames(EncodingNameRegistrar registrar) -{ - registrar("UTF-8", "UTF-8"); -} - -void TextCodecBrew::registerBaseCodecs(TextCodecRegistrar registrar) -{ - registrar("UTF-8", newTextCodecBrew, 0); -} - void TextCodecBrew::registerExtendedEncodingNames(EncodingNameRegistrar registrar) { // FIXME: Not sure how to enumerate all available encodings. diff --git a/Source/WebCore/platform/text/brew/TextCodecBrew.h b/Source/WebCore/platform/text/brew/TextCodecBrew.h index 97e2c87..14d11f0 100644 --- a/Source/WebCore/platform/text/brew/TextCodecBrew.h +++ b/Source/WebCore/platform/text/brew/TextCodecBrew.h @@ -35,9 +35,6 @@ namespace WebCore { class TextCodecBrew : public TextCodec { public: - static void registerBaseEncodingNames(EncodingNameRegistrar); - static void registerBaseCodecs(TextCodecRegistrar); - static void registerExtendedEncodingNames(EncodingNameRegistrar); static void registerExtendedCodecs(TextCodecRegistrar); diff --git a/Source/WebCore/platform/text/cf/StringCF.cpp b/Source/WebCore/platform/text/cf/StringCF.cpp index dcaf8fb..0a1928b 100644 --- a/Source/WebCore/platform/text/cf/StringCF.cpp +++ b/Source/WebCore/platform/text/cf/StringCF.cpp @@ -21,7 +21,7 @@ #include "config.h" #include "PlatformString.h" -#if PLATFORM(CF) +#if USE(CF) #include <CoreFoundation/CoreFoundation.h> @@ -52,4 +52,4 @@ CFStringRef String::createCFString() const } -#endif // PLATFORM(CF) +#endif // USE(CF) diff --git a/Source/WebCore/platform/text/cf/StringImplCF.cpp b/Source/WebCore/platform/text/cf/StringImplCF.cpp index 0157918..c99ddac 100644 --- a/Source/WebCore/platform/text/cf/StringImplCF.cpp +++ b/Source/WebCore/platform/text/cf/StringImplCF.cpp @@ -21,7 +21,7 @@ #include "config.h" #include <wtf/text/StringImpl.h> -#if PLATFORM(CF) +#if USE(CF) #include <CoreFoundation/CoreFoundation.h> #include <wtf/MainThread.h> @@ -159,4 +159,4 @@ CFStringRef StringImpl::createCFString() } -#endif // PLATFORM(CF) +#endif // USE(CF) diff --git a/Source/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp b/Source/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp index 990e331..8f289f3 100644 --- a/Source/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp +++ b/Source/WebCore/platform/text/gtk/TextBreakIteratorGtk.cpp @@ -239,11 +239,34 @@ TextBreakIterator* wordBreakIterator(const UChar* string, int length) return setUpIterator(createdWordBreakIterator, staticWordBreakIterator, UBRK_WORD, string, length); } -TextBreakIterator* lineBreakIterator(const UChar* string, int length) +static bool createdLineBreakIterator = false; +static TextBreakIterator* staticLineBreakIterator; + +TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) { - static bool createdLineBreakIterator = false; - static TextBreakIterator* staticLineBreakIterator; - return setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length); + TextBreakIterator* lineBreakIterator = 0; + if (!createdLineBreakIterator || staticLineBreakIterator) { + setUpIterator(createdLineBreakIterator, staticLineBreakIterator, UBRK_LINE, string, length); + swap(staticLineBreakIterator, lineBreakIterator); + } + + if (!lineBreakIterator) { + bool createdNewLineBreakIterator = false; + setUpIterator(createdNewLineBreakIterator, lineBreakIterator, UBRK_LINE, string, length); + } + + return lineBreakIterator; +} + +void releaseLineBreakIterator(TextBreakIterator* iterator) +{ + ASSERT(createdLineBreakIterator); + ASSERT(iterator); + + if (!staticLineBreakIterator) + staticLineBreakIterator = iterator; + else + delete iterator; } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) diff --git a/Source/WebCore/platform/network/chromium/NetworkStateNotifierChromium.cpp b/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm index 3b28fbd..8cfe200 100644 --- a/Source/WebCore/platform/network/chromium/NetworkStateNotifierChromium.cpp +++ b/Source/WebCore/platform/text/mac/LocalizedNumberMac.mm @@ -1,10 +1,10 @@ /* - * Copyright (c) 2008, Google Inc. All rights reserved. - * + * Copyright (C) 2011 Google Inc. All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -29,22 +29,47 @@ */ #include "config.h" -#include "NetworkStateNotifier.h" +#include "LocalizedNumber.h" + +#include <limits> +#import <Foundation/NSNumberFormatter.h> +#include <wtf/RetainPtr.h> +#include <wtf/text/CString.h> + +using namespace std; namespace WebCore { -// Chromium doesn't currently support network state notifications. This causes -// an extra DLL to get loaded into the renderer which can slow things down a -// bit. We may want an alternate design. +static RetainPtr<NSNumberFormatter> createFormatterForCurrentLocale() +{ + RetainPtr<NSNumberFormatter> formatter(AdoptNS, [[NSNumberFormatter alloc] init]); + [formatter.get() setLocalizesFormat:YES]; + [formatter.get() setNumberStyle:NSNumberFormatterDecimalStyle]; + return formatter; +} + +static NSNumberFormatter *numberFormatter() +{ + ASSERT(isMainThread()); + static NSNumberFormatter *formatter = createFormatterForCurrentLocale().leakRef(); + return formatter; +} -void NetworkStateNotifier::updateState() +double parseLocalizedNumber(const String& numberString) { + if (numberString.isEmpty()) + return numeric_limits<double>::quiet_NaN(); + NSNumber *number = [numberFormatter() numberFromString:numberString]; + if (!number) + return numeric_limits<double>::quiet_NaN(); + return [number doubleValue]; } -NetworkStateNotifier::NetworkStateNotifier() - : m_isOnLine(true) - , m_networkStateChangedFunction(0) +String formatLocalizedNumber(double inputNumber) { + RetainPtr<NSNumber> number(AdoptNS, [[NSNumber alloc] initWithDouble:inputNumber]); + return String([numberFormatter() stringFromNumber:number.get()]); } } // namespace WebCore + diff --git a/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp index b9f5a9e..3fae657 100644 --- a/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp +++ b/Source/WebCore/platform/text/qt/TextBreakIteratorQt.cpp @@ -31,6 +31,8 @@ #define DEBUG if (1) {} else qDebug #endif +using namespace std; + namespace WebCore { #if USE(QT_ICU_TEXT_BREAKING) @@ -39,36 +41,27 @@ const char* currentTextBreakLocaleID() return QLocale::system().name().toLatin1(); } #else - static unsigned char buffer[1024]; - class TextBreakIterator : public QTextBoundaryFinder { public: - TextBreakIterator(QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) - : QTextBoundaryFinder(type, (const QChar*)string, length, buffer, sizeof(buffer)) - , length(length) - , string(string) {} + TextBreakIterator(QTextBoundaryFinder::BoundaryType type, const QString& string) + : QTextBoundaryFinder(type, string) + { } TextBreakIterator() : QTextBoundaryFinder() - , length(0) - , string(0) {} - - int length; - const UChar* string; + { } }; - TextBreakIterator* setUpIterator(TextBreakIterator& iterator, QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) + TextBreakIterator* setUpIterator(TextBreakIterator& iterator, QTextBoundaryFinder::BoundaryType type, const UChar* characters, int length) { - if (!string || !length) + if (!characters || !length) return 0; - if (iterator.isValid() && type == iterator.type() && length == iterator.length - && memcmp(string, iterator.string, length) == 0) { + if (iterator.isValid() && type == iterator.type() && iterator.string() == QString::fromRawData(reinterpret_cast<const QChar*>(characters), length)) { iterator.toStart(); return &iterator; } - iterator = TextBreakIterator(type, string, length); - + iterator = TextBreakIterator(type, QString(reinterpret_cast<const QChar*>(characters), length)); return &iterator; } @@ -89,10 +82,30 @@ const char* currentTextBreakLocaleID() return characterBreakIterator(string, length); } - TextBreakIterator* lineBreakIterator(const UChar* string, int length) + static TextBreakIterator* staticLineBreakIterator; + + TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) + { + TextBreakIterator* lineBreakIterator = 0; + if (staticLineBreakIterator) { + setUpIterator(*staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); + swap(staticLineBreakIterator, lineBreakIterator); + } + + if (!lineBreakIterator && string && length) + lineBreakIterator = new TextBreakIterator(QTextBoundaryFinder::Line, QString(reinterpret_cast<const QChar*>(string), length)); + + return lineBreakIterator; + } + + void releaseLineBreakIterator(TextBreakIterator* iterator) { - static TextBreakIterator staticLineBreakIterator; - return setUpIterator(staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); + ASSERT(iterator); + + if (!staticLineBreakIterator) + staticLineBreakIterator = iterator; + else + delete iterator; } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) diff --git a/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp b/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp index 96488c0..a4d2dbe 100644 --- a/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp +++ b/Source/WebCore/platform/text/wince/TextBreakIteratorWinCE.cpp @@ -26,6 +26,7 @@ #include <wtf/StdLibExtras.h> #include <wtf/unicode/Unicode.h> +using namespace std; using namespace WTF::Unicode; namespace WebCore { @@ -241,11 +242,32 @@ TextBreakIterator* characterBreakIterator(const UChar* string, int length) return &iterator; } -TextBreakIterator* lineBreakIterator(const UChar* string, int length) +static TextBreakIterator* staticLineBreakIterator; + +TextBreakIterator* acquireLineBreakIterator(const UChar* string, int length) { - DEFINE_STATIC_LOCAL(LineBreakIterator , iterator, ()); - iterator.reset(string, length); - return &iterator; + TextBreakIterator* lineBreakIterator = 0; + if (staticLineBreakIterator) { + staticLineBreakIterator->reset(string, length); + swap(staticLineBreakIterator, lineBreakIterator); + } + + if (!lineBreakIterator && string && length) { + lineBreakIterator = new LineBreakIterator; + lineBreakIterator->reset(string, length); + } + + return lineBreakIterator; +} + +void releaseLineBreakIterator(TextBreakIterator* iterator) +{ + ASSERT(iterator); + + if (!staticLineBreakIterator) + staticLineBreakIterator = iterator; + else + delete iterator; } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) diff --git a/Source/WebCore/platform/text/wince/TextCodecWinCE.cpp b/Source/WebCore/platform/text/wince/TextCodecWinCE.cpp index 3532e74..88ab8fc 100644 --- a/Source/WebCore/platform/text/wince/TextCodecWinCE.cpp +++ b/Source/WebCore/platform/text/wince/TextCodecWinCE.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved. - * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> + * Copyright (C) 2010-2011 Patrick Gansterer <paroga@paroga.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -35,7 +35,6 @@ #include <wtf/text/CString.h> #include <wtf/text/StringConcatenate.h> #include <wtf/text/StringHash.h> -#include <wtf/unicode/UTF8.h> namespace WebCore { @@ -122,9 +121,6 @@ LanguageManager::LanguageManager() static UINT getCodePage(const char* name) { - if (!strcmp(name, "UTF-8")) - return CP_UTF8; - // Explicitly use a "const" reference to fix the silly VS build error // saying "==" is not found for const_iterator and iterator const HashMap<String, CharsetInfo>& charsets = knownCharsets(); @@ -146,16 +142,6 @@ TextCodecWinCE::~TextCodecWinCE() { } -void TextCodecWinCE::registerBaseEncodingNames(EncodingNameRegistrar registrar) -{ - registrar("UTF-8", "UTF-8"); -} - -void TextCodecWinCE::registerBaseCodecs(TextCodecRegistrar registrar) -{ - registrar("UTF-8", newTextCodecWinCE, 0); -} - void TextCodecWinCE::registerExtendedEncodingNames(EncodingNameRegistrar registrar) { languageManager(); @@ -181,9 +167,6 @@ void TextCodecWinCE::registerExtendedCodecs(TextCodecRegistrar registrar) static DWORD getCodePageFlags(UINT codePage) { - if (codePage == CP_UTF8) - return MB_ERR_INVALID_CHARS; - if (codePage == 42) // Symbol return 0; @@ -213,7 +196,7 @@ static inline const char* findFirstNonAsciiCharacter(const char* bytes, size_t l return bytes; } -static void decode(Vector<UChar, 8192>& result, UINT codePage, const char* bytes, size_t length, size_t* left, bool canBeFirstTime, bool& sawInvalidChar) +static void decodeInternal(Vector<UChar, 8192>& result, UINT codePage, const char* bytes, size_t length, size_t* left) { *left = length; if (!bytes || !length) @@ -221,93 +204,32 @@ static void decode(Vector<UChar, 8192>& result, UINT codePage, const char* bytes DWORD flags = getCodePageFlags(codePage); - if (codePage == CP_UTF8) { - if (canBeFirstTime) { - // Handle BOM. - if (length > 3) { - if (bytes[0] == (char)0xEF && bytes[1] == (char)0xBB && bytes[2] == (char)0xBF) { - // BOM found! - length -= 3; - bytes += 3; - *left = length; - } - } else if (bytes[0] == 0xEF && (length < 2 || bytes[1] == (char)0xBB) && (length < 3 || bytes[2] == (char)0xBF)) { - if (length == 3) - *left = 0; - return; - } - } - - // Process ASCII characters at beginning. - const char* firstNonAsciiChar = findFirstNonAsciiCharacter(bytes, length); - int numAsciiCharacters = firstNonAsciiChar - bytes; - if (numAsciiCharacters) { - result.append(bytes, numAsciiCharacters); - length -= numAsciiCharacters; - if (!length) { - *left = 0; - return; - } - bytes = firstNonAsciiChar; - } - - int oldSize = result.size(); - result.resize(oldSize + length); - UChar* resultStart = result.data() + oldSize; - const char* sourceStart = bytes; - const char* const sourceEnd = bytes + length; - for (;;) { - using namespace WTF::Unicode; - ConversionResult convRes = convertUTF8ToUTF16(&sourceStart - , sourceEnd - , &resultStart - , result.data() + result.size() - , true); - - // FIXME: is it possible? - if (convRes == targetExhausted && sourceStart < sourceEnd) { - oldSize = result.size(); - result.resize(oldSize + 256); - resultStart = result.data() + oldSize; - continue; - } + int testLength = length; + int untestedLength = length; + for (;;) { + int resultLength = MultiByteToWideChar(codePage, flags, bytes, testLength, 0, 0); - if (convRes != conversionOK) - sawInvalidChar = true; + if (resultLength > 0) { + int oldSize = result.size(); + result.resize(oldSize + resultLength); - break; - } + MultiByteToWideChar(codePage, flags, bytes, testLength, result.data() + oldSize, resultLength); - *left = sourceEnd - sourceStart; - result.resize(resultStart - result.data()); - } else { - int testLength = length; - int untestedLength = length; - for (;;) { - int resultLength = MultiByteToWideChar(codePage, flags, bytes, testLength, 0, 0); - - if (resultLength > 0) { - int oldSize = result.size(); - result.resize(oldSize + resultLength); - - MultiByteToWideChar(codePage, flags, bytes, testLength, result.data() + oldSize, resultLength); - - if (testLength == untestedLength) { - *left = length - testLength; - break; - } - untestedLength -= testLength; - length -= testLength; - bytes += testLength; - } else { - untestedLength = testLength - 1; - if (!untestedLength) { - *left = length; - break; - } + if (testLength == untestedLength) { + *left = length - testLength; + break; + } + untestedLength -= testLength; + length -= testLength; + bytes += testLength; + } else { + untestedLength = testLength - 1; + if (!untestedLength) { + *left = length; + break; } - testLength = (untestedLength + 1) / 2; } + testLength = (untestedLength + 1) / 2; } } @@ -322,12 +244,11 @@ String TextCodecWinCE::decode(const char* bytes, size_t length, bool flush, bool size_t left; Vector<UChar, 8192> result; for (;;) { - bool sawInvalidChar = false; - WebCore::decode(result, m_codePage, bytes, length, &left, m_decodeBuffer.isEmpty(), sawInvalidChar); + decodeInternal(result, m_codePage, bytes, length, &left); if (!left) break; - if (!sawInvalidChar && !flush && left < 16) + if (!flush && left < 16) break; result.append(L'?'); @@ -359,9 +280,7 @@ CString TextCodecWinCE::encode(const UChar* characters, size_t length, Unencodab if (!characters || !length) return CString(); - DWORD flags = m_codePage == CP_UTF8 ? 0 : WC_COMPOSITECHECK; - - int resultLength = WideCharToMultiByte(m_codePage, flags, characters, length, 0, 0, 0, 0); + int resultLength = WideCharToMultiByte(m_codePage, WC_COMPOSITECHECK, characters, length, 0, 0, 0, 0); // FIXME: We need to implement UnencodableHandling: QuestionMarksForUnencodables, EntitiesForUnencodables, and URLEncodedEntitiesForUnencodables. @@ -371,7 +290,7 @@ CString TextCodecWinCE::encode(const UChar* characters, size_t length, Unencodab char* characterBuffer; CString result = CString::newUninitialized(resultLength, characterBuffer); - WideCharToMultiByte(m_codePage, flags, characters, length, characterBuffer, resultLength, 0, 0); + WideCharToMultiByte(m_codePage, WC_COMPOSITECHECK, characters, length, characterBuffer, resultLength, 0, 0); return result; } diff --git a/Source/WebCore/platform/text/wince/TextCodecWinCE.h b/Source/WebCore/platform/text/wince/TextCodecWinCE.h index 8d332a6..500a8cd 100644 --- a/Source/WebCore/platform/text/wince/TextCodecWinCE.h +++ b/Source/WebCore/platform/text/wince/TextCodecWinCE.h @@ -39,9 +39,6 @@ namespace WebCore { class TextCodecWinCE : public TextCodec { public: - static void registerBaseEncodingNames(EncodingNameRegistrar); - static void registerBaseCodecs(TextCodecRegistrar); - static void registerExtendedEncodingNames(EncodingNameRegistrar); static void registerExtendedCodecs(TextCodecRegistrar); diff --git a/Source/WebCore/platform/win/BString.cpp b/Source/WebCore/platform/win/BString.cpp index 6622f96..872ab7e 100644 --- a/Source/WebCore/platform/win/BString.cpp +++ b/Source/WebCore/platform/win/BString.cpp @@ -31,7 +31,7 @@ #include <windows.h> #include <wtf/text/AtomicString.h> -#if PLATFORM(CF) +#if USE(CF) #include <CoreFoundation/CoreFoundation.h> #endif @@ -92,7 +92,7 @@ BString::BString(const UString& s) m_bstr = SysAllocStringLen(s.characters(), s.length()); } -#if PLATFORM(CF) +#if USE(CF) BString::BString(CFStringRef cfstr) : m_bstr(0) { diff --git a/Source/WebCore/platform/win/BString.h b/Source/WebCore/platform/win/BString.h index bdbf189..922d3e2 100644 --- a/Source/WebCore/platform/win/BString.h +++ b/Source/WebCore/platform/win/BString.h @@ -28,7 +28,7 @@ #include <wtf/Forward.h> -#if PLATFORM(CF) +#if USE(CF) typedef const struct __CFString * CFStringRef; #endif @@ -51,7 +51,7 @@ namespace WebCore { BString(const AtomicString&); BString(const KURL&); BString(const JSC::UString&); -#if PLATFORM(CF) +#if USE(CF) BString(CFStringRef); #endif ~BString(); diff --git a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp index 77b95ef..513992d 100644 --- a/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp +++ b/Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp @@ -38,14 +38,14 @@ #include <wtf/text/CString.h> #include <wtf/text/StringConcatenate.h> -#if PLATFORM(CF) +#if USE(CF) #include <CoreFoundation/CoreFoundation.h> #include <wtf/RetainPtr.h> #endif namespace WebCore { -#if PLATFORM(CF) +#if USE(CF) FORMATETC* cfHDropFormat() { static FORMATETC urlFormat = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; @@ -83,7 +83,7 @@ static bool getDataMapItem(const DragDataMap* dataObject, FORMATETC* format, Str static bool getWebLocData(IDataObject* dataObject, String& url, String* title) { bool succeeded = false; -#if PLATFORM(CF) +#if USE(CF) WCHAR filename[MAX_PATH]; WCHAR urlBuffer[INTERNET_MAX_URL_LENGTH]; @@ -123,7 +123,7 @@ exit: static bool getWebLocData(const DragDataMap* dataObject, String& url, String* title) { -#if PLATFORM(CF) +#if USE(CF) WCHAR filename[MAX_PATH]; WCHAR urlBuffer[INTERNET_MAX_URL_LENGTH]; @@ -390,7 +390,7 @@ String getURL(IDataObject* dataObject, DragData::FilenameConversionPolicy filena ReleaseStgMedium(&store); success = true; } -#if PLATFORM(CF) +#if USE(CF) else if (filenamePolicy == DragData::ConvertFilenames) { if (SUCCEEDED(dataObject->GetData(filenameWFormat(), &store))) { // file using unicode @@ -434,7 +434,7 @@ String getURL(const DragDataMap* data, DragData::FilenameConversionPolicy filena return extractURL(url, title); if (getDataMapItem(data, urlFormat(), url)) return extractURL(url, title); -#if PLATFORM(CF) +#if USE(CF) if (filenamePolicy != DragData::ConvertFilenames) return url; @@ -654,7 +654,7 @@ void getUtf8Data(IDataObject* data, FORMATETC* format, Vector<String>& dataStrin ReleaseStgMedium(&store); } -#if PLATFORM(CF) +#if USE(CF) void getCFData(IDataObject* data, FORMATETC* format, Vector<String>& dataStrings) { STGMEDIUM store; @@ -710,7 +710,7 @@ void setUtf8Data(IDataObject* data, FORMATETC* format, const Vector<String>& dat ::GlobalFree(medium.hGlobal); } -#if PLATFORM(CF) +#if USE(CF) void setCFData(IDataObject* data, FORMATETC* format, const Vector<String>& dataStrings) { STGMEDIUM medium = {0}; @@ -738,7 +738,7 @@ static const ClipboardFormatMap& getClipboardMap() formatMap.add(texthtmlFormat()->cfFormat, new ClipboardDataItem(texthtmlFormat(), getStringData<UChar>, setUCharData)); formatMap.add(plainTextFormat()->cfFormat, new ClipboardDataItem(plainTextFormat(), getStringData<char>, setUtf8Data)); formatMap.add(plainTextWFormat()->cfFormat, new ClipboardDataItem(plainTextWFormat(), getStringData<UChar>, setUCharData)); -#if PLATFORM(CF) +#if USE(CF) formatMap.add(cfHDropFormat()->cfFormat, new ClipboardDataItem(cfHDropFormat(), getCFData, setCFData)); #endif formatMap.add(filenameFormat()->cfFormat, new ClipboardDataItem(filenameFormat(), getStringData<char>, setUtf8Data)); diff --git a/Source/WebCore/platform/win/ClipboardWin.cpp b/Source/WebCore/platform/win/ClipboardWin.cpp index c0af712..791ec86 100644 --- a/Source/WebCore/platform/win/ClipboardWin.cpp +++ b/Source/WebCore/platform/win/ClipboardWin.cpp @@ -318,7 +318,7 @@ static HRESULT writeFileToDataObject(IDataObject* dataObject, HGLOBAL fileDescri if (FAILED(hr = dataObject->SetData(fe, &medium, TRUE))) goto exit; -#if PLATFORM(CF) +#if USE(CF) // HDROP if (hDropContent) { medium.hGlobal = hDropContent; diff --git a/Source/WebCore/platform/win/DragImageWin.cpp b/Source/WebCore/platform/win/DragImageWin.cpp index 4e5d168..0d67002 100644 --- a/Source/WebCore/platform/win/DragImageWin.cpp +++ b/Source/WebCore/platform/win/DragImageWin.cpp @@ -210,13 +210,13 @@ DragImageRef createDragImageForLink(KURL& url, const String& inLabel, Frame* fra static const Color bottomColor(255, 255, 255, 127); // original alpha = 0.5 if (drawURLString) { if (clipURLString) - urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont, false); + urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont); IntPoint textPos(DragLabelBorderX, imageSize.height() - (LabelBorderYOffset + urlFont->fontMetrics().descent())); WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, topColor, bottomColor); } if (clipLabelString) - label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont, false); + label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont); IntPoint textPos(DragLabelBorderX, DragLabelBorderY + labelFont->pixelSize()); WebCoreDrawDoubledTextAtPoint(context, label, textPos, *labelFont, topColor, bottomColor); diff --git a/Source/WebCore/platform/win/FileChooserWin.cpp b/Source/WebCore/platform/win/FileChooserWin.cpp index 195b8eb..708a067 100644 --- a/Source/WebCore/platform/win/FileChooserWin.cpp +++ b/Source/WebCore/platform/win/FileChooserWin.cpp @@ -26,10 +26,9 @@ #include "config.h" #include "FileChooser.h" +#include "FileSystem.h" #include "LocalizedStrings.h" #include "StringTruncator.h" -#include <shlwapi.h> -#include <windows.h> namespace WebCore { @@ -41,14 +40,12 @@ String FileChooser::basenameForWidth(const Font& font, int width) const String string; if (m_filenames.isEmpty()) string = fileButtonNoFileSelectedLabel(); - else if (m_filenames.size() == 1) { - String tmpFilename = m_filenames[0]; - LPWSTR basename = PathFindFileNameW(tmpFilename.charactersWithNullTermination()); - string = String(basename); - } else - return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font, false); + else if (m_filenames.size() == 1) + string = pathGetFileName(m_filenames[0]); + else + return StringTruncator::rightTruncate(String::number(m_filenames.size()) + " files", width, font); - return StringTruncator::centerTruncate(string, width, font, false); + return StringTruncator::centerTruncate(string, width, font); } } // namespace WebCore diff --git a/Source/WebCore/platform/win/PopupMenuWin.cpp b/Source/WebCore/platform/win/PopupMenuWin.cpp index 3f3afa2..c75e219 100644 --- a/Source/WebCore/platform/win/PopupMenuWin.cpp +++ b/Source/WebCore/platform/win/PopupMenuWin.cpp @@ -326,7 +326,7 @@ void PopupMenuWin::calculatePositionAndSize(const IntRect& r, FrameView* v) itemFont.update(m_popupClient->fontSelector()); } - popupWidth = max(popupWidth, itemFont.width(TextRun(text.characters(), text.length()))); + popupWidth = max(popupWidth, static_cast<int>(ceilf(itemFont.width(TextRun(text.characters(), text.length()))))); } if (naturalHeight > maxPopupHeight) diff --git a/Source/WebCore/platform/wince/KeygenWinCE.cpp b/Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp index 8537f44..50aee8e 100644 --- a/Source/WebCore/platform/wince/KeygenWinCE.cpp +++ b/Source/WebCore/platform/win/SSLKeyGeneratorWin.cpp @@ -43,10 +43,10 @@ String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& PCERT_PUBLIC_KEY_INFO pPubInfo = 0; // Try to delete it if it exists already - CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); + CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); do { - if (!CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) + if (!CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) break; DWORD dwPubInfoLength = 0; @@ -85,7 +85,7 @@ String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& if (pPubInfo) fastFree(pPubInfo); - + if (hKey) CryptDestroyKey(hKey); diff --git a/Source/WebCore/platform/win/SearchPopupMenuWin.cpp b/Source/WebCore/platform/win/SearchPopupMenuWin.cpp index 7ae800b..a5ca9b7 100644 --- a/Source/WebCore/platform/win/SearchPopupMenuWin.cpp +++ b/Source/WebCore/platform/win/SearchPopupMenuWin.cpp @@ -23,7 +23,7 @@ #include <wtf/text/AtomicString.h> -#if PLATFORM(CF) +#if USE(CF) #include <wtf/RetainPtr.h> #endif @@ -41,14 +41,14 @@ PopupMenu* SearchPopupMenuWin::popupMenu() bool SearchPopupMenuWin::enabled() { -#if PLATFORM(CF) +#if USE(CF) return true; #else return false; #endif } -#if PLATFORM(CF) +#if USE(CF) static RetainPtr<CFStringRef> autosaveKey(const String& name) { String key = "com.apple.WebKit.searchField:" + name; @@ -61,7 +61,7 @@ void SearchPopupMenuWin::saveRecentSearches(const AtomicString& name, const Vect if (name.isEmpty()) return; -#if PLATFORM(CF) +#if USE(CF) RetainPtr<CFMutableArrayRef> items; size_t size = searchItems.size(); @@ -83,7 +83,7 @@ void SearchPopupMenuWin::loadRecentSearches(const AtomicString& name, Vector<Str if (name.isEmpty()) return; -#if PLATFORM(CF) +#if USE(CF) searchItems.clear(); RetainPtr<CFArrayRef> items(AdoptCF, reinterpret_cast<CFArrayRef>(CFPreferencesCopyAppValue(autosaveKey(name).get(), kCFPreferencesCurrentApplication))); diff --git a/Source/WebCore/platform/win/TemporaryLinkStubs.cpp b/Source/WebCore/platform/win/TemporaryLinkStubs.cpp index d82f21c..46a0714 100644 --- a/Source/WebCore/platform/win/TemporaryLinkStubs.cpp +++ b/Source/WebCore/platform/win/TemporaryLinkStubs.cpp @@ -33,4 +33,10 @@ namespace WebCore { // <keygen> String signedPublicKeyAndChallengeString(unsigned, const String&, const KURL&) { notImplemented(); return String(); } void getSupportedKeySizes(Vector<String>&) { notImplemented(); } + +#if !USE(CFNETWORK) +void startObservingCookieChanges() { notImplemented(); } +void stopObservingCookieChanges() { notImplemented(); } +#endif + } // namespace WebCore diff --git a/Source/WebCore/platform/win/WebCoreTextRenderer.cpp b/Source/WebCore/platform/win/WebCoreTextRenderer.cpp index e96ba31..717e31d 100644 --- a/Source/WebCore/platform/win/WebCoreTextRenderer.cpp +++ b/Source/WebCore/platform/win/WebCoreTextRenderer.cpp @@ -101,7 +101,7 @@ void WebCoreDrawDoubledTextAtPoint(GraphicsContext& context, const String& text, float WebCoreTextFloatWidth(const String& text, const Font& font) { - return StringTruncator::width(text, font, false); + return StringTruncator::width(text, font); } void WebCoreSetShouldUseFontSmoothing(bool smooth) diff --git a/Source/WebCore/platform/win/Win32Handle.h b/Source/WebCore/platform/win/Win32Handle.h new file mode 100644 index 0000000..cefdf42 --- /dev/null +++ b/Source/WebCore/platform/win/Win32Handle.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Patrick Gansterer <paroga@paroga.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 AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Win32Handle_h +#define Win32Handle_h + +#include <memory> +#include <windows.h> +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class Win32Handle { + WTF_MAKE_NONCOPYABLE(Win32Handle); +public: + Win32Handle() : m_handle(INVALID_HANDLE_VALUE) { } + explicit Win32Handle(HANDLE handle) : m_handle(handle) { } + + ~Win32Handle() { clear(); } + + void clear() + { + if (!isValid()) + return; + CloseHandle(m_handle); + m_handle = INVALID_HANDLE_VALUE; + } + + bool isValid() const { return m_handle != INVALID_HANDLE_VALUE; } + + HANDLE get() const { return m_handle; } + HANDLE release() { HANDLE ret = m_handle; m_handle = INVALID_HANDLE_VALUE; return ret; } + + Win32Handle& operator=(HANDLE handle) + { + clear(); + m_handle = handle; + } + +private: + HANDLE m_handle; +}; + +} // namespace WebCore + +#endif // Win32Handle_h diff --git a/Source/WebCore/platform/wx/DragDataWx.cpp b/Source/WebCore/platform/wx/DragDataWx.cpp index 53b4219..be24042 100644 --- a/Source/WebCore/platform/wx/DragDataWx.cpp +++ b/Source/WebCore/platform/wx/DragDataWx.cpp @@ -28,6 +28,7 @@ #include "Document.h" #include "DocumentFragment.h" +#include "Range.h" namespace WebCore { diff --git a/Source/WebCore/platform/wx/LocalizedStringsWx.cpp b/Source/WebCore/platform/wx/LocalizedStringsWx.cpp index 4b56394..835c3cd 100644 --- a/Source/WebCore/platform/wx/LocalizedStringsWx.cpp +++ b/Source/WebCore/platform/wx/LocalizedStringsWx.cpp @@ -47,6 +47,11 @@ String resetButtonDefaultLabel() return String("Reset"); } +String defaultDetailsSummaryText() +{ + return String("Details"); +} + String platformDefaultLanguage() { return String("en"); diff --git a/Source/WebCore/platform/wx/WidgetWx.cpp b/Source/WebCore/platform/wx/WidgetWx.cpp index 7591a5b..9de4c3d 100644 --- a/Source/WebCore/platform/wx/WidgetWx.cpp +++ b/Source/WebCore/platform/wx/WidgetWx.cpp @@ -80,10 +80,6 @@ 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); diff --git a/Source/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp b/Source/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp index 2fcd761..c1320c3 100644 --- a/Source/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp +++ b/Source/WebCore/platform/wx/wxcode/win/non-kerned-drawing.cpp @@ -79,7 +79,7 @@ void drawTextWithSpacing(GraphicsContext* graphicsContext, const SimpleFontData* // get the native HDC handle to draw using native APIs HDC hdc = 0; - float y = point.y() - font->ascent(); + float y = point.y() - font->fontMetrics().ascent(); float x = point.x(); #if USE(WXGC) |