diff options
author | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 22:31:35 +0000 |
---|---|---|
committer | tc@google.com <tc@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-01 22:31:35 +0000 |
commit | de56f378336660dcc848763c80267a5e063ae47d (patch) | |
tree | 7f551b88923b35bc4022ce6ab3a3f602fb60d91c /webkit/port/platform | |
parent | dc4f63c80cb90efe594131030aad6776e5945fcc (diff) | |
download | chromium_src-de56f378336660dcc848763c80267a5e063ae47d.zip chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.gz chromium_src-de56f378336660dcc848763c80267a5e063ae47d.tar.bz2 |
Merge the chrome_webkit_merge_branch back on to trunk. This brings us
up to webkit@36102.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2778 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/platform')
62 files changed, 2021 insertions, 1160 deletions
diff --git a/webkit/port/platform/ClipboardUtilitiesWin.cpp b/webkit/port/platform/ClipboardUtilitiesWin.cpp index a35794f..f23c2fe 100644 --- a/webkit/port/platform/ClipboardUtilitiesWin.cpp +++ b/webkit/port/platform/ClipboardUtilitiesWin.cpp @@ -41,6 +41,20 @@ namespace WebCore { +FORMATETC* cfHDropFormat() +{ + static FORMATETC urlFormat = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +//Firefox text/html +static FORMATETC* texthtmlFormat() +{ + static UINT cf = RegisterClipboardFormat(L"text/html"); + static FORMATETC texthtmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &texthtmlFormat; +} + HGLOBAL createGlobalData(const KURL& url, const String& title) { String mutableURL(url.string()); @@ -56,77 +70,86 @@ HGLOBAL createGlobalData(const KURL& url, const String& title) return cbData; } -HGLOBAL createGlobalData(String str) -{ - SIZE_T size = (str.length() + 1) * sizeof(UChar); - HGLOBAL cbData = ::GlobalAlloc(GPTR, size); - if (cbData) { - void* buffer = ::GlobalLock(cbData); - memcpy(buffer, str.charactersWithNullTermination(), size); - ::GlobalUnlock(cbData); - } - return cbData; +HGLOBAL createGlobalData(const String& str) +{ + HGLOBAL globalData = ::GlobalAlloc(GPTR, (str.length() + 1) * sizeof(UChar)); + if (!globalData) + return 0; + UChar* buffer = static_cast<UChar*>(::GlobalLock(globalData)); + memcpy(buffer, str.characters(), str.length() * sizeof(UChar)); + buffer[str.length()] = 0; + ::GlobalUnlock(globalData); + return globalData; } -HGLOBAL createGlobalData(CString str) +HGLOBAL createGlobalData(const Vector<char>& vector) { - SIZE_T size = str.length() * sizeof(char); - HGLOBAL cbData = ::GlobalAlloc(GPTR, size + 1); - if (cbData) { - char* buffer = static_cast<char*>(::GlobalLock(cbData)); - memcpy(buffer, str.data(), size); - buffer[size] = 0; - ::GlobalUnlock(cbData); - } - return cbData; + HGLOBAL globalData = ::GlobalAlloc(GPTR, vector.size() + 1); + if (!globalData) + return 0; + char* buffer = static_cast<char*>(::GlobalLock(globalData)); + memcpy(buffer, vector.data(), vector.size()); + buffer[vector.size()] = 0; + ::GlobalUnlock(globalData); + return globalData; +} + +static void append(Vector<char>& vector, const char* string) +{ + vector.append(string, strlen(string)); +} + +static void append(Vector<char>& vector, const CString& string) +{ + vector.append(string.data(), string.length()); } // Documentation for the CF_HTML format is available at http://msdn.microsoft.com/workshop/networking/clipboard/htmlclipboard.asp -DeprecatedCString markupToCF_HTML(const String& markup, const String& srcURL) +void markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result) { - if (!markup.length()) - return DeprecatedCString(); + if (markup.isEmpty()) + return; - DeprecatedCString cf_html ("Version:0.9"); - DeprecatedCString startHTML ("\nStartHTML:"); - DeprecatedCString endHTML ("\nEndHTML:"); - DeprecatedCString startFragment ("\nStartFragment:"); - DeprecatedCString endFragment ("\nEndFragment:"); - DeprecatedCString sourceURL ("\nSourceURL:"); + #define MAX_DIGITS 10 + #define MAKE_NUMBER_FORMAT_1(digits) MAKE_NUMBER_FORMAT_2(digits) + #define MAKE_NUMBER_FORMAT_2(digits) "%0" #digits "u" + #define NUMBER_FORMAT MAKE_NUMBER_FORMAT_1(MAX_DIGITS) - bool shouldFillSourceURL = !srcURL.isEmpty() && (srcURL != "about:blank"); - if (shouldFillSourceURL) - sourceURL.append(srcURL.utf8().data()); + const char* header = "Version:0.9\n" + "StartHTML:" NUMBER_FORMAT "\n" + "EndHTML:" NUMBER_FORMAT "\n" + "StartFragment:" NUMBER_FORMAT "\n" + "EndFragment:" NUMBER_FORMAT "\n"; + const char* sourceURLPrefix = "SourceURL:"; - DeprecatedCString startMarkup ("\n<HTML>\n<BODY>\n<!--StartFragment-->\n"); - DeprecatedCString endMarkup ("\n<!--EndFragment-->\n</BODY>\n</HTML>"); + const char* startMarkup = "<HTML>\n<BODY>\n<!--StartFragment-->\n"; + const char* endMarkup = "\n<!--EndFragment-->\n</BODY>\n</HTML>"; - // calculate offsets - const unsigned UINT_MAXdigits = 10; // number of digits in UINT_MAX in base 10 - unsigned startHTMLOffset = cf_html.length() + startHTML.length() + endHTML.length() + startFragment.length() + endFragment.length() + (shouldFillSourceURL ? sourceURL.length() : 0) + (4*UINT_MAXdigits); - unsigned startFragmentOffset = startHTMLOffset + startMarkup.length(); + CString sourceURLUTF8 = srcURL == blankURL() ? "" : srcURL.utf8(); CString markupUTF8 = markup.utf8(); - unsigned endFragmentOffset = startFragmentOffset + markupUTF8.length(); - unsigned endHTMLOffset = endFragmentOffset + endMarkup.length(); - - // fill in needed data - startHTML.append(String::format("%010u", startHTMLOffset).deprecatedString().utf8()); - endHTML.append(String::format("%010u", endHTMLOffset).deprecatedString().utf8()); - startFragment.append(String::format("%010u", startFragmentOffset).deprecatedString().utf8()); - endFragment.append(String::format("%010u", endFragmentOffset).deprecatedString().utf8()); - startMarkup.append(markupUTF8.data()); - // create full cf_html string from the fragments - cf_html.append(startHTML); - cf_html.append(endHTML); - cf_html.append(startFragment); - cf_html.append(endFragment); - if (shouldFillSourceURL) - cf_html.append(sourceURL); - cf_html.append(startMarkup); - cf_html.append(endMarkup); + // calculate offsets + unsigned startHTMLOffset = strlen(header) - strlen(NUMBER_FORMAT) * 4 + MAX_DIGITS * 4; + if (sourceURLUTF8.length()) + startHTMLOffset += strlen(sourceURLPrefix) + sourceURLUTF8.length() + 1; + unsigned startFragmentOffset = startHTMLOffset + strlen(startMarkup); + unsigned endFragmentOffset = startFragmentOffset + markupUTF8.length(); + unsigned endHTMLOffset = endFragmentOffset + strlen(endMarkup); - return cf_html; + append(result, String::format(header, startHTMLOffset, endHTMLOffset, startFragmentOffset, endFragmentOffset).utf8()); + if (sourceURLUTF8.length()) { + append(result, sourceURLPrefix); + append(result, sourceURLUTF8); + result.append('\n'); + } + append(result, startMarkup); + append(result, markupUTF8); + append(result, endMarkup); + + #undef MAX_DIGITS + #undef MAKE_NUMBER_FORMAT_1 + #undef MAKE_NUMBER_FORMAT_2 + #undef NUMBER_FORMAT } String urlToMarkup(const KURL& url, const String& title) @@ -156,7 +179,7 @@ String urlToImageMarkup(const KURL& url, const String& altStr) { void replaceNewlinesWithWindowsStyleNewlines(String& str) { static const UChar Newline = '\n'; - static const String WindowsNewline("\r\n"); + static const char* const WindowsNewline("\r\n"); str.replace(Newline, WindowsNewline); } @@ -167,6 +190,60 @@ void replaceNBSPWithSpace(String& str) str.replace(NonBreakingSpaceCharacter, SpaceCharacter); } +FORMATETC* urlWFormat() +{ + static UINT cf = RegisterClipboardFormat(L"UniformResourceLocatorW"); + static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +FORMATETC* urlFormat() +{ + static UINT cf = RegisterClipboardFormat(L"UniformResourceLocator"); + static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +FORMATETC* plainTextFormat() +{ + static FORMATETC textFormat = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &textFormat; +} + +FORMATETC* plainTextWFormat() +{ + static FORMATETC textFormat = {CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &textFormat; +} + +FORMATETC* filenameWFormat() +{ + static UINT cf = RegisterClipboardFormat(L"FileNameW"); + static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +FORMATETC* filenameFormat() +{ + static UINT cf = RegisterClipboardFormat(L"FileName"); + static FORMATETC urlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &urlFormat; +} + +//MSIE HTML Format +FORMATETC* htmlFormat() +{ + static UINT cf = RegisterClipboardFormat(L"HTML Format"); + static FORMATETC htmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &htmlFormat; +} + +FORMATETC* smartPasteFormat() +{ + static UINT cf = RegisterClipboardFormat(L"WebKit Smart Paste Format"); + static FORMATETC htmlFormat = {cf, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; + return &htmlFormat; +} PassRefPtr<DocumentFragment> fragmentFromFilenames(Document*, const IDataObject*) { diff --git a/webkit/port/platform/ClipboardUtilitiesWin.h b/webkit/port/platform/ClipboardUtilitiesWin.h index 7cfe569..bc8fb0a 100644 --- a/webkit/port/platform/ClipboardUtilitiesWin.h +++ b/webkit/port/platform/ClipboardUtilitiesWin.h @@ -32,17 +32,25 @@ namespace WebCore { -class CString; -class DeprecatedCString; class Document; class KURL; class String; -HGLOBAL createGlobalData(String str); -HGLOBAL createGlobalData(CString str); +HGLOBAL createGlobalData(const String&); +HGLOBAL createGlobalData(const Vector<char>&); HGLOBAL createGlobalData(const KURL& url, const String& title); -DeprecatedCString markupToCF_HTML(const String& markup, const String& srcURL); +FORMATETC* urlWFormat(); +FORMATETC* urlFormat(); +FORMATETC* plainTextWFormat(); +FORMATETC* plainTextFormat(); +FORMATETC* filenameWFormat(); +FORMATETC* filenameFormat(); +FORMATETC* htmlFormat(); +FORMATETC* cfHDropFormat(); +FORMATETC* smartPasteFormat(); + +void markupToCF_HTML(const String& markup, const String& srcURL, Vector<char>& result); String urlToMarkup(const KURL& url, const String& title); String urlToImageMarkup(const KURL& url, const String& altStr); diff --git a/webkit/port/platform/ClipboardWin.cpp b/webkit/port/platform/ClipboardWin.cpp index a3b83f9..0383610 100644 --- a/webkit/port/platform/ClipboardWin.cpp +++ b/webkit/port/platform/ClipboardWin.cpp @@ -33,9 +33,9 @@ #include "ClipboardUtilitiesWin.h" #include "csshelper.h" #include "CString.h" -#include "DeprecatedString.h" #include "Document.h" #include "DragData.h" +#include "Editor.h" #include "Element.h" #include "EventHandler.h" #include "Frame.h" @@ -52,11 +52,13 @@ #include "Range.h" #include "RenderImage.h" #include "ResourceResponse.h" +#include "StringBuilder.h" #include "StringHash.h" #include "WCDataObject.h" #include <wtf/RefPtr.h> #pragma warning(pop) +#undef LOG #include "base/clipboard_util.h" #include "base/string_util.h" #include "googleurl/src/gurl.h" @@ -133,7 +135,7 @@ static String filesystemPathFromUrlOrTitle(const String& url, const String& titl // The filename for any content based drag should be the last element of // the path. If we can't find it, or we're coming up with the name for a link // we just use the entire url. - KURL kurl(url.deprecatedString()); + KURL kurl(url); String lastComponent; if (!isLink && !(lastComponent = kurl.lastPathComponent()).isEmpty()) { len = min<DWORD>(MAX_PATH - 1, lastComponent.length()); @@ -219,11 +221,10 @@ static HGLOBAL createGlobalHDropContent(const KURL& url, String& fileName, Share WCHAR filePath[MAX_PATH]; if (url.isLocalFile()) { - DeprecatedString path = url.path(); + String localPath = url.path(); // windows does not enjoy a leading slash on paths - if (path[0] == '/') - path = path.mid(1); - String localPath = path.ascii(); + if (localPath[0] == '/') + localPath = localPath.substring(1); LPCTSTR localPathStr = localPath.charactersWithNullTermination(); if (wcslen(localPathStr) + 1 < MAX_PATH) wcscpy_s(filePath, MAX_PATH, localPathStr); @@ -310,6 +311,9 @@ static HGLOBAL createGlobalUrlFileDescriptor(const String& url, const String& ti static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& title, CachedImage* image) { + ASSERT_ARG(image, image); + ASSERT(image->image()->data()); + HRESULT hr = S_OK; HGLOBAL memObj = 0; String fsPath; @@ -323,11 +327,8 @@ static HGLOBAL createGlobalImageFileDescriptor(const String& url, const String& fgd->fgd[0].dwFlags = FD_FILESIZE; fgd->fgd[0].nFileSizeLow = image->image()->data()->size(); - // Note: We fail to get the extension if we're running in the sandbox. - String extension = WebCore::MIMETypeRegistry::getPreferredExtensionForMIMEType( - image->response().mimeType()); - if (!extension.isEmpty()) - extension = "." + extension; + String extension("."); + extension += WebCore::MIMETypeRegistry::getPreferredExtensionForMIMEType(image->response().mimeType()); const String& preferredTitle = title.isEmpty() ? image->response().suggestedFilename() : title; fsPath = filesystemPathFromUrlOrTitle(url, preferredTitle, extension.isEmpty() ? 0 : (TCHAR*)extension.charactersWithNullTermination(), false); @@ -406,14 +407,23 @@ ClipboardWin::~ClipboardWin() { } +PassRefPtr<ClipboardWin> ClipboardWin::create(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy) +{ + return adoptRef(new ClipboardWin(isForDragging, dataObject, policy)); +} + +PassRefPtr<ClipboardWin> ClipboardWin::create(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy) +{ + return adoptRef(new ClipboardWin(isForDragging, dataObject, policy)); +} + static bool writeURL(WCDataObject *data, const KURL& url, String title, bool withPlainText, bool withHTML) { ASSERT(data); - ASSERT(!url.isEmpty()); - - if (!url.isValid()) - return false; + if (url.isEmpty()) + return false; + if (title.isEmpty()) { title = url.lastPathComponent(); if (title.isEmpty()) @@ -431,8 +441,10 @@ static bool writeURL(WCDataObject *data, const KURL& url, String title, bool wit success = true; if (withHTML) { - medium.hGlobal = createGlobalData(markupToCF_HTML(urlToMarkup(url, title), "")); - if (medium.hGlobal && FAILED(data->SetData(ClipboardUtil::GetHtmlFormat(), &medium, TRUE))) + Vector<char> cfhtmlData; + markupToCF_HTML(urlToMarkup(url, title), "", cfhtmlData); + medium.hGlobal = createGlobalData(cfhtmlData); + if (medium.hGlobal && FAILED(data->SetData(htmlFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); else success = true; @@ -516,21 +528,19 @@ String ClipboardWin::getData(const String& type, bool& success) const return ""; } -bool ClipboardWin::setData(const String &type, const String &data) +bool ClipboardWin::setData(const String& type, const String& data) { - //FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941> + // FIXME: Need to be able to write to the system clipboard <rdar://problem/5015941> ASSERT(isForDragging()); if (policy() != ClipboardWritable || !m_writableDataObject) return false; ClipboardDataType winType = clipboardTypeFromMIMEType(type); - if (winType == ClipboardDataTypeURL) { - KURL url = data.deprecatedString(); - if (!url.isValid()) - return false; - return WebCore::writeURL(m_writableDataObject.get(), url, String(), false, true); - } else if ( winType == ClipboardDataTypeText) { + if (winType == ClipboardDataTypeURL) + return WebCore::writeURL(m_writableDataObject.get(), KURL(data), String(), false, true); + + if (winType == ClipboardDataTypeText) { STGMEDIUM medium = {0}; medium.tymed = TYMED_HGLOBAL; medium.hGlobal = createGlobalData(data); @@ -595,10 +605,10 @@ void ClipboardWin::setDragImage(CachedImage* image, Node *node, const IntPoint & return; if (m_dragImage) - m_dragImage->deref(this); + m_dragImage->removeClient(this); m_dragImage = image; if (m_dragImage) - m_dragImage->ref(this); + m_dragImage->addClient(this); m_dragLoc = loc; m_dragImageElement = node; @@ -627,7 +637,8 @@ DragImageRef ClipboardWin::createDragImage(IntPoint& loc) const static String imageToMarkup(const String& url, Element* element) { - String markup("<img src=\""); + StringBuilder markup; + markup.append("<img src=\""); markup.append(url); markup.append("\""); // Copy over attributes. If we are dragging an image, we expect things like @@ -641,12 +652,14 @@ static String imageToMarkup(const String& url, Element* element) markup.append(" "); markup.append(attr->localName()); markup.append("=\""); - markup.append(attr->value().deprecatedString().replace("\"", """)); + String escapedAttr = attr->value(); + escapedAttr.replace("\"", """); + markup.append(escapedAttr); markup.append("\""); } markup.append("/>"); - return markup; + return markup.toString(); } static CachedImage* getCachedImage(Element* element) @@ -672,7 +685,7 @@ static void writeImageToDataObject(IDataObject* dataObject, Element* element, co return; SharedBuffer* imageBuffer = cachedImage->image()->data(); - if (!imageBuffer->size()) + if (!imageBuffer || !imageBuffer->size()) return; HGLOBAL imageFileDescriptor = createGlobalImageFileDescriptor(url.string(), element->getAttribute(altAttr), cachedImage); @@ -691,8 +704,6 @@ static void writeImageToDataObject(IDataObject* dataObject, Element* element, co HGLOBAL hDropContent = createGlobalHDropContent(url, fileName, imageBuffer); writeFileToDataObject(dataObject, imageFileDescriptor, imageFileContent, hDropContent); - // TODO(tc): Also write the mime type to the dataObject so we can - // fix the filename once we're back in the browser process. } void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, const String& title, Frame* frame) @@ -716,8 +727,10 @@ void ClipboardWin::declareAndWriteDragImage(Element* element, const KURL& url, c ExceptionCode ec = 0; // Put img tag on the clipboard referencing the image - medium.hGlobal = createGlobalData(markupToCF_HTML(imageToMarkup(fullURL, element), "")); - if (medium.hGlobal && FAILED(m_writableDataObject->SetData(ClipboardUtil::GetHtmlFormat(), &medium, TRUE))) + Vector<char> data; + markupToCF_HTML(imageToMarkup(fullURL, element), "", data); + medium.hGlobal = createGlobalData(data); + if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); } @@ -751,16 +764,23 @@ void ClipboardWin::writeRange(Range* selectedRange, Frame* frame) medium.tymed = TYMED_HGLOBAL; ExceptionCode ec = 0; - medium.hGlobal = createGlobalData(markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), selectedRange->startContainer(ec)->document()->url())); - if (medium.hGlobal && FAILED(m_writableDataObject->SetData(ClipboardUtil::GetHtmlFormat(), &medium, TRUE))) + Vector<char> data; + markupToCF_HTML(createMarkup(selectedRange, 0, AnnotateForInterchange), + selectedRange->startContainer(ec)->document()->url().string(), data); + medium.hGlobal = createGlobalData(data); + if (medium.hGlobal && FAILED(m_writableDataObject->SetData(htmlFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); String str = frame->selectedText(); replaceNewlinesWithWindowsStyleNewlines(str); replaceNBSPWithSpace(str); medium.hGlobal = createGlobalData(str); - if (medium.hGlobal && FAILED(m_writableDataObject->SetData(ClipboardUtil::GetPlainTextWFormat(), &medium, TRUE))) + if (medium.hGlobal && FAILED(m_writableDataObject->SetData(plainTextWFormat(), &medium, TRUE))) ::GlobalFree(medium.hGlobal); + + medium.hGlobal = 0; + if (frame->editor()->canSmartCopyOrDelete()) + m_writableDataObject->SetData(smartPasteFormat(), &medium, TRUE); } bool ClipboardWin::hasData() diff --git a/webkit/port/platform/ClipboardWin.h b/webkit/port/platform/ClipboardWin.h index 0d6e448..a52c242 100644 --- a/webkit/port/platform/ClipboardWin.h +++ b/webkit/port/platform/ClipboardWin.h @@ -43,9 +43,10 @@ namespace WebCore { // State available during IE's events for drag and drop and copy/paste class ClipboardWin : public Clipboard, public CachedResourceClient { public: - ClipboardWin(bool isForDragging, IDataObject* dataObject, ClipboardAccessPolicy policy); - ClipboardWin(bool isForDragging, WCDataObject* dataObject, ClipboardAccessPolicy policy); ~ClipboardWin(); + + static PassRefPtr<ClipboardWin> create(bool isForDragging, IDataObject*, ClipboardAccessPolicy); + static PassRefPtr<ClipboardWin> create(bool isForDragging, WCDataObject*, ClipboardAccessPolicy); void clearData(const String& type); void clearAllData(); @@ -67,6 +68,9 @@ namespace WebCore { COMPtr<IDataObject> dataObject() { return m_dataObject; } private: + ClipboardWin(bool isForDragging, IDataObject*, ClipboardAccessPolicy); + ClipboardWin(bool isForDragging, WCDataObject*, ClipboardAccessPolicy); + void resetFromClipboard(); void setDragImage(CachedImage*, Node*, const IntPoint&); COMPtr<IDataObject> m_dataObject; diff --git a/webkit/port/platform/Cursor.h b/webkit/port/platform/Cursor.h index 7dd4700..c976ea9 100644 --- a/webkit/port/platform/Cursor.h +++ b/webkit/port/platform/Cursor.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2006, 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 @@ -27,11 +27,14 @@ #define Cursor_h #include <wtf/Platform.h> -#include "webkit/glue/webcursor.h" #if PLATFORM(WIN) +#include "webkit/glue/webcursor.h" typedef struct HICON__* HICON; typedef HICON HCURSOR; +#include <wtf/PassRefPtr.h> +#include <wtf/RefCounted.h> +#include <wtf/RefPtr.h> #elif PLATFORM(GTK) #include <gdk/gdk.h> #elif PLATFORM(QT) @@ -46,6 +49,10 @@ class NSCursor; #endif #endif +#if PLATFORM(WX) +class wxCursor; +#endif + namespace WebCore { class Image; @@ -59,6 +66,8 @@ namespace WebCore { typedef GdkCursor* PlatformCursor; #elif PLATFORM(QT) && !defined(QT_NO_CURSOR) typedef QCursor PlatformCursor; +#elif PLATFORM(WX) + typedef wxCursor* PlatformCursor; #else typedef void* PlatformCursor; #endif @@ -66,14 +75,10 @@ namespace WebCore { class Cursor { public: Cursor() -#if !PLATFORM(QT) - : m_impl(WebCursor::ARROW) -#endif { } Cursor(Image*, const IntPoint& hotspot); Cursor(const Cursor&); - ~Cursor(); Cursor& operator=(const Cursor&); @@ -81,7 +86,7 @@ namespace WebCore { PlatformCursor impl() const { return m_impl; } private: - WebCursor m_impl; + PlatformCursor m_impl; }; const Cursor& pointerCursor(); @@ -105,6 +110,15 @@ namespace WebCore { const Cursor& northWestSouthEastResizeCursor(); const Cursor& columnResizeCursor(); const Cursor& rowResizeCursor(); + const Cursor& middlePanningCursor(); + const Cursor& eastPanningCursor(); + const Cursor& northPanningCursor(); + const Cursor& northEastPanningCursor(); + const Cursor& northWestPanningCursor(); + const Cursor& southPanningCursor(); + const Cursor& southEastPanningCursor(); + const Cursor& southWestPanningCursor(); + const Cursor& westPanningCursor(); const Cursor& verticalTextCursor(); const Cursor& cellCursor(); const Cursor& contextMenuCursor(); diff --git a/webkit/port/platform/CursorWin.cpp b/webkit/port/platform/CursorWin.cpp index e5b31eb..884c464d 100644 --- a/webkit/port/platform/CursorWin.cpp +++ b/webkit/port/platform/CursorWin.cpp @@ -29,7 +29,10 @@ #include "Image.h" #include "IntPoint.h" #include "NativeImageSkia.h" +#include "NotImplemented.h" + #include "webkit/glue/webkit_resources.h" +#include "webkit/glue/webkit_glue.h" #define ALPHA_CURSORS @@ -42,14 +45,15 @@ Cursor::Cursor(const Cursor& other) Cursor::Cursor(Image* img, const IntPoint& hotspot) { - // If we don't have a valid bitmap, then fallback to the default - // cursor (ARROW). - NativeImageSkia* bitmap = img->getBitmap(); - if (bitmap) { + // If we don't have a valid bitmap, then fallback to the default + // cursor (ARROW). + NativeImageSkia* bitmap = img->nativeImageForCurrentFrame(); + if (!bitmap) + return; + m_impl.set_type(WebCursor::CUSTOM); m_impl.set_hotspot(hotspot.x(), hotspot.y()); m_impl.set_bitmap(*bitmap); - } } Cursor::~Cursor() @@ -187,6 +191,69 @@ const Cursor& rowResizeCursor() return c; } +const Cursor& middlePanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_MIDDLE); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& eastPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_EAST); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& northPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_NORTH); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& northEastPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_NORTH_EAST); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& northWestPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_NORTH_WEST); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& southPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_SOUTH); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& southEastPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_SOUTH_EAST); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& southWestPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_SOUTH_WEST); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + +const Cursor& westPanningCursor() +{ + SkBitmap* bitmap = webkit_glue::GetBitmapResource(IDC_PAN_WEST); + static Cursor c = WebCursor(bitmap, 7, 7); + return c; +} + const Cursor& moveCursor() { static Cursor c = WebCursor::SIZEALL; diff --git a/webkit/port/platform/DragDataWin.cpp b/webkit/port/platform/DragDataWin.cpp index 6a374b8..8deca48 100644 --- a/webkit/port/platform/DragDataWin.cpp +++ b/webkit/port/platform/DragDataWin.cpp @@ -37,6 +37,7 @@ #include "Markup.h" #include "WCDataObject.h" +#undef LOG #include "base/file_util.h" #include "base/string_util.h" #include "net/base/base64.h" @@ -62,16 +63,16 @@ WebDropData* dropData(DragDataRef dragData) { namespace WebCore { -Clipboard* DragData::createClipboard(ClipboardAccessPolicy policy) const +PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const { WCDataObject* data; WCDataObject::createInstance(&data); - ClipboardWin* clipboard = new ClipboardWin(true, data, policy); + RefPtr<ClipboardWin> clipboard = ClipboardWin::create(true, data, policy); // The clipboard keeps a reference to the WCDataObject, so we can release // our reference to it. data->Release(); - return clipboard; + return clipboard.release(); } bool DragData::containsURL() const diff --git a/webkit/port/platform/EditorWin.cpp b/webkit/port/platform/EditorWin.cpp index 8839f42..8ffcf9a 100644 --- a/webkit/port/platform/EditorWin.cpp +++ b/webkit/port/platform/EditorWin.cpp @@ -46,7 +46,7 @@ PassRefPtr<Clipboard> Editor::newGeneralClipboard(ClipboardAccessPolicy policy) if (!SUCCEEDED(OleGetClipboard(&clipboardData))) clipboardData = 0; - return new ClipboardWin(false, clipboardData.get(), policy); + return ClipboardWin::create(false, clipboardData.get(), policy); } } // namespace WebCore diff --git a/webkit/port/platform/FileChooserWin.cpp b/webkit/port/platform/FileChooserWin.cpp index 96ef4e4..8497372 100644 --- a/webkit/port/platform/FileChooserWin.cpp +++ b/webkit/port/platform/FileChooserWin.cpp @@ -39,17 +39,6 @@ namespace WebCore { -FileChooser::FileChooser(FileChooserClient* client, const String& filename) - : m_client(client) - , m_filename(filename) - , m_icon(chooseIcon(filename)) -{ -} - -FileChooser::~FileChooser() -{ -} - void FileChooser::openFileChooser(Document* document) { Frame* frame = document->frame(); diff --git a/webkit/port/platform/GKURL.cpp b/webkit/port/platform/GKURL.cpp index bf71fda..f809109 100644 --- a/webkit/port/platform/GKURL.cpp +++ b/webkit/port/platform/GKURL.cpp @@ -35,21 +35,17 @@ #ifdef USE_GOOGLE_URL_LIBRARY +#undef LOG #include "base/string_util.h" #include "googleurl/src/url_canon_internal.h" #include "googleurl/src/url_util.h" +using namespace WTF; + namespace WebCore { namespace { -// For getting the UTF-16 wchar_t pointer out of a DeprecatedString, which -// uses weird character types that happen to be the same as a wchar_t. -const wchar_t* UnicodeForString(const DeprecatedString& s) -{ - return reinterpret_cast<const wchar_t*>(s.unicode()); -} - // Wraps WebKit's text encoding in a character set converter for the // canonicalizer. class WebCoreCharsetConverter : public url_canon::CharsetConverter { @@ -63,10 +59,7 @@ public: virtual void ConvertFromUTF16(const url_parse::UTF16Char* input, int input_len, url_canon::CanonOutput* output) { - // When we merge to WebCore > r31089, this call should change into: - // CString encoded = m_encoding.encode(inupt, input_len, - // URLEncodedEntitiesForUnencodables); - CString encoded = m_encoding->encode(input, input_len); + CString encoded = m_encoding->encode(input, input_len, URLEncodedEntitiesForUnencodables); output->Append(encoded.data(), static_cast<int>(encoded.length())); } @@ -74,6 +67,30 @@ private: const TextEncoding* m_encoding; }; +// Note that this function must be named differently than the one in KURL.cpp +// since our unit tests evilly include both files, and their local definition +// will be ambiguous. +inline void AssertProtocolIsGood(const char* protocol) +{ +#ifndef NDEBUG + const char* p = protocol; + while (*p) { + ASSERT(*p > ' ' && *p < 0x7F && !(*p >= 'A' && *p <= 'Z')); + ++p; + } +#endif +} + +// Returns the characters for the given string, or a pointer to a static empty +// string if the input string is NULL. This will always ensure we have a non- +// NULL character pointer since ReplaceComponents has special meaning for NULL. +inline const url_parse::UTF16Char* CharactersOrEmpty(const String& str) { + static const url_parse::UTF16Char zero = 0; + return str.characters() ? + reinterpret_cast<const url_parse::UTF16Char*>(str.characters()) : + &zero; +} + } // namespace // KURL::URLString ------------------------------------------------------------- @@ -81,7 +98,6 @@ private: KURL::URLString::URLString() : m_utf8IsASCII(true) , m_stringIsValid(false) - , m_deprecatedStringIsValid(false) { } @@ -104,14 +120,12 @@ void KURL::URLString::setUtf8(const char* data, int data_len) m_utf8 = CString(data, data_len); m_stringIsValid = false; - m_deprecatedStringIsValid = false; } void KURL::URLString::setAscii(const char* data, int data_len) { m_utf8 = CString(data, data_len); m_utf8IsASCII = true; m_stringIsValid = false; - m_deprecatedStringIsValid = false; } const String& KURL::URLString::string() const @@ -131,38 +145,8 @@ const String& KURL::URLString::string() const return m_string; } -const DeprecatedString KURL::URLString::deprecatedString() const -{ - if (!m_deprecatedStringIsValid) { - // Must special case the NULL case, since constructing the - // string like we do below will generate an empty rather than - // a NULL string. - if (m_utf8.isNull()) { - m_deprecatedString = DeprecatedString(); - } else if (m_utf8IsASCII) { - // This is not just an optimization. equalIgnoringCase will - // treat two strings as different if their 8/16-bitedness - // doesn't match, even if a conversion would make them match. - m_deprecatedString = DeprecatedString(m_utf8.data(), - m_utf8.length()); - } else { - // DeprecatedString has a fromUTF8 function, but internally - // it will convert to a string! We use this opportunity to - // re-use the old String conversion or save the new one - // to our cache. - m_deprecatedString = string().deprecatedString(); - } - m_deprecatedStringIsValid = true; - } - return m_deprecatedString; -} - // KURL ------------------------------------------------------------------------ -KURL::KURL() : m_isValid(false) -{ -} - // Creates with NULL-terminated string input representing an absolute URL. // WebCore generally calls this only with hardcoded strings, so the input is // ASCII. We treat is as UTF-8 just in case. @@ -184,31 +168,21 @@ KURL::KURL(const char *url) // to a string and then converted back. In this case, the URL is already // canonical and in proper escaped form so needs no encoding. We treat it was // UTF-8 just in case. -KURL::KURL(const DeprecatedString& url) -{ - init(KURL(), url, NULL); - - if (m_url.utf8String().isNull()) { - // See FIXME above. - // - // Bug-for-bug KURL compatibility for WebKit bug: - // http://bugs.webkit.org/show_bug.cgi?id=16487 - // - // URLs created with NULL depricated strings should be changed to be - // empty rather than NULL. This masks some crashes in WebKit. This - // special case should be removed when we bring in a WebKit version - // newer than r31089 which fixes - // http://bugs.webkit.org/show_bug.cgi?id=16485 - // - // This extends to any DeprecatedString, even if it is invalid, and even - // though KURL(KURL(), <same string>) would give a NULL string. Gaa! - m_url.setUtf8("", 0); +KURL::KURL(const String& url) +{ + if (!url.isNull()) { + init(KURL(), url, NULL); + } else { + // WebKit expects us to preserve the nullness of strings when this + // constructor is used. In all other cases, it expects a non-null + // empty string, which is what init() will create. + m_isValid = false; } } // Constructs a new URL given a base URL and a possibly relative input URL. // This assumes UTF-8 encoding. -KURL::KURL(const KURL& base, const DeprecatedString& relative) +KURL::KURL(const KURL& base, const String& relative) { init(base, relative, NULL); } @@ -216,7 +190,7 @@ KURL::KURL(const KURL& base, const DeprecatedString& relative) // Constructs a new URL given a base URL and a possibly relative input URL. // Any query portion of the relative URL will be encoded in the given encoding. KURL::KURL(const KURL& base, - const DeprecatedString& relative, + const String& relative, const TextEncoding& encoding) { init(base, relative, &encoding); @@ -235,10 +209,15 @@ KURL::KURL(const char* canonical_spec, int canonical_spec_len, m_url.setAscii(canonical_spec, canonical_spec_len); } -DeprecatedString KURL::componentString(const url_parse::Component& comp) const +String KURL::componentString(const url_parse::Component& comp) const { - if (!m_isValid || comp.len <= 0) - return DeprecatedString(); + if (!m_isValid || comp.len <= 0) { + // KURL returns a NULL string if the URL is itself a NULL string, and an + // empty string for other nonexistant entities. + if (isNull()) + return String(); + return String("", 0); + } // begin and len are in terms of bytes which do not match // if urlString is UTF-16 and input contains non-ASCII characters. // However, the only part in urlString that can contain non-ASCII @@ -247,40 +226,20 @@ DeprecatedString KURL::componentString(const url_parse::Component& comp) const // byte) will be longer than what's needed by 'mid'. However, mid // truncates len to avoid go past the end of a string so that we can // get away withtout doing anything here. - return m_url.deprecatedString().mid(comp.begin, comp.len); + return m_url.string().substring(comp.begin, comp.len); } void KURL::init(const KURL& base, - const DeprecatedString& relative, + const String& relative, const TextEncoding* query_encoding) { - if (relative.hasFastLatin1()) { - // Use the UTF-8 version when possible. This probably means that the - // URL is all ASCII already, so we can run faster. - init(base, relative.ascii(), relative.length(), query_encoding); - } else { - init(base, reinterpret_cast<const UChar*>(relative.unicode()), - relative.length(), query_encoding); - } + init(base, relative.characters(), relative.length(), query_encoding); } // Note: code mostly duplicated below. void KURL::init(const KURL& base, const char* rel, int rel_len, const TextEncoding* query_encoding) { - // Resolving an empty string on the original URL should return the original. - // This will be handled by the relative URL resolver below, of course, but - // it will not preserve the isNull()ness of the source URL, so we special - // case it here. - // - // Note that resolving a string with just whitespace on am empty URL will - // not preserve the isNullness since this case won't get triggered, but this - // seems like it will be OK. - if (rel_len == 0) { - *this = base; - return; - } - // As a performance optimization, we only use the charset converter if the // encoding is not UTF-8. The URL canonicalizer will be more efficient with // no charset converter object because it can do UTF-8 internally with no @@ -314,6 +273,9 @@ void KURL::init(const KURL& base, const char* rel, int rel_len, m_url.setUtf8(output.data(), output.length()); else m_url.setAscii(output.data(), output.length()); + } else { + // WebKit expects resolved URLs to be empty rather than NULL. + m_url.setUtf8("", 0); } } @@ -321,11 +283,6 @@ void KURL::init(const KURL& base, const char* rel, int rel_len, void KURL::init(const KURL& base, const UChar* rel, int rel_len, const TextEncoding* query_encoding) { - if (rel_len == 0) { - *this = base; - return; - } - WebCoreCharsetConverter charset_converter_object(query_encoding); WebCoreCharsetConverter* charset_converter = (!query_encoding || *query_encoding == UTF8Encoding()) ? 0 : @@ -343,6 +300,8 @@ void KURL::init(const KURL& base, const UChar* rel, int rel_len, m_url.setUtf8(output.data(), output.length()); else m_url.setAscii(output.data(), output.length()); + } else { + m_url.setUtf8("", 0); } } @@ -355,7 +314,7 @@ bool KURL::hasPath() const // We handle "parameters" separated be a semicolon, while the old KURL does // not, which can lead to different results in some cases. -DeprecatedString KURL::lastPathComponent() const +String KURL::lastPathComponent() const { // When the output ends in a slash, WebKit has different expectations than // our library. For "/foo/bar/" the library will return the empty string, @@ -366,15 +325,20 @@ DeprecatedString KURL::lastPathComponent() const url_parse::Component file; url_parse::ExtractFileName(m_url.utf8String().data(), path, &file); + + // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns + // a null string when the path is empty, which we duplicate here. + if (!file.is_nonempty()) + return String(); return componentString(file); } -DeprecatedString KURL::protocol() const +String KURL::protocol() const { return componentString(m_parsed.scheme); } -DeprecatedString KURL::host() const +String KURL::host() const { // Note: WebKit decode_string()s here. return componentString(m_parsed.host); @@ -396,21 +360,32 @@ unsigned short int KURL::port() const } // Returns the empty string if there is no password. -DeprecatedString KURL::pass() const +String KURL::pass() const { + // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns + // a null string when the password is empty, which we duplicate here. + if (!m_parsed.password.is_nonempty()) + return String(); + // Note: WebKit decode_string()s here. return componentString(m_parsed.password); } // Returns the empty string if there is no username. -DeprecatedString KURL::user() const +String KURL::user() const { // Note: WebKit decode_string()s here. return componentString(m_parsed.username); } -DeprecatedString KURL::ref() const +String KURL::ref() const { + // Empty but present refs ("foo.com/bar#") should result in the empty + // string, which componentString will produce. Nonexistant refs should be + // the NULL string. + if (!m_parsed.ref.is_valid()) + return String(); + // Note: WebKit decode_string()s here. return componentString(m_parsed.ref); } @@ -422,7 +397,7 @@ bool KURL::hasRef() const return m_parsed.ref.len >= 0; } -DeprecatedString KURL::query() const +String KURL::query() const { if (m_parsed.query.len >= 0) { // KURL's query() includes the question mark, even though the reference @@ -433,49 +408,50 @@ DeprecatedString KURL::query() const query_comp.len++; return componentString(query_comp); } - return DeprecatedString(); + + // Bug: https://bugs.webkit.org/show_bug.cgi?id=21015 this function returns + // an empty string when the query is empty rather than a null (not sure + // which is right). + return String("", 0); } -DeprecatedString KURL::path() const +String KURL::path() const { // Note: WebKit decode_string()s here. return componentString(m_parsed.path); } -void KURL::setProtocol(const DeprecatedString& protocol) +void KURL::setProtocol(const String& protocol) { Replacements replacements; - replacements.SetScheme( - reinterpret_cast<const wchar_t*>(protocol.unicode()), - url_parse::Component(0, protocol.length())); + replacements.SetScheme(CharactersOrEmpty(protocol), + url_parse::Component(0, protocol.length())); replaceComponents(replacements); } -void KURL::setHost(const DeprecatedString& host) +void KURL::setHost(const String& host) { Replacements replacements; - replacements.SetHost( - reinterpret_cast<const wchar_t*>(host.unicode()), - url_parse::Component(0, host.length())); + replacements.SetHost(CharactersOrEmpty(host), + url_parse::Component(0, host.length())); replaceComponents(replacements); } -// This function is used only in the KJS build. -void KURL::setHostAndPort(const DeprecatedString& s) { - DeprecatedString newhost = s.left(s.find(":")); - DeprecatedString newport = s.mid(s.find(":") + 1); +// This function is used only in the JSC build. +void KURL::setHostAndPort(const String& s) { + String newhost = s.left(s.find(":")); + String newport = s.substring(s.find(":") + 1); Replacements replacements; - replacements.SetHost( // Host can't be removed, so we always set. - reinterpret_cast<const wchar_t*>(newhost.unicode()), - url_parse::Component(0, newhost.length())); + // Host can't be removed, so we always set. + replacements.SetHost(CharactersOrEmpty(newhost), + url_parse::Component(0, newhost.length())); if (newport.isEmpty()) { // Port may be removed, so we support clearing. replacements.ClearPort(); } else { - replacements.SetPort( - reinterpret_cast<const wchar_t*>(newport.unicode()), - url_parse::Component(0, newport.length())); + replacements.SetPort(CharactersOrEmpty(newport), + url_parse::Component(0, newport.length())); } replaceComponents(replacements); } @@ -483,11 +459,11 @@ void KURL::setHostAndPort(const DeprecatedString& s) { void KURL::setPort(unsigned short i) { Replacements replacements; - DeprecatedString portStr; + String portStr; if (i > 0) { - portStr = DeprecatedString::number(static_cast<int>(i)); + portStr = String::number(static_cast<int>(i)); replacements.SetPort( - reinterpret_cast<const wchar_t*>(portStr.unicode()), + reinterpret_cast<const wchar_t*>(portStr.characters()), url_parse::Component(0, portStr.length())); } else { @@ -497,7 +473,7 @@ void KURL::setPort(unsigned short i) replaceComponents(replacements); } -void KURL::setUser(const DeprecatedString& user) +void KURL::setUser(const String& user) { // This function is commonly called to clear the username, which we // normally don't have, so we optimize this case. @@ -507,13 +483,12 @@ void KURL::setUser(const DeprecatedString& user) // The canonicalizer will clear any usernames that are empty, so we // don't have to explicitly call ClearUsername() here. Replacements replacements; - replacements.SetUsername( - reinterpret_cast<const wchar_t*>(user.unicode()), - url_parse::Component(0, user.length())); + replacements.SetUsername(CharactersOrEmpty(user), + url_parse::Component(0, user.length())); replaceComponents(replacements); } -void KURL::setPass(const DeprecatedString& pass) +void KURL::setPass(const String& pass) { // This function is commonly called to clear the password, which we // normally don't have, so we optimize this case. @@ -523,13 +498,12 @@ void KURL::setPass(const DeprecatedString& pass) // The canonicalizer will clear any passwords that are empty, so we // don't have to explicitly call ClearUsername() here. Replacements replacements; - replacements.SetPassword( - reinterpret_cast<const wchar_t*>(pass.unicode()), - url_parse::Component(0, pass.length())); + replacements.SetPassword(CharactersOrEmpty(pass), + url_parse::Component(0, pass.length())); replaceComponents(replacements); } -void KURL::setRef(const DeprecatedString& ref) +void KURL::setRef(const String& ref) { // This function is commonly called to clear the ref, which we // normally don't have, so we optimize this case. @@ -540,57 +514,92 @@ void KURL::setRef(const DeprecatedString& ref) if (ref.isNull()) { replacements.ClearRef(); } else { - replacements.SetRef( - reinterpret_cast<const wchar_t*>(ref.unicode()), - url_parse::Component(0, ref.length())); + replacements.SetRef(CharactersOrEmpty(ref), + url_parse::Component(0, ref.length())); } replaceComponents(replacements); } -void KURL::setQuery(const DeprecatedString& query) +void KURL::removeRef() +{ + Replacements replacements; + replacements.ClearRef(); + replaceComponents(replacements); +} + +void KURL::setQuery(const String& query) { Replacements replacements; if (query.isNull()) { // WebKit sets to NULL to clear any query. replacements.ClearQuery(); - } else if (query.length() > 0 && query.ascii()[0] == '?') { + } else if (query.length() > 0 && query[0] == '?') { // WebKit expects the query string to begin with a question mark, but // our library doesn't. So we trim off the question mark when setting. - replacements.SetQuery( - reinterpret_cast<const wchar_t*>(query.unicode()), - url_parse::Component(1, query.length() - 1)); + replacements.SetQuery(CharactersOrEmpty(query), + url_parse::Component(1, query.length() - 1)); } else { // When set with the empty string or something that doesn't begin with // a question mark, WebKit will add a question mark for you. The only // way this isn't compatible is if you call this function with an empty // string. Old KURL will leave a '?' with nothing following it in the // URL, whereas we'll clear it. - replacements.SetQuery( - reinterpret_cast<const wchar_t*>(query.unicode()), - url_parse::Component(0, query.length())); + replacements.SetQuery(CharactersOrEmpty(query), + url_parse::Component(0, query.length())); } replaceComponents(replacements); } -void KURL::setPath(const DeprecatedString& path) +void KURL::setPath(const String& path) { // Empty paths will be canonicalized to "/", so we don't have to worry // about calling ClearPath(). Replacements replacements; - replacements.SetPath( - reinterpret_cast<const wchar_t*>(path.unicode()), - url_parse::Component(0, path.length())); + replacements.SetPath(CharactersOrEmpty(path), + url_parse::Component(0, path.length())); replaceComponents(replacements); } // On Mac, this just seems to return the same URL, but with "/foo/bar" for // file: URLs instead of file:///foo/bar. We don't bother with any of this, // at least for now. -DeprecatedString KURL::prettyURL() const +String KURL::prettyURL() const { if (!m_isValid) - return DeprecatedString(); - return m_url.deprecatedString(); + return String(); + return m_url.string(); +} + +// Copy the KURL version here on Sept 12, 2008 while doing the webkit merge. +// +// TODO(erg): Somehow share this with KURL? Like we'd theoretically merge +// with decodeURLEscapeSequences below? +#ifdef KURL_DECORATE_GLOBALS +String KURL::mimeTypeFromDataURL(const String& url) +#else +String mimeTypeFromDataURL(const String& url) +#endif +{ + ASSERT(protocolIs(url, "data")); + int index = url.find(';'); + if (index == -1) + index = url.find(','); + if (index != -1) { + int len = index - 5; + if (len > 0) + return url.substring(5, len); + return "text/plain"; // Data URLs with no MIME type are considered text/plain. + } + return ""; +} + +#ifdef KURL_DECORATE_GLOBALS +String KURL::decodeURLEscapeSequences(const String& str) +#else +String decodeURLEscapeSequences(const String& str) +#endif +{ + return decodeURLEscapeSequences(str, UTF8Encoding()); } // In WebKit's implementation, this is called by every component getter. @@ -605,14 +614,28 @@ DeprecatedString KURL::prettyURL() const // IE doesn't unescape %00, forcing you to use \x00 in JS strings, so we do // the same. This also eliminates NULL-related problems should a consumer // incorrectly call this function for non-JavaScript. -DeprecatedString KURL::decode_string(const DeprecatedString& urlString) +// +// TODO(brettw) these should be merged to the regular KURL implementation. +#ifdef KURL_DECORATE_GLOBALS +String KURL::decodeURLEscapeSequences(const String& str, const TextEncoding& encoding) +#else +String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding) +#endif { - // First unescape all input. WebKit's implementation seems to assume the - // input is 8-bit, so we do as well. - ASSERT(urlString.isAllLatin1()); - - const char* input = urlString.latin1(); - int input_length = urlString.length(); + // TODO(brettw) We can probably use KURL's version of this function + // without modification. However, I'm concerned about + // https://bugs.webkit.org/show_bug.cgi?id=20559 so am keeping this old + // custom code for now. Using their version will also fix the bug that + // we ignore the encoding. + // + // TODO(brettw) bug 1350291: This does not get called very often. We just + // convert first to 8-bit UTF-8, then unescape, then back to 16-bit. This + // kind of sucks, and we don't use the encoding properly, which will make + // some obscure anchor navigations fail. + CString cstr = str.utf8(); + + const char* input = cstr.data(); + int input_length = cstr.length(); url_canon::RawCanonOutputT<char> unescaped; for (int i = 0; i < input_length; i++) { if (input[i] == '%') { @@ -631,7 +654,7 @@ DeprecatedString KURL::decode_string(const DeprecatedString& urlString) unescaped.push_back('%'); } } else { - // Regular non-escaped character. + // Regular non-escaped 8-bit character. unescaped.push_back(input[i]); } } @@ -668,17 +691,10 @@ DeprecatedString KURL::decode_string(const DeprecatedString& urlString) } } - return DeprecatedString(reinterpret_cast<DeprecatedChar*>(utf16.data()), + return String(reinterpret_cast<UChar*>(utf16.data()), utf16.length()); } -// The encoding parameter to this function is currently never used. -DeprecatedString KURL::decode_string(const DeprecatedString& urlString, - const TextEncoding& encoding) -{ - return decode_string(urlString); -} - void KURL::replaceComponents(const Replacements& replacements) { url_canon::RawCanonOutputT<char> output; @@ -694,19 +710,20 @@ void KURL::replaceComponents(const Replacements& replacements) m_url.setAscii(output.data(), output.length()); } -bool KURL::schemeIs(const char* lower_ascii_scheme) const +bool KURL::protocolIs(const char* protocol) const { + AssertProtocolIsGood(protocol); if (m_parsed.scheme.len <= 0) - return lower_ascii_scheme == NULL; + return protocol == NULL; return LowerCaseEqualsASCII( m_url.utf8String().data() + m_parsed.scheme.begin, m_url.utf8String().data() + m_parsed.scheme.end(), - lower_ascii_scheme); + protocol); } bool KURL::isLocalFile() const { - return schemeIs("file"); + return protocolIs("file"); } // This is called to escape a URL string. It is only used externally when @@ -718,11 +735,16 @@ bool KURL::isLocalFile() const // ways, and may expect to get a valid URL string. The dangerous thing we want // to protect against here is accidentally getting NULLs in a string that is // not supposed to have NULLs. Therefore, we escape NULLs here to prevent this. -DeprecatedString KURL::encode_string(const DeprecatedString& notEncodedString) +#ifdef KURL_DECORATE_GLOBALS +String KURL::encodeWithURLEscapeSequences(const String& notEncodedString) +#else +String encodeWithURLEscapeSequences(const String& notEncodedString) +#endif { CString utf8 = UTF8Encoding().encode( - reinterpret_cast<const UChar*>(notEncodedString.unicode()), - notEncodedString.length()); + reinterpret_cast<const UChar*>(notEncodedString.characters()), + notEncodedString.length(), + URLEncodedEntitiesForUnencodables); const char* input = utf8.data(); int input_len = utf8.length(); @@ -733,7 +755,7 @@ DeprecatedString KURL::encode_string(const DeprecatedString& notEncodedString) else buffer.append(input[i]); } - return DeprecatedString(buffer.data(), buffer.size()); + return String(buffer.data(), buffer.size()); } bool KURL::isHierarchical() const @@ -753,9 +775,11 @@ void KURL::print() const } #endif -bool operator==(const KURL &a, const KURL &b) +void KURL::invalidate() { - return a.m_url.utf8String() == b.m_url.utf8String(); + // This is only called from the constructor so resetting the (automatically + // initialized) string and parsed structure would be a waste of time. + m_isValid = false; } // Equal up to reference fragments, if any. @@ -776,6 +800,71 @@ bool equalIgnoringRef(const KURL& a, const KURL& b) strncmp(a.m_url.utf8String().data(), b.m_url.utf8String().data(), a_len) == 0; } +unsigned KURL::hostStart() const +{ + return m_parsed.CountCharactersBefore(url_parse::Parsed::HOST, false); +} + +unsigned KURL::hostEnd() const +{ + return m_parsed.CountCharactersBefore(url_parse::Parsed::PORT, true); +} + +unsigned KURL::pathStart() const +{ + return m_parsed.CountCharactersBefore(url_parse::Parsed::PATH, false); +} + +unsigned KURL::pathEnd() const +{ + return m_parsed.CountCharactersBefore(url_parse::Parsed::QUERY, true); +} + +unsigned KURL::pathAfterLastSlash() const +{ + // When there's no path, ask for what would be the beginning of it. + if (!m_parsed.path.is_valid()) + return m_parsed.CountCharactersBefore(url_parse::Parsed::PATH, false); + + url_parse::Component filename; + url_parse::ExtractFileName(m_url.utf8String().data(), m_parsed.path, + &filename); + return filename.begin; +} + +#ifdef KURL_DECORATE_GLOBALS +const KURL& KURL::blankURL() +#else +const KURL& blankURL() +#endif +{ + static KURL staticBlankURL("about:blank"); + return staticBlankURL; +} + +#ifdef KURL_DECORATE_GLOBALS +bool KURL::protocolIs(const String& url, const char* protocol) +#else +bool protocolIs(const String& url, const char* protocol) +#endif +{ + // Do the comparison without making a new string object. + AssertProtocolIsGood(protocol); + for (int i = 0; ; ++i) { + if (!protocol[i]) + return url[i] == ':'; + if (toASCIILower(url[i]) != protocol[i]) + return false; + } +} + +#ifndef KURL_DECORATE_GLOBALS +inline bool KURL::protocolIs(const String& string, const char* protocol) +{ + return WebCore::protocolIs(string, protocol); +} +#endif + } // namespace WebCore #endif // USE_GOOGLE_URL_LIBRARY diff --git a/webkit/port/platform/GKURL_unittest.cpp b/webkit/port/platform/GKURL_unittest.cpp index 5f525d1..46c91e8 100644 --- a/webkit/port/platform/GKURL_unittest.cpp +++ b/webkit/port/platform/GKURL_unittest.cpp @@ -46,6 +46,8 @@ // This evil preprocessor hack allows us to run both the original KURL and our // KURL code at the same time regardless of build options. +#define KURL_DECORATE_GLOBALS + // Old KURL #undef USE_GOOGLE_URL_LIBRARY #define KURL WebKitKURL @@ -79,9 +81,11 @@ struct ComponentCase { // Output stream operator so gTest's macros work with WebCore strings. std::ostream& operator<<(std::ostream& out, - const WebCore::DeprecatedString& str) { + const WebCore::String& str) { + if (str.isEmpty()) + return out; return out << WideToUTF8(std::wstring( - reinterpret_cast<const wchar_t*>(str.unicode()), str.length())); + reinterpret_cast<const wchar_t*>(str.characters()), str.length())); } } // namespace @@ -114,8 +118,8 @@ TEST(GKURL, SameGetters) { // UTF-16 std::wstring wstr(UTF8ToWide(cases[i])); - WebCore::DeprecatedString utf16( - reinterpret_cast<const WebCore::DeprecatedChar*>(wstr.c_str()), + WebCore::String utf16( + reinterpret_cast<const ::UChar*>(wstr.c_str()), static_cast<int>(wstr.length())); kurl = WebCore::WebKitKURL(utf16); gurl = WebCore::GoogleKURL(utf16); @@ -140,17 +144,17 @@ TEST(GKURL, DifferentGetters) { // Old WebKit allows references and queries in what we call "path" URLs // like javascript, so the path here will only consist of "hello!". - {"javascript:hello!?#/\\world", "javascript", NULL, 0, NULL, NULL, "hello!?#/\\world", "world", NULL, NULL}, + {"javascript:hello!?#/\\world", "javascript", "", 0, "", NULL, "hello!?#/\\world", "world", "", NULL}, // Old WebKit doesn't handle "parameters" in paths, so will // disagree with us about where the path is for this URL. - {"http://a.com/hello;world", "http", "a.com", 0, NULL, NULL, "/hello;world", "hello", NULL, NULL}, + {"http://a.com/hello;world", "http", "a.com", 0, "", NULL, "/hello;world", "hello", "", NULL}, // WebKit doesn't like UTF-8 or UTF-16 input. - {"http://\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd/", "http", "xn--6qqa088eba", 0, NULL, NULL, "/", NULL, NULL, NULL}, + {"http://\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd/", "http", "xn--6qqa088eba", 0, "", NULL, "/", NULL, "", NULL}, // WebKit %-escapes non-ASCII characters in reference, but we don't. - {"http://www.google.com/foo/blah?bar=baz#\xce\xb1\xce\xb2", "http", "www.google.com", 0, NULL, NULL, "/foo/blah/", "blah", "?bar=baz", "\xce\xb1\xce\xb2"} + {"http://www.google.com/foo/blah?bar=baz#\xce\xb1\xce\xb2", "http", "www.google.com", 0, "", NULL, "/foo/blah/", "blah", "?bar=baz", "\xce\xb1\xce\xb2"} }; for (int i = 0; i < arraysize(cases); i++) { @@ -163,13 +167,12 @@ TEST(GKURL, DifferentGetters) { EXPECT_EQ(cases[i].pass, gurl.pass()); EXPECT_EQ(cases[i].last_path, gurl.lastPathComponent()); EXPECT_EQ(cases[i].query, gurl.query()); - if (cases[i].ref == NULL) { - EXPECT_EQ(cases[i].ref, gurl.ref()); + // Want to compare UCS-16 refs (or to NULL). + if (cases[i].ref) { + EXPECT_EQ(webkit_glue::StdWStringToString(UTF8ToWide(cases[i].ref)), + gurl.ref()); } else { - // We can't compare cases[i].ref and gurl.ref() directly - // because operator==(const char*, const DeprecatedString&) invoked - // in CmpHelperEQ does not treat 'char *' as UTF-8. - EXPECT_STREQ(cases[i].ref, gurl.ref().utf8()); + EXPECT_TRUE(gurl.ref().isNull()); } } } @@ -181,12 +184,12 @@ TEST(GKURL, UTF8) { WebCore::GoogleKURL ascii_gurl(ascii_url); EXPECT_TRUE(ascii_gurl.string() == WebCore::String(ascii_url)); - // When the result is ASCII, we should get an ASCII DeprecatedString. Some - // code depends on being able to compare the result of the .deprecatedString() - // getter with another deprecatedString, and the isASCIIness of the two + // When the result is ASCII, we should get an ASCII String. Some + // code depends on being able to compare the result of the .string() + // getter with another String, and the isASCIIness of the two // strings must match for these functions (like equalIgnoringCase). - EXPECT_TRUE(WebCore::equalIgnoringCase(ascii_gurl.deprecatedString(), - WebCore::DeprecatedString(ascii_url))); + EXPECT_TRUE(WebCore::equalIgnoringCase(ascii_gurl, + WebCore::String(ascii_url))); // Reproduce code path in FrameLoader.cpp -- equalIgnoringCase implicitly // expects gkurl.protocol() to have been created as ascii. @@ -218,42 +221,42 @@ TEST(GKURL, Setters) { WebCore::GoogleKURL gurl(cases[i].url); WebCore::WebKitKURL kurl(cases[i].url); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setProtocol(cases[i].protocol); gurl.setProtocol(cases[i].protocol); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setHost(cases[i].host); gurl.setHost(cases[i].host); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setPort(cases[i].port); gurl.setPort(cases[i].port); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setUser(cases[i].user); gurl.setUser(cases[i].user); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setPass(cases[i].pass); gurl.setPass(cases[i].pass); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setPath(cases[i].path); gurl.setPath(cases[i].path); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); kurl.setQuery(cases[i].query); gurl.setQuery(cases[i].query); - EXPECT_EQ(kurl.deprecatedString(), gurl.deprecatedString()); + EXPECT_EQ(kurl.string(), gurl.string()); // Refs are tested below. On the Safari 3.1 branch, we don't match their // KURL since we integrated a fix from their trunk. } } -// Tests that KURL::decode_string works as expected +// Tests that KURL::decodeURLEscapeSequences works as expected TEST(GKURL, Decode) { const char* decode_cases[] = { "hello, world", @@ -270,41 +273,41 @@ TEST(GKURL, Decode) { }; for (int i = 0; i < arraysize(decode_cases); i++) { - WebCore::DeprecatedString input(decode_cases[i]); - WebCore::DeprecatedString webkit = WebCore::WebKitKURL::decode_string(input); - WebCore::DeprecatedString google = WebCore::GoogleKURL::decode_string(input); + WebCore::String input(decode_cases[i]); + WebCore::String webkit = WebCore::WebKitKURL::decodeURLEscapeSequences(input); + WebCore::String google = WebCore::GoogleKURL::decodeURLEscapeSequences(input); EXPECT_TRUE(webkit == google); } // Our decode should not decode %00 - WebCore::DeprecatedString zero = WebCore::GoogleKURL::decode_string("%00"); - EXPECT_STREQ("%00", zero.ascii()); + WebCore::String zero = WebCore::GoogleKURL::decodeURLEscapeSequences("%00"); + EXPECT_STREQ("%00", zero.utf8().data()); // Test the error behavior for invalid UTF-8 (we differ from WebKit here). - WebCore::DeprecatedString invalid = WebCore::GoogleKURL::decode_string( + WebCore::String invalid = WebCore::GoogleKURL::decodeURLEscapeSequences( "%e4%a0%e5%a5%bd"); - WebCore::DeprecatedString invalid_expected( - reinterpret_cast<const WebCore::DeprecatedChar*>(L"\x00e4\x00a0\x597d"), + WebCore::String invalid_expected( + reinterpret_cast<const ::UChar*>(L"\x00e4\x00a0\x597d"), 3); EXPECT_EQ(invalid_expected, invalid); } TEST(GKURL, Encode) { // Also test that it gets converted to UTF-8 properly. - WebCore::DeprecatedString wide_input( - reinterpret_cast<const WebCore::DeprecatedChar*>(L"\x4f60\x597d"), 2); - WebCore::DeprecatedString wide_reference("\xe4\xbd\xa0\xe5\xa5\xbd", 6); - WebCore::DeprecatedString wide_output = - WebCore::GoogleKURL::encode_string(wide_input); + WebCore::String wide_input( + reinterpret_cast<const ::UChar*>(L"\x4f60\x597d"), 2); + WebCore::String wide_reference("\xe4\xbd\xa0\xe5\xa5\xbd", 6); + WebCore::String wide_output = + WebCore::GoogleKURL::encodeWithURLEscapeSequences(wide_input); EXPECT_EQ(wide_reference, wide_output); // Our encode only escapes NULLs for safety (see the implementation for // more), so we only bother to test a few cases. - WebCore::DeprecatedString input( + WebCore::String input( "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16); - WebCore::DeprecatedString reference( + WebCore::String reference( "%00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 18); - WebCore::DeprecatedString output = WebCore::GoogleKURL::encode_string(input); + WebCore::String output = WebCore::GoogleKURL::encodeWithURLEscapeSequences(input); EXPECT_EQ(reference, output); } @@ -316,7 +319,7 @@ TEST(GKURL, ResolveEmpty) { const char abs[] = "http://www.google.com/"; WebCore::GoogleKURL resolve_abs(empty_base, abs); EXPECT_TRUE(resolve_abs.isValid()); - EXPECT_STREQ(abs, resolve_abs.deprecatedString().ascii()); + EXPECT_STREQ(abs, resolve_abs.string().utf8().data()); // Resolving a non-relative URL agains the empty one should still error. const char rel[] = "foo.html"; @@ -332,7 +335,7 @@ TEST(GKURL, ReplaceInvalid) { EXPECT_EQ(kurl.isValid(), gurl.isValid()); EXPECT_EQ(kurl.isEmpty(), gurl.isEmpty()); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); gurl.setProtocol("http"); kurl.setProtocol("http"); @@ -344,27 +347,27 @@ TEST(GKURL, ReplaceInvalid) { // differently if there is only a scheme. We check the results here to make // it more obvious what is going on, but it shouldn't be a big deal if these // change. - EXPECT_STREQ("http:", gurl.deprecatedString().ascii()); - EXPECT_STREQ("http:/", kurl.deprecatedString().ascii()); + EXPECT_STREQ("http:", gurl.string().utf8().data()); + EXPECT_STREQ("http:/", kurl.string().utf8().data()); gurl.setHost("www.google.com"); kurl.setHost("www.google.com"); EXPECT_EQ(kurl.isValid(), gurl.isValid()); EXPECT_EQ(kurl.isEmpty(), gurl.isEmpty()); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); gurl.setPort(8000); kurl.setPort(8000); EXPECT_EQ(kurl.isValid(), gurl.isValid()); EXPECT_EQ(kurl.isEmpty(), gurl.isEmpty()); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); gurl.setPath("/favicon.ico"); kurl.setPath("/favicon.ico"); EXPECT_EQ(kurl.isValid(), gurl.isValid()); EXPECT_EQ(kurl.isEmpty(), gurl.isEmpty()); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); - EXPECT_STREQ("http://www.google.com:8000/favicon.ico", gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); + EXPECT_STREQ("http://www.google.com:8000/favicon.ico", gurl.string().utf8().data()); // Now let's test that giving an invalid replacement still fails. gurl.setProtocol("f/sj#@"); @@ -377,12 +380,12 @@ TEST(GKURL, Path) { WebCore::WebKitKURL kurl(initial); // Clear by setting a NULL string. - WebCore::DeprecatedString null_string; + WebCore::String null_string; EXPECT_TRUE(null_string.isNull()); gurl.setPath(null_string); kurl.setPath(null_string); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); - EXPECT_STREQ("http://www.google.com/", gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); + EXPECT_STREQ("http://www.google.com/", gurl.string().utf8().data()); } // Test that setting the query to different things works. Thq query is handled @@ -393,32 +396,32 @@ TEST(GKURL, Query) { WebCore::WebKitKURL kurl(initial); // Clear by setting a NULL string. - WebCore::DeprecatedString null_string; + WebCore::String null_string; EXPECT_TRUE(null_string.isNull()); gurl.setQuery(null_string); kurl.setQuery(null_string); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); // Clear by setting an empty string. gurl = WebCore::GoogleKURL(initial); kurl = WebCore::WebKitKURL(initial); - WebCore::DeprecatedString empty_string(""); + WebCore::String empty_string(""); EXPECT_FALSE(empty_string.isNull()); gurl.setQuery(empty_string); kurl.setQuery(empty_string); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); // Set with something that begins in a question mark. const char question[] = "?foo=bar"; gurl.setQuery(question); kurl.setQuery(question); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); // Set with something that doesn't begin in a question mark. const char query[] = "foo=bar"; gurl.setQuery(query); kurl.setQuery(query); - EXPECT_STREQ(kurl.deprecatedString().ascii(), gurl.deprecatedString().ascii()); + EXPECT_STREQ(kurl.string().utf8().data(), gurl.string().utf8().data()); } TEST(GKURL, Ref) { @@ -427,26 +430,26 @@ TEST(GKURL, Ref) { // Basic ref setting. WebCore::GoogleKURL cur("http://foo/bar"); cur.setRef("asdf"); - EXPECT_STREQ(cur.deprecatedString().ascii(), "http://foo/bar#asdf"); + EXPECT_STREQ("http://foo/bar#asdf", cur.string().utf8().data()); cur = gurl; cur.setRef("asdf"); - EXPECT_STREQ(cur.deprecatedString().ascii(), "http://foo/bar#asdf"); + EXPECT_STREQ("http://foo/bar#asdf", cur.string().utf8().data()); // Setting a ref to the empty string will set it to "#". cur = WebCore::GoogleKURL("http://foo/bar"); - cur.setRef(WebCore::DeprecatedString("")); - EXPECT_STREQ("http://foo/bar#", cur.deprecatedString().ascii()); + cur.setRef(""); + EXPECT_STREQ("http://foo/bar#", cur.string().utf8().data()); cur = gurl; - cur.setRef(WebCore::DeprecatedString("")); - EXPECT_STREQ("http://foo/bar#", cur.deprecatedString().ascii()); + cur.setRef(""); + EXPECT_STREQ("http://foo/bar#", cur.string().utf8().data()); // Setting the ref to the null string will clear it altogether. cur = WebCore::GoogleKURL("http://foo/bar"); - cur.setRef(WebCore::DeprecatedString()); - EXPECT_STREQ("http://foo/bar", cur.deprecatedString().ascii()); + cur.setRef(WebCore::String()); + EXPECT_STREQ("http://foo/bar", cur.string().utf8().data()); cur = gurl; - cur.setRef(WebCore::DeprecatedString()); - EXPECT_STREQ("http://foo/bar", cur.deprecatedString().ascii()); + cur.setRef(WebCore::String()); + EXPECT_STREQ("http://foo/bar", cur.string().utf8().data()); } TEST(GKURL, Empty) { @@ -456,31 +459,43 @@ TEST(GKURL, Empty) { // First test that regular empty URLs are the same. EXPECT_EQ(kurl.isEmpty(), gurl.isEmpty()); EXPECT_EQ(kurl.isValid(), gurl.isValid()); + EXPECT_EQ(kurl.isNull(), gurl.isNull()); EXPECT_EQ(kurl.string().isNull(), gurl.string().isNull()); EXPECT_EQ(kurl.string().isEmpty(), gurl.string().isEmpty()); - // Now test that resolved empty URLs are the same. + // Test resolving a NULL URL on an empty string. WebCore::GoogleKURL gurl2(gurl, ""); WebCore::WebKitKURL kurl2(kurl, ""); + EXPECT_EQ(kurl2.isNull(), gurl2.isNull()); EXPECT_EQ(kurl2.isEmpty(), gurl2.isEmpty()); EXPECT_EQ(kurl2.isValid(), gurl2.isValid()); EXPECT_EQ(kurl2.string().isNull(), gurl2.string().isNull()); EXPECT_EQ(kurl2.string().isEmpty(), gurl2.string().isEmpty()); - EXPECT_EQ(kurl2.deprecatedString().isNull(), gurl2.deprecatedString().isNull()); - EXPECT_EQ(kurl2.deprecatedString().isEmpty(), gurl2.deprecatedString().isEmpty()); + EXPECT_EQ(kurl2.string().isNull(), gurl2.string().isNull()); + EXPECT_EQ(kurl2.string().isEmpty(), gurl2.string().isEmpty()); - // Now test that non-hierarchical schemes are resolved the same. + // Resolve the NULL URL on a NULL string. + WebCore::GoogleKURL gurl22(gurl, WebCore::String()); + WebCore::WebKitKURL kurl22(kurl, WebCore::String()); + EXPECT_EQ(kurl2.isNull(), gurl2.isNull()); + EXPECT_EQ(kurl2.isEmpty(), gurl2.isEmpty()); + EXPECT_EQ(kurl2.isValid(), gurl2.isValid()); + EXPECT_EQ(kurl2.string().isNull(), gurl2.string().isNull()); + EXPECT_EQ(kurl2.string().isEmpty(), gurl2.string().isEmpty()); + EXPECT_EQ(kurl2.string().isNull(), gurl2.string().isNull()); + EXPECT_EQ(kurl2.string().isEmpty(), gurl2.string().isEmpty()); + + // Test non-hierarchical schemes resolving. The actual URLs will be different. + // WebKit's one will set the string to "something.gif" and we'll set it to an + // empty string. I think either is OK, so we just check our behavior. WebCore::GoogleKURL gurl3(WebCore::GoogleKURL("data:foo"), "something.gif"); - WebCore::WebKitKURL kurl3(WebCore::WebKitKURL("data:foo"), "something.gif"); - EXPECT_EQ(kurl3.isEmpty(), gurl3.isEmpty()); - EXPECT_EQ(kurl3.isValid(), gurl3.isValid()); - EXPECT_EQ(kurl3.string().isNull(), gurl3.string().isNull()); - EXPECT_EQ(kurl3.string().isEmpty(), gurl3.string().isEmpty()); + EXPECT_TRUE(gurl3.isEmpty()); + EXPECT_FALSE(gurl3.isValid()); // Test for weird isNull string input, // see: http://bugs.webkit.org/show_bug.cgi?id=16487 - WebCore::GoogleKURL gurl4(gurl.deprecatedString()); - WebCore::WebKitKURL kurl4(kurl.deprecatedString()); + WebCore::GoogleKURL gurl4(gurl.string()); + WebCore::WebKitKURL kurl4(kurl.string()); EXPECT_EQ(kurl4.isEmpty(), gurl4.isEmpty()); EXPECT_EQ(kurl4.isValid(), gurl4.isValid()); EXPECT_EQ(kurl4.string().isNull(), gurl4.string().isNull()); @@ -489,10 +504,11 @@ TEST(GKURL, Empty) { // Resolving an empty URL on an invalid string. WebCore::GoogleKURL gurl5(WebCore::GoogleKURL(), "foo.js"); WebCore::WebKitKURL kurl5(WebCore::WebKitKURL(), "foo.js"); - EXPECT_EQ(kurl5.isEmpty(), gurl5.isEmpty()); + // We'll be empty in this case, but KURL won't be. Should be OK. + // EXPECT_EQ(kurl5.isEmpty(), gurl5.isEmpty()); + // EXPECT_EQ(kurl5.string().isEmpty(), gurl5.string().isEmpty()); EXPECT_EQ(kurl5.isValid(), gurl5.isValid()); EXPECT_EQ(kurl5.string().isNull(), gurl5.string().isNull()); - EXPECT_EQ(kurl5.string().isEmpty(), gurl5.string().isEmpty()); // Empty string as input WebCore::GoogleKURL gurl6(""); @@ -534,3 +550,35 @@ TEST(GKURL, UserPass) { kurl.setUser(""); EXPECT_TRUE(kurl.string() == gurl.string()); } + +TEST(GKURL, Offsets) { + const char* src1 = "http://user:pass@google.com/foo/bar.html?baz=query#ref"; + WebCore::GoogleKURL gurl1(src1); + WebCore::WebKitKURL kurl1(src1); + + EXPECT_TRUE(kurl1.hostStart() == gurl1.hostStart()); + EXPECT_TRUE(kurl1.hostEnd() == gurl1.hostEnd()); + EXPECT_TRUE(kurl1.pathStart() == gurl1.pathStart()); + EXPECT_TRUE(kurl1.pathEnd() == gurl1.pathEnd()); + EXPECT_TRUE(kurl1.pathAfterLastSlash() == gurl1.pathAfterLastSlash()); + + const char* src2 = "http://google.com/foo/"; + WebCore::GoogleKURL gurl2(src2); + WebCore::WebKitKURL kurl2(src2); + + EXPECT_TRUE(kurl2.hostStart() == gurl2.hostStart()); + EXPECT_TRUE(kurl2.hostEnd() == gurl2.hostEnd()); + EXPECT_TRUE(kurl2.pathStart() == gurl2.pathStart()); + EXPECT_TRUE(kurl2.pathEnd() == gurl2.pathEnd()); + EXPECT_TRUE(kurl2.pathAfterLastSlash() == gurl2.pathAfterLastSlash()); + + const char* src3 = "javascript:foobar"; + WebCore::GoogleKURL gurl3(src3); + WebCore::WebKitKURL kurl3(src3); + + EXPECT_TRUE(kurl3.hostStart() == gurl3.hostStart()); + EXPECT_TRUE(kurl3.hostEnd() == gurl3.hostEnd()); + EXPECT_TRUE(kurl3.pathStart() == gurl3.pathStart()); + EXPECT_TRUE(kurl3.pathEnd() == gurl3.pathEnd()); + EXPECT_TRUE(kurl3.pathAfterLastSlash() == gurl3.pathAfterLastSlash()); +}
\ No newline at end of file diff --git a/webkit/port/platform/MIMETypeRegistry.cpp b/webkit/port/platform/MIMETypeRegistry.cpp index 6c936d1..1c3f38b 100644 --- a/webkit/port/platform/MIMETypeRegistry.cpp +++ b/webkit/port/platform/MIMETypeRegistry.cpp @@ -43,11 +43,17 @@ namespace WebCore // (and will give linker error if used): // HashSet<String> &MIMETypeRegistry::getSupportedImageMIMETypes() // HashSet<String> &MIMETypeRegistry::getSupportedImageResourceMIMETypes() -// HashSet<String> &MIMETypeRegistry::getSupportedNonImageMIMETypes() // These methods are referenced by WebKit but not WebCore. // Therefore defering their implementation until necessary. // Since the returned HashSet is mutable, chrome would need to synchronize -// the mime type registry between renderer/browser. +// the mime type registry between renderer/browser. This one is called, but we +// currently stub it out until this can be resolved. +HashSet<String>& MIMETypeRegistry::getSupportedNonImageMIMETypes() +{ + static HashSet<String> supportedNonImageMIMETypes; + return supportedNonImageMIMETypes; +} + // Checks if any of the plugins handle this extension, and if so returns the // plugin's mime type for this extension. Otherwise returns an empty string. @@ -74,6 +80,12 @@ bool MIMETypeRegistry::isSupportedImageMIMEType(const String& mimeType) && net::IsSupportedImageMimeType(mimeType.latin1().data()); } +bool MIMETypeRegistry::isSupportedImageMIMETypeForEncoding(const String& mimeType) +{ + // TODO(brettw) fill this out. See: http://trac.webkit.org/changeset/30888 + return isSupportedImageMIMEType(mimeType); +} + bool MIMETypeRegistry::isSupportedJavaScriptMIMEType(const String& mimeType) { return !mimeType.isEmpty() diff --git a/webkit/port/platform/MimeTypeRegistryWin.cpp b/webkit/port/platform/MimeTypeRegistryWin.cpp index 0b214b8..a4eaa9f 100644 --- a/webkit/port/platform/MimeTypeRegistryWin.cpp +++ b/webkit/port/platform/MimeTypeRegistryWin.cpp @@ -59,8 +59,6 @@ String MIMETypeRegistry::getPreferredExtensionForMIMEType(const String& type) return webkit_glue::StdWStringToString(ext); } -// NOTE: This does not work in the sandbox because the renderer doesn't have -// access to the Windows Registry. String MIMETypeRegistry::getMIMETypeForExtension(const String &ext) { if (ext.isEmpty()) diff --git a/webkit/port/platform/PasteboardWin.cpp b/webkit/port/platform/PasteboardWin.cpp index dae2ab5..f22b85f 100644 --- a/webkit/port/platform/PasteboardWin.cpp +++ b/webkit/port/platform/PasteboardWin.cpp @@ -28,7 +28,6 @@ #include "ClipboardUtilitiesWin.h" #include "CString.h" -#include "DeprecatedString.h" #include "DocumentFragment.h" #include "Document.h" #include "Element.h" @@ -82,7 +81,7 @@ void Pasteboard::writeSelection(Range* selectedRange, bool canSmartCopyOrDelete, webkit_glue::ClipboardWriteHTML( webkit_glue::StringToStdWString( createMarkup(selectedRange, 0, AnnotateForInterchange)), - GURL(webkit_glue::DeprecatedStringToStdWString( + GURL(webkit_glue::StringToStdWString( selectedRange->startContainer(ec)->document()->url()))); // Put plain string on the pasteboard. CF_UNICODETEXT covers CF_TEXT as well @@ -117,7 +116,7 @@ void Pasteboard::writeURL(const KURL& url, const String& titleStr, Frame* frame) webkit_glue::ClipboardWriteHTML(link, GURL()); // bare-bones CF_UNICODETEXT support - std::wstring spec(webkit_glue::DeprecatedStringToStdWString(url.deprecatedString())); + std::wstring spec(webkit_glue::StringToStdWString(url)); webkit_glue::ClipboardWriteText(spec); } @@ -131,7 +130,7 @@ void Pasteboard::writeImage(Node* node, const KURL& url, const String& title) ASSERT(image); clear(); - NativeImageSkia* bitmap = image->getBitmap(); + NativeImageSkia* bitmap = image->nativeImageForCurrentFrame(); if (bitmap) webkit_glue::ClipboardWriteBitmap(*bitmap); if (!url.isEmpty()) { @@ -146,7 +145,7 @@ void Pasteboard::writeImage(Node* node, const KURL& url, const String& title) webkit_glue::ClipboardWriteHTML(markup, GURL()); // bare-bones CF_UNICODETEXT support - std::wstring spec(webkit_glue::DeprecatedStringToStdWString(url.deprecatedString())); + std::wstring spec(webkit_glue::StringToStdWString(url.string())); webkit_glue::ClipboardWriteText(spec); } } diff --git a/webkit/port/platform/PlatformScrollBar.h b/webkit/port/platform/PlatformScrollBar.h index ee619e1..4b3c17b 100644 --- a/webkit/port/platform/PlatformScrollBar.h +++ b/webkit/port/platform/PlatformScrollBar.h @@ -59,8 +59,10 @@ namespace WebCore { class PlatformScrollbar : public Widget, public Scrollbar { public: - PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize); - + static PassRefPtr<PlatformScrollbar> create(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size) + { + return adoptRef(new PlatformScrollbar(client, orientation, size)); + } virtual ~PlatformScrollbar(); virtual bool isWidget() const { return true; } @@ -105,6 +107,8 @@ protected: virtual void updateThumbProportion(); private: + PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize); + // Scroll bar segment identifiers enum Segment { Arrow1 = 0, diff --git a/webkit/port/platform/PlatformScrollBarWin.cpp b/webkit/port/platform/PlatformScrollBarWin.cpp index c921e97..723d321 100644 --- a/webkit/port/platform/PlatformScrollBarWin.cpp +++ b/webkit/port/platform/PlatformScrollBarWin.cpp @@ -189,17 +189,16 @@ void PlatformScrollbar::DrawTickmarks(GraphicsContext* context) const // will not be serialized, i.e. composition is done in the renderer and // never in the browser. // Prepare the bitmap for drawing the tickmarks on the scroll bar. - gfx::PlatformCanvasWin* canvas = PlatformContextToPlatformContextSkia( - context->platformContext())->canvas(); + gfx::PlatformCanvas* canvas = context->platformContext()->canvas(); // Load the image for the tickmark. - static Image* dashImg = Image::loadPlatformResource("tickmarkDash"); + static RefPtr<Image> dashImg = Image::loadPlatformResource("tickmarkDash"); DCHECK(dashImg); if (dashImg->isNull()) { ASSERT_NOT_REACHED(); return; } - const NativeImageSkia* dash = dashImg->getBitmap(); + const NativeImageSkia* dash = dashImg->nativeImageForCurrentFrame(); for (Vector<RefPtr<Range> >::const_iterator i = tickmarks.begin(); @@ -237,10 +236,9 @@ void PlatformScrollbar::paint(GraphicsContext* gc, const IntRect& damageRect) layout(); - HDC hdc = gc->getWindowsContext(); + HDC hdc = gc->getWindowsContext(damageRect); const bool horz = orientation() == HorizontalScrollbar; - const PlatformContextSkia* const skia = - PlatformContextToPlatformContextSkia(gc->platformContext()); + const PlatformContextSkia* const skia = gc->platformContext(); const gfx::NativeTheme* const nativeTheme = skia->nativeTheme(); gfx::PlatformCanvasWin* const canvas = skia->canvas(); @@ -308,7 +306,7 @@ void PlatformScrollbar::paint(GraphicsContext* gc, const IntRect& damageRect) DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN) | getClassicThemeState(Arrow2), &m_segmentRects[Arrow2]); - gc->releaseWindowsContext(hdc); + gc->releaseWindowsContext(hdc, damageRect); gc->restore(); } diff --git a/webkit/port/platform/PopupMenuWin.cpp b/webkit/port/platform/PopupMenuWin.cpp index 145e0fb..ae0e407c 100644 --- a/webkit/port/platform/PopupMenuWin.cpp +++ b/webkit/port/platform/PopupMenuWin.cpp @@ -757,7 +757,7 @@ Font PopupListBox::getRowFont(int rowIndex) if (m_popupClient->itemIsLabel(rowIndex)) { // Bold-ify labels (ie, an <optgroup> heading). FontDescription d = itemFont.fontDescription(); - d.setBold(true); + d.setWeight(FontWeightBold); Font font(d, itemFont.letterSpacing(), itemFont.wordSpacing()); font.update(0); return font; diff --git a/webkit/port/platform/ScrollViewWin.cpp b/webkit/port/platform/ScrollViewWin.cpp index 6761073..6964f82 100644 --- a/webkit/port/platform/ScrollViewWin.cpp +++ b/webkit/port/platform/ScrollViewWin.cpp @@ -69,6 +69,8 @@ public: , m_hScrollbarMode(ScrollbarAuto) , m_visible(false) , m_attachedToWindow(false) + , m_panScrollIconPoint(0,0) + , m_drawPanScrollIcon(false) { } @@ -126,13 +128,17 @@ public: HashSet<Widget*> m_children; bool m_visible; bool m_attachedToWindow; + IntPoint m_panScrollIconPoint; + bool m_drawPanScrollIcon; }; +const int panIconSizeLength = 20; + void ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar(bool hasBar) { if (Scrollbar::hasPlatformScrollbars()) { if (hasBar && !m_hBar) { - m_hBar = new PlatformScrollbar(this, HorizontalScrollbar, RegularScrollbar); + m_hBar = PlatformScrollbar::create(this, HorizontalScrollbar, RegularScrollbar); m_view->addChild(m_hBar.get()); } else if (!hasBar && m_hBar) { m_view->removeChild(m_hBar.get()); @@ -145,7 +151,7 @@ void ScrollView::ScrollViewPrivate::setHasVerticalScrollbar(bool hasBar) { if (Scrollbar::hasPlatformScrollbars()) { if (hasBar && !m_vBar) { - m_vBar = new PlatformScrollbar(this, VerticalScrollbar, RegularScrollbar); + m_vBar = PlatformScrollbar::create(this, VerticalScrollbar, RegularScrollbar); m_view->addChild(m_vBar.get()); } else if (!hasBar && m_vBar) { m_view->removeChild(m_vBar.get()); @@ -314,8 +320,7 @@ void ScrollView::ScrollViewPrivate::highlightMatches( // will not be serialized, i.e. composition is done in the renderer and // never in the browser. // Prepare for drawing the arrows along the scroll bar. - gfx::PlatformCanvasWin* canvas = PlatformContextToPlatformContextSkia( - context->platformContext())->canvas(); + gfx::PlatformCanvas* canvas = context->platformContext()->canvas(); int horz_start = 0; int horz_end = m_view->width(); @@ -338,7 +343,8 @@ void ScrollView::ScrollViewPrivate::highlightMatches( vert_end -= PlatformScrollbar::horizontalScrollbarHeight() + 1; } - HDC hdc = context->getWindowsContext(); + IntRect view_rect(IntPoint(), m_view->size()); + HDC hdc = context->getWindowsContext(view_rect); // We create a memory DC, copy the bits we want to highlight to the DC and // then MERGE_COPY pieces of it back with a yellow brush selected (which @@ -391,7 +397,7 @@ void ScrollView::ScrollViewPrivate::highlightMatches( DeleteDC(mem_dc); - context->releaseWindowsContext(hdc); + context->releaseWindowsContext(hdc, view_rect); context->restore(); } @@ -421,12 +427,7 @@ void ScrollView::ScrollViewPrivate::highlightInspectedNode( // TODO(ojan): http://b/1143975 Draw the padding/border/margin boxes in // different colors. - SkRect destRect; - WebCoreRectToSkiaRect(inspected_node->getRect(), &destRect); - - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia( - context->platformContext()); - skia->paintSkPaint(destRect, paint); + context->platformContext()->paintSkPaint(inspected_node->getRect(), paint); } void ScrollView::ScrollViewPrivate::highlightRange(HDC hdc, HDC mem_dc, @@ -531,8 +532,15 @@ void ScrollView::updateContents(const IntRect& rect, bool now) if (containingWindowRect.y() < 0) containingWindowRect.setY(0); + updateWindowRect(containingWindowRect, now); +} + +void ScrollView::updateWindowRect(const IntRect& rect, bool now) +{ + // TODO(dglazkov): make sure this is actually the right way to do this + // Cache the dirty spot. - addToDirtyRegion(containingWindowRect); + addToDirtyRegion(rect); // since painting always happens asynchronously, we don't have a way to // honor the "now" parameter. it is unclear if it matters. @@ -1196,4 +1204,24 @@ bool ScrollView::allowsScrolling() const return m_data->allowsScrolling(); } +void ScrollView::printPanScrollIcon(const IntPoint& iconPosition) +{ + m_data->m_drawPanScrollIcon = true; + m_data->m_panScrollIconPoint = IntPoint(iconPosition.x() - panIconSizeLength / 2 , iconPosition.y() - panIconSizeLength / 2) ; + + updateWindowRect(IntRect(m_data->m_panScrollIconPoint, IntSize(panIconSizeLength,panIconSizeLength)), true); +} + +void ScrollView::removePanScrollIcon() +{ + m_data->m_drawPanScrollIcon = false; + + updateWindowRect(IntRect(m_data->m_panScrollIconPoint, IntSize(panIconSizeLength, panIconSizeLength)), true); +} + +bool ScrollView::isScrollable() +{ + return m_data->m_vBar != 0 || m_data->m_hBar != 0; +} + } // namespace WebCore diff --git a/webkit/port/platform/cairo.h b/webkit/port/platform/cairo.h deleted file mode 100644 index 71786e4..0000000 --- a/webkit/port/platform/cairo.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// We compile WebKit with PLATFORM(CAIRO) defined. This only affects a few -// places in the shared headers. Therefore, we provide this replacement -// <cairo.h> that defines the Cairo types used in these shared headers to be -// the types that we desire. - -#ifndef CHROME_WEBKIT_PORT_PLATFORM_CAIRO_H__ -#define CHROME_WEBKIT_PORT_PLATFORM_CAIRO_H__ - -#include "SkMatrix.h" - -// For AffineTransform.h, this allows us to define the internal matrix type -// to be the Skia one we use internally. -typedef SkMatrix cairo_matrix_t; - -// For GlyphBuffer.h -struct cairo_glyph_t { - // Cairo defines this to be an unsigned long. PLATFORM(CG) in GlyphBuffer.h - // defines the glyph to be an unsigned short, so we do the same here. - unsigned short index; - - // Totally unused. This is defined by Cairo and set in GlyphBuffer.h to 0, - // so we define it. We use unsigned short so that the size of this structure - // is padded out to 4 bytes. - unsigned short y; - - // Cairo also defines an |x| here, but it's never used by the shared headers. -}; - -#endif // CHROME_WEBKIT_PORT_PLATFORM_CAIRO_H__ - diff --git a/webkit/port/platform/graphics/AffineTransformSkia.cpp b/webkit/port/platform/graphics/AffineTransformSkia.cpp index ed4942a..30d87d3 100644 --- a/webkit/port/platform/graphics/AffineTransformSkia.cpp +++ b/webkit/port/platform/graphics/AffineTransformSkia.cpp @@ -78,26 +78,18 @@ void AffineTransform::map(double x, double y, double *x2, double *y2) const *y2 = SkScalarToDouble(dst.fY); } -IntRect AffineTransform::mapRect(const IntRect &rect) const +IntRect AffineTransform::mapRect(const IntRect& src) const { - SkRect src, dst; - SkIRect ir; - - WebCoreRectToSkiaRect(rect, &src); + SkRect dst; m_transform.mapRect(&dst, src); - dst.round(&ir); - - return IntRect(ir.fLeft, ir.fTop, ir.width(), ir.height()); + return enclosingIntRect(dst); } -FloatRect AffineTransform::mapRect(const FloatRect &rect) const +FloatRect AffineTransform::mapRect(const FloatRect& src) const { - SkRect src, dst; - - WebCoreRectToSkiaRect(rect, &src); + SkRect dst; m_transform.mapRect(&dst, src); - - return FloatRect(dst.fLeft, dst.fTop, dst.width(), dst.height()); + return dst; } bool AffineTransform::isIdentity() const @@ -152,18 +144,18 @@ AffineTransform::operator SkMatrix() const return m_transform; } -bool AffineTransform::operator==(const AffineTransform &m2) const +bool AffineTransform::operator==(const AffineTransform& m2) const { return m_transform == m2.m_transform; } -AffineTransform &AffineTransform::operator*= (const AffineTransform &m2) +AffineTransform &AffineTransform::operator*=(const AffineTransform& m2) { m_transform.setConcat(m2.m_transform, m_transform); return *this; } -AffineTransform AffineTransform::operator* (const AffineTransform &m2) +AffineTransform AffineTransform::operator*(const AffineTransform& m2) { AffineTransform cat; @@ -171,46 +163,58 @@ AffineTransform AffineTransform::operator* (const AffineTransform &m2) return cat; } -double AffineTransform::a() const { +double AffineTransform::a() const +{ return SkScalarToDouble(m_transform.getScaleX()); } -void AffineTransform::setA(double a) { +void AffineTransform::setA(double a) +{ m_transform.setScaleX(WebCoreDoubleToSkScalar(a)); } -double AffineTransform::b() const { +double AffineTransform::b() const +{ return SkScalarToDouble(m_transform.getSkewY()); } -void AffineTransform::setB(double b) { +void AffineTransform::setB(double b) +{ m_transform.setSkewY(WebCoreDoubleToSkScalar(b)); } -double AffineTransform::c() const { +double AffineTransform::c() const +{ return SkScalarToDouble(m_transform.getSkewX()); } -void AffineTransform::setC(double c) { +void AffineTransform::setC(double c) +{ m_transform.setSkewX(WebCoreDoubleToSkScalar(c)); } -double AffineTransform::d() const { +double AffineTransform::d() const +{ return SkScalarToDouble(m_transform.getScaleY()); } -void AffineTransform::setD(double d) { +void AffineTransform::setD(double d) +{ m_transform.setScaleY(WebCoreDoubleToSkScalar(d)); } -double AffineTransform::e() const { +double AffineTransform::e() const +{ return SkScalarToDouble(m_transform.getTranslateX()); } -void AffineTransform::setE(double e) { +void AffineTransform::setE(double e) +{ m_transform.setTranslateX(WebCoreDoubleToSkScalar(e)); } -double AffineTransform::f() const { +double AffineTransform::f() const +{ return SkScalarToDouble(m_transform.getTranslateY()); } -void AffineTransform::setF(double f) { +void AffineTransform::setF(double f) +{ m_transform.setTranslateY(WebCoreDoubleToSkScalar(f)); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/ColorSkia.cpp b/webkit/port/platform/graphics/ColorSkia.cpp new file mode 100644 index 0000000..23c5eb0 --- /dev/null +++ b/webkit/port/platform/graphics/ColorSkia.cpp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2008 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 "Color.h" + +#include "SkColor.h" + +#include <wtf/Assertions.h> + +namespace WebCore { + +COMPILE_ASSERT(SK_ColorBLACK == Color::black, SkColorAndColorAreLaidOutTheSame); + +} // namespace WebCore diff --git a/webkit/port/platform/graphics/FloatPointSkia.cpp b/webkit/port/platform/graphics/FloatPointSkia.cpp new file mode 100644 index 0000000..01c94ef --- /dev/null +++ b/webkit/port/platform/graphics/FloatPointSkia.cpp @@ -0,0 +1,47 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 "FloatPoint.h"
+
+#include "SkPoint.h"
+#include "SkiaUtils.h"
+
+namespace WebCore {
+
+FloatPoint::FloatPoint(const SkPoint& p)
+ : m_x(p.fX)
+ , m_y(p.fY)
+{
+}
+
+FloatPoint::operator SkPoint() const
+{
+ SkPoint p = { WebCoreFloatToSkScalar(m_x), WebCoreFloatToSkScalar(m_y) };
+ return p;
+}
+
+} // namespace WebCore
+
diff --git a/webkit/port/platform/graphics/FloatRectSkia.cpp b/webkit/port/platform/graphics/FloatRectSkia.cpp new file mode 100644 index 0000000..4676983 --- /dev/null +++ b/webkit/port/platform/graphics/FloatRectSkia.cpp @@ -0,0 +1,46 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 "FloatRect.h"
+
+#include "SkRect.h"
+
+namespace WebCore {
+
+FloatRect::FloatRect(const SkRect& r)
+ : m_location(r.fLeft, r.fTop)
+ , m_size(r.width(), r.height())
+{
+}
+
+FloatRect::operator SkRect() const
+{
+ SkRect rect = { x(), y(), right(), bottom() };
+ return rect;
+}
+
+} // namespace WebCore
+
diff --git a/webkit/port/platform/graphics/FontCacheWin.cpp b/webkit/port/platform/graphics/FontCacheWin.cpp index 29fe120..e4b2c65 100644 --- a/webkit/port/platform/graphics/FontCacheWin.cpp +++ b/webkit/port/platform/graphics/FontCacheWin.cpp @@ -29,6 +29,7 @@ #include "config.h" #include "FontCache.h" #include "Font.h" +#include "HashSet.h" #include "SimpleFontData.h" #include "StringHash.h" #include <algorithm> @@ -555,6 +556,22 @@ FontPlatformData* FontCache::getLastResortFallbackFont( return getCachedFontPlatformData(description, fontStr); } +static LONG toGDIFontWeight(FontWeight fontWeight) +{ + static LONG gdiFontWeights[] = { + FW_THIN, // FontWeight100 + FW_EXTRALIGHT, // FontWeight200 + FW_LIGHT, // FontWeight300 + FW_NORMAL, // FontWeight400 + FW_MEDIUM, // FontWeight500 + FW_SEMIBOLD, // FontWeight600 + FW_BOLD, // FontWeight700 + FW_EXTRABOLD, // FontWeight800 + FW_HEAVY // FontWeight900 + }; + return gdiFontWeights[fontWeight]; +} + // TODO(jungshik): This may not be the best place to put this function. See // TODO in pending/FontCache.h. AtomicString FontCache::getGenericFontForScript(UScriptCode script, const FontDescription& description) @@ -584,16 +601,7 @@ static void FillLogFont(const FontDescription& fontDescription, LOGFONT* winfont : DEFAULT_QUALITY; // Honor user's desktop settings. winfont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE; winfont->lfItalic = fontDescription.italic(); - - // FIXME: Support weights for real. Do our own enumeration of the available weights. - // We can't rely on Windows here, since we need to follow the CSS2 algorithm for how to fill in - // gaps in the weight list. - // fontExists() used to hardcod Lucida Grande. According to FIXME comment, - // that's because it uses different weights than typical Win32 fonts - // (500/600 instead of 400/700). However, createFontPlatformData - // didn't. Special-casing Lucida Grande in a refactored function - // led to massive webkit test failure. - winfont->lfWeight = fontDescription.bold() ? 700 : 400; + winfont->lfWeight = toGDIFontWeight(fontDescription.weight()); } bool FontCache::fontExists(const FontDescription& fontDescription, const AtomicString& family) @@ -618,6 +626,55 @@ bool FontCache::fontExists(const FontDescription& fontDescription, const AtomicS return LookupAltName(family, altName) && equalIgnoringCase(altName, winName); } +struct TraitsInFamilyProcData { + TraitsInFamilyProcData(const AtomicString& familyName) + : m_familyName(familyName) + { + } + + const AtomicString& m_familyName; + HashSet<unsigned> m_traitsMasks; +}; + +static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMETRIC* metrics, DWORD fontType, LPARAM lParam) +{ + TraitsInFamilyProcData* procData = reinterpret_cast<TraitsInFamilyProcData*>(lParam); + + unsigned traitsMask = 0; + traitsMask |= logFont->lfItalic ? FontStyleItalicMask : FontStyleNormalMask; + traitsMask |= FontVariantNormalMask; + LONG weight = logFont->lfWeight; + traitsMask |= weight == FW_THIN ? FontWeight100Mask : + weight == FW_EXTRALIGHT ? FontWeight200Mask : + weight == FW_LIGHT ? FontWeight300Mask : + weight == FW_NORMAL ? FontWeight400Mask : + weight == FW_MEDIUM ? FontWeight500Mask : + weight == FW_SEMIBOLD ? FontWeight600Mask : + weight == FW_BOLD ? FontWeight700Mask : + weight == FW_EXTRABOLD ? FontWeight800Mask : + FontWeight900Mask; + procData->m_traitsMasks.add(traitsMask); + return 1; +} + +void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) +{ + HDC hdc = GetDC(0); + + LOGFONT logFont; + logFont.lfCharSet = DEFAULT_CHARSET; + unsigned familyLength = min(familyName.length(), static_cast<unsigned>(LF_FACESIZE - 1)); + memcpy(logFont.lfFaceName, familyName.characters(), familyLength * sizeof(UChar)); + logFont.lfFaceName[familyLength] = 0; + logFont.lfPitchAndFamily = 0; + + TraitsInFamilyProcData procData(familyName); + EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0); + copyToVector(procData.m_traitsMasks, traitsMasks); + + ReleaseDC(0, hdc); +} + FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { LOGFONT winfont = {0}; @@ -631,8 +688,8 @@ FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontD if (!hfont) return 0; - // TODO(pamg): Do we need to use predefined fonts "guaranteed" to exist - // when we're running in layout-test mode? + // TODO(pamg): Do we need to use predefined fonts "guaranteed" to exist + // when we're running in layout-test mode? if (!equalIgnoringCase(family, winName)) { // For CJK fonts with both English and native names, // GetTextFace returns a native name under the font's "locale" diff --git a/webkit/port/platform/graphics/FontPlatformData.h b/webkit/port/platform/graphics/FontPlatformData.h index ff0d863..25938dc 100644 --- a/webkit/port/platform/graphics/FontPlatformData.h +++ b/webkit/port/platform/graphics/FontPlatformData.h @@ -25,6 +25,7 @@ #define FontPlatformData_H #include "StringImpl.h" +#include <wtf/PassRefPtr.h> #include <wtf/RefCounted.h> typedef struct HFONT__ *HFONT; @@ -36,21 +37,13 @@ class FontDescription; class FontPlatformData { public: - class Deleted {}; - // Used for deleted values in the font cache's hash tables. The hash table // will create us with this structure, and it will compare other values // to this "Deleted" one. It expects the Deleted one to be differentiable // from the NULL one (created with the empty constructor), so we can't just // set everything to NULL. - // - // NOTE: On WebKit trunk now, this is changed to the new value - // WTF::HashTableDeletedValue (declared in RefPtr.h). When we merge to a - // version with that, we should use it and remove our "Deleted" version. - // We would just assign the magic WTF::HashTableDeletedValue to our - // m_font RefPtr. - FontPlatformData(Deleted) - : m_font(RefCountedHFONT::createDeleted()) + FontPlatformData(WTF::HashTableDeletedValueType) + : m_font(hashTableDeletedFontValue()) , m_size(-1) , m_isMLangFont(false) {} @@ -65,6 +58,8 @@ public: bool isMLangFont); FontPlatformData(float size, bool bold, bool oblique); + bool isHashTableDeletedValue() const { return m_font == hashTableDeletedFontValue(); } + ~FontPlatformData(); HFONT hfont() const { return m_font ? m_font->hfont() : 0; } @@ -87,8 +82,10 @@ private: // don't really want to re-create the HFONT. class RefCountedHFONT : public RefCounted<RefCountedHFONT> { public: - static PassRefPtr<RefCountedHFONT> create(HFONT hfont) { return adoptRef(new RefCountedHFONT(hfont)); } - static PassRefPtr<RefCountedHFONT> createDeleted() { return adoptRef(new RefCountedHFONT(reinterpret_cast<HFONT>(-1))); } + static PassRefPtr<RefCountedHFONT> create(HFONT hfont) + { + return adoptRef(new RefCountedHFONT(hfont)); + } ~RefCountedHFONT(); @@ -102,14 +99,15 @@ private: // The create() function assumes there is already a refcount of one // so it can do adoptRef. RefCountedHFONT(HFONT hfont) - : RefCounted<RefCountedHFONT>(1) - , m_hfont(hfont) + : m_hfont(hfont) { } HFONT m_hfont; }; + static RefCountedHFONT* hashTableDeletedFontValue(); + RefPtr<RefCountedHFONT> m_font; float m_size; // Point size of the font in pixels. diff --git a/webkit/port/platform/graphics/FontPlatformDataWin.cpp b/webkit/port/platform/graphics/FontPlatformDataWin.cpp index 53ade3e..2aad126 100644 --- a/webkit/port/platform/graphics/FontPlatformDataWin.cpp +++ b/webkit/port/platform/graphics/FontPlatformDataWin.cpp @@ -55,4 +55,11 @@ FontPlatformData::RefCountedHFONT::~RefCountedHFONT() DeleteObject(m_hfont); } +FontPlatformData::RefCountedHFONT* FontPlatformData::hashTableDeletedFontValue() +{ + static RefPtr<RefCountedHFONT> deletedValue = + RefCountedHFONT::create(reinterpret_cast<HFONT>(-1)); + return deletedValue.get(); +} + } diff --git a/webkit/port/platform/graphics/FontWin.cpp b/webkit/port/platform/graphics/FontWin.cpp index 0287d3f..9bd5a7a 100644 --- a/webkit/port/platform/graphics/FontWin.cpp +++ b/webkit/port/platform/graphics/FontWin.cpp @@ -47,8 +47,6 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const FloatPoint& point) const { PlatformGraphicsContext* context = graphicsContext->platformContext(); - SkPoint origin; - WebCorePointToSkiaPoint(point, &origin); // Max buffer length passed to the underlying windows API. const int kMaxBufferLength = 1024; @@ -84,7 +82,7 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, // the 'point' represents the baseline, so we need to move it up to the // top of the bounding square by subtracting the ascent - SkPoint origin2 = origin; + SkPoint origin2 = point; origin2.fY -= font->ascent(); origin2.fX += chunk_x; @@ -135,10 +133,7 @@ void Font::drawComplexText(GraphicsContext* context, int to) const { UniscribeStateTextRun state(run, *this); - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia(context->platformContext()); - SkPoint p; - WebCorePointToSkiaPoint(point, &p); - skia->paintComplexText(state, p, from, to, ascent()); + context->platformContext()->paintComplexText(state, point, from, to, ascent()); } float Font::floatWidthForComplexText(const TextRun& run) const @@ -161,4 +156,4 @@ int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includ return char_index; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/GradientSkia.cpp b/webkit/port/platform/graphics/GradientSkia.cpp new file mode 100644 index 0000000..b287bde --- /dev/null +++ b/webkit/port/platform/graphics/GradientSkia.cpp @@ -0,0 +1,142 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 "Gradient.h"
+
+#include "CSSParser.h"
+#include "GraphicsContext.h"
+#include "NotImplemented.h"
+
+#include "SkGradientShader.h"
+#include "SkiaUtils.h"
+
+namespace WebCore {
+
+void Gradient::platformDestroy()
+{
+ if (m_gradient)
+ m_gradient->safeUnref();
+ m_gradient = 0;
+}
+
+static inline U8CPU F2B(float x)
+{
+ return static_cast<int>(x * 255);
+}
+
+static SkColor makeSkColor(float a, float r, float g, float b)
+{
+ return SkColorSetARGB(F2B(a), F2B(r), F2B(g), F2B(b));
+}
+
+// Determine the total number of stops needed, including pseudo-stops at the
+// ends as necessary.
+static size_t total_stops_needed(const Gradient::ColorStop* stopData, size_t count)
+{
+ const Gradient::ColorStop* stop = stopData;
+ size_t count_used = count;
+ if (count < 1 || stop->stop > 0.0)
+ count_used++;
+ stop += count - 1;
+ if (count < 2 || stop->stop < 1.0)
+ count_used++;
+ return count_used;
+}
+
+// Collect sorted stop position and color information into the pos and colors
+// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large
+// enough to hold information for all stops, including the new endpoints if
+// stops at 0.0 and 1.0 aren't already included.
+static void fill_stops(const Gradient::ColorStop* stopData,
+ size_t count, SkScalar* pos, SkColor* colors)
+{
+ const Gradient::ColorStop* stop = stopData;
+ size_t start = 0;
+ if (count < 1) {
+ // A gradient with no stops must be transparent black.
+ pos[0] = WebCoreFloatToSkScalar(0.0);
+ colors[0] = makeSkColor(0.0, 0.0, 0.0, 0.0);
+ start = 1;
+ } else if (stop->stop > 0.0) {
+ // Copy the first stop to 0.0. The first stop position may have a slight
+ // rounding error, but we don't care in this float comparison, since
+ // 0.0 comes through cleanly and people aren't likely to want a gradient
+ // with a stop at (0 + epsilon).
+ pos[0] = WebCoreFloatToSkScalar(0.0);
+ colors[0] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue);
+ start = 1;
+ }
+
+ for (size_t i = start; i < start + count; i++) {
+ pos[i] = WebCoreFloatToSkScalar(stop->stop);
+ colors[i] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue);
+ ++stop;
+ }
+
+ // Copy the last stop to 1.0 if needed. See comment above about this float
+ // comparison.
+ if (count < 1 || (--stop)->stop < 1.0) {
+ pos[start + count] = WebCoreFloatToSkScalar(1.0);
+ colors[start + count] = colors[start + count - 1];
+ }
+}
+
+SkShader* Gradient::platformGradient()
+{
+ if (m_gradient)
+ return m_gradient;
+
+ size_t count_used = total_stops_needed(m_stops.data(), m_stops.size());
+ ASSERT(count_used >= 2);
+ ASSERT(count_used >= m_stops.size());
+
+ // FIXME: Why is all this manual pointer math needed?!
+ SkAutoMalloc storage(count_used * (sizeof(SkColor) + sizeof(SkScalar)));
+ SkColor* colors = (SkColor*)storage.get();
+ SkScalar* pos = (SkScalar*)(colors + count_used);
+
+ fill_stops(m_stops.data(), m_stops.size(), pos, colors);
+
+ if (m_radial) {
+ m_gradient = SkGradientShader::CreateRadial(m_p1,
+ WebCoreFloatToSkScalar(m_r1), colors, pos,
+ static_cast<int>(count_used), SkShader::kClamp_TileMode);
+ } else {
+ SkPoint pts[2] = { m_p0, m_p1 };
+ m_gradient = SkGradientShader::CreateLinear(pts, colors, pos,
+ static_cast<int>(count_used), SkShader::kClamp_TileMode);
+ }
+
+ return m_gradient;
+}
+
+void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
+{
+ // Until this is filled, we don't support CSSGradients
+ notImplemented();
+}
+
+} // namespace WebCore
diff --git a/webkit/port/platform/graphics/GraphicsContextPrivate.cpp b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.cpp index d06ee33..7f28d19 100644 --- a/webkit/port/platform/graphics/GraphicsContextPrivate.cpp +++ b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.cpp @@ -19,9 +19,8 @@ #include "config.h" -#include "GraphicsContextPrivate.h" - #include "GraphicsContext.h" +#include "GraphicsContextPlatformPrivate.h" #include "PlatformContextSkia.h" namespace WebCore { diff --git a/webkit/port/platform/graphics/GraphicsContextPrivate.h b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.h index 70e3d60..77f5e89 100644 --- a/webkit/port/platform/graphics/GraphicsContextPrivate.h +++ b/webkit/port/platform/graphics/GraphicsContextPlatformPrivate.h @@ -30,9 +30,7 @@ public: GraphicsContextPlatformPrivate(PlatformContextSkia* pgc); ~GraphicsContextPlatformPrivate(); - PlatformContextSkia* platformContext() { - return m_context; - } + PlatformContextSkia* platformContext() { return m_context; } void setShouldDelete(bool should_delete) { m_should_delete = should_delete; diff --git a/webkit/port/platform/graphics/GraphicsContextSkia.cpp b/webkit/port/platform/graphics/GraphicsContextSkia.cpp index 90eb7ea..d282555 100644 --- a/webkit/port/platform/graphics/GraphicsContextSkia.cpp +++ b/webkit/port/platform/graphics/GraphicsContextSkia.cpp @@ -18,20 +18,22 @@ #include "config.h" #include "GraphicsContext.h" +#include "GraphicsContextPlatformPrivate.h" #include "GraphicsContextPrivate.h" #include "wtf/MathExtras.h" #include "Assertions.h" #include "AffineTransform.h" +#include "FloatRect.h" +#include "Gradient.h" +#include "IntRect.h" #include "NativeImageSkia.h" +#include "NotImplemented.h" #include "SkBlurDrawLooper.h" #include "SkCornerPathEffect.h" #include "SkiaUtils.h" -#ifdef ANDROID_CANVAS_IMPL -# include "SkBitmap.h" -# include "SkGradientShader.h" -#endif +#include "SkBitmap.h" #include "base/gfx/platform_canvas_win.h" @@ -165,70 +167,6 @@ void add_corner_arc(SkPath* path, const SkRect& rect, const IntSize& size, int s path->arcTo(r, SkIntToScalar(startAngle), SkIntToScalar(90), false); } -U8CPU F2B(float x) -{ - return (int)(x * 255); -} - -SkColor make_color(float a, float r, float g, float b) -{ - return SkColorSetARGB(F2B(a), F2B(r), F2B(g), F2B(b)); -} - -// Determine the total number of stops needed, including pseudo-stops at the -// ends as necessary. -size_t total_stops_needed(const WebCore::CanvasGradient::ColorStop* stopData, - size_t count) -{ - const WebCore::CanvasGradient::ColorStop* stop = stopData; - size_t count_used = count; - if (count < 1 || stop->stop > 0.0) - count_used++; - stop += count - 1; - if (count < 2 || stop->stop < 1.0) - count_used++; - return count_used; -} - -// Collect sorted stop position and color information into the pos and colors -// buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large -// enough to hold information for all stops, including the new endpoints if -// stops at 0.0 and 1.0 aren't already included. -void fill_stops(const WebCore::CanvasGradient::ColorStop* stopData, - size_t count, SkScalar* pos, SkColor* colors) -{ - const WebCore::CanvasGradient::ColorStop* stop = stopData; - size_t start = 0; - if (count < 1) { - // A gradient with no stops must be transparent black. - pos[0] = WebCoreFloatToSkScalar(0.0); - colors[0] = make_color(0.0, 0.0, 0.0, 0.0); - start = 1; - } else if (stop->stop > 0.0) { - // Copy the first stop to 0.0. The first stop position may have a slight - // rounding error, but we don't care in this float comparison, since - // 0.0 comes through cleanly and people aren't likely to want a gradient - // with a stop at (0 + epsilon). - pos[0] = WebCoreFloatToSkScalar(0.0); - colors[0] = make_color(stop->alpha, stop->red, stop->green, stop->blue); - start = 1; - } - - for (size_t i = start; i < start + count; i++) - { - pos[i] = WebCoreFloatToSkScalar(stop->stop); - colors[i] = make_color(stop->alpha, stop->red, stop->green, stop->blue); - ++stop; - } - - // Copy the last stop to 1.0 if needed. See comment above about this float - // comparison. - if (count < 1 || (--stop)->stop < 1.0) { - pos[start + count] = WebCoreFloatToSkScalar(1.0); - colors[start + count] = colors[start + count - 1]; - } -} - COMPILE_ASSERT(GraphicsContextPlatformPrivate::NoStroke == NoStroke, AssertNoStroke); COMPILE_ASSERT(GraphicsContextPlatformPrivate::SolidStroke == SolidStroke, AssertSolidStroke); COMPILE_ASSERT(GraphicsContextPlatformPrivate::DottedStroke == DottedStroke, AssertDottedStroke); @@ -248,7 +186,7 @@ GraphicsContextPlatformPrivate::StrokeStyle StrokeStyle2StrokeStyle(StrokeStyle // no painting. GraphicsContext::GraphicsContext(PlatformGraphicsContext *gc) : m_common(createGraphicsContextPrivate()) - , m_data(new GraphicsContextPlatformPrivate(PlatformContextToPlatformContextSkia(gc))) + , m_data(new GraphicsContextPlatformPrivate(gc)) { setPaintingDisabled(!m_data->canvas()); } @@ -277,9 +215,8 @@ void GraphicsContext::drawRect(const IntRect& rect) if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // See the fillRect below. ClipRectToCanvas(*m_data->canvas(), r, &r); } @@ -298,21 +235,17 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) return; SkPaint paint; - SkPoint pts[2]; - - WebCorePointToSkiaPoint(point1, &pts[0]); - WebCorePointToSkiaPoint(point2, &pts[1]); - if (!IsPointReasonable(m_data->canvas()->getTotalMatrix(), pts[0]) || - !IsPointReasonable(m_data->canvas()->getTotalMatrix(), pts[1])) + SkPoint pts[2] = { (SkPoint)point1, (SkPoint)point2 }; + if (!IsPointReasonable(getCTM(), pts[0]) || + !IsPointReasonable(getCTM(), pts[1])) return; //we know these are vertical or horizontal lines, so the length will just be the sum of the //displacement component vectors give or take 1 - probably worth the speed up of no square //root, which also won't be exact - SkPoint disp = pts[1]-pts[0]; - int length = SkScalarRound(disp.fX+disp.fY); - //int length = SkScalarRound(disp.length()); - int width = m_data->setup_paint_stroke(&paint, NULL, length); + SkPoint disp = pts[1] - pts[0]; + int length = SkScalarRound(disp.fX + disp.fY); + int width = m_data->setup_paint_stroke(&paint, 0, length); // "borrowed" this comment and idea from GraphicsContextCG.cpp // For odd widths, we add in 0.5 to the appropriate x/y so that the float arithmetic @@ -324,12 +257,10 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2) if (width & 1) //odd { - if (isVerticalLine) - { + if (isVerticalLine) { pts[0].fX = pts[0].fX + SK_ScalarHalf; pts[1].fX = pts[0].fX; - } - else //Horizontal line + } else //Horizontal line { pts[0].fY = pts[0].fY + SK_ScalarHalf; pts[1].fY = pts[0].fY; @@ -439,26 +370,24 @@ void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& pt, } // This method is only used to draw the little circles used in lists. -void GraphicsContext::drawEllipse(const IntRect& rect) +void GraphicsContext::drawEllipse(const IntRect& elipseRect) { if (paintingDisabled()) return; - SkPaint paint; - SkRect oval; - - WebCoreRectToSkiaRect(rect, &oval); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), oval)) + SkRect rect = elipseRect; + if (!IsRectReasonable(getCTM(), rect)) return; + SkPaint paint; if (fillColor().rgb() & 0xFF000000) { m_data->setup_paint_fill(&paint); - m_data->canvas()->drawOval(oval, paint); + m_data->canvas()->drawOval(rect, paint); } if (strokeStyle() != NoStroke) { paint.reset(); - m_data->setup_paint_stroke(&paint, &oval, 0); - m_data->canvas()->drawOval(oval, paint); + m_data->setup_paint_stroke(&paint, &rect, 0); + m_data->canvas()->drawOval(rect, paint); } } @@ -478,27 +407,23 @@ void GraphicsContext::strokeArc(const IntRect& r, int startAngle, int angleSpan) if (paintingDisabled()) return; - SkPath path; SkPaint paint; - SkRect oval; - - WebCoreRectToSkiaRect(r, &oval); + SkRect oval = r; if (strokeStyle() == NoStroke) { m_data->setup_paint_fill(&paint); // we want the fill color paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(WebCoreFloatToSkScalar(strokeThickness())); - } - else { + } else m_data->setup_paint_stroke(&paint, NULL, 0); - } // we do this before converting to scalar, so we don't overflow SkFixed startAngle = fast_mod(startAngle, 360); angleSpan = fast_mod(angleSpan, 360); + SkPath path; path.addArc(oval, SkIntToScalar(-startAngle), SkIntToScalar(-angleSpan)); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), path)) + if (!IsPathReasonable(getCTM(), path)) return; m_data->canvas()->drawPath(path, paint); } @@ -511,7 +436,6 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin if (numPoints <= 1) return; - SkPaint paint; SkPath path; path.incReserve(numPoints); @@ -519,9 +443,10 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin for (size_t i = 1; i < numPoints; i++) path.lineTo(WebCoreFloatToSkScalar(points[i].x()), WebCoreFloatToSkScalar(points[i].y())); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), path)) + if (!IsPathReasonable(getCTM(), path)) return; + SkPaint paint; if (fillColor().rgb() & 0xFF000000) { m_data->setup_paint_fill(&paint); m_data->canvas()->drawPath(path, paint); @@ -534,171 +459,115 @@ void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* poin } } -#ifdef ANDROID_CANVAS_IMPL - -static void check_set_shader(SkPaint* paint, SkShader* s0, SkShader* s1) -{ - if (s0) { - paint->setShader(s0); - } - else if (s1) { - paint->setShader(s1); - } -} - - -void GraphicsContext::fillPath(const Path& webCorePath, PlatformGradient* grad, PlatformPattern* pat) -{ - fillPath(PathToSkPath(webCorePath), grad, pat); -} - -void GraphicsContext::fillPath(PlatformPath* path, PlatformGradient* grad, PlatformPattern* pat) +void GraphicsContext::fillPath() { if (paintingDisabled()) return; - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), *path)) + const SkPath& path = *m_data->currentPath(); + if (!IsPathReasonable(getCTM(), path)) return; - SkPaint paint; + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.fillColorSpace; - m_data->setup_paint_fill(&paint); - check_set_shader(&paint, grad, pat); + if (colorSpace == SolidColorSpace && !fillColor().alpha()) + return; - m_data->canvas()->drawPath(*path, paint); -} + SkPaint paint; + m_data->setup_paint_fill(&paint); + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.fillPattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.fillGradient->platformGradient()); -void GraphicsContext::strokePath(const Path& webCorePath, PlatformGradient* grad, PlatformPattern* pat) -{ - strokePath(PathToSkPath(webCorePath), grad, pat); + m_data->canvas()->drawPath(path, paint); } -void GraphicsContext::strokePath(PlatformPath* path, PlatformGradient* grad, PlatformPattern* pat) +void GraphicsContext::strokePath() { if (paintingDisabled()) return; - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), *path)) + const SkPath& path = *m_data->currentPath(); + if (!IsPathReasonable(getCTM(), path)) return; - SkPaint paint; + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.strokeColorSpace; + + if (colorSpace == SolidColorSpace && !strokeColor().alpha()) + return; + SkPaint paint; m_data->setup_paint_stroke(&paint, NULL, 0); - check_set_shader(&paint, grad, pat); - m_data->canvas()->drawPath(*path, paint); + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.strokePattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.strokeGradient->platformGradient()); + + m_data->canvas()->drawPath(path, paint); } -void GraphicsContext::fillRect(const FloatRect& rect, PlatformGradient* grad, PlatformPattern* pat) +void GraphicsContext::fillRect(const FloatRect& rect) { if (paintingDisabled()) return; - SkPaint paint; - m_data->setup_paint_fill(&paint); - check_set_shader(&paint, grad, pat); - - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // See the other version of fillRect below. ClipRectToCanvas(*m_data->canvas(), r, &r); } - m_data->canvas()->drawRect(r, paint); -} + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.fillColorSpace; -void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth, PlatformGradient* grad, PlatformPattern* pat) -{ - if (paintingDisabled()) + if (colorSpace == SolidColorSpace && !fillColor().alpha()) return; SkPaint paint; - m_data->setup_paint_stroke(&paint, NULL, 0); - paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); - check_set_shader(&paint, grad, pat); + m_data->setup_paint_fill(&paint); - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) - return; + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.fillPattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.fillGradient->platformGradient()); m_data->canvas()->drawRect(r, paint); } -PlatformGradient* GraphicsContext::newPlatformLinearGradient(const FloatPoint& p0, - const FloatPoint& p1, - const WebCore::CanvasGradient::ColorStop* stopData, size_t count) +void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) { - SkPoint pts[2]; - WebCorePointToSkiaPoint(p0, &pts[0]); - WebCorePointToSkiaPoint(p1, &pts[1]); - - size_t count_used = total_stops_needed(stopData, count); - ASSERT(count_used >= 2); - ASSERT(count_used >= count); - - SkAutoMalloc storage(count_used * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + count_used); - - fill_stops(stopData, count, pos, colors); - return SkGradientShader::CreateLinear(pts, colors, pos, - static_cast<int>(count_used), - SkShader::kClamp_TileMode); -} - -PlatformGradient* GraphicsContext::newPlatformRadialGradient(const FloatPoint& p0, float r0, - const FloatPoint& p1, float r1, - const WebCore::CanvasGradient::ColorStop* stopData, size_t count) -{ - SkPoint center; - WebCorePointToSkiaPoint(p1, ¢er); - SkMatrix identity; - identity.reset(); - if (!IsPointReasonable(identity, center)) { - center.fX = 0; - center.fY = 0; - } - - size_t count_used = total_stops_needed(stopData, count); - ASSERT(count_used >= 2); - ASSERT(count_used >= count); - - SkAutoMalloc storage(count_used * (sizeof(SkColor) + sizeof(SkScalar))); - SkColor* colors = (SkColor*)storage.get(); - SkScalar* pos = (SkScalar*)(colors + count_used); - - fill_stops(stopData, count, pos, colors); - return SkGradientShader::CreateRadial(center, WebCoreFloatToSkScalar(r1), - colors, pos, - static_cast<int>(count_used), - SkShader::kClamp_TileMode); -} + if (paintingDisabled()) + return; + if (!IsRectReasonable(getCTM(), rect)) + return; -void GraphicsContext::freePlatformGradient(PlatformGradient* shader) -{ - shader->safeUnref(); -} + const GraphicsContextState& state = m_common->state; + ColorSpace colorSpace = state.strokeColorSpace; -PlatformPattern* GraphicsContext::newPlatformPattern(Image* image, - Image::TileRule hRule, - Image::TileRule vRule) -{ - if (NULL == image) - return NULL; + if (colorSpace == SolidColorSpace && !strokeColor().alpha()) + return; - NativeImageSkia* bm = image->getBitmap(); - if (NULL == bm) - return NULL; + SkPaint paint; + m_data->setup_paint_stroke(&paint, NULL, 0); + paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); - return SkShader::CreateBitmapShader(*bm, - WebCoreTileToSkiaTile(hRule), - WebCoreTileToSkiaTile(vRule)); -} + if (colorSpace == PatternColorSpace) { + SkShader* pat = state.strokePattern->createPlatformPattern(getCTM()); + paint.setShader(pat); + pat->unref(); + } else if (colorSpace == GradientColorSpace) + paint.setShader(state.strokeGradient->platformGradient()); -void GraphicsContext::freePlatformPattern(PlatformPattern* shader) -{ - shader->safeUnref(); + m_data->canvas()->drawRect(rect, paint); } GraphicsContext* GraphicsContext::createOffscreenContext(int width, int height) @@ -725,21 +594,20 @@ void GraphicsContext::drawOffscreenContext(GraphicsContext* ctx, const FloatRect if (paintingDisabled() || ctx->paintingDisabled()) return; - const SkBitmap& bm = ctx->m_data->canvas()->getDevice()->accessBitmap(false); - SkIRect src; - SkRect dst; - SkPaint paint; + SkIRect src; if (srcRect) { - WebCoreRectToSkiaRect(*srcRect, &src); - // FIXME(brettw) FIX THIS YOU RETARD! + src = enclosingIntRect(*srcRect); + if (!IsRectReasonable(getCTM(), *srcRect)) + return; } - - WebCoreRectToSkiaRect(dstRect, &dst); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), dst)) + SkRect dst = dstRect; + if (!IsRectReasonable(getCTM(), dst)) return; + SkPaint paint; paint.setFilterBitmap(true); + const SkBitmap& bm = ctx->m_data->canvas()->getDevice()->accessBitmap(false); m_data->canvas()->drawBitmapRect(bm, srcRect ? &src : NULL, dst, @@ -749,38 +617,33 @@ void GraphicsContext::drawOffscreenContext(GraphicsContext* ctx, const FloatRect FloatRect GraphicsContext::getClipLocalBounds() const { SkRect r; - if (!m_data->canvas()->getClipBounds(&r)) r.setEmpty(); - return FloatRect(SkScalarToFloat(r.fLeft), SkScalarToFloat(r.fTop), - SkScalarToFloat(r.width()), SkScalarToFloat(r.height())); + return r; } -FloatRect GraphicsContext::getPathBoundingBox(const Path& path) const +FloatRect GraphicsContext::getBoundingBoxForCurrentPath(bool includeStroke) const { - SkRect r; - SkPaint paint; - m_data->setup_paint_stroke(&paint, NULL, 0); - SkPath boundingPath; - paint.getFillPath(*path.platformPath(), &boundingPath); + if (includeStroke) { + SkPaint paint; + m_data->setup_paint_stroke(&paint, NULL, 0); + paint.getFillPath(*m_data->currentPath(), &boundingPath); + } else + boundingPath = *m_data->currentPath(); + + SkRect r; boundingPath.computeBounds(&r, SkPath::kExact_BoundsType); - return FloatRect( - SkScalarToFloat(r.fLeft), - SkScalarToFloat(r.fTop), - SkScalarToFloat(r.width()), - SkScalarToFloat(r.height())); + return r; } bool GraphicsContext::strokeContains(const Path& path, const FloatPoint& point) const { - SkRegion rgn, clip; SkPaint paint; - m_data->setup_paint_stroke(&paint, NULL, 0); SkPath strokePath; @@ -789,33 +652,14 @@ bool GraphicsContext::strokeContains(const Path& path, const FloatPoint& point) return SkPathContainsPoint(&strokePath, point, SkPath::kWinding_FillType); } - -#endif // ANDROID_CANVAS_IMPL - -#if 0 -static int getBlendedColorComponent(int c, int a) -{ - // We use white. - float alpha = (float)(a) / 255; - int whiteBlend = 255 - a; - c -= whiteBlend; - return (int)(c/alpha); -} -#endif - -void GraphicsContext::fillRect(const IntRect& rect, const Color& color) +void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) { if (paintingDisabled()) return; if (color.rgb() & 0xFF000000) { - SkPaint paint; - SkRect r; - - WebCoreRectToSkiaRect(rect, &r); - - static const float kMaxCoord = 32767; - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // Special case when the rectangle overflows fixed point. This is a // workaround to fix bug 1212844. When the input rectangle is very // large, it can overflow Skia's internal fixed point rect. This @@ -829,27 +673,7 @@ void GraphicsContext::fillRect(const IntRect& rect, const Color& color) ClipRectToCanvas(*m_data->canvas(), r, &r); } - m_data->setup_paint_common(&paint); - paint.setColor(color.rgb()); - m_data->canvas()->drawRect(r, paint); - } -} - -void GraphicsContext::fillRect(const FloatRect& rect, const Color& color) -{ - if (paintingDisabled()) - return; - - if (color.rgb() & 0xFF000000) { SkPaint paint; - SkRect r; - - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { - // See other fillRect() above. - ClipRectToCanvas(*m_data->canvas(), r, &r); - } - m_data->setup_paint_common(&paint); paint.setColor(color.rgb()); m_data->canvas()->drawRect(r, paint); @@ -862,34 +686,31 @@ void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLef if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) { + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) { // See fillRect(). ClipRectToCanvas(*m_data->canvas(), r, &r); } - SkPaint paint; SkPath path; - add_corner_arc(&path, r, topRight, 270); add_corner_arc(&path, r, bottomRight, 0); add_corner_arc(&path, r, bottomLeft, 90); add_corner_arc(&path, r, topLeft, 180); + SkPaint paint; m_data->setup_paint_fill(&paint); m_data->canvas()->drawPath(path, paint); return fillRect(rect, color); } -void GraphicsContext::clip(const IntRect& rect) +void GraphicsContext::clip(const FloatRect& rect) { if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + SkRect r(rect); + if (!IsRectReasonable(getCTM(), r)) return; m_data->canvas()->clipRect(r); @@ -900,8 +721,8 @@ void GraphicsContext::clip(const Path& path) if (paintingDisabled()) return; - const SkPath& p = *PathToSkPath(path); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), p)) + const SkPath& p = *path.platformPath(); + if (!IsPathReasonable(getCTM(), p)) return; m_data->canvas()->clipPath(p); @@ -911,16 +732,15 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness { if (paintingDisabled()) return; - SkPath path; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + + SkRect r(rect); + if (!IsRectReasonable(getCTM(), r)) return; + SkPath path; path.addOval(r, SkPath::kCW_Direction); // only perform the inset if we won't invert r - if (2*thickness < rect.width() && 2*thickness < rect.height()) - { + if (2*thickness < rect.width() && 2*thickness < rect.height()) { r.inset(SkIntToScalar(thickness) ,SkIntToScalar(thickness)); path.addOval(r, SkPath::kCCW_Direction); } @@ -932,9 +752,9 @@ void GraphicsContext::clipOut(const IntRect& rect) { if (paintingDisabled()) return; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + + SkRect r(rect); + if (!IsRectReasonable(getCTM(), r)) return; m_data->canvas()->clipRect(r, SkRegion::kDifference_Op); @@ -944,13 +764,12 @@ void GraphicsContext::clipOutEllipseInRect(const IntRect& rect) { if (paintingDisabled()) return; - SkRect oval; - SkPath path; - WebCoreRectToSkiaRect(rect, &oval); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), oval)) + SkRect oval(rect); + if (!IsRectReasonable(getCTM(), oval)) return; + SkPath path; path.addOval(oval, SkPath::kCCW_Direction); m_data->canvas()->clipPath(path, SkRegion::kDifference_Op); } @@ -960,18 +779,12 @@ void GraphicsContext::clipOut(const Path& p) if (paintingDisabled()) return; - const SkPath& path = *PathToSkPath(p); - if (!IsPathReasonable(m_data->canvas()->getTotalMatrix(), path)) + const SkPath& path = *p.platformPath(); + if (!IsPathReasonable(getCTM(), path)) return; - m_data->canvas()->clipPath(path, SkRegion::kDifference_Op); -} -#if SVG_SUPPORT -KRenderingDeviceContext* GraphicsContext::createRenderingDeviceContext() -{ - return new KRenderingDeviceContextQuartz(platformContext()); + m_data->canvas()->clipPath(path, SkRegion::kDifference_Op); } -#endif void GraphicsContext::beginTransparencyLayer(float opacity) { @@ -1001,13 +814,17 @@ void GraphicsContext::endTransparencyLayer() m_data->canvas()->restore(); } -void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& color) +void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle& stroke) +{ + m_data->setStrokeStyle(StrokeStyle2StrokeStyle(stroke)); +} + +void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color) { if (paintingDisabled()) return; - if (blur > 0) - { + if (blur > 0) { SkColor c; if (color.isValid()) @@ -1020,16 +837,12 @@ void GraphicsContext::setShadow(const IntSize& size, int blur, const Color& colo SkIntToScalar(size.height()), c); m_data->setDrawLooper(dl)->unref(); - } - else + } else m_data->setDrawLooper(NULL); } -void GraphicsContext::clearShadow() +void GraphicsContext::clearPlatformShadow() { - if (paintingDisabled()) - return; - m_data->setDrawLooper(NULL); } @@ -1044,10 +857,8 @@ void GraphicsContext::drawFocusRing(const Color& color) SkRegion exterior_region; const SkScalar exterior_offset = WebCoreFloatToSkScalar(0.5); - for (unsigned i = 0; i < rectCount; i++) - { - SkIRect r; - WebCoreRectToSkiaRect(rects[i], &r); + for (unsigned i = 0; i < rectCount; i++) { + SkIRect r = rects[i]; r.inset(-exterior_offset, -exterior_offset); exterior_region.op(r, SkRegion::kUnion_Op); } @@ -1090,31 +901,13 @@ void GraphicsContext::clearRect(const FloatRect& rect) if (paintingDisabled()) return; - SkPaint paint; - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) + SkRect r = rect; + if (!IsRectReasonable(getCTM(), r)) ClipRectToCanvas(*m_data->canvas(), r, &r); - m_data->setup_paint_fill(&paint); - paint.setPorterDuffXfermode(SkPorterDuff::kClear_Mode); - m_data->canvas()->drawRect(r, paint); -} - -void GraphicsContext::strokeRect(const FloatRect& rect, float lineWidth) -{ - if (paintingDisabled()) - return; - SkPaint paint; - SkRect r; - - WebCoreRectToSkiaRect(rect, &r); - if (!IsRectReasonable(m_data->canvas()->getTotalMatrix(), r)) - return; - m_data->setup_paint_fill(&paint); - paint.setStrokeWidth(WebCoreFloatToSkScalar(lineWidth)); + paint.setPorterDuffXfermode(SkPorterDuff::kClear_Mode); m_data->canvas()->drawRect(r, paint); } @@ -1154,21 +947,6 @@ void GraphicsContext::setLineJoin(LineJoin join) } } -void GraphicsContext::setFillRule(WindRule rule) -{ - switch (rule) { - case RULE_NONZERO: - m_data->setFillRule(SkPath::kWinding_FillType); - break; - case RULE_EVENODD: - m_data->setFillRule(SkPath::kEvenOdd_FillType); - break; - default: - SkDEBUGF(("GraphicsContext::setFillRule: unknown WindRule %d\n", rule)); - break; - } -} - void GraphicsContext::scale(const FloatSize& size) { if (paintingDisabled()) @@ -1200,15 +978,16 @@ AffineTransform GraphicsContext::getCTM() const return m_data->canvas()->getTotalMatrix(); } - -HDC GraphicsContext::getWindowsContext(bool supportAlphaBlend, const IntRect*) { +HDC GraphicsContext::getWindowsContext(const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap) +{ if (paintingDisabled()) - return NULL; + return 0; // No need to ever call endPlatformPaint() since it is a noop. return m_data->canvas()->beginPlatformPaint(); } -void GraphicsContext::releaseWindowsContext(HDC hdc, bool supportAlphaBlend, const IntRect*) { +void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect&, bool supportAlphaBlend, bool mayCreateBitmap) +{ // noop, the DC will be lazily freed by the bitmap when no longer needed } @@ -1267,10 +1046,14 @@ void GraphicsContext::setPlatformFillColor(const Color& color) m_data->setFillColor(color.rgb()); } +/* +TODO(brettw): WebKit's implementation of this function moved into the cross- +platform file GraphicsContext.cpp. We need to figure out how to hook this up +properly once everything links. void GraphicsContext::setPlatformStrokeStyle(const StrokeStyle & strokestyle) { m_data->setStrokeStyle(StrokeStyle2StrokeStyle(strokestyle)); -} +}*/ void GraphicsContext::setPlatformStrokeColor(const Color& strokecolor) { @@ -1284,7 +1067,7 @@ void GraphicsContext::setPlatformStrokeThickness(float thickness) void GraphicsContext::addPath(const Path& path) { - m_data->addPath(*PathToSkPath(path)); + m_data->addPath(*path.platformPath()); } void GraphicsContext::beginPath() @@ -1305,9 +1088,36 @@ void GraphicsContext::setShouldDelete(bool should_delete) m_data->setShouldDelete(should_delete); } -PlatformPath* GraphicsContext::currentPath() +// TODO(eseidel): This is needed for image masking and complex text fills +void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer) +{ + if (paintingDisabled()) + return; + + notImplemented(); +} + +void GraphicsContext::setImageInterpolationQuality(InterpolationQuality) +{ + notImplemented(); +} + +// Skia platform gradients and patterns are handled at draw time +// Upstream is considering removing these methods anyway +void GraphicsContext::setPlatformStrokePattern(Pattern* pattern) +{ +} + +void GraphicsContext::setPlatformFillPattern(Pattern* pattern) +{ +} + +void GraphicsContext::setPlatformStrokeGradient(Gradient*) +{ +} + +void GraphicsContext::setPlatformFillGradient(Gradient*) { - return m_data->currentPath(); } } diff --git a/webkit/port/platform/graphics/IconWin.cpp b/webkit/port/platform/graphics/IconWin.cpp index b348f45..6c17a53 100644 --- a/webkit/port/platform/graphics/IconWin.cpp +++ b/webkit/port/platform/graphics/IconWin.cpp @@ -31,11 +31,6 @@ namespace WebCore { -Icon::Icon() - : m_hIcon(0) -{ -} - Icon::Icon(HICON icon) : m_hIcon(icon) { @@ -56,9 +51,7 @@ PassRefPtr<Icon> Icon::newIconForFile(const String& filename) if (!SHGetFileInfo(tmpFilename.charactersWithNullTermination(), 0, &sfi, sizeof(sfi), SHGFI_ICON | SHGFI_SHELLICONSIZE | SHGFI_SMALLICON)) return 0; - Icon* icon = new Icon(); - icon->m_hIcon = sfi.hIcon; - return icon; + return adoptRef(new Icon(sfi.hIcon)); } void Icon::paint(GraphicsContext* context, const IntRect& r) @@ -66,9 +59,7 @@ void Icon::paint(GraphicsContext* context, const IntRect& r) if (context->paintingDisabled()) return; - SkIRect rect; - WebCoreRectToSkiaRect(r, &rect); - PlatformContextToPlatformContextSkia(context->platformContext())->paintIcon(m_hIcon, rect); + context->platformContext()->paintIcon(m_hIcon, r); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/ImageBufferSkia.cpp b/webkit/port/platform/graphics/ImageBufferSkia.cpp index dcad45a..e1d9c90 100644 --- a/webkit/port/platform/graphics/ImageBufferSkia.cpp +++ b/webkit/port/platform/graphics/ImageBufferSkia.cpp @@ -30,13 +30,12 @@ #include "config.h" #include "ImageBuffer.h" +#include "BitmapImage.h" #include "GraphicsContext.h" -#include "PlatformContextSkia.h" -#include <cairo.h> - -#include "SkBitmap.h" - +#include "ImageData.h" #include "NotImplemented.h" +#include "PlatformContextSkia.h" +#include "SkiaUtils.h" using namespace std; @@ -44,26 +43,50 @@ namespace WebCore { auto_ptr<ImageBuffer> ImageBuffer::create(const IntSize& size, bool) { - return auto_ptr<ImageBuffer>(new ImageBuffer(size)); + return auto_ptr<ImageBuffer>(new ImageBuffer(size)); +} + +GraphicsContext* ImageBuffer::context() const +{ + return m_context.get(); } -const SkBitmap* ImageBuffer::image() const +Image* ImageBuffer::image() const { - return m_context.get()->platformContext()->bitmap(); + if (!m_image) { + // It's assumed that if image() is called, the actual rendering to + // the GraphicsContext must be done. + ASSERT(context()); + const SkBitmap* bitmap = context()->platformContext()->bitmap(); + m_image = BitmapImage::create(); + // TODO(tc): This is inefficient because we serialize then re-interpret + // the image. If this matters for performance, we should add another + // BitmapImage::create method that takes a SkBitmap (similar to what + // CoreGraphics does). + m_image->setData(SerializeSkBitmap(*bitmap), true); + } + return m_image.get(); } -cairo_surface_t* ImageBuffer::surface() const +PassRefPtr<ImageData> ImageBuffer::getImageData(const IntRect&) const { notImplemented(); - return NULL; + return 0; } -GraphicsContext* ImageBuffer::context() const +void ImageBuffer::putImageData(ImageData*, const IntRect&, const IntPoint&) { - return m_context.get(); + notImplemented(); +} + +String ImageBuffer::toDataURL(const String&) const +{ + notImplemented(); + return String(); } ImageBuffer::ImageBuffer(const IntSize& size) : + m_data(0), m_size(size), m_context(GraphicsContext::createOffscreenContext(size.width(), size.height())) { diff --git a/webkit/port/platform/graphics/ImageSkia.cpp b/webkit/port/platform/graphics/ImageSkia.cpp index 359f6c0..1989eba8 100644 --- a/webkit/port/platform/graphics/ImageSkia.cpp +++ b/webkit/port/platform/graphics/ImageSkia.cpp @@ -77,42 +77,6 @@ void TransformDimensions(const SkMatrix& matrix, *dest_height = SkScalarToFloat((dest_points[2] - dest_points[0]).length()); } -// Constructs a BMP V4 bitmap from an SkBitmap. -PassRefPtr<SharedBuffer> SerializeBitmap(const SkBitmap& bitmap) -{ - int width = bitmap.width(); - int height = bitmap.height(); - - // Create a BMP v4 header that we can serialize. - BITMAPV4HEADER v4Header; - gfx::CreateBitmapV4Header(width, height, &v4Header); - v4Header.bV4SizeImage = width * sizeof(uint32_t) * height; - - // Serialize the bitmap. - BITMAPFILEHEADER fileHeader; - fileHeader.bfType = 0x4d42; // "BM" header - fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + v4Header.bV4Size; - fileHeader.bfSize = fileHeader.bfOffBits + v4Header.bV4SizeImage; - fileHeader.bfReserved1 = fileHeader.bfReserved2 = 0; - - // Write BITMAPFILEHEADER - RefPtr<SharedBuffer> buffer(new SharedBuffer( - reinterpret_cast<const char*>(&fileHeader), - sizeof(BITMAPFILEHEADER))); - - // Write BITMAPINFOHEADER - buffer->append(reinterpret_cast<const char*>(&v4Header), - sizeof(BITMAPV4HEADER)); - - // Write the image body. - SkAutoLockPixels bitmap_lock(bitmap); - buffer->append(reinterpret_cast<const char*>(bitmap.getAddr32(0, 0)), - v4Header.bV4SizeImage); - - return buffer; -} - - // Creates an Image for the text area resize corner. We do this by drawing the // theme native control into a memory buffer then converting the memory buffer // into a BMP byte stream, then feeding it into the Image object. We have to @@ -120,9 +84,9 @@ PassRefPtr<SharedBuffer> SerializeBitmap(const SkBitmap& bitmap) // us to directly manipulate the image data. We don't bother caching this // image because the caller holds onto a static copy (see // WebCore/rendering/RenderLayer.cpp). -void GetTextAreaResizeCorner(Image* image) +static PassRefPtr<Image> GetTextAreaResizeCorner() { - ASSERT(image); + RefPtr<Image> image = BitmapImage::create(); // Get the size of the resizer. const int width = PlatformScrollbar::verticalScrollbarWidth(); @@ -139,12 +103,8 @@ void GetTextAreaResizeCorner(Image* image) gfx::NativeTheme::instance()->PaintStatusGripper(hdc, SP_GRIPPER, 0, 0, &widgetRect); device.postProcessGDI(0, 0, width, height); - image->setData(SerializeBitmap(device.accessBitmap(false)), true); -} - -// Convert from what WebKit thinks the type is, to what it is for our port -inline NativeImageSkia* ToSkiaFrame(NativeImagePtr native) { - return reinterpret_cast<NativeImageSkia*>(native); + image->setData(SerializeSkBitmap(device.accessBitmap(false)), true); + return image.release(); } } // namespace @@ -157,91 +117,83 @@ void FrameData::clear() m_hasAlpha = true; } +static inline PassRefPtr<Image> loadImageWithResourceId(int resourceId) +{ + RefPtr<Image> image = BitmapImage::create(); + // Load the desired resource. + std::string data(webkit_glue::GetDataResource(resourceId)); + RefPtr<SharedBuffer> buffer(SharedBuffer::create(data.data(), data.length())); + image->setData(buffer, true); + return image.release(); +} + // static -Image* Image::loadPlatformResource(const char *name) +PassRefPtr<Image> Image::loadPlatformResource(const char *name) { - Image* image = new BitmapImage; - - // Figure out which resource ID the caller wanted. - int resource_id; - if (!strcmp(name, "missingImage")) { - resource_id = IDR_BROKENIMAGE; - } else if (!strcmp(name, "tickmarkDash")) { - resource_id = IDR_TICKMARK_DASH; - } else if (!strcmp(name, "textAreaResizeCorner")) { - GetTextAreaResizeCorner(image); - return image; - } else if (!strcmp(name, "deleteButton") || - !strcmp(name, "deleteButtonPressed")) { + if (!strcmp(name, "missingImage")) + return loadImageWithResourceId(IDR_BROKENIMAGE); + if (!strcmp(name, "tickmarkDash")) + return loadImageWithResourceId(IDR_TICKMARK_DASH); + if (!strcmp(name, "textAreaResizeCorner")) + return GetTextAreaResizeCorner(); + if (!strcmp(name, "deleteButton") || !strcmp(name, "deleteButtonPressed")) { LOG(NotYetImplemented, "Image resource %s does not yet exist\n", name); - return image; - } else { - LOG(NotYetImplemented, "Unknown image resource %s requested\n", name); - return image; + return Image::nullImage(); } - // Load the desired resource. - std::string data(webkit_glue::GetDataResource(resource_id)); - RefPtr<SharedBuffer> buffer(new SharedBuffer(data.data(), data.length())); - image->setData(buffer, true); - return image; + LOG(NotYetImplemented, "Unknown image resource %s requested\n", name); + return Image::nullImage(); } -static bool subsetBitmap(SkBitmap* dst, const SkBitmap& src, const FloatRect& r) +static bool subsetBitmap(SkBitmap* dst, const SkBitmap& src, const FloatRect& clip) { - SkIRect bounds, clip; - bounds.set(0, 0, src.width(), src.height()); - WebCoreRectToSkiaRect(r, &clip); - + FloatRect floatBounds(0, 0, src.width(), src.height()); + if (!floatBounds.intersects(clip)) + return false; + SkAutoLockPixels src_lock(src); - if (bounds.intersect(clip)) - { - void* addr; - switch (src.getConfig()) { - case SkBitmap::kIndex8_Config: - case SkBitmap::kA8_Config: - addr = (void*)src.getAddr8(bounds.fLeft, bounds.fTop); - break; - case SkBitmap::kRGB_565_Config: - addr = (void*)src.getAddr16(bounds.fLeft, bounds.fTop); - break; - case SkBitmap::kARGB_8888_Config: - addr = (void*)src.getAddr32(bounds.fLeft, bounds.fTop); - break; - default: - SkDEBUGF(("subset_bitmap: can't subset this bitmap config %d\n", src.getConfig())); - return false; - } - dst->setConfig(src.getConfig(), bounds.width(), bounds.height(), src.rowBytes()); - dst->setPixels(addr); + IntRect bounds(floatBounds); + void* addr; + switch (src.getConfig()) { + case SkBitmap::kIndex8_Config: + case SkBitmap::kA8_Config: + addr = (void*)src.getAddr8(bounds.x(), bounds.y()); + break; + case SkBitmap::kRGB_565_Config: + addr = (void*)src.getAddr16(bounds.x(), bounds.y()); + break; + case SkBitmap::kARGB_8888_Config: + addr = (void*)src.getAddr32(bounds.x(), bounds.y()); + break; + default: + SkDEBUGF(("subset_bitmap: can't subset this bitmap config %d\n", src.getConfig())); + return false; } + dst->setConfig(src.getConfig(), bounds.width(), bounds.height(), src.rowBytes()); + dst->setPixels(addr); return false; } void Image::drawPattern(GraphicsContext* context, - const FloatRect& srcRect, + const FloatRect& floatSrcRect, const AffineTransform& patternTransform, const FloatPoint& phase, CompositeOperator compositeOp, const FloatRect& destRect) { - if (destRect.isEmpty() || srcRect.isEmpty()) + if (destRect.isEmpty() || floatSrcRect.isEmpty()) return; // nothing to draw - NativeImageSkia* bitmap = ToSkiaFrame(nativeImageForCurrentFrame()); + NativeImageSkia* bitmap = nativeImageForCurrentFrame(); if (!bitmap) return; - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia( - context->platformContext()); - // This is a very inexpensive operation. It will generate a new bitmap but // it will internally reference the old bitmap's pixels, adjusting the row // stride so the extra pixels appear as padding to the subsetted bitmap. - SkIRect srcSkIRect; - WebCoreRectToSkiaRect(srcRect, &srcSkIRect); SkBitmap src_subset; - bitmap->extractSubset(&src_subset, srcSkIRect); + SkIRect srcRect = enclosingIntRect(floatSrcRect); + bitmap->extractSubset(&src_subset, srcRect); SkBitmap resampled; SkShader* shader; @@ -255,9 +207,9 @@ void Image::drawPattern(GraphicsContext* context, // Compute the resampling mode. PlatformContextSkia::ResamplingMode resampling; - if (context->platformContext()->IsPrinting()) { + if (context->platformContext()->IsPrinting()) resampling = PlatformContextSkia::RESAMPLE_LINEAR; - } else { + else { resampling = PlatformContextSkia::computeResamplingMode( *bitmap, srcRect.width(), srcRect.height(), @@ -299,9 +251,7 @@ void Image::drawPattern(GraphicsContext* context, paint.setPorterDuffXfermode(WebCoreCompositeToSkiaComposite(compositeOp)); paint.setFilterBitmap(resampling == PlatformContextSkia::RESAMPLE_LINEAR); - SkRect dstR; - WebCoreRectToSkiaRect(destRect, &dstR); - skia->paintSkPaint(dstR, paint); + context->platformContext()->paintSkPaint(destRect, paint); } // ================================================ @@ -327,7 +277,7 @@ void BitmapImage::checkForSolidColor() bool BitmapImage::getHBITMAP(HBITMAP bmp) { - NativeImageSkia* bm = getBitmap(); + NativeImageSkia* bm = nativeImageForCurrentFrame(); if (!bm) return false; @@ -347,11 +297,6 @@ bool BitmapImage::getHBITMAPOfSize(HBITMAP bmp, LPSIZE size) return false; } -NativeImageSkia* BitmapImage::getBitmap() -{ - return ToSkiaFrame(nativeImageForCurrentFrame()); -} - void BitmapImage::drawFrameMatchingSourceSize(GraphicsContext*, const FloatRect& dstRect, const IntSize& srcSize, @@ -366,23 +311,17 @@ void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dstRect, if (!m_source.initialized()) return; - const NativeImageSkia* bm = getBitmap(); + const NativeImageSkia* bm = nativeImageForCurrentFrame(); if (!bm) return; // It's too early and we don't have an image yet. - SkIRect source_rect; - WebCoreRectToSkiaRect(srcRect, &source_rect); - SkRect dest_rect; - WebCoreRectToSkiaRect(dstRect, &dest_rect); - if (source_rect.isEmpty() || dest_rect.isEmpty()) + if (srcRect.isEmpty() || dstRect.isEmpty()) return; // Nothing to draw. - PlatformContextSkia* skia = PlatformContextToPlatformContextSkia( - ctxt->platformContext()); - skia->paintSkBitmap(*bm, source_rect, dest_rect, - WebCoreCompositeToSkiaComposite(compositeOp)); + ctxt->platformContext()->paintSkBitmap(*bm, enclosingIntRect(srcRect), + enclosingIntRect(dstRect), WebCoreCompositeToSkiaComposite(compositeOp)); startAnimation(); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/ImageSourceSkia.cpp b/webkit/port/platform/graphics/ImageSourceSkia.cpp index 48db176..fda00ab 100644 --- a/webkit/port/platform/graphics/ImageSourceSkia.cpp +++ b/webkit/port/platform/graphics/ImageSourceSkia.cpp @@ -139,6 +139,12 @@ IntSize ImageSource::size() const return m_decoder->size(); } +IntSize ImageSource::frameSizeAtIndex(size_t) const +{ + // TODO(brettw) do we need anything here? + return size(); +} + int ImageSource::repetitionCount() { if (!m_decoder) diff --git a/webkit/port/platform/graphics/IntPointSkia.cpp b/webkit/port/platform/graphics/IntPointSkia.cpp new file mode 100644 index 0000000..21e110e --- /dev/null +++ b/webkit/port/platform/graphics/IntPointSkia.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2008 Google, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 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 "IntPoint.h" +#include "SkPoint.h" + +namespace WebCore { + +IntPoint::IntPoint(const SkIPoint& p) + : m_x(p.fX) + , m_y(p.fY) +{ +} + +IntPoint::operator SkIPoint() const +{ + SkIPoint p = { m_x, m_y }; + return p; +} + +IntPoint::operator SkPoint() const +{ + SkPoint p = { SkIntToScalar(m_x), SkIntToScalar(m_y) }; + return p; +} + +} // namespace WebCore diff --git a/webkit/port/platform/graphics/IntPointWin.cpp b/webkit/port/platform/graphics/IntPointWin.cpp index a6ce0bb..91ffe02 100644 --- a/webkit/port/platform/graphics/IntPointWin.cpp +++ b/webkit/port/platform/graphics/IntPointWin.cpp @@ -53,4 +53,4 @@ IntPoint::operator POINTS() const return p; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/IntRectSkia.cpp b/webkit/port/platform/graphics/IntRectSkia.cpp new file mode 100644 index 0000000..e3186e2 --- /dev/null +++ b/webkit/port/platform/graphics/IntRectSkia.cpp @@ -0,0 +1,54 @@ +/*
+ * Copyright (C) 2008 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 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 "IntRect.h"
+
+#include "SkRect.h"
+
+namespace WebCore {
+
+IntRect::operator SkIRect() const
+{
+ SkIRect rect = { x(), y(), right(), bottom() };
+ return rect;
+}
+
+IntRect::operator SkRect() const
+{
+ SkRect rect;
+ rect.set(SkIntToScalar(x()), SkIntToScalar(y()),
+ SkIntToScalar(right()), SkIntToScalar(bottom()));
+ return rect;
+}
+
+IntRect::IntRect(const SkIRect& r)
+ : m_location(r.fLeft, r.fTop)
+ , m_size(r.width(), r.height())
+{
+}
+
+}
+
diff --git a/webkit/port/platform/graphics/IntRectWin.cpp b/webkit/port/platform/graphics/IntRectWin.cpp index 6228be8..a156039 100644 --- a/webkit/port/platform/graphics/IntRectWin.cpp +++ b/webkit/port/platform/graphics/IntRectWin.cpp @@ -30,7 +30,8 @@ namespace WebCore { IntRect::IntRect(const RECT& r) - : m_location(IntPoint(r.left, r.top)), m_size(IntSize(r.right-r.left, r.bottom-r.top)) + : m_location(IntPoint(r.left, r.top)) + , m_size(IntSize(r.right-r.left, r.bottom-r.top)) { } @@ -40,4 +41,4 @@ IntRect::operator RECT() const return rect; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/IntSizeWin.cpp b/webkit/port/platform/graphics/IntSizeWin.cpp index 8a27cdb..b8156e5 100644 --- a/webkit/port/platform/graphics/IntSizeWin.cpp +++ b/webkit/port/platform/graphics/IntSizeWin.cpp @@ -41,4 +41,4 @@ IntSize::operator SIZE() const return s; } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/PathSkia.cpp b/webkit/port/platform/graphics/PathSkia.cpp index b88d11d..d8b5b75 100644 --- a/webkit/port/platform/graphics/PathSkia.cpp +++ b/webkit/port/platform/graphics/PathSkia.cpp @@ -47,7 +47,6 @@ Path::Path() Path::Path(const Path& other) { m_path = new SkPath(*other.m_path); - m_rule = other.m_rule; } Path::~Path() @@ -159,16 +158,12 @@ void Path::addArc(const FloatPoint& p, float r, float sa, float ea, void Path::addRect(const FloatRect& rect) { - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - m_path->addRect(r); + m_path->addRect(rect); } void Path::addEllipse(const FloatRect& rect) { - SkRect r; - WebCoreRectToSkiaRect(rect, &r); - m_path->addOval(r); + m_path->addOval(rect); } void Path::clear() @@ -243,23 +238,23 @@ String Path::debugString() const verb = iter.next(pts); switch (verb) { case SkPath::kMove_Verb: - result += String::format("M%.2f,%.2f", pts[0].fX, pts[0].fY); + result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY); numPoints -= 1; break; case SkPath::kLine_Verb: if (!iter.isCloseLine()) { - result += String::format("L%.2f,%.2f", pts[1].fX, pts[1].fY); + result += String::format("L%.2f,%.2f ", pts[1].fX, pts[1].fY); numPoints -= 1; } break; case SkPath::kQuad_Verb: - result += String::format("Q%.2f,%.2f,%.2f,%.2f", + result += String::format("Q%.2f,%.2f,%.2f,%.2f ", pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY); numPoints -= 2; break; case SkPath::kCubic_Verb: - result += String::format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f", + result += String::format("C%.2f,%.2f,%.2f,%.2f,%.2f,%.2f ", pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY); @@ -278,10 +273,10 @@ String Path::debugString() const if (numPoints) { ASSERT(numPoints==1); m_path->getLastPt(pts); - result += String::format("M%.2f,%.2f", pts[0].fX, pts[0].fY); + result += String::format("M%.2f,%.2f ", pts[0].fX, pts[0].fY); } - return result; + return result.stripWhiteSpace(); } -} +} // namespace WebCore diff --git a/webkit/port/platform/graphics/PatternSkia.cpp b/webkit/port/platform/graphics/PatternSkia.cpp new file mode 100644 index 0000000..d80d3ec --- /dev/null +++ b/webkit/port/platform/graphics/PatternSkia.cpp @@ -0,0 +1,57 @@ +/*
+ * Copyright (C) 2008 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Pattern.h"
+
+#include "AffineTransform.h"
+#include "Image.h"
+#include "NativeImageSkia.h"
+
+#include "SkShader.h"
+
+namespace WebCore {
+
+static inline SkShader::TileMode shaderRule(bool shouldRepeat)
+{
+ // FIXME: Skia does not have a "draw the tile only once" option
+ // Clamp draws the last line of the image after stopping repeating
+ return shouldRepeat ? SkShader::kRepeat_TileMode : SkShader::kClamp_TileMode;
+}
+
+PlatformPatternPtr Pattern::createPlatformPattern(const AffineTransform& patternTransform) const
+{
+ SkBitmap* bm = m_tileImage->nativeImageForCurrentFrame();
+ SkShader* shader = SkShader::CreateBitmapShader(*bm,
+ shaderRule(m_repeatX),
+ shaderRule(m_repeatY));
+ shader->setLocalMatrix(patternTransform);
+ return shader;
+}
+
+} // namespace WebCore
diff --git a/webkit/port/platform/graphics/PlatformGraphics.h b/webkit/port/platform/graphics/PlatformGraphics.h index b3d83dc..6669dae 100644 --- a/webkit/port/platform/graphics/PlatformGraphics.h +++ b/webkit/port/platform/graphics/PlatformGraphics.h @@ -5,8 +5,8 @@ #ifndef PlatformGraphics_d #define PlatformGraphics_d -typedef class SkShader PlatformGradient; -typedef class SkShader PlatformPattern; +typedef class SkShader* PlatformGradient; +typedef class SkShader* PlatformPattern; #endif diff --git a/webkit/port/platform/graphics/SkGraphicsContext.cpp b/webkit/port/platform/graphics/SkGraphicsContext.cpp index 3a1b3c7..d89dbd0 100644 --- a/webkit/port/platform/graphics/SkGraphicsContext.cpp +++ b/webkit/port/platform/graphics/SkGraphicsContext.cpp @@ -27,6 +27,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#include "config.h" #include "SkGraphicsContext.h" #include <vssym32.h> @@ -35,7 +36,7 @@ #include "base/gfx/native_theme.h" #include "base/gfx/platform_canvas_win.h" #include "base/gfx/skia_utils.h" -#include "GraphicsContextPrivate.h" +#include "GraphicsContextPlatformPrivate.h" #include "NativeImageSkia.h" #include "SkBitmap.h" diff --git a/webkit/port/platform/graphics/SkiaUtils.cpp b/webkit/port/platform/graphics/SkiaUtils.cpp index 27779c7..aa8aef0 100644 --- a/webkit/port/platform/graphics/SkiaUtils.cpp +++ b/webkit/port/platform/graphics/SkiaUtils.cpp @@ -31,15 +31,13 @@ #include "SkiaUtils.h" +#include "SharedBuffer.h" #include "SkCanvas.h" #include "SkColorPriv.h" #include "SkMatrix.h" #include "SkRegion.h" -void WebCorePointToSkiaPoint(const WebCore::IntPoint& src, SkPoint* dst) -{ - dst->set(SkIntToScalar(src.x()), SkIntToScalar(src.y())); -} +#include "base/gfx/bitmap_header.h" void WebCorePointToSkiaPoint(const WebCore::FloatPoint& src, SkPoint* dst) { @@ -112,15 +110,6 @@ SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(WebCore::CompositeOperator op return SkPorterDuff::kSrcOver_Mode; // fall-back } -SkShader::TileMode WebCoreTileToSkiaTile(WebCore::Image::TileRule rule) -{ - // StretchTile, RoundTile, RepeatTile - // hack!!!! what does stretch and round mean??? - - return SkShader::kRepeat_TileMode; -} - - static U8CPU InvScaleByte(U8CPU component, uint32_t scale) { SkASSERT(component == (uint8_t)component); @@ -144,9 +133,7 @@ static SkColor SkPMColorToColor(SkPMColor pm) WebCore::Color SkPMColorToWebCoreColor(SkPMColor pm) { - SkColor c = SkPMColorToColor(pm); - - return WebCore::Color(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c)); + return SkPMColorToColor(pm); } void IntersectRectAndRegion(const SkRegion& region, const SkRect& src_rect, @@ -239,3 +226,37 @@ bool SkPathContainsPoint(SkPath* orig_path, WebCore::FloatPoint point, SkPath::F orig_path->setFillType(orig_ft); // restore return contains; } + +PassRefPtr<WebCore::SharedBuffer> SerializeSkBitmap(const SkBitmap& bitmap) +{ + int width = bitmap.width(); + int height = bitmap.height(); + + // Create a BMP v4 header that we can serialize. + BITMAPV4HEADER v4Header; + gfx::CreateBitmapV4Header(width, height, &v4Header); + v4Header.bV4SizeImage = width * sizeof(uint32_t) * height; + + // Serialize the bitmap. + BITMAPFILEHEADER fileHeader; + fileHeader.bfType = 0x4d42; // "BM" header + fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + v4Header.bV4Size; + fileHeader.bfSize = fileHeader.bfOffBits + v4Header.bV4SizeImage; + fileHeader.bfReserved1 = fileHeader.bfReserved2 = 0; + + // Write BITMAPFILEHEADER + RefPtr<WebCore::SharedBuffer> buffer(WebCore::SharedBuffer::create( + reinterpret_cast<const char*>(&fileHeader), + sizeof(BITMAPFILEHEADER))); + + // Write BITMAPINFOHEADER + buffer->append(reinterpret_cast<const char*>(&v4Header), + sizeof(BITMAPV4HEADER)); + + // Write the image body. + SkAutoLockPixels bitmap_lock(bitmap); + buffer->append(reinterpret_cast<const char*>(bitmap.getAddr32(0, 0)), + v4Header.bV4SizeImage); + + return buffer; +} diff --git a/webkit/port/platform/graphics/SkiaUtils.h b/webkit/port/platform/graphics/SkiaUtils.h index 28d43be..617b8c8 100644 --- a/webkit/port/platform/graphics/SkiaUtils.h +++ b/webkit/port/platform/graphics/SkiaUtils.h @@ -7,46 +7,23 @@ #ifndef SkiaUtils_h #define SkiaUtils_h +#include <wtf/PassRefPtr.h> #include "base/float_util.h" #include "GraphicsContext.h" #include "SkPath.h" #include "SkShader.h" #include "PlatformContextSkia.h" +class WebCore::SharedBuffer; class SkRegion; -// Converts the given WebCore point to a Skia point. -void WebCorePointToSkiaPoint(const WebCore::IntPoint& src, SkPoint* dst); -void WebCorePointToSkiaPoint(const WebCore::FloatPoint& src, SkPoint* dst); - -// Converts from various types of WebCore rectangles to the corresponding -// Skia rectangle types. -void WebCoreRectToSkiaRect(const WebCore::IntRect& src, SkRect* dst); -void WebCoreRectToSkiaRect(const WebCore::FloatRect& src, SkRect* dst); -void WebCoreRectToSkiaRect(const WebCore::IntRect& src, SkIRect* dst); -void WebCoreRectToSkiaRect(const WebCore::FloatRect& src, SkIRect* dst); - -// Converts a WebCore |Path| to an SkPath. -inline SkPath* PathToSkPath(const WebCore::Path& path) { - return reinterpret_cast<SkPath*>(path.platformPath()); -} - // Converts a WebCore composit operation (WebCore::Composite*) to the // corresponding Skia type. SkPorterDuff::Mode WebCoreCompositeToSkiaComposite(WebCore::CompositeOperator); -// Converts a WebCore tiling rule to the corresponding Skia tiling mode. -SkShader::TileMode WebCoreTileToSkiaTile(WebCore::Image::TileRule); - // Converts Android colors to WebKit ones. WebCore::Color SkPMColorToWebCoreColor(SkPMColor pm); -// A platform graphics context is actually a PlatformContextSkia. -inline PlatformContextSkia* PlatformContextToPlatformContextSkia( - PlatformGraphicsContext* context) { - return reinterpret_cast<PlatformContextSkia*>(context); -} - // Skia has problems when passed infinite, etc floats, filter them to 0. inline SkScalar WebCoreFloatToSkScalar(const float& f) { return SkFloatToScalar(base::IsFinite(f) ? f : 0); @@ -74,5 +51,7 @@ void ClipRectToCanvas(const SkCanvas& canvas, const SkRect& src_rect, // Determine if a given WebKit point is contained in a path bool SkPathContainsPoint(SkPath* orig_path, WebCore::FloatPoint point, SkPath::FillType ft); -#endif // SkiaUtils_h +// Constructs a BMP V4 bitmap from an SkBitmap. +PassRefPtr<WebCore::SharedBuffer> SerializeSkBitmap(const SkBitmap&); +#endif // SkiaUtils_h diff --git a/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp b/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp index 84c445b..76b2370 100644 --- a/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp +++ b/webkit/port/platform/graphics/svg/SVGPaintServerGradientSkia.cpp @@ -35,6 +35,7 @@ #include "SVGPaintServerRadialGradient.h" #include "GraphicsContext.h" +#include "Path.h" #include "RenderObject.h" #include "RenderPath.h" #include "RenderStyle.h" @@ -156,17 +157,15 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, SkMatrix matrix; // Calculate a matrix to transform a gradient to fit the bounding box - if(boundingBoxMode()) { + if (boundingBoxMode()) { matrix.reset(); - SkRect rc; - context->currentPath()->computeBounds(&rc, SkPath::kExact_BoundsType); + SkRect rc = context->getBoundingBoxForCurrentPath(true); matrix.preTranslate(rc.fLeft, rc.fTop); matrix.preScale(rc.width(), rc.height()); matrix.preConcat(gradientTransform()); - } else { + } else matrix = gradientTransform(); - } if (this->type() == LinearGradientPaintServer) { const SVGPaintServerLinearGradient* linear = diff --git a/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp b/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp index f9b97a6..8400633 100644 --- a/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp +++ b/webkit/port/platform/graphics/svg/SVGPaintServerPatternSkia.cpp @@ -33,6 +33,7 @@ #include "GraphicsContext.h" #include "ImageBuffer.h" #include "RenderObject.h" +#include "Pattern.h" #include "SVGPatternElement.h" #include "SVGPaintServerPattern.h" #include "SkiaSupport.h" @@ -59,20 +60,19 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* if (!tile()) return false; - SkShader* shader = SkShader::CreateBitmapShader(*tile()->image(), SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); + AffineTransform transform = patternTransform(); + transform.translate(patternBoundaries().x(), patternBoundaries().y()); - SkMatrix matrix = patternTransform(); - matrix.preTranslate(patternBoundaries().x(), patternBoundaries().y()); - - shader->setLocalMatrix(matrix); - context->platformContext()->setPattern(shader); + RefPtr<Pattern> pattern(Pattern::create(tile()->image(), true, true)); if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) { + context->setFillPattern(pattern); if (isPaintingText) context->setTextDrawingMode(cTextFill); } if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) { + context->setStrokePattern(pattern); applyStrokeStyleToContext(context, style, object); if (isPaintingText) context->setTextDrawingMode(cTextStroke); diff --git a/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp b/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp index 7684396..4acd0f9 100644 --- a/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp +++ b/webkit/port/platform/graphics/svg/SVGPaintServerSkia.cpp @@ -36,9 +36,6 @@ #include "RenderPath.h" #include "SkiaUtils.h" -#include "SkDashPathEffect.h" - -#include "NotImplemented.h" namespace WebCore { @@ -53,22 +50,17 @@ void SVGPaintServer::draw(GraphicsContext*& context, const RenderObject* object, void SVGPaintServer::teardown(GraphicsContext*& context, const RenderObject*, SVGPaintTargetType, bool isPaintingText) const { - context->beginPath(); - context->platformContext()->setGradient(NULL); - context->platformContext()->setPattern(NULL); } void SVGPaintServer::renderPath(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type) const { RenderStyle* renderStyle = object ? object->style() : NULL; - SkPath* path = context->currentPath(); - if ((type & ApplyToFillTargetType) && (!renderStyle || renderStyle->svgStyle()->hasFill())) - context->fillPath(path, NULL, NULL); + context->fillPath(); if ((type & ApplyToStrokeTargetType) && (!renderStyle || renderStyle->svgStyle()->hasStroke())) - context->strokePath(path, NULL, NULL); + context->strokePath(); } } // namespace WebCore diff --git a/webkit/port/platform/graphics/svg/SkiaSupport.cpp b/webkit/port/platform/graphics/svg/SkiaSupport.cpp index fbc752b..2df8841 100644 --- a/webkit/port/platform/graphics/svg/SkiaSupport.cpp +++ b/webkit/port/platform/graphics/svg/SkiaSupport.cpp @@ -55,12 +55,11 @@ void applyStrokeStyleToContext(GraphicsContext* context, const RenderStyle* styl context->setLineCap(svgStyle->capStyle()); context->setLineJoin(svgStyle->joinStyle()); - if(svgStyle->joinStyle() == MiterJoin) { + if (svgStyle->joinStyle() == MiterJoin) context->setMiterLimit(svgStyle->strokeMiterLimit()); - } - const DashArray& dashes = WebCore::dashArrayFromRenderingStyle(style); - double dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0); + const DashArray& dashes = dashArrayFromRenderingStyle(style); + float dashOffset = SVGRenderStyle::cssPrimitiveToLength(object, style->svgStyle()->strokeDashOffset(), 0.0); unsigned int dashLength = !dashes.isEmpty() ? dashes.size() : 0; if(dashLength) { @@ -79,9 +78,8 @@ void applyStrokeStyleToContext(GraphicsContext* context, const RenderStyle* styl GraphicsContext* scratchContext() { static GraphicsContext* scratch = NULL; - if (!scratch) { + if (!scratch) scratch = GraphicsContext::createOffscreenContext(1, 1); - } return scratch; } @@ -90,8 +88,10 @@ FloatRect strokeBoundingBox(const Path& path, RenderStyle* style, const RenderOb GraphicsContext* scratch = scratchContext(); scratch->save(); + scratch->beginPath(); + scratch->addPath(path); applyStrokeStyleToContext(scratch, style, object); - FloatRect bbox = scratch->getPathBoundingBox(path); + FloatRect bbox = scratch->getBoundingBoxForCurrentPath(true); scratch->restore(); return bbox; diff --git a/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp b/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp index 68f42dd..678e080 100644 --- a/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp +++ b/webkit/port/platform/image-decoders/gif/GIFImageDecoder.cpp @@ -421,4 +421,3 @@ void GIFImageDecoder::gifComplete() } } - diff --git a/webkit/port/platform/image-decoders/ico/ICOImageDecoder.cpp b/webkit/port/platform/image-decoders/ico/ICOImageDecoder.cpp index cd740b4..f102b22 100644 --- a/webkit/port/platform/image-decoders/ico/ICOImageDecoder.cpp +++ b/webkit/port/platform/image-decoders/ico/ICOImageDecoder.cpp @@ -217,8 +217,8 @@ void ICOImageDecoder::decodePNG(SharedBuffer* data) // offset the perceived start of |data| by |m_dirEntry.dwImageOffset| when // passing it to setData()... RefPtr<SharedBuffer> pngData( - new SharedBuffer(&data->data()[m_dirEntry.dwImageOffset], - data->size() - m_dirEntry.dwImageOffset)); + SharedBuffer::create(&data->data()[m_dirEntry.dwImageOffset], + data->size() - m_dirEntry.dwImageOffset)); m_pngDecoder.setData(pngData.get(), true); // Decode PNG as a side effect of asking for the frame. Strangely, it's diff --git a/webkit/port/platform/image-decoders/ico/ICOImageDecoder_unittest.cpp b/webkit/port/platform/image-decoders/ico/ICOImageDecoder_unittest.cpp index f17fd2c..d49706a 100644 --- a/webkit/port/platform/image-decoders/ico/ICOImageDecoder_unittest.cpp +++ b/webkit/port/platform/image-decoders/ico/ICOImageDecoder_unittest.cpp @@ -69,7 +69,7 @@ TEST_F(ICOImageDecoderTest, FaviconSize) { // Decode, preferring the favicon size. scoped_ptr<WebCore::ImageDecoder> decoder(new WebCore::ICOImageDecoder( WebCore::IntSize(kFavIconSize, kFavIconSize))); - RefPtr<WebCore::SharedBuffer> shared_contents(new WebCore::SharedBuffer); + RefPtr<WebCore::SharedBuffer> shared_contents(WebCore::SharedBuffer::create()); shared_contents->append(image_contents.data(), static_cast<int>(image_contents.size())); decoder->setData(shared_contents.get(), true); diff --git a/webkit/port/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/webkit/port/platform/image-decoders/jpeg/JPEGImageDecoder.cpp index 3c05d46..ebdbbaf 100644 --- a/webkit/port/platform/image-decoders/jpeg/JPEGImageDecoder.cpp +++ b/webkit/port/platform/image-decoders/jpeg/JPEGImageDecoder.cpp @@ -509,4 +509,3 @@ void JPEGImageDecoder::jpegComplete() } } - diff --git a/webkit/port/platform/image-decoders/png/PNGImageDecoder.cpp b/webkit/port/platform/image-decoders/png/PNGImageDecoder.cpp index 4ee7a67..7f62f63 100644 --- a/webkit/port/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/webkit/port/platform/image-decoders/png/PNGImageDecoder.cpp @@ -409,4 +409,3 @@ void PNGImageDecoder::pngComplete() } } - diff --git a/webkit/port/platform/network/AuthenticationChallenge.cpp b/webkit/port/platform/network/AuthenticationChallenge.cpp new file mode 100644 index 0000000..f6831cf --- /dev/null +++ b/webkit/port/platform/network/AuthenticationChallenge.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 "AuthenticationChallenge.h"
+
+namespace WebCore {
+
+bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
+{
+ return true;
+}
+
+} // namespace WebCore
diff --git a/webkit/port/platform/network/AuthenticationChallenge.h b/webkit/port/platform/network/AuthenticationChallenge.h new file mode 100644 index 0000000..b1db6cf --- /dev/null +++ b/webkit/port/platform/network/AuthenticationChallenge.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * Copyright (C) 2008 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 AuthenticationChallenge_h +#define AuthenticationChallenge_h + +#include "AuthenticationChallengeBase.h" +#include "ResourceHandle.h" + +#include <wtf/RefPtr.h> + +namespace WebCore { + +class ResourceHandle; + +class AuthenticationChallenge : public AuthenticationChallengeBase { +public: + AuthenticationChallenge() {} + AuthenticationChallenge(const ProtectionSpace& protectionSpace, const Credential& proposedCredential, unsigned previousFailureCount, const ResourceResponse& response, const ResourceError& error); + + ResourceHandle* sourceHandle() const { return m_sourceHandle.get(); } + +private: + friend class AuthenticationChallengeBase; + static bool platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b); + + RefPtr<ResourceHandle> m_sourceHandle; +}; + +} + +#endif diff --git a/webkit/port/platform/network/CookieJarWin.cpp b/webkit/port/platform/network/CookieJarWin.cpp index cb68d81..9d2ec62 100644 --- a/webkit/port/platform/network/CookieJarWin.cpp +++ b/webkit/port/platform/network/CookieJarWin.cpp @@ -30,7 +30,6 @@ #include "KURL.h" #include "PlatformString.h" #include "CString.h" -#include "DeprecatedString.h" #include "Vector.h" #pragma warning(pop) @@ -44,7 +43,7 @@ void setCookies(Document* document, const KURL& url, const KURL& policyURL, cons { // We ignore the policyURL and compute it directly ourselves to ensure // consistency with the cookies() method below. - KURL policyBaseURL(document->policyBaseURL().deprecatedString()); + KURL policyBaseURL = document->policyBaseURL(); WebCore::CString utf8value = value.utf8(); webkit_glue::SetCookie( webkit_glue::KURLToGURL(url), @@ -54,7 +53,7 @@ void setCookies(Document* document, const KURL& url, const KURL& policyURL, cons String cookies(const Document* document, const KURL& url) { - KURL policyBaseURL(document->policyBaseURL().deprecatedString()); + KURL policyBaseURL = document->policyBaseURL(); std::string result = webkit_glue::GetCookies(webkit_glue::KURLToGURL(url), webkit_glue::KURLToGURL(policyBaseURL)); diff --git a/webkit/port/platform/network/DNS.cpp b/webkit/port/platform/network/DNS.cpp new file mode 100644 index 0000000..a11d236 --- /dev/null +++ b/webkit/port/platform/network/DNS.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008 Collin Jackson <collinj@webkit.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "DNS.h" + +#include "webkit/glue/glue_util.h" +#include "webkit/glue/webkit_glue.h" + +namespace WebCore { + +void prefetchDNS(const String& hostname) +{ + webkit_glue::PrefetchDns(webkit_glue::StringToStdString(hostname)); +} + +}
\ No newline at end of file diff --git a/webkit/port/platform/network/NetworkStateNotifierWin.cpp b/webkit/port/platform/network/NetworkStateNotifierWin.cpp new file mode 100644 index 0000000..3f5edbb --- /dev/null +++ b/webkit/port/platform/network/NetworkStateNotifierWin.cpp @@ -0,0 +1,114 @@ +/*
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "NetworkStateNotifier.h"
+
+#include <wtf/MainThread.h>
+#include <wtf/Vector.h>
+
+#include <winsock2.h>
+#include <iphlpapi.h>
+
+namespace WebCore {
+
+void NetworkStateNotifier::updateState()
+{
+ // Assume that we're online until proven otherwise.
+ m_isOnLine = true;
+
+ Vector<char> buffer;
+ DWORD size = 0;
+
+ if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, 0, &size) != ERROR_BUFFER_OVERFLOW)
+ return;
+
+ buffer.resize(size);
+ PIP_ADAPTER_ADDRESSES addresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(buffer.data());
+
+ if (::GetAdaptersAddresses(AF_UNSPEC, 0, 0, addresses, &size) != ERROR_SUCCESS) {
+ // We couldn't determine whether we're online or not, so assume that we are.
+ return;
+ }
+
+ for (; addresses; addresses = addresses->Next) {
+ if (addresses->IfType == MIB_IF_TYPE_LOOPBACK)
+ continue;
+
+ if (addresses->OperStatus != IfOperStatusUp)
+ continue;
+
+ // We found an interface that was up.
+ return;
+ }
+
+ // We didn't find any valid interfaces, so we must be offline.
+ m_isOnLine = false;
+}
+
+void NetworkStateNotifier::addressChanged()
+{
+ bool oldOnLine = m_isOnLine;
+
+ updateState();
+
+ if (m_isOnLine == oldOnLine)
+ return;
+
+ if (m_networkStateChangedFunction)
+ m_networkStateChangedFunction();
+}
+
+void NetworkStateNotifier::callAddressChanged(void* context)
+{
+ static_cast<NetworkStateNotifier*>(context)->addressChanged();
+}
+
+void CALLBACK NetworkStateNotifier::addrChangeCallback(void* context, BOOLEAN timedOut)
+{
+ callOnMainThread(callAddressChanged, context);
+}
+
+void NetworkStateNotifier::registerForAddressChange()
+{
+ HANDLE handle;
+ ::NotifyAddrChange(&handle, &m_overlapped);
+}
+
+NetworkStateNotifier::NetworkStateNotifier()
+ : m_isOnLine(false)
+{
+ updateState();
+
+ memset(&m_overlapped, 0, sizeof(m_overlapped));
+
+ m_overlapped.hEvent = ::CreateEvent(0, false, false, 0);
+
+ ::RegisterWaitForSingleObject(&m_waitHandle, m_overlapped.hEvent, addrChangeCallback, this, INFINITE, 0);
+
+ registerForAddressChange();
+}
+
+}
diff --git a/webkit/port/platform/network/ResourceError.h b/webkit/port/platform/network/ResourceError.h new file mode 100644 index 0000000..a71b302 --- /dev/null +++ b/webkit/port/platform/network/ResourceError.h @@ -0,0 +1,52 @@ +// -*- mode: c++; c-basic-offset: 4 -*- +/* + * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2008 Google, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 ResourceError_h +#define ResourceError_h + +#include "ResourceErrorBase.h" + +namespace WebCore { + +class ResourceError : public ResourceErrorBase { +public: + ResourceError() + { + } + + ResourceError(const String& domain, int errorCode, const String& failingURL, const String& localizedDescription) + : ResourceErrorBase(domain, errorCode, failingURL, localizedDescription) + { + } + +private: + friend class ResourceErrorBase; +}; + +} // namespace WebCore + +#endif // ResourceError_h_ diff --git a/webkit/port/platform/network/ResourceRequest.h b/webkit/port/platform/network/ResourceRequest.h index 19c401d..6420d5d 100644 --- a/webkit/port/platform/network/ResourceRequest.h +++ b/webkit/port/platform/network/ResourceRequest.h @@ -40,7 +40,7 @@ namespace WebCore { class ResourceRequest : public ResourceRequestBase { public: ResourceRequest(const String& url) - : ResourceRequestBase(KURL(url.deprecatedString()), UseProtocolCachePolicy) + : ResourceRequestBase(KURL(url), UseProtocolCachePolicy) , m_frame(0) , m_originPid(0) , m_resourceType(ResourceType::SUB_RESOURCE) |