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