diff options
Diffstat (limited to 'WebCore/platform/mac')
43 files changed, 1858 insertions, 1405 deletions
diff --git a/WebCore/platform/mac/ClipboardMac.h b/WebCore/platform/mac/ClipboardMac.h index 480d828..db6ecb6 100644 --- a/WebCore/platform/mac/ClipboardMac.h +++ b/WebCore/platform/mac/ClipboardMac.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 @@ -23,15 +23,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// An implementation of the clipboard class from IE that talks to the Cocoa Pasteboard - #ifndef ClipboardMac_h #define ClipboardMac_h -#include "IntPoint.h" -#include "Clipboard.h" -#include "ClipboardAccessPolicy.h" #include "CachedResourceClient.h" +#include "Clipboard.h" #include <wtf/RetainPtr.h> #ifdef __OBJC__ @@ -40,7 +36,6 @@ #else class NSImage; class NSPasteboard; -typedef unsigned NSDragOperation; #endif namespace WebCore { @@ -49,7 +44,11 @@ class Frame; class ClipboardMac : public Clipboard, public CachedResourceClient { public: - ClipboardMac(bool forDragging, NSPasteboard *, ClipboardAccessPolicy, Frame* = 0); + static PassRefPtr<ClipboardMac> create(bool forDragging, NSPasteboard *pasteboard, ClipboardAccessPolicy policy, Frame* frame) + { + return adoptRef(new ClipboardMac(forDragging, pasteboard, policy, frame)); + } + virtual ~ClipboardMac(); void clearData(const String& type); @@ -73,7 +72,10 @@ public: // Methods for getting info in Cocoa's type system NSImage *dragNSImage(NSPoint&) const; // loc converted from dragLoc, based on whole image size NSPasteboard *pasteboard() { return m_pasteboard.get(); } + private: + ClipboardMac(bool forDragging, NSPasteboard *, ClipboardAccessPolicy, Frame*); + void setDragImage(CachedImage*, Node*, const IntPoint&); RetainPtr<NSPasteboard> m_pasteboard; diff --git a/WebCore/platform/mac/ClipboardMac.mm b/WebCore/platform/mac/ClipboardMac.mm index 01ec573..8117b2b 100644 --- a/WebCore/platform/mac/ClipboardMac.mm +++ b/WebCore/platform/mac/ClipboardMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2005, 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 @@ -26,27 +26,18 @@ #import "config.h" #import "ClipboardMac.h" -#import "CachedImage.h" -#import "Document.h" #import "DOMElementInternal.h" #import "DragClient.h" #import "DragController.h" #import "Editor.h" -#import "EventHandler.h" -#import "FloatRect.h" #import "FoundationExtras.h" #import "Frame.h" -#import "HTMLImageElement.h" #import "Image.h" #import "Page.h" #import "Pasteboard.h" -#import "Range.h" #import "RenderImage.h" -#import "WebCoreFrameBridge.h" #import "WebCoreSystemInterface.h" -@class WebArchive; - namespace WebCore { ClipboardMac::ClipboardMac(bool forDragging, NSPasteboard *pasteboard, ClipboardAccessPolicy policy, Frame *frame) @@ -284,10 +275,10 @@ void ClipboardMac::setDragImage(CachedImage* image, Node *node, const IntPoint & { if (policy() == ClipboardImageWritable || policy() == ClipboardWritable) { 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; @@ -332,7 +323,7 @@ void ClipboardMac::declareAndWriteDragImage(Element* element, const KURL& url, c { ASSERT(frame); if (Page* page = frame->page()) - page->dragController()->client()->declareAndWriteDragImage(m_pasteboard.get(), [DOMElement _wrapElement:element], url.getNSURL(), title, frame); + page->dragController()->client()->declareAndWriteDragImage(m_pasteboard.get(), [DOMElement _wrapElement:element], url, title, frame); } DragImageRef ClipboardMac::createDragImage(IntPoint& loc) const diff --git a/WebCore/platform/mac/CookieJar.mm b/WebCore/platform/mac/CookieJar.mm index 7c288ad..5fe7a63 100644 --- a/WebCore/platform/mac/CookieJar.mm +++ b/WebCore/platform/mac/CookieJar.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2003, 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 @@ -26,14 +26,12 @@ #import "config.h" #import "CookieJar.h" -#import "KURL.h" #import "BlockExceptions.h" -#import "PlatformString.h" - +#import "KURL.h" #import <wtf/RetainPtr.h> #ifdef BUILDING_ON_TIGER -typedef unsigned int NSUInteger; +typedef unsigned NSUInteger; #endif namespace WebCore { @@ -42,7 +40,7 @@ String cookies(const Document* /*document*/, const KURL& url) { BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSURL *cookieURL = url.getNSURL(); + NSURL *cookieURL = url; NSArray *cookiesForURL = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:cookieURL]; // <rdar://problem/5632883> On 10.5, NSHTTPCookieStorage would happily store an empty cookie, which would be sent as "Cookie: =". @@ -70,14 +68,14 @@ void setCookies(Document* /*document*/, const KURL& url, const KURL& policyBaseU if (cookieStr.isEmpty()) return; - NSURL *cookieURL = url.getNSURL(); + NSURL *cookieURL = url; // <http://bugs.webkit.org/show_bug.cgi?id=6531>, <rdar://4409034> // cookiesWithResponseHeaderFields doesn't parse cookies without a value String cookieString = cookieStr.contains('=') ? cookieStr : cookieStr + "="; NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary dictionaryWithObject:cookieString forKey:@"Set-Cookie"] forURL:cookieURL]; - [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:cookieURL mainDocumentURL:policyBaseURL.getNSURL()]; + [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:cookieURL mainDocumentURL:policyBaseURL]; END_BLOCK_OBJC_EXCEPTIONS; } diff --git a/WebCore/platform/mac/CursorMac.mm b/WebCore/platform/mac/CursorMac.mm index fe8680f..b07964b 100644 --- a/WebCore/platform/mac/CursorMac.mm +++ b/WebCore/platform/mac/CursorMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2006 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -295,4 +295,61 @@ const Cursor& rowResizeCursor() return c; } +const Cursor& middlePanningCursor() +{ + return moveCursor(); +} + +const Cursor& eastPanningCursor() +{ + return eastResizeCursor(); +} + +const Cursor& northPanningCursor() +{ + return northResizeCursor(); +} + +const Cursor& northEastPanningCursor() +{ + return northEastResizeCursor(); +} + +const Cursor& northWestPanningCursor() +{ + return northWestResizeCursor(); +} + +const Cursor& southPanningCursor() +{ + return southResizeCursor(); +} + +const Cursor& southEastPanningCursor() +{ + return southEastResizeCursor(); +} + +const Cursor& southWestPanningCursor() +{ + return southWestResizeCursor(); +} + +const Cursor& westPanningCursor() +{ + return westResizeCursor(); +} + +const Cursor& grabCursor() +{ + static Cursor c = [NSCursor openHandCursor]; + return c; +} + +const Cursor& grabbingCursor() +{ + static Cursor c = [NSCursor closedHandCursor]; + return c; +} + } diff --git a/WebCore/platform/mac/DeprecatedStringMac.mm b/WebCore/platform/mac/DeprecatedStringMac.mm deleted file mode 100644 index 6e58eba..0000000 --- a/WebCore/platform/mac/DeprecatedStringMac.mm +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "DeprecatedString.h" - -#import <wtf/Assertions.h> -#import "TextEncoding.h" - -using namespace WebCore; - -void DeprecatedString::setBufferFromCFString(CFStringRef cfs) -{ - if (!cfs) { - return; - } - CFIndex size = CFStringGetLength(cfs); - UniChar fixedSizeBuffer[1024]; - UniChar *buffer; - if (size > (CFIndex)(sizeof(fixedSizeBuffer) / sizeof(UniChar))) { - buffer = (UniChar *)fastMalloc(size * sizeof(UniChar)); - } else { - buffer = fixedSizeBuffer; - } - CFStringGetCharacters(cfs, CFRangeMake (0, size), buffer); - setUnicode((const DeprecatedChar *)buffer, (unsigned)size); - if (buffer != fixedSizeBuffer) { - fastFree(buffer); - } -} - - -DeprecatedString DeprecatedString::fromCFString(CFStringRef cfs) -{ - DeprecatedString qs; - qs.setBufferFromCFString(cfs); - return qs; -} - -DeprecatedString DeprecatedString::fromNSString(NSString *nss) -{ - DeprecatedString qs; - qs.setBufferFromCFString((CFStringRef)nss); - return qs; -} - -NSString *DeprecatedString::getNSString() const -{ - // The Cocoa calls in this method don't need exceptions blocked - // because they are simple NSString calls that can't throw. - - int length = dataHandle[0]->_length; - if (dataHandle[0]->_isUnicodeValid) { - return [NSString stringWithCharacters:(const unichar *)unicode() length:length]; - } - - if (dataHandle[0]->_isAsciiValid) { - return [[[NSString alloc] initWithBytes:ascii() length:length encoding:NSISOLatin1StringEncoding] autorelease]; - } - - FATAL("invalid character cache"); - return nil; -} diff --git a/WebCore/platform/mac/DragDataMac.mm b/WebCore/platform/mac/DragDataMac.mm index 73170d7..bd66787 100644 --- a/WebCore/platform/mac/DragDataMac.mm +++ b/WebCore/platform/mac/DragDataMac.mm @@ -91,7 +91,7 @@ String DragData::asPlainText() const { return m_pasteboardHelper->plainTextFromPasteboard([m_platformDragData draggingPasteboard]); } - + Color DragData::asColor() const { NSColor *color = [NSColor colorFromPasteboard:[m_platformDragData draggingPasteboard]]; @@ -99,14 +99,13 @@ Color DragData::asColor() const (int)([color blueComponent] * 255.0 + 0.5), (int)([color alphaComponent] * 255.0 + 0.5)); } -Clipboard* DragData::createClipboard(ClipboardAccessPolicy policy) const +PassRefPtr<Clipboard> DragData::createClipboard(ClipboardAccessPolicy policy) const { - return new ClipboardMac(true, [m_platformDragData draggingPasteboard], policy); + return ClipboardMac::create(true, [m_platformDragData draggingPasteboard], policy, 0); } bool DragData::containsCompatibleContent() const { - NSPasteboard *pasteboard = [m_platformDragData draggingPasteboard]; NSMutableSet *types = [NSMutableSet setWithArray:[pasteboard types]]; [types intersectSet:[NSSet setWithArray:m_pasteboardHelper->insertablePasteboardTypes()]]; @@ -122,8 +121,7 @@ String DragData::asURL(String* title) const { return m_pasteboardHelper->urlFromPasteboard([m_platformDragData draggingPasteboard], title); } - - + PassRefPtr<DocumentFragment> DragData::asFragment(Document* doc) const { return [m_pasteboardHelper->fragmentFromPasteboard([m_platformDragData draggingPasteboard]) _documentFragment]; diff --git a/WebCore/platform/mac/DeprecatedStringListMac.mm b/WebCore/platform/mac/EventLoopMac.mm index abb6329..05ef33a 100644 --- a/WebCore/platform/mac/DeprecatedStringListMac.mm +++ b/WebCore/platform/mac/EventLoopMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. + * 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 @@ -10,31 +10,30 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" -#import "DeprecatedStringList.h" +#include "EventLoop.h" namespace WebCore { -NSArray *DeprecatedStringList::getNSArray() const +void EventLoop::cycle() { - NSMutableArray *array = [NSMutableArray array]; - for (ConstIterator it = begin(); it != end(); ++it) { - [array addObject:(*it).getNSString()]; - } - return array; + // FIXME: Should this use NSRunLoopCommonModes? Switching to NSRunLoopCommonModes causes Safari to hang in a tight loop. + [NSApp setWindowsNeedUpdate:YES]; + NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES]; + [NSApp sendEvent:event]; } -} +} // namespace WebCore diff --git a/WebCore/platform/mac/FileChooserMac.mm b/WebCore/platform/mac/FileChooserMac.mm index e8f9159..03532ff 100644 --- a/WebCore/platform/mac/FileChooserMac.mm +++ b/WebCore/platform/mac/FileChooserMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. + * Copyright (C) 2006, 2007, 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 @@ -30,97 +30,24 @@ #import "config.h" #import "FileChooser.h" -#import "Document.h" -#import "SimpleFontData.h" -#import "Frame.h" -#import "Icon.h" #import "LocalizedStrings.h" +#import "SimpleFontData.h" #import "StringTruncator.h" -#import "WebCoreFrameBridge.h" - -using namespace WebCore; - -@interface WebCoreOpenPanelController : NSObject <WebCoreOpenPanelResultListener> { - FileChooser *_fileChooser; - WebCoreFrameBridge *_bridge; -} -- (id)initWithFileChooser:(FileChooser *)fileChooser; -- (void)disconnectFileChooser; -- (void)beginSheetWithFrame:(Frame*)frame; -@end - -@implementation WebCoreOpenPanelController - -- (id)initWithFileChooser:(FileChooser *)fileChooser -{ - self = [super init]; - if (!self) - return nil; - - _fileChooser = fileChooser; - return self; -} - -- (void)disconnectFileChooser -{ - _fileChooser = 0; -} - -- (void)beginSheetWithFrame:(Frame*)frame -{ - if (!_fileChooser) - return; - - _bridge = frame->bridge(); - [_bridge retain]; - [_bridge runOpenPanelForFileButtonWithResultListener:self]; -} - -- (void)chooseFilename:(NSString *)filename -{ - if (_fileChooser) - _fileChooser->chooseFile(filename); - [_bridge release]; -} - -- (void)cancel -{ - [_bridge release]; -} - -@end namespace WebCore { -FileChooser::FileChooser(FileChooserClient* client, const String& filename) - : m_client(client) - , m_filename(filename) - , m_icon(chooseIcon(filename)) - , m_controller(AdoptNS, [[WebCoreOpenPanelController alloc] initWithFileChooser:this]) -{ -} - -FileChooser::~FileChooser() -{ - [m_controller.get() disconnectFileChooser]; -} - -void FileChooser::openFileChooser(Document* document) -{ - if (Frame* frame = document->frame()) - [m_controller.get() beginSheetWithFrame:frame]; -} - String FileChooser::basenameForWidth(const Font& font, int width) const { if (width <= 0) return String(); String strToTruncate; - if (m_filename.isEmpty()) + if (m_filenames.isEmpty()) strToTruncate = fileButtonNoFileSelectedLabel(); + else if (m_filenames.size() == 1) + strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:(m_filenames[0])]; else - strToTruncate = [[NSFileManager defaultManager] displayNameAtPath:m_filename]; + return StringTruncator::rightTruncate(multipleFileUploadText(m_filenames.size()), width, font, false); return StringTruncator::centerTruncate(strToTruncate, width, font, false); } diff --git a/WebCore/platform/mac/KURLMac.mm b/WebCore/platform/mac/KURLMac.mm index 102f3a5..c913ab4 100644 --- a/WebCore/platform/mac/KURLMac.mm +++ b/WebCore/platform/mac/KURLMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 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 @@ -23,42 +23,45 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "config.h" +#import "config.h" #import "KURL.h" #import "FoundationExtras.h" -#import <wtf/Assertions.h> -#import <wtf/Vector.h> namespace WebCore { KURL::KURL(NSURL *url) { - if (url) { - CFIndex bytesLength = CFURLGetBytes((CFURLRef)url, 0, 0); - Vector<char, 2048> buffer(bytesLength + 6); // 5 for "file:", 1 for NUL terminator - char *bytes = &buffer[5]; - CFURLGetBytes((CFURLRef)url, (UInt8 *)bytes, bytesLength); - bytes[bytesLength] = '\0'; - if (bytes[0] == '/') { - buffer[0] = 'f'; - buffer[1] = 'i'; - buffer[2] = 'l'; - buffer[3] = 'e'; - buffer[4] = ':'; - parse(buffer.data(), 0); - } else - parse(bytes, 0); - } else + if (!url) { parse(0, 0); + return; + } + + CFIndex bytesLength = CFURLGetBytes(reinterpret_cast<CFURLRef>(url), 0, 0); + Vector<char, 512> buffer(bytesLength + 6); // 5 for "file:", 1 for null character to end C string + char* bytes = &buffer[5]; + CFURLGetBytes(reinterpret_cast<CFURLRef>(url), reinterpret_cast<UInt8*>(bytes), bytesLength); + bytes[bytesLength] = '\0'; + if (bytes[0] != '/') { + parse(bytes, 0); + return; + } + + buffer[0] = 'f'; + buffer[1] = 'i'; + buffer[2] = 'l'; + buffer[3] = 'e'; + buffer[4] = ':'; + + parse(buffer.data(), 0); } -NSURL *KURL::getNSURL() const +KURL::operator NSURL *() const { - if (urlString.isNull()) + if (isNull()) return nil; - // CFURL can't hold an empty URL, unlike NSURL + // CFURL can't hold an empty URL, unlike NSURL. if (isEmpty()) return [NSURL URLWithString:@""]; diff --git a/WebCore/platform/mac/KeyEventMac.mm b/WebCore/platform/mac/KeyEventMac.mm index 9aa6d8b..b6c3b21 100644 --- a/WebCore/platform/mac/KeyEventMac.mm +++ b/WebCore/platform/mac/KeyEventMac.mm @@ -815,6 +815,7 @@ PlatformKeyboardEvent::PlatformKeyboardEvent(NSEvent *event) , m_keyIdentifier(keyIdentifierForKeyEvent(event)) , m_autoRepeat(([event type] != NSFlagsChanged) && [event isARepeat]) , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(event)) + , m_nativeVirtualKeyCode([event keyCode]) , m_isKeypad(isKeypadEvent(event)) , m_shiftKey([event modifierFlags] & NSShiftKeyMask) , m_ctrlKey([event modifierFlags] & NSControlKeyMask) diff --git a/WebCore/platform/mac/LocalizedStringsMac.mm b/WebCore/platform/mac/LocalizedStringsMac.mm index f5b208d..d458778 100644 --- a/WebCore/platform/mac/LocalizedStringsMac.mm +++ b/WebCore/platform/mac/LocalizedStringsMac.mm @@ -27,6 +27,7 @@ #import "LocalizedStrings.h" #import "BlockExceptions.h" +#import "IntSize.h" #import "PlatformString.h" #import "WebCoreViewFactory.h" @@ -496,6 +497,78 @@ String AXHeadingText() return String(); } +String AXDefinitionListTermText() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXDefinitionListTermText]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXDefinitionListDefinitionText() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXDefinitionListDefinitionText]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXButtonActionVerb() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXButtonActionVerb]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXRadioButtonActionVerb() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXRadioButtonActionVerb]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXTextFieldActionVerb() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXTextFieldActionVerb]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXCheckedCheckBoxActionVerb() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXCheckedCheckBoxActionVerb]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXUncheckedCheckBoxActionVerb() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXUncheckedCheckBoxActionVerb]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String AXLinkActionVerb() +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] AXLinkActionVerb]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + +String multipleFileUploadText(unsigned numberOfFiles) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] multipleFileUploadTextForNumberOfFiles:numberOfFiles]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + String unknownFileSizeText() { BEGIN_BLOCK_OBJC_EXCEPTIONS; @@ -504,4 +577,12 @@ String unknownFileSizeText() return String(); } +String imageTitle(const String& filename, const IntSize& size) +{ + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return [[WebCoreViewFactory sharedFactory] imageTitleForFilename:filename width:size.width() height:size.height()]; + END_BLOCK_OBJC_EXCEPTIONS; + return String(); +} + } diff --git a/WebCore/platform/mac/LoggingMac.mm b/WebCore/platform/mac/LoggingMac.mm index bb7a2be..2ee983c 100644 --- a/WebCore/platform/mac/LoggingMac.mm +++ b/WebCore/platform/mac/LoggingMac.mm @@ -68,6 +68,7 @@ void InitializeLoggingChannelsIfNecessary() initializeWithUserDefault(LogStorageAPI); initializeWithUserDefault(LogMedia); initializeWithUserDefault(LogPlugin); + initializeWithUserDefault(LogArchives); } } diff --git a/WebCore/platform/mac/MIMETypeRegistryMac.mm b/WebCore/platform/mac/MIMETypeRegistryMac.mm index 36474cc..c67b891 100644 --- a/WebCore/platform/mac/MIMETypeRegistryMac.mm +++ b/WebCore/platform/mac/MIMETypeRegistryMac.mm @@ -1,6 +1,6 @@ /* * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2007 Trolltech ASA + * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/WebCore/platform/mac/PasteboardMac.mm b/WebCore/platform/mac/PasteboardMac.mm index 87db2f9..4e15ad0 100644 --- a/WebCore/platform/mac/PasteboardMac.mm +++ b/WebCore/platform/mac/PasteboardMac.mm @@ -33,14 +33,15 @@ #import "DocumentFragment.h" #import "Editor.h" #import "EditorClient.h" +#import "Frame.h" #import "HitTestResult.h" #import "Image.h" #import "KURL.h" +#import "LegacyWebArchive.h" #import "LoaderNSURLExtras.h" #import "MIMETypeRegistry.h" #import "RenderImage.h" #import "WebCoreNSStringExtras.h" -#import "WebCoreSystemInterface.h" #import "markup.h" #import <wtf/RetainPtr.h> @@ -159,7 +160,9 @@ void Pasteboard::writeSelection(NSPasteboard* pasteboard, Range* selectedRange, // Put HTML on the pasteboard. if ([types containsObject:WebArchivePboardType]) { - [pasteboard setData:frame->editor()->client()->dataForArchivedSelection(frame) forType:WebArchivePboardType]; + RefPtr<LegacyWebArchive> archive = LegacyWebArchive::createFromSelection(frame); + RetainPtr<CFDataRef> data = archive ? archive->rawDataRepresentation() : 0; + [pasteboard setData:(NSData *)data.get() forType:WebArchivePboardType]; } // Put the attributed string on the pasteboard (RTF/RTFD format). @@ -210,7 +213,7 @@ void Pasteboard::writeURL(NSPasteboard* pasteboard, NSArray* types, const KURL& ASSERT(!url.isEmpty()); - NSURL *cocoaURL = url.getNSURL(); + NSURL *cocoaURL = url; NSString *userVisibleString = frame->editor()->client()->userVisibleString(cocoaURL); NSString *title = (NSString*)titleStr; @@ -270,17 +273,21 @@ void Pasteboard::writeImage(Node* node, const KURL& url, const String& title) ASSERT(node); Frame* frame = node->document()->frame(); - NSURL *cocoaURL = url.getNSURL(); + NSURL *cocoaURL = url; ASSERT(cocoaURL); - NSArray* types = writableTypesForImage(); - [m_pasteboard.get() declareTypes:types owner:nil]; - writeURL(m_pasteboard.get(), types, cocoaURL, nsStringNilIfEmpty(title), frame); - ASSERT(node->renderer() && node->renderer()->isImage()); RenderImage* renderer = static_cast<RenderImage*>(node->renderer()); CachedImage* cachedImage = static_cast<CachedImage*>(renderer->cachedImage()); ASSERT(cachedImage); + + if (cachedImage->errorOccurred()) + return; + + NSArray* types = writableTypesForImage(); + [m_pasteboard.get() declareTypes:types owner:nil]; + writeURL(m_pasteboard.get(), types, cocoaURL, nsStringNilIfEmpty(title), frame); + Image* image = cachedImage->image(); ASSERT(image); diff --git a/WebCore/platform/mac/PlatformScreenMac.mm b/WebCore/platform/mac/PlatformScreenMac.mm index e98ff25..8f12df0 100644 --- a/WebCore/platform/mac/PlatformScreenMac.mm +++ b/WebCore/platform/mac/PlatformScreenMac.mm @@ -57,13 +57,13 @@ bool screenIsMonochrome(Widget*) FloatRect screenRect(Widget* widget) { - NSWindow *window = widget ? [widget->getView() window] : nil; + NSWindow *window = widget ? [widget->platformWidget() window] : nil; return toUserSpace([screenForWindow(window) frame], window); } FloatRect screenAvailableRect(Widget* widget) { - NSWindow *window = widget ? [widget->getView() window] : nil; + NSWindow *window = widget ? [widget->platformWidget() window] : nil; return toUserSpace([screenForWindow(window) visibleFrame], window); } diff --git a/WebCore/platform/mac/PlatformScrollBar.h b/WebCore/platform/mac/PlatformScrollBar.h deleted file mode 100644 index 36e9ade..0000000 --- a/WebCore/platform/mac/PlatformScrollBar.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PlatformScrollBar_h -#define PlatformScrollBar_h - -#include "Widget.h" -#include "ScrollBar.h" - -#ifdef __OBJC__ -@class NSScroller; -#else -class NSScroller; -typedef int NSScrollerPart; -#endif - -namespace WebCore { - -class PlatformScrollbar : public Widget, public Scrollbar { -public: - PlatformScrollbar(ScrollbarClient*, ScrollbarOrientation, ScrollbarControlSize); - virtual ~PlatformScrollbar(); - - virtual bool isWidget() const { return true; } - - virtual int width() const; - virtual int height() const; - virtual void setRect(const IntRect&); - virtual void setEnabled(bool); - virtual void paint(GraphicsContext*, const IntRect& damageRect); - - bool scrollbarHit(NSScrollerPart); - - static int horizontalScrollbarHeight() { return 15; } - static int verticalScrollbarWidth() { return 15; } - -protected: - virtual void updateThumbPosition(); - virtual void updateThumbProportion(); -}; - -} - -#endif // PlatformScrollBar_h - diff --git a/WebCore/platform/mac/PlatformScrollBarMac.mm b/WebCore/platform/mac/PlatformScrollBarMac.mm deleted file mode 100644 index b07e055..0000000 --- a/WebCore/platform/mac/PlatformScrollBarMac.mm +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "PlatformScrollBar.h" - -#import "BlockExceptions.h" - -using namespace WebCore; - -@interface WebCoreScrollBar : NSScroller -{ - PlatformScrollbar* scrollbar; -} - -- (id)initWithPlatformScrollbar:(PlatformScrollbar*)s; -- (void)detachPlatformScrollbar; - -@end - -@implementation WebCoreScrollBar - -static NSControlSize NSControlSizeForScrollBarControlSize(ScrollbarControlSize size) -{ - if (size == SmallScrollbar) - return NSSmallControlSize; - if (size == MiniScrollbar) - return NSMiniControlSize; - return NSRegularControlSize; -} - -- (id)initWithPlatformScrollbar:(PlatformScrollbar*)s -{ - // Cocoa scrollbars just set their orientation by examining their own - // dimensions, so we have to do this unsavory hack. - NSRect orientation; - NSControlSize controlSize = NSControlSizeForScrollBarControlSize(s->controlSize()); - orientation.origin.x = orientation.origin.y = 0; - if (s->orientation() == VerticalScrollbar) { - orientation.size.width = [NSScroller scrollerWidthForControlSize:controlSize]; - orientation.size.height = 100; - } else { - orientation.size.width = 100; - orientation.size.height = [NSScroller scrollerWidthForControlSize:controlSize]; - } - self = [self initWithFrame:orientation]; - - scrollbar = s; - - [self setEnabled:YES]; - [self setTarget:self]; - [self setAction:@selector(scroll:)]; - [self setControlSize:controlSize]; - - return self; -} - -- (void)detachPlatformScrollbar -{ - [self setTarget:nil]; - scrollbar = 0; -} - -- (IBAction)scroll:(NSScroller*)sender -{ - if (scrollbar) - scrollbar->scrollbarHit([sender hitPart]); -} - -- (void)mouseDown:(NSEvent *)event -{ - Widget::beforeMouseDown(self, scrollbar); - [super mouseDown:event]; - Widget::afterMouseDown(self, scrollbar); -} - -@end - -namespace WebCore -{ - -PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize controlSize) - : Scrollbar(client, orientation, controlSize) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - WebCoreScrollBar *bar = [[WebCoreScrollBar alloc] initWithPlatformScrollbar:this]; - setView(bar); - [bar release]; - - END_BLOCK_OBJC_EXCEPTIONS; -} - -PlatformScrollbar::~PlatformScrollbar() -{ - WebCoreScrollBar* bar = (WebCoreScrollBar*)getView(); - [bar detachPlatformScrollbar]; - - // Widget should probably do this for all widgets. - // But we don't need it for form elements, and for frames it doesn't work - // well because of the way the NSViews are created in WebKit. So for now, - // we'll just do it explictly for Scrollbar. - removeFromSuperview(); -} - -void PlatformScrollbar::updateThumbPosition() -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - WebCoreScrollBar *bar = (WebCoreScrollBar *)getView(); - [bar setFloatValue:(float)m_currentPos / (m_totalSize - m_visibleSize) - knobProportion:[bar knobProportion]]; - END_BLOCK_OBJC_EXCEPTIONS; -} - -void PlatformScrollbar::updateThumbProportion() -{ - float val = static_cast<float>(m_visibleSize) / m_totalSize; - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - WebCoreScrollBar *bar = (WebCoreScrollBar *)getView(); - if (val != [bar knobProportion] && val >= 0) - [bar setFloatValue:static_cast<float>(m_currentPos) / (m_totalSize - m_visibleSize) knobProportion:val]; - END_BLOCK_OBJC_EXCEPTIONS; -} - -bool PlatformScrollbar::scrollbarHit(NSScrollerPart hitPart) -{ - int maxPos = m_totalSize - m_visibleSize; - if (maxPos <= 0) - return false; // Impossible to scroll anywhere. - - WebCoreScrollBar *bar = (WebCoreScrollBar *)getView(); - int newPos = value(); - switch (hitPart) { - case NSScrollerDecrementLine: - newPos -= m_lineStep; - break; - case NSScrollerIncrementLine: - newPos += m_lineStep; - break; - case NSScrollerDecrementPage: - newPos -= m_pageStep; - break; - case NSScrollerIncrementPage: - newPos += m_pageStep; - break; - - // If the thumb is hit, then the scrollbar changed its value for us. - case NSScrollerKnob: - case NSScrollerKnobSlot: - newPos = (int)([bar floatValue] * maxPos); - break; - - case NSScrollerNoPart: - break; - } - - return setValue(newPos); -} - -int PlatformScrollbar::width() const -{ - return Widget::width(); -} - -int PlatformScrollbar::height() const -{ - return Widget::height(); -} - -void PlatformScrollbar::setRect(const IntRect& rect) -{ - setFrameGeometry(rect); -} - -void PlatformScrollbar::setEnabled(bool enabled) -{ - Widget::setEnabled(enabled); -} - -void PlatformScrollbar::paint(GraphicsContext* graphicsContext, const IntRect& damageRect) -{ - Widget::paint(graphicsContext, damageRect); -} - -} diff --git a/WebCore/platform/mac/PlugInInfoStoreMac.mm b/WebCore/platform/mac/PlugInInfoStoreMac.mm deleted file mode 100644 index 2776eae..0000000 --- a/WebCore/platform/mac/PlugInInfoStoreMac.mm +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "PluginInfoStore.h" - -#import "BlockExceptions.h" -#import "Logging.h" -#import "WebCoreViewFactory.h" - -namespace WebCore { - -String PluginInfoStore::pluginNameForMIMEType(const String& mimeType) -{ - return [[WebCoreViewFactory sharedFactory] pluginNameForMIMEType:mimeType]; -} - -PluginInfo *PluginInfoStore::createPluginInfoForPluginAtIndex(unsigned index) -{ - PluginInfo *pluginInfo = new PluginInfo; - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - id <WebCorePluginInfo> plugin = [[[WebCoreViewFactory sharedFactory] pluginsInfo] objectAtIndex:index]; - - pluginInfo->name = [plugin name]; - pluginInfo->file = [plugin filename]; - pluginInfo->desc = [plugin pluginDescription]; - - NSEnumerator *MIMETypeEnumerator = [plugin MIMETypeEnumerator]; - while (NSString *MIME = [MIMETypeEnumerator nextObject]) { - MimeClassInfo *mime = new MimeClassInfo; - pluginInfo->mimes.append(mime); - mime->type = String(MIME).lower(); - mime->suffixes = [[plugin extensionsForMIMEType:MIME] componentsJoinedByString:@","]; - mime->desc = [plugin descriptionForMIMEType:MIME]; - mime->plugin = pluginInfo; - } - - return pluginInfo; - - END_BLOCK_OBJC_EXCEPTIONS; - - if (pluginInfo && !pluginInfo->mimes.isEmpty()) - deleteAllValues(pluginInfo->mimes); - delete pluginInfo; - - return 0; -} - -unsigned PluginInfoStore::pluginCount() const -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - return [[[WebCoreViewFactory sharedFactory] pluginsInfo] count]; - END_BLOCK_OBJC_EXCEPTIONS; - - return 0; -} - -bool PluginInfoStore::supportsMIMEType(const String& mimeType) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - return [[WebCoreViewFactory sharedFactory] pluginSupportsMIMEType:mimeType]; - END_BLOCK_OBJC_EXCEPTIONS; - - return NO; -} - -void refreshPlugins(bool reloadOpenPages) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - [[WebCoreViewFactory sharedFactory] refreshPlugins:reloadOpenPages]; - END_BLOCK_OBJC_EXCEPTIONS; -} - -} - diff --git a/WebCore/platform/mac/PopupMenuMac.mm b/WebCore/platform/mac/PopupMenuMac.mm index 0d6565b..23324d3 100644 --- a/WebCore/platform/mac/PopupMenuMac.mm +++ b/WebCore/platform/mac/PopupMenuMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,14 +20,16 @@ #import "config.h" #import "PopupMenu.h" +#import "ChromeClient.h" #import "EventHandler.h" -#import "SimpleFontData.h" #import "Frame.h" #import "FrameView.h" #import "HTMLNames.h" #import "HTMLOptGroupElement.h" #import "HTMLOptionElement.h" #import "HTMLSelectElement.h" +#import "Page.h" +#import "SimpleFontData.h" #import "WebCoreSystemInterface.h" namespace WebCore { @@ -76,10 +78,10 @@ void PopupMenu::populate() if (client()->itemIsSeparator(i)) [[m_popup.get() menu] addItem:[NSMenuItem separatorItem]]; else { - RenderStyle* style = client()->itemStyle(i); + PopupMenuStyle style = client()->itemStyle(i); NSMutableDictionary* attributes = [[NSMutableDictionary alloc] init]; - if (style->font() != Font()) - [attributes setObject:style->font().primaryFont()->getNSFont() forKey:NSFontAttributeName]; + if (style.font() != Font()) + [attributes setObject:style.font().primaryFont()->getNSFont() forKey:NSFontAttributeName]; // FIXME: Add support for styling the foreground and background colors. // FIXME: Find a way to customize text color when an item is highlighted. NSAttributedString* string = [[NSAttributedString alloc] initWithString:client()->itemText(i) attributes:attributes]; @@ -111,7 +113,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) if (index == -1 && numItems == 2 && !client()->shouldPopOver() && ![[m_popup.get() itemAtIndex:1] isEnabled]) index = 0; - NSView* view = v->getDocumentView(); + NSView* view = v->documentView(); [m_popup.get() attachPopUpWithFrame:r inView:view]; [m_popup.get() selectItemAtIndex:index]; @@ -119,7 +121,7 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) NSMenu* menu = [m_popup.get() menu]; NSPoint location; - NSFont* font = client()->clientStyle()->font().primaryFont()->getNSFont(); + NSFont* font = client()->menuStyle().font().primaryFont()->getNSFont(); // These values were borrowed from AppKit to match their placement of the menu. const int popOverHorizontalAdjust = -10; @@ -150,7 +152,8 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) [view addSubview:dummyView.get()]; location = [dummyView.get() convertPoint:location fromView:view]; - frame->willPopupMenu(menu); + if (Page* page = frame->page()) + page->chrome()->client()->willPopUpMenu(menu); wkPopupMenu(menu, location, roundf(NSWidth(r)), dummyView.get(), index, font); [m_popup.get() dismissPopUp]; diff --git a/WebCore/platform/mac/SSLKeyGeneratorMac.mm b/WebCore/platform/mac/SSLKeyGeneratorMac.mm index 5c4161a..dd76b59 100644 --- a/WebCore/platform/mac/SSLKeyGeneratorMac.mm +++ b/WebCore/platform/mac/SSLKeyGeneratorMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2003, 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 @@ -31,22 +31,19 @@ namespace WebCore { -Vector<String> supportedKeySizes() +void getSupportedKeySizes(Vector<String>& supportedKeySizes) { NSEnumerator *enumerator = [[[WebCoreKeyGenerator sharedGenerator] strengthMenuItemTitles] objectEnumerator]; - Vector<String> supportedKeySizes; NSString *string; - while ((string = [enumerator nextObject]) != nil) { + while ((string = [enumerator nextObject]) != nil) supportedKeySizes.append(string); - } - return supportedKeySizes; } String signedPublicKeyAndChallengeString(unsigned keySizeIndex, const String& challengeString, const KURL& url) { return [[WebCoreKeyGenerator sharedGenerator] signedPublicKeyAndChallengeStringWithStrengthIndex:keySizeIndex challenge:challengeString - pageURL:url.getNSURL()]; + pageURL:url]; } } diff --git a/WebCore/platform/mac/WebCoreObjCExtras.c b/WebCore/platform/mac/SchedulePairMac.mm index cac1116..e1709b3 100644 --- a/WebCore/platform/mac/WebCoreObjCExtras.c +++ b/WebCore/platform/mac/SchedulePairMac.mm @@ -1,18 +1,18 @@ /* - * Copyright (C) 2007 Apple Inc. All rights reserved. + * 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. + * 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. + * 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. + * 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 @@ -26,13 +26,18 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "WebCoreObjCExtras.h" +#include "config.h" -#include <objc/objc-auto.h> +#include "SchedulePair.h" -void WebCoreObjCFinalizeOnMainThread(Class cls) +namespace WebCore { + +SchedulePair::SchedulePair(NSRunLoop* runLoop, CFStringRef mode) + : m_nsRunLoop(runLoop) + , m_runLoop([runLoop getCFRunLoop]) { -#if !defined(BUILDING_ON_TIGER) && !defined(DONT_FINALIZE_ON_MAIN_THREAD) - objc_finalizeOnMainThread(cls); -#endif + if (mode) + m_mode.adoptCF(CFStringCreateCopy(0, mode)); } + +} // namespace diff --git a/WebCore/platform/mac/ScrollViewMac.mm b/WebCore/platform/mac/ScrollViewMac.mm index 1caa433..6d477e2 100644 --- a/WebCore/platform/mac/ScrollViewMac.mm +++ b/WebCore/platform/mac/ScrollViewMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 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 @@ -26,333 +26,146 @@ #import "config.h" #import "ScrollView.h" +#import "BlockExceptions.h" #import "FloatRect.h" #import "IntRect.h" -#import "BlockExceptions.h" #import "Logging.h" +#import "NotImplemented.h" #import "WebCoreFrameView.h" -/* - This class implementation does NOT actually emulate the Qt ScrollView. - It does provide an implementation that khtml will use to interact with - WebKit's WebFrameView documentView and our NSScrollView subclass. +using namespace std; - ScrollView's view is a NSScrollView (or subclass of NSScrollView) - in most cases. That scrollview is a subview of an - WebCoreFrameView. The WebCoreFrameView's documentView will also be - the scroll view's documentView. - - The WebCoreFrameView's size is the frame size. The WebCoreFrameView's documentView - corresponds to the frame content size. The scrollview itself is autosized to the - WebCoreFrameView's size (see Widget::resize). -*/ +@interface NSWindow (WebWindowDetails) +- (BOOL)_needsToResetDragMargins; +- (void)_setNeedsToResetDragMargins:(BOOL)needs; +@end namespace WebCore { -int ScrollView::visibleWidth() const -{ - NSScrollView *view = (NSScrollView *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - return (int)[view documentVisibleRect].size.width; - else - return (int)[view bounds].size.width; - END_BLOCK_OBJC_EXCEPTIONS; - - return 0; -} - -int ScrollView::visibleHeight() const -{ - NSScrollView *view = (NSScrollView *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - return (int)[view documentVisibleRect].size.height; - else - return (int)[view bounds].size.height; - END_BLOCK_OBJC_EXCEPTIONS; - - return 0; -} - -FloatRect ScrollView::visibleContentRect() const +inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const { - NSScrollView *view = (NSScrollView *)getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - return [view documentVisibleRect]; - else - return [view visibleRect]; - END_BLOCK_OBJC_EXCEPTIONS; - - return FloatRect(); + ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]); + ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]); + return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget()); } -FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const +NSView *ScrollView::documentView() const { BEGIN_BLOCK_OBJC_EXCEPTIONS; - if (NSView *docView = getDocumentView()) - return [docView visibleRect]; + return [scrollView() documentView]; END_BLOCK_OBJC_EXCEPTIONS; - - return FloatRect(); + return nil; } - -int ScrollView::contentsWidth() const +void ScrollView::platformAddChild(Widget* child) { - NSView *docView, *view = getView(); - docView = getDocumentView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if (docView) - return (int)[docView bounds].size.width; - else - return (int)[view bounds].size.width; + NSView *parentView = documentView(); + NSView *childView = child->getOuterView(); + ASSERT(![parentView isDescendantOf:childView]); + + // Suppress the resetting of drag margins since we know we can't affect them. + NSWindow *window = [parentView window]; + BOOL resetDragMargins = [window _needsToResetDragMargins]; + [window _setNeedsToResetDragMargins:NO]; + if ([childView superview] != parentView) + [parentView addSubview:childView]; + [window _setNeedsToResetDragMargins:resetDragMargins]; END_BLOCK_OBJC_EXCEPTIONS; - - return 0; } -int ScrollView::contentsHeight() const +void ScrollView::platformRemoveChild(Widget* child) { - NSView *docView, *view = getView(); - docView = getDocumentView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if (docView) - return (int)[docView bounds].size.height; - else - return (int)[view bounds].size.height; - END_BLOCK_OBJC_EXCEPTIONS; - - return 0; + child->removeFromSuperview(); } -int ScrollView::contentsX() const +void ScrollView::platformSetScrollbarModes() { - NSView *view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - return (int)[(NSScrollView *)view documentVisibleRect].origin.x; - else - return (int)[view visibleRect].origin.x; + [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO]; END_BLOCK_OBJC_EXCEPTIONS; - - return 0; } -int ScrollView::contentsY() const +void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const { - NSView *view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - return (int)[(NSScrollView *)view documentVisibleRect].origin.y; - else - return (int)[view visibleRect].origin.y; + [scrollView() scrollingModes:&horizontal vertical:&vertical]; END_BLOCK_OBJC_EXCEPTIONS; - - return 0; } - -IntSize ScrollView::scrollOffset() const -{ - NSView *view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - return IntPoint([[(NSScrollView *)view contentView] visibleRect].origin) - IntPoint(); - END_BLOCK_OBJC_EXCEPTIONS; - return IntSize(); -} - -void ScrollView::scrollBy(int dx, int dy) -{ - setContentsPos(contentsX() + dx, contentsY() + dy); -} - -void ScrollView::scrollRectIntoViewRecursively(const IntRect& r) -{ - NSRect rect = r; - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *docView; - NSView *view = getView(); - docView = getDocumentView(); - if (docView) - view = docView; - - NSView *originalView = view; - while (view) { - if ([view isKindOfClass:[NSClipView class]]) { - NSClipView *clipView = (NSClipView *)view; - NSView *documentView = [clipView documentView]; - [documentView scrollRectToVisible:[documentView convertRect:rect fromView:originalView]]; - } - - view = [view superview]; - } - - END_BLOCK_OBJC_EXCEPTIONS; -} - -void ScrollView::setContentsPos(int x, int y) +void ScrollView::platformSetCanBlitOnScroll() { - x = (x < 0) ? 0 : x; - y = (y < 0) ? 0 : y; - NSPoint p = NSMakePoint(x,y); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *docView; - NSView *view = getView(); - docView = getDocumentView(); - if (docView) - view = docView; - [view scrollPoint:p]; + [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll()]; END_BLOCK_OBJC_EXCEPTIONS; } -void ScrollView::setVScrollbarMode(ScrollbarMode vMode) +IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const { - NSView* view = getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { - NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view; - [frameView setVerticalScrollingMode: (WebCoreScrollbarMode)vMode]; + BEGIN_BLOCK_OBJC_EXCEPTIONS; + if (includeScrollbars) { + if (NSView* documentView = this->documentView()) + return enclosingIntRect([documentView visibleRect]); } - END_BLOCK_OBJC_EXCEPTIONS; + return enclosingIntRect([scrollView() documentVisibleRect]); + END_BLOCK_OBJC_EXCEPTIONS; + return IntRect(); } -void ScrollView::setHScrollbarMode(ScrollbarMode hMode) +IntSize ScrollView::platformContentsSize() const { - NSView* view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { - NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view; - [frameView setHorizontalScrollingMode: (WebCoreScrollbarMode)hMode]; - } + if (NSView* documentView = this->documentView()) + return enclosingIntRect([documentView bounds]).size(); END_BLOCK_OBJC_EXCEPTIONS; + return IntSize(); } -void ScrollView::setScrollbarsMode(ScrollbarMode mode) +void ScrollView::platformSetContentsSize() { - NSView* view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { - NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view; - [frameView setScrollingMode: (WebCoreScrollbarMode)mode]; - } + int w = m_contentsSize.width(); + int h = m_contentsSize.height(); + LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h); + NSSize tempSize = { max(0, w), max(0, h) }; // workaround for 4213314 + [documentView() setFrameSize:tempSize]; END_BLOCK_OBJC_EXCEPTIONS; } -ScrollbarMode ScrollView::vScrollbarMode() const +void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress) { - NSView* view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { - NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view; - return (ScrollbarMode)[frameView verticalScrollingMode]; - } + [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed + repaintOnUnsuppress:repaintOnUnsuppress]; END_BLOCK_OBJC_EXCEPTIONS; - - return ScrollbarAuto; } -ScrollbarMode ScrollView::hScrollbarMode() const +void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint) { - NSView* view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { - NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view; - return (ScrollbarMode)[frameView horizontalScrollingMode]; - } + NSPoint tempPoint = { max(0, scrollPoint.x()), max(0, scrollPoint.y()) }; // Don't use NSMakePoint to work around 4213314. + [documentView() scrollPoint:tempPoint]; END_BLOCK_OBJC_EXCEPTIONS; - - return ScrollbarAuto; } -void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnUnsuppress) +bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity) { - NSView* view = getView(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { - NSView<WebCoreFrameView>* frameView = (NSView<WebCoreFrameView>*)view; - [frameView setScrollBarsSuppressed: suppressed - repaintOnUnsuppress: repaintOnUnsuppress]; - } - END_BLOCK_OBJC_EXCEPTIONS; + // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away. + notImplemented(); + return true; } -void ScrollView::addChild(Widget* child) -{ - ASSERT(child != this); - - NSView *thisView = getView(); - NSView *thisDocView = getDocumentView(); - if (thisDocView) - thisView = thisDocView; - -#ifndef NDEBUG - NSView *subview = child->getOuterView(); - - LOG(Frames, "Adding %p %@ with size w %d h %d\n", subview, - [(id)[subview class] className], (int)[subview frame].size.width, (int)[subview frame].size.height); -#endif - child->addToSuperview(thisView); -} - -void ScrollView::removeChild(Widget* child) -{ - child->removeFromSuperview(); -} - -void ScrollView::resizeContents(int w, int h) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - int _w = w; - int _h = h; - - LOG(Frames, "%p %@ at w %d h %d\n", getView(), [(id)[getView() class] className], w, h); - NSView *view = getView(); - if ([view isKindOfClass:[NSScrollView class]]){ - view = getDocumentView(); - - LOG(Frames, "%p %@ at w %d h %d\n", view, [(id)[view class] className], w, h); - if (_w < 0) - _w = 0; - if (_h < 0) - _h = 0; - - NSSize tempSize = { _w, _h }; // workaround for 4213314 - [view setFrameSize:tempSize]; - } else { - resize (_w, _h); - } - END_BLOCK_OBJC_EXCEPTIONS; -} - -void ScrollView::updateContents(const IntRect &rect, bool now) +void ScrollView::platformRepaintContentRectangle(const IntRect& rect, bool now) { BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *view = getView(); - - if ([view isKindOfClass:[NSScrollView class]]) - view = getDocumentView(); - + NSView *view = documentView(); NSRect visibleRect = visibleContentRect(); + // FIXME: I don't think this intersection is necessary any more now that + // selection doesn't call this method directly (but has to go through FrameView's + // repaintContentRectangle, which does the intersection test also). Leaving it in + // for now until I'm sure. // Checking for rect visibility is an important optimization for the case of // Select All of a large document. AppKit does not do this check, and so ends // up building a large complicated NSRegion if we don't perform the check. @@ -368,134 +181,35 @@ void ScrollView::updateContents(const IntRect &rect, bool now) END_BLOCK_OBJC_EXCEPTIONS; } -void ScrollView::update() -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - NSView *view = getView(); - [[view window] displayIfNeeded]; - [[view window] flushWindowIfNeeded]; - - END_BLOCK_OBJC_EXCEPTIONS; -} - // "Containing Window" means the NSWindow's coord system, which is origin lower left -IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - NSView *docView; - NSView *view = getView(); - - docView = getDocumentView(); - if (docView) - view = docView; - - NSPoint tempPoint = { contentsPoint.x(), contentsPoint.y() }; // workaround for 4213314 - NSPoint np = [view convertPoint:tempPoint toView: nil]; - return IntPoint(np); - - END_BLOCK_OBJC_EXCEPTIONS; - - return IntPoint(); -} - -IntPoint ScrollView::windowToContents(const IntPoint& point) const +IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const { BEGIN_BLOCK_OBJC_EXCEPTIONS; - - NSView *docView; - NSView *view = getView(); - - docView = getDocumentView(); - if (docView) - view = docView; - - NSPoint tempPoint = { point.x(), point.y() }; // workaround for 4213314 - NSPoint np = [view convertPoint:tempPoint fromView: nil]; - - return IntPoint(np); - - END_BLOCK_OBJC_EXCEPTIONS; - - return IntPoint(); -} - -IntRect ScrollView::contentsToWindow(const IntRect& contentsRect) const -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - NSView* docView; - NSView* view = getView(); - - docView = getDocumentView(); - if (docView) - view = docView; - - NSRect nr = [view convertRect:contentsRect toView: nil]; - return IntRect(nr); - - END_BLOCK_OBJC_EXCEPTIONS; - - return IntRect(); -} - -IntRect ScrollView::windowToContents(const IntRect& rect) const -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - - NSView* docView; - NSView* view = getView(); - - docView = getDocumentView(); - if (docView) - view = docView; - - NSRect nr = [view convertRect:rect fromView: nil]; - - return IntRect(nr); - + if (NSView* documentView = this->documentView()) { + NSRect tempRect = rect; + tempRect = [documentView convertRect:tempRect toView:nil]; + tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin]; + return enclosingIntRect(tempRect); + } END_BLOCK_OBJC_EXCEPTIONS; - return IntRect(); } -void ScrollView::setStaticBackground(bool b) -{ - NSScrollView *view = (NSScrollView *)getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view isKindOfClass:[NSScrollView class]]) - [[view contentView] setCopiesOnScroll: !b]; - END_BLOCK_OBJC_EXCEPTIONS; -} - -NSView *ScrollView::getDocumentView() const +IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const { - id view = getView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view respondsToSelector:@selector(documentView)]) - return [view documentView]; + if (NSView* documentView = this->documentView()) { + NSPoint windowCoord = [[documentView window] convertScreenToBase: point]; + return IntPoint([documentView convertPoint:windowCoord fromView:nil]); + } END_BLOCK_OBJC_EXCEPTIONS; - - return nil; -} - -PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent) -{ - // On Mac, the ScrollView is really the "document", so events will never flow into it to get to the scrollers. - return 0; -} - -bool ScrollView::inWindow() const -{ - return [getView() window]; + return IntPoint(); } -void ScrollView::wheelEvent(PlatformWheelEvent&) +bool ScrollView::platformIsOffscreen() const { - // Do nothing. NSScrollView handles doing the scroll for us. + return ![platformWidget() window] || ![[platformWidget() window] isVisible]; } } diff --git a/WebCore/platform/mac/ScrollbarThemeMac.h b/WebCore/platform/mac/ScrollbarThemeMac.h new file mode 100644 index 0000000..5af5fd5 --- /dev/null +++ b/WebCore/platform/mac/ScrollbarThemeMac.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef ScrollbarThemeMac_h +#define ScrollbarThemeMac_h + +#include "ScrollbarThemeComposite.h" + +namespace WebCore { + +class ScrollbarThemeMac : public ScrollbarThemeComposite { +public: + ScrollbarThemeMac(); + virtual ~ScrollbarThemeMac(); + + virtual bool paint(Scrollbar*, GraphicsContext* context, const IntRect& damageRect); + + virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + virtual bool supportsControlTints() const { return true; } + + virtual double initialAutoscrollTimerDelay(); + virtual double autoscrollTimerDelay(); + + virtual ScrollbarButtonsPlacement buttonsPlacement() const; + + virtual void registerScrollbar(Scrollbar*); + virtual void unregisterScrollbar(Scrollbar*); + +protected: + virtual bool hasButtons(Scrollbar*); + virtual bool hasThumb(Scrollbar*); + + virtual IntRect backButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect forwardButtonRect(Scrollbar*, ScrollbarPart, bool painting = false); + virtual IntRect trackRect(Scrollbar*, bool painting = false); + + virtual int minimumThumbLength(Scrollbar*); + + virtual bool shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent&); + +public: + void preferencesChanged(); +}; + +} + +#endif diff --git a/WebCore/platform/mac/ScrollbarThemeMac.mm b/WebCore/platform/mac/ScrollbarThemeMac.mm new file mode 100644 index 0000000..dd2c233 --- /dev/null +++ b/WebCore/platform/mac/ScrollbarThemeMac.mm @@ -0,0 +1,403 @@ +/* + * 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 "ScrollbarThemeMac.h" + +#include "GraphicsContext.h" +#include "ImageBuffer.h" +#include "IntRect.h" +#include "Page.h" +#include "PlatformMouseEvent.h" +#include "Scrollbar.h" +#include "ScrollbarClient.h" +#include "Settings.h" + +#include <Carbon/Carbon.h> + +// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow. + +using namespace std; +using namespace WebCore; + +static HashSet<Scrollbar*>* gScrollbars; + +@interface ScrollbarPrefsObserver : NSObject +{ + +} + ++ (void)registerAsObserver; ++ (void)appearancePrefsChanged:(NSNotification*)theNotification; ++ (void)behaviorPrefsChanged:(NSNotification*)theNotification; + +@end + +@implementation ScrollbarPrefsObserver + ++ (void)appearancePrefsChanged:(NSNotification*)theNotification +{ + static_cast<ScrollbarThemeMac*>(ScrollbarTheme::nativeTheme())->preferencesChanged(); + if (!gScrollbars) + return; + HashSet<Scrollbar*>::iterator end = gScrollbars->end(); + for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) { + (*it)->styleChanged(); + (*it)->invalidate(); + } +} + ++ (void)behaviorPrefsChanged:(NSNotification*)theNotification +{ + static_cast<ScrollbarThemeMac*>(ScrollbarTheme::nativeTheme())->preferencesChanged(); +} + ++ (void)registerAsObserver +{ + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(appearancePrefsChanged:) name:@"AppleAquaScrollBarVariantChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(behaviorPrefsChanged:) name:@"AppleNoRedisplayAppearancePreferenceChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce]; +} + +@end + +namespace WebCore { + +ScrollbarTheme* ScrollbarTheme::nativeTheme() +{ + static ScrollbarThemeMac theme; + return &theme; +} + +// FIXME: Get these numbers from CoreUI. +static int cScrollbarThickness[] = { 15, 11 }; +static int cRealButtonLength[] = { 28, 21 }; +static int cButtonInset[] = { 14, 11 }; +static int cButtonHitInset[] = { 3, 2 }; +// cRealButtonLength - cButtonInset +static int cButtonLength[] = { 14, 10 }; +static int cThumbMinLength[] = { 26, 20 }; + +static int cOuterButtonLength[] = { 16, 14 }; // The outer button in a double button pair is a bit bigger. +static int cOuterButtonOverlap = 2; + +static float gInitialButtonDelay = 0.5f; +static float gAutoscrollButtonDelay = 0.05f; +static bool gJumpOnTrackClick = false; +static ScrollbarButtonsPlacement gButtonPlacement = ScrollbarButtonsDoubleEnd; + +static void updateArrowPlacement() +{ + NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleScrollBarVariant"]; + if ([buttonPlacement isEqualToString:@"Single"]) + gButtonPlacement = ScrollbarButtonsSingle; + else if ([buttonPlacement isEqualToString:@"DoubleMin"]) + gButtonPlacement = ScrollbarButtonsDoubleStart; + else if ([buttonPlacement isEqualToString:@"DoubleBoth"]) + gButtonPlacement = ScrollbarButtonsDoubleBoth; + else + gButtonPlacement = ScrollbarButtonsDoubleEnd; // The default is ScrollbarButtonsDoubleEnd. +} + +void ScrollbarThemeMac::registerScrollbar(Scrollbar* scrollbar) +{ + if (!gScrollbars) + gScrollbars = new HashSet<Scrollbar*>; + gScrollbars->add(scrollbar); +} + +void ScrollbarThemeMac::unregisterScrollbar(Scrollbar* scrollbar) +{ + gScrollbars->remove(scrollbar); + if (gScrollbars->isEmpty()) { + delete gScrollbars; + gScrollbars = 0; + } +} + +ScrollbarThemeMac::ScrollbarThemeMac() +{ + static bool initialized; + if (!initialized) { + initialized = true; + [ScrollbarPrefsObserver registerAsObserver]; + preferencesChanged(); + } +} + +ScrollbarThemeMac::~ScrollbarThemeMac() +{ +} + +void ScrollbarThemeMac::preferencesChanged() +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + [defaults synchronize]; + updateArrowPlacement(); + gInitialButtonDelay = [defaults floatForKey:@"NSScrollerButtonDelay"]; + gAutoscrollButtonDelay = [defaults floatForKey:@"NSScrollerButtonPeriod"]; + gJumpOnTrackClick = [defaults boolForKey:@"AppleScrollerPagingBehavior"]; +} + +int ScrollbarThemeMac::scrollbarThickness(ScrollbarControlSize controlSize) +{ + return cScrollbarThickness[controlSize]; +} + +double ScrollbarThemeMac::initialAutoscrollTimerDelay() +{ + return gInitialButtonDelay; +} + +double ScrollbarThemeMac::autoscrollTimerDelay() +{ + return gAutoscrollButtonDelay; +} + +ScrollbarButtonsPlacement ScrollbarThemeMac::buttonsPlacement() const +{ + return gButtonPlacement; +} + +bool ScrollbarThemeMac::hasButtons(Scrollbar* scrollbar) +{ + return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? + scrollbar->width() : + scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->controlSize()] - cButtonHitInset[scrollbar->controlSize()]); +} + +bool ScrollbarThemeMac::hasThumb(Scrollbar* scrollbar) +{ + return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? + scrollbar->width() : + scrollbar->height()) >= 2 * cButtonInset[scrollbar->controlSize()] + cThumbMinLength[scrollbar->controlSize()] + 1; +} + +static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start) +{ + IntRect paintRect(buttonRect); + if (orientation == HorizontalScrollbar) { + paintRect.setWidth(cRealButtonLength[controlSize]); + if (!start) + paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width())); + } else { + paintRect.setHeight(cRealButtonLength[controlSize]); + if (!start) + paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height())); + } + + return paintRect; +} + +IntRect ScrollbarThemeMac::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) +{ + IntRect result; + + if (part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd)) + return result; + + if (part == BackButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsSingle)) + return result; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + bool outerButton = part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsDoubleBoth); + if (outerButton) { + if (scrollbar->orientation() == HorizontalScrollbar) + result = IntRect(scrollbar->x(), scrollbar->y(), cOuterButtonLength[scrollbar->controlSize()] + painting ? cOuterButtonOverlap : 0, thickness); + else + result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cOuterButtonLength[scrollbar->controlSize()] + painting ? cOuterButtonOverlap : 0); + return result; + } + + // Our repaint rect is slightly larger, since we are a button that is adjacent to the track. + if (scrollbar->orientation() == HorizontalScrollbar) { + int start = part == BackButtonStartPart ? scrollbar->x() : scrollbar->x() + scrollbar->width() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()]; + result = IntRect(start, scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness); + } else { + int start = part == BackButtonStartPart ? scrollbar->y() : scrollbar->y() + scrollbar->height() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()]; + result = IntRect(scrollbar->x(), start, thickness, cButtonLength[scrollbar->controlSize()]); + } + + if (painting) + return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == BackButtonStartPart); + return result; +} + +IntRect ScrollbarThemeMac::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) +{ + IntRect result; + + if (part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart)) + return result; + + if (part == ForwardButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsSingle)) + return result; + + int thickness = scrollbarThickness(scrollbar->controlSize()); + int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()]; + int buttonLength = cButtonLength[scrollbar->controlSize()]; + + bool outerButton = part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsDoubleBoth); + if (outerButton) { + if (scrollbar->orientation() == HorizontalScrollbar) { + result = IntRect(scrollbar->x() + scrollbar->width() - outerButtonLength, scrollbar->y(), outerButtonLength, thickness); + if (painting) + result.inflateX(cOuterButtonOverlap); + } else { + result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - outerButtonLength, thickness, outerButtonLength); + if (painting) + result.inflateY(cOuterButtonOverlap); + } + return result; + } + + if (scrollbar->orientation() == HorizontalScrollbar) { + int start = part == ForwardButtonEndPart ? scrollbar->x() + scrollbar->width() - buttonLength : scrollbar->x() + outerButtonLength; + result = IntRect(start, scrollbar->y(), buttonLength, thickness); + } else { + int start = part == ForwardButtonEndPart ? scrollbar->y() + scrollbar->height() - buttonLength : scrollbar->y() + outerButtonLength; + result = IntRect(scrollbar->x(), start, thickness, buttonLength); + } + if (painting) + return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == ForwardButtonStartPart); + return result; +} + +IntRect ScrollbarThemeMac::trackRect(Scrollbar* scrollbar, bool painting) +{ + if (painting || !hasButtons(scrollbar)) + return scrollbar->frameRect(); + + IntRect result; + int thickness = scrollbarThickness(scrollbar->controlSize()); + int startWidth = 0; + int endWidth = 0; + int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()]; + int buttonLength = cButtonLength[scrollbar->controlSize()]; + int doubleButtonLength = outerButtonLength + buttonLength; + switch (buttonsPlacement()) { + case ScrollbarButtonsSingle: + startWidth = buttonLength; + endWidth = buttonLength; + break; + case ScrollbarButtonsDoubleStart: + startWidth = doubleButtonLength; + break; + case ScrollbarButtonsDoubleEnd: + endWidth = doubleButtonLength; + break; + case ScrollbarButtonsDoubleBoth: + startWidth = doubleButtonLength; + endWidth = doubleButtonLength; + break; + default: + break; + } + + int totalWidth = startWidth + endWidth; + if (scrollbar->orientation() == HorizontalScrollbar) + return IntRect(scrollbar->x() + startWidth, scrollbar->y(), scrollbar->width() - totalWidth, thickness); + return IntRect(scrollbar->x(), scrollbar->y() + startWidth, thickness, scrollbar->height() - totalWidth); +} + +int ScrollbarThemeMac::minimumThumbLength(Scrollbar* scrollbar) +{ + return cThumbMinLength[scrollbar->controlSize()]; +} + +bool ScrollbarThemeMac::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) +{ + if (evt.button() != LeftButton) + return false; + if (gJumpOnTrackClick) + return !evt.altKey(); + return evt.altKey(); +} + +static int scrollbarPartToHIPressedState(ScrollbarPart part) +{ + switch (part) { + case BackButtonStartPart: + return kThemeTopOutsideArrowPressed; + case BackButtonEndPart: + return kThemeTopOutsideArrowPressed; // This does not make much sense. For some reason the outside constant is required. + case ForwardButtonStartPart: + return kThemeTopInsideArrowPressed; + case ForwardButtonEndPart: + return kThemeBottomOutsideArrowPressed; + case ThumbPart: + return kThemeThumbPressed; + default: + return 0; + } +} + +bool ScrollbarThemeMac::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& damageRect) +{ + HIThemeTrackDrawInfo trackInfo; + trackInfo.version = 0; + trackInfo.kind = scrollbar->controlSize() == RegularScrollbar ? kThemeMediumScrollBar : kThemeSmallScrollBar; + trackInfo.bounds = scrollbar->frameRect(); + trackInfo.min = 0; + trackInfo.max = scrollbar->maximum(); + trackInfo.value = scrollbar->currentPos(); + trackInfo.trackInfo.scrollbar.viewsize = scrollbar->pageStep(); + trackInfo.attributes = 0; + if (scrollbar->orientation() == HorizontalScrollbar) + trackInfo.attributes |= kThemeTrackHorizontal; + trackInfo.enableState = scrollbar->client()->isActive() ? kThemeTrackActive : kThemeTrackInactive; + if (!scrollbar->enabled()) + trackInfo.enableState = kThemeTrackDisabled; + if (hasThumb(scrollbar)) + trackInfo.attributes |= kThemeTrackShowThumb; + else if (!hasButtons(scrollbar)) + trackInfo.enableState = kThemeTrackNothingToScroll; + trackInfo.trackInfo.scrollbar.pressState = scrollbarPartToHIPressedState(scrollbar->pressedPart()); + + CGAffineTransform currentCTM = CGContextGetCTM(context->platformContext()); + + // The Aqua scrollbar is buggy when rotated and scaled. We will just draw into a bitmap if we detect a scale or rotation. + bool canDrawDirectly = currentCTM.a == 1.0f && currentCTM.b == 0.0f && currentCTM.c == 0.0f && (currentCTM.d == 1.0f || currentCTM.d == -1.0f); + if (canDrawDirectly) + HIThemeDrawTrack(&trackInfo, 0, context->platformContext(), kHIThemeOrientationNormal); + else { + trackInfo.bounds = IntRect(IntPoint(), scrollbar->frameRect().size()); + + IntRect bufferRect(scrollbar->frameRect()); + bufferRect.intersect(damageRect); + bufferRect.move(-scrollbar->frameRect().x(), -scrollbar->frameRect().y()); + + auto_ptr<ImageBuffer> imageBuffer = ImageBuffer::create(bufferRect.size(), false); + if (!imageBuffer.get()) + return true; + + HIThemeDrawTrack(&trackInfo, 0, imageBuffer->context()->platformContext(), kHIThemeOrientationNormal); + context->drawImage(imageBuffer->image(), scrollbar->frameRect().location()); + } + + return true; +} + +} + diff --git a/WebCore/platform/mac/SharedBufferMac.mm b/WebCore/platform/mac/SharedBufferMac.mm index c3753c2..ecf01c7 100644 --- a/WebCore/platform/mac/SharedBufferMac.mm +++ b/WebCore/platform/mac/SharedBufferMac.mm @@ -30,6 +30,10 @@ #include <string.h> #include <wtf/PassRefPtr.h> +#ifdef BUILDING_ON_TIGER +typedef unsigned NSUInteger; +#endif + using namespace WebCore; @interface WebCoreSharedBufferData : NSData @@ -51,6 +55,9 @@ using namespace WebCore; - (void)dealloc { + if (WebCoreObjCScheduleDeallocateOnMainThread([WebCoreSharedBufferData class], self)) + return; + sharedBuffer->deref(); [super dealloc]; @@ -75,7 +82,7 @@ using namespace WebCore; return self; } -- (unsigned)length +- (NSUInteger)length { return sharedBuffer->size(); } @@ -91,12 +98,7 @@ namespace WebCore { PassRefPtr<SharedBuffer> SharedBuffer::wrapNSData(NSData *nsData) { - return new SharedBuffer(nsData); -} - -SharedBuffer::SharedBuffer(NSData *nsData) - : m_nsData(nsData) -{ + return adoptRef(new SharedBuffer((CFDataRef)nsData)); } NSData *SharedBuffer::createNSData() @@ -105,40 +107,13 @@ NSData *SharedBuffer::createNSData() } CFDataRef SharedBuffer::createCFData() -{ - return (CFDataRef)HardRetainWithNSRelease([[WebCoreSharedBufferData alloc] initWithSharedBuffer:this]); -} - -bool SharedBuffer::hasPlatformData() const -{ - return m_nsData; -} - -const char* SharedBuffer::platformData() const -{ - return (const char*)[m_nsData.get() bytes]; -} - -unsigned SharedBuffer::platformDataSize() const -{ - return [m_nsData.get() length]; -} - -void SharedBuffer::maybeTransferPlatformData() { - if (!m_nsData) - return; + if (m_cfData) { + CFRetain(m_cfData.get()); + return m_cfData.get(); + } - ASSERT(m_buffer.size() == 0); - - m_buffer.append(reinterpret_cast<const char*>([m_nsData.get() bytes]), [m_nsData.get() length]); - - m_nsData = nil; -} - -void SharedBuffer::clearPlatformData() -{ - m_nsData = 0; + return (CFDataRef)HardRetainWithNSRelease([[WebCoreSharedBufferData alloc] initWithSharedBuffer:this]); } PassRefPtr<SharedBuffer> SharedBuffer::createWithContentsOfFile(const String& filePath) diff --git a/WebCore/platform/mac/SharedTimerMac.cpp b/WebCore/platform/mac/SharedTimerMac.mm index 991f527..991f527 100644 --- a/WebCore/platform/mac/SharedTimerMac.cpp +++ b/WebCore/platform/mac/SharedTimerMac.mm diff --git a/WebCore/platform/mac/SoftLinking.h b/WebCore/platform/mac/SoftLinking.h index d470b29..ce72f34 100644 --- a/WebCore/platform/mac/SoftLinking.h +++ b/WebCore/platform/mac/SoftLinking.h @@ -98,3 +98,22 @@ get##name = name##Function; \ return pointer##name; \ } + +#define SOFT_LINK_CONSTANT(framework, name, type) \ + static type init##name(); \ + static type (*get##name)() = init##name; \ + static type constant##name; \ + \ + static type name##Function() \ + { \ + return constant##name; \ + }\ + \ + static type init##name() \ + { \ + void* constant = dlsym(framework##Library(), #name); \ + ASSERT(constant); \ + constant##name = *static_cast<type*>(constant); \ + get##name = name##Function; \ + return constant##name; \ + } diff --git a/WebCore/platform/mac/SystemTimeMac.cpp b/WebCore/platform/mac/SystemTimeMac.cpp index a541b1d..dd5e500 100644 --- a/WebCore/platform/mac/SystemTimeMac.cpp +++ b/WebCore/platform/mac/SystemTimeMac.cpp @@ -26,8 +26,7 @@ #include "config.h" #include "SystemTime.h" -#include "WebCoreSystemInterface.h" - +#include <CoreGraphics/CGEventSource.h> #include <CoreFoundation/CFDate.h> namespace WebCore { @@ -39,7 +38,7 @@ double currentTime() float userIdleTime() { - return wkSecondsSinceLastInputEvent(); + return static_cast<float>(CGEventSourceSecondsSinceLastEventType(kCGEventSourceStateCombinedSessionState, kCGAnyInputEventType)); } } diff --git a/WebCore/platform/mac/ThemeMac.h b/WebCore/platform/mac/ThemeMac.h new file mode 100644 index 0000000..ce534b1 --- /dev/null +++ b/WebCore/platform/mac/ThemeMac.h @@ -0,0 +1,56 @@ +/* + * 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. + */ + +#ifndef ThemeMac_h +#define ThemeMac_h + +#include "Theme.h" + +namespace WebCore { + +class ThemeMac : public Theme { +public: + ThemeMac() { } + virtual ~ThemeMac() { } + + virtual int baselinePositionAdjustment(ControlPart) const; + + virtual FontDescription controlFont(ControlPart, const Font&, float zoomFactor) const; + + virtual LengthSize controlSize(ControlPart, const Font&, const LengthSize&, float zoomFactor) const; + virtual LengthSize minimumControlSize(ControlPart, const Font&, float zoomFactor) const; + + virtual LengthBox controlPadding(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const; + virtual LengthBox controlBorder(ControlPart, const Font&, const LengthBox& zoomedBox, float zoomFactor) const; + + virtual bool controlRequiresPreWhiteSpace(ControlPart part) const { return part == PushButtonPart; } + + virtual void paint(ControlPart, ControlStates, GraphicsContext*, const IntRect&, float zoomFactor, ScrollView*) const; + virtual void inflateControlPaintRect(ControlPart, ControlStates, IntRect&, float zoomFactor) const; +}; + +} // namespace WebCore + +#endif // ThemeMac_h diff --git a/WebCore/platform/mac/ThemeMac.mm b/WebCore/platform/mac/ThemeMac.mm new file mode 100644 index 0000000..3b1da55 --- /dev/null +++ b/WebCore/platform/mac/ThemeMac.mm @@ -0,0 +1,544 @@ +/* + * 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. + */ + +#import "config.h" +#import "ThemeMac.h" + +#import "GraphicsContext.h" +#import "LocalCurrentGraphicsContext.h" +#import "ScrollView.h" +#import "WebCoreSystemInterface.h" + +using namespace std; + +// FIXME: Default buttons really should be more like push buttons and not like buttons. + +namespace WebCore { + +enum { + topMargin, + rightMargin, + bottomMargin, + leftMargin +}; + +Theme* platformTheme() +{ + static ThemeMac themeMac; + return &themeMac; +} + +// Helper functions used by a bunch of different control parts. + +static NSControlSize controlSizeForFont(const Font& font) +{ + int fontSize = font.pixelSize(); + if (fontSize >= 16) + return NSRegularControlSize; + if (fontSize >= 11) + return NSSmallControlSize; + return NSMiniControlSize; +} + +static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) +{ + IntSize controlSize = sizes[controlSizeForFont(font)]; + if (zoomFactor != 1.0f) + controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor); + LengthSize result = zoomedSize; + if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0) + result.setWidth(Length(controlSize.width(), Fixed)); + if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) + result.setHeight(Length(controlSize.height(), Fixed)); + return result; +} + +static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) +{ + NSControlSize size; + if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) && + minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor)) + size = NSRegularControlSize; + else if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) && + minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor)) + size = NSSmallControlSize; + else + size = NSMiniControlSize; + if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same. + [cell setControlSize:size]; +} + +static void updateStates(NSCell* cell, ControlStates states) +{ + // Hover state is not supported by Aqua. + + // Pressed state + bool oldPressed = [cell isHighlighted]; + bool pressed = states & PressedState; + if (pressed != oldPressed) + [cell setHighlighted:pressed]; + + // Enabled state + bool oldEnabled = [cell isEnabled]; + bool enabled = states & EnabledState; + if (enabled != oldEnabled) + [cell setEnabled:enabled]; + + // Focused state + bool oldFocused = [cell showsFirstResponder]; + bool focused = states & FocusState; + if (focused != oldFocused) + [cell setShowsFirstResponder:focused]; + + // Checked and Indeterminate + bool oldIndeterminate = [cell state] == NSMixedState; + bool indeterminate = (states & IndeterminateState); + bool checked = states & CheckedState; + bool oldChecked = [cell state] == NSOnState; + if (oldIndeterminate != indeterminate || checked != oldChecked) + [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)]; + + // Window inactive state does not need to be checked explicitly, since we paint parented to + // a view in a window whose key state can be detected. +} + +static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor) +{ + // Only do the inflation if the available width/height are too small. Otherwise try to + // fit the glow/check space into the available box's width/height. + int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMargin] * zoomFactor + margins[rightMargin] * zoomFactor); + int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMargin] * zoomFactor + margins[bottomMargin] * zoomFactor); + IntRect result(zoomedRect); + if (widthDelta < 0) { + result.setX(result.x() - margins[leftMargin] * zoomFactor); + result.setWidth(result.width() - widthDelta); + } + if (heightDelta < 0) { + result.setY(result.y() - margins[topMargin] * zoomFactor); + result.setHeight(result.height() - heightDelta); + } + return result; +} + +// Checkboxes + +static const IntSize* checkboxSizes() +{ + static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; + return sizes; +} + +static const int* checkboxMargins(NSControlSize controlSize) +{ + static const int margins[3][4] = + { + { 3, 4, 4, 2 }, + { 4, 3, 3, 3 }, + { 4, 3, 3, 3 }, + }; + return margins[controlSize]; +} + +static LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) +{ + // If the width and height are both specified, then we have nothing to do. + if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) + return zoomedSize; + + // Use the font size to determine the intrinsic width of the control. + return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes()); +} + +static NSButtonCell* checkbox(ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + static NSButtonCell* checkboxCell; + if (!checkboxCell) { + checkboxCell = [[NSButtonCell alloc] init]; + [checkboxCell setButtonType:NSSwitchButton]; + [checkboxCell setTitle:nil]; + [checkboxCell setAllowsMixedState:YES]; + [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; + } + + // Set the control size based off the rectangle we're painting into. + setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor); + + // Update the various states we respond to. + updateStates(checkboxCell, states); + + return checkboxCell; +} + +// FIXME: Share more code with radio buttons. +static void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) +{ + // Determine the width and height needed for the control and prepare the cell for painting. + NSButtonCell* checkboxCell = checkbox(states, zoomedRect, zoomFactor); + + context->save(); + + NSControlSize controlSize = [checkboxCell controlSize]; + IntSize zoomedSize = checkboxSizes()[controlSize]; + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); + + if (zoomFactor != 1.0f) { + inflatedRect.setWidth(inflatedRect.width() / zoomFactor); + inflatedRect.setHeight(inflatedRect.height() / zoomFactor); + context->translate(inflatedRect.x(), inflatedRect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-inflatedRect.x(), -inflatedRect.y()); + } + + [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:scrollView->documentView()]; + [checkboxCell setControlView:nil]; + + context->restore(); +} + +// Radio Buttons + +static const IntSize* radioSizes() +{ + static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; + return sizes; +} + +static const int* radioMargins(NSControlSize controlSize) +{ + static const int margins[3][4] = + { + { 2, 2, 4, 2 }, + { 3, 2, 3, 2 }, + { 1, 0, 2, 0 }, + }; + return margins[controlSize]; +} + +static LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) +{ + // If the width and height are both specified, then we have nothing to do. + if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) + return zoomedSize; + + // Use the font size to determine the intrinsic width of the control. + return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes()); +} + +static NSButtonCell* radio(ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + static NSButtonCell* radioCell; + if (!radioCell) { + radioCell = [[NSButtonCell alloc] init]; + [radioCell setButtonType:NSRadioButton]; + [radioCell setTitle:nil]; + [radioCell setFocusRingType:NSFocusRingTypeExterior]; + } + + // Set the control size based off the rectangle we're painting into. + setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); + + // Update the various states we respond to. + updateStates(radioCell, states); + + return radioCell; +} + +static void paintRadio(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) +{ + // Determine the width and height needed for the control and prepare the cell for painting. + NSButtonCell* radioCell = radio(states, zoomedRect, zoomFactor); + + context->save(); + + NSControlSize controlSize = [radioCell controlSize]; + IntSize zoomedSize = radioSizes()[controlSize]; + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); + + if (zoomFactor != 1.0f) { + inflatedRect.setWidth(inflatedRect.width() / zoomFactor); + inflatedRect.setHeight(inflatedRect.height() / zoomFactor); + context->translate(inflatedRect.x(), inflatedRect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-inflatedRect.x(), -inflatedRect.y()); + } + + [radioCell drawWithFrame:NSRect(inflatedRect) inView:scrollView->documentView()]; + [radioCell setControlView:nil]; + + context->restore(); +} + +// Buttons + +// Buttons really only constrain height. They respect width. +static const IntSize* buttonSizes() +{ + static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; + return sizes; +} + +static const int* buttonMargins(NSControlSize controlSize) +{ + static const int margins[3][4] = + { + { 4, 6, 7, 6 }, + { 4, 5, 6, 5 }, + { 0, 1, 1, 1 }, + }; + return margins[controlSize]; +} + +static NSButtonCell* button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) +{ + static NSButtonCell *buttonCell; + static bool defaultButton; + if (!buttonCell) { + buttonCell = [[NSButtonCell alloc] init]; + [buttonCell setTitle:nil]; + [buttonCell setButtonType:NSMomentaryPushInButton]; + } + + // Set the control size based off the rectangle we're painting into. + if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) { + // Use the square button + if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle) + [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle]; + } else if ([buttonCell bezelStyle] != NSRoundedBezelStyle) + [buttonCell setBezelStyle:NSRoundedBezelStyle]; + + setControlSize(buttonCell, buttonSizes(), zoomedRect.size(), zoomFactor); + + if (defaultButton != (states & DefaultState)) { + defaultButton = !defaultButton; + [buttonCell setKeyEquivalent:(defaultButton ? @"\r" : @"")]; + } + + // Update the various states we respond to. + updateStates(buttonCell, states); + + return buttonCell; +} + +static void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) +{ + // Determine the width and height needed for the control and prepare the cell for painting. + NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor); + LocalCurrentGraphicsContext localContext(context); + + NSControlSize controlSize = [buttonCell controlSize]; + IntSize zoomedSize = buttonSizes()[controlSize]; + zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + IntRect inflatedRect = zoomedRect; + if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { + // Center the button within the available space. + if (inflatedRect.height() > zoomedSize.height()) { + inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2); + inflatedRect.setHeight(zoomedSize.height()); + } + + // Now inflate it to account for the shadow. + inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); + + if (zoomFactor != 1.0f) { + inflatedRect.setWidth(inflatedRect.width() / zoomFactor); + inflatedRect.setHeight(inflatedRect.height() / zoomFactor); + context->translate(inflatedRect.x(), inflatedRect.y()); + context->scale(FloatSize(zoomFactor, zoomFactor)); + context->translate(-inflatedRect.x(), -inflatedRect.y()); + } + } + + NSView *view = scrollView->documentView(); + NSWindow *window = [view window]; + NSButtonCell *previousDefaultButtonCell = [window defaultButtonCell]; + + if ((states & DefaultState) && [window isKeyWindow]) { + [window setDefaultButtonCell:buttonCell]; + wkAdvanceDefaultButtonPulseAnimation(buttonCell); + } else if ([previousDefaultButtonCell isEqual:buttonCell]) + [window setDefaultButtonCell:nil]; + + [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view]; + [buttonCell setControlView:nil]; + + if (![previousDefaultButtonCell isEqual:buttonCell]) + [window setDefaultButtonCell:previousDefaultButtonCell]; +} + +// Theme overrides + +int ThemeMac::baselinePositionAdjustment(ControlPart part) const +{ + if (part == CheckboxPart || part == RadioPart) + return -2; + return Theme::baselinePositionAdjustment(part); +} + +FontDescription ThemeMac::controlFont(ControlPart part, const Font& font, float zoomFactor) const +{ + switch (part) { + case PushButtonPart: { + FontDescription fontDescription; + fontDescription.setIsAbsoluteSize(true); + fontDescription.setGenericFamily(FontDescription::SerifFamily); + + NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(font)]]; + fontDescription.firstFamily().setFamily([nsFont familyName]); + fontDescription.setComputedSize([nsFont pointSize] * zoomFactor); + fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor); + return fontDescription; + } + default: + return Theme::controlFont(part, font, zoomFactor); + } +} + +LengthSize ThemeMac::controlSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor) const +{ + switch (part) { + case CheckboxPart: + return checkboxSize(font, zoomedSize, zoomFactor); + case RadioPart: + return radioSize(font, zoomedSize, zoomFactor); + case PushButtonPart: + // Height is reset to auto so that specified heights can be ignored. + return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes()); + default: + return zoomedSize; + } +} + +LengthSize ThemeMac::minimumControlSize(ControlPart part, const Font& font, float zoomFactor) const +{ + switch (part) { + case SquareButtonPart: + case DefaultButtonPart: + case ButtonPart: + return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed)); + default: + return Theme::minimumControlSize(part, font, zoomFactor); + } +} + +LengthBox ThemeMac::controlBorder(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const +{ + switch (part) { + case SquareButtonPart: + case DefaultButtonPart: + case ButtonPart: + return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value()); + default: + return Theme::controlBorder(part, font, zoomedBox, zoomFactor); + } +} + +LengthBox ThemeMac::controlPadding(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const +{ + switch (part) { + case PushButtonPart: { + // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large + // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is + // by definition constrained, since we select mini only for small cramped environments. + // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent + // padding. + const int padding = 8 * zoomFactor; + return LengthBox(0, padding, 0, padding); + } + default: + return Theme::controlPadding(part, font, zoomedBox, zoomFactor); + } +} + +void ThemeMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect& zoomedRect, float zoomFactor) const +{ + switch (part) { + case CheckboxPart: { + // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox + // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. + NSCell *cell = checkbox(states, zoomedRect, zoomFactor); + NSControlSize controlSize = [cell controlSize]; + IntSize zoomedSize = checkboxSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); + break; + } + case RadioPart: { + // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button + // shadow". We don't consider this part of the bounds of the control in WebKit. + NSCell *cell = radio(states, zoomedRect, zoomFactor); + NSControlSize controlSize = [cell controlSize]; + IntSize zoomedSize = radioSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedSize.width() * zoomFactor); + zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); + break; + } + case PushButtonPart: + case DefaultButtonPart: + case ButtonPart: { + NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor); + NSControlSize controlSize = [cell controlSize]; + + // We inflate the rect as needed to account for the Aqua button's shadow. + if ([cell bezelStyle] == NSRoundedBezelStyle) { + IntSize zoomedSize = buttonSizes()[controlSize]; + zoomedSize.setHeight(zoomedSize.height() * zoomFactor); + zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. + zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); + } + break; + } + default: + break; + } +} + +void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) const +{ + switch (part) { + case CheckboxPart: + paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView); + break; + case RadioPart: + paintRadio(states, context, zoomedRect, zoomFactor, scrollView); + break; + case PushButtonPart: + case DefaultButtonPart: + case ButtonPart: + case SquareButtonPart: + paintButton(part, states, context, zoomedRect, zoomFactor, scrollView); + break; + default: + break; + } +} + +} diff --git a/WebCore/platform/mac/ThreadCheck.mm b/WebCore/platform/mac/ThreadCheck.mm index 92fcd44..6320c70 100644 --- a/WebCore/platform/mac/ThreadCheck.mm +++ b/WebCore/platform/mac/ThreadCheck.mm @@ -27,7 +27,7 @@ #import "ThreadCheck.h" #import "StringHash.h" -#import <JavaScriptCore/HashSet.h> +#import <wtf/HashSet.h> namespace WebCore { diff --git a/WebCore/platform/mac/WebCoreHistory.h b/WebCore/platform/mac/WebCoreHistory.h deleted file mode 100644 index d99e9b1..0000000 --- a/WebCore/platform/mac/WebCoreHistory.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2003, 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE 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. - */ - -@protocol WebCoreHistoryProvider <NSObject> -- (BOOL)containsURL:(const UniChar*)unicode length:(unsigned)length; -@end - -@interface WebCoreHistory : NSObject - -+ (void)setHistoryProvider:(id<WebCoreHistoryProvider>)h; -+ (id<WebCoreHistoryProvider>)historyProvider; - -@end diff --git a/WebCore/platform/mac/WebCoreHistory.m b/WebCore/platform/mac/WebCoreHistory.m deleted file mode 100644 index e1d7f38..0000000 --- a/WebCore/platform/mac/WebCoreHistory.m +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" - -#import "WebCoreHistory.h" - -@implementation WebCoreHistory - -static id<WebCoreHistoryProvider> _historyProvider = nil; - -+ (void)setHistoryProvider: (id<WebCoreHistoryProvider>)h -{ - if (_historyProvider != h){ - [_historyProvider release]; - _historyProvider = [h retain]; - } -} - -+ (id<WebCoreHistoryProvider>)historyProvider -{ - return _historyProvider; -} - -@end diff --git a/WebCore/platform/mac/WebCoreObjCExtras.h b/WebCore/platform/mac/WebCoreObjCExtras.h index a30702e..7e699a5 100644 --- a/WebCore/platform/mac/WebCoreObjCExtras.h +++ b/WebCore/platform/mac/WebCoreObjCExtras.h @@ -34,6 +34,10 @@ extern "C" { void WebCoreObjCFinalizeOnMainThread(Class cls); +// The 'Class' that should be passed in here is the class of the +// object that implements the dealloc method that this function is called from. +bool WebCoreObjCScheduleDeallocateOnMainThread(Class cls, id object); + #ifdef __cplusplus } #endif diff --git a/WebCore/platform/mac/Threading.mm b/WebCore/platform/mac/WebCoreObjCExtras.mm index 02d39a3..105c462 100644 --- a/WebCore/platform/mac/Threading.mm +++ b/WebCore/platform/mac/WebCoreObjCExtras.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,42 +25,58 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#import "config.h" -#import "Threading.h" -@interface WebCoreFunctionWrapper : NSObject { - WebCore::MainThreadFunction* m_function; - void* m_context; -} -- (id)initWithFunction:(WebCore::MainThreadFunction*)function context:(void*)context; -- (void)invoke; -@end +#include "config.h" +#include "WebCoreObjCExtras.h" -@implementation WebCoreFunctionWrapper +#include <objc/objc-auto.h> +#include <objc/objc-runtime.h> +#include <wtf/Assertions.h> +#include <wtf/MainThread.h> +#include <wtf/Threading.h> -- (id)initWithFunction:(WebCore::MainThreadFunction*)function context:(void*)context; +void WebCoreObjCFinalizeOnMainThread(Class cls) { - [super init]; - m_function = function; - m_context = context; - return self; +#if !defined(BUILDING_ON_TIGER) && !defined(DONT_FINALIZE_ON_MAIN_THREAD) + objc_finalizeOnMainThread(cls); +#endif + + // The reason we call initializeThreading here is that we'd like to have + // threading initialized early, otherwise WebCoreObjCScheduleDeallocateOnMainThread + // will crash + WTF::initializeThreading(); } -- (void)invoke +#ifdef BUILDING_ON_TIGER +static inline IMP method_getImplementation(Method method) { - m_function(m_context); + return method->method_imp; } +#endif -@end // implementation WebCoreFunctionWrapper +typedef std::pair<Class, id> ClassAndIdPair; -namespace WebCore { +static void deallocCallback(void* context) +{ + ClassAndIdPair* pair = static_cast<ClassAndIdPair*>(context); + + Method method = class_getInstanceMethod(pair->first, @selector(dealloc)); + + IMP imp = method_getImplementation(method); + imp(pair->second, @selector(dealloc)); + + delete pair; +} -void callOnMainThread(MainThreadFunction* function, void* context) +bool WebCoreObjCScheduleDeallocateOnMainThread(Class cls, id object) { - WebCoreFunctionWrapper *wrapper = [[WebCoreFunctionWrapper alloc] initWithFunction:function context:context]; - [wrapper performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:NO]; - [wrapper release]; + ASSERT([object isKindOfClass:cls]); + + if (pthread_main_np() != 0) + return false; + + ClassAndIdPair* pair = new ClassAndIdPair(cls, object); + callOnMainThread(deallocCallback, pair); + return true; } -} // namespace WebCore diff --git a/WebCore/platform/mac/WebCoreSystemInterface.h b/WebCore/platform/mac/WebCoreSystemInterface.h index fbbacd2..6085483 100644 --- a/WebCore/platform/mac/WebCoreSystemInterface.h +++ b/WebCore/platform/mac/WebCoreSystemInterface.h @@ -40,6 +40,7 @@ typedef struct _NSRect NSRect; #endif #ifdef __OBJC__ +@class NSButtonCell; @class NSData; @class NSEvent; @class NSFont; @@ -49,6 +50,7 @@ typedef struct _NSRect NSRect; @class QTMovieView; #else typedef struct NSArray NSArray; +typedef struct NSButtonCell NSButtonCell; typedef struct NSData NSData; typedef struct NSDate NSDate; typedef struct NSEvent NSEvent; @@ -71,12 +73,10 @@ typedef struct QTMovieView QTMovieView; extern "C" { #endif -#define GLYPH_VECTOR_SIZE (50 * 32) - // In alphabetical order. +extern void (*wkAdvanceDefaultButtonPulseAnimation)(NSButtonCell *); extern BOOL (*wkCGContextGetShouldSmoothFonts)(CGContextRef); -extern void (*wkClearGlyphVector)(void* glyphs); extern CFReadStreamRef (*wkCreateCustomCFReadStream)(void *(*formCreate)(CFReadStreamRef, void *), void (*formFinalize)(CFReadStreamRef, void *), Boolean (*formOpen)(CFReadStreamRef, CFStreamError *, Boolean *, void *), @@ -86,23 +86,15 @@ extern CFReadStreamRef (*wkCreateCustomCFReadStream)(void *(*formCreate)(CFReadS void (*formSchedule)(CFReadStreamRef, CFRunLoopRef, CFStringRef, void *), void (*formUnschedule)(CFReadStreamRef, CFRunLoopRef, CFStringRef, void *), void *context); -extern OSStatus (*wkConvertCharToGlyphs)(void* styleGroup, const UniChar*, unsigned numCharacters, void* glyphs); extern id (*wkCreateNSURLConnectionDelegateProxy)(void); extern void (*wkDrawBezeledTextFieldCell)(NSRect, BOOL enabled); extern void (*wkDrawTextFieldCellFocusRing)(NSTextFieldCell*, NSRect); extern void (*wkDrawCapsLockIndicator)(CGContextRef, CGRect); extern void (*wkDrawBezeledTextArea)(NSRect, BOOL enabled); extern void (*wkDrawFocusRing)(CGContextRef, CGColorRef, int radius); -extern BOOL (*wkFontSmoothingModeIsLCD)(int mode); -extern OSStatus (*wkGetATSStyleGroup)(ATSUStyle, void** styleGroup); -extern CGFontRef (*wkGetCGFontFromNSFont)(NSFont*); extern NSFont* (*wkGetFontInLanguageForRange)(NSFont*, NSString*, NSRange); extern NSFont* (*wkGetFontInLanguageForCharacter)(NSFont*, UniChar); -extern void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm); extern BOOL (*wkGetGlyphTransformedAdvances)(CGFontRef, NSFont*, CGAffineTransform*, ATSGlyphRef*, CGSize* advance); -extern ATSLayoutRecord* (*wkGetGlyphVectorFirstRecord)(void* glyphVector); -extern int (*wkGetGlyphVectorNumGlyphs)(void* glyphVector); -extern size_t (*wkGetGlyphVectorRecordSize)(void* glyphVector); extern void (*wkDrawMediaFullscreenButton)(CGContextRef context, CGRect rect, BOOL active); extern void (*wkDrawMediaMuteButton)(CGContextRef context, CGRect rect, BOOL active); extern void (*wkDrawMediaPauseButton)(CGContextRef context, CGRect rect, BOOL active); @@ -120,26 +112,41 @@ extern double (*wkGetNSURLResponseCalculatedExpiration)(NSURLResponse *response) extern NSDate *(*wkGetNSURLResponseLastModifiedDate)(NSURLResponse *response); extern BOOL (*wkGetNSURLResponseMustRevalidate)(NSURLResponse *response); extern void (*wkGetWheelEventDeltas)(NSEvent*, float* deltaX, float* deltaY, BOOL* continuous); -extern OSStatus (*wkInitializeGlyphVector)(int count, void* glyphs); -extern NSString* (*wkPathFromFont)(NSFont*); extern void (*wkPopupMenu)(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*); extern int (*wkQTMovieDataRate)(QTMovie*); extern float (*wkQTMovieMaxTimeLoaded)(QTMovie*); extern void (*wkQTMovieViewSetDrawSynchronously)(QTMovieView*, BOOL); -extern void (*wkReleaseStyleGroup)(void* group); extern void (*wkSetCGFontRenderingMode)(CGContextRef, NSFont*); extern void (*wkSetDragImage)(NSImage*, NSPoint offset); extern void (*wkSetNSURLConnectionDefersCallbacks)(NSURLConnection *, BOOL); extern void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL); extern void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform); extern void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint); -extern void (*wkSetUpFontCache)(size_t); +extern void (*wkSetUpFontCache)(); extern void (*wkSignalCFReadStreamEnd)(CFReadStreamRef stream); extern void (*wkSignalCFReadStreamError)(CFReadStreamRef stream, CFStreamError *error); extern void (*wkSignalCFReadStreamHasBytes)(CFReadStreamRef stream); + +#ifndef BUILDING_ON_TIGER +extern void (*wkGetGlyphsForCharacters)(CGFontRef, const UniChar[], CGGlyph[], size_t); +#else +#define GLYPH_VECTOR_SIZE (50 * 32) + +extern void (*wkClearGlyphVector)(void* glyphs); +extern OSStatus (*wkConvertCharToGlyphs)(void* styleGroup, const UniChar*, unsigned numCharacters, void* glyphs); +extern CFStringRef (*wkCopyFullFontName)(CGFontRef font); +extern OSStatus (*wkGetATSStyleGroup)(ATSUStyle, void** styleGroup); +extern CGFontRef (*wkGetCGFontFromNSFont)(NSFont*); +extern void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm); +extern ATSLayoutRecord* (*wkGetGlyphVectorFirstRecord)(void* glyphVector); +extern void* wkGetGlyphsForCharacters; +extern int (*wkGetGlyphVectorNumGlyphs)(void* glyphVector); +extern size_t (*wkGetGlyphVectorRecordSize)(void* glyphVector); +extern OSStatus (*wkInitializeGlyphVector)(int count, void* glyphs); +extern void (*wkReleaseStyleGroup)(void* group); extern BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *); -extern Class (*wkNSURLProtocolClassForReqest)(NSURLRequest *); -extern float (*wkSecondsSinceLastInputEvent)(void); +#endif + #ifdef __cplusplus } #endif diff --git a/WebCore/platform/mac/WebCoreSystemInterface.mm b/WebCore/platform/mac/WebCoreSystemInterface.mm index 9e8856d..c0305ae 100644 --- a/WebCore/platform/mac/WebCoreSystemInterface.mm +++ b/WebCore/platform/mac/WebCoreSystemInterface.mm @@ -26,9 +26,8 @@ #import "config.h" #import "WebCoreSystemInterface.h" +void (*wkAdvanceDefaultButtonPulseAnimation)(NSButtonCell *); BOOL (*wkCGContextGetShouldSmoothFonts)(CGContextRef); -void (*wkClearGlyphVector)(void* glyphs); -OSStatus (*wkConvertCharToGlyphs)(void* styleGroup, const UniChar*, unsigned numCharacters, void* glyphs); NSString* (*wkCreateURLPasteboardFlavorTypeName)(void); NSString* (*wkCreateURLNPasteboardFlavorTypeName)(void); void (*wkDrawBezeledTextFieldCell)(NSRect, BOOL enabled); @@ -36,16 +35,9 @@ void (*wkDrawTextFieldCellFocusRing)(NSTextFieldCell*, NSRect); void (*wkDrawCapsLockIndicator)(CGContextRef, CGRect); void (*wkDrawBezeledTextArea)(NSRect, BOOL enabled); void (*wkDrawFocusRing)(CGContextRef, CGColorRef, int radius); -BOOL (*wkFontSmoothingModeIsLCD)(int mode); -OSStatus (*wkGetATSStyleGroup)(ATSUStyle, void** styleGroup); -CGFontRef (*wkGetCGFontFromNSFont)(NSFont*); NSFont* (*wkGetFontInLanguageForRange)(NSFont*, NSString*, NSRange); NSFont* (*wkGetFontInLanguageForCharacter)(NSFont*, UniChar); -void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm); BOOL (*wkGetGlyphTransformedAdvances)(CGFontRef, NSFont*, CGAffineTransform*, ATSGlyphRef*, CGSize* advance); -ATSLayoutRecord* (*wkGetGlyphVectorFirstRecord)(void* glyphVector); -int (*wkGetGlyphVectorNumGlyphs)(void* glyphVector); -size_t (*wkGetGlyphVectorRecordSize)(void* glyphVector); void (*wkDrawMediaFullscreenButton)(CGContextRef context, CGRect rect, BOOL active); void (*wkDrawMediaMuteButton)(CGContextRef context, CGRect rect, BOOL active); void (*wkDrawMediaPauseButton)(CGContextRef context, CGRect rect, BOOL active); @@ -58,23 +50,19 @@ void (*wkDrawMediaUnMuteButton)(CGContextRef context, CGRect rect, BOOL active); NSString* (*wkGetPreferredExtensionForMIMEType)(NSString*); NSArray* (*wkGetExtensionsForMIMEType)(NSString*); NSString* (*wkGetMIMETypeForExtension)(NSString*); -ATSUFontID (*wkGetNSFontATSUFontId)(NSFont*); NSTimeInterval (*wkGetNSURLResponseCalculatedExpiration)(NSURLResponse *response); NSDate *(*wkGetNSURLResponseLastModifiedDate)(NSURLResponse *response); BOOL (*wkGetNSURLResponseMustRevalidate)(NSURLResponse *response); void (*wkGetWheelEventDeltas)(NSEvent*, float* deltaX, float* deltaY, BOOL* continuous); -OSStatus (*wkInitializeGlyphVector)(int count, void* glyphs); -NSString* (*wkPathFromFont)(NSFont*); void (*wkPopupMenu)(NSMenu*, NSPoint location, float width, NSView*, int selectedItem, NSFont*); int (*wkQTMovieDataRate)(QTMovie*); float (*wkQTMovieMaxTimeLoaded)(QTMovie*); void (*wkQTMovieViewSetDrawSynchronously)(QTMovieView*, BOOL); -void (*wkReleaseStyleGroup)(void* group); void (*wkSetCGFontRenderingMode)(CGContextRef, NSFont*); void (*wkSetDragImage)(NSImage*, NSPoint offset); void (*wkSetPatternBaseCTM)(CGContextRef, CGAffineTransform); void (*wkSetPatternPhaseInUserSpace)(CGContextRef, CGPoint point); -void (*wkSetUpFontCache)(size_t); +void (*wkSetUpFontCache)(); void (*wkSignalCFReadStreamEnd)(CFReadStreamRef stream); void (*wkSignalCFReadStreamHasBytes)(CFReadStreamRef stream); void (*wkSignalCFReadStreamError)(CFReadStreamRef stream, CFStreamError *error); @@ -90,6 +78,22 @@ CFReadStreamRef (*wkCreateCustomCFReadStream)(void *(*formCreate)(CFReadStreamRe void (*wkSetNSURLConnectionDefersCallbacks)(NSURLConnection *, BOOL); void (*wkSetNSURLRequestShouldContentSniff)(NSMutableURLRequest *, BOOL); id (*wkCreateNSURLConnectionDelegateProxy)(void); + +#ifndef BUILDING_ON_TIGER +void (*wkGetGlyphsForCharacters)(CGFontRef, const UniChar[], CGGlyph[], size_t); +#else +void (*wkClearGlyphVector)(void* glyphs); +OSStatus (*wkConvertCharToGlyphs)(void* styleGroup, const UniChar*, unsigned numCharacters, void* glyphs); +CFStringRef (*wkCopyFullFontName)(CGFontRef font); +OSStatus (*wkGetATSStyleGroup)(ATSUStyle, void** styleGroup); +CGFontRef (*wkGetCGFontFromNSFont)(NSFont*); +void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm); +ATSLayoutRecord* (*wkGetGlyphVectorFirstRecord)(void* glyphVector); +void* wkGetGlyphsForCharacters; +int (*wkGetGlyphVectorNumGlyphs)(void* glyphVector); +size_t (*wkGetGlyphVectorRecordSize)(void* glyphVector); +OSStatus (*wkInitializeGlyphVector)(int count, void* glyphs); +void (*wkReleaseStyleGroup)(void* group); +ATSUFontID (*wkGetNSFontATSUFontId)(NSFont*); BOOL (*wkSupportsMultipartXMixedReplace)(NSMutableURLRequest *); -Class (*wkNSURLProtocolClassForReqest)(NSURLRequest *); -float (*wkSecondsSinceLastInputEvent)(void); +#endif diff --git a/WebCore/platform/mac/WebCoreTextRenderer.h b/WebCore/platform/mac/WebCoreTextRenderer.h index dc1de8c..3e77434 100644 --- a/WebCore/platform/mac/WebCoreTextRenderer.h +++ b/WebCore/platform/mac/WebCoreTextRenderer.h @@ -31,8 +31,9 @@ extern void WebCoreDrawTextAtPoint(const UniChar*, unsigned length, NSPoint, NSF extern float WebCoreTextFloatWidth(const UniChar*, unsigned length, NSFont*); extern void WebCoreSetShouldUseFontSmoothing(bool); extern bool WebCoreShouldUseFontSmoothing(); -extern void WebCoreSetAlwaysUseATSU(bool); -extern NSFont* WebCoreFindFont(NSString* familyName, NSFontTraitMask, int size); +extern void WebCoreSetAlwaysUsesComplexTextCodePath(bool); +extern bool WebCoreAlwaysUsesComplexTextCodePath(); +extern NSFont* WebCoreFindFont(NSString* familyName, NSFontTraitMask, int weight, int size); #ifdef __cplusplus } diff --git a/WebCore/platform/mac/WebCoreTextRenderer.mm b/WebCore/platform/mac/WebCoreTextRenderer.mm index 51ddf8e..0cd5967 100644 --- a/WebCore/platform/mac/WebCoreTextRenderer.mm +++ b/WebCore/platform/mac/WebCoreTextRenderer.mm @@ -77,12 +77,17 @@ bool WebCoreShouldUseFontSmoothing() return gShouldUseFontSmoothing; } -void WebCoreSetAlwaysUseATSU(bool useATSU) +void WebCoreSetAlwaysUsesComplexTextCodePath(bool complex) { - Font::setCodePath(useATSU ? Font::Complex : Font::Auto); + Font::setCodePath(complex ? Font::Complex : Font::Auto); } -NSFont* WebCoreFindFont(NSString* familyName, NSFontTraitMask traits, int size) +bool WebCoreAlwaysUsesComplexTextCodePath() { - return [WebFontCache fontWithFamily:familyName traits:traits size:size]; + return Font::codePath() == Font::Complex; +} + +NSFont* WebCoreFindFont(NSString* familyName, NSFontTraitMask traits, int weight, int size) +{ + return [WebFontCache fontWithFamily:familyName traits:traits weight:weight size:size]; } diff --git a/WebCore/platform/mac/WebFontCache.h b/WebCore/platform/mac/WebFontCache.h index b45cff3..b31a684 100644 --- a/WebCore/platform/mac/WebFontCache.h +++ b/WebCore/platform/mac/WebFontCache.h @@ -1,5 +1,6 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,7 +24,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <wtf/Vector.h> + // This interface exists so that third party products (like Silk) can patch in to an Obj-C method to manipulate WebKit's font caching/substitution. @interface WebFontCache : NSObject -+ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits size:(float)size; ++ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits weight:(int)desiredWeight size:(float)size; ++ (void)getTraits:(Vector<unsigned>&)traitsMasks inFamily:(NSString *)desiredFamily; + @end diff --git a/WebCore/platform/mac/WebFontCache.mm b/WebCore/platform/mac/WebFontCache.mm index 1fcceb5..84f60b5 100644 --- a/WebCore/platform/mac/WebFontCache.mm +++ b/WebCore/platform/mac/WebFontCache.mm @@ -1,5 +1,6 @@ /* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. + * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +28,20 @@ */ #import "config.h" +#import "FontTraitsMask.h" #import "WebFontCache.h" #import <math.h> +using namespace WebCore; + +#ifdef BUILDING_ON_TIGER +typedef int NSInteger; +#endif + #define SYNTHESIZED_FONT_TRAITS (NSBoldFontMask | NSItalicFontMask) #define IMPORTANT_FONT_TRAITS (0 \ - | NSBoldFontMask \ | NSCompressedFontMask \ | NSCondensedFontMask \ | NSExpandedFontMask \ @@ -44,10 +51,7 @@ | NSSmallCapsFontMask \ ) -#define DESIRED_WEIGHT 5 - -static BOOL acceptableChoice(NSFontTraitMask desiredTraits, int desiredWeight, - NSFontTraitMask candidateTraits, int candidateWeight) +static BOOL acceptableChoice(NSFontTraitMask desiredTraits, int desiredWeight, NSFontTraitMask candidateTraits, int candidateWeight) { desiredTraits &= ~SYNTHESIZED_FONT_TRAITS; return (candidateTraits & desiredTraits) == desiredTraits; @@ -57,10 +61,9 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, NSFontTraitMask chosenTraits, int chosenWeight, NSFontTraitMask candidateTraits, int candidateWeight) { - if (!acceptableChoice(desiredTraits, desiredWeight, candidateTraits, candidateWeight)) { + if (!acceptableChoice(desiredTraits, desiredWeight, candidateTraits, candidateWeight)) return NO; - } - + // A list of the traits we care about. // The top item in the list is the worst trait to mismatch; if a font has this // and we didn't ask for it, we'd prefer any other font in the family. @@ -72,8 +75,9 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, NSCondensedFontMask, NSExpandedFontMask, NSNarrowFontMask, - NSBoldFontMask, - 0 }; + 0 + }; + int i = 0; NSFontTraitMask mask; while ((mask = masks[i++])) { @@ -85,55 +89,91 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, if (!chosenHasUnwantedTrait && candidateHasUnwantedTrait) return NO; } - - int chosenWeightDelta = chosenWeight - desiredWeight; - int candidateWeightDelta = candidateWeight - desiredWeight; - - int chosenWeightDeltaMagnitude = abs(chosenWeightDelta); - int candidateWeightDeltaMagnitude = abs(candidateWeightDelta); - - // Smaller magnitude wins. - // If both have same magnitude, tie breaker is that the smaller weight wins. - // Otherwise, first font in the array wins (should almost never happen). - if (candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude) { - return YES; - } - if (candidateWeightDeltaMagnitude == chosenWeightDeltaMagnitude && candidateWeight < chosenWeight) { - return YES; - } - - return NO; + + int chosenWeightDeltaMagnitude = abs(chosenWeight - desiredWeight); + int candidateWeightDeltaMagnitude = abs(candidateWeight - desiredWeight); + + // If both are the same distance from the desired weight, prefer the candidate if it is further from medium. + if (chosenWeightDeltaMagnitude == candidateWeightDeltaMagnitude) + return abs(candidateWeight - 6) > abs(chosenWeight - 6); + + // Otherwise, prefer the one closer to the desired weight. + return candidateWeightDeltaMagnitude < chosenWeightDeltaMagnitude; +} + +// Workaround for <rdar://problem/5781372>. +static inline void fixUpWeight(NSInteger& weight, NSString *fontName) +{ + if (weight == 3 && [fontName rangeOfString:@"ultralight" options:NSCaseInsensitiveSearch | NSBackwardsSearch | NSLiteralSearch].location != NSNotFound) + weight = 2; +} + +static inline FontTraitsMask toTraitsMask(NSFontTraitMask appKitTraits, NSInteger appKitWeight) +{ + return static_cast<FontTraitsMask>(((appKitTraits & NSFontItalicTrait) ? FontStyleItalicMask : FontStyleNormalMask) + | FontVariantNormalMask + | (appKitWeight == 1 ? FontWeight100Mask : + appKitWeight == 2 ? FontWeight200Mask : + appKitWeight <= 4 ? FontWeight300Mask : + appKitWeight == 5 ? FontWeight400Mask : + appKitWeight == 6 ? FontWeight500Mask : + appKitWeight <= 8 ? FontWeight600Mask : + appKitWeight == 9 ? FontWeight700Mask : + appKitWeight <= 11 ? FontWeight800Mask : + FontWeight900Mask)); } @implementation WebFontCache -// Family name is somewhat of a misnomer here. We first attempt to find an exact match -// comparing the desiredFamily to the PostScript name of the installed fonts. If that fails -// we then do a search based on the family names of the installed fonts. -+ (NSFont *)internalFontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits size:(float)size ++ (void)getTraits:(Vector<unsigned>&)traitsMasks inFamily:(NSString *)desiredFamily { NSFontManager *fontManager = [NSFontManager sharedFontManager]; - // Look for an exact match first. - NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnumerator]; - NSString *availableFont; - NSFont *nameMatchedFont = nil; - while ((availableFont = [availableFonts nextObject])) { - if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrderedSame) { - nameMatchedFont = [NSFont fontWithName:availableFont size:size]; - - // Special case Osaka-Mono. According to <rdar://problem/3999467>, we need to - // treat Osaka-Mono as fixed pitch. - if ([desiredFamily caseInsensitiveCompare:@"Osaka-Mono"] == NSOrderedSame && desiredTraits == 0) - return nameMatchedFont; - - NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFont]; - if ((traits & desiredTraits) == desiredTraits) - return [fontManager convertFont:nameMatchedFont toHaveTrait:desiredTraits]; + NSEnumerator *e = [[fontManager availableFontFamilies] objectEnumerator]; + NSString *availableFamily; + while ((availableFamily = [e nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFamily] == NSOrderedSame) break; + } + + if (!availableFamily) { + // Match by PostScript name. + NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnumerator]; + NSString *availableFont; + while ((availableFont = [availableFonts nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrderedSame) { + NSFont *font = [NSFont fontWithName:availableFont size:10]; + NSInteger weight = [fontManager weightOfFont:font]; + fixUpWeight(weight, desiredFamily); + traitsMasks.append(toTraitsMask([fontManager traitsOfFont:font], weight)); + break; + } } + return; } + NSArray *fonts = [fontManager availableMembersOfFontFamily:availableFamily]; + unsigned n = [fonts count]; + unsigned i; + for (i = 0; i < n; i++) { + NSArray *fontInfo = [fonts objectAtIndex:i]; + // Array indices must be hard coded because of lame AppKit API. + NSString *fontFullName = [fontInfo objectAtIndex:0]; + NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue]; + fixUpWeight(fontWeight, fontFullName); + + NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValue]; + traitsMasks.append(toTraitsMask(fontTraits, fontWeight)); + } +} + +// Family name is somewhat of a misnomer here. We first attempt to find an exact match +// comparing the desiredFamily to the PostScript name of the installed fonts. If that fails +// we then do a search based on the family names of the installed fonts. ++ (NSFont *)internalFontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits weight:(int)desiredWeight size:(float)size +{ + NSFontManager *fontManager = [NSFontManager sharedFontManager]; + // Do a simple case insensitive search for a matching font family. // NSFontManager requires exact name matches. // This addresses the problem of matching arial to Arial, etc., but perhaps not all the issues. @@ -144,13 +184,36 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, break; } - if (!availableFamily) - availableFamily = [nameMatchedFont familyName]; + if (!availableFamily) { + // Match by PostScript name. + NSEnumerator *availableFonts = [[fontManager availableFonts] objectEnumerator]; + NSString *availableFont; + NSFont *nameMatchedFont = nil; + NSFontTraitMask desiredTraitsForNameMatch = desiredTraits | (desiredWeight >= 7 ? NSBoldFontMask : 0); + while ((availableFont = [availableFonts nextObject])) { + if ([desiredFamily caseInsensitiveCompare:availableFont] == NSOrderedSame) { + nameMatchedFont = [NSFont fontWithName:availableFont size:size]; + + // Special case Osaka-Mono. According to <rdar://problem/3999467>, we need to + // treat Osaka-Mono as fixed pitch. + if ([desiredFamily caseInsensitiveCompare:@"Osaka-Mono"] == NSOrderedSame && desiredTraitsForNameMatch == 0) + return nameMatchedFont; + + NSFontTraitMask traits = [fontManager traitsOfFont:nameMatchedFont]; + if ((traits & desiredTraitsForNameMatch) == desiredTraitsForNameMatch) + return [fontManager convertFont:nameMatchedFont toHaveTrait:desiredTraitsForNameMatch]; + + availableFamily = [nameMatchedFont familyName]; + break; + } + } + } // Found a family, now figure out what weight and traits to use. BOOL choseFont = false; int chosenWeight = 0; NSFontTraitMask chosenTraits = 0; + NSString *chosenFullName = 0; NSArray *fonts = [fontManager availableMembersOfFontFamily:availableFamily]; unsigned n = [fonts count]; @@ -159,21 +222,25 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, NSArray *fontInfo = [fonts objectAtIndex:i]; // Array indices must be hard coded because of lame AppKit API. - int fontWeight = [[fontInfo objectAtIndex:2] intValue]; + NSString *fontFullName = [fontInfo objectAtIndex:0]; + NSInteger fontWeight = [[fontInfo objectAtIndex:2] intValue]; + fixUpWeight(fontWeight, fontFullName); + NSFontTraitMask fontTraits = [[fontInfo objectAtIndex:3] unsignedIntValue]; BOOL newWinner; if (!choseFont) - newWinner = acceptableChoice(desiredTraits, DESIRED_WEIGHT, fontTraits, fontWeight); + newWinner = acceptableChoice(desiredTraits, desiredWeight, fontTraits, fontWeight); else - newWinner = betterChoice(desiredTraits, DESIRED_WEIGHT, chosenTraits, chosenWeight, fontTraits, fontWeight); + newWinner = betterChoice(desiredTraits, desiredWeight, chosenTraits, chosenWeight, fontTraits, fontWeight); if (newWinner) { choseFont = YES; chosenWeight = fontWeight; chosenTraits = fontTraits; + chosenFullName = fontFullName; - if (chosenWeight == DESIRED_WEIGHT && (chosenTraits & IMPORTANT_FONT_TRAITS) == (desiredTraits & IMPORTANT_FONT_TRAITS)) + if (chosenWeight == desiredWeight && (chosenTraits & IMPORTANT_FONT_TRAITS) == (desiredTraits & IMPORTANT_FONT_TRAITS)) break; } } @@ -181,17 +248,18 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, if (!choseFont) return nil; - NSFont *font = [fontManager fontWithFamily:availableFamily traits:chosenTraits weight:chosenWeight size:size]; + NSFont *font = [NSFont fontWithName:chosenFullName size:size]; if (!font) return nil; NSFontTraitMask actualTraits = 0; - if (desiredTraits & (NSItalicFontMask | NSBoldFontMask)) - actualTraits = [[NSFontManager sharedFontManager] traitsOfFont:font]; + if (desiredTraits & NSFontItalicTrait) + actualTraits = [fontManager traitsOfFont:font]; + int actualWeight = [fontManager weightOfFont:font]; - bool syntheticBold = (desiredTraits & NSBoldFontMask) && !(actualTraits & NSBoldFontMask); - bool syntheticOblique = (desiredTraits & NSItalicFontMask) && !(actualTraits & NSItalicFontMask); + bool syntheticBold = desiredWeight >= 7 && actualWeight < 7; + bool syntheticOblique = (desiredTraits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait); // There are some malformed fonts that will be correctly returned by -fontWithFamily:traits:weight:size: as a match for a particular trait, // though -[NSFontManager traitsOfFont:] incorrectly claims the font does not have the specified trait. This could result in applying @@ -215,10 +283,10 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, return font; } -+ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits size:(float)size ++ (NSFont *)fontWithFamily:(NSString *)desiredFamily traits:(NSFontTraitMask)desiredTraits weight:(int)desiredWeight size:(float)size { #ifndef BUILDING_ON_TIGER - NSFont *font = [self internalFontWithFamily:desiredFamily traits:desiredTraits size:size]; + NSFont *font = [self internalFontWithFamily:desiredFamily traits:desiredTraits weight:desiredWeight size:size]; if (font) return font; @@ -227,7 +295,7 @@ static BOOL betterChoice(NSFontTraitMask desiredTraits, int desiredWeight, [NSFont fontWithName:desiredFamily size:size]; #endif - return [self internalFontWithFamily:desiredFamily traits:desiredTraits size:size]; + return [self internalFontWithFamily:desiredFamily traits:desiredTraits weight:desiredWeight size:size]; } @end diff --git a/WebCore/platform/mac/WheelEventMac.mm b/WebCore/platform/mac/WheelEventMac.mm index 558bc5f..7b60494 100644 --- a/WebCore/platform/mac/WheelEventMac.mm +++ b/WebCore/platform/mac/WheelEventMac.mm @@ -34,8 +34,6 @@ namespace WebCore { PlatformWheelEvent::PlatformWheelEvent(NSEvent* event) : m_position(pointForEvent(event)) , m_globalPosition(globalPointForEvent(event)) - , m_deltaX([event deltaX]) - , m_deltaY([event deltaY]) , m_isAccepted(false) , m_shiftKey([event modifierFlags] & NSShiftKeyMask) , m_ctrlKey([event modifierFlags] & NSControlKeyMask) @@ -43,8 +41,12 @@ PlatformWheelEvent::PlatformWheelEvent(NSEvent* event) , m_metaKey([event modifierFlags] & NSCommandKeyMask) { BOOL continuous; - wkGetWheelEventDeltas(event, &m_continuousDeltaX, &m_continuousDeltaY, &continuous); - m_isContinuous = continuous; + wkGetWheelEventDeltas(event, &m_deltaX, &m_deltaY, &continuous); + m_granularity = continuous ? ScrollByPixelWheelEvent : ScrollByLineWheelEvent; + if (m_granularity == ScrollByLineWheelEvent) { + m_deltaX *= horizontalLineMultiplier(); + m_deltaY *= verticalLineMultiplier(); + } } } // namespace WebCore diff --git a/WebCore/platform/mac/WidgetMac.mm b/WebCore/platform/mac/WidgetMac.mm index 533f721..3fe8e0d 100644 --- a/WebCore/platform/mac/WidgetMac.mm +++ b/WebCore/platform/mac/WidgetMac.mm @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2004, 2005, 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 @@ -30,29 +30,31 @@ #import "Cursor.h" #import "Document.h" #import "Font.h" +#import "FoundationExtras.h" #import "Frame.h" #import "GraphicsContext.h" #import "Page.h" #import "PlatformMouseEvent.h" -#import "WebCoreFrameBridge.h" +#import "ScrollView.h" #import "WebCoreFrameView.h" #import "WebCoreView.h" -#import "WidgetClient.h" #import <wtf/RetainPtr.h> -@interface NSWindow (WindowPrivate) -- (BOOL) _needsToResetDragMargins; -- (void) _setNeedsToResetDragMargins:(BOOL)s; +@interface NSWindow (WebWindowDetails) +- (BOOL)_needsToResetDragMargins; +- (void)_setNeedsToResetDragMargins:(BOOL)needs; +@end + +@interface NSView (WebSetSelectedMethods) +- (void)setIsSelected:(BOOL)isSelected; +- (void)webPlugInSetIsSelected:(BOOL)isSelected; @end namespace WebCore { class WidgetPrivate { public: - RetainPtr<NSView> view; - WidgetClient* client; - bool visible; bool mustStayInWindow; bool removeFromSuperviewSoon; }; @@ -73,58 +75,18 @@ static void safeRemoveFromSuperview(NSView *view) [window _setNeedsToResetDragMargins:resetDragMargins]; } -Widget::Widget() : data(new WidgetPrivate) +Widget::Widget(NSView* view) + : m_data(new WidgetPrivate) { - data->view = nil; - data->client = 0; - data->visible = true; - data->mustStayInWindow = false; - data->removeFromSuperviewSoon = false; + init(view); + m_data->mustStayInWindow = false; + m_data->removeFromSuperviewSoon = false; } -Widget::Widget(NSView* view) : data(new WidgetPrivate) +Widget::~Widget() { - data->view = view; - data->client = 0; - data->visible = true; - data->mustStayInWindow = false; - data->removeFromSuperviewSoon = false; -} - -Widget::~Widget() -{ - delete data; -} - -void Widget::setEnabled(bool enabled) -{ - id view = data->view.get(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view respondsToSelector:@selector(setEnabled:)]) { - [view setEnabled:enabled]; - } - END_BLOCK_OBJC_EXCEPTIONS; -} - -bool Widget::isEnabled() const -{ - id view = data->view.get(); - - BEGIN_BLOCK_OBJC_EXCEPTIONS; - if ([view respondsToSelector:@selector(isEnabled)]) { - return [view isEnabled]; - } - END_BLOCK_OBJC_EXCEPTIONS; - - return true; -} - -IntRect Widget::frameGeometry() const -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - return enclosingIntRect([getOuterView() frame]); - END_BLOCK_OBJC_EXCEPTIONS; - return IntRect(); + releasePlatformWidget(); + delete m_data; } // FIXME: Should move this to Chrome; bad layering that this knows about Frame. @@ -136,7 +98,7 @@ void Widget::setFocus() BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *view = [getView() _webcore_effectiveFirstResponder]; + NSView *view = [platformWidget() _webcore_effectiveFirstResponder]; if (Page* page = frame->page()) page->chrome()->focusNSView(view); @@ -152,10 +114,10 @@ void Widget::setFocus() void Widget::show() { - if (!data || data->visible) + if (isSelfVisible()) return; - data->visible = true; + setSelfVisible(true); BEGIN_BLOCK_OBJC_EXCEPTIONS; [getOuterView() setHidden:NO]; @@ -164,46 +126,49 @@ void Widget::show() void Widget::hide() { - if (!data || !data->visible) + if (!isSelfVisible()) return; - data->visible = false; + setSelfVisible(false); BEGIN_BLOCK_OBJC_EXCEPTIONS; [getOuterView() setHidden:YES]; END_BLOCK_OBJC_EXCEPTIONS; } -void Widget::setFrameGeometry(const IntRect &rect) +IntRect Widget::frameRect() const { + if (!platformWidget()) + return m_frame; + BEGIN_BLOCK_OBJC_EXCEPTIONS; - NSView *v = getOuterView(); - NSRect f = rect; - if (!NSEqualRects(f, [v frame])) { - [v setFrame:f]; - [v setNeedsDisplay: NO]; - } + return enclosingIntRect([getOuterView() frame]); END_BLOCK_OBJC_EXCEPTIONS; + + return m_frame; } -NSView* Widget::getView() const +void Widget::setFrameRect(const IntRect& rect) { - return data->view.get(); -} + m_frame = rect; -void Widget::setView(NSView* view) -{ BEGIN_BLOCK_OBJC_EXCEPTIONS; - data->view = view; + NSView *v = getOuterView(); + NSRect f = rect; + if (!NSEqualRects(f, [v frame])) { + [v setFrame:f]; + [v setNeedsDisplay: NO]; + } END_BLOCK_OBJC_EXCEPTIONS; } NSView* Widget::getOuterView() const { - // If this widget's view is a WebCoreFrameView the we resize its containing view, a WebFrameView. + NSView* view = platformWidget(); - NSView* view = data->view.get(); - if ([view conformsToProtocol:@protocol(WebCoreFrameView)]) { + // If this widget's view is a WebCoreFrameScrollView then we + // resize its containing view, a WebFrameView. + if ([view conformsToProtocol:@protocol(WebCoreFrameScrollView)]) { view = [view superview]; ASSERT(view); } @@ -216,58 +181,71 @@ void Widget::paint(GraphicsContext* p, const IntRect& r) if (p->paintingDisabled()) return; NSView *view = getOuterView(); - BEGIN_BLOCK_OBJC_EXCEPTIONS; - [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]]; - END_BLOCK_OBJC_EXCEPTIONS; -} + NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; + if (currentContext == [[view window] graphicsContext] || ![currentContext isDrawingToScreen]) { + // This is the common case of drawing into a window or printing. + BEGIN_BLOCK_OBJC_EXCEPTIONS; + [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]]]; + END_BLOCK_OBJC_EXCEPTIONS; + } else { + // This is the case of drawing into a bitmap context other than a window backing store. It gets hit beneath + // -cacheDisplayInRect:toBitmapImageRep:. + + // Transparent subframes are in fact implemented with scroll views that return YES from -drawsBackground (whenever the WebView + // itself is in drawsBackground mode). In the normal drawing code path, the scroll views are never asked to draw the background, + // so this is not an issue, but in this code path they are, so the following code temporarily turns background drwaing off. + NSView *innerView = platformWidget(); + NSScrollView *scrollView = 0; + if ([innerView conformsToProtocol:@protocol(WebCoreFrameScrollView)]) { + ASSERT([innerView isKindOfClass:[NSScrollView class]]); + NSScrollView *scrollView = static_cast<NSScrollView *>(innerView); + // -copiesOnScroll will return NO whenever the content view is not fully opaque. + if ([scrollView drawsBackground] && ![[scrollView contentView] copiesOnScroll]) + [scrollView setDrawsBackground:NO]; + else + scrollView = 0; + } + + CGContextRef cgContext = p->platformContext(); + ASSERT(cgContext == [currentContext graphicsPort]); + CGContextSaveGState(cgContext); + + NSRect viewFrame = [view frame]; + NSRect viewBounds = [view bounds]; + // Set up the translation and (flipped) orientation of the graphics context. In normal drawing, AppKit does it as it descends down + // the view hierarchy. + CGContextTranslateCTM(cgContext, viewFrame.origin.x - viewBounds.origin.x, viewFrame.origin.y + viewFrame.size.height + viewBounds.origin.y); + CGContextScaleCTM(cgContext, 1, -1); -void Widget::invalidate() -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - [getView() setNeedsDisplay: YES]; - END_BLOCK_OBJC_EXCEPTIONS; -} + BEGIN_BLOCK_OBJC_EXCEPTIONS; + NSGraphicsContext *nsContext = [NSGraphicsContext graphicsContextWithGraphicsPort:cgContext flipped:YES]; + [view displayRectIgnoringOpacity:[view convertRect:r fromView:[view superview]] inContext:nsContext]; + END_BLOCK_OBJC_EXCEPTIONS; -void Widget::invalidateRect(const IntRect& r) -{ - BEGIN_BLOCK_OBJC_EXCEPTIONS; - [getView() setNeedsDisplayInRect: r]; - END_BLOCK_OBJC_EXCEPTIONS; -} + CGContextRestoreGState(cgContext); -// FIXME: Should move this to Chrome; bad layering that this knows about Frame. -void Widget::setIsSelected(bool isSelected) -{ - if (Frame* frame = Frame::frameForWidget(this)) - [frame->bridge() setIsSelected:isSelected forView:getView()]; + if (scrollView) + [scrollView setDrawsBackground:YES]; + } } -void Widget::addToSuperview(NSView *view) +void Widget::setIsSelected(bool isSelected) { + NSView *view = platformWidget(); BEGIN_BLOCK_OBJC_EXCEPTIONS; - - ASSERT(view); - NSView *subview = getOuterView(); - ASSERT(![view isDescendantOf:subview]); - - // Suppress the resetting of drag margins since we know we can't affect them. - NSWindow* window = [view window]; - BOOL resetDragMargins = [window _needsToResetDragMargins]; - [window _setNeedsToResetDragMargins:NO]; - if ([subview superview] != view) - [view addSubview:subview]; - data->removeFromSuperviewSoon = false; - [window _setNeedsToResetDragMargins:resetDragMargins]; - + if ([view respondsToSelector:@selector(webPlugInSetIsSelected:)]) + [view webPlugInSetIsSelected:isSelected]; + else if ([view respondsToSelector:@selector(setIsSelected:)]) + [view setIsSelected:isSelected]; END_BLOCK_OBJC_EXCEPTIONS; } void Widget::removeFromSuperview() { - if (data->mustStayInWindow) - data->removeFromSuperviewSoon = true; + if (m_data->mustStayInWindow) + m_data->removeFromSuperviewSoon = true; else { - data->removeFromSuperviewSoon = false; + m_data->removeFromSuperviewSoon = false; BEGIN_BLOCK_OBJC_EXCEPTIONS; safeRemoveFromSuperview(getOuterView()); END_BLOCK_OBJC_EXCEPTIONS; @@ -278,8 +256,8 @@ void Widget::beforeMouseDown(NSView *view, Widget* widget) { if (widget) { ASSERT(view == widget->getOuterView()); - ASSERT(!widget->data->mustStayInWindow); - widget->data->mustStayInWindow = true; + ASSERT(!widget->m_data->mustStayInWindow); + widget->m_data->mustStayInWindow = true; } } @@ -290,32 +268,86 @@ void Widget::afterMouseDown(NSView *view, Widget* widget) safeRemoveFromSuperview(view); END_BLOCK_OBJC_EXCEPTIONS; } else { - ASSERT(widget->data->mustStayInWindow); - widget->data->mustStayInWindow = false; - if (widget->data->removeFromSuperviewSoon) + ASSERT(widget->m_data->mustStayInWindow); + widget->m_data->mustStayInWindow = false; + if (widget->m_data->removeFromSuperviewSoon) widget->removeFromSuperview(); } } -void Widget::setClient(WidgetClient* c) +IntPoint Widget::convertFromContainingWindow(const IntPoint& point) const +{ + if (!platformWidget() && parent()) { + IntPoint result = parent()->convertFromContainingWindow(point); + result.move(parent()->scrollX() - x(), parent()->scrollY() - y()); + return result; + } + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return IntPoint([platformWidget() convertPoint:point fromView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return point; +} + +IntRect Widget::convertFromContainingWindow(const IntRect& rect) const { - data->client = c; + if (!platformWidget() && parent()) { + IntRect result = parent()->convertFromContainingWindow(rect); + result.move(parent()->scrollX() - x(), parent()->scrollY() - y()); + return result; + } + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return enclosingIntRect([platformWidget() convertRect:rect fromView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return rect; } -WidgetClient* Widget::client() const +IntRect Widget::convertToContainingWindow(const IntRect& r) const +{ + if (!platformWidget()) { + if (!parent()) + return r; + IntRect result = r; + result.move(parent()->scrollX() - x(), parent()->scrollY() - y()); + return parent()->convertToContainingWindow(result); + } + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return IntRect([platformWidget() convertRect:r toView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return r; +} + +IntPoint Widget::convertToContainingWindow(const IntPoint& p) const { - return data->client; + if (!platformWidget()) { + if (!parent()) + return p; + IntPoint result = p; + result.move(parent()->scrollX() - x(), parent()->scrollY() - y()); + return parent()->convertToContainingWindow(result); + } + + BEGIN_BLOCK_OBJC_EXCEPTIONS; + return IntPoint([platformWidget() convertPoint:p toView:nil]); + END_BLOCK_OBJC_EXCEPTIONS; + + return p; } -void Widget::removeFromParent() +void Widget::releasePlatformWidget() { + HardRelease(m_widget); } -IntPoint Widget::convertToScreenCoordinate(NSView *view, const IntPoint& point) +void Widget::retainPlatformWidget() { - NSPoint conversionPoint = { point.x(), point.y() }; - conversionPoint = [view convertPoint:conversionPoint toView:nil]; - return globalPoint(conversionPoint, [view window]); + HardRetain(m_widget); } } + |