diff options
author | Steve Block <steveblock@google.com> | 2010-08-24 07:50:47 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-08-24 07:50:47 -0700 |
commit | c570a147a94b126d4172c30914f53dea17b4c8f5 (patch) | |
tree | 99c11741887d21f65d67c5bbdab58b7ba2a5d4d5 /WebCore/platform | |
parent | c952714bc6809a5ad081baaf9fcc04107b92ea3f (diff) | |
parent | 6c65f16005b91786c2b7c0791b9ea1dd684d57f4 (diff) | |
download | external_webkit-c570a147a94b126d4172c30914f53dea17b4c8f5.zip external_webkit-c570a147a94b126d4172c30914f53dea17b4c8f5.tar.gz external_webkit-c570a147a94b126d4172c30914f53dea17b4c8f5.tar.bz2 |
Merge changes I2e7e2317,Ie6ccde3a,I3e89f231,Id06ff339,I268dfe7d,Icaf70d9f,Ie234f1a0,Iff5c7aaa,I69b75bf0,Ifbf384f4
* changes:
Merge WebKit at r65615 : Update WebKit revision number
Merge WebKit at r65615 : Ignore http/tests/appcache/origin-quota.html
Merge WebKit at r65615 : Android-specific results for Geolocation tests.
Merge WebKit at r65615 : Fix GraphicsContext and ImageBuffer.
Merge WebKit at r65615 : processingUserGesture() is now static.
Merge WebKit at r65615 : UTF8String() becomes utf8().
Merge WebKit at r65615 : Fix include paths for string headers.
Merge WebKit at r65615 : Fix Makefiles.
Merge WebKit at r65615 : Fix conflicts.
Merge WebKit at r65615 : Initial merge by git.
Diffstat (limited to 'WebCore/platform')
179 files changed, 3472 insertions, 1044 deletions
diff --git a/WebCore/platform/ContentType.cpp b/WebCore/platform/ContentType.cpp index 3dce7b5..c094d54 100644 --- a/WebCore/platform/ContentType.cpp +++ b/WebCore/platform/ContentType.cpp @@ -41,14 +41,14 @@ String ContentType::parameter(const String& parameterName) const String strippedType = m_type.stripWhiteSpace(); // a MIME type can have one or more "param=value" after a semi-colon, and separated from each other by semi-colons - int semi = strippedType.find(';'); - if (semi != -1) { - int start = strippedType.find(parameterName, semi + 1, false); - if (start != -1) { + size_t semi = strippedType.find(';'); + if (semi != notFound) { + size_t start = strippedType.find(parameterName, semi + 1, false); + if (start != notFound) { start = strippedType.find('=', start + 6); - if (start != -1) { - int end = strippedType.find(';', start + 6); - if (end == -1) + if (start != notFound) { + size_t end = strippedType.find(';', start + 6); + if (end == notFound) end = strippedType.length(); parameterValue = strippedType.substring(start + 1, end - (start + 1)).stripWhiteSpace(); } @@ -63,8 +63,8 @@ String ContentType::type() const String strippedType = m_type.stripWhiteSpace(); // "type" can have parameters after a semi-colon, strip them - int semi = strippedType.find(';'); - if (semi != -1) + size_t semi = strippedType.find(';'); + if (semi != notFound) strippedType = strippedType.left(semi).stripWhiteSpace(); return strippedType; diff --git a/WebCore/platform/Cookie.h b/WebCore/platform/Cookie.h index 0fe3851..4eea7d2 100644 --- a/WebCore/platform/Cookie.h +++ b/WebCore/platform/Cookie.h @@ -27,7 +27,7 @@ #define Cookie_h #include "PlatformString.h" -#include "StringHash.h" +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/FileSystem.cpp b/WebCore/platform/FileSystem.cpp new file mode 100644 index 0000000..511f8aa --- /dev/null +++ b/WebCore/platform/FileSystem.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2007 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 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 "FileSystem.h" + +namespace WebCore { + +// The following lower-ASCII characters need escaping to be used in a filename +// across all systems, including Windows: +// - Unprintable ASCII (00-1F) +// - Space (20) +// - Double quote (22) +// - Percent (25) (escaped because it is our escape character) +// - Asterisk (2A) +// - Slash (2F) +// - Colon (3A) +// - Less-than (3C) +// - Greater-than (3E) +// - Question Mark (3F) +// - Backslash (5C) +// - Pipe (7C) +// - Delete (7F) + +static const bool needsEscaping[128] = { + /* 00-07 */ true, true, true, true, true, true, true, true, + /* 08-0F */ true, true, true, true, true, true, true, true, + + /* 10-17 */ true, true, true, true, true, true, true, true, + /* 18-1F */ true, true, true, true, true, true, true, true, + + /* 20-27 */ true, false, true, false, false, true, false, false, + /* 28-2F */ false, false, true, false, false, false, false, true, + + /* 30-37 */ false, false, false, false, false, false, false, false, + /* 38-3F */ false, false, true, false, true, false, true, true, + + /* 40-47 */ false, false, false, false, false, false, false, false, + /* 48-4F */ false, false, false, false, false, false, false, false, + + /* 50-57 */ false, false, false, false, false, false, false, false, + /* 58-5F */ false, false, false, false, true, false, false, false, + + /* 60-67 */ false, false, false, false, false, false, false, false, + /* 68-6F */ false, false, false, false, false, false, false, false, + + /* 70-77 */ false, false, false, false, false, false, false, false, + /* 78-7F */ false, false, false, false, true, false, false, true, +}; + +static inline bool shouldEscapeUChar(UChar c) +{ + return c > 127 ? false : needsEscaping[c]; +} + +static const char hexDigits[17] = "0123456789ABCDEF"; + +String encodeForFileName(const String& inputStr) +{ + unsigned length = inputStr.length(); + Vector<UChar, 512> buffer(length * 3 + 1); + UChar* p = buffer.data(); + + const UChar* str = inputStr.characters(); + const UChar* strEnd = str + length; + + while (str < strEnd) { + UChar c = *str++; + if (shouldEscapeUChar(c)) { + *p++ = '%'; + *p++ = hexDigits[(c >> 4) & 0xF]; + *p++ = hexDigits[c & 0xF]; + } else + *p++ = c; + } + + ASSERT(p - buffer.data() <= static_cast<int>(buffer.size())); + + return String(buffer.data(), p - buffer.data()); +} + +} // namespace WebCore diff --git a/WebCore/platform/FileSystem.h b/WebCore/platform/FileSystem.h index 617470b..ec75a21 100644 --- a/WebCore/platform/FileSystem.h +++ b/WebCore/platform/FileSystem.h @@ -170,6 +170,9 @@ int readFromFile(PlatformFileHandle, char* data, int length); // Methods for dealing with loadable modules bool unloadModule(PlatformModule); +// Encode a string for use within a file name. +String encodeForFileName(const String&); + #if PLATFORM(WIN) String localUserSpecificStorageDirectory(); String roamingUserSpecificStorageDirectory(); diff --git a/WebCore/platform/KURL.cpp b/WebCore/platform/KURL.cpp index 9ed900f..16b84b5 100644 --- a/WebCore/platform/KURL.cpp +++ b/WebCore/platform/KURL.cpp @@ -29,11 +29,11 @@ #include "KURL.h" -#include "StringHash.h" #include "TextEncoding.h" #include <wtf/text/CString.h> #include <wtf/HashMap.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #if USE(ICU_UNICODE) #include <unicode/uidna.h> @@ -551,12 +551,12 @@ String KURL::lastPathComponent() const if (!hasPath()) return String(); - int end = m_pathEnd - 1; + unsigned end = m_pathEnd - 1; if (m_string[end] == '/') --end; - int start = m_string.reverseFind('/', end); - if (start < m_portEnd) + size_t start = m_string.reverseFind('/', end); + if (start < static_cast<unsigned>(m_portEnd)) return String(); ++start; @@ -675,7 +675,7 @@ String KURL::path() const bool KURL::setProtocol(const String& s) { // Firefox and IE remove everything after the first ':'. - int separatorPosition = s.find(':'); + size_t separatorPosition = s.find(':'); String newProtocol = s.substring(0, separatorPosition); if (!isValidProtocol(newProtocol)) @@ -882,13 +882,13 @@ String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding) CharBuffer buffer; - int length = str.length(); - int decodedPosition = 0; - int searchPosition = 0; - int encodedRunPosition; - while ((encodedRunPosition = str.find('%', searchPosition)) >= 0) { + unsigned length = str.length(); + unsigned decodedPosition = 0; + unsigned searchPosition = 0; + size_t encodedRunPosition; + while ((encodedRunPosition = str.find('%', searchPosition)) != notFound) { // Find the sequence of %-escape codes. - int encodedRunEnd = encodedRunPosition; + unsigned encodedRunEnd = encodedRunPosition; while (length - encodedRunEnd >= 3 && str[encodedRunEnd] == '%' && isASCIIHexDigit(str[encodedRunEnd + 1]) @@ -1614,13 +1614,13 @@ static void encodeRelativeString(const String& rel, const TextEncoding& encoding static String substituteBackslashes(const String& string) { - int questionPos = string.find('?'); - int hashPos = string.find('#'); - int pathEnd; + size_t questionPos = string.find('?'); + size_t hashPos = string.find('#'); + unsigned pathEnd; - if (hashPos >= 0 && (questionPos < 0 || questionPos > hashPos)) + if (hashPos != notFound && (questionPos == notFound || questionPos > hashPos)) pathEnd = hashPos; - else if (questionPos >= 0) + else if (questionPos != notFound) pathEnd = questionPos; else pathEnd = string.length(); @@ -1799,13 +1799,12 @@ bool portAllowed(const KURL& url) String mimeTypeFromDataURL(const String& url) { ASSERT(protocolIs(url, "data")); - int index = url.find(';'); - if (index == -1) + size_t index = url.find(';'); + if (index == notFound) index = url.find(','); - if (index != -1) { - int len = index - 5; - if (len > 0) - return url.substring(5, len); + if (index != notFound) { + if (index > 5) + return url.substring(5, index - 5); return "text/plain"; // Data URLs with no MIME type are considered text/plain. } return ""; diff --git a/WebCore/platform/KURLGoogle.cpp b/WebCore/platform/KURLGoogle.cpp index ac02630..3d23fcf 100644 --- a/WebCore/platform/KURLGoogle.cpp +++ b/WebCore/platform/KURLGoogle.cpp @@ -40,13 +40,13 @@ #include <algorithm> -#include "StringHash.h" #include "NotImplemented.h" #include "TextEncoding.h" #include <wtf/HashMap.h> #include <wtf/Vector.h> #include <wtf/StdLibExtras.h> #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> #include <googleurl/src/url_util.h> diff --git a/WebCore/platform/KURLHash.h b/WebCore/platform/KURLHash.h index 283170b..44a4624 100644 --- a/WebCore/platform/KURLHash.h +++ b/WebCore/platform/KURLHash.h @@ -28,7 +28,7 @@ #include "KURL.h" #include "PlatformString.h" -#include "StringHash.h" +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/Length.cpp b/WebCore/platform/Length.cpp index 3757d92..e2fd9b8 100644 --- a/WebCore/platform/Length.cpp +++ b/WebCore/platform/Length.cpp @@ -26,9 +26,9 @@ #include "Length.h" #include "PlatformString.h" -#include "StringBuffer.h" #include <wtf/ASCIICType.h> #include <wtf/Assertions.h> +#include <wtf/text/StringBuffer.h> using namespace WTF; @@ -103,10 +103,10 @@ Length* newCoordsArray(const String& string, int& len) Length* r = new Length[len]; int i = 0; - int pos = 0; - int pos2; + unsigned pos = 0; + size_t pos2; - while ((pos2 = str->find(' ', pos)) != -1) { + while ((pos2 = str->find(' ', pos)) != notFound) { r[i++] = parseLength(str->characters() + pos, pos2 - pos); pos = pos2+1; } @@ -129,10 +129,10 @@ Length* newLengthArray(const String& string, int& len) Length* r = new Length[len]; int i = 0; - int pos = 0; - int pos2; + unsigned pos = 0; + size_t pos2; - while ((pos2 = str->find(',', pos)) != -1) { + while ((pos2 = str->find(',', pos)) != notFound) { r[i++] = parseLength(str->characters() + pos, pos2 - pos); pos = pos2+1; } diff --git a/WebCore/platform/LinkHash.cpp b/WebCore/platform/LinkHash.cpp index 12437ab..86b4c8a 100644 --- a/WebCore/platform/LinkHash.cpp +++ b/WebCore/platform/LinkHash.cpp @@ -22,49 +22,49 @@ */ #include "config.h" -#include "AtomicString.h" #include "KURL.h" #include "LinkHash.h" #include "PlatformString.h" -#include "StringHash.h" -#include "StringImpl.h" +#include <wtf/text/AtomicString.h> +#include <wtf/text/StringHash.h> +#include <wtf/text/StringImpl.h> namespace WebCore { -static inline int findSlashDotDotSlash(const UChar* characters, size_t length) +static inline size_t findSlashDotDotSlash(const UChar* characters, size_t length) { if (length < 4) - return -1; + return notFound; unsigned loopLimit = length - 3; for (unsigned i = 0; i < loopLimit; ++i) { if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/') return i; } - return -1; + return notFound; } -static inline int findSlashSlash(const UChar* characters, size_t length, int position) +static inline size_t findSlashSlash(const UChar* characters, size_t length, int position) { if (length < 2) - return -1; + return notFound; unsigned loopLimit = length - 1; for (unsigned i = position; i < loopLimit; ++i) { if (characters[i] == '/' && characters[i + 1] == '/') return i; } - return -1; + return notFound; } -static inline int findSlashDotSlash(const UChar* characters, size_t length) +static inline size_t findSlashDotSlash(const UChar* characters, size_t length) { if (length < 3) - return -1; + return notFound; unsigned loopLimit = length - 2; for (unsigned i = 0; i < loopLimit; ++i) { if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/') return i; } - return -1; + return notFound; } static inline bool containsColonSlashSlash(const UChar* characters, unsigned length) @@ -82,36 +82,32 @@ static inline bool containsColonSlashSlash(const UChar* characters, unsigned len static inline void cleanPath(Vector<UChar, 512>& path) { // FIXME: Should not do this in the query or anchor part. - int pos; - while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) { - int prev = reverseFind(path.data(), path.size(), '/', pos - 1); + size_t pos; + while ((pos = findSlashDotDotSlash(path.data(), path.size())) != notFound) { + size_t prev = reverseFind(path.data(), path.size(), '/', pos - 1); // don't remove the host, i.e. http://foo.org/../foo.html - if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/')) + if (prev == notFound || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/')) path.remove(pos, 3); else path.remove(prev, pos - prev + 3); } // FIXME: Should not do this in the query part. - // Set refPos to -2 to mean "I haven't looked for the anchor yet". - // We don't want to waste a function call on the search for the the anchor - // in the vast majority of cases where there is no "//" in the path. pos = 0; - int refPos = -2; - while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) { - if (refPos == -2) - refPos = find(path.data(), path.size(), '#'); - if (refPos > 0 && pos >= refPos) - break; - - if (pos == 0 || path[pos - 1] != ':') - path.remove(pos); - else - pos += 2; + if ((pos = findSlashSlash(path.data(), path.size(), pos)) != notFound) { + size_t refPos = find(path.data(), path.size(), '#'); + while (refPos == 0 || refPos == notFound || pos < refPos) { + if (pos == 0 || path[pos - 1] != ':') + path.remove(pos); + else + pos += 2; + if ((pos = findSlashSlash(path.data(), path.size(), pos)) == notFound) + break; + } } // FIXME: Should not do this in the query or anchor part. - while ((pos = findSlashDotSlash(path.data(), path.size())) != -1) + while ((pos = findSlashDotSlash(path.data(), path.size())) != notFound) path.remove(pos, 2); } diff --git a/WebCore/platform/LinkHash.h b/WebCore/platform/LinkHash.h index a499a8e..dc494d2 100644 --- a/WebCore/platform/LinkHash.h +++ b/WebCore/platform/LinkHash.h @@ -26,8 +26,8 @@ #ifndef LinkHash_h #define LinkHash_h -#include "StringHash.h" #include <wtf/Forward.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/MIMETypeRegistry.cpp b/WebCore/platform/MIMETypeRegistry.cpp index e9e5dd3..b489d3b 100644 --- a/WebCore/platform/MIMETypeRegistry.cpp +++ b/WebCore/platform/MIMETypeRegistry.cpp @@ -31,10 +31,10 @@ #include "ArchiveFactory.h" #endif #include "MediaPlayer.h" -#include "StringHash.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #if PLATFORM(CG) #include "ImageSourceCG.h" @@ -403,8 +403,8 @@ static void initializeMIMETypeRegistry() String MIMETypeRegistry::getMIMETypeForPath(const String& path) { - int pos = path.reverseFind('.'); - if (pos >= 0) { + size_t pos = path.reverseFind('.'); + if (pos != notFound) { String extension = path.substring(pos + 1); String result = getMIMETypeForExtension(extension); if (result.length()) diff --git a/WebCore/platform/MIMETypeRegistry.h b/WebCore/platform/MIMETypeRegistry.h index f71b478..64abea8 100644 --- a/WebCore/platform/MIMETypeRegistry.h +++ b/WebCore/platform/MIMETypeRegistry.h @@ -27,9 +27,9 @@ #define MIMETypeRegistry_h #include "PlatformString.h" -#include "StringHash.h" #include <wtf/HashSet.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/SchemeRegistry.cpp b/WebCore/platform/SchemeRegistry.cpp index 0423236..58df51a 100644 --- a/WebCore/platform/SchemeRegistry.cpp +++ b/WebCore/platform/SchemeRegistry.cpp @@ -113,8 +113,8 @@ bool SchemeRegistry::shouldTreatURLAsLocal(const String& url) return true; } - int loc = url.find(':'); - if (loc == -1) + size_t loc = url.find(':'); + if (loc == notFound) return false; String scheme = url.left(loc); diff --git a/WebCore/platform/SchemeRegistry.h b/WebCore/platform/SchemeRegistry.h index d92ec4e..56e3b33 100644 --- a/WebCore/platform/SchemeRegistry.h +++ b/WebCore/platform/SchemeRegistry.h @@ -27,8 +27,8 @@ #define SchemeRegistry_h #include "PlatformString.h" -#include "StringHash.h" #include <wtf/HashSet.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/ScrollView.cpp b/WebCore/platform/ScrollView.cpp index ddecf1e..615ae5d 100644 --- a/WebCore/platform/ScrollView.cpp +++ b/WebCore/platform/ScrollView.cpp @@ -322,6 +322,7 @@ void ScrollView::valueChanged(Scrollbar* scrollbar) if (scrollbarsSuppressed()) return; + repaintFixedElementsAfterScrolling(); scrollContents(scrollDelta); } diff --git a/WebCore/platform/ThreadGlobalData.cpp b/WebCore/platform/ThreadGlobalData.cpp index 99cd44a..6d7eb51 100644 --- a/WebCore/platform/ThreadGlobalData.cpp +++ b/WebCore/platform/ThreadGlobalData.cpp @@ -28,10 +28,10 @@ #include "ThreadGlobalData.h" #include "EventNames.h" -#include "StringImpl.h" #include "ThreadTimers.h" #include <wtf/UnusedParam.h> #include <wtf/WTFThreadData.h> +#include <wtf/text/StringImpl.h> #if USE(ICU_UNICODE) #include "TextCodecICU.h" diff --git a/WebCore/platform/ThreadGlobalData.h b/WebCore/platform/ThreadGlobalData.h index c17fbeb..9f57f00 100644 --- a/WebCore/platform/ThreadGlobalData.h +++ b/WebCore/platform/ThreadGlobalData.h @@ -27,10 +27,10 @@ #ifndef ThreadGlobalData_h #define ThreadGlobalData_h -#include "StringHash.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> +#include <wtf/text/StringHash.h> #if ENABLE(WORKERS) #include <wtf/ThreadSpecific.h> diff --git a/WebCore/platform/android/PackageNotifier.h b/WebCore/platform/android/PackageNotifier.h index d9b4fd4..8191d84 100644 --- a/WebCore/platform/android/PackageNotifier.h +++ b/WebCore/platform/android/PackageNotifier.h @@ -29,10 +29,11 @@ #if ENABLE(APPLICATION_INSTALLED) #include "PlatformString.h" -#include "StringHash.h" #include "Timer.h" + #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/android/PopupMenuAndroid.cpp b/WebCore/platform/android/PopupMenuAndroid.cpp new file mode 100644 index 0000000..8a1ed07 --- /dev/null +++ b/WebCore/platform/android/PopupMenuAndroid.cpp @@ -0,0 +1,57 @@ +/* + * This file is part of the popup menu implementation for <select> elements in WebCore. + * + * Copyright 2009, The Android Open Source Project + * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006 Michael Emmel mike.emmel@gmail.com + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "config.h" +#include "PopupMenu.h" + +namespace WebCore { + +// Now we handle all of this in WebViewCore.cpp. +PopupMenu::PopupMenu(PopupMenuClient* menuList) + : m_popupClient(menuList) +{ +} + +PopupMenu::~PopupMenu() +{ +} + +void PopupMenu::show(const IntRect&, FrameView*, int) +{ +} + +void PopupMenu::hide() +{ +} + +void PopupMenu::updateFromElement() +{ +} + +bool PopupMenu::itemWritingDirectionIsNatural() +{ + return false; +} + +} // namespace WebCore diff --git a/WebCore/platform/android/SearchPopupMenuAndroid.cpp b/WebCore/platform/android/SearchPopupMenuAndroid.cpp new file mode 100644 index 0000000..0d67fdd --- /dev/null +++ b/WebCore/platform/android/SearchPopupMenuAndroid.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2006, The Android Open Source Project + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 "SearchPopupMenu.h" + +namespace WebCore { + +// Save the past searches stored in 'searchItems' to a database associated with 'name' +void SearchPopupMenu::saveRecentSearches(const AtomicString& name, const Vector<String>& searchItems) +{ +} + +// Load past searches associated with 'name' from the database to 'searchItems' +void SearchPopupMenu::loadRecentSearches(const AtomicString& name, Vector<String>& searchItems) +{ +} + +// Create a search popup menu - not sure what else we have to do here +SearchPopupMenu::SearchPopupMenu(PopupMenuClient* client) + : PopupMenu(client) +{ +} + +bool SearchPopupMenu::enabled() +{ + return false; +} + +} // namespace WebCore diff --git a/WebCore/platform/cf/BinaryPropertyList.cpp b/WebCore/platform/cf/BinaryPropertyList.cpp index f0facae..27b44d4 100644 --- a/WebCore/platform/cf/BinaryPropertyList.cpp +++ b/WebCore/platform/cf/BinaryPropertyList.cpp @@ -26,9 +26,9 @@ #include "config.h" #include "BinaryPropertyList.h" -#include "StringHash.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> +#include <wtf/text/StringHash.h> #include <limits> using namespace std; diff --git a/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm b/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm index e532d57..bafc96e 100644 --- a/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm +++ b/WebCore/platform/chromium/ScrollbarThemeChromiumMac.mm @@ -452,9 +452,8 @@ bool ScrollbarThemeChromiumMac::paint(Scrollbar* scrollbar, GraphicsContext* con HIThemeDrawTrack(&trackInfo, 0, drawingContext->platformContext(), kHIThemeOrientationNormal); } - if (!canDrawDirectly) { - context->drawImage(imageBuffer->image(), DeviceColorSpace, scrollbar->frameRect().location()); - } + if (!canDrawDirectly) + context->drawImageBuffer(imageBuffer.get(), DeviceColorSpace, scrollbar->frameRect().location()); return true; } diff --git a/WebCore/platform/chromium/SearchPopupMenuChromium.cpp b/WebCore/platform/chromium/SearchPopupMenuChromium.cpp index d4d4ff5..dc06b5a 100644 --- a/WebCore/platform/chromium/SearchPopupMenuChromium.cpp +++ b/WebCore/platform/chromium/SearchPopupMenuChromium.cpp @@ -32,8 +32,8 @@ #include "config.h" #include "SearchPopupMenuChromium.h" -#include "AtomicString.h" #include "NotImplemented.h" +#include <wtf/text/AtomicString.h> namespace WebCore { diff --git a/WebCore/platform/efl/ClipboardEfl.cpp b/WebCore/platform/efl/ClipboardEfl.cpp index 60146b5..caff813 100644 --- a/WebCore/platform/efl/ClipboardEfl.cpp +++ b/WebCore/platform/efl/ClipboardEfl.cpp @@ -24,7 +24,7 @@ #include "Editor.h" #include "FileList.h" #include "NotImplemented.h" -#include "StringHash.h" +#include <wtf/text/StringHash.h> namespace WebCore { PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy, Frame*) diff --git a/WebCore/platform/efl/CookieJarEfl.cpp b/WebCore/platform/efl/CookieJarEfl.cpp index 01dcddb..6c78dbd 100644 --- a/WebCore/platform/efl/CookieJarEfl.cpp +++ b/WebCore/platform/efl/CookieJarEfl.cpp @@ -30,9 +30,8 @@ #include "KURL.h" #include "PlatformString.h" -#include "StringHash.h" - #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/efl/LocalizedStringsEfl.cpp b/WebCore/platform/efl/LocalizedStringsEfl.cpp index a58dba2..6023205 100644 --- a/WebCore/platform/efl/LocalizedStringsEfl.cpp +++ b/WebCore/platform/efl/LocalizedStringsEfl.cpp @@ -350,6 +350,26 @@ String imageTitle(const String& filename, const IntSize& size) return String(); } +#if ENABLE(VIDEO) +String localizedMediaControlElementString(const String& name) +{ + notImplemented(); + return String(); +} + +String localizedMediaControlElementHelpText(const String& name) +{ + notImplemented(); + return String(); +} + +String localizedMediaTimeDescription(float time) +{ + notImplemented(); + return String(); +} +#endif + String mediaElementLoadingStateText() { return String::fromUTF8("Loading..."); diff --git a/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp b/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp index 70e317e..fd84b15 100644 --- a/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp +++ b/WebCore/platform/efl/PlatformKeyboardEventEfl.cpp @@ -33,7 +33,6 @@ #include "PlatformKeyboardEvent.h" #include "NotImplemented.h" -#include "StringHash.h" #include "TextEncoding.h" #include "WindowsKeyboardCodes.h" @@ -41,6 +40,7 @@ #include <stdio.h> #include <wtf/HashMap.h> #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/graphics/ANGLEWebKitBridge.cpp b/WebCore/platform/graphics/ANGLEWebKitBridge.cpp new file mode 100644 index 0000000..9a14820 --- /dev/null +++ b/WebCore/platform/graphics/ANGLEWebKitBridge.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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" + +#if ENABLE(3D_CANVAS) + +#include "ANGLEWebKitBridge.h" + +namespace WebCore { + + +ANGLEWebKitBridge::ANGLEWebKitBridge() : + builtCompilers(false) +{ + ShInitialize(); +} + +ANGLEWebKitBridge::~ANGLEWebKitBridge() +{ + if (builtCompilers) { + ShDestruct(m_fragmentCompiler); + ShDestruct(m_vertexCompiler); + } + + ShFinalize(); +} + +bool ANGLEWebKitBridge::validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog) +{ + if (!builtCompilers) { + m_fragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecWebGL, &m_resources); + m_vertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecWebGL, &m_resources); + + builtCompilers = true; + } + + ShHandle compiler; + + if (shaderType == SHADER_TYPE_VERTEX) + compiler = m_vertexCompiler; + else + compiler = m_fragmentCompiler; + + const char* const shaderSourceStrings[] = { shaderSource }; + + bool validateSuccess = ShCompile(compiler, shaderSourceStrings, 1, EShOptNone, EDebugOpIntermediate); + + translatedShaderSource = ShGetObjectCode(compiler); + shaderValidationLog = ShGetInfoLog(compiler); + + return validateSuccess; +} + +} + +#endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/ANGLEWebKitBridge.h b/WebCore/platform/graphics/ANGLEWebKitBridge.h new file mode 100644 index 0000000..d01de8f --- /dev/null +++ b/WebCore/platform/graphics/ANGLEWebKitBridge.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 ANGLEWebKitBridge_h +#define ANGLEWebKitBridge_h + +#include "ANGLE/ShaderLang.h" +#include "PlatformString.h" + +#include <wtf/text/CString.h> + +namespace WebCore { + +enum ANGLEShaderType { + SHADER_TYPE_VERTEX = EShLangVertex, + SHADER_TYPE_FRAGMENT = EShLangFragment +}; + +class ANGLEWebKitBridge { +public: + + ANGLEWebKitBridge(); + ~ANGLEWebKitBridge(); + + void setResources(TBuiltInResource resources) { m_resources = resources; } + + bool validateShaderSource(const char* shaderSource, ANGLEShaderType shaderType, String& translatedShaderSource, String& shaderValidationLog); + +private: + + ShHandle m_fragmentCompiler; + ShHandle m_vertexCompiler; + + bool builtCompilers; + + TBuiltInResource m_resources; +}; + +} // namespace WebCore + +#endif diff --git a/WebCore/platform/graphics/FontCache.cpp b/WebCore/platform/graphics/FontCache.cpp index cb54cdd..ff865c2 100644 --- a/WebCore/platform/graphics/FontCache.cpp +++ b/WebCore/platform/graphics/FontCache.cpp @@ -34,10 +34,10 @@ #include "FontFallbackList.h" #include "FontPlatformData.h" #include "FontSelector.h" -#include "StringHash.h" #include <wtf/HashMap.h> #include <wtf/ListHashSet.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> using namespace WTF; diff --git a/WebCore/platform/graphics/FontDescription.h b/WebCore/platform/graphics/FontDescription.h index 86a4349..48fcaad 100644 --- a/WebCore/platform/graphics/FontDescription.h +++ b/WebCore/platform/graphics/FontDescription.h @@ -103,7 +103,11 @@ public: void setIsAbsoluteSize(bool s) { m_isAbsoluteSize = s; } void setWeight(FontWeight w) { m_weight = w; } void setGenericFamily(GenericFamilyType genericFamily) { m_genericFamily = genericFamily; } +#if PLATFORM(CHROMIUM) && OS(DARWIN) + void setUsePrinterFont(bool) { } +#else void setUsePrinterFont(bool p) { m_usePrinterFont = p; } +#endif void setRenderingMode(FontRenderingMode mode) { m_renderingMode = mode; } void setKeywordSize(unsigned s) { m_keywordSize = s; } void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = smoothing; } diff --git a/WebCore/platform/graphics/FontFamily.h b/WebCore/platform/graphics/FontFamily.h index 126bd83..21a6b64 100644 --- a/WebCore/platform/graphics/FontFamily.h +++ b/WebCore/platform/graphics/FontFamily.h @@ -26,9 +26,9 @@ #ifndef FontFamily_h #define FontFamily_h -#include "AtomicString.h" #include <wtf/RefCounted.h> #include <wtf/ListRefPtr.h> +#include <wtf/text/AtomicString.h> namespace WebCore { diff --git a/WebCore/platform/graphics/GeneratedImage.cpp b/WebCore/platform/graphics/GeneratedImage.cpp index cd0748e..5df2608 100644 --- a/WebCore/platform/graphics/GeneratedImage.cpp +++ b/WebCore/platform/graphics/GeneratedImage.cpp @@ -63,11 +63,8 @@ void GeneratedImage::drawPattern(GraphicsContext* context, const FloatRect& srcR GraphicsContext* graphicsContext = imageBuffer->context(); graphicsContext->fillRect(FloatRect(FloatPoint(), adjustedSize), *m_generator.get()); - // Grab the final image from the image buffer. - Image* bitmap = imageBuffer->image(); - - // Now just call drawTiled on that image. - bitmap->drawPattern(context, adjustedSrcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect); + // Tile the image buffer into the context. + imageBuffer->drawPattern(context, adjustedSrcRect, patternTransform, phase, styleColorSpace, compositeOp, destRect); } } diff --git a/WebCore/platform/graphics/GraphicsContext.cpp b/WebCore/platform/graphics/GraphicsContext.cpp index bee3ef6..bb4f858 100644 --- a/WebCore/platform/graphics/GraphicsContext.cpp +++ b/WebCore/platform/graphics/GraphicsContext.cpp @@ -30,6 +30,7 @@ #include "Font.h" #include "Generator.h" #include "GraphicsContextPrivate.h" +#include "ImageBuffer.h" using namespace std; @@ -442,6 +443,57 @@ void GraphicsContext::drawTiledImage(Image* image, ColorSpace styleColorSpace, c restore(); } +void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntPoint& p, CompositeOperator op) +{ + drawImageBuffer(image, styleColorSpace, p, IntRect(0, 0, -1, -1), op); +} + +void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntRect& r, CompositeOperator op, bool useLowQualityScale) +{ + drawImageBuffer(image, styleColorSpace, r, IntRect(0, 0, -1, -1), op, useLowQualityScale); +} + +void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntPoint& dest, const IntRect& srcRect, CompositeOperator op) +{ + drawImageBuffer(image, styleColorSpace, IntRect(dest, srcRect.size()), srcRect, op); +} + +void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const IntRect& dest, const IntRect& srcRect, CompositeOperator op, bool useLowQualityScale) +{ + drawImageBuffer(image, styleColorSpace, FloatRect(dest), srcRect, op, useLowQualityScale); +} + +void GraphicsContext::drawImageBuffer(ImageBuffer* image, ColorSpace styleColorSpace, const FloatRect& dest, const FloatRect& src, CompositeOperator op, bool useLowQualityScale) +{ + if (paintingDisabled() || !image) + return; + + float tsw = src.width(); + float tsh = src.height(); + float tw = dest.width(); + float th = dest.height(); + + if (tsw == -1) + tsw = image->width(); + if (tsh == -1) + tsh = image->height(); + + if (tw == -1) + tw = image->width(); + if (th == -1) + th = image->height(); + + if (useLowQualityScale) { + save(); + setImageInterpolationQuality(InterpolationNone); + } + + image->draw(this, styleColorSpace, dest, src, op, useLowQualityScale); + + if (useLowQualityScale) + restore(); +} + void GraphicsContext::addRoundedRectClip(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight) { @@ -460,6 +512,13 @@ void GraphicsContext::clipOutRoundedRect(const IntRect& rect, const IntSize& top clipOut(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); } +void GraphicsContext::clipToImageBuffer(ImageBuffer* buffer, const FloatRect& rect) +{ + if (paintingDisabled()) + return; + buffer->clip(this, rect); +} + int GraphicsContext::textDrawingMode() { return m_common->state.textDrawingMode; @@ -541,4 +600,14 @@ void GraphicsContext::adjustLineToPixelBoundaries(FloatPoint& p1, FloatPoint& p2 } } +#if !PLATFORM(SKIA) +void GraphicsContext::setGraphicsContext3D(GraphicsContext3D*, const IntSize&) +{ +} + +void GraphicsContext::syncSoftwareCanvas() +{ +} +#endif + } diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h index 9cae2f1..c48f91a 100644 --- a/WebCore/platform/graphics/GraphicsContext.h +++ b/WebCore/platform/graphics/GraphicsContext.h @@ -104,6 +104,12 @@ typedef unsigned char UInt8; #endif #endif +#if PLATFORM(CHROMIUM) +#define CanvasInterpolationQuality InterpolationMedium +#else +#define CanvasInterpolationQuality InterpolationDefault +#endif + #if PLATFORM(QT) && defined(Q_WS_WIN) #include <windows.h> #endif @@ -267,6 +273,13 @@ namespace WebCore { Image::TileRule hRule = Image::StretchTile, Image::TileRule vRule = Image::StretchTile, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); + void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint&, CompositeOperator = CompositeSourceOver); + void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect&, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); + void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntPoint& destPoint, const IntRect& srcRect, CompositeOperator = CompositeSourceOver); + void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const IntRect& destRect, const IntRect& srcRect, CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); + void drawImageBuffer(ImageBuffer*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), + CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); + void setImageInterpolationQuality(InterpolationQuality); InterpolationQuality imageInterpolationQuality() const; @@ -277,8 +290,8 @@ namespace WebCore { void clipOutEllipseInRect(const IntRect&); void clipOutRoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight); void clipPath(WindRule); - void clipToImageBuffer(const FloatRect&, const ImageBuffer*); void clipConvexPolygon(size_t numPoints, const FloatPoint*, bool antialias = true); + void clipToImageBuffer(ImageBuffer*, const FloatRect&); int textDrawingMode(); void setTextDrawingMode(int); @@ -415,6 +428,7 @@ namespace WebCore { #if PLATFORM(QT) bool inTransparencyLayer() const; PlatformPath* currentPath(); + void pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask); QPen pen(); static QPainter::CompositionMode toQtCompositionMode(CompositeOperator op); #endif @@ -429,10 +443,8 @@ namespace WebCore { pattern getHaikuStrokeStyle(); #endif -#if PLATFORM(SKIA) void setGraphicsContext3D(GraphicsContext3D*, const IntSize&); void syncSoftwareCanvas(); -#endif private: void savePlatformState(); diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp index 79f6ecf..51c4cd5 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.cpp +++ b/WebCore/platform/graphics/GraphicsContext3D.cpp @@ -816,6 +816,21 @@ bool GraphicsContext3D::packPixels(const uint8_t* sourceData, return true; } +#if !PLATFORM(CHROMIUM) +bool GraphicsContext3D::supportsBGRA() +{ + // For OpenGL ES2.0, this requires checking for + // GL_EXT_texture_format_BGRA8888 and GL_EXT_read_format_bgra. + // For desktop GL, BGRA has been supported since OpenGL 1.2. + + // However, note that the GL ES2 extension requires the internalFormat to + // glTexImage2D() be GL_BGRA, while desktop GL will not accept GL_BGRA + // (must be GL_RGBA), so this must be checked on each platform. + // Returning false for now to be safe. + return false; +} +#endif + } // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h index d702096..25d1d06 100644 --- a/WebCore/platform/graphics/GraphicsContext3D.h +++ b/WebCore/platform/graphics/GraphicsContext3D.h @@ -26,9 +26,13 @@ #ifndef GraphicsContext3D_h #define GraphicsContext3D_h +#if PLATFORM(MAC) +#include "ANGLEWebKitBridge.h" +#endif #include "GraphicsLayer.h" #include "PlatformString.h" +#include <wtf/HashMap.h> #include <wtf/ListHashSet.h> #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> @@ -403,7 +407,9 @@ public: // WebGL-specific enums UNPACK_FLIP_Y_WEBGL = 0x9240, - UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241 + UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241, + + BGRA_EXT = 0x80E1 }; // Context creation attributes. @@ -716,11 +722,13 @@ public: void paintRenderingResultsToCanvas(CanvasRenderingContext* context); - // Helpers for notification about paint events - void beginPaint(CanvasRenderingContext* context); - void endPaint(); #if PLATFORM(QT) void paint(QPainter* painter, const QRect& rect) const; + bool paintsIntoCanvasBuffer() const { return true; } +#elif PLATFORM(CHROMIUM) + bool paintsIntoCanvasBuffer() const; +#else + bool paintsIntoCanvasBuffer() const { return false; } #endif // Support for buffer creation and deletion @@ -748,6 +756,8 @@ public: // getError in the order they were added. void synthesizeGLError(unsigned long error); + bool supportsBGRA(); + private: GraphicsContext3D(Attributes attrs, HostWindow* hostWindow); @@ -807,7 +817,16 @@ public: int m_currentWidth, m_currentHeight; + typedef struct { + String source; + String log; + bool isValid; + } ShaderSourceEntry; + HashMap<Platform3DObject, ShaderSourceEntry> m_shaderSourceMap; + #if PLATFORM(MAC) + ANGLEWebKitBridge m_compiler; + Attributes m_attrs; Vector<Vector<float> > m_vertexArray; diff --git a/WebCore/platform/graphics/Image.h b/WebCore/platform/graphics/Image.h index 7c00b71..3c5e7fd 100644 --- a/WebCore/platform/graphics/Image.h +++ b/WebCore/platform/graphics/Image.h @@ -154,6 +154,9 @@ public: static PassRefPtr<Image> loadPlatformThemeIcon(const char* name, int size); #endif + virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); + protected: Image(ImageObserver* = 0); @@ -171,9 +174,6 @@ protected: virtual bool mayFillWithSolidColor() { return false; } virtual Color solidColor() const { return Color(); } - virtual void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, - const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); - private: RefPtr<SharedBuffer> m_data; // The encoded raw data for the image. ImageObserver* m_imageObserver; diff --git a/WebCore/platform/graphics/ImageBuffer.h b/WebCore/platform/graphics/ImageBuffer.h index a54c721..3c0508e 100644 --- a/WebCore/platform/graphics/ImageBuffer.h +++ b/WebCore/platform/graphics/ImageBuffer.h @@ -29,6 +29,7 @@ #define ImageBuffer_h #include "AffineTransform.h" +#include "FloatRect.h" #include "Image.h" #include "IntSize.h" #include "ImageBufferData.h" @@ -71,16 +72,13 @@ namespace WebCore { ~ImageBuffer(); const IntSize& size() const { return m_size; } + int width() const { return m_size.width(); } + int height() const { return m_size.height(); } + GraphicsContext* context() const; - Image* image() const; -#if PLATFORM(QT) - Image* imageForRendering() const; -#else - Image* imageForRendering() const { return image(); } -#endif - - void clearImage() { m_image.clear(); } + bool drawsUsingCopy() const; // If the image buffer has to render using a copied image, it will return true. + PassRefPtr<Image> copyImage() const; // Return a new image that is a copy of the buffer. PassRefPtr<ImageData> getUnmultipliedImageData(const IntRect&) const; PassRefPtr<ImageData> getPremultipliedImageData(const IntRect&) const; @@ -96,12 +94,23 @@ namespace WebCore { #else AffineTransform baseTransform() const { return AffineTransform(1, 0, 0, -1, 0, m_size.height()); } #endif + + private: + void clip(GraphicsContext*, const FloatRect&) const; + + // The draw method draws the contents of the buffer without copying it. + void draw(GraphicsContext*, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect = FloatRect(0, 0, -1, -1), + CompositeOperator = CompositeSourceOver, bool useLowQualityScale = false); + void drawPattern(GraphicsContext*, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator, const FloatRect& destRect); + friend class GraphicsContext; + friend class GeneratedImage; + private: ImageBufferData m_data; IntSize m_size; OwnPtr<GraphicsContext> m_context; - mutable RefPtr<Image> m_image; #if !PLATFORM(CG) Vector<int> m_linearRgbLUT; diff --git a/WebCore/platform/graphics/MediaPlayer.cpp b/WebCore/platform/graphics/MediaPlayer.cpp index b8b742d..e72987a 100644 --- a/WebCore/platform/graphics/MediaPlayer.cpp +++ b/WebCore/platform/graphics/MediaPlayer.cpp @@ -173,7 +173,7 @@ static Vector<MediaPlayerFactory*>& installedMediaEngines() #if PLATFORM(WIN) MediaPlayerPrivateQuickTimeVisualContext::registerMediaEngine(addMediaEngine); -#elif !PLATFORM(GTK) +#elif !PLATFORM(GTK) && !PLATFORM(EFL) // FIXME: currently all the MediaEngines are named // MediaPlayerPrivate. This code will need an update when bug // 36663 is adressed. @@ -257,8 +257,8 @@ void MediaPlayer::load(const String& url, const ContentType& contentType) // if we don't know the MIME type, see if the extension can help if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") { - int pos = url.reverseFind('.'); - if (pos >= 0) { + size_t pos = url.reverseFind('.'); + if (pos != notFound) { String extension = url.substring(pos + 1); String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension); if (!mediaType.isEmpty()) diff --git a/WebCore/platform/graphics/MediaPlayer.h b/WebCore/platform/graphics/MediaPlayer.h index 4da697a..643f17f 100644 --- a/WebCore/platform/graphics/MediaPlayer.h +++ b/WebCore/platform/graphics/MediaPlayer.h @@ -34,12 +34,12 @@ #include "Document.h" #include "IntRect.h" -#include "StringHash.h" #include <wtf/Forward.h> #include <wtf/HashSet.h> #include <wtf/OwnPtr.h> #include <wtf/Noncopyable.h> #include <wtf/PassOwnPtr.h> +#include <wtf/text/StringHash.h> #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayer.h" diff --git a/WebCore/platform/graphics/Path.cpp b/WebCore/platform/graphics/Path.cpp index af94be7..333afcb 100644 --- a/WebCore/platform/graphics/Path.cpp +++ b/WebCore/platform/graphics/Path.cpp @@ -266,8 +266,6 @@ Path Path::createCircle(const FloatPoint& center, float r) Path Path::createLine(const FloatPoint& start, const FloatPoint& end) { Path path; - if (start.x() == end.x() && start.y() == end.y()) - return path; path.moveTo(start); path.addLineTo(end); diff --git a/WebCore/platform/graphics/Path.h b/WebCore/platform/graphics/Path.h index 43ba889..61ea328 100644 --- a/WebCore/platform/graphics/Path.h +++ b/WebCore/platform/graphics/Path.h @@ -156,6 +156,10 @@ namespace WebCore { private: PlatformPathPtr m_path; + +#if PLATFORM(QT) + int m_lastMoveToIndex; +#endif }; } diff --git a/WebCore/platform/graphics/Pattern.cpp b/WebCore/platform/graphics/Pattern.cpp index bb07307..82d0a24 100644 --- a/WebCore/platform/graphics/Pattern.cpp +++ b/WebCore/platform/graphics/Pattern.cpp @@ -31,7 +31,7 @@ namespace WebCore { -Pattern::Pattern(Image* image, bool repeatX, bool repeatY) +Pattern::Pattern(PassRefPtr<Image> image, bool repeatX, bool repeatY) : m_tileImage(image) , m_repeatX(repeatX) , m_repeatY(repeatY) @@ -39,7 +39,7 @@ Pattern::Pattern(Image* image, bool repeatX, bool repeatY) , m_pattern(0) #endif { - ASSERT(image); + ASSERT(m_tileImage); } Pattern::~Pattern() diff --git a/WebCore/platform/graphics/Pattern.h b/WebCore/platform/graphics/Pattern.h index 48e8d8b..e215f3d 100644 --- a/WebCore/platform/graphics/Pattern.h +++ b/WebCore/platform/graphics/Pattern.h @@ -29,6 +29,7 @@ #define Pattern_h #include "AffineTransform.h" +#include "Image.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> @@ -64,11 +65,10 @@ typedef void* PlatformPatternPtr; namespace WebCore { class AffineTransform; -class Image; class Pattern : public RefCounted<Pattern> { public: - static PassRefPtr<Pattern> create(Image* tileImage, bool repeatX, bool repeatY) + static PassRefPtr<Pattern> create(PassRefPtr<Image> tileImage, bool repeatX, bool repeatY) { return adoptRef(new Pattern(tileImage, repeatX, repeatY)); } @@ -91,7 +91,7 @@ public: bool repeatY() const { return m_repeatY; } private: - Pattern(Image*, bool repeatX, bool repeatY); + Pattern(PassRefPtr<Image>, bool repeatX, bool repeatY); RefPtr<Image> m_tileImage; bool m_repeatX; diff --git a/WebCore/platform/graphics/WOFFFileFormat.cpp b/WebCore/platform/graphics/WOFFFileFormat.cpp index 908e288..25b3b00 100644 --- a/WebCore/platform/graphics/WOFFFileFormat.cpp +++ b/WebCore/platform/graphics/WOFFFileFormat.cpp @@ -31,6 +31,9 @@ #include "SharedBuffer.h" #if !PLATFORM(WIN) +#if OS(UNIX) +#include <netinet/in.h> +#endif #include <zlib.h> #if PLATFORM(BREWMP) #include <AEEStdLib.h> diff --git a/WebCore/platform/graphics/android/FontPlatformData.h b/WebCore/platform/graphics/android/FontPlatformData.h index 19f83f8..7d2176d 100644 --- a/WebCore/platform/graphics/android/FontPlatformData.h +++ b/WebCore/platform/graphics/android/FontPlatformData.h @@ -34,7 +34,7 @@ #include "PlatformString.h" #endif -#include "StringImpl.h" +#include <wtf/text/StringImpl.h> class SkPaint; class SkTypeface; diff --git a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp index ba10706d..180c97e 100644 --- a/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp +++ b/WebCore/platform/graphics/android/GraphicsContextAndroid.cpp @@ -801,10 +801,6 @@ void GraphicsContext::clipOut(const Path& p) GC2Canvas(this)->clipPath(*p.platformPath(), SkRegion::kDifference_Op); } -void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*) { - SkDebugf("xxxxxxxxxxxxxxxxxx clipToImageBuffer not implemented\n"); -} - ////////////////////////////////////////////////////////////////////////////////////////////////// #if SVG_SUPPORT diff --git a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp index 082af3e..3b89777 100644 --- a/WebCore/platform/graphics/android/ImageBufferAndroid.cpp +++ b/WebCore/platform/graphics/android/ImageBufferAndroid.cpp @@ -66,27 +66,42 @@ GraphicsContext* ImageBuffer::context() const return m_context.get(); } -/* This guy needs to make a deep copy of the bitmap, so that the returned - image doesn't reflect any subsequent changes to the canvas' backend. - e.g. this is called when <canvas> wants to make a Pattern, which needs - to snapshot the current pixels when it is created. - */ -Image* ImageBuffer::image() const +bool ImageBuffer::drawsUsingCopy() const { - if (!m_image) { - ASSERT(context()); - SkCanvas* canvas = context()->platformContext()->mCanvas; - SkDevice* device = canvas->getDevice(); - const SkBitmap& orig = device->accessBitmap(false); - - SkBitmap copy; - orig.copyTo(©, orig.config()); - - SkBitmapRef* ref = new SkBitmapRef(copy); - m_image = BitmapImage::create(ref, 0); - ref->unref(); - } - return m_image.get(); + return true; +} + +PassRefPtr<Image> ImageBuffer::copyImage() const +{ + ASSERT(context()); + SkCanvas* canvas = context()->platformContext()->mCanvas; + SkDevice* device = canvas->getDevice(); + const SkBitmap& orig = device->accessBitmap(false); + + SkBitmap copy; + orig.copyTo(©, orig.config()); + + SkBitmapRef* ref = new SkBitmapRef(copy); + RefPtr<Image> image = BitmapImage::create(ref, 0); + ref->unref(); + return image; +} + +void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const +{ + SkDebugf("xxxxxxxxxxxxxxxxxx clip not implemented\n"); +} + +void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator op, bool useLowQualityScale) +{ + RefPtr<Image> imageCopy = copyImage(); + context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); +} + +void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + RefPtr<Image> imageCopy = copyImage(); + imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) const @@ -95,7 +110,7 @@ PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) if (!gc) { return 0; } - + const SkBitmap& src = android_gc2canvas(gc)->getDevice()->accessBitmap(false); SkAutoLockPixels alp(src); if (!src.getPixels()) { @@ -105,10 +120,10 @@ PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) // ! Can't use PassRefPtr<>, otherwise the second access will cause crash. RefPtr<ImageData> result = ImageData::create(rect.width(), rect.height()); unsigned char* data = result->data()->data()->data(); - + if (rect.x() < 0 || rect.y() < 0 || (rect.x() + rect.width()) > m_size.width() || (rect.y() + rect.height()) > m_size.height()) memset(data, 0, result->data()->length()); - + int originx = rect.x(); int destx = 0; if (originx < 0) { @@ -119,7 +134,7 @@ PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) if (endx > m_size.width()) endx = m_size.width(); int numColumns = endx - originx; - + int originy = rect.y(); int desty = 0; if (originy < 0) { @@ -130,10 +145,10 @@ PassRefPtr<ImageData> ImageBuffer::getUnmultipliedImageData(const IntRect& rect) if (endy > m_size.height()) endy = m_size.height(); int numRows = endy - originy; - + unsigned srcPixelsPerRow = src.rowBytesAsPixels(); unsigned destBytesPerRow = 4 * rect.width(); - + const SkPMColor* srcRows = src.getAddr32(originx, originy); unsigned char* destRows = data + desty * destBytesPerRow + destx * 4; for (int y = 0; y < numRows; ++y) { @@ -158,7 +173,7 @@ void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sou if (!gc) { return; } - + const SkBitmap& dst = android_gc2canvas(gc)->getDevice()->accessBitmap(true); SkAutoLockPixels alp(dst); if (!dst.getPixels()) { @@ -167,33 +182,33 @@ void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sou ASSERT(sourceRect.width() > 0); ASSERT(sourceRect.height() > 0); - + int originx = sourceRect.x(); int destx = destPoint.x() + sourceRect.x(); ASSERT(destx >= 0); ASSERT(destx < m_size.width()); ASSERT(originx >= 0); ASSERT(originx <= sourceRect.right()); - + int endx = destPoint.x() + sourceRect.right(); ASSERT(endx <= m_size.width()); - + int numColumns = endx - destx; - + int originy = sourceRect.y(); int desty = destPoint.y() + sourceRect.y(); ASSERT(desty >= 0); ASSERT(desty < m_size.height()); ASSERT(originy >= 0); ASSERT(originy <= sourceRect.bottom()); - + int endy = destPoint.y() + sourceRect.bottom(); ASSERT(endy <= m_size.height()); int numRows = endy - desty; - + unsigned srcBytesPerRow = 4 * source->width(); unsigned dstPixelsPerRow = dst.rowBytesAsPixels(); - + unsigned char* srcRows = source->data()->data()->data() + originy * srcBytesPerRow + originx * 4; SkPMColor* dstRows = dst.getAddr32(destx, desty); for (int y = 0; y < numRows; ++y) { @@ -209,9 +224,9 @@ void ImageBuffer::putUnmultipliedImageData(ImageData* source, const IntRect& sou } } - + String ImageBuffer::toDataURL(const String&, const double*) const -{ +{ // Encode the image into a vector. SkDynamicMemoryWStream pngStream; const SkBitmap& dst = android_gc2canvas(context())->getDevice()->accessBitmap(true); diff --git a/WebCore/platform/graphics/android/LayerAndroid.h b/WebCore/platform/graphics/android/LayerAndroid.h index 712d699..245d224 100644 --- a/WebCore/platform/graphics/android/LayerAndroid.h +++ b/WebCore/platform/graphics/android/LayerAndroid.h @@ -22,8 +22,9 @@ #include "RefPtr.h" #include "SkColor.h" #include "SkLayer.h" -#include "StringHash.h" + #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> #ifndef BZERO_DEFINED #define BZERO_DEFINED diff --git a/WebCore/platform/graphics/cairo/GRefPtrCairo.cpp b/WebCore/platform/graphics/cairo/GRefPtrCairo.cpp new file mode 100644 index 0000000..d244954 --- /dev/null +++ b/WebCore/platform/graphics/cairo/GRefPtrCairo.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU 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 "GRefPtrCairo.h" + +#include <cairo.h> + +namespace WTF { + +template <> cairo_t* refGPtr(cairo_t* ptr) +{ + if (ptr) + cairo_reference(ptr); + return ptr; +} + +template <> void derefGPtr(cairo_t* ptr) +{ + if (ptr) + cairo_destroy(ptr); +} + +template <> cairo_surface_t* refGPtr(cairo_surface_t* ptr) +{ + if (ptr) + cairo_surface_reference(ptr); + return ptr; +} + +template <> void derefGPtr(cairo_surface_t* ptr) +{ + if (ptr) + cairo_surface_destroy(ptr); +} + +} diff --git a/WebCore/platform/graphics/cairo/GRefPtrCairo.h b/WebCore/platform/graphics/cairo/GRefPtrCairo.h new file mode 100644 index 0000000..aef51fe --- /dev/null +++ b/WebCore/platform/graphics/cairo/GRefPtrCairo.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2010 Igalia S.L. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef GRefPtrCairo_h +#define GRefPtrCairo_h + +#include "GRefPtr.h" + +typedef struct _cairo cairo_t; +typedef struct _cairo_surface cairo_surface_t; + +namespace WTF { + +template <> cairo_t* refGPtr(cairo_t* ptr); +template <> void derefGPtr(cairo_t* ptr); + +template <> cairo_surface_t* refGPtr(cairo_surface_t* ptr); +template <> void derefGPtr(cairo_surface_t* ptr); + +} + +#endif diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp index f3fc943..9b3096e 100644 --- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp +++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp @@ -908,14 +908,6 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness cairo_set_fill_rule(cr, savedFillRule); } -void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer) -{ - if (paintingDisabled()) - return; - - notImplemented(); -} - void GraphicsContext::setPlatformShadow(FloatSize const& size, float, Color const&, ColorSpace) { // Cairo doesn't support shadows natively, they are drawn manually in the draw* @@ -936,7 +928,7 @@ void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const // draw the shadow without blurring, if kernelSize is zero if (!kernelSize) { setColor(cr, shadowColor); - cairo_mask_surface(cr, buffer->image()->nativeImageForCurrentFrame(), shadowRect.x(), shadowRect.y()); + cairo_mask_surface(cr, buffer->m_data.m_surface, shadowRect.x(), shadowRect.y()); return; } @@ -956,7 +948,7 @@ void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const // Mask the filter with the shadow color and draw it to the context. // Masking makes it possible to just blur the alpha channel. setColor(cr, shadowColor); - cairo_mask_surface(cr, blur->resultImage()->image()->nativeImageForCurrentFrame(), shadowRect.x(), shadowRect.y()); + cairo_mask_surface(cr, blur->resultImage()->m_data.m_surface, shadowRect.x(), shadowRect.y()); #endif } diff --git a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp index 1a43e54..db66276 100644 --- a/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp +++ b/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp @@ -35,6 +35,7 @@ #include "GraphicsContext.h" #include "ImageData.h" #include "MIMETypeRegistry.h" +#include "NotImplemented.h" #include "Pattern.h" #include "PlatformString.h" @@ -97,26 +98,34 @@ GraphicsContext* ImageBuffer::context() const return m_context.get(); } -Image* ImageBuffer::image() const +bool ImageBuffer::drawsUsingCopy() const { - if (!m_image) { - // It's assumed that if image() is called, the actual rendering to the - // GraphicsContext must be done. - ASSERT(context()); - - // This creates a COPY of the image and will cache that copy. This means - // that if subsequent operations take place on the context, neither the - // currently-returned image, nor the results of future image() calls, - // will contain that operation. - // - // This seems silly, but is the way the CG port works: image() is - // intended to be used only when rendering is "complete." - cairo_surface_t* newsurface = copySurface(m_data.m_surface); - - // BitmapImage will release the passed in surface on destruction - m_image = BitmapImage::create(newsurface); - } - return m_image.get(); + return true; +} + +PassRefPtr<Image> ImageBuffer::copyImage() const +{ + // BitmapImage will release the passed in surface on destruction + return BitmapImage::create(copySurface(m_data.m_surface)); +} + +void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const +{ + notImplemented(); +} + +void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, + CompositeOperator op , bool useLowQualityScale) +{ + RefPtr<Image> imageCopy = copyImage(); + context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); +} + +void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + RefPtr<Image> imageCopy = copyImage(); + imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) diff --git a/WebCore/platform/graphics/cairo/ImageCairo.cpp b/WebCore/platform/graphics/cairo/ImageCairo.cpp index 64fbedf..1582671 100644 --- a/WebCore/platform/graphics/cairo/ImageCairo.cpp +++ b/WebCore/platform/graphics/cairo/ImageCairo.cpp @@ -33,6 +33,7 @@ #include "AffineTransform.h" #include "Color.h" #include "FloatRect.h" +#include "GRefPtrCairo.h" #include "GraphicsContext.h" #include "ImageBuffer.h" #include "ImageObserver.h" @@ -184,17 +185,14 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con cairo_t* cr = context->platformContext(); context->save(); - IntRect imageSize = enclosingIntRect(tileRect); - OwnPtr<ImageBuffer> imageSurface = ImageBuffer::create(imageSize.size()); - - if (!imageSurface) - return; - + GRefPtr<cairo_surface_t> clippedImageSurface = 0; if (tileRect.size() != size()) { - cairo_t* clippedImageContext = imageSurface->context()->platformContext(); - cairo_set_source_surface(clippedImageContext, image, -tileRect.x(), -tileRect.y()); - cairo_paint(clippedImageContext); - image = imageSurface->image()->nativeImageForCurrentFrame(); + IntRect imageSize = enclosingIntRect(tileRect); + clippedImageSurface = adoptGRef(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, imageSize.width(), imageSize.height())); + GRefPtr<cairo_t> clippedImageContext(cairo_create(clippedImageSurface.get())); + cairo_set_source_surface(clippedImageContext.get(), image, -tileRect.x(), -tileRect.y()); + cairo_paint(clippedImageContext.get()); + image = clippedImageSurface.get(); } cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp index 2de4d14..e5079dc 100644 --- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp +++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp @@ -753,18 +753,6 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness CGContextEOClip(context); } -void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer) -{ - if (paintingDisabled()) - return; - - CGContextTranslateCTM(platformContext(), rect.x(), rect.y() + rect.height()); - CGContextScaleCTM(platformContext(), 1, -1); - CGContextClipToMask(platformContext(), FloatRect(FloatPoint(), rect.size()), imageBuffer->image()->getCGImageRef()); - CGContextScaleCTM(platformContext(), 1, -1); - CGContextTranslateCTM(platformContext(), -rect.x(), -rect.y() - rect.height()); -} - void GraphicsContext::beginTransparencyLayer(float opacity) { if (paintingDisabled()) @@ -950,9 +938,17 @@ void GraphicsContext::clip(const Path& path) if (paintingDisabled()) return; CGContextRef context = platformContext(); - CGContextBeginPath(context); - CGContextAddPath(context, path.platformPath()); - CGContextClip(context); + + // CGContextClip does nothing if the path is empty, so in this case, we + // instead clip against a zero rect to reduce the clipping region to + // nothing - which is the intended behavior of clip() if the path is empty. + if (path.isEmpty()) + CGContextClipToRect(context, CGRectZero); + else { + CGContextBeginPath(context); + CGContextAddPath(context, path.platformPath()); + CGContextClip(context); + } m_data->clip(path); } diff --git a/WebCore/platform/graphics/cg/ImageBufferCG.cpp b/WebCore/platform/graphics/cg/ImageBufferCG.cpp index feb8cec..ecbcf60 100644 --- a/WebCore/platform/graphics/cg/ImageBufferCG.cpp +++ b/WebCore/platform/graphics/cg/ImageBufferCG.cpp @@ -46,6 +46,11 @@ using namespace std; namespace WebCore { +static void releaseImageData(void*, const void* data, size_t) +{ + fastFree(const_cast<void*>(data)); +} + ImageBufferData::ImageBufferData(const IntSize&) : m_data(0) { @@ -56,42 +61,46 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b , m_size(size) { success = false; // Make early return mean failure. - unsigned bytesPerRow; if (size.width() < 0 || size.height() < 0) return; - bytesPerRow = size.width(); + + unsigned bytesPerRow = size.width(); if (imageColorSpace != GrayScale) { // Protect against overflow if (bytesPerRow > 0x3FFFFFFF) return; bytesPerRow *= 4; } + m_data.m_bytesPerRow = bytesPerRow; + size_t dataSize = size.height() * bytesPerRow; if (!tryFastCalloc(size.height(), bytesPerRow).getValue(m_data.m_data)) return; ASSERT((reinterpret_cast<size_t>(m_data.m_data) & 2) == 0); - RetainPtr<CGColorSpaceRef> colorSpace; switch(imageColorSpace) { case DeviceRGB: - colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB()); + m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB()); break; case GrayScale: - colorSpace.adoptCF(CGColorSpaceCreateDeviceGray()); + m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceGray()); break; #if ((PLATFORM(MAC) || PLATFORM(CHROMIUM)) && !defined(BUILDING_ON_TIGER)) case LinearRGB: - colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); + m_data.m_colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); break; + #endif default: - colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB()); + m_data.m_colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB()); break; } + m_data.m_grayScale = imageColorSpace == GrayScale; + m_data.m_bitmapInfo = m_data.m_grayScale ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast; RetainPtr<CGContextRef> cgContext(AdoptCF, CGBitmapContextCreate(m_data.m_data, size.width(), size.height(), 8, bytesPerRow, - colorSpace.get(), (imageColorSpace == GrayScale) ? kCGImageAlphaNone : kCGImageAlphaPremultipliedLast)); + m_data.m_colorSpace.get(), m_data.m_bitmapInfo)); if (!cgContext) return; @@ -99,11 +108,13 @@ ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace imageColorSpace, b m_context->scale(FloatSize(1, -1)); m_context->translate(0, -size.height()); success = true; + + // Create a live image that wraps the data. + m_data.m_dataProvider.adoptCF(CGDataProviderCreateWithData(0, m_data.m_data, dataSize, releaseImageData)); } ImageBuffer::~ImageBuffer() { - fastFree(m_data.m_data); } GraphicsContext* ImageBuffer::context() const @@ -111,17 +122,59 @@ GraphicsContext* ImageBuffer::context() const return m_context.get(); } -Image* ImageBuffer::image() const +bool ImageBuffer::drawsUsingCopy() const +{ + return false; +} + +PassRefPtr<Image> ImageBuffer::copyImage() const +{ + // BitmapImage will release the passed in CGImage on destruction + return BitmapImage::create(CGBitmapContextCreateImage(context()->platformContext())); +} + +static CGImageRef cgImage(const IntSize& size, const ImageBufferData& data) { - if (!m_image) { - // It's assumed that if image() is called, the actual rendering to the - // GraphicsContext must be done. - ASSERT(context()); - CGImageRef cgImage = CGBitmapContextCreateImage(context()->platformContext()); - // BitmapImage will release the passed in CGImage on destruction - m_image = BitmapImage::create(cgImage); + return CGImageCreate(size.width(), size.height(), 8, data.m_grayScale ? 8 : 32, data.m_bytesPerRow, + data.m_colorSpace.get(), data.m_bitmapInfo, data.m_dataProvider.get(), 0, true, kCGRenderingIntentDefault); +} + +void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, + CompositeOperator op, bool useLowQualityScale) +{ + if (destContext == context()) { + // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. + RefPtr<Image> copy = copyImage(); + destContext->drawImage(copy.get(), DeviceColorSpace, destRect, srcRect, op, useLowQualityScale); + } else { + RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data)); + destContext->drawImage(imageForRendering.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); + } +} + +void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + if (destContext == context()) { + // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. + RefPtr<Image> copy = copyImage(); + copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); + } else { + RefPtr<Image> imageForRendering = BitmapImage::create(cgImage(m_size, m_data)); + imageForRendering->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } - return m_image.get(); +} + +void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const +{ + RetainPtr<CGImageRef> image(AdoptCF, cgImage(m_size, m_data)); + + CGContextRef platformContext = context->platformContext(); + 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()); } template <Multiply multiplied> diff --git a/WebCore/platform/graphics/cg/ImageBufferData.h b/WebCore/platform/graphics/cg/ImageBufferData.h index 5e6fc4c..2f9d854 100644 --- a/WebCore/platform/graphics/cg/ImageBufferData.h +++ b/WebCore/platform/graphics/cg/ImageBufferData.h @@ -26,6 +26,14 @@ #ifndef ImageBufferData_h #define ImageBufferData_h +#include "Image.h" +#include <wtf/RefPtr.h> +#include <wtf/RetainPtr.h> + +typedef struct CGColorSpace *CGColorSpaceRef; +typedef struct CGDataProvider *CGDataProviderRef; +typedef uint32_t CGBitmapInfo; + namespace WebCore { class IntSize; @@ -35,6 +43,12 @@ public: ImageBufferData(const IntSize&); void* m_data; + + RetainPtr<CGDataProviderRef> m_dataProvider; + CGBitmapInfo m_bitmapInfo; + bool m_grayScale; + unsigned m_bytesPerRow; + RetainPtr<CGColorSpaceRef> m_colorSpace; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp b/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp index c7d9a0b..ef69e5e 100644 --- a/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp +++ b/WebCore/platform/graphics/cg/ImageSourceCGWin.cpp @@ -27,8 +27,8 @@ #include "ImageSourceCG.h" #include "StdLibExtras.h" -#include "StringHash.h" #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp index 8ba37c6..7c3e450 100644 --- a/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontCacheChromiumWin.cpp @@ -38,8 +38,8 @@ #include "HashMap.h" #include "HashSet.h" #include "SimpleFontData.h" -#include "StringHash.h" #include <unicode/uniset.h> +#include <wtf/text/StringHash.h> #include <windows.h> #include <objidl.h> diff --git a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp index 53f4a52..2fda22d 100644 --- a/WebCore/platform/graphics/chromium/FontCacheLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontCacheLinux.cpp @@ -31,7 +31,6 @@ #include "config.h" #include "FontCache.h" -#include "AtomicString.h" #include "ChromiumBridge.h" #include "Font.h" #include "FontDescription.h" @@ -46,6 +45,7 @@ #include <unicode/utf16.h> #include <wtf/Assertions.h> +#include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> namespace WebCore { diff --git a/WebCore/platform/graphics/chromium/FontLinux.cpp b/WebCore/platform/graphics/chromium/FontLinux.cpp index 1953dd8..ec79b82 100644 --- a/WebCore/platform/graphics/chromium/FontLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontLinux.cpp @@ -166,6 +166,9 @@ public: , m_offsetX(m_startingX) , m_run(getTextRun(run)) , m_iterateBackwards(m_run.rtl()) + , m_wordSpacingAdjustment(0) + , m_padding(0) + , m_padError(0) { // Do not use |run| inside this constructor. Use |m_run| instead. @@ -207,6 +210,56 @@ public: delete[] m_item.string; } + // setWordSpacingAdjustment sets a delta (in pixels) which is applied at + // each word break in the TextRun. + void setWordSpacingAdjustment(int wordSpacingAdjustment) + { + m_wordSpacingAdjustment = wordSpacingAdjustment; + } + + // setLetterSpacingAdjustment sets an additional number of pixels that is + // added to the advance after each output cluster. This matches the behaviour + // of WidthIterator::advance. + // + // (NOTE: currently does nothing because I don't know how to get the + // cluster information from Harfbuzz.) + void setLetterSpacingAdjustment(int letterSpacingAdjustment) + { + m_letterSpacing = letterSpacingAdjustment; + } + + bool isWordBreak(unsigned i, bool isRTL) + { + if (!isRTL) + return i && isCodepointSpace(m_item.string[i]) && !isCodepointSpace(m_item.string[i - 1]); + return i != m_item.stringLength - 1 && isCodepointSpace(m_item.string[i]) && !isCodepointSpace(m_item.string[i + 1]); + } + + // setPadding sets a number of pixels to be distributed across the TextRun. + // WebKit uses this to justify text. + void setPadding(int padding) + { + m_padding = padding; + if (!m_padding) + return; + + // If we have padding to distribute, then we try to give an equal + // amount to each space. The last space gets the smaller amount, if + // any. + unsigned numWordBreaks = 0; + bool isRTL = m_iterateBackwards; + + for (unsigned i = 0; i < m_item.stringLength; i++) { + if (isWordBreak(i, isRTL)) + numWordBreaks++; + } + + if (numWordBreaks) + m_padPerWordBreak = m_padding / numWordBreaks; + else + m_padPerWordBreak = 0; + } + void reset() { if (m_iterateBackwards) @@ -453,8 +506,15 @@ private: void setGlyphXPositions(bool isRTL) { double position = 0; + // logClustersIndex indexes logClusters for the first (or last when + // RTL) codepoint of the current glyph. Each time we advance a glyph, + // we skip over all the codepoints that contributed to the current + // glyph. + unsigned logClustersIndex = isRTL ? m_item.num_glyphs - 1 : 0; + for (int iter = 0; iter < m_item.num_glyphs; ++iter) { - // Glyphs are stored in logical order, but for layout purposes we always go left to right. + // Glyphs are stored in logical order, but for layout purposes we + // always go left to right. int i = isRTL ? m_item.num_glyphs - iter - 1 : iter; m_glyphs16[i] = m_item.glyphs[i]; @@ -462,12 +522,48 @@ private: m_xPositions[i] = m_offsetX + position + offsetX; double advance = truncateFixedPointToInteger(m_item.advances[i]); + unsigned glyphIndex = m_item.item.pos + logClustersIndex; + if (isWordBreak(glyphIndex, isRTL)) { + advance += m_wordSpacingAdjustment; + + if (m_padding > 0) { + unsigned toPad = roundf(m_padPerWordBreak + m_padError); + m_padError += m_padPerWordBreak - toPad; + + if (m_padding < toPad) + toPad = m_padding; + m_padding -= toPad; + advance += toPad; + } + } + + // We would like to add m_letterSpacing after each cluster, but I + // don't know where the cluster information is. This is typically + // fine for Roman languages, but breaks more complex languages + // terribly. + // advance += m_letterSpacing; + + if (isRTL) { + while (logClustersIndex > 0 && logClusters()[logClustersIndex] == i) + logClustersIndex--; + } else { + while (logClustersIndex < m_item.num_glyphs && logClusters()[logClustersIndex] == i) + logClustersIndex++; + } + position += advance; } + m_pixelWidth = position; m_offsetX += m_pixelWidth; } + static bool isCodepointSpace(HB_UChar16 c) + { + // This matches the logic in RenderBlock::findNextLineBreak + return c == ' ' || c == '\t'; + } + void mirrorCharacters(UChar* destination, const UChar* source, int length) const { int position = 0; @@ -498,6 +594,14 @@ private: OwnArrayPtr<UChar> m_normalizedBuffer; // A buffer for normalized run. const TextRun& m_run; bool m_iterateBackwards; + int m_wordSpacingAdjustment; // delta adjustment (pixels) for each word break. + float m_padding; // pixels to be distributed over the line at word breaks. + float m_padPerWordBreak; // pixels to be added to each word break. + float m_padError; // |m_padPerWordBreak| might have a fractional component. + // Since we only add a whole number of padding pixels at + // each word break we accumulate error. This is the + // number of pixels that we are behind so far. + unsigned m_letterSpacing; // pixels to be added after each glyph. }; static void setupForTextPainting(SkPaint* paint, SkColor color) @@ -534,6 +638,9 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, TextRunWalker walker(run, point.x(), this); bool haveMultipleLayers = isCanvasMultiLayered(canvas); + walker.setWordSpacingAdjustment(wordSpacing()); + walker.setLetterSpacingAdjustment(letterSpacing()); + walker.setPadding(run.padding()); while (walker.nextScriptRun()) { if (fill) { @@ -553,6 +660,8 @@ void Font::drawComplexText(GraphicsContext* gc, const TextRun& run, float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* /* fallbackFonts */, GlyphOverflow* /* glyphOverflow */) const { TextRunWalker walker(run, 0, this); + walker.setWordSpacingAdjustment(wordSpacing()); + walker.setLetterSpacingAdjustment(letterSpacing()); return walker.widthOfFullRun(); } @@ -588,6 +697,8 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat, // (Mac code ignores includePartialGlyphs, and they don't know what it's // supposed to do, so we just ignore it as well.) TextRunWalker walker(run, 0, this); + walker.setWordSpacingAdjustment(wordSpacing()); + walker.setLetterSpacingAdjustment(letterSpacing()); // If this is RTL text, the first glyph from the left is actually the last // code point. So we need to know how many code points there are total in @@ -664,6 +775,8 @@ FloatRect Font::selectionRectForComplexText(const TextRun& run, { int fromX = -1, toX = -1, fromAdvance = -1, toAdvance = -1; TextRunWalker walker(run, 0, this); + walker.setWordSpacingAdjustment(wordSpacing()); + walker.setLetterSpacingAdjustment(letterSpacing()); // Base will point to the x offset for the current script run. Note that, in // the LTR case, width will be 0. diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h index 1d6cc8e..beac0bf 100644 --- a/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h +++ b/WebCore/platform/graphics/chromium/FontPlatformDataChromiumWin.h @@ -34,10 +34,10 @@ #include "config.h" -#include "StringImpl.h" #include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> +#include <wtf/text/StringImpl.h> #include <usp10.h> diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp index 9b54732..b51eb8c 100644 --- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp +++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp @@ -35,11 +35,12 @@ #include "HarfbuzzSkia.h" #include "NotImplemented.h" #include "PlatformString.h" -#include "StringImpl.h" #include "SkPaint.h" #include "SkTypeface.h" +#include <wtf/text/StringImpl.h> + namespace WebCore { static SkPaint::Hinting skiaHinting = SkPaint::kNormal_Hinting; diff --git a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h index de12832..363e55f 100644 --- a/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h +++ b/WebCore/platform/graphics/chromium/FontPlatformDataLinux.h @@ -32,10 +32,10 @@ #define FontPlatformDataLinux_h #include "FontRenderStyle.h" -#include "StringImpl.h" #include <wtf/Forward.h> #include <wtf/RefPtr.h> #include <wtf/text/CString.h> +#include <wtf/text/StringImpl.h> #include <SkPaint.h> class SkTypeface; diff --git a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp index 78170a9..e725c50 100644 --- a/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp +++ b/WebCore/platform/graphics/chromium/FontUtilsChromiumWin.cpp @@ -34,11 +34,11 @@ #include <limits> #include "PlatformString.h" -#include "StringHash.h" #include "UniscribeHelper.h" #include <unicode/locid.h> #include <unicode/uchar.h> #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp index 8a9bde1..534de7b 100644 --- a/WebCore/platform/graphics/chromium/GLES2Canvas.cpp +++ b/WebCore/platform/graphics/chromium/GLES2Canvas.cpp @@ -38,14 +38,15 @@ #include "FloatRect.h" #include "GLES2Texture.h" #include "GraphicsContext3D.h" +#include "IntRect.h" #include "PlatformString.h" #include "Uint16Array.h" #define _USE_MATH_DEFINES #include <math.h> -#include <wtf/text/CString.h> #include <wtf/OwnArrayPtr.h> +#include <wtf/text/CString.h> namespace WebCore { @@ -221,7 +222,6 @@ void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRe checkGLError("glUseProgram"); m_context->activeTexture(GraphicsContext3D::TEXTURE0); - texture->bind(); m_context->uniform1i(m_texSamplerLocation, 0); checkGLError("glUniform1i"); @@ -229,28 +229,52 @@ void GLES2Canvas::drawTexturedRect(GLES2Texture* texture, const FloatRect& srcRe m_context->uniform1f(m_texAlphaLocation, alpha); checkGLError("glUniform1f for alpha"); + m_context->vertexAttribPointer(m_texPositionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0); + + m_context->enableVertexAttribArray(m_texPositionLocation); + + const TilingData& tiles = texture->tiles(); + IntRect tileIdxRect = tiles.overlappedTileIndices(srcRect); + + for (int y = tileIdxRect.y(); y <= tileIdxRect.bottom(); y++) { + for (int x = tileIdxRect.x(); x <= tileIdxRect.right(); x++) + drawTexturedRectTile(texture, tiles.tileIndex(x, y), srcRect, dstRect, transform); + } +} + +void GLES2Canvas::drawTexturedRectTile(GLES2Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform& transform) +{ + if (dstRect.isEmpty()) + return; + + const TilingData& tiles = texture->tiles(); + + texture->bindTile(tile); + + FloatRect srcRectClippedInTileSpace; + FloatRect dstRectIntersected; + tiles.intersectDrawQuad(srcRect, dstRect, tile, &srcRectClippedInTileSpace, &dstRectIntersected); + + IntRect tileBoundsWithBorder = tiles.tileBoundsWithBorder(tile); + AffineTransform matrix(m_flipMatrix); matrix.multLeft(transform); - matrix.translate(dstRect.x(), dstRect.y()); - matrix.scale(dstRect.width(), dstRect.height()); + matrix.translate(dstRectIntersected.x(), dstRectIntersected.y()); + matrix.scale(dstRectIntersected.width(), dstRectIntersected.height()); float mat[9]; affineTo3x3(matrix, mat); m_context->uniformMatrix3fv(m_texMatrixLocation, false /*transpose*/, mat, 1 /*count*/); checkGLError("glUniformMatrix3fv"); AffineTransform texMatrix; - texMatrix.scale(1.0f / texture->width(), 1.0f / texture->height()); - texMatrix.translate(srcRect.x(), srcRect.y()); - texMatrix.scale(srcRect.width(), srcRect.height()); + texMatrix.scale(1.0f / tileBoundsWithBorder.width(), 1.0f / tileBoundsWithBorder.height()); + texMatrix.translate(srcRectClippedInTileSpace.x(), srcRectClippedInTileSpace.y()); + texMatrix.scale(srcRectClippedInTileSpace.width(), srcRectClippedInTileSpace.height()); float texMat[9]; affineTo3x3(texMatrix, texMat); m_context->uniformMatrix3fv(m_texTexMatrixLocation, false /*transpose*/, texMat, 1 /*count*/); checkGLError("glUniformMatrix3fv"); - m_context->vertexAttribPointer(m_texPositionLocation, 3, GraphicsContext3D::FLOAT, false, 0, 0); - - m_context->enableVertexAttribArray(m_texPositionLocation); - m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0); checkGLError("glDrawElements"); } diff --git a/WebCore/platform/graphics/chromium/GLES2Canvas.h b/WebCore/platform/graphics/chromium/GLES2Canvas.h index cea90ae..0ad07fc 100644 --- a/WebCore/platform/graphics/chromium/GLES2Canvas.h +++ b/WebCore/platform/graphics/chromium/GLES2Canvas.h @@ -81,6 +81,7 @@ public: GLES2Texture* getTexture(NativeImagePtr); private: + void drawTexturedRectTile(GLES2Texture* texture, int tile, const FloatRect& srcRect, const FloatRect& dstRect, const AffineTransform&); void applyCompositeOperator(CompositeOperator); void checkGLError(const char* header); unsigned getQuadVertices(); diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.cpp b/WebCore/platform/graphics/chromium/GLES2Texture.cpp index 5e8a141..ae230db 100644 --- a/WebCore/platform/graphics/chromium/GLES2Texture.cpp +++ b/WebCore/platform/graphics/chromium/GLES2Texture.cpp @@ -35,45 +35,27 @@ #include "GLES2Texture.h" #include "GraphicsContext3D.h" - +#include "IntRect.h" #include <wtf/OwnArrayPtr.h> namespace WebCore { -GLES2Texture::GLES2Texture(GraphicsContext3D* context, unsigned textureId, Format format, int width, int height) + +GLES2Texture::GLES2Texture(GraphicsContext3D* context, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize) : m_context(context) - , m_textureId(textureId) , m_format(format) - , m_width(width) - , m_height(height) + , m_tiles(maxTextureSize, width, height, true) + , m_tileTextureIds(tileTextureIds) { } GLES2Texture::~GLES2Texture() { - m_context->deleteTexture(m_textureId); -} - -PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format format, int width, int height) -{ - int max; - context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &max); - if (width > max || height > max) { - ASSERT(!"texture too big"); - return 0; - } - - unsigned textureId = context->createTexture(); - if (!textureId) - return 0; - - context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); - context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, width, height, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0); - - return adoptRef(new GLES2Texture(context, textureId, format, width, height)); + for (unsigned int i = 0; i < m_tileTextureIds->size(); i++) + m_context->deleteTexture(m_tileTextureIds->at(i)); } -static void convertFormat(GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle) +static void convertFormat(GraphicsContext3D* context, GLES2Texture::Format format, unsigned int* glFormat, unsigned int* glType, bool* swizzle) { *swizzle = false; switch (format) { @@ -82,43 +64,113 @@ static void convertFormat(GLES2Texture::Format format, unsigned int* glFormat, u *glType = GraphicsContext3D::UNSIGNED_BYTE; break; case GLES2Texture::BGRA8: -// FIXME: Once we have support for extensions, we should check for EXT_texture_format_BGRA8888, -// and use that if present. - *glFormat = GraphicsContext3D::RGBA; - *glType = GraphicsContext3D::UNSIGNED_BYTE; - *swizzle = true; + if (context->supportsBGRA()) { + *glFormat = GraphicsContext3D::BGRA_EXT; + *glType = GraphicsContext3D::UNSIGNED_BYTE; + } else { + *glFormat = GraphicsContext3D::RGBA; + *glType = GraphicsContext3D::UNSIGNED_BYTE; + *swizzle = true; + } break; default: - ASSERT(!"bad format"); + ASSERT_NOT_REACHED(); break; } } +PassRefPtr<GLES2Texture> GLES2Texture::create(GraphicsContext3D* context, Format format, int width, int height) +{ + int maxTextureSize = 0; + context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &maxTextureSize); + + TilingData tiling(maxTextureSize, width, height, true); + int numTiles = tiling.numTiles(); + + OwnPtr<Vector<unsigned int> > textureIds(new Vector<unsigned int>(numTiles)); + textureIds->fill(0, numTiles); + + for (int i = 0; i < numTiles; i++) { + int textureId = context->createTexture(); + if (!textureId) { + for (int i = 0; i < numTiles; i++) + context->deleteTexture(textureIds->at(i)); + return 0; + } + textureIds->at(i) = textureId; + + IntRect tileBoundsWithBorder = tiling.tileBoundsWithBorder(i); + + unsigned int glFormat, glType; + bool swizzle; + convertFormat(context, format, &glFormat, &glType, &swizzle); + context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId); + context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, glFormat, + tileBoundsWithBorder.width(), + tileBoundsWithBorder.height(), + 0, glFormat, glType, 0); + } + return adoptRef(new GLES2Texture(context, textureIds.leakPtr(), format, width, height, maxTextureSize)); +} + +template <bool swizzle> +static uint32_t* copySubRect(uint32_t* src, int srcX, int srcY, uint32_t* dst, int width, int height, int srcStride) +{ + uint32_t* srcOffset = src + srcX + srcY * srcStride; + + if (!swizzle && width == srcStride) + return srcOffset; + + uint32_t* dstPixel = dst; + for (int y = 0; y < height; y++) { + for (int x = 0; x < width ; x++) { + uint32_t pixel = srcOffset[x + y * srcStride]; + if (swizzle) + *dstPixel = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); + else + *dstPixel = pixel; + dstPixel++; + } + } + return dst; +} + void GLES2Texture::load(void* pixels) { + uint32_t* pixels32 = static_cast<uint32_t*>(pixels); unsigned int glFormat, glType; bool swizzle; - convertFormat(m_format, &glFormat, &glType, &swizzle); - m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); + convertFormat(m_context, m_format, &glFormat, &glType, &swizzle); if (swizzle) { ASSERT(glFormat == GraphicsContext3D::RGBA && glType == GraphicsContext3D::UNSIGNED_BYTE); // FIXME: This could use PBO's to save doing an extra copy here. - int size = m_width * m_height; - unsigned* pixels32 = static_cast<unsigned*>(pixels); - OwnArrayPtr<unsigned> buf(new unsigned[size]); - unsigned* bufptr = buf.get(); - for (int i = 0; i < size; ++i) { - unsigned pixel = pixels32[i]; - bufptr[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); + } + OwnArrayPtr<uint32_t> tempBuff(new uint32_t[m_tiles.maxTextureSize() * m_tiles.maxTextureSize()]); + + for (int i = 0; i < m_tiles.numTiles(); i++) { + IntRect tileBoundsWithBorder = m_tiles.tileBoundsWithBorder(i); + + uint32_t* uploadBuff = 0; + if (swizzle) { + uploadBuff = copySubRect<true>( + pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(), + tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX()); + } else { + uploadBuff = copySubRect<false>( + pixels32, tileBoundsWithBorder.x(), tileBoundsWithBorder.y(), + tempBuff.get(), tileBoundsWithBorder.width(), tileBoundsWithBorder.height(), m_tiles.totalSizeX()); } - m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, m_width, m_height, glFormat, glType, buf.get()); - } else - m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, m_width, m_height, glFormat, glType, pixels); + + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(i)); + m_context->texSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, + tileBoundsWithBorder.width(), + tileBoundsWithBorder.height(), glFormat, glType, uploadBuff); + } } -void GLES2Texture::bind() +void GLES2Texture::bindTile(int tile) { - m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId); + m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_tileTextureIds->at(tile)); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR); m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE); diff --git a/WebCore/platform/graphics/chromium/GLES2Texture.h b/WebCore/platform/graphics/chromium/GLES2Texture.h index 4d351cd..43a4955 100644 --- a/WebCore/platform/graphics/chromium/GLES2Texture.h +++ b/WebCore/platform/graphics/chromium/GLES2Texture.h @@ -35,6 +35,10 @@ #include "RefCounted.h" #include "RefPtr.h" +#include "TilingData.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> namespace WebCore { class GraphicsContext3D; @@ -44,18 +48,16 @@ public: ~GLES2Texture(); enum Format { RGBA8, BGRA8 }; static PassRefPtr<GLES2Texture> create(GraphicsContext3D*, Format, int width, int height); - void bind(); + void bindTile(int tile); void load(void* pixels); Format format() const { return m_format; } - int width() const { return m_width; } - int height() const { return m_height; } + const TilingData& tiles() const { return m_tiles; } private: - GLES2Texture(GraphicsContext3D*, unsigned textureId, Format, int width, int height); + GLES2Texture(GraphicsContext3D*, PassOwnPtr<Vector<unsigned int> > tileTextureIds, Format format, int width, int height, int maxTextureSize); GraphicsContext3D* m_context; - unsigned m_textureId; Format m_format; - int m_width; - int m_height; + TilingData m_tiles; + OwnPtr<Vector<unsigned int> > m_tileTextureIds; }; } diff --git a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp index 9f6ee17..3cc7cad 100644 --- a/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/ImageLayerChromium.cpp @@ -114,7 +114,7 @@ void ImageLayerChromium::updateTextureContents(unsigned textureId) case kCGColorSpaceModelDeviceN: break; default: - colorSpace.adoptCF(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); + colorSpace.adoptCF(CGColorSpaceCreateDeviceRGB()); break; } RetainPtr<CGContextRef> tempContext(AdoptCF, CGBitmapContextCreate(tempVector.data(), diff --git a/WebCore/platform/graphics/chromium/LayerChromium.cpp b/WebCore/platform/graphics/chromium/LayerChromium.cpp index bba65f4..21d8d12 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerChromium.cpp @@ -180,8 +180,7 @@ void LayerChromium::updateTextureContents(unsigned textureId) int rowBytes = 4 * dirtyRect.width(); tempVector.resize(rowBytes * dirtyRect.height()); memset(tempVector.data(), 0, tempVector.size()); - // FIXME: unsure whether this is the best color space choice. - RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(), dirtyRect.width(), dirtyRect.height(), 8, rowBytes, colorSpace.get(), diff --git a/WebCore/platform/graphics/chromium/LayerChromium.h b/WebCore/platform/graphics/chromium/LayerChromium.h index ebb4504..9fba415 100644 --- a/WebCore/platform/graphics/chromium/LayerChromium.h +++ b/WebCore/platform/graphics/chromium/LayerChromium.h @@ -38,12 +38,12 @@ #include "GraphicsContext.h" #include "GraphicsLayerChromium.h" #include "PlatformString.h" -#include "StringHash.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> namespace skia { diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp index 15acfa5..2f70efa 100644 --- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp +++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp @@ -255,8 +255,7 @@ void LayerRendererChromium::setRootLayerCanvasSize(const IntSize& size) int rowBytes = 4 * size.width(); m_rootLayerBackingStore.resize(rowBytes * size.height()); memset(m_rootLayerBackingStore.data(), 0, m_rootLayerBackingStore.size()); - // FIXME: unsure whether this is the best color space choice. - RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateWithName(kCGColorSpaceGenericRGBLinear)); + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); m_rootLayerCGContext.adoptCF(CGBitmapContextCreate(m_rootLayerBackingStore.data(), size.width(), size.height(), 8, rowBytes, colorSpace.get(), diff --git a/WebCore/platform/graphics/chromium/TilingData.cpp b/WebCore/platform/graphics/chromium/TilingData.cpp new file mode 100755 index 0000000..c52288d --- /dev/null +++ b/WebCore/platform/graphics/chromium/TilingData.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "TilingData.h" + +#include "FloatRect.h" +#include "IntRect.h" +#include <algorithm> + +using namespace std; + +namespace WebCore { + +static int computeNumTiles(int maxTextureSize, int totalSize, int borderTexels) +{ + return max(1, 1 + (totalSize - 1 - 2 * borderTexels) / (maxTextureSize - 2 * borderTexels)); +} + +TilingData::TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels) + : m_maxTextureSize(maxTextureSize) + , m_totalSizeX(totalSizeX) + , m_totalSizeY(totalSizeY) + , m_borderTexels(hasBorderTexels ? 1 : 0) +{ + m_numTilesX = computeNumTiles(maxTextureSize, m_totalSizeX, m_borderTexels); + m_numTilesY = computeNumTiles(maxTextureSize, m_totalSizeY, m_borderTexels); +} + +int TilingData::tileXIndexFromSrcCoord(int srcPos) const +{ + int x = (srcPos - m_borderTexels) / (m_maxTextureSize - 2 * m_borderTexels); + return min(max(x, 0), numTilesX() - 1); +} + +int TilingData::tileYIndexFromSrcCoord(int srcPos) const +{ + int y = (srcPos - m_borderTexels) / (m_maxTextureSize - 2 * m_borderTexels); + return min(max(y, 0), numTilesY() - 1); +} + +IntRect TilingData::tileBounds(int tile) const +{ + assertTile(tile); + int ix = tileXIndex(tile); + int iy = tileYIndex(tile); + int x = tilePositionX(ix); + int y = tilePositionY(iy); + int width = tileSizeX(ix); + int height = tileSizeY(iy); + ASSERT(x >= 0 && y >= 0 && width >= 0 && height >= 0); + ASSERT(x <= totalSizeX() && y <= totalSizeY()); + return IntRect(x, y, width, height); +} + +IntRect TilingData::tileBoundsWithBorder(int tile) const +{ + IntRect bounds = tileBounds(tile); + + if (m_borderTexels) { + int x1 = bounds.x(); + int x2 = bounds.right(); + int y1 = bounds.y(); + int y2 = bounds.bottom(); + + if (tileXIndex(tile) > 0) + x1--; + if (tileXIndex(tile) < (numTilesX() - 1)) + x2++; + if (tileYIndex(tile) > 0) + y1--; + if (tileYIndex(tile) < (numTilesY() - 1)) + y2++; + + bounds = IntRect(x1, y1, x2 - x1, y2 - y1); + } + + return bounds; +} + +FloatRect TilingData::tileBoundsNormalized(int tile) const +{ + assertTile(tile); + FloatRect bounds(tileBounds(tile)); + bounds.scale(1.0f / m_totalSizeX, 1.0f / m_totalSizeY); + return bounds; +} + +int TilingData::tilePositionX(int xIndex) const +{ + ASSERT(xIndex >= 0 && xIndex < numTilesX()); + + if (!xIndex) + return 0; + return tilePositionX(xIndex - 1) + tileSizeX(xIndex - 1); +} + +int TilingData::tilePositionY(int yIndex) const +{ + ASSERT(yIndex >= 0 && yIndex < numTilesY()); + + if (!yIndex) + return 0; + return tilePositionX(yIndex - 1) + tileSizeY(yIndex - 1); +} + +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) + return m_maxTextureSize - m_borderTexels; + if (xIndex < numTilesX() - 1) + return m_maxTextureSize - 2 * m_borderTexels; + if (xIndex == numTilesX() - 1) + return m_totalSizeX - tilePositionX(xIndex); + + ASSERT_NOT_REACHED(); + return 0; +} + +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) + return m_maxTextureSize - m_borderTexels; + if (yIndex < numTilesY() - 1) + return m_maxTextureSize - 2 * m_borderTexels; + if (yIndex == numTilesY() - 1) + return m_totalSizeY - tilePositionY(yIndex); + + ASSERT_NOT_REACHED(); + return 0; +} + +IntRect TilingData::overlappedTileIndices(const WebCore::IntRect &srcRect) const +{ + int x = tileXIndexFromSrcCoord(srcRect.x()); + int y = tileYIndexFromSrcCoord(srcRect.y()); + int r = tileXIndexFromSrcCoord(srcRect.right()); + int b = tileYIndexFromSrcCoord(srcRect.bottom()); + return IntRect(x, y, r - x, b - y); +} + +IntRect TilingData::overlappedTileIndices(const WebCore::FloatRect &srcRect) const +{ + return overlappedTileIndices(enclosingIntRect(srcRect)); +} + +void TilingData::intersectDrawQuad(const FloatRect& srcRect, const FloatRect& dstRect, int tile, + FloatRect* newSrc, FloatRect* newDst) const +{ + // Intersect with tile + FloatRect tileBounds = this->tileBounds(tile); + FloatRect srcRectIntersected = srcRect; + srcRectIntersected.intersect(tileBounds); + + if (srcRectIntersected.isEmpty()) { + *newSrc = *newDst = FloatRect(0, 0, 0, 0); + return; + } + + float srcRectIntersectedNormX = (srcRectIntersected.x() - srcRect.x()) / srcRect.width(); + float srcRectIntersectedNormY = (srcRectIntersected.y() - srcRect.y()) / srcRect.height(); + float srcRectIntersectedNormW = srcRectIntersected.width() / srcRect.width(); + float srcRectIntersectedNormH = srcRectIntersected.height() / srcRect.height(); + + *newSrc = srcRectIntersected; + newSrc->move( + -tileBounds.x() + ((tileXIndex(tile) > 0) ? m_borderTexels : 0), + -tileBounds.y() + ((tileYIndex(tile) > 0) ? m_borderTexels : 0)); + + *newDst = FloatRect( + srcRectIntersectedNormX * dstRect.width() + dstRect.x(), + srcRectIntersectedNormY * dstRect.height() + dstRect.y(), + srcRectIntersectedNormW * dstRect.width(), + srcRectIntersectedNormH * dstRect.height()); +} + +} diff --git a/WebCore/platform/graphics/chromium/TilingData.h b/WebCore/platform/graphics/chromium/TilingData.h new file mode 100755 index 0000000..f12e66e --- /dev/null +++ b/WebCore/platform/graphics/chromium/TilingData.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TilingData_h +#define TilingData_h + +#include <wtf/Noncopyable.h> + +namespace WebCore { + +class FloatRect; +class IntRect; + +class TilingData : public Noncopyable { +public: + TilingData(int maxTextureSize, int totalSizeX, int totalSizeY, bool hasBorderTexels); + int maxTextureSize() const { return m_maxTextureSize; } + int totalSizeX() const { return m_totalSizeX; } + int totalSizeY() const { return m_totalSizeY; } + + int numTiles() const { return numTilesX() * numTilesY(); } + int numTilesX() const { return m_numTilesX; } + int numTilesY() const { return m_numTilesY; } + int tileIndex(int x, int y) const { return x + y * numTilesX(); } + int tileXIndex(int tile) const { assertTile(tile); return tile % numTilesX(); } + int tileYIndex(int tile) const { assertTile(tile); return tile / numTilesX(); } + int tileXIndexFromSrcCoord(int) const; + int tileYIndexFromSrcCoord(int) const; + + IntRect tileBounds(int tile) const; + IntRect tileBoundsWithBorder(int tile) const; + FloatRect tileBoundsNormalized(int tile) const; + int tilePositionX(int xIndex) const; + int tilePositionY(int yIndex) const; + int tileSizeX(int xIndex) const; + int tileSizeY(int yIndex) const; + IntRect overlappedTileIndices(const IntRect& srcRect) const; + IntRect overlappedTileIndices(const FloatRect& srcRect) const; + + // Given a set of source and destination coordinates for a drawing quad + // 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; + +private: + TilingData() : m_maxTextureSize(0), m_totalSizeX(0), m_totalSizeY(0) {} + void assertTile(int tile) const { ASSERT(tile >= 0 && tile < numTiles()); } + + int m_maxTextureSize; + int m_totalSizeX; + int m_totalSizeY; + int m_borderTexels; // 0 or 1 + + // computed values: + int m_numTilesX; + int m_numTilesY; +}; + +} + +#endif // TilingData_h diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp index c5ae3b9..7718066 100644 --- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -164,7 +164,7 @@ void FEColorMatrix::apply(Filter* filter) if (!filterContext) return; - filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); IntRect imageRect(IntPoint(), resultImage()->size()); PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect)); diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp index 18df3b2..0bafc48 100644 --- a/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/WebCore/platform/graphics/filters/FEComposite.cpp @@ -131,26 +131,26 @@ void FEComposite::apply(Filter* filter) FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f); switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: - filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); + filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); break; case FECOMPOSITE_OPERATOR_IN: filterContext->save(); - filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->scaledSubRegion()), m_in2->resultImage()); - filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->clipToImageBuffer(m_in->resultImage(), calculateDrawingRect(m_in2->scaledSubRegion())); + filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); filterContext->restore(); break; case FECOMPOSITE_OPERATOR_OUT: - filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); - filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut); + filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); + filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut); break; case FECOMPOSITE_OPERATOR_ATOP: - filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop); + filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); + filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop); break; case FECOMPOSITE_OPERATOR_XOR: - filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); - filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR); + filterContext->drawImageBuffer(m_in2->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); + filterContext->drawImageBuffer(m_in->resultImage(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR); break; case FECOMPOSITE_OPERATOR_ARITHMETIC: { IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp index 61aea90..70465a0 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp @@ -3,6 +3,7 @@ 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> 2009 Dirk Schulze <krit@webkit.org> + 2010 Igalia, S.L. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -29,18 +30,19 @@ #include "Filter.h" #include "GraphicsContext.h" #include "ImageData.h" -#include <math.h> #include <wtf/MathExtras.h> using std::max; +static const float gGaussianKernelFactor = (3 * sqrtf(2 * piFloat) / 4.f); + namespace WebCore { FEGaussianBlur::FEGaussianBlur(FilterEffect* in, const float& x, const float& y) : FilterEffect() , m_in(in) - , m_x(x) - , m_y(y) + , m_stdX(x) + , m_stdY(y) { } @@ -51,30 +53,27 @@ PassRefPtr<FEGaussianBlur> FEGaussianBlur::create(FilterEffect* in, const float& float FEGaussianBlur::stdDeviationX() const { - return m_x; + return m_stdX; } void FEGaussianBlur::setStdDeviationX(float x) { - m_x = x; + m_stdX = x; } float FEGaussianBlur::stdDeviationY() const { - return m_y; + return m_stdY; } void FEGaussianBlur::setStdDeviationY(float y) { - m_y = y; + m_stdY = y; } static void boxBlur(CanvasPixelArray*& srcPixelArray, CanvasPixelArray*& dstPixelArray, - unsigned dx, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage) + unsigned dx, int dxLeft, int dxRight, int stride, int strideLine, int effectWidth, int effectHeight, bool alphaImage) { - int dxLeft = dx / 2; - int dxRight = dx - dxLeft; - for (int y = 0; y < effectHeight; ++y) { int line = y * strideLine; for (int channel = 3; channel >= 0; --channel) { @@ -99,6 +98,34 @@ static void boxBlur(CanvasPixelArray*& srcPixelArray, CanvasPixelArray*& dstPixe } } +void FEGaussianBlur::kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight) +{ + // check http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement for details + switch (boxBlur) { + case 0: + if (!(std % 2)) { + dLeft = std / 2 - 1; + dRight = std - dLeft; + } else { + dLeft = std / 2; + dRight = std - dLeft; + } + break; + case 1: + if (!(std % 2)) { + dLeft++; + dRight--; + } + break; + case 2: + if (!(std % 2)) { + dRight++; + std++; + } + break; + } +} + void FEGaussianBlur::apply(Filter* filter) { m_in->apply(filter); @@ -110,26 +137,50 @@ void FEGaussianBlur::apply(Filter* filter) setIsAlphaImage(m_in->isAlphaImage()); - if (m_x == 0 || m_y == 0) + IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); + RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)); + IntRect imageRect(IntPoint(), resultImage()->size()); + + if (!m_stdX && !m_stdY) { + resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint()); return; + } - unsigned sdx = static_cast<unsigned>(floor(m_x * filter->filterResolution().width() * 3 * sqrt(2 * piDouble) / 4.f + 0.5f)); - unsigned sdy = static_cast<unsigned>(floor(m_y * filter->filterResolution().height() * 3 * sqrt(2 * piDouble) / 4.f + 0.5f)); - sdx = max(sdx, static_cast<unsigned>(1)); - sdy = max(sdy, static_cast<unsigned>(1)); + unsigned kernelSizeX = 0; + if (m_stdX) + kernelSizeX = max(2U, static_cast<unsigned>(floor(m_stdX * filter->filterResolution().width() * gGaussianKernelFactor + 0.5f))); - IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); - RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)); - CanvasPixelArray* srcPixelArray(srcImageData->data()); + unsigned kernelSizeY = 0; + if (m_stdY) + kernelSizeY = max(2U, static_cast<unsigned>(floor(m_stdY * filter->filterResolution().height() * gGaussianKernelFactor + 0.5f))); - IntRect imageRect(IntPoint(), resultImage()->size()); + CanvasPixelArray* srcPixelArray(srcImageData->data()); RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height()); CanvasPixelArray* tmpPixelArray(tmpImageData->data()); int stride = 4 * imageRect.width(); + int dxLeft = 0; + int dxRight = 0; + int dyLeft = 0; + int dyRight = 0; for (int i = 0; i < 3; ++i) { - boxBlur(srcPixelArray, tmpPixelArray, sdx, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage()); - boxBlur(tmpPixelArray, srcPixelArray, sdy, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage()); + if (kernelSizeX) { + kernelPosition(i, kernelSizeX, dxLeft, dxRight); + boxBlur(srcPixelArray, tmpPixelArray, kernelSizeX, dxLeft, dxRight, 4, stride, imageRect.width(), imageRect.height(), isAlphaImage()); + } else { + CanvasPixelArray* auxPixelArray = tmpPixelArray; + tmpPixelArray = srcPixelArray; + srcPixelArray = auxPixelArray; + } + + if (kernelSizeY) { + kernelPosition(i, kernelSizeY, dyLeft, dyRight); + boxBlur(tmpPixelArray, srcPixelArray, kernelSizeY, dyLeft, dyRight, stride, 4, imageRect.height(), imageRect.width(), isAlphaImage()); + } else { + CanvasPixelArray* auxPixelArray = tmpPixelArray; + tmpPixelArray = srcPixelArray; + srcPixelArray = auxPixelArray; + } } resultImage()->putPremultipliedImageData(srcImageData.get(), imageRect, IntPoint()); @@ -144,7 +195,7 @@ TextStream& FEGaussianBlur::externalRepresentation(TextStream& ts, int indent) c writeIndent(ts, indent); ts << "[feGaussianBlur"; FilterEffect::externalRepresentation(ts); - ts << " stdDeviation=\"" << m_x << ", " << m_y << "\"]\n"; + ts << " stdDeviation=\"" << m_stdX << ", " << m_stdY << "\"]\n"; m_in->externalRepresentation(ts, indent + 1); return ts; } diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.h b/WebCore/platform/graphics/filters/FEGaussianBlur.h index bcc030e..4c7c43c 100644 --- a/WebCore/platform/graphics/filters/FEGaussianBlur.h +++ b/WebCore/platform/graphics/filters/FEGaussianBlur.h @@ -45,10 +45,11 @@ public: private: FEGaussianBlur(FilterEffect*, const float&, const float&); + static void kernelPosition(int boxBlur, unsigned& std, int& dLeft, int& dRight); RefPtr<FilterEffect> m_in; - float m_x; - float m_y; + float m_stdX; + float m_stdY; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h index 8924b94..16d499f 100644 --- a/WebCore/platform/graphics/filters/Filter.h +++ b/WebCore/platform/graphics/filters/Filter.h @@ -24,11 +24,11 @@ #include "FloatRect.h" #include "FloatSize.h" #include "ImageBuffer.h" -#include "StringHash.h" #include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> #include <wtf/RefPtr.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp index eb23814..37b0023 100644 --- a/WebCore/platform/graphics/filters/SourceAlpha.cpp +++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp @@ -63,9 +63,9 @@ void SourceAlpha::apply(Filter* filter) setIsAlphaImage(true); - FloatRect imageRect(FloatPoint(), filter->sourceImage()->image()->size()); + FloatRect imageRect(FloatPoint(), filter->sourceImage()->size()); filterContext->save(); - filterContext->clipToImageBuffer(imageRect, filter->sourceImage()); + filterContext->clipToImageBuffer(filter->sourceImage(), imageRect); filterContext->fillRect(imageRect, Color::black, DeviceColorSpace); filterContext->restore(); } diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp index a1864d6..5730d34 100644 --- a/WebCore/platform/graphics/filters/SourceGraphic.cpp +++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp @@ -60,7 +60,7 @@ void SourceGraphic::apply(Filter* filter) if (!filterContext) return; - filterContext->drawImage(filter->sourceImage()->image(), DeviceColorSpace, IntPoint()); + filterContext->drawImageBuffer(filter->sourceImage(), DeviceColorSpace, IntPoint()); } void SourceGraphic::dump() diff --git a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp index d3b5f1b..1059b59 100644 --- a/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp +++ b/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp @@ -780,9 +780,13 @@ void StreamingClient::didFail(ResourceHandle*, const ResourceError& error) void StreamingClient::wasBlocked(ResourceHandle*) { + GST_ERROR_OBJECT(m_src, "Request was blocked"); + GST_ELEMENT_ERROR(m_src, RESOURCE, OPEN_READ, ("Access to \"%s\" was blocked", m_src->priv->uri), (0)); } void StreamingClient::cannotShowURL(ResourceHandle*) { + GST_ERROR_OBJECT(m_src, "Cannot show URL"); + GST_ELEMENT_ERROR(m_src, RESOURCE, OPEN_READ, ("Can't show \"%s\"", m_src->priv->uri), (0)); } diff --git a/WebCore/platform/graphics/gtk/ImageGtk.cpp b/WebCore/platform/graphics/gtk/ImageGtk.cpp index 30db6d7..5272243 100644 --- a/WebCore/platform/graphics/gtk/ImageGtk.cpp +++ b/WebCore/platform/graphics/gtk/ImageGtk.cpp @@ -27,81 +27,60 @@ #include "BitmapImage.h" #include "CairoUtilities.h" -#include "GOwnPtr.h" +#include "GOwnPtrGtk.h" #include "SharedBuffer.h" #include <wtf/text/CString.h> #include <cairo.h> #include <gtk/gtk.h> -#ifdef _WIN32 -# include <mbstring.h> -# include <shlobj.h> -/* search for data relative to where we are installed */ +#if PLATFORM(WIN) +#include <mbstring.h> +#include <shlobj.h> static HMODULE hmodule; -#ifdef __cplusplus extern "C" { -#endif -BOOL WINAPI -DllMain(HINSTANCE hinstDLL, - DWORD fdwReason, - LPVOID lpvReserved) +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - switch (fdwReason) { - case DLL_PROCESS_ATTACH: + if (fdwReason == DLL_PROCESS_ATTACH) hmodule = hinstDLL; - break; - } - return TRUE; } -#ifdef __cplusplus } -#endif -static char * -get_webkit_datadir(void) +static const char* getWebKitDataDirectory() { - static char retval[1000]; - static int beenhere = 0; - - unsigned char *p; - - if (beenhere) - return retval; + static char* dataDirectory = 0; + if (dataDirectory) + return dataDirectory; - if (!GetModuleFileName (hmodule, (CHAR *) retval, sizeof(retval) - 10)) + dataDirectory = new char[PATH_MAX]; + if (!GetModuleFileName(hmodule, static_cast<CHAR*>(dataDirectory), sizeof(dataDirectory) - 10)) return DATA_DIR; - p = _mbsrchr((const unsigned char *) retval, '\\'); + // FIXME: This is pretty ugly. Ideally we should be using Windows API + // functions or GLib methods to calculate paths. + unsigned char *p; + p = _mbsrchr(static_cast<const unsigned char *>(dataDirectory), '\\'); *p = '\0'; - p = _mbsrchr((const unsigned char *) retval, '\\'); + p = _mbsrchr(static_cast<const unsigned char *>(dataDirectory), '\\'); if (p) { if (!stricmp((const char *) (p+1), "bin")) *p = '\0'; } - strcat(retval, "\\share"); - - beenhere = 1; + strcat(dataDirectory, "\\share"); - return retval; + return dataDirectory; } -#undef DATA_DIR -#define DATA_DIR get_webkit_datadir () -#endif - +#else -namespace WTF { - -template <> void freeOwnedGPtr<GtkIconInfo>(GtkIconInfo* info) +static const char* getWebKitDataDirectory() { - if (info) - gtk_icon_info_free(info); + return DATA_DIR; } -} +#endif namespace WebCore { @@ -158,11 +137,9 @@ PassRefPtr<Image> Image::loadPlatformResource(const char* name) if (!strcmp("missingImage", name)) fileName = getThemeIconFileName(GTK_STOCK_MISSING_IMAGE, 16); if (fileName.isNull()) { - gchar* imagename = g_strdup_printf("%s.png", name); - gchar* glibFileName = g_build_filename(DATA_DIR, "webkit-1.0", "images", imagename, NULL); - fileName = glibFileName; - g_free(imagename); - g_free(glibFileName); + GOwnPtr<gchar> imageName(g_strdup_printf("%s.png", name)); + GOwnPtr<gchar> glibFileName(g_build_filename(getWebKitDataDirectory(), "webkitgtk-"WEBKITGTK_API_VERSION_STRING, "images", imageName.get(), NULL)); + fileName = glibFileName.get(); } return loadImageFromFile(fileName); diff --git a/WebCore/platform/graphics/mac/FontPlatformData.h b/WebCore/platform/graphics/mac/FontPlatformData.h index 07ae4f8..dc876a8 100644 --- a/WebCore/platform/graphics/mac/FontPlatformData.h +++ b/WebCore/platform/graphics/mac/FontPlatformData.h @@ -24,7 +24,7 @@ #ifndef FontPlatformData_h #define FontPlatformData_h -#include "StringImpl.h" +#include <wtf/text/StringImpl.h> #ifdef __OBJC__ @class NSFont; diff --git a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm index fd503fc..be1d278 100644 --- a/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm +++ b/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm @@ -31,6 +31,7 @@ #import "BlockExceptions.h" +#include "ANGLE/ResourceLimits.h" #include "ArrayBuffer.h" #include "ArrayBufferView.h" #include "WebGLObject.h" @@ -181,6 +182,30 @@ GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs, HostWi ::glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); } + // ANGLE initialization. + + TBuiltInResource ANGLEResources; + + ANGLEResources.maxVertexAttribs = 0; + getIntegerv(GraphicsContext3D::MAX_VERTEX_ATTRIBS, &ANGLEResources.maxVertexAttribs); + ANGLEResources.maxVertexUniformVectors = 0; + getIntegerv(GraphicsContext3D::MAX_VERTEX_UNIFORM_VECTORS, &ANGLEResources.maxVertexUniformVectors); + ANGLEResources.maxVaryingVectors = 0; + getIntegerv(GraphicsContext3D::MAX_VARYING_VECTORS, &ANGLEResources.maxVaryingVectors); + ANGLEResources.maxVertexTextureImageUnits = 0; + getIntegerv(GraphicsContext3D::MAX_VERTEX_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxVertexTextureImageUnits); + ANGLEResources.maxCombinedTextureImageUnits = 0; + getIntegerv(GraphicsContext3D::MAX_COMBINED_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxCombinedTextureImageUnits); + ANGLEResources.maxTextureImageUnits = 0; + getIntegerv(GraphicsContext3D::MAX_TEXTURE_IMAGE_UNITS, &ANGLEResources.maxTextureImageUnits); + ANGLEResources.maxFragmentUniformVectors = 0; + getIntegerv(GraphicsContext3D::MAX_FRAGMENT_UNIFORM_VECTORS, &ANGLEResources.maxFragmentUniformVectors); + + // Always set to 1 for OpenGL ES. + ANGLEResources.maxDrawBuffers = 1; + + m_compiler.setResources(ANGLEResources); + ::glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); ::glClearColor(0, 0, 0, 0); } @@ -282,15 +307,6 @@ void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* co canvas->width(), canvas->height(), imageBuffer->context()->platformContext()); } -void GraphicsContext3D::beginPaint(CanvasRenderingContext* context) -{ - UNUSED_PARAM(context); -} - -void GraphicsContext3D::endPaint() -{ -} - bool GraphicsContext3D::isGLES2Compliant() const { return false; @@ -617,7 +633,52 @@ void GraphicsContext3D::compileShader(Platform3DObject shader) { ASSERT(shader); ensureContext(m_contextObj); + + int GLshaderType; + ANGLEShaderType shaderType; + + glGetShaderiv(shader, SHADER_TYPE, &GLshaderType); + + if (GLshaderType == VERTEX_SHADER) + shaderType = SHADER_TYPE_VERTEX; + else if (GLshaderType == FRAGMENT_SHADER) + shaderType = SHADER_TYPE_FRAGMENT; + else + return; // Invalid shader type. + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + if (result == m_shaderSourceMap.end()) + return; + + ShaderSourceEntry& entry = result->second; + + String translatedShaderSource; + String shaderInfoLog; + + bool isValid = m_compiler.validateShaderSource(entry.source.utf8().data(), shaderType, translatedShaderSource, shaderInfoLog); + + entry.log = shaderInfoLog; + entry.isValid = isValid; + + if (!isValid) + return; // Shader didn't validate, don't move forward with compiling translated source + + int translatedShaderLength = translatedShaderSource.length(); + + const CString& translatedShaderCString = translatedShaderSource.utf8(); + const char* translatedShaderPtr = translatedShaderCString.data(); + + ::glShaderSource((GLuint) shader, 1, &translatedShaderPtr, &translatedShaderLength); + ::glCompileShader((GLuint) shader); + + int GLCompileSuccess; + + ::glGetShaderiv((GLuint) shader, COMPILE_STATUS, &GLCompileSuccess); + + // ASSERT that ANGLE generated GLSL will be accepted by OpenGL + ASSERT(GLCompileSuccess == GL_TRUE); } void GraphicsContext3D::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border) @@ -998,11 +1059,12 @@ void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri ASSERT(shader); ensureContext(m_contextObj); - const CString& cs = string.utf8(); - const char* s = cs.data(); - - int length = string.length(); - ::glShaderSource((GLuint) shader, 1, &s, &length); + + ShaderSourceEntry entry; + + entry.source = string; + + m_shaderSourceMap.set(shader, entry); } void GraphicsContext3D::stencilFunc(unsigned long func, long ref, unsigned long mask) @@ -1346,26 +1408,77 @@ void GraphicsContext3D::getShaderiv(Platform3DObject shader, unsigned long pname ASSERT(shader); ensureContext(m_contextObj); - ::glGetShaderiv((GLuint) shader, pname, value); + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + switch (pname) { + case DELETE_STATUS: + case SHADER_TYPE: + // Let OpenGL handle these. + + ::glGetShaderiv((GLuint) shader, pname, value); + break; + + case COMPILE_STATUS: + if (result == m_shaderSourceMap.end()) { + (*value) = static_cast<int>(false); + return; + } + + (*value) = static_cast<int>(result->second.isValid); + break; + + case INFO_LOG_LENGTH: + if (result == m_shaderSourceMap.end()) { + (*value) = 0; + return; + } + + (*value) = getShaderInfoLog(shader).length(); + break; + + case SHADER_SOURCE_LENGTH: + (*value) = getShaderSource(shader).length(); + break; + + default: + synthesizeGLError(INVALID_ENUM); + } } String GraphicsContext3D::getShaderInfoLog(Platform3DObject shader) { ASSERT(shader); - + ensureContext(m_contextObj); GLint length; ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length); - - GLsizei size; - GLchar* info = (GLchar*) fastMalloc(length); - if (!info) - return ""; - - ::glGetShaderInfoLog((GLuint) shader, length, &size, info); - String s(info); - fastFree(info); - return s; + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + if (result == m_shaderSourceMap.end()) + return ""; + + ShaderSourceEntry entry = result->second; + + if (entry.isValid) { + GLint length; + ::glGetShaderiv((GLuint) shader, GL_INFO_LOG_LENGTH, &length); + + GLsizei size; + GLchar* info = (GLchar*) fastMalloc(length); + if (!info) + return ""; + + ::glGetShaderInfoLog((GLuint) shader, length, &size, info); + + String s(info); + fastFree(info); + return s; + } + else { + return entry.log; + } } String GraphicsContext3D::getShaderSource(Platform3DObject shader) @@ -1373,18 +1486,13 @@ String GraphicsContext3D::getShaderSource(Platform3DObject shader) ASSERT(shader); ensureContext(m_contextObj); - GLint length; - ::glGetShaderiv((GLuint) shader, GL_SHADER_SOURCE_LENGTH, &length); - - GLsizei size; - GLchar* info = (GLchar*) fastMalloc(length); - if (!info) + + HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader); + + if (result == m_shaderSourceMap.end()) return ""; - - ::glGetShaderSource((GLuint) shader, length, &size, info); - String s(info); - fastFree(info); - return s; + + return result->second.source; } diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h index ee70338..a9f747a 100644 --- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h +++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h @@ -29,11 +29,11 @@ #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayer.h" -#include "StringHash.h" #include "WebLayer.h" #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/RetainPtr.h> +#include <wtf/text/StringHash.h> @class CABasicAnimation; @class CAKeyframeAnimation; diff --git a/WebCore/platform/graphics/qt/ContextShadow.cpp b/WebCore/platform/graphics/qt/ContextShadow.cpp new file mode 100644 index 0000000..0511218 --- /dev/null +++ b/WebCore/platform/graphics/qt/ContextShadow.cpp @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2010 Sencha, 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 "ContextShadow.h" + +namespace WebCore { + +ContextShadow::ContextShadow() + : type(NoShadow) + , blurRadius(0) +{ +} + +ContextShadow::ContextShadow(const QColor& c, float r, qreal dx, qreal dy) + : color(c) + , blurRadius(qRound(r)) + , offset(dx, dy) +{ + // The type of shadow is decided by the blur radius, shadow offset, and shadow color. + if (!color.isValid() || !color.alpha()) { + // Can't paint the shadow with invalid or invisible color. + type = NoShadow; + } else if (r > 0) { + // Shadow is always blurred, even the offset is zero. + type = BlurShadow; + } else if (offset.isNull()) { + // Without blur and zero offset means the shadow is fully hidden. + type = NoShadow; + } else { + if (color.alpha() > 0) + type = AlphaSolidShadow; + else + type = OpaqueSolidShadow; + } +} + +void ContextShadow::clear() +{ + type = NoShadow; + color = QColor(); + blurRadius = 0; + offset = QPointF(0, 0); +} + +// Instead of integer division, we use 18.14 for fixed-point division. +static const int BlurSumShift = 14; + +// Note: image must be RGB32 format +static void blurHorizontal(QImage& image, int radius, bool swap = false) +{ + Q_ASSERT(image.format() == QImage::Format_ARGB32_Premultiplied); + + // See comments in http://webkit.org/b/40793, it seems sensible + // to follow Skia's limit of 128 pixels of blur radius + radius = qMin(128, radius); + + int imgWidth = image.width(); + int imgHeight = image.height(); + + // Check http://www.w3.org/TR/SVG/filters.html#feGaussianBlur + // for the approaches when the box-blur radius is even vs odd. + int dmax = radius >> 1; + int dmin = qMax(0, dmax - 1 + (radius & 1)); + + for (int y = 0; y < imgHeight; ++y) { + + unsigned char* pixels = image.scanLine(y); + + int left; + int right; + int pixelCount; + int prev; + int next; + int firstAlpha; + int lastAlpha; + int totalAlpha; + unsigned char* target; + unsigned char* prevPtr; + unsigned char* nextPtr; + + int invCount; + + static const int alphaChannel = 3; + static const int blueChannel = 0; + static const int greenChannel = 1; + + // For each step, we use sliding window algorithm. This is much more + // efficient than computing the sum of each pixels covered by the box + // kernel size for each x. + + // As noted in the SVG filter specification, running box blur 3x + // approximates a real gaussian blur nicely. + + // Step 1: blur alpha channel and store the result in the blue channel. + left = swap ? dmax : dmin; + right = swap ? dmin : dmax; + pixelCount = left + 1 + right; + invCount = (1 << BlurSumShift) / pixelCount; + prev = -left; + next = 1 + right; + firstAlpha = pixels[alphaChannel]; + lastAlpha = pixels[(imgWidth - 1) * 4 + alphaChannel]; + totalAlpha = 0; + for (int i = 0; i < pixelCount; ++i) + totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + alphaChannel]; + target = pixels + blueChannel; + prevPtr = pixels + prev * 4 + alphaChannel; + nextPtr = pixels + next * 4 + alphaChannel; + for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) { + *target = (totalAlpha * invCount) >> BlurSumShift; + int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) - + ((prev > 0) ? *prevPtr : firstAlpha); + totalAlpha += delta; + } + + // Step 2: blur blue channel and store the result in the green channel. + left = swap ? dmin : dmax; + right = swap ? dmax : dmin; + pixelCount = left + 1 + right; + invCount = (1 << BlurSumShift) / pixelCount; + prev = -left; + next = 1 + right; + firstAlpha = pixels[blueChannel]; + lastAlpha = pixels[(imgWidth - 1) * 4 + blueChannel]; + totalAlpha = 0; + for (int i = 0; i < pixelCount; ++i) + totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + blueChannel]; + target = pixels + greenChannel; + prevPtr = pixels + prev * 4 + blueChannel; + nextPtr = pixels + next * 4 + blueChannel; + for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) { + *target = (totalAlpha * invCount) >> BlurSumShift; + int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) - + ((prev > 0) ? *prevPtr : firstAlpha); + totalAlpha += delta; + } + + // Step 3: blur green channel and store the result in the alpha channel. + left = dmax; + right = dmax; + pixelCount = left + 1 + right; + invCount = (1 << BlurSumShift) / pixelCount; + prev = -left; + next = 1 + right; + firstAlpha = pixels[greenChannel]; + lastAlpha = pixels[(imgWidth - 1) * 4 + greenChannel]; + totalAlpha = 0; + for (int i = 0; i < pixelCount; ++i) + totalAlpha += pixels[qBound(0, i - left, imgWidth - 1) * 4 + greenChannel]; + target = pixels + alphaChannel; + prevPtr = pixels + prev * 4 + greenChannel; + nextPtr = pixels + next * 4 + greenChannel; + for (int x = 0; x < imgWidth; ++x, ++prev, ++next, target += 4, prevPtr += 4, nextPtr += 4) { + *target = (totalAlpha * invCount) >> BlurSumShift; + int delta = ((next < imgWidth) ? *nextPtr : lastAlpha) - + ((prev > 0) ? *prevPtr : firstAlpha); + totalAlpha += delta; + } + } +} + +static void shadowBlur(QImage& image, int radius, const QColor& shadowColor) +{ + blurHorizontal(image, radius); + + QTransform transform; + transform.rotate(90); + image = image.transformed(transform); + blurHorizontal(image, radius, true); + transform.reset(); + transform.rotate(270); + image = image.transformed(transform); + + // "Colorize" with the right shadow color. + QPainter p(&image); + p.setCompositionMode(QPainter::CompositionMode_SourceIn); + p.fillRect(image.rect(), shadowColor.rgb()); + p.end(); +} + +void ContextShadow::drawShadowRect(QPainter* p, const QRectF& rect) +{ + if (type == NoShadow) + return; + + if (type == BlurShadow) { + QRectF shadowRect = rect.translated(offset); + + // We expand the area by the blur radius * 2 to give extra space + // for the blur transition. + int extra = blurRadius * 2; + QRectF bufferRect = shadowRect.adjusted(-extra, -extra, extra, extra); + QRect alignedBufferRect = bufferRect.toAlignedRect(); + + QRect clipRect; + if (p->hasClipping()) + clipRect = p->clipRegion().boundingRect(); + else + clipRect = p->transform().inverted().mapRect(p->window()); + + if (!clipRect.contains(alignedBufferRect)) { + + // No need to have the buffer larger that the clip. + alignedBufferRect = alignedBufferRect.intersected(clipRect); + if (alignedBufferRect.isEmpty()) + return; + + // We adjust again because the pixels at the borders are still + // potentially affected by the pixels outside the buffer. + alignedBufferRect.adjust(-extra, -extra, extra, extra); + } + + QImage shadowImage(alignedBufferRect.size(), QImage::Format_ARGB32_Premultiplied); + shadowImage.fill(Qt::transparent); + QPainter shadowPainter(&shadowImage); + + shadowPainter.fillRect(shadowRect.translated(-alignedBufferRect.topLeft()), color); + shadowPainter.end(); + + shadowBlur(shadowImage, blurRadius, color); + + p->drawImage(alignedBufferRect.topLeft(), shadowImage); + + return; + } + + p->fillRect(rect.translated(offset), color); +} + + +} diff --git a/WebCore/platform/graphics/qt/ContextShadow.h b/WebCore/platform/graphics/qt/ContextShadow.h new file mode 100644 index 0000000..e114ebc --- /dev/null +++ b/WebCore/platform/graphics/qt/ContextShadow.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 Sencha, 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 ContextShadow_h +#define ContextShadow_h + +#include <QPainter> + +namespace WebCore { + +// This is to track and keep the shadow state. We use this rather than +// using GraphicsContextState to allow possible optimizations (right now +// only to determine the shadow type, but in future it might covers things +// like cached scratch image, persistent shader, etc). + +// This class should be copyable since GraphicsContextQt keeps a stack of +// the shadow state for savePlatformState and restorePlatformState. + +class ContextShadow { +public: + enum { + NoShadow, + OpaqueSolidShadow, + AlphaSolidShadow, + BlurShadow + } type; + + QColor color; + int blurRadius; + QPointF offset; + + ContextShadow(); + ContextShadow(const QColor& c, float r, qreal dx, qreal dy); + + void clear(); + + // Draws the shadow for colored rectangle (can't be filled with pattern + // or gradient) according to the shadow parameters. + // Note: 'rect' specifies the rectangle which casts the shadow, + // NOT the bounding box of the shadow. + void drawShadowRect(QPainter* p, const QRectF& rect); + +}; + +} // namespace WebCore + +#endif // ContextShadow_h diff --git a/WebCore/platform/graphics/qt/FontCacheQt.cpp b/WebCore/platform/graphics/qt/FontCacheQt.cpp index bfcc5c3..c59c523 100644 --- a/WebCore/platform/graphics/qt/FontCacheQt.cpp +++ b/WebCore/platform/graphics/qt/FontCacheQt.cpp @@ -29,10 +29,10 @@ #include "FontPlatformData.h" #include "Font.h" #include "PlatformString.h" -#include "StringHash.h" #include <utility> #include <wtf/ListHashSet.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #include <QFont> diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp index 273e2dd..d5e7b3f 100644 --- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp @@ -512,15 +512,6 @@ void GraphicsContext3D::makeContextCurrent() m_internal->m_glWidget->makeCurrent(); } -void GraphicsContext3D::beginPaint(CanvasRenderingContext* context) -{ - paintRenderingResultsToCanvas(); -} - -void GraphicsContext3D::endPaint() -{ -} - void GraphicsContext3D::paintRenderingResultsToCanvas(CanvasRenderingContext* context) { m_internal->m_glWidget->makeCurrent(); diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp index d4a145f..1632804 100644 --- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp +++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp @@ -8,6 +8,7 @@ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> + * Copyright (C) 2010 Sencha, Inc. * * All rights reserved. * @@ -42,6 +43,7 @@ #include "AffineTransform.h" #include "Color.h" +#include "ContextShadow.h" #include "FloatConversion.h" #include "Font.h" #include "GraphicsContextPrivate.h" @@ -50,6 +52,7 @@ #include "Path.h" #include "Pattern.h" #include "Pen.h" +#include "TransparencyLayer.h" #include <QBrush> #include <QDebug> @@ -166,48 +169,6 @@ static inline Qt::FillRule toQtFillRule(WindRule rule) return Qt::OddEvenFill; } -struct TransparencyLayer : FastAllocBase { - TransparencyLayer(const QPainter* p, const QRect &rect, qreal opacity, QPixmap& alphaMask) - : pixmap(rect.width(), rect.height()) - , opacity(opacity) - , alphaMask(alphaMask) - , saveCounter(1) // see the comment for saveCounter - { - offset = rect.topLeft(); - pixmap.fill(Qt::transparent); - painter.begin(&pixmap); - painter.setRenderHint(QPainter::Antialiasing, p->testRenderHint(QPainter::Antialiasing)); - painter.translate(-offset); - painter.setPen(p->pen()); - painter.setBrush(p->brush()); - painter.setTransform(p->transform(), true); - painter.setOpacity(p->opacity()); - painter.setFont(p->font()); - if (painter.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) - painter.setCompositionMode(p->compositionMode()); - // if the path is an empty region, this assignment disables all painting - if (!p->clipPath().isEmpty()) - painter.setClipPath(p->clipPath()); - } - - TransparencyLayer() - { - } - - QPixmap pixmap; - QPoint offset; - QPainter painter; - qreal opacity; - // for clipToImageBuffer - QPixmap alphaMask; - // saveCounter is only used in combination with alphaMask - // otherwise, its value is unspecified - int saveCounter; -private: - TransparencyLayer(const TransparencyLayer &) {} - TransparencyLayer & operator=(const TransparencyLayer &) { return *this; } -}; - class GraphicsContextPlatformPrivate : public Noncopyable { public: GraphicsContextPlatformPrivate(QPainter* painter); @@ -240,6 +201,14 @@ public: // Only used by SVG for now. QPainterPath currentPath; + ContextShadow shadow; + QStack<ContextShadow> shadowStack; + + bool hasShadow() const + { + return shadow.type != ContextShadow::NoShadow; + } + private: QPainter* painter; }; @@ -307,6 +276,7 @@ void GraphicsContext::savePlatformState() if (!m_data->layers.isEmpty() && !m_data->layers.top()->alphaMask.isNull()) ++m_data->layers.top()->saveCounter; m_data->p()->save(); + m_data->shadowStack.push(m_data->shadow); } void GraphicsContext::restorePlatformState() @@ -321,9 +291,16 @@ void GraphicsContext::restorePlatformState() QTransform matrix = m_common->state.pathTransform; m_data->currentPath = m_data->currentPath * matrix; } + + if (m_data->shadowStack.isEmpty()) + m_data->shadow = ContextShadow(); + else + m_data->shadow = m_data->shadowStack.pop(); } // Draws a filled rectangle with a stroked border. +// This is only used to draw borders (real fill is done via fillRect), and +// thus it must not cast any shadow. void GraphicsContext::drawRect(const IntRect& rect) { if (paintingDisabled()) @@ -333,24 +310,13 @@ void GraphicsContext::drawRect(const IntRect& rect) const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); - if (m_common->state.shadowColor.isValid()) { - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - if (getShadow(shadowSize, shadowBlur, shadowColor)) { - IntRect shadowRect = rect; - shadowRect.move(shadowSize.width(), shadowSize.height()); - shadowRect.inflate(static_cast<int>(p->pen().widthF())); - p->fillRect(shadowRect, QColor(shadowColor)); - } - } - p->drawRect(rect); p->setRenderHint(QPainter::Antialiasing, antiAlias); } // This is only used to draw borders. +// Must not cast any shadow. void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) { if (paintingDisabled()) @@ -372,17 +338,6 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) p->setRenderHint(QPainter::Antialiasing, m_data->antiAliasingForRectsAndLines); adjustLineToPixelBoundaries(p1, p2, width, style); - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - if (textDrawingMode() == cTextFill && getShadow(shadowSize, shadowBlur, shadowColor)) { - p->save(); - p->translate(shadowSize.width(), shadowSize.height()); - p->setPen(shadowColor); - p->drawLine(p1, p2); - p->restore(); - } - int patWidth = 0; switch (style) { case NoStroke: @@ -474,16 +429,14 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp const bool antiAlias = p->testRenderHint(QPainter::Antialiasing); p->setRenderHint(QPainter::Antialiasing, true); - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; startAngle *= 16; angleSpan *= 16; - if (getShadow(shadowSize, shadowBlur, shadowColor)) { + + if (m_data->hasShadow()) { p->save(); - p->translate(shadowSize.width(), shadowSize.height()); + p->translate(m_data->shadow.offset); QPen pen(p->pen()); - pen.setColor(shadowColor); + pen.setColor(m_data->shadow.color); p->setPen(pen); p->drawArc(rect, startAngle, angleSpan); p->restore(); @@ -509,17 +462,14 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points QPainter* p = m_data->p(); p->save(); p->setRenderHint(QPainter::Antialiasing, shouldAntialias); - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - if (getShadow(shadowSize, shadowBlur, shadowColor)) { + if (m_data->hasShadow()) { p->save(); - p->translate(shadowSize.width(), shadowSize.height()); + p->translate(m_data->shadow.offset); if (p->brush().style() != Qt::NoBrush) - p->setBrush(QBrush(shadowColor)); + p->setBrush(QBrush(m_data->shadow.color)); QPen pen(p->pen()); if (pen.style() != Qt::NoPen) { - pen.setColor(shadowColor); + pen.setColor(m_data->shadow.color); p->setPen(pen); } p->drawConvexPolygon(polygon); @@ -553,18 +503,6 @@ QPen GraphicsContext::pen() return p->pen(); } -static void inline drawFilledShadowPath(GraphicsContext* context, QPainter* p, const QPainterPath& path) -{ - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - if (context->getShadow(shadowSize, shadowBlur, shadowColor)) { - p->translate(shadowSize.width(), shadowSize.height()); - p->fillPath(path, QBrush(shadowColor)); - p->translate(-shadowSize.width(), -shadowSize.height()); - } -} - void GraphicsContext::fillPath() { if (paintingDisabled()) @@ -574,7 +512,11 @@ void GraphicsContext::fillPath() QPainterPath& path = m_data->currentPath; // Avoid detaching the QPainterPath path.setFillRule(toQtFillRule(fillRule())); - drawFilledShadowPath(this, p, path); + if (m_data->hasShadow()) { + p->translate(m_data->shadow.offset); + p->fillPath(path, m_data->shadow.color); + p->translate(-m_data->shadow.offset); + } if (m_common->state.fillPattern) { AffineTransform affine; p->fillPath(path, QBrush(m_common->state.fillPattern->createPlatformPattern(affine))); @@ -598,16 +540,12 @@ void GraphicsContext::strokePath() QPainterPath& path = m_data->currentPath; // Avoid detaching the QPainterPath path.setFillRule(toQtFillRule(fillRule())); - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - if (getShadow(shadowSize, shadowBlur, shadowColor)) { - QTransform t(p->worldTransform()); - p->translate(shadowSize.width(), shadowSize.height()); + if (m_data->hasShadow()) { + p->translate(m_data->shadow.offset); QPen shadowPen(pen); - shadowPen.setColor(shadowColor); + shadowPen.setColor(m_data->shadow.color); p->strokePath(path, shadowPen); - p->setWorldTransform(t); + p->translate(-m_data->shadow.offset); } if (m_common->state.strokePattern) { AffineTransform affine; @@ -625,18 +563,6 @@ void GraphicsContext::strokePath() m_data->currentPath = QPainterPath(); } -static inline void drawBorderlessRectShadow(GraphicsContext* context, QPainter* p, const FloatRect& rect) -{ - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - if (context->getShadow(shadowSize, shadowBlur, shadowColor)) { - FloatRect shadowRect(rect); - shadowRect.move(shadowSize.width(), shadowSize.height()); - p->fillRect(shadowRect, QColor(shadowColor)); - } -} - static inline void drawRepeatPattern(QPainter* p, QPixmap* image, const FloatRect& rect, const bool repeatX, const bool repeatY) { // Patterns must be painted so that the top left of the first image is anchored at @@ -712,22 +638,18 @@ void GraphicsContext::fillRect(const FloatRect& rect) QPainter* p = m_data->p(); FloatRect normalizedRect = rect.normalized(); - FloatSize shadowSize; - float shadowBlur; - Color shadowColor; - bool hasShadow = getShadow(shadowSize, shadowBlur, shadowColor); - FloatRect shadowDestRect; + QRectF shadowDestRect; QImage* shadowImage = 0; QPainter* pShadow = 0; - if (hasShadow) { + if (m_data->hasShadow()) { shadowImage = new QImage(roundedIntSize(normalizedRect.size()), QImage::Format_ARGB32_Premultiplied); pShadow = new QPainter(shadowImage); shadowDestRect = normalizedRect; - shadowDestRect.move(shadowSize.width(), shadowSize.height()); + shadowDestRect.translate(m_data->shadow.offset); pShadow->setCompositionMode(QPainter::CompositionMode_Source); - pShadow->fillRect(shadowImage->rect(), shadowColor); + pShadow->fillRect(shadowImage->rect(), m_data->shadow.color); pShadow->setCompositionMode(QPainter::CompositionMode_DestinationIn); } @@ -737,7 +659,7 @@ void GraphicsContext::fillRect(const FloatRect& rect) QBrush brush(m_common->state.fillPattern->createPlatformPattern(affine)); QPixmap* image = m_common->state.fillPattern->tileImage()->nativeImageForCurrentFrame(); - if (hasShadow) { + if (m_data->hasShadow()) { drawRepeatPattern(pShadow, image, FloatRect(static_cast<QRectF>(shadowImage->rect())), m_common->state.fillPattern->repeatX(), m_common->state.fillPattern->repeatY()); pShadow->end(); p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect()); @@ -747,14 +669,14 @@ void GraphicsContext::fillRect(const FloatRect& rect) QBrush brush(*m_common->state.fillGradient->platformGradient()); brush.setTransform(m_common->state.fillGradient->gradientSpaceTransform()); - if (hasShadow) { + if (m_data->hasShadow()) { pShadow->fillRect(shadowImage->rect(), brush); pShadow->end(); p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect()); } p->fillRect(normalizedRect, brush); } else { - if (hasShadow) { + if (m_data->hasShadow()) { pShadow->fillRect(shadowImage->rect(), p->brush()); pShadow->end(); p->drawImage(shadowDestRect, *shadowImage, shadowImage->rect()); @@ -774,8 +696,10 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS m_data->solidColor.setColor(color); QPainter* p = m_data->p(); - if (m_common->state.shadowColor.isValid()) - drawBorderlessRectShadow(this, p, rect); + + if (m_data->hasShadow()) + m_data->shadow.drawShadowRect(p, rect); + p->fillRect(rect, m_data->solidColor); } @@ -786,7 +710,11 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef Path path = Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight); QPainter* p = m_data->p(); - drawFilledShadowPath(this, p, path.platformPath()); + if (m_data->hasShadow()) { + p->translate(m_data->shadow.offset); + p->fillPath(path.platformPath(), m_data->shadow.color); + p->translate(-m_data->shadow.offset); + } p->fillPath(path.platformPath(), QColor(color)); } @@ -928,7 +856,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect) return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin); } -void GraphicsContext::setPlatformShadow(const FloatSize& size, float, const Color&, ColorSpace) +void GraphicsContext::setPlatformShadow(const FloatSize& size, float blur, const Color& color, ColorSpace) { // Qt doesn't support shadows natively, they are drawn manually in the draw* // functions @@ -937,13 +865,20 @@ void GraphicsContext::setPlatformShadow(const FloatSize& size, float, const Colo // Meaning that this graphics context is associated with a CanvasRenderingContext // We flip the height since CG and HTML5 Canvas have opposite Y axis m_common->state.shadowSize = FloatSize(size.width(), -size.height()); + m_data->shadow = ContextShadow(color, blur, size.width(), -size.height()); + } else { + m_data->shadow = ContextShadow(color, blur, size.width(), size.height()); } } void GraphicsContext::clearPlatformShadow() { - // Qt doesn't support shadows natively, they are drawn manually in the draw* - // functions + m_data->shadow.clear(); +} + +void GraphicsContext::pushTransparencyLayerInternal(const QRect &rect, qreal opacity, QPixmap& alphaMask) +{ + m_data->layers.push(new TransparencyLayer(m_data->p(), m_data->p()->transform().mapRect(rect), 1.0, alphaMask)); } void GraphicsContext::beginTransparencyLayer(float opacity) @@ -1226,23 +1161,6 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) } } -void GraphicsContext::clipToImageBuffer(const FloatRect& floatRect, const ImageBuffer* image) -{ - if (paintingDisabled()) - return; - - QPixmap* nativeImage = image->image()->nativeImageForCurrentFrame(); - if (!nativeImage) - return; - - IntRect rect(floatRect); - QPixmap alphaMask = *nativeImage; - if (alphaMask.width() != rect.width() || alphaMask.height() != rect.height()) - alphaMask = alphaMask.scaled(rect.width(), rect.height()); - - m_data->layers.push(new TransparencyLayer(m_data->p(), m_data->p()->transform().mapRect(rect), 1.0, alphaMask)); -} - void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness) { diff --git a/WebCore/platform/graphics/qt/ImageBufferData.h b/WebCore/platform/graphics/qt/ImageBufferData.h index 222dabe..aa32253 100644 --- a/WebCore/platform/graphics/qt/ImageBufferData.h +++ b/WebCore/platform/graphics/qt/ImageBufferData.h @@ -26,6 +26,9 @@ #ifndef ImageBufferData_h #define ImageBufferData_h +#include "Image.h" +#include <wtf/RefPtr.h> + #include <QPainter> #include <QPixmap> @@ -41,6 +44,7 @@ public: QPixmap m_pixmap; OwnPtr<QPainter> m_painter; + RefPtr<Image> m_image; }; } // namespace WebCore diff --git a/WebCore/platform/graphics/qt/ImageBufferQt.cpp b/WebCore/platform/graphics/qt/ImageBufferQt.cpp index 761a4fe..11ca377 100644 --- a/WebCore/platform/graphics/qt/ImageBufferQt.cpp +++ b/WebCore/platform/graphics/qt/ImageBufferQt.cpp @@ -33,6 +33,7 @@ #include "ImageData.h" #include "MIMETypeRegistry.h" #include "StillImageQt.h" +#include "TransparencyLayer.h" #include <wtf/text/CString.h> #include <QBuffer> @@ -74,6 +75,8 @@ ImageBufferData::ImageBufferData(const IntSize& size) brush.setColor(Qt::black); painter->setBrush(brush); painter->setCompositionMode(QPainter::CompositionMode_SourceOver); + + m_image = StillImage::createForRendering(&m_pixmap); } ImageBuffer::ImageBuffer(const IntSize& size, ImageColorSpace, bool& success) @@ -98,24 +101,50 @@ GraphicsContext* ImageBuffer::context() const return m_context.get(); } -Image* ImageBuffer::imageForRendering() const +bool ImageBuffer::drawsUsingCopy() const { - if (!m_image) - m_image = StillImage::createForRendering(&m_data.m_pixmap); + return false; +} - return m_image.get(); +PassRefPtr<Image> ImageBuffer::copyImage() const +{ + return StillImage::create(m_data.m_pixmap); } -Image* ImageBuffer::image() const +void ImageBuffer::draw(GraphicsContext* destContext, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, + CompositeOperator op, bool useLowQualityScale) { - if (!m_image) { - // It's assumed that if image() is called, the actual rendering to the - // GraphicsContext must be done. - ASSERT(context()); - m_image = StillImage::create(m_data.m_pixmap); - } + if (destContext == context()) { + // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. + RefPtr<Image> copy = copyImage(); + destContext->drawImage(copy.get(), DeviceColorSpace, destRect, srcRect, op, useLowQualityScale); + } else + destContext->drawImage(m_data.m_image.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); +} + +void ImageBuffer::drawPattern(GraphicsContext* destContext, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + if (destContext == context()) { + // We're drawing into our own buffer. In order for this to work, we need to copy the source buffer first. + RefPtr<Image> copy = copyImage(); + copy->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); + } else + m_data.m_image->drawPattern(destContext, srcRect, patternTransform, phase, styleColorSpace, op, destRect); +} + +void ImageBuffer::clip(GraphicsContext* context, const FloatRect& floatRect) const +{ + QPixmap* nativeImage = m_data.m_image->nativeImageForCurrentFrame(); + if (!nativeImage) + return; + + IntRect rect(floatRect); + QPixmap alphaMask = *nativeImage; + if (alphaMask.width() != rect.width() || alphaMask.height() != rect.height()) + alphaMask = alphaMask.scaled(rect.width(), rect.height()); - return m_image.get(); + context->pushTransparencyLayerInternal(rect, 1.0, alphaMask); } void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) diff --git a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp index fb3d621..858cc44 100644 --- a/WebCore/platform/graphics/qt/ImageDecoderQt.cpp +++ b/WebCore/platform/graphics/qt/ImageDecoderQt.cpp @@ -78,6 +78,9 @@ void ImageDecoderQt::setData(SharedBuffer* data, bool allDataReceived) m_buffer->open(QIODevice::ReadOnly | QIODevice::Unbuffered); m_reader.set(new QImageReader(m_buffer.get(), m_format)); + // This will force the JPEG decoder to use JDCT_IFAST + m_reader->setQuality(49); + // QImageReader only allows retrieving the format before reading the image m_format = m_reader->format(); } @@ -186,20 +189,16 @@ void ImageDecoderQt::internalReadImage(size_t frameIndex) bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex) { QPixmap pixmap; - bool pixmapLoaded; - const int imageCount = m_reader->imageCount(); - if (imageCount == 0 || imageCount == 1) - pixmapLoaded = pixmap.loadFromData((const uchar*)(m_data->data()), m_data->size(), m_format); - else { - QImage img; - const bool imageLoaded = m_reader->read(&img); - if (imageLoaded) { - pixmap = QPixmap::fromImage(img); - pixmapLoaded = true; - } - } - if (!pixmapLoaded) { +#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0) + pixmap = QPixmap::fromImageReader(m_reader.get()); +#else + QImage img; + if (m_reader->read(&img)) + pixmap = QPixmap::fromImage(img); +#endif + + if (pixmap.isNull()) { frameCount(); repetitionCount(); clearPointers(); diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp index 3c6c5aa..08eb816 100644 --- a/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp +++ b/WebCore/platform/graphics/qt/MediaPlayerPrivatePhonon.cpp @@ -534,7 +534,11 @@ void MediaPlayerPrivate::aboutToFinish() void MediaPlayerPrivate::totalTimeChanged(qint64 totalTime) { +#if OS(WINDOWS) + LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%I64d)", totalTime); +#else LOG(Media, "MediaPlayerPrivatePhonon::totalTimeChanged(%lld)", totalTime); +#endif LOG_MEDIAOBJECT(); } diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp index 525aaf4..4ad5571 100644 --- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp +++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.cpp @@ -25,6 +25,7 @@ #include "GraphicsContext.h" #include "HTMLMediaElement.h" #include "HTMLVideoElement.h" +#include "NotImplemented.h" #include "TimeRanges.h" #include "Widget.h" #include "qwebframe.h" @@ -95,6 +96,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) , m_isSeeking(false) , m_composited(false) , m_queuedSeek(-1) + , m_preload(MediaPlayer::Auto) { m_mediaPlayer->bind(m_videoItem); m_videoScene->addItem(m_videoItem); @@ -106,6 +108,8 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) this, SLOT(stateChanged(QMediaPlayer::State))); connect(m_mediaPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(handleError(QMediaPlayer::Error))); + connect(m_mediaPlayer, SIGNAL(bufferStatusChanged(int)), + this, SLOT(bufferStatusChanged(int))); connect(m_mediaPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64))); connect(m_mediaPlayer, SIGNAL(positionChanged(qint64)), @@ -145,6 +149,20 @@ bool MediaPlayerPrivate::hasAudio() const void MediaPlayerPrivate::load(const String& url) { + m_mediaUrl = url; + + // QtMultimedia does not have an API to throttle loading + // so we handle this ourselves by delaying the load + if (m_preload == MediaPlayer::None) { + m_delayingLoad = true; + return; + } + + commitLoad(url); +} + +void MediaPlayerPrivate::commitLoad(const String& url) +{ // We are now loading if (m_networkState != MediaPlayer::Loading) { m_networkState = MediaPlayer::Loading; @@ -208,6 +226,21 @@ void MediaPlayerPrivate::load(const String& url) // engine which does. m_mediaPlayer->setMuted(element->muted()); m_mediaPlayer->setVolume(static_cast<int>(element->volume() * 100.0)); + + // 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()) + m_mediaPlayer->pause(); + else + m_mediaPlayer->play(); +} + +void MediaPlayerPrivate::resumeLoad() +{ + m_delayingLoad = false; + + if (!m_mediaUrl.isNull()) + commitLoad(m_mediaUrl); } void MediaPlayerPrivate::cancelLoad() @@ -216,6 +249,12 @@ void MediaPlayerPrivate::cancelLoad() updateStates(); } +void MediaPlayerPrivate::prepareToPlay() +{ + if (m_mediaPlayer->media().isNull() || m_delayingLoad) + resumeLoad(); +} + void MediaPlayerPrivate::play() { if (m_mediaPlayer->state() != QMediaPlayer::PlayingState) @@ -322,24 +361,11 @@ float MediaPlayerPrivate::maxTimeSeekable() const unsigned MediaPlayerPrivate::bytesLoaded() const { - unsigned percentage = m_mediaPlayer->bufferStatus(); - - if (percentage == 100) { - if (m_networkState != MediaPlayer::Idle) { - m_networkState = MediaPlayer::Idle; - m_player->networkStateChanged(); - } - if (m_readyState != MediaPlayer::HaveEnoughData) { - m_readyState = MediaPlayer::HaveEnoughData; - m_player->readyStateChanged(); - } - } - QLatin1String bytesLoadedKey("bytes-loaded"); if (m_mediaPlayer->availableExtendedMetaData().contains(bytesLoadedKey)) return m_mediaPlayer->extendedMetaData(bytesLoadedKey).toInt(); - return percentage; + return m_mediaPlayer->bufferStatus(); } unsigned MediaPlayerPrivate::totalBytes() const @@ -350,6 +376,13 @@ unsigned MediaPlayerPrivate::totalBytes() const return 100; } +void MediaPlayerPrivate::setPreload(MediaPlayer::Preload preload) +{ + m_preload = preload; + if (m_delayingLoad && m_preload != MediaPlayer::None) + resumeLoad(); +} + void MediaPlayerPrivate::setRate(float rate) { m_mediaPlayer->setPlaybackRate(rate); @@ -439,6 +472,11 @@ void MediaPlayerPrivate::positionChanged(qint64) } } +void MediaPlayerPrivate::bufferStatusChanged(int) +{ + notImplemented(); +} + void MediaPlayerPrivate::durationChanged(qint64) { m_player->durationChanged(); diff --git a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h index d72404c..165efde 100644 --- a/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h +++ b/WebCore/platform/graphics/qt/MediaPlayerPrivateQt.h @@ -50,10 +50,13 @@ public: bool hasAudio() const; void load(const String &url); + void commitLoad(const String& url); + void resumeLoad(); void cancelLoad(); void play(); void pause(); + void prepareToPlay(); bool paused() const; bool seeking() const; @@ -68,6 +71,8 @@ public: bool supportsMuting() const; void setMuted(bool); + void setPreload(MediaPlayer::Preload); + MediaPlayer::NetworkState networkState() const; MediaPlayer::ReadyState readyState() const; @@ -103,6 +108,7 @@ private slots: void seekTimeout(); void positionChanged(qint64); void durationChanged(qint64); + void bufferStatusChanged(int); void volumeChanged(int); void mutedChanged(bool); void repaint(); @@ -127,6 +133,10 @@ private: bool m_isSeeking; bool m_composited; qint64 m_queuedSeek; + MediaPlayer::Preload m_preload; + bool m_delayingLoad; + String m_mediaUrl; + }; } diff --git a/WebCore/platform/graphics/qt/PathQt.cpp b/WebCore/platform/graphics/qt/PathQt.cpp index de9de07..ce5da2e 100644 --- a/WebCore/platform/graphics/qt/PathQt.cpp +++ b/WebCore/platform/graphics/qt/PathQt.cpp @@ -51,6 +51,7 @@ namespace WebCore { Path::Path() + : m_lastMoveToIndex(0) { } @@ -60,12 +61,14 @@ Path::~Path() Path::Path(const Path& other) : m_path(other.m_path) + , m_lastMoveToIndex(other.m_lastMoveToIndex) { } Path& Path::operator=(const Path& other) { m_path = other.m_path; + m_lastMoveToIndex = other.m_lastMoveToIndex; return *this; } @@ -180,6 +183,7 @@ FloatRect Path::strokeBoundingRect(StrokeStyleApplier* applier) void Path::moveTo(const FloatPoint& point) { + m_lastMoveToIndex = m_path.elementCount(); m_path.moveTo(point); } @@ -260,7 +264,26 @@ void Path::addArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) void Path::closeSubpath() { - m_path.closeSubpath(); + const int elementCount = m_path.elementCount(); + + if (!elementCount) + return; + + QPointF lastMoveToPoint = m_path.elementAt(m_lastMoveToIndex); + int elementsInLastSubpath = 0; + + for (int i = m_lastMoveToIndex; i < elementCount; ++i) { + QPainterPath::Element element = m_path.elementAt(i); + if (element.isLineTo() || element.isCurveTo()) { + // All we need to know is if there are 1 or more elements in the last subpath. + if (++elementsInLastSubpath == 2) { + m_path.lineTo(lastMoveToPoint); + return; + } + } + } + + moveTo(lastMoveToPoint); } #define DEGREES(t) ((t) * 180.0 / M_PI) @@ -440,7 +463,7 @@ void Path::transform(const AffineTransform& transform) // QTransform.map doesn't handle the MoveTo element because of the isEmpty issue if (m_path.isEmpty() && m_path.elementCount()) { QPointF point = qTransform.map(m_path.currentPosition()); - m_path.moveTo(point); + moveTo(point); } else #endif m_path = qTransform.map(m_path); diff --git a/WebCore/platform/graphics/qt/TransparencyLayer.h b/WebCore/platform/graphics/qt/TransparencyLayer.h new file mode 100644 index 0000000..0d9c121 --- /dev/null +++ b/WebCore/platform/graphics/qt/TransparencyLayer.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2006 Dirk Mueller <mueller@kde.org> + * Copyright (C) 2006 Zack Rusin <zack@kde.org> + * Copyright (C) 2006 George Staikos <staikos@kde.org> + * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org> + * Copyright (C) 2006 Allan Sandfeld Jensen <sandfeld@kde.org> + * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2008 Dirk Schulze <vbs85@gmx.de> + * + * 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 TransparencyLayer_h +#define TransparencyLayer_h + +#include <QPaintEngine> +#include <QPainter> +#include <QPixmap> + +namespace WebCore { + +struct TransparencyLayer : FastAllocBase { + TransparencyLayer(const QPainter* p, const QRect &rect, qreal opacity, QPixmap& alphaMask) + : pixmap(rect.width(), rect.height()) + , opacity(opacity) + , alphaMask(alphaMask) + , saveCounter(1) // see the comment for saveCounter + { + offset = rect.topLeft(); + pixmap.fill(Qt::transparent); + painter.begin(&pixmap); + painter.setRenderHint(QPainter::Antialiasing, p->testRenderHint(QPainter::Antialiasing)); + painter.translate(-offset); + painter.setPen(p->pen()); + painter.setBrush(p->brush()); + painter.setTransform(p->transform(), true); + painter.setOpacity(p->opacity()); + painter.setFont(p->font()); + if (painter.paintEngine()->hasFeature(QPaintEngine::PorterDuff)) + painter.setCompositionMode(p->compositionMode()); + // if the path is an empty region, this assignment disables all painting + if (!p->clipPath().isEmpty()) + painter.setClipPath(p->clipPath()); + } + + TransparencyLayer() + { + } + + QPixmap pixmap; + QPoint offset; + QPainter painter; + qreal opacity; + // for clipToImageBuffer + QPixmap alphaMask; + // saveCounter is only used in combination with alphaMask + // otherwise, its value is unspecified + int saveCounter; +private: + TransparencyLayer(const TransparencyLayer &) {} + TransparencyLayer & operator=(const TransparencyLayer &) { return *this; } +}; + +} // namespace WebCore + +#endif // TransparencyLayer_h diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp index 7bcd84b..fe7f6ce 100644 --- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp +++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp @@ -53,6 +53,7 @@ #include <math.h> #include <wtf/Assertions.h> #include <wtf/MathExtras.h> +#include <wtf/UnusedParam.h> #if USE(GLES2_RENDERING) #include "GLES2Canvas.h" @@ -455,17 +456,6 @@ void GraphicsContext::clipPath(WindRule clipRule) platformContext()->clipPathAntiAliased(path); } -void GraphicsContext::clipToImageBuffer(const FloatRect& rect, - const ImageBuffer* imageBuffer) -{ - if (paintingDisabled()) - return; - -#if OS(LINUX) || OS(WINDOWS) - platformContext()->beginLayerClippedToImage(rect, imageBuffer); -#endif -} - void GraphicsContext::concatCTM(const AffineTransform& affine) { if (paintingDisabled()) diff --git a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp index eaa91ec..a63eec5 100644 --- a/WebCore/platform/graphics/skia/ImageBufferSkia.cpp +++ b/WebCore/platform/graphics/skia/ImageBufferSkia.cpp @@ -87,20 +87,35 @@ GraphicsContext* ImageBuffer::context() const return m_context.get(); } -Image* ImageBuffer::image() const +bool ImageBuffer::drawsUsingCopy() const { - if (!m_image) { - // This creates a COPY of the image and will cache that copy. This means - // that if subsequent operations take place on the context, neither the - // currently-returned image, nor the results of future image() calls, - // will contain that operation. - // - // This seems silly, but is the way the CG port works: image() is - // intended to be used only when rendering is "complete." - m_image = BitmapImageSingleFrameSkia::create( - *m_data.m_platformContext.bitmap()); - } - return m_image.get(); + return true; +} + +PassRefPtr<Image> ImageBuffer::copyImage() const +{ + return BitmapImageSingleFrameSkia::create(*m_data.m_platformContext.bitmap()); +} + +void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const +{ +#if OS(LINUX) || OS(WINDOWS) + context->platformContext()->beginLayerClippedToImage(rect, this); +#endif +} + +void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, + CompositeOperator op, bool useLowQualityScale) +{ + RefPtr<Image> imageCopy = copyImage(); + context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); +} + +void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + RefPtr<Image> imageCopy = copyImage(); + imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); } void ImageBuffer::platformTransformColorSpace(const Vector<int>& lookUpTable) diff --git a/WebCore/platform/graphics/skia/ImageSkia.cpp b/WebCore/platform/graphics/skia/ImageSkia.cpp index 024bf50..b514b1a 100644 --- a/WebCore/platform/graphics/skia/ImageSkia.cpp +++ b/WebCore/platform/graphics/skia/ImageSkia.cpp @@ -465,18 +465,18 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, if (!bm) return; // It's too early and we don't have an image yet. -#if USE(GLES2_RENDERING) - if (ctxt->platformContext()->useGPU()) { - drawBitmapGLES2(ctxt, bm, srcRect, dstRect, colorSpace, compositeOp); - return; - } -#endif FloatRect normDstRect = normalizeRect(dstRect); FloatRect normSrcRect = normalizeRect(srcRect); if (normSrcRect.isEmpty() || normDstRect.isEmpty()) return; // Nothing to draw. +#if USE(GLES2_RENDERING) + if (ctxt->platformContext()->useGPU()) { + drawBitmapGLES2(ctxt, bm, normSrcRect, normDstRect, colorSpace, compositeOp); + return; + } +#endif ctxt->platformContext()->prepareForSoftwareDraw(); paintSkBitmap(ctxt->platformContext(), diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp index abf04f9..1161224 100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp @@ -39,6 +39,7 @@ #include "NativeImageSkia.h" #include "PlatformContextSkia.h" #include "SkiaUtils.h" +#include "TilingData.h" #include "skia/ext/image_operations.h" #include "skia/ext/platform_canvas.h" @@ -706,6 +707,7 @@ void PlatformContextSkia::setGraphicsContext3D(GraphicsContext3D* context, const { m_useGPU = true; m_gpuCanvas = new GLES2Canvas(context, size); + m_uploadTexture.clear(); #if USE(ACCELERATED_COMPOSITING) CanvasLayerChromium* layer = static_cast<CanvasLayerChromium*>(context->platformLayer()); layer->setPrepareTextureCallback(PrepareTextureCallbackImpl::create(this)); @@ -791,13 +793,13 @@ void PlatformContextSkia::uploadSoftwareToHardware(CompositeOperator op) const { const SkBitmap& bitmap = m_canvas->getDevice()->accessBitmap(false); SkAutoLockPixels lock(bitmap); - // FIXME: Keep a texture around for this rather than constantly creating/destroying one. GraphicsContext3D* context = m_gpuCanvas->context(); - RefPtr<GLES2Texture> texture = GLES2Texture::create(context, GLES2Texture::BGRA8, bitmap.width(), bitmap.height()); - texture->load(bitmap.getPixels()); + if (!m_uploadTexture || m_uploadTexture->tiles().totalSizeX() < bitmap.width() || m_uploadTexture->tiles().totalSizeY() < bitmap.height()) + m_uploadTexture = GLES2Texture::create(context, GLES2Texture::BGRA8, bitmap.width(), bitmap.height()); + m_uploadTexture->load(bitmap.getPixels()); IntRect rect(0, 0, bitmap.width(), bitmap.height()); AffineTransform identity; - gpuCanvas()->drawTexturedRect(texture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op); + gpuCanvas()->drawTexturedRect(m_uploadTexture.get(), rect, rect, identity, 1.0, DeviceColorSpace, op); } void PlatformContextSkia::readbackHardwareToSoftware() const @@ -810,11 +812,15 @@ void PlatformContextSkia::readbackHardwareToSoftware() const // Flips the image vertically. for (int y = 0; y < height; ++y) { uint32_t* pixels = bitmap.getAddr32(0, y); - context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels); - for (int i = 0; i < width; ++i) { - uint32_t pixel = pixels[i]; - // Swizzles from RGBA -> BGRA. - pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); + if (context->supportsBGRA()) + context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::BGRA_EXT, GraphicsContext3D::UNSIGNED_BYTE, pixels); + else { + context->readPixels(0, height - 1 - y, width, 1, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels); + for (int i = 0; i < width; ++i) { + uint32_t pixel = pixels[i]; + // Swizzles from RGBA -> BGRA. + pixels[i] = pixel & 0xFF00FF00 | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16); + } } } } diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h index ff80d1b..6c84797 100644 --- a/WebCore/platform/graphics/skia/PlatformContextSkia.h +++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h @@ -48,6 +48,7 @@ namespace WebCore { #if USE(GLES2_RENDERING) enum CompositeOperator; class GLES2Canvas; +class GLES2Texture; class GraphicsContext3D; #endif @@ -240,6 +241,7 @@ private: bool m_useGPU; OwnPtr<GLES2Canvas> m_gpuCanvas; mutable enum { None, Software, Mixed, Hardware } m_backingStoreState; + mutable RefPtr<GLES2Texture> m_uploadTexture; #endif }; diff --git a/WebCore/platform/graphics/win/FontCacheWin.cpp b/WebCore/platform/graphics/win/FontCacheWin.cpp index d050243..2240f80 100644 --- a/WebCore/platform/graphics/win/FontCacheWin.cpp +++ b/WebCore/platform/graphics/win/FontCacheWin.cpp @@ -31,11 +31,11 @@ #include "FontCache.h" #include "Font.h" #include "SimpleFontData.h" -#include "StringHash.h" #include "UnicodeRange.h" #include <mlang.h> #include <windows.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #if PLATFORM(CG) #include <ApplicationServices/ApplicationServices.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> diff --git a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp index a804432..9234229 100644 --- a/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp +++ b/WebCore/platform/graphics/win/FontPlatformDataCGWin.cpp @@ -25,12 +25,12 @@ #include "FontPlatformData.h" #include "PlatformString.h" -#include "StringHash.h" #include <ApplicationServices/ApplicationServices.h> #include <WebKitSystemInterface/WebKitSystemInterface.h> #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> using std::min; diff --git a/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp index 9b916bd..0f5c365 100644 --- a/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp +++ b/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp @@ -27,10 +27,10 @@ #include "FontPlatformData.h" #include "PlatformString.h" -#include "StringHash.h" #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> #include <cairo-win32.h> diff --git a/WebCore/platform/graphics/win/FontPlatformDataWin.cpp b/WebCore/platform/graphics/win/FontPlatformDataWin.cpp index 99f364c..09ed4a6 100644 --- a/WebCore/platform/graphics/win/FontPlatformDataWin.cpp +++ b/WebCore/platform/graphics/win/FontPlatformDataWin.cpp @@ -26,10 +26,10 @@ #include "FontPlatformData.h" #include "PlatformString.h" -#include "StringHash.h" #include <wtf/HashMap.h> #include <wtf/RetainPtr.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> using std::min; diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp index e0ecf78..9bc68d1 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeVisualContext.cpp @@ -43,7 +43,6 @@ #include "Settings.h" #include "SoftLinking.h" #include "StringBuilder.h" -#include "StringHash.h" #include "TimeRanges.h" #include "Timer.h" #include <AssertMacros.h> @@ -54,6 +53,7 @@ #include <wtf/MainThread.h> #include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayerCACF.h" diff --git a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp index 69aaeaf..34f1135 100644 --- a/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp +++ b/WebCore/platform/graphics/win/MediaPlayerPrivateQuickTimeWin.cpp @@ -39,7 +39,6 @@ #include "ScrollView.h" #include "SoftLinking.h" #include "StringBuilder.h" -#include "StringHash.h" #include "TimeRanges.h" #include "Timer.h" #include <Wininet.h> @@ -47,6 +46,7 @@ #include <wtf/HashSet.h> #include <wtf/MathExtras.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #if USE(ACCELERATED_COMPOSITING) #include "GraphicsLayerCACF.h" diff --git a/WebCore/platform/graphics/win/WKCACFLayer.h b/WebCore/platform/graphics/win/WKCACFLayer.h index ed39297..abc04c8 100644 --- a/WebCore/platform/graphics/win/WKCACFLayer.h +++ b/WebCore/platform/graphics/win/WKCACFLayer.h @@ -28,8 +28,6 @@ #if USE(ACCELERATED_COMPOSITING) -#include "StringHash.h" - #include <wtf/RefCounted.h> #include <QuartzCore/CACFLayer.h> @@ -37,6 +35,7 @@ #include <wtf/PassRefPtr.h> #include <wtf/RetainPtr.h> #include <wtf/Vector.h> +#include <wtf/text/StringHash.h> #include "GraphicsContext.h" #include "PlatformString.h" diff --git a/WebCore/platform/graphics/wince/FontPlatformData.cpp b/WebCore/platform/graphics/wince/FontPlatformData.cpp index 74cadc2..d84a7cc 100644 --- a/WebCore/platform/graphics/wince/FontPlatformData.cpp +++ b/WebCore/platform/graphics/wince/FontPlatformData.cpp @@ -26,10 +26,10 @@ #include "FontData.h" #include "PlatformString.h" #include "SimpleFontData.h" -#include "StringHash.h" #include "UnicodeRange.h" #include "wtf/OwnPtr.h" #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #include <windows.h> #include <mlang.h> diff --git a/WebCore/platform/graphics/wince/PathWince.cpp b/WebCore/platform/graphics/wince/PathWince.cpp index 747e650..6aa2864 100644 --- a/WebCore/platform/graphics/wince/PathWince.cpp +++ b/WebCore/platform/graphics/wince/PathWince.cpp @@ -160,11 +160,9 @@ bool Path::hasCurrentPoint() const return !isEmpty(); } -FloatPoint Path::currentPoint() const +FloatPoint Path::currentPoint() const { - // FIXME: return current point of subpath. - float quietNaN = std::numeric_limits<float>::quiet_NaN(); - return FloatPoint(quietNaN, quietNaN); + return m_path->lastPoint(); } -} +} // namespace WebCore diff --git a/WebCore/platform/graphics/wx/FontPlatformData.h b/WebCore/platform/graphics/wx/FontPlatformData.h index 4f8d740..b328545 100644 --- a/WebCore/platform/graphics/wx/FontPlatformData.h +++ b/WebCore/platform/graphics/wx/FontPlatformData.h @@ -30,10 +30,10 @@ #define FontPlatformData_h #include "FontDescription.h" -#include "AtomicString.h" #include "StringImpl.h" #include <wtf/Forward.h> #include <wtf/RefPtr.h> +#include <wtf/text/AtomicString.h> #include <wtf/text/CString.h> #include <wx/defs.h> diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp index 4d5afd7..2428e7e 100644 --- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp +++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp @@ -378,11 +378,6 @@ void GraphicsContext::canvasClip(const Path& path) clip(path); } -void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*) -{ - notImplemented(); -} - AffineTransform GraphicsContext::getCTM() const { #if USE(WXGC) diff --git a/WebCore/platform/graphics/wx/ImageBufferWx.cpp b/WebCore/platform/graphics/wx/ImageBufferWx.cpp index 775e018..2522cbd 100644 --- a/WebCore/platform/graphics/wx/ImageBufferWx.cpp +++ b/WebCore/platform/graphics/wx/ImageBufferWx.cpp @@ -82,12 +82,36 @@ String ImageBuffer::toDataURL(const String&, const double*) const return String(); } -Image* ImageBuffer::image() const +bool ImageBuffer::drawsUsingCopy() const +{ + return true; +} + +PassRefPtr<Image> ImageBuffer::copyImage() const { notImplemented(); return 0; } +void ImageBuffer::clip(GraphicsContext*, const FloatRect&) const +{ + notImplemented(); +} + +void ImageBuffer::draw(GraphicsContext* context, ColorSpace styleColorSpace, const FloatRect& destRect, const FloatRect& srcRect, + CompositeOperator op, bool useLowQualityScale) +{ + RefPtr<Image> imageCopy = copyImage(); + context->drawImage(imageCopy.get(), styleColorSpace, destRect, srcRect, op, useLowQualityScale); +} + +void ImageBuffer::drawPattern(GraphicsContext* context, const FloatRect& srcRect, const AffineTransform& patternTransform, + const FloatPoint& phase, ColorSpace styleColorSpace, CompositeOperator op, const FloatRect& destRect) +{ + RefPtr<Image> imageCopy = copyImage(); + imageCopy->drawPattern(context, srcRect, patternTransform, phase, styleColorSpace, op, destRect); +} + void ImageBuffer::platformTransformColorSpace(const Vector<int>&) { notImplemented(); diff --git a/WebCore/platform/gtk/ClipboardGtk.cpp b/WebCore/platform/gtk/ClipboardGtk.cpp index 7003cf0..21ebe4c 100644 --- a/WebCore/platform/gtk/ClipboardGtk.cpp +++ b/WebCore/platform/gtk/ClipboardGtk.cpp @@ -30,9 +30,9 @@ #include "PasteboardHelper.h" #include "RenderImage.h" #include "ScriptExecutionContext.h" -#include "StringHash.h" #include "markup.h" #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> #include <gtk/gtk.h> namespace WebCore { diff --git a/WebCore/platform/gtk/DataObjectGtk.h b/WebCore/platform/gtk/DataObjectGtk.h index 8fba938..a7d8baf 100644 --- a/WebCore/platform/gtk/DataObjectGtk.h +++ b/WebCore/platform/gtk/DataObjectGtk.h @@ -23,9 +23,9 @@ #include <GRefPtr.h> #include "KURL.h" #include "Range.h" -#include "StringHash.h" #include <wtf/RefCounted.h> #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> typedef struct _GdkPixbuf GdkPixbuf; typedef struct _GdkDragContext GdkDragContext; diff --git a/WebCore/platform/gtk/GOwnPtrGtk.cpp b/WebCore/platform/gtk/GOwnPtrGtk.cpp index 0558f33..9b693f4 100644 --- a/WebCore/platform/gtk/GOwnPtrGtk.cpp +++ b/WebCore/platform/gtk/GOwnPtrGtk.cpp @@ -19,8 +19,7 @@ #include "config.h" #include "GOwnPtrGtk.h" -#include <gdk/gdk.h> -#include <glib.h> +#include <gtk/gtk.h> namespace WTF { @@ -30,4 +29,10 @@ template <> void freeOwnedGPtr<GdkEvent>(GdkEvent* ptr) gdk_event_free(ptr); } +template <> void freeOwnedGPtr<GtkIconInfo>(GtkIconInfo* info) +{ + if (info) + gtk_icon_info_free(info); +} + } diff --git a/WebCore/platform/gtk/GOwnPtrGtk.h b/WebCore/platform/gtk/GOwnPtrGtk.h index 674ea58..8341661 100644 --- a/WebCore/platform/gtk/GOwnPtrGtk.h +++ b/WebCore/platform/gtk/GOwnPtrGtk.h @@ -23,10 +23,12 @@ #include "GOwnPtr.h" typedef union _GdkEvent GdkEvent; +typedef struct _GtkIconInfo GtkIconInfo; namespace WTF { -template<> void freeOwnedGPtr<GdkEvent>(GdkEvent*); +template <> void freeOwnedGPtr<GdkEvent>(GdkEvent*); +template <> void freeOwnedGPtr<GtkIconInfo>(GtkIconInfo*); } diff --git a/WebCore/platform/gtk/GtkVersioning.cpp b/WebCore/platform/gtk/GtkVersioning.cpp new file mode 100644 index 0000000..e7734a8 --- /dev/null +++ b/WebCore/platform/gtk/GtkVersioning.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Collabora Ltd. + * + * 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 "GtkVersioning.h" + +#include <gtk/gtk.h> + +#if !GTK_CHECK_VERSION(2, 14, 0) +void gtk_adjustment_set_value(GtkAdjustment* adjusment, gdouble value) +{ + m_adjustment->value = m_currentPos; + gtk_adjustment_value_changed(m_adjustment); +} + +void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble lower, gdouble upper, + gdouble stepIncrement, gdouble pageIncrement, gdouble pageSize) +{ + g_object_freeze_notify(G_OBJECT(adjustment)); + + g_object_set(adjustment, + "lower", lower, + "upper", upper, + "step-increment", stepIncrement, + "page-increment", pageIncrement, + "page-size", pageSize, + NULL); + + g_object_thaw_notify(G_OBJECT(adjustment)); + + gtk_adjustment_changed(adjustment); + gtk_adjustment_value_changed(adjustment); +} +#endif diff --git a/WebCore/platform/gtk/GtkVersioning.h b/WebCore/platform/gtk/GtkVersioning.h index ebb1645..6b45228 100644 --- a/WebCore/platform/gtk/GtkVersioning.h +++ b/WebCore/platform/gtk/GtkVersioning.h @@ -58,6 +58,11 @@ #define gtk_selection_data_get_data(data) (data)->data #define gtk_selection_data_get_target(data) (data)->target #define gtk_adjustment_set_page_size(adj, value) (adj)->page_size = value + +void gtk_adjustment_configure(GtkAdjustment* adjustment, gdouble value, gdouble lower, gdouble upper, + gdouble stepIncrement, gdouble pageIncrement, gdouble pageSize); + +void gtk_adjustment_set_value(GtkAdjustment* adjusment, gdouble value); #endif // GTK_CHECK_VERSION(2, 14, 0) #endif // GtkVersioning_h diff --git a/WebCore/platform/gtk/RenderThemeGtk.cpp b/WebCore/platform/gtk/RenderThemeGtk.cpp index bc0d147..36fccf0 100644 --- a/WebCore/platform/gtk/RenderThemeGtk.cpp +++ b/WebCore/platform/gtk/RenderThemeGtk.cpp @@ -485,7 +485,7 @@ void RenderThemeGtk::adjustSearchFieldResultsButtonStyle(CSSStyleSelector* selec bool RenderThemeGtk::paintSearchFieldResultsButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_DROPDOWN_ARROW, o, i, rect); + return paintSearchFieldResultsDecoration(o, i, rect); } void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const @@ -501,7 +501,12 @@ void RenderThemeGtk::adjustSearchFieldResultsDecorationStyle(CSSStyleSelector* s bool RenderThemeGtk::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect); + GraphicsContext* context = i.context; + + static Image* searchImage = Image::loadPlatformThemeIcon(GTK_STOCK_FIND, rect.width()).releaseRef(); + context->drawImage(searchImage, DeviceColorSpace, rect); + + return false; } void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const @@ -517,7 +522,13 @@ void RenderThemeGtk::adjustSearchFieldCancelButtonStyle(CSSStyleSelector* select bool RenderThemeGtk::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& i, const IntRect& rect) { - return paintMozillaGtkWidget(this, MOZ_GTK_CHECKMENUITEM, o, i, rect); + GraphicsContext* context = i.context; + + // TODO: Brightening up the image on hover is desirable here, I believe. + static Image* cancelImage = Image::loadPlatformThemeIcon(GTK_STOCK_CLEAR, rect.width()).releaseRef(); + context->drawImage(cancelImage, DeviceColorSpace, rect); + + return false; } void RenderThemeGtk::adjustSearchFieldStyle(CSSStyleSelector* selector, RenderStyle* style, Element* e) const diff --git a/WebCore/platform/gtk/ScrollViewGtk.cpp b/WebCore/platform/gtk/ScrollViewGtk.cpp index e705fe0..871a0bf 100644 --- a/WebCore/platform/gtk/ScrollViewGtk.cpp +++ b/WebCore/platform/gtk/ScrollViewGtk.cpp @@ -36,6 +36,7 @@ #include "Frame.h" #include "FrameView.h" #include "GraphicsContext.h" +#include "GtkVersioning.h" #include "HostWindow.h" #include "IntRect.h" #include "Page.h" @@ -72,29 +73,6 @@ PassRefPtr<Scrollbar> ScrollView::createScrollbar(ScrollbarOrientation orientati return Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar); } -#if !GTK_CHECK_VERSION(2, 14, 0) -#define gtk_adjustment_configure AdjustmentConfigure - -static void AdjustmentConfigure(GtkAdjustment* adjustment, gdouble value, gdouble lower, gdouble upper, - gdouble stepIncrement, gdouble pageIncrement, gdouble pageSize) -{ - g_object_freeze_notify(G_OBJECT(adjustment)); - - g_object_set(adjustment, - "lower", lower, - "upper", upper, - "step-increment", stepIncrement, - "page-increment", pageIncrement, - "page-size", pageSize, - NULL); - - g_object_thaw_notify(G_OBJECT(adjustment)); - - gtk_adjustment_changed(adjustment); - gtk_adjustment_value_changed(adjustment); -} -#endif - /* * The following is assumed: * (hadj && vadj) || (!hadj && !vadj) diff --git a/WebCore/platform/gtk/ScrollbarGtk.cpp b/WebCore/platform/gtk/ScrollbarGtk.cpp index 8081fb8..3b86ec9 100644 --- a/WebCore/platform/gtk/ScrollbarGtk.cpp +++ b/WebCore/platform/gtk/ScrollbarGtk.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2007, 2009 Holger Hans Peter Freyther zecke@selfish.org * Copyright (C) 2010 Gustavo Noronha Silva <gns@gnome.org> + * Copyright (C) 2010 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,10 +21,10 @@ #include "config.h" #include "ScrollbarGtk.h" +#include "FrameView.h" +#include "GraphicsContext.h" #include "GtkVersioning.h" #include "IntRect.h" -#include "GraphicsContext.h" -#include "FrameView.h" #include "ScrollbarTheme.h" #include <gtk/gtk.h> @@ -120,15 +121,8 @@ void ScrollbarGtk::detachAdjustment() // For the case where we only operate on the GtkAdjustment it is best to // reset the values so that the surrounding scrollbar gets updated, or // e.g. for a GtkScrolledWindow the scrollbar gets hidden. -#if GTK_CHECK_VERSION(2, 14, 0) gtk_adjustment_configure(m_adjustment, 0, 0, 0, 0, 0, 0); -#else - m_adjustment->lower = 0; - m_adjustment->upper = 0; - m_adjustment->value = 0; - gtk_adjustment_changed(m_adjustment); - gtk_adjustment_value_changed(m_adjustment); -#endif + g_object_unref(m_adjustment); m_adjustment = 0; } @@ -162,19 +156,12 @@ void ScrollbarGtk::frameRectsChanged() void ScrollbarGtk::updateThumbPosition() { - if (gtk_adjustment_get_value(m_adjustment) != m_currentPos) { -#if GTK_CHECK_VERSION(2, 14, 0) + if (gtk_adjustment_get_value(m_adjustment) != m_currentPos) gtk_adjustment_set_value(m_adjustment, m_currentPos); -#else - m_adjustment->value = m_currentPos; - gtk_adjustment_value_changed(m_adjustment); -#endif - } } void ScrollbarGtk::updateThumbProportion() { -#if GTK_CHECK_VERSION(2, 14, 0) gtk_adjustment_configure(m_adjustment, gtk_adjustment_get_value(m_adjustment), gtk_adjustment_get_lower(m_adjustment), @@ -182,13 +169,6 @@ void ScrollbarGtk::updateThumbProportion() m_lineStep, m_pageStep, m_visibleSize); -#else - m_adjustment->step_increment = m_lineStep; - m_adjustment->page_increment = m_pageStep; - m_adjustment->page_size = m_visibleSize; - m_adjustment->upper = m_totalSize; - gtk_adjustment_changed(m_adjustment); -#endif } void ScrollbarGtk::setFrameRect(const IntRect& rect) diff --git a/WebCore/platform/gtk/SharedTimerGtk.cpp b/WebCore/platform/gtk/SharedTimerGtk.cpp index 092df95..ee4d75b 100644 --- a/WebCore/platform/gtk/SharedTimerGtk.cpp +++ b/WebCore/platform/gtk/SharedTimerGtk.cpp @@ -30,6 +30,7 @@ #include <wtf/Assertions.h> #include <wtf/CurrentTime.h> +#include <gdk/gdk.h> #include <glib.h> namespace WebCore { @@ -63,7 +64,7 @@ void setSharedTimerFireTime(double fireTime) } stopSharedTimer(); - sharedTimer = g_timeout_add(intervalInMS, timeout_cb, NULL); + sharedTimer = g_timeout_add_full(GDK_PRIORITY_REDRAW, intervalInMS, timeout_cb, 0, 0); } void stopSharedTimer() diff --git a/WebCore/platform/haiku/ClipboardHaiku.cpp b/WebCore/platform/haiku/ClipboardHaiku.cpp index 9931131..da242c1 100644 --- a/WebCore/platform/haiku/ClipboardHaiku.cpp +++ b/WebCore/platform/haiku/ClipboardHaiku.cpp @@ -31,13 +31,13 @@ #include "IntPoint.h" #include "NotImplemented.h" #include "PlatformString.h" -#include "StringHash.h" #include <support/Locker.h> #include <app/Clipboard.h> #include <Message.h> #include <String.h> #include <wtf/HashTable.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/haiku/CookieJarHaiku.cpp b/WebCore/platform/haiku/CookieJarHaiku.cpp index f619f00..471ac59 100644 --- a/WebCore/platform/haiku/CookieJarHaiku.cpp +++ b/WebCore/platform/haiku/CookieJarHaiku.cpp @@ -32,9 +32,8 @@ #include "Cookie.h" #include "KURL.h" #include "PlatformString.h" -#include "StringHash.h" - #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/haiku/SearchPopupMenuHaiku.cpp b/WebCore/platform/haiku/SearchPopupMenuHaiku.cpp index 109409a..ea73c61 100644 --- a/WebCore/platform/haiku/SearchPopupMenuHaiku.cpp +++ b/WebCore/platform/haiku/SearchPopupMenuHaiku.cpp @@ -21,8 +21,8 @@ #include "config.h" #include "SearchPopupMenuHaiku.h" -#include "AtomicString.h" #include "NotImplemented.h" +#include <wtf/text/AtomicString.h> namespace WebCore { diff --git a/WebCore/platform/mac/DragImageMac.mm b/WebCore/platform/mac/DragImageMac.mm index 7b51018..f444b6e 100644 --- a/WebCore/platform/mac/DragImageMac.mm +++ b/WebCore/platform/mac/DragImageMac.mm @@ -87,9 +87,9 @@ RetainPtr<NSImage> createDragImageIconForCachedImage(CachedImage* image) { const String& filename = image->response().suggestedFilename(); NSString *extension = nil; - int dotIndex = filename.reverseFind('.'); + size_t dotIndex = filename.reverseFind('.'); - if (dotIndex > 0 && dotIndex < (int)(filename.length() - 1)) // require that a . exists after the first character and before the last + if (dotIndex != notFound && dotIndex < (filename.length() - 1)) // require that a . exists after the first character and before the last extension = filename.substring(dotIndex + 1); else { // It might be worth doing a further lookup to pull the extension from the MIME type. diff --git a/WebCore/platform/mac/ScrollbarThemeMac.mm b/WebCore/platform/mac/ScrollbarThemeMac.mm index 067f28f..bfa584a 100644 --- a/WebCore/platform/mac/ScrollbarThemeMac.mm +++ b/WebCore/platform/mac/ScrollbarThemeMac.mm @@ -396,7 +396,7 @@ bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, co return true; HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal); - context->drawImage(imageBuffer->image(), DeviceColorSpace, scrollbar->frameRect().location()); + context->drawImageBuffer(imageBuffer.get(), DeviceColorSpace, scrollbar->frameRect().location()); } return true; diff --git a/WebCore/platform/mac/SearchPopupMenuMac.mm b/WebCore/platform/mac/SearchPopupMenuMac.mm index 69018ee..47d6e57 100644 --- a/WebCore/platform/mac/SearchPopupMenuMac.mm +++ b/WebCore/platform/mac/SearchPopupMenuMac.mm @@ -21,7 +21,7 @@ #import "config.h" #import "SearchPopupMenuMac.h" -#import "AtomicString.h" +#include <wtf/text/AtomicString.h> namespace WebCore { diff --git a/WebCore/platform/mac/ThreadCheck.mm b/WebCore/platform/mac/ThreadCheck.mm index ddee05c..4792191 100644 --- a/WebCore/platform/mac/ThreadCheck.mm +++ b/WebCore/platform/mac/ThreadCheck.mm @@ -26,9 +26,9 @@ #import "config.h" #import "ThreadCheck.h" -#import "StringHash.h" #import <wtf/HashSet.h> #import <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/mock/SpeechInputClientMock.cpp b/WebCore/platform/mock/SpeechInputClientMock.cpp index 74a3151..c3d74d1 100644 --- a/WebCore/platform/mock/SpeechInputClientMock.cpp +++ b/WebCore/platform/mock/SpeechInputClientMock.cpp @@ -41,34 +41,42 @@ SpeechInputClientMock::SpeechInputClientMock() : m_recording(false) , m_timer(this, &SpeechInputClientMock::timerFired) , m_listener(0) + , m_requestId(0) { } -bool SpeechInputClientMock::startRecognition(SpeechInputListener* listener) +void SpeechInputClientMock::setListener(SpeechInputListener* listener) +{ + m_listener = listener; +} + +bool SpeechInputClientMock::startRecognition(int requestId) { if (m_timer.isActive()) return false; - m_listener = listener; + m_requestId = requestId; m_recording = true; m_timer.startOneShot(0); return true; } -void SpeechInputClientMock::stopRecording() +void SpeechInputClientMock::stopRecording(int requestId) { + ASSERT(requestId == m_requestId); if (m_timer.isActive() && m_recording) { m_timer.stop(); timerFired(&m_timer); } } -void SpeechInputClientMock::cancelRecognition() +void SpeechInputClientMock::cancelRecognition(int requestId) { + ASSERT(requestId == m_requestId); if (m_timer.isActive()) { m_timer.stop(); m_recording = false; - m_listener->didCompleteRecognition(); - m_listener = 0; + m_listener->didCompleteRecognition(m_requestId); + m_requestId = 0; } } @@ -81,12 +89,12 @@ void SpeechInputClientMock::timerFired(WebCore::Timer<SpeechInputClientMock>*) { if (m_recording) { m_recording = false; - m_listener->didCompleteRecording(); + m_listener->didCompleteRecording(m_requestId); m_timer.startOneShot(0); } else { - m_listener->setRecognitionResult(m_recognitionResult); - m_listener->didCompleteRecognition(); - m_listener = 0; + m_listener->setRecognitionResult(m_requestId, m_recognitionResult); + m_listener->didCompleteRecognition(m_requestId); + m_requestId = 0; } } diff --git a/WebCore/platform/mock/SpeechInputClientMock.h b/WebCore/platform/mock/SpeechInputClientMock.h index faca444..7d5fda2 100644 --- a/WebCore/platform/mock/SpeechInputClientMock.h +++ b/WebCore/platform/mock/SpeechInputClientMock.h @@ -49,9 +49,10 @@ public: void setRecognitionResult(const String& result); // SpeechInputClient methods. - bool startRecognition(SpeechInputListener*); - void stopRecording(); - void cancelRecognition(); + void setListener(SpeechInputListener*); + bool startRecognition(int); + void stopRecording(int); + void cancelRecognition(int); private: void timerFired(Timer<SpeechInputClientMock>*); @@ -59,6 +60,7 @@ private: bool m_recording; Timer<SpeechInputClientMock> m_timer; SpeechInputListener* m_listener; + int m_requestId; String m_recognitionResult; }; diff --git a/WebCore/platform/network/BlobData.cpp b/WebCore/platform/network/BlobData.cpp new file mode 100644 index 0000000..bb256d0 --- /dev/null +++ b/WebCore/platform/network/BlobData.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "BlobData.h" + +namespace WebCore { + +const long long BlobDataItem::toEndOfFile = -1; +const double BlobDataItem::doNotCheckFileChange = 0; + +void BlobDataItem::copy(const BlobDataItem& item) +{ + type = item.type; + data = item.data; // This is OK because the underlying storage is Vector<char>. + path = item.path.crossThreadString(); + url = item.url.copy(); + offset = item.offset; + length = item.length; + expectedModificationTime = item.expectedModificationTime; +} + +PassOwnPtr<BlobData> BlobData::copy() const +{ + OwnPtr<BlobData> blobData = adoptPtr(new BlobData()); + blobData->m_contentType = m_contentType.crossThreadString(); + blobData->m_contentDisposition = m_contentDisposition.crossThreadString(); + blobData->m_items.resize(m_items.size()); + for (size_t i = 0; i < m_items.size(); ++i) + blobData->m_items.at(i).copy(m_items.at(i)); + + return blobData.release(); +} + +void BlobData::appendData(const CString& data) +{ + m_items.append(BlobDataItem(data)); +} + +void BlobData::appendFile(const String& path) +{ + m_items.append(BlobDataItem(path)); +} + +void BlobData::appendFile(const String& path, long long offset, long long length, double expectedModificationTime) +{ + m_items.append(BlobDataItem(path, offset, length, expectedModificationTime)); +} + +void BlobData::appendBlob(const KURL& url, long long offset, long long length) +{ + m_items.append(BlobDataItem(url, offset, length)); +} + +void BlobData::swapItems(BlobDataItemList& items) +{ + m_items.swap(items); +} + +} // namespace WebCore diff --git a/WebCore/platform/network/BlobData.h b/WebCore/platform/network/BlobData.h new file mode 100644 index 0000000..17cdfdd --- /dev/null +++ b/WebCore/platform/network/BlobData.h @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BlobData_h +#define BlobData_h + +#include "KURL.h" +#include "PlatformString.h" +#include <wtf/PassOwnPtr.h> +#include <wtf/Vector.h> +#include <wtf/text/CString.h> + +namespace WebCore { + +struct BlobDataItem { + static const long long toEndOfFile; + static const double doNotCheckFileChange; + + // Default constructor. + BlobDataItem() + : offset(0) + , length(toEndOfFile) + , expectedModificationTime(doNotCheckFileChange) + { + } + + // Constructor for String type. + BlobDataItem(const CString& data) + : type(Data) + , data(data) + , offset(0) + , length(toEndOfFile) + , expectedModificationTime(doNotCheckFileChange) + { + } + + // Constructor for File type (complete file). + BlobDataItem(const String& path) + : type(File) + , path(path) + , offset(0) + , length(toEndOfFile) + , expectedModificationTime(doNotCheckFileChange) + { + } + + // Constructor for File type (partial file). + BlobDataItem(const String& path, long long offset, long long length, double expectedModificationTime) + : type(File) + , path(path) + , offset(offset) + , length(length) + , expectedModificationTime(expectedModificationTime) + { + } + + // Constructor for Blob type. + BlobDataItem(const KURL& url, long long offset, long long length) + : type(Blob) + , url(url) + , offset(offset) + , length(length) + , expectedModificationTime(doNotCheckFileChange) + { + } + + // Gets a copy of the data suitable for passing to another thread. + void copy(const BlobDataItem&); + + enum { Data, File, Blob } type; + + // For Data type. + CString data; + + // For File type. + String path; + + // For Blob type. + KURL url; + + // For File and Blob type. + long long offset; + long long length; + + // For File type only. + double expectedModificationTime; +}; + +typedef Vector<BlobDataItem> BlobDataItemList; + +class BlobData { +public: + static PassOwnPtr<BlobData> create() + { + return adoptPtr(new BlobData()); + } + + // Gets a copy of the data suitable for passing to another thread. + PassOwnPtr<BlobData> copy() const; + + const String& contentType() const { return m_contentType; } + void setContentType(const String& contentType) { m_contentType = contentType; } + + const String& contentDisposition() const { return m_contentDisposition; } + void setContentDisposition(const String& contentDisposition) { m_contentDisposition = contentDisposition; } + + const BlobDataItemList& items() const { return m_items; } + void swapItems(BlobDataItemList&); + + void appendData(const CString&); + void appendFile(const String& path); + void appendFile(const String& path, long long offset, long long length, double expectedModificationTime); + void appendBlob(const KURL&, long long offset, long long length); + +private: + BlobData() { } + + String m_contentType; + String m_contentDisposition; + BlobDataItemList m_items; +}; + +} // namespace WebCore + +#endif // BlobData_h diff --git a/WebCore/platform/network/BlobRegistry.h b/WebCore/platform/network/BlobRegistry.h new file mode 100644 index 0000000..fcd7b1c --- /dev/null +++ b/WebCore/platform/network/BlobRegistry.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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 BlobRegistry_h +#define BlobRegistry_h + +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> + +namespace WebCore { + +class BlobData; +class KURL; +class ResourceError; +class ResourceHandle; +class ResourceHandleClient; +class ResourceRequest; +class ResourceResponse; + +// BlobRegistry is not thread-safe. It should only be called from main thread. +class BlobRegistry { +public: + static BlobRegistry& instance(); + + virtual void registerBlobURL(const KURL&, PassOwnPtr<BlobData>) = 0; + virtual void registerBlobURL(const KURL&, const KURL& srcURL) = 0; + virtual void unregisterBlobURL(const KURL&) = 0; + virtual PassRefPtr<ResourceHandle> createResourceHandle(const ResourceRequest&, ResourceHandleClient*) = 0; + virtual bool loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data) = 0; + + virtual ~BlobRegistry() { } +}; + +} // namespace WebCore + +#endif // BlobRegistry_h diff --git a/WebCore/platform/network/BlobRegistryImpl.cpp b/WebCore/platform/network/BlobRegistryImpl.cpp new file mode 100644 index 0000000..bbbb8f0 --- /dev/null +++ b/WebCore/platform/network/BlobRegistryImpl.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "BlobRegistryImpl.h" + +#include "FileStream.h" +#include "FileStreamProxy.h" +#include "FileSystem.h" +#include "ResourceError.h" +#include "ResourceHandle.h" +#include "ResourceLoader.h" +#include "ResourceRequest.h" +#include "ResourceResponse.h" +#include <wtf/MainThread.h> +#include <wtf/StdLibExtras.h> + +namespace WebCore { + +bool BlobRegistryImpl::shouldLoadResource(const ResourceRequest& request) const +{ + // If the resource is not fetched using the GET method, bail out. + if (!equalIgnoringCase(request.httpMethod(), "GET")) + return false; + + return true; +} + +PassRefPtr<ResourceHandle> BlobRegistryImpl::createResourceHandle(const ResourceRequest& request, ResourceHandleClient*) +{ + if (!shouldLoadResource(request)) + return 0; + + // FIXME: To be implemented. + return 0; +} + +bool BlobRegistryImpl::loadResourceSynchronously(const ResourceRequest& request, ResourceError&, ResourceResponse&, Vector<char>&) +{ + if (!shouldLoadResource(request)) + return false; + + // FIXME: To be implemented. + return false; +} + +BlobRegistry& BlobRegistry::instance() +{ + ASSERT(isMainThread()); + DEFINE_STATIC_LOCAL(BlobRegistryImpl, instance, ()); + return instance; +} + +void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobStorageDataItemList& items) +{ + for (BlobStorageDataItemList::const_iterator iter = items.begin(); iter != items.end(); ++iter) { + if (iter->type == BlobStorageDataItem::Data) + blobStorageData->appendData(iter->data, iter->offset, iter->length); + else { + ASSERT(iter->type == BlobStorageDataItem::File); + blobStorageData->appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime); + } + } +} + +void BlobRegistryImpl::appendStorageItems(BlobStorageData* blobStorageData, const BlobStorageDataItemList& items, long long offset, long long length) +{ + ASSERT(length != BlobDataItem::toEndOfFile); + + BlobStorageDataItemList::const_iterator iter = items.begin(); + if (offset) { + for (; iter != items.end(); ++iter) { + if (offset >= iter->length) + offset -= iter->length; + else + break; + } + } + + for (; iter != items.end() && length > 0; ++iter) { + long long currentLength = iter->length - offset; + long long newLength = currentLength > length ? length : currentLength; + if (iter->type == BlobStorageDataItem::Data) + blobStorageData->appendData(iter->data, iter->offset + offset, newLength); + else { + ASSERT(iter->type == BlobStorageDataItem::File); + blobStorageData->appendFile(iter->path, iter->offset + offset, newLength, iter->expectedModificationTime); + } + offset = 0; + } +} + +void BlobRegistryImpl::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blobData) +{ + ASSERT(isMainThread()); + + RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create(); + blobStorageData->setContentType(blobData->contentType()); + blobStorageData->setContentDisposition(blobData->contentDisposition()); + + for (BlobDataItemList::const_iterator iter = blobData->items().begin(); iter != blobData->items().end(); ++iter) { + switch (iter->type) { + case BlobDataItem::Data: + blobStorageData->appendData(iter->data, 0, iter->data.length()); + break; + case BlobDataItem::File: + blobStorageData->appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime); + break; + case BlobDataItem::Blob: + if (m_blobs.contains(iter->url.string())) + appendStorageItems(blobStorageData.get(), m_blobs.get(iter->url.string())->items(), iter->offset, iter->length); + break; + } + } + + + m_blobs.set(url.string(), blobStorageData); +} + +void BlobRegistryImpl::registerBlobURL(const KURL& url, const KURL& srcURL) +{ + ASSERT(isMainThread()); + + RefPtr<BlobStorageData> src = m_blobs.get(srcURL.string()); + ASSERT(src); + if (!src) + return; + + RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create(); + blobStorageData->setContentType(src->contentType()); + blobStorageData->setContentDisposition(src->contentDisposition()); + appendStorageItems(blobStorageData.get(), src->items()); + + m_blobs.set(url.string(), blobStorageData); +} + +void BlobRegistryImpl::unregisterBlobURL(const KURL& url) +{ + ASSERT(isMainThread()); + m_blobs.remove(url.string()); +} + +PassRefPtr<BlobStorageData> BlobRegistryImpl::getBlobDataFromURL(const KURL& url) const +{ + ASSERT(isMainThread()); + return m_blobs.get(url.string()); +} + +} // namespace WebCore diff --git a/WebCore/platform/network/BlobRegistryImpl.h b/WebCore/platform/network/BlobRegistryImpl.h new file mode 100644 index 0000000..42693bc --- /dev/null +++ b/WebCore/platform/network/BlobRegistryImpl.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BlobRegistryImpl_h +#define BlobRegistryImpl_h + +#include "BlobData.h" +#include "BlobRegistry.h" +#include "BlobStorageData.h" +#include "PlatformString.h" +#include <wtf/HashMap.h> +#include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> + +namespace WebCore { + +class KURL; +class ResourceError; +class ResourceHandle; +class ResourceHandleClient; +class ResourceRequest; +class ResourceResponse; + +// BlobRegistryImpl is not thread-safe. It should only be called from main thread. +class BlobRegistryImpl : public BlobRegistry { +public: + virtual ~BlobRegistryImpl() { } + + virtual void registerBlobURL(const KURL&, PassOwnPtr<BlobData>); + virtual void registerBlobURL(const KURL&, const KURL& srcURL); + virtual void unregisterBlobURL(const KURL&); + virtual PassRefPtr<ResourceHandle> createResourceHandle(const ResourceRequest&, ResourceHandleClient*); + virtual bool loadResourceSynchronously(const ResourceRequest&, ResourceError&, ResourceResponse&, Vector<char>& data); + + PassRefPtr<BlobStorageData> getBlobDataFromURL(const KURL&) const; + +private: + bool shouldLoadResource(const ResourceRequest& request) const; + void appendStorageItems(BlobStorageData*, const BlobStorageDataItemList&); + void appendStorageItems(BlobStorageData*, const BlobStorageDataItemList&, long long offset, long long length); + + HashMap<String, RefPtr<BlobStorageData> > m_blobs; +}; + +} // namespace WebCore + +#endif // BlobRegistryImpl_h diff --git a/WebCore/platform/network/BlobStorageData.h b/WebCore/platform/network/BlobStorageData.h new file mode 100644 index 0000000..f4125a4 --- /dev/null +++ b/WebCore/platform/network/BlobStorageData.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * 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 BlobStorageData_h +#define BlobStorageData_h + +#include "PlatformString.h" +#include <wtf/PassRefPtr.h> +#include <wtf/Vector.h> +#include <wtf/text/CString.h> + +namespace WebCore { + +struct BlobStorageDataItem { + enum BlobStoreDataItemType { Data, File }; + BlobStoreDataItemType type; + long long offset; + long long length; + + // For string data. + CString data; + + // For file data. + String path; + double expectedModificationTime; + + BlobStorageDataItem(const CString& data, long long offset, long long length) + : type(Data) + , offset(offset) + , length(length) + , data(data) + , expectedModificationTime(0) + { + } + + BlobStorageDataItem(const String& path, long long offset, long long length, double expectedModificationTime) + : type(File) + , offset(offset) + , length(length) + , path(path) + , expectedModificationTime(expectedModificationTime) + { + } +}; + +typedef Vector<BlobStorageDataItem> BlobStorageDataItemList; + +class BlobStorageData : public RefCounted<BlobStorageData> { +public: + static PassRefPtr<BlobStorageData> create() + { + return adoptRef(new BlobStorageData()); + } + + const String& contentType() const { return m_contentType; } + void setContentType(const String& contentType) { m_contentType = contentType; } + + const String& contentDisposition() const { return m_contentDisposition; } + void setContentDisposition(const String& contentDisposition) { m_contentDisposition = contentDisposition; } + + const BlobStorageDataItemList& items() const { return m_items; } + + void appendData(const CString& data, long long offset, long long length) + { + m_items.append(BlobStorageDataItem(data, offset, length)); + } + + void appendFile(const String& path, long long offset, long long length, double expectedModificationTime) + { + m_items.append(BlobStorageDataItem(path, offset, length, expectedModificationTime)); + } + +private: + String m_contentType; + String m_contentDisposition; + BlobStorageDataItemList m_items; +}; + +} // namespace WebCore + +#endif // BlobStorageData_h diff --git a/WebCore/platform/network/CredentialStorage.cpp b/WebCore/platform/network/CredentialStorage.cpp index 14f4086..4fb7799 100644 --- a/WebCore/platform/network/CredentialStorage.cpp +++ b/WebCore/platform/network/CredentialStorage.cpp @@ -29,8 +29,8 @@ #include "Credential.h" #include "KURL.h" #include "ProtectionSpaceHash.h" -#include "StringHash.h" #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/StdLibExtras.h> @@ -75,9 +75,9 @@ static String protectionSpaceMapKeyFromURL(const KURL& url) unsigned directoryURLPathStart = url.pathStart(); ASSERT(directoryURL[directoryURLPathStart] == '/'); if (directoryURL.length() > directoryURLPathStart + 1) { - int index = directoryURL.reverseFind('/'); - ASSERT(index > 0); - directoryURL = directoryURL.substring(0, (static_cast<unsigned>(index) != directoryURLPathStart) ? static_cast<unsigned>(index) : directoryURLPathStart + 1); + size_t index = directoryURL.reverseFind('/'); + ASSERT(index != notFound); + directoryURL = directoryURL.substring(0, (index != directoryURLPathStart) ? index : directoryURLPathStart + 1); } ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/'); @@ -132,9 +132,9 @@ static PathToDefaultProtectionSpaceMap::iterator findDefaultProtectionSpaceForUR if (directoryURL.length() == directoryURLPathStart + 1) // path is "/" already, cannot shorten it any more return map.end(); - int index = directoryURL.reverseFind('/', -2); - ASSERT(index > 0); - directoryURL = directoryURL.substring(0, (static_cast<unsigned>(index) == directoryURLPathStart) ? index + 1 : index); + size_t index = directoryURL.reverseFind('/', directoryURL.length() - 2); + ASSERT(index != notFound); + directoryURL = directoryURL.substring(0, (index == directoryURLPathStart) ? index + 1 : index); ASSERT(directoryURL.length() > directoryURLPathStart); ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/'); } diff --git a/WebCore/platform/network/HTTPHeaderMap.h b/WebCore/platform/network/HTTPHeaderMap.h index 557ddb3..c6145bd 100644 --- a/WebCore/platform/network/HTTPHeaderMap.h +++ b/WebCore/platform/network/HTTPHeaderMap.h @@ -27,13 +27,13 @@ #ifndef HTTPHeaderMap_h #define HTTPHeaderMap_h -#include "AtomicString.h" -#include "AtomicStringHash.h" -#include "StringHash.h" #include <utility> #include <wtf/HashMap.h> #include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> +#include <wtf/text/AtomicString.h> +#include <wtf/text/AtomicStringHash.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/network/HTTPParsers.cpp b/WebCore/platform/network/HTTPParsers.cpp index 6252bfc..b3f3d45 100644 --- a/WebCore/platform/network/HTTPParsers.cpp +++ b/WebCore/platform/network/HTTPParsers.cpp @@ -42,9 +42,9 @@ using namespace WTF; namespace WebCore { // true if there is more to parse -static inline bool skipWhiteSpace(const String& str, int& pos, bool fromHttpEquivMeta) +static inline bool skipWhiteSpace(const String& str, unsigned& pos, bool fromHttpEquivMeta) { - int len = str.length(); + unsigned len = str.length(); if (fromHttpEquivMeta) { while (pos != len && str[pos] <= ' ') @@ -59,9 +59,9 @@ static inline bool skipWhiteSpace(const String& str, int& pos, bool fromHttpEqui // Returns true if the function can match the whole token (case insensitive). // Note: Might return pos == str.length() -static inline bool skipToken(const String& str, int& pos, const char* token) +static inline bool skipToken(const String& str, unsigned& pos, const char* token) { - int len = str.length(); + unsigned len = str.length(); while (pos != len && *token) { if (toASCIILower(str[pos]) != *token++) @@ -104,8 +104,8 @@ ContentDispositionType contentDispositionType(const String& contentDisposition) bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url) { - int len = refresh.length(); - int pos = 0; + unsigned len = refresh.length(); + unsigned pos = 0; if (!skipWhiteSpace(refresh, pos, fromHttpEquivMeta)) return false; @@ -126,7 +126,7 @@ bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del ++pos; skipWhiteSpace(refresh, pos, fromHttpEquivMeta); - int urlStartPos = pos; + unsigned urlStartPos = pos; if (refresh.find("url", urlStartPos, false) == urlStartPos) { urlStartPos += 3; skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta); @@ -137,7 +137,7 @@ bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del urlStartPos = pos; // e.g. "Refresh: 0; url.html" } - int urlEndPos = len; + unsigned urlEndPos = len; if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') { UChar quotationMark = refresh[urlStartPos]; @@ -173,8 +173,8 @@ String filenameFromHTTPContentDisposition(const String& value) unsigned length = keyValuePairs.size(); for (unsigned i = 0; i < length; i++) { - int valueStartPos = keyValuePairs[i].find('='); - if (valueStartPos < 0) + size_t valueStartPos = keyValuePairs[i].find('='); + if (valueStartPos == notFound) continue; String key = keyValuePairs[i].left(valueStartPos).stripWhiteSpace(); @@ -241,12 +241,12 @@ void findCharsetInMediaType(const String& mediaType, unsigned int& charsetPos, u charsetPos = start; charsetLen = 0; - int pos = start; - int length = (int)mediaType.length(); + size_t pos = start; + unsigned length = mediaType.length(); while (pos < length) { pos = mediaType.find("charset", pos, false); - if (pos <= 0) { + if (pos == notFound || pos == 0) { charsetLen = 0; return; } @@ -270,7 +270,7 @@ void findCharsetInMediaType(const String& mediaType, unsigned int& charsetPos, u ++pos; // we don't handle spaces within quoted parameter values, because charset names cannot have any - int endpos = pos; + unsigned endpos = pos; while (pos != length && mediaType[endpos] > ' ' && mediaType[endpos] != '"' && mediaType[endpos] != '\'' && mediaType[endpos] != ';') ++endpos; @@ -290,8 +290,8 @@ XSSProtectionDisposition parseXSSProtectionHeader(const String& header) if (stippedHeader[0] == '0') return XSSProtectionDisabled; - int length = (int)header.length(); - int pos = 0; + unsigned length = header.length(); + unsigned pos = 0; if (stippedHeader[pos++] == '1' && skipWhiteSpace(stippedHeader, pos, false) && stippedHeader[pos++] == ';' @@ -309,7 +309,7 @@ XSSProtectionDisposition parseXSSProtectionHeader(const String& header) String extractReasonPhraseFromHTTPStatusLine(const String& statusLine) { - int spacePos = statusLine.find(' '); + size_t spacePos = statusLine.find(' '); // Remove status code from the status line. spacePos = statusLine.find(' ', spacePos + 1); return statusLine.substring(spacePos + 1); diff --git a/WebCore/platform/network/NetworkingContext.h b/WebCore/platform/network/NetworkingContext.h new file mode 100644 index 0000000..31f3025 --- /dev/null +++ b/WebCore/platform/network/NetworkingContext.h @@ -0,0 +1,68 @@ +/* + 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 NetworkingContext_h +#define NetworkingContext_h + +#include <wtf/RefCounted.h> + +#if PLATFORM(MAC) +#include "SchedulePair.h" +#endif + +#if PLATFORM(QT) +class QObject; +class QNetworkAccessManager; +#endif + +namespace WebCore { + +class ResourceError; +class ResourceRequest; + +class NetworkingContext : public RefCounted<NetworkingContext> { +public: + virtual ~NetworkingContext() { } + + virtual bool isValid() const { return true; } + +#if PLATFORM(MAC) + virtual bool needsSiteSpecificQuirks() const = 0; + virtual bool localFileContentSniffingEnabled() const = 0; + virtual SchedulePairHashSet* scheduledRunLoopPairs() const = 0; + virtual ResourceError blockedError(const ResourceRequest&) const = 0; +#endif + +#if PLATFORM(QT) + virtual QObject* originatingObject() const = 0; + virtual QNetworkAccessManager* networkAccessManager() const = 0; +#endif + +#if PLATFORM(WIN) + virtual String userAgent() const = 0; + virtual String referrer() const = 0; +#endif + +protected: + NetworkingContext() { } +}; + +} + +#endif // NetworkingContext_h diff --git a/WebCore/platform/network/ResourceResponseBase.cpp b/WebCore/platform/network/ResourceResponseBase.cpp index f30344e..e231652 100644 --- a/WebCore/platform/network/ResourceResponseBase.cpp +++ b/WebCore/platform/network/ResourceResponseBase.cpp @@ -439,8 +439,8 @@ bool ResourceResponseBase::isAttachment() const DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("content-disposition")); String value = m_httpHeaderFields.get(headerName); - int loc = value.find(';'); - if (loc != -1) + size_t loc = value.find(';'); + if (loc != notFound) value = value.left(loc); value = value.stripWhiteSpace(); DEFINE_STATIC_LOCAL(const AtomicString, attachmentString, ("attachment")); @@ -591,9 +591,9 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> > const String safeHeader = header.removeCharacters(isControlCharacter); unsigned max = safeHeader.length(); for (unsigned pos = 0; pos < max; /* pos incremented in loop */) { - int nextCommaPosition = safeHeader.find(',', pos); - int nextEqualSignPosition = safeHeader.find('=', pos); - if (nextEqualSignPosition >= 0 && (nextEqualSignPosition < nextCommaPosition || nextCommaPosition < 0)) { + size_t nextCommaPosition = safeHeader.find(',', pos); + size_t nextEqualSignPosition = safeHeader.find('=', pos); + if (nextEqualSignPosition != notFound && (nextEqualSignPosition < nextCommaPosition || nextCommaPosition == notFound)) { // Get directive name, parse right hand side of equal sign, then add to map String directive = trimToNextSeparator(safeHeader.substring(pos, nextEqualSignPosition - pos).stripWhiteSpace()); pos += nextEqualSignPosition - pos + 1; @@ -601,14 +601,14 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> > String value = safeHeader.substring(pos, max - pos).stripWhiteSpace(); if (value[0] == '"') { // The value is a quoted string - int nextDoubleQuotePosition = value.find('"', 1); - if (nextDoubleQuotePosition >= 0) { + size_t nextDoubleQuotePosition = value.find('"', 1); + if (nextDoubleQuotePosition != notFound) { // Store the value as a quoted string without quotes result.append(pair<String, String>(directive, value.substring(1, nextDoubleQuotePosition - 1).stripWhiteSpace())); pos += (safeHeader.find('"', pos) - pos) + nextDoubleQuotePosition + 1; // Move past next comma, if there is one - int nextCommaPosition2 = safeHeader.find(',', pos); - if (nextCommaPosition2 >= 0) + size_t nextCommaPosition2 = safeHeader.find(',', pos); + if (nextCommaPosition2 != notFound) pos += nextCommaPosition2 - pos + 1; else return; // Parse error if there is anything left with no comma @@ -619,8 +619,8 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> > } } else { // The value is a token until the next comma - int nextCommaPosition2 = value.find(',', 0); - if (nextCommaPosition2 >= 0) { + size_t nextCommaPosition2 = value.find(',', 0); + if (nextCommaPosition2 != notFound) { // The value is delimited by the next comma result.append(pair<String, String>(directive, trimToNextSeparator(value.substring(0, nextCommaPosition2).stripWhiteSpace()))); pos += (safeHeader.find(',', pos) - pos) + 1; @@ -630,7 +630,7 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> > return; } } - } else if (nextCommaPosition >= 0 && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition < 0)) { + } else if (nextCommaPosition != notFound && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition == notFound)) { // Add directive to map with empty string as value result.append(pair<String, String>(trimToNextSeparator(safeHeader.substring(pos, nextCommaPosition - pos).stripWhiteSpace()), "")); pos += nextCommaPosition - pos + 1; diff --git a/WebCore/platform/network/cf/DNSCFNet.cpp b/WebCore/platform/network/cf/DNSCFNet.cpp index bda9e41..fbceb7d 100644 --- a/WebCore/platform/network/cf/DNSCFNet.cpp +++ b/WebCore/platform/network/cf/DNSCFNet.cpp @@ -27,11 +27,11 @@ #include "config.h" #include "DNS.h" -#include "StringHash.h" #include "Timer.h" #include <wtf/HashSet.h> #include <wtf/RetainPtr.h> #include <wtf/StdLibExtras.h> +#include <wtf/text/StringHash.h> #if PLATFORM(WIN) #include "LoaderRunLoopCF.h" diff --git a/WebCore/platform/network/curl/CookieJarCurl.cpp b/WebCore/platform/network/curl/CookieJarCurl.cpp index 7c906a0..e05947c 100644 --- a/WebCore/platform/network/curl/CookieJarCurl.cpp +++ b/WebCore/platform/network/curl/CookieJarCurl.cpp @@ -21,9 +21,8 @@ #include "Document.h" #include "KURL.h" #include "PlatformString.h" -#include "StringHash.h" - #include <wtf/HashMap.h> +#include <wtf/text/StringHash.h> namespace WebCore { diff --git a/WebCore/platform/qt/ClipboardQt.cpp b/WebCore/platform/qt/ClipboardQt.cpp index 6ca4830..f677d28 100644 --- a/WebCore/platform/qt/ClipboardQt.cpp +++ b/WebCore/platform/qt/ClipboardQt.cpp @@ -43,8 +43,8 @@ #include "PlatformString.h" #include "Range.h" #include "RenderImage.h" -#include "StringHash.h" #include "markup.h" +#include <wtf/text/StringHash.h> #include <QApplication> #include <QClipboard> diff --git a/WebCore/platform/sql/SQLiteDatabase.cpp b/WebCore/platform/sql/SQLiteDatabase.cpp index 05a2a22..80d3946 100644 --- a/WebCore/platform/sql/SQLiteDatabase.cpp +++ b/WebCore/platform/sql/SQLiteDatabase.cpp @@ -33,6 +33,7 @@ #include "SQLiteStatement.h" #include <sqlite3.h> #include <wtf/Threading.h> +#include <wtf/text/CString.h> namespace WebCore { @@ -156,7 +157,11 @@ void SQLiteDatabase::setMaximumSize(int64_t size) SQLiteStatement statement(*this, "PRAGMA max_page_count = " + String::number(newMaxPageCount)); statement.prepare(); if (statement.step() != SQLResultRow) +#if OS(WINDOWS) + LOG_ERROR("Failed to set maximum size of database to %I64i bytes", static_cast<long long>(size)); +#else LOG_ERROR("Failed to set maximum size of database to %lli bytes", static_cast<long long>(size)); +#endif enableAuthorizer(true); diff --git a/WebCore/platform/sql/SQLiteStatement.cpp b/WebCore/platform/sql/SQLiteStatement.cpp index ac467a6..4dc80fb 100644 --- a/WebCore/platform/sql/SQLiteStatement.cpp +++ b/WebCore/platform/sql/SQLiteStatement.cpp @@ -30,6 +30,7 @@ #include "SQLValue.h" #include <sqlite3.h> #include <wtf/Assertions.h> +#include <wtf/text/CString.h> namespace WebCore { diff --git a/WebCore/platform/text/AtomicString.h b/WebCore/platform/text/AtomicString.h deleted file mode 100644 index 6ce63b5..0000000 --- a/WebCore/platform/text/AtomicString.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WebCoreAtomicString_h -#define WebCoreAtomicString_h - -// FIXME: remove this header, use the forward from wtf directly. -#include <wtf/text/AtomicString.h> - -#endif // AtomicString_h diff --git a/WebCore/platform/text/AtomicStringHash.h b/WebCore/platform/text/AtomicStringHash.h deleted file mode 100644 index d13332b..0000000 --- a/WebCore/platform/text/AtomicStringHash.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AtomicStringHash_h -#define AtomicStringHash_h - -#include "AtomicString.h" -#include <wtf/HashTraits.h> - -namespace WebCore { - - struct AtomicStringHash { - static unsigned hash(const AtomicString& key) - { - return key.impl()->existingHash(); - } - - static bool equal(const AtomicString& a, const AtomicString& b) - { - return a == b; - } - - static const bool safeToCompareToEmptyOrDeleted = false; - }; - -} - -namespace WTF { - - // WebCore::AtomicStringHash is the default hash for AtomicString - template<> struct HashTraits<WTF::AtomicString> : GenericHashTraits<WTF::AtomicString> { - static const bool emptyValueIsZero = true; - static void constructDeletedValue(WTF::AtomicString& slot) { new (&slot) WTF::AtomicString(HashTableDeletedValue); } - static bool isDeletedValue(const WTF::AtomicString& slot) { return slot.isHashTableDeletedValue(); } - }; - -} - -#endif diff --git a/WebCore/platform/text/AtomicStringImpl.h b/WebCore/platform/text/AtomicStringImpl.h deleted file mode 100644 index 64bce77..0000000 --- a/WebCore/platform/text/AtomicStringImpl.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. - * - * 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 WebCoreAtomicStringImpl_h -#define WebCoreAtomicStringImpl_h - -// FIXME: remove this header, use the forward from wtf directly. -#include <wtf/text/AtomicStringImpl.h> - -#endif diff --git a/WebCore/platform/text/AtomicStringKeyedMRUCache.h b/WebCore/platform/text/AtomicStringKeyedMRUCache.h index a47585a..b3004f7 100644 --- a/WebCore/platform/text/AtomicStringKeyedMRUCache.h +++ b/WebCore/platform/text/AtomicStringKeyedMRUCache.h @@ -26,6 +26,8 @@ #ifndef AtomicStringKeyedMRUCache_h #define AtomicStringKeyedMRUCache_h +#include <wtf/text/AtomicString.h> + namespace WebCore { template<typename T, size_t capacity = 4> diff --git a/WebCore/platform/text/SegmentedString.cpp b/WebCore/platform/text/SegmentedString.cpp index 04d6c77..b9ff503 100644 --- a/WebCore/platform/text/SegmentedString.cpp +++ b/WebCore/platform/text/SegmentedString.cpp @@ -52,6 +52,7 @@ const SegmentedString& SegmentedString::operator=(const SegmentedString &other) else m_currentChar = other.m_currentChar; m_closed = other.m_closed; + m_numberOfCharactersConsumedPriorToCurrentString = other.m_numberOfCharactersConsumedPriorToCurrentString; return *this; } @@ -99,6 +100,7 @@ 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); @@ -110,7 +112,15 @@ void SegmentedString::append(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 { @@ -160,7 +170,12 @@ void SegmentedString::prepend(const SegmentedString &s) void SegmentedString::advanceSubstring() { if (m_composite) { + 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 { diff --git a/WebCore/platform/text/SegmentedString.h b/WebCore/platform/text/SegmentedString.h index 1d3098d..91c2cbe 100644 --- a/WebCore/platform/text/SegmentedString.h +++ b/WebCore/platform/text/SegmentedString.h @@ -45,6 +45,8 @@ public: void setExcludeLineNumbers() { m_doNotExcludeLineNumbers = false; } + int numberOfCharactersConsumed() const { return m_string.length() - m_length; } + void appendTo(String& str) const { if (m_string.characters() == m_current) { @@ -69,10 +71,26 @@ private: class SegmentedString { public: SegmentedString() - : m_pushedChar1(0), m_pushedChar2(0), m_currentChar(0), m_composite(false), m_closed(false) {} + : m_pushedChar1(0) + , m_pushedChar2(0) + , m_currentChar(0) + , m_numberOfCharactersConsumedPriorToCurrentString(0) + , m_composite(false) + , m_closed(false) + { + } + SegmentedString(const String& str) - : m_pushedChar1(0), m_pushedChar2(0), m_currentString(str) - , m_currentChar(m_currentString.m_current), m_composite(false), m_closed(false) {} + : m_pushedChar1(0) + , m_pushedChar2(0) + , m_currentString(str) + , m_currentChar(m_currentString.m_current) + , m_numberOfCharactersConsumedPriorToCurrentString(0) + , m_composite(false) + , m_closed(false) + { + } + SegmentedString(const SegmentedString&); const SegmentedString& operator=(const SegmentedString&); @@ -173,6 +191,13 @@ public: bool escaped() const { return m_pushedChar1; } + int numberOfCharactersConsumed() + { + // We don't currently handle the case when there are pushed character. + ASSERT(!m_pushedChar1); + return m_numberOfCharactersConsumedPriorToCurrentString + m_currentString.numberOfCharactersConsumed(); + } + String toString() const; const UChar& operator*() const { return *current(); } @@ -221,6 +246,7 @@ private: UChar m_pushedChar2; SegmentedSubstring m_currentString; const UChar* m_currentChar; + int m_numberOfCharactersConsumedPriorToCurrentString; Deque<SegmentedSubstring> m_substrings; bool m_composite; bool m_closed; diff --git a/WebCore/platform/text/StringBuilder.cpp b/WebCore/platform/text/StringBuilder.cpp index 213daab..1c47129 100644 --- a/WebCore/platform/text/StringBuilder.cpp +++ b/WebCore/platform/text/StringBuilder.cpp @@ -30,7 +30,7 @@ #include "config.h" #include "StringBuilder.h" -#include "StringBuffer.h" +#include <wtf/text/StringBuffer.h> namespace WebCore { diff --git a/WebCore/platform/text/StringHash.h b/WebCore/platform/text/StringHash.h deleted file mode 100644 index 35de30d..0000000 --- a/WebCore/platform/text/StringHash.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved - * Copyright (C) Research In Motion Limited 2009. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WebCoreStringHash_h -#define WebCoreStringHash_h - -// FIXME: remove this header, use the forward from wtf directly. -#include <wtf/text/StringHash.h> - -#endif diff --git a/WebCore/platform/text/StringImpl.h b/WebCore/platform/text/StringImpl.h deleted file mode 100644 index fa79b61..0000000 --- a/WebCore/platform/text/StringImpl.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WebCoreStringImpl_h -#define WebCoreStringImpl_h - -// FIXME: remove this header, use the forward from wtf directly. -#include <wtf/text/StringImpl.h> - -#endif diff --git a/WebCore/platform/text/TextBoundaries.cpp b/WebCore/platform/text/TextBoundaries.cpp index 2455f6d..8eaffca 100644 --- a/WebCore/platform/text/TextBoundaries.cpp +++ b/WebCore/platform/text/TextBoundaries.cpp @@ -27,8 +27,8 @@ #include "config.h" #include "TextBoundaries.h" -#include "StringImpl.h" #include "TextBreakIterator.h" +#include <wtf/text/StringImpl.h> #include <wtf/unicode/Unicode.h> using namespace WTF; diff --git a/WebCore/platform/text/TextCodecLatin1.cpp b/WebCore/platform/text/TextCodecLatin1.cpp index 1e9385d..4f9cbe0 100644 --- a/WebCore/platform/text/TextCodecLatin1.cpp +++ b/WebCore/platform/text/TextCodecLatin1.cpp @@ -27,9 +27,9 @@ #include "TextCodecLatin1.h" #include "PlatformString.h" -#include "StringBuffer.h" #include <stdio.h> #include <wtf/text/CString.h> +#include <wtf/text/StringBuffer.h> #include <wtf/PassOwnPtr.h> namespace WebCore { diff --git a/WebCore/platform/text/TextCodecUTF16.cpp b/WebCore/platform/text/TextCodecUTF16.cpp index 16f8431..5c23732 100644 --- a/WebCore/platform/text/TextCodecUTF16.cpp +++ b/WebCore/platform/text/TextCodecUTF16.cpp @@ -27,8 +27,8 @@ #include "TextCodecUTF16.h" #include "PlatformString.h" -#include "StringBuffer.h" #include <wtf/text/CString.h> +#include <wtf/text/StringBuffer.h> #include <wtf/PassOwnPtr.h> namespace WebCore { diff --git a/WebCore/platform/text/TextCodecUserDefined.cpp b/WebCore/platform/text/TextCodecUserDefined.cpp index 851d693..70d8673 100644 --- a/WebCore/platform/text/TextCodecUserDefined.cpp +++ b/WebCore/platform/text/TextCodecUserDefined.cpp @@ -27,9 +27,9 @@ #include "TextCodecUserDefined.h" #include "PlatformString.h" -#include "StringBuffer.h" #include <stdio.h> #include <wtf/text/CString.h> +#include <wtf/text/StringBuffer.h> #include <wtf/PassOwnPtr.h> namespace WebCore { diff --git a/WebCore/platform/text/cf/HyphenationCF.cpp b/WebCore/platform/text/cf/HyphenationCF.cpp index b983979..8be537d 100644 --- a/WebCore/platform/text/cf/HyphenationCF.cpp +++ b/WebCore/platform/text/cf/HyphenationCF.cpp @@ -28,7 +28,6 @@ #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) -#include "AtomicString.h" #include "AtomicStringKeyedMRUCache.h" #include "TextBreakIteratorInternalICU.h" #include <wtf/ListHashSet.h> diff --git a/WebCore/platform/text/cf/StringImplCF.cpp b/WebCore/platform/text/cf/StringImplCF.cpp index 18e137f..0157918 100644 --- a/WebCore/platform/text/cf/StringImplCF.cpp +++ b/WebCore/platform/text/cf/StringImplCF.cpp @@ -19,7 +19,7 @@ */ #include "config.h" -#include "StringImpl.h" +#include <wtf/text/StringImpl.h> #if PLATFORM(CF) diff --git a/WebCore/platform/text/mac/HyphenationMac.mm b/WebCore/platform/text/mac/HyphenationMac.mm index 56122df..d5c9283 100644 --- a/WebCore/platform/text/mac/HyphenationMac.mm +++ b/WebCore/platform/text/mac/HyphenationMac.mm @@ -28,7 +28,6 @@ #if defined(BUILDING_ON_TIGER) || defined(BUILDING_ON_LEOPARD) || defined(BUILDING_ON_SNOW_LEOPARD) -#import "AtomicString.h" #import "AtomicStringKeyedMRUCache.h" #import "TextBreakIteratorInternalICU.h" #import "WebCoreSystemInterface.h" diff --git a/WebCore/platform/text/mac/StringImplMac.mm b/WebCore/platform/text/mac/StringImplMac.mm index 843f396..6f5e953 100644 --- a/WebCore/platform/text/mac/StringImplMac.mm +++ b/WebCore/platform/text/mac/StringImplMac.mm @@ -19,7 +19,7 @@ */ #include "config.h" -#include "StringImpl.h" +#include <wtf/text/StringImpl.h> #include "FoundationExtras.h" diff --git a/WebCore/platform/text/transcoder/FontTranscoder.h b/WebCore/platform/text/transcoder/FontTranscoder.h index 1fdc936..67db977 100644 --- a/WebCore/platform/text/transcoder/FontTranscoder.h +++ b/WebCore/platform/text/transcoder/FontTranscoder.h @@ -31,9 +31,9 @@ #ifndef FontTranscoder_h #define FontTranscoder_h -#include "AtomicStringHash.h" #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> +#include <wtf/text/AtomicStringHash.h> namespace WebCore { diff --git a/WebCore/platform/text/wince/TextCodecWinCE.cpp b/WebCore/platform/text/wince/TextCodecWinCE.cpp index 644b12f..578f789 100644 --- a/WebCore/platform/text/wince/TextCodecWinCE.cpp +++ b/WebCore/platform/text/wince/TextCodecWinCE.cpp @@ -27,13 +27,13 @@ #include "ce_textcodecs.h" #include "FontCache.h" #include "PlatformString.h" -#include "StringHash.h" #include <mlang.h> #include <winbase.h> #include <winnls.h> #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> #include <wtf/unicode/UTF8.h> namespace WebCore { diff --git a/WebCore/platform/win/BString.cpp b/WebCore/platform/win/BString.cpp index 618ecf3..4d6d11e 100644 --- a/WebCore/platform/win/BString.cpp +++ b/WebCore/platform/win/BString.cpp @@ -26,9 +26,9 @@ #include "config.h" #include "BString.h" -#include "AtomicString.h" #include "KURL.h" #include "PlatformString.h" +#include <wtf/text/AtomicString.h> #include <tchar.h> #include <windows.h> @@ -90,7 +90,7 @@ BString::BString(const UString& s) if (s.isNull()) m_bstr = 0; else - m_bstr = SysAllocStringLen(s.data(), s.size()); + m_bstr = SysAllocStringLen(s.characters(), s.length()); } #if PLATFORM(CF) diff --git a/WebCore/platform/win/COMPtr.h b/WebCore/platform/win/COMPtr.h index 692706f..6b84256 100644 --- a/WebCore/platform/win/COMPtr.h +++ b/WebCore/platform/win/COMPtr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2007, 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,7 +44,7 @@ enum AdoptCOMTag { AdoptCOM }; enum QueryTag { Query }; enum CreateTag { Create }; -template <typename T> class COMPtr { +template<typename T> class COMPtr { public: COMPtr() : m_ptr(0) { } COMPtr(T* ptr) : m_ptr(ptr) { if (m_ptr) m_ptr->AddRef(); } @@ -52,7 +52,7 @@ public: COMPtr(const COMPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->AddRef(); } COMPtr(QueryTag, IUnknown* ptr) : m_ptr(copyQueryInterfaceRef(ptr)) { } - template <typename U> COMPtr(QueryTag, const COMPtr<U>& ptr) : m_ptr(copyQueryInterfaceRef(ptr.get())) { } + template<typename U> COMPtr(QueryTag, const COMPtr<U>& ptr) : m_ptr(copyQueryInterfaceRef(ptr.get())) { } COMPtr(CreateTag, const IID& clsid) : m_ptr(createInstance(clsid)) { } @@ -63,7 +63,9 @@ public: ~COMPtr() { if (m_ptr) m_ptr->Release(); } T* get() const { return m_ptr; } - T* releaseRef() { T* tmp = m_ptr; m_ptr = 0; return tmp; } + + void clear(); + T* leakRef(); T& operator*() const { return *m_ptr; } T* operator->() const { return m_ptr; } @@ -78,16 +80,19 @@ public: COMPtr& operator=(const COMPtr&); COMPtr& operator=(T*); - template <typename U> COMPtr& operator=(const COMPtr<U>&); + template<typename U> COMPtr& operator=(const COMPtr<U>&); void query(IUnknown* ptr) { adoptRef(copyQueryInterfaceRef(ptr)); } - template <typename U> void query(const COMPtr<U>& ptr) { query(ptr.get()); } + template<typename U> void query(const COMPtr<U>& ptr) { query(ptr.get()); } void create(const IID& clsid) { adoptRef(createInstance(clsid)); } - template <typename U> HRESULT copyRefTo(U**); + template<typename U> HRESULT copyRefTo(U**); void adoptRef(T*); + // FIXME: Remove releaseRef once we change all callers to call leakRef instead. + T* releaseRef() { return leakRef(); } + private: static T* copyQueryInterfaceRef(IUnknown*); static T* createInstance(const IID& clsid); @@ -96,7 +101,22 @@ private: T* m_ptr; }; -template <typename T> inline T* COMPtr<T>::createInstance(const IID& clsid) +template<typename T> inline void COMPtr<T>::clear() +{ + if (T* ptr = m_ptr) { + m_ptr = 0; + ptr->Release(); + } +} + +template<typename T> inline T* COMPtr<T>::leakRef() +{ + T* ptr = m_ptr; + m_ptr = 0; + return ptr; +} + +template<typename T> inline T* COMPtr<T>::createInstance(const IID& clsid) { T* result; if (FAILED(CoCreateInstance(clsid, 0, CLSCTX_ALL, __uuidof(result), reinterpret_cast<void**>(&result)))) @@ -104,7 +124,7 @@ template <typename T> inline T* COMPtr<T>::createInstance(const IID& clsid) return result; } -template <typename T> inline T* COMPtr<T>::copyQueryInterfaceRef(IUnknown* ptr) +template<typename T> inline T* COMPtr<T>::copyQueryInterfaceRef(IUnknown* ptr) { if (!ptr) return 0; @@ -114,7 +134,7 @@ template <typename T> inline T* COMPtr<T>::copyQueryInterfaceRef(IUnknown* ptr) return result; } -template <typename T> template <typename U> inline HRESULT COMPtr<T>::copyRefTo(U** ptr) +template<typename T> template<typename U> inline HRESULT COMPtr<T>::copyRefTo(U** ptr) { if (!ptr) return E_POINTER; @@ -124,14 +144,14 @@ template <typename T> template <typename U> inline HRESULT COMPtr<T>::copyRefTo( return S_OK; } -template <typename T> inline void COMPtr<T>::adoptRef(T *ptr) +template<typename T> inline void COMPtr<T>::adoptRef(T *ptr) { if (m_ptr) m_ptr->Release(); m_ptr = ptr; } -template <typename T> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<T>& o) +template<typename T> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<T>& o) { T* optr = o.get(); if (optr) @@ -143,7 +163,7 @@ template <typename T> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<T>& o) return *this; } -template <typename T> template <typename U> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<U>& o) +template<typename T> template<typename U> inline COMPtr<T>& COMPtr<T>::operator=(const COMPtr<U>& o) { T* optr = o.get(); if (optr) @@ -155,7 +175,7 @@ template <typename T> template <typename U> inline COMPtr<T>& COMPtr<T>::operato return *this; } -template <typename T> inline COMPtr<T>& COMPtr<T>::operator=(T* optr) +template<typename T> inline COMPtr<T>& COMPtr<T>::operator=(T* optr) { if (optr) optr->AddRef(); @@ -166,32 +186,32 @@ template <typename T> inline COMPtr<T>& COMPtr<T>::operator=(T* optr) return *this; } -template <typename T, typename U> inline bool operator==(const COMPtr<T>& a, const COMPtr<U>& b) +template<typename T, typename U> inline bool operator==(const COMPtr<T>& a, const COMPtr<U>& b) { return a.get() == b.get(); } -template <typename T, typename U> inline bool operator==(const COMPtr<T>& a, U* b) +template<typename T, typename U> inline bool operator==(const COMPtr<T>& a, U* b) { return a.get() == b; } -template <typename T, typename U> inline bool operator==(T* a, const COMPtr<U>& b) +template<typename T, typename U> inline bool operator==(T* a, const COMPtr<U>& b) { return a == b.get(); } -template <typename T, typename U> inline bool operator!=(const COMPtr<T>& a, const COMPtr<U>& b) +template<typename T, typename U> inline bool operator!=(const COMPtr<T>& a, const COMPtr<U>& b) { return a.get() != b.get(); } -template <typename T, typename U> inline bool operator!=(const COMPtr<T>& a, U* b) +template<typename T, typename U> inline bool operator!=(const COMPtr<T>& a, U* b) { return a.get() != b; } -template <typename T, typename U> inline bool operator!=(T* a, const COMPtr<U>& b) +template<typename T, typename U> inline bool operator!=(T* a, const COMPtr<U>& b) { return a != b.get(); } @@ -200,8 +220,8 @@ namespace WTF { template<typename P> struct HashTraits<COMPtr<P> > : GenericHashTraits<COMPtr<P> > { static const bool emptyValueIsZero = true; - static void constructDeletedValue(COMPtr<P>& slot) { slot.releaseRef(); *&slot = reinterpret_cast<P*>(-1); } - static bool isDeletedValue(const COMPtr<P>& value) { return value == reinterpret_cast<P*>(-1); } + static void constructDeletedValue(COMPtr<P>& slot) { new (&slot) COMPtr<P>(HashTableDeletedValue); } + static bool isDeletedValue(const COMPtr<P>& value) { return value.isHashTableDeletedValue(); } }; template<typename P> struct PtrHash<COMPtr<P> > : PtrHash<P*> { diff --git a/WebCore/platform/win/ClipboardWin.cpp b/WebCore/platform/win/ClipboardWin.cpp index 6e026d6..2915f9d 100644 --- a/WebCore/platform/win/ClipboardWin.cpp +++ b/WebCore/platform/win/ClipboardWin.cpp @@ -49,7 +49,6 @@ #include "RenderImage.h" #include "ResourceResponse.h" #include "SharedBuffer.h" -#include "StringHash.h" #include "WCDataObject.h" #include "csshelper.h" #include "markup.h" @@ -57,6 +56,7 @@ #include <wininet.h> #include <wtf/RefPtr.h> #include <wtf/text/CString.h> +#include <wtf/text/StringHash.h> using namespace std; diff --git a/WebCore/platform/win/SearchPopupMenuWin.cpp b/WebCore/platform/win/SearchPopupMenuWin.cpp index 6655b1b..7ae800b 100644 --- a/WebCore/platform/win/SearchPopupMenuWin.cpp +++ b/WebCore/platform/win/SearchPopupMenuWin.cpp @@ -21,7 +21,7 @@ #include "config.h" #include "SearchPopupMenuWin.h" -#include "AtomicString.h" +#include <wtf/text/AtomicString.h> #if PLATFORM(CF) #include <wtf/RetainPtr.h> diff --git a/WebCore/platform/win/SharedBufferWin.cpp b/WebCore/platform/win/SharedBufferWin.cpp index bbecb86..59a5a76 100644 --- a/WebCore/platform/win/SharedBufferWin.cpp +++ b/WebCore/platform/win/SharedBufferWin.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "SharedBuffer.h" +#include <wtf/text/CString.h> // INVALID_FILE_SIZE is not defined on WinCE. #ifndef INVALID_FILE_SIZE diff --git a/WebCore/platform/wince/SearchPopupMenuWince.cpp b/WebCore/platform/wince/SearchPopupMenuWince.cpp index 756b7cf..f9d65a6 100644 --- a/WebCore/platform/wince/SearchPopupMenuWince.cpp +++ b/WebCore/platform/wince/SearchPopupMenuWince.cpp @@ -20,8 +20,8 @@ #include "config.h" #include "SearchPopupMenu.h" -#include "AtomicString.h" #include "NotImplemented.h" +#include <wtf/text/AtomicString.h> namespace WebCore { diff --git a/WebCore/platform/wx/ClipboardWx.cpp b/WebCore/platform/wx/ClipboardWx.cpp index 336881d..2ef943f 100644 --- a/WebCore/platform/wx/ClipboardWx.cpp +++ b/WebCore/platform/wx/ClipboardWx.cpp @@ -32,7 +32,7 @@ #include "NotImplemented.h" #include "Pasteboard.h" #include "PlatformString.h" -#include "StringHash.h" +#include <wtf/text/StringHash.h> namespace WebCore { |