diff options
author | Steve Block <steveblock@google.com> | 2011-05-25 08:15:24 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-25 08:15:24 -0700 |
commit | fa91a01aee5d4a80ca6c80f722116b850f09996c (patch) | |
tree | f72740e60d3c3d4f0ab144e88c03d1f134944ce3 /Source/WebCore/platform/mac/DragImageMac.mm | |
parent | 96f37d6d1b390f6690858789706ee6ec25bc1677 (diff) | |
parent | feebf8e7a79ad68b04a1a948e2b8078d6e5f0048 (diff) | |
download | external_webkit-fa91a01aee5d4a80ca6c80f722116b850f09996c.zip external_webkit-fa91a01aee5d4a80ca6c80f722116b850f09996c.tar.gz external_webkit-fa91a01aee5d4a80ca6c80f722116b850f09996c.tar.bz2 |
Merge changes I78ff6a85,Ic85c6405,Ibf903baa,I3a0459db,I35140385,I54790419,I6bfe5d24,Ia9f39b83,I5bcecd5a,I1de96683,I543c6810,I8a5b0878,I0ae670bf,Ide4d58dc,I28ebaf3d,I499d6631,Ie5090e0d,I6d3e5f1f
* changes:
Merge WebKit at r78450: Update ThirdPartyProject.prop
Merge WebKit at r78450: Add new Font::canExpandAroundIdeographsInComplexText()
Merge WebKit at r78450: Add new ChromeClient::selectItemAlignmentFollowsMenuWritingDirection()
Merge WebKit at r78450: FrameLoaderClient::didRunInsecureContent() signature changed
Merge WebKit at r78450: HTMLAreaElement::getRect() renamed
Merge WebKit at r78450: FrameLoader::url() removed
Merge WebKit at r78450: HTMLParserQuirks removed
Merge WebKit at r78450: TextRun::padding() renamed
Merge WebKit at r78450: Use new FontMetrics
Merge WebKit at r78450: GraphicsContext current path removed
Merge WebKit at r78450: TransformationMatrix multiply methods renamed and meaning changed
Merge WebKit at r78450: FontCustomPlatformData::fontPlatformData() signature changed
Merge WebKit at r78450: IntRect::bottom()/right() renamed
Merge WebKit at r78450: Fix remaining conflicts
Merge WebKit at r78450: Fix conflicts due to new ENABLE_WEB_ARCHIVE guard
Merge WebKit at r78450: Fix conflicts in media controls
Merge WebKit at r78450: Fix Makefiles
Merge WebKit at r78450: Initial merge by git.
Diffstat (limited to 'Source/WebCore/platform/mac/DragImageMac.mm')
-rw-r--r-- | Source/WebCore/platform/mac/DragImageMac.mm | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/Source/WebCore/platform/mac/DragImageMac.mm b/Source/WebCore/platform/mac/DragImageMac.mm index f444b6e..fc58173 100644 --- a/Source/WebCore/platform/mac/DragImageMac.mm +++ b/Source/WebCore/platform/mac/DragImageMac.mm @@ -28,9 +28,16 @@ #if ENABLE(DRAG_SUPPORT) #import "CachedImage.h" +#import "Font.h" +#import "FontDescription.h" +#import "FontSelector.h" +#import "GraphicsContext.h" #import "Image.h" #import "KURL.h" #import "ResourceResponse.h" +#import "Settings.h" +#import "StringTruncator.h" +#import "TextRun.h" namespace WebCore { @@ -98,7 +105,210 @@ RetainPtr<NSImage> createDragImageIconForCachedImage(CachedImage* image) return [[NSWorkspace sharedWorkspace] iconForFileType:extension]; } + + +const float DragLabelBorderX = 4; +//Keep border_y in synch with DragController::LinkDragBorderInset +const float DragLabelBorderY = 2; +const float DragLabelRadius = 5; +const float LabelBorderYOffset = 2; + +const float MinDragLabelWidthBeforeClip = 120; +const float MaxDragLabelWidth = 320; + +const float DragLinkLabelFontsize = 11; +const float DragLinkUrlFontSize = 10; + +// FIXME - we should move all the functionality of NSString extras to WebCore + +static Font& fontFromNSFont(NSFont *font) +{ + static NSFont *currentFont; + DEFINE_STATIC_LOCAL(Font, currentRenderer, ()); + + if ([font isEqual:currentFont]) + return currentRenderer; + if (currentFont) + CFRelease(currentFont); + currentFont = font; + CFRetain(currentFont); + FontPlatformData f(font, [font pointSize]); + currentRenderer = Font(f, ![[NSGraphicsContext currentContext] isDrawingToScreen]); + return currentRenderer; +} + +static bool canUseFastRenderer(const UniChar* buffer, unsigned length) +{ + unsigned i; + for (i = 0; i < length; i++) { + UCharDirection direction = u_charDirection(buffer[i]); + if (direction == U_RIGHT_TO_LEFT || direction > U_OTHER_NEUTRAL) + return false; + } + return true; +} + +static float widthWithFont(NSString *string, NSFont *font) +{ + unsigned length = [string length]; + Vector<UniChar, 2048> buffer(length); + [string getCharacters:buffer.data()]; + + if (canUseFastRenderer(buffer.data(), length)) { + Font webCoreFont(FontPlatformData(font, [font pointSize]), ![[NSGraphicsContext currentContext] isDrawingToScreen]); + TextRun run(buffer.data(), length); + run.disableRoundingHacks(); + return webCoreFont.floatWidth(run); + } + + return [string sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]].width; +} + +static inline CGFloat webkit_CGCeiling(CGFloat value) +{ + if (sizeof(value) == sizeof(float)) + return ceilf(value); + return static_cast<CGFloat>(ceil(value)); +} + +static void drawAtPoint(NSString *string, NSPoint point, NSFont *font, NSColor *textColor) +{ + unsigned length = [string length]; + Vector<UniChar, 2048> buffer(length); + + [string getCharacters:buffer.data()]; + + if (canUseFastRenderer(buffer.data(), length)) { + // The following is a half-assed attempt to match AppKit's rounding rules for drawAtPoint. + // It's probably incorrect for high DPI. + // If you change this, be sure to test all the text drawn this way in Safari, including + // the status bar, bookmarks bar, tab bar, and activity window. + point.y = webkit_CGCeiling(point.y); + + NSGraphicsContext *nsContext = [NSGraphicsContext currentContext]; + CGContextRef cgContext = static_cast<CGContextRef>([nsContext graphicsPort]); + GraphicsContext graphicsContext(cgContext); + + // Safari doesn't flip the NSGraphicsContext before calling WebKit, yet WebCore requires a flipped graphics context. + BOOL flipped = [nsContext isFlipped]; + if (!flipped) + CGContextScaleCTM(cgContext, 1, -1); + + Font webCoreFont(FontPlatformData(font, [font pointSize]), ![nsContext isDrawingToScreen], Antialiased); + TextRun run(buffer.data(), length); + run.disableRoundingHacks(); + + CGFloat red; + CGFloat green; + CGFloat blue; + CGFloat alpha; + [[textColor colorUsingColorSpaceName:NSDeviceRGBColorSpace] getRed:&red green:&green blue:&blue alpha:&alpha]; + graphicsContext.setFillColor(makeRGBA(red * 255, green * 255, blue * 255, alpha * 255), ColorSpaceDeviceRGB); + + webCoreFont.drawText(&graphicsContext, run, FloatPoint(point.x, (flipped ? point.y : (-1 * point.y)))); + + if (!flipped) + CGContextScaleCTM(cgContext, 1, -1); + } else { + // The given point is on the baseline. + if ([[NSView focusView] isFlipped]) + point.y -= [font ascender]; + else + point.y += [font descender]; + + [string drawAtPoint:point withAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, textColor, NSForegroundColorAttributeName, nil]]; + } +} + +static void drawDoubledAtPoint(NSString *string, NSPoint textPoint, NSColor *topColor, NSColor *bottomColor, NSFont *font) +{ + // turn off font smoothing so translucent text draws correctly (Radar 3118455) + drawAtPoint(string, textPoint, font, bottomColor); + + textPoint.y += 1; + drawAtPoint(string, textPoint, font, topColor); +} + +DragImageRef createDragImageForLink(KURL& url, const String& title, Frame* frame) +{ + if (!frame) + return nil; + NSString *label = 0; + if (!title.isEmpty()) + label = title; + NSURL *cocoaURL = url; + NSString *urlString = [cocoaURL absoluteString]; + + BOOL drawURLString = YES; + BOOL clipURLString = NO; + BOOL clipLabelString = NO; + + if (!label) { + drawURLString = NO; + label = urlString; + } + + NSFont *labelFont = [[NSFontManager sharedFontManager] convertFont:[NSFont systemFontOfSize:DragLinkLabelFontsize] + toHaveTrait:NSBoldFontMask]; + NSFont *urlFont = [NSFont systemFontOfSize:DragLinkUrlFontSize]; + NSSize labelSize; + labelSize.width = widthWithFont(label, labelFont); + labelSize.height = [labelFont ascender] - [labelFont descender]; + if (labelSize.width > MaxDragLabelWidth){ + labelSize.width = MaxDragLabelWidth; + clipLabelString = YES; + } + + NSSize imageSize; + imageSize.width = labelSize.width + DragLabelBorderX * 2; + imageSize.height = labelSize.height + DragLabelBorderY * 2; + if (drawURLString) { + NSSize urlStringSize; + urlStringSize.width = widthWithFont(urlString, urlFont); + urlStringSize.height = [urlFont ascender] - [urlFont descender]; + imageSize.height += urlStringSize.height; + if (urlStringSize.width > MaxDragLabelWidth) { + imageSize.width = std::max(MaxDragLabelWidth + DragLabelBorderY * 2, MinDragLabelWidthBeforeClip); + clipURLString = YES; + } else + imageSize.width = std::max(labelSize.width + DragLabelBorderX * 2, urlStringSize.width + DragLabelBorderX * 2); + } + NSImage *dragImage = [[[NSImage alloc] initWithSize: imageSize] autorelease]; + [dragImage lockFocus]; + + [[NSColor colorWithDeviceRed: 0.7f green: 0.7f blue: 0.7f alpha: 0.8f] set]; + + // Drag a rectangle with rounded corners + NSBezierPath *path = [NSBezierPath bezierPath]; + [path appendBezierPathWithOvalInRect: NSMakeRect(0, 0, DragLabelRadius * 2, DragLabelRadius * 2)]; + [path appendBezierPathWithOvalInRect: NSMakeRect(0, imageSize.height - DragLabelRadius * 2, DragLabelRadius * 2, DragLabelRadius * 2)]; + [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DragLabelRadius * 2, imageSize.height - DragLabelRadius * 2, DragLabelRadius * 2, DragLabelRadius * 2)]; + [path appendBezierPathWithOvalInRect: NSMakeRect(imageSize.width - DragLabelRadius * 2, 0, DragLabelRadius * 2, DragLabelRadius * 2)]; + + [path appendBezierPathWithRect: NSMakeRect(DragLabelRadius, 0, imageSize.width - DragLabelRadius * 2, imageSize.height)]; + [path appendBezierPathWithRect: NSMakeRect(0, DragLabelRadius, DragLabelRadius + 10, imageSize.height - 2 * DragLabelRadius)]; + [path appendBezierPathWithRect: NSMakeRect(imageSize.width - DragLabelRadius - 20, DragLabelRadius, DragLabelRadius + 20, imageSize.height - 2 * DragLabelRadius)]; + [path fill]; + + NSColor *topColor = [NSColor colorWithDeviceWhite:0.0f alpha:0.75f]; + NSColor *bottomColor = [NSColor colorWithDeviceWhite:1.0f alpha:0.5f]; + if (drawURLString) { + if (clipURLString) + urlString = StringTruncator::centerTruncate(urlString, imageSize.width - (DragLabelBorderX * 2), fontFromNSFont(urlFont)); + + drawDoubledAtPoint(urlString, NSMakePoint(DragLabelBorderX, DragLabelBorderY - [urlFont descender]), topColor, bottomColor, urlFont); + } + + if (clipLabelString) + label = StringTruncator::rightTruncate(label, imageSize.width - (DragLabelBorderX * 2), fontFromNSFont(labelFont)); + drawDoubledAtPoint(label, NSMakePoint(DragLabelBorderX, imageSize.height - LabelBorderYOffset - [labelFont pointSize]), topColor, bottomColor, labelFont); + + [dragImage unlockFocus]; + + return dragImage; +} + } // namespace WebCore #endif // ENABLE(DRAG_SUPPORT) |