18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "config.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "DragImage.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#if ENABLE(DRAG_SUPPORT) 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "CachedImage.h" 312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "Font.h" 322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "FontDescription.h" 332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "FontSelector.h" 342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "GraphicsContext.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "Image.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "KURL.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "ResourceResponse.h" 382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "Settings.h" 392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "StringTruncator.h" 402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "TextRun.h" 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectIntSize dragImageSize(RetainPtr<NSImage> image) 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return (IntSize)[image.get() size]; 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid deleteDragImage(RetainPtr<NSImage>) 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Since this is a RetainPtr, there's nothing additional we need to do to 52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // delete it. It will be released when it falls out of scope. 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRetainPtr<NSImage> scaleDragImage(RetainPtr<NSImage> image, FloatSize scale) 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSSize originalSize = [image.get() size]; 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSSize newSize = NSMakeSize((originalSize.width * scale.width()), (originalSize.height * scale.height())); 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newSize.width = roundf(newSize.width); 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project newSize.height = roundf(newSize.height); 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [image.get() setScalesWhenResized:YES]; 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [image.get() setSize:newSize]; 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return image; 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRetainPtr<NSImage> dissolveDragImageToFraction(RetainPtr<NSImage> image, float delta) 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RetainPtr<NSImage> dissolvedImage(AdoptNS, [[NSImage alloc] initWithSize:[image.get() size]]); 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSPoint point = [image.get() isFlipped] ? NSMakePoint(0, [image.get() size].height) : NSZeroPoint; 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // In this case the dragging image is always correct. 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [dissolvedImage.get() setFlipped:[image.get() isFlipped]]; 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [dissolvedImage.get() lockFocus]; 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [image.get() dissolveToPoint:point fraction: delta]; 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [dissolvedImage.get() unlockFocus]; 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [image.get() lockFocus]; 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [dissolvedImage.get() compositeToPoint:point operation:NSCompositeCopy]; 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [image.get() unlockFocus]; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return image; 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 86635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRetainPtr<NSImage> createDragImageFromImage(Image* image) 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RetainPtr<NSImage> dragImage(AdoptNS, [image->getNSImage() copy]); 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [dragImage.get() setSize:(NSSize)(image->size())]; 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return dragImage; 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectRetainPtr<NSImage> createDragImageIconForCachedImage(CachedImage* image) 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const String& filename = image->response().suggestedFilename(); 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *extension = nil; 97f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick size_t dotIndex = filename.reverseFind('.'); 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 99f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (dotIndex != notFound && dotIndex < (filename.length() - 1)) // require that a . exists after the first character and before the last 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project extension = filename.substring(dotIndex + 1); 101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else { 102635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // It might be worth doing a further lookup to pull the extension from the MIME type. 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project extension = @""; 104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return [[NSWorkspace sharedWorkspace] iconForFileType:extension]; 1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1102fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float DragLabelBorderX = 4; 1112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block//Keep border_y in synch with DragController::LinkDragBorderInset 1122fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float DragLabelBorderY = 2; 1132fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float DragLabelRadius = 5; 1142fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float LabelBorderYOffset = 2; 1152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1162fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float MinDragLabelWidthBeforeClip = 120; 1172fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float MaxDragLabelWidth = 320; 1182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1192fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float DragLinkLabelFontsize = 11; 1202fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst float DragLinkUrlFontSize = 10; 1212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1222fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// FIXME - we should move all the functionality of NSString extras to WebCore 1232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1242fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic Font& fontFromNSFont(NSFont *font) 1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block static NSFont *currentFont; 1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DEFINE_STATIC_LOCAL(Font, currentRenderer, ()); 1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if ([font isEqual:currentFont]) 1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return currentRenderer; 1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (currentFont) 1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CFRelease(currentFont); 1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currentFont = font; 1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CFRetain(currentFont); 1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FontPlatformData f(font, [font pointSize]); 1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block currentRenderer = Font(f, ![[NSGraphicsContext currentContext] isDrawingToScreen]); 1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return currentRenderer; 1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1402fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic bool canUseFastRenderer(const UniChar* buffer, unsigned length) 1412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned i; 1432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block for (i = 0; i < length; i++) { 1442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block UCharDirection direction = u_charDirection(buffer[i]); 1452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (direction == U_RIGHT_TO_LEFT || direction > U_OTHER_NEUTRAL) 1462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return false; 1472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return true; 1492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1512fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic float widthWithFont(NSString *string, NSFont *font) 1522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned length = [string length]; 1542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Vector<UniChar, 2048> buffer(length); 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [string getCharacters:buffer.data()]; 1572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (canUseFastRenderer(buffer.data(), length)) { 1592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Font webCoreFont(FontPlatformData(font, [font pointSize]), ![[NSGraphicsContext currentContext] isDrawingToScreen]); 1602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block TextRun run(buffer.data(), length); 16181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch return webCoreFont.width(run); 1622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 1632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return [string sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]].width; 1652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1672fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic inline CGFloat webkit_CGCeiling(CGFloat value) 1682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (sizeof(value) == sizeof(float)) 1702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return ceilf(value); 1712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return static_cast<CGFloat>(ceil(value)); 1722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 1732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1742fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void drawAtPoint(NSString *string, NSPoint point, NSFont *font, NSColor *textColor) 1752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 1762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned length = [string length]; 1772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Vector<UniChar, 2048> buffer(length); 1782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [string getCharacters:buffer.data()]; 1802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (canUseFastRenderer(buffer.data(), length)) { 1822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // The following is a half-assed attempt to match AppKit's rounding rules for drawAtPoint. 1832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // It's probably incorrect for high DPI. 1842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // If you change this, be sure to test all the text drawn this way in Safari, including 1852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // the status bar, bookmarks bar, tab bar, and activity window. 1862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.y = webkit_CGCeiling(point.y); 1872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSGraphicsContext *nsContext = [NSGraphicsContext currentContext]; 1892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGContextRef cgContext = static_cast<CGContextRef>([nsContext graphicsPort]); 1902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block GraphicsContext graphicsContext(cgContext); 1912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Safari doesn't flip the NSGraphicsContext before calling WebKit, yet WebCore requires a flipped graphics context. 1932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BOOL flipped = [nsContext isFlipped]; 1942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!flipped) 1952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGContextScaleCTM(cgContext, 1, -1); 1962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 1972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block Font webCoreFont(FontPlatformData(font, [font pointSize]), ![nsContext isDrawingToScreen], Antialiased); 1982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block TextRun run(buffer.data(), length); 19981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 2002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGFloat red; 2012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGFloat green; 2022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGFloat blue; 2032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGFloat alpha; 2042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [[textColor colorUsingColorSpaceName:NSDeviceRGBColorSpace] getRed:&red green:&green blue:&blue alpha:&alpha]; 2052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block graphicsContext.setFillColor(makeRGBA(red * 255, green * 255, blue * 255, alpha * 255), ColorSpaceDeviceRGB); 2062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block webCoreFont.drawText(&graphicsContext, run, FloatPoint(point.x, (flipped ? point.y : (-1 * point.y)))); 2082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!flipped) 2102fc2651226baac27029e38c9d6ef883fa32084dbSteve Block CGContextScaleCTM(cgContext, 1, -1); 2112fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else { 2122fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // The given point is on the baseline. 2132fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if ([[NSView focusView] isFlipped]) 2142fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.y -= [font ascender]; 2152fc2651226baac27029e38c9d6ef883fa32084dbSteve Block else 2162fc2651226baac27029e38c9d6ef883fa32084dbSteve Block point.y += [font descender]; 2172fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2182fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [string drawAtPoint:point withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, textColor, NSForegroundColorAttributeName, nil]]; 2192fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2202fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 2212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2222fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockstatic void drawDoubledAtPoint(NSString *string, NSPoint textPoint, NSColor *topColor, NSColor *bottomColor, NSFont *font) 2232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 2242fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // turn off font smoothing so translucent text draws correctly (Radar 3118455) 2252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawAtPoint(string, textPoint, font, bottomColor); 2262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block textPoint.y += 1; 2282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawAtPoint(string, textPoint, font, topColor); 2292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 2302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2312fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockDragImageRef createDragImageForLink(KURL& url, const String& title, Frame* frame) 2322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 2332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!frame) 2342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return nil; 2352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSString *label = 0; 2362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!title.isEmpty()) 2372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block label = title; 2382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSURL *cocoaURL = url; 2392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSString *urlString = [cocoaURL absoluteString]; 2402fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2412fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BOOL drawURLString = YES; 2422fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BOOL clipURLString = NO; 2432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block BOOL clipLabelString = NO; 2442fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2452fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!label) { 2462fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawURLString = NO; 2472fc2651226baac27029e38c9d6ef883fa32084dbSteve Block label = urlString; 2482fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSFont *labelFont = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:DragLinkLabelFontsize] 2512fc2651226baac27029e38c9d6ef883fa32084dbSteve Block toHaveTrait:NSBoldFontMask]; 2522fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSFont *urlFont = [NSFont systemFontOfSize:DragLinkUrlFontSize]; 2532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSSize labelSize; 2542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block labelSize.width = widthWithFont(label, labelFont); 2552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block labelSize.height = [labelFont ascender] - [labelFont descender]; 2562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (labelSize.width > MaxDragLabelWidth){ 2572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block labelSize.width = MaxDragLabelWidth; 2582fc2651226baac27029e38c9d6ef883fa32084dbSteve Block clipLabelString = YES; 2592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSSize imageSize; 2622fc2651226baac27029e38c9d6ef883fa32084dbSteve Block imageSize.width = labelSize.width + DragLabelBorderX * 2; 2632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block imageSize.height = labelSize.height + DragLabelBorderY * 2; 2642fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (drawURLString) { 2652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSSize urlStringSize; 2662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block urlStringSize.width = widthWithFont(urlString, urlFont); 2672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block urlStringSize.height = [urlFont ascender] - [urlFont descender]; 2682fc2651226baac27029e38c9d6ef883fa32084dbSteve Block imageSize.height += urlStringSize.height; 2692fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (urlStringSize.width > MaxDragLabelWidth) { 2702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block imageSize.width = std::max(MaxDragLabelWidth + DragLabelBorderY * 2, MinDragLabelWidthBeforeClip); 2712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block clipURLString = YES; 2722fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } else 2732fc2651226baac27029e38c9d6ef883fa32084dbSteve Block imageSize.width = std::max(labelSize.width + DragLabelBorderX * 2, urlStringSize.width + DragLabelBorderX * 2); 2742fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 2752fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease]; 2762fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [dragImage lockFocus]; 2772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [[NSColor colorWithDeviceRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set]; 2792fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2802fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Drag a rectangle with rounded corners 2812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSBezierPath *path = [NSBezierPath bezierPath]; 2822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithOvalInRect: NSMakeRect(0, 0, DragLabelRadius * 2, DragLabelRadius * 2)]; 2832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithOvalInRect: NSMakeRect(0, imageSize.height - DragLabelRadius * 2, DragLabelRadius * 2, DragLabelRadius * 2)]; 2842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DragLabelRadius * 2, imageSize.height - DragLabelRadius * 2, DragLabelRadius * 2, DragLabelRadius * 2)]; 2852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DragLabelRadius * 2, 0, DragLabelRadius * 2, DragLabelRadius * 2)]; 2862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithRect: NSMakeRect(DragLabelRadius, 0, imageSize.width - DragLabelRadius * 2, imageSize.height)]; 2882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithRect: NSMakeRect(0, DragLabelRadius, DragLabelRadius + 10, imageSize.height - 2 * DragLabelRadius)]; 2892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DragLabelRadius - 20, DragLabelRadius, DragLabelRadius + 20, imageSize.height - 2 * DragLabelRadius)]; 2902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [path fill]; 2912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSColor *topColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.75f]; 2932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block NSColor *bottomColor = [NSColor colorWithDeviceWhite:1.0f alpha:0.5f]; 2942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (drawURLString) { 2952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (clipURLString) 2962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block urlString = StringTruncator::centerTruncate(urlString, imageSize.width - (DragLabelBorderX * 2), fontFromNSFont(urlFont)); 2972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawDoubledAtPoint(urlString, NSMakePoint(DragLabelBorderX, DragLabelBorderY - [urlFont descender]), topColor, bottomColor, urlFont); 2992fc2651226baac27029e38c9d6ef883fa32084dbSteve Block } 3002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3012fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (clipLabelString) 3022fc2651226baac27029e38c9d6ef883fa32084dbSteve Block label = StringTruncator::rightTruncate(label, imageSize.width - (DragLabelBorderX * 2), fontFromNSFont(labelFont)); 3032fc2651226baac27029e38c9d6ef883fa32084dbSteve Block drawDoubledAtPoint(label, NSMakePoint(DragLabelBorderX, imageSize.height - LabelBorderYOffset - [labelFont pointSize]), topColor, bottomColor, labelFont); 3042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3052fc2651226baac27029e38c9d6ef883fa32084dbSteve Block [dragImage unlockFocus]; 3062fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 3072fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return dragImage; 3082fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 3092fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore 311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#endif // ENABLE(DRAG_SUPPORT) 313