| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. | |
| 3 * | |
| 4 * Redistribution and use in source and binary forms, with or without | |
| 5 * modification, are permitted provided that the following conditions | |
| 6 * are met: | |
| 7 * 1. Redistributions of source code must retain the above copyright | |
| 8 * notice, this list of conditions and the following disclaimer. | |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | |
| 10 * notice, this list of conditions and the following disclaimer in the | |
| 11 * documentation and/or other materials provided with the distribution. | |
| 12 * | |
| 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
| 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
| 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
| 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
| 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
| 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
| 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 24 */ | |
| 25 | |
| 26 #include "config.h" | |
| 27 #include "DragImage.h" | |
| 28 | |
| 29 #include "CachedImage.h" | |
| 30 #include "Font.h" | |
| 31 #include "FontCache.h" | |
| 32 #include "FontDescription.h" | |
| 33 #include "FontSelector.h" | |
| 34 #include "Frame.h" | |
| 35 #include "GraphicsContext.h" | |
| 36 #include "HWndDC.h" | |
| 37 #include "Image.h" | |
| 38 #include "Settings.h" | |
| 39 #include "StringTruncator.h" | |
| 40 #include "TextRun.h" | |
| 41 #include "WebCoreTextRenderer.h" | |
| 42 #include <wtf/RetainPtr.h> | |
| 43 | |
| 44 #include <windows.h> | |
| 45 | |
| 46 namespace WebCore { | |
| 47 | |
| 48 HBITMAP allocImage(HDC, IntSize, PlatformGraphicsContext** targetRef); | |
| 49 void deallocContext(PlatformGraphicsContext* target); | |
| 50 | |
| 51 IntSize dragImageSize(DragImageRef image) | |
| 52 { | |
| 53 if (!image) | |
| 54 return IntSize(); | |
| 55 BITMAP b; | |
| 56 GetObject(image, sizeof(BITMAP), &b); | |
| 57 return IntSize(b.bmWidth, b.bmHeight); | |
| 58 } | |
| 59 | |
| 60 void deleteDragImage(DragImageRef image) | |
| 61 { | |
| 62 if (image) | |
| 63 ::DeleteObject(image); | |
| 64 } | |
| 65 | |
| 66 DragImageRef dissolveDragImageToFraction(DragImageRef image, float) | |
| 67 { | |
| 68 //We don't do this on windows as the dragimage is blended by the OS | |
| 69 return image; | |
| 70 } | |
| 71 | |
| 72 DragImageRef createDragImageIconForCachedImage(CachedImage* image) | |
| 73 { | |
| 74 if (!image) | |
| 75 return 0; | |
| 76 | |
| 77 String filename = image->response().suggestedFilename(); | |
| 78 | |
| 79 SHFILEINFO shfi = {0}; | |
| 80 if (FAILED(SHGetFileInfo(static_cast<LPCWSTR>(filename.charactersWithNullTer
mination()), FILE_ATTRIBUTE_NORMAL, | |
| 81 &shfi, sizeof(shfi), SHGFI_ICON | SHGFI_USEFILEATTRIBUTES))) | |
| 82 return 0; | |
| 83 | |
| 84 ICONINFO iconInfo; | |
| 85 if (!GetIconInfo(shfi.hIcon, &iconInfo)) { | |
| 86 DestroyIcon(shfi.hIcon); | |
| 87 return 0; | |
| 88 } | |
| 89 | |
| 90 DestroyIcon(shfi.hIcon); | |
| 91 DeleteObject(iconInfo.hbmMask); | |
| 92 | |
| 93 return iconInfo.hbmColor; | |
| 94 } | |
| 95 | |
| 96 const float DragLabelBorderX = 4; | |
| 97 // Keep border_y in synch with DragController::LinkDragBorderInset. | |
| 98 const float DragLabelBorderY = 2; | |
| 99 const float DragLabelRadius = 5; | |
| 100 const float LabelBorderYOffset = 2; | |
| 101 | |
| 102 const float MinDragLabelWidthBeforeClip = 120; | |
| 103 const float MaxDragLabelWidth = 200; | |
| 104 const float MaxDragLabelStringWidth = (MaxDragLabelWidth - 2 * DragLabelBorderX)
; | |
| 105 | |
| 106 const float DragLinkLabelFontsize = 11; | |
| 107 const float DragLinkUrlFontSize = 10; | |
| 108 | |
| 109 static Font dragLabelFont(int size, bool bold, FontRenderingMode renderingMode) | |
| 110 { | |
| 111 Font result; | |
| 112 #if !OS(WINCE) | |
| 113 NONCLIENTMETRICS metrics; | |
| 114 metrics.cbSize = sizeof(metrics); | |
| 115 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0); | |
| 116 | |
| 117 FontDescription description; | |
| 118 description.setWeight(bold ? FontWeightBold : FontWeightNormal); | |
| 119 | |
| 120 FontFamily family; | |
| 121 family.setFamily(metrics.lfSmCaptionFont.lfFaceName); | |
| 122 description.setFamily(family); | |
| 123 description.setSpecifiedSize((float)size); | |
| 124 description.setComputedSize((float)size); | |
| 125 description.setRenderingMode(renderingMode); | |
| 126 result = Font(description, 0, 0); | |
| 127 result.update(0); | |
| 128 #endif | |
| 129 return result; | |
| 130 } | |
| 131 | |
| 132 DragImageRef createDragImageForLink(KURL& url, const String& inLabel, Frame* fra
me) | |
| 133 { | |
| 134 // This is more or less an exact match for the Mac OS X code. | |
| 135 | |
| 136 const Font* labelFont; | |
| 137 const Font* urlFont; | |
| 138 FontCachePurgePreventer fontCachePurgePreventer; | |
| 139 | |
| 140 if (frame->settings() && frame->settings()->fontRenderingMode() == Alternate
RenderingMode) { | |
| 141 static const Font alternateRenderingModeLabelFont = dragLabelFont(DragLi
nkLabelFontsize, true, AlternateRenderingMode); | |
| 142 static const Font alternateRenderingModeURLFont = dragLabelFont(DragLink
UrlFontSize, false, AlternateRenderingMode); | |
| 143 labelFont = &alternateRenderingModeLabelFont; | |
| 144 urlFont = &alternateRenderingModeURLFont; | |
| 145 } else { | |
| 146 static const Font normalRenderingModeLabelFont = dragLabelFont(DragLinkL
abelFontsize, true, NormalRenderingMode); | |
| 147 static const Font normalRenderingModeURLFont = dragLabelFont(DragLinkUrl
FontSize, false, NormalRenderingMode); | |
| 148 labelFont = &normalRenderingModeLabelFont; | |
| 149 urlFont = &normalRenderingModeURLFont; | |
| 150 } | |
| 151 | |
| 152 bool drawURLString = true; | |
| 153 bool clipURLString = false; | |
| 154 bool clipLabelString = false; | |
| 155 | |
| 156 String urlString = url.string(); | |
| 157 String label = inLabel; | |
| 158 if (label.isEmpty()) { | |
| 159 drawURLString = false; | |
| 160 label = urlString; | |
| 161 } | |
| 162 | |
| 163 // First step in drawing the link drag image width. | |
| 164 TextRun labelRun(label.impl()); | |
| 165 TextRun urlRun(urlString.impl()); | |
| 166 IntSize labelSize(labelFont->width(labelRun), labelFont->fontMetrics().ascen
t() + labelFont->fontMetrics().descent()); | |
| 167 | |
| 168 if (labelSize.width() > MaxDragLabelStringWidth) { | |
| 169 labelSize.setWidth(MaxDragLabelStringWidth); | |
| 170 clipLabelString = true; | |
| 171 } | |
| 172 | |
| 173 IntSize urlStringSize; | |
| 174 IntSize imageSize(labelSize.width() + DragLabelBorderX * 2, labelSize.height
() + DragLabelBorderY * 2); | |
| 175 | |
| 176 if (drawURLString) { | |
| 177 urlStringSize.setWidth(urlFont->width(urlRun)); | |
| 178 urlStringSize.setHeight(urlFont->fontMetrics().ascent() + urlFont->fontM
etrics().descent()); | |
| 179 imageSize.setHeight(imageSize.height() + urlStringSize.height()); | |
| 180 if (urlStringSize.width() > MaxDragLabelStringWidth) { | |
| 181 imageSize.setWidth(MaxDragLabelWidth); | |
| 182 clipURLString = true; | |
| 183 } else | |
| 184 imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()
) + DragLabelBorderX * 2); | |
| 185 } | |
| 186 | |
| 187 // We now know how big the image needs to be, so we create and | |
| 188 // fill the background | |
| 189 HBITMAP image = 0; | |
| 190 HWndDC dc(0); | |
| 191 HDC workingDC = CreateCompatibleDC(dc); | |
| 192 if (!workingDC) | |
| 193 return 0; | |
| 194 | |
| 195 PlatformGraphicsContext* contextRef; | |
| 196 image = allocImage(workingDC, imageSize, &contextRef); | |
| 197 if (!image) { | |
| 198 DeleteDC(workingDC); | |
| 199 return 0; | |
| 200 } | |
| 201 | |
| 202 SelectObject(workingDC, image); | |
| 203 GraphicsContext context(contextRef); | |
| 204 // On Mac alpha is {0.7, 0.7, 0.7, 0.8}, however we can't control alpha | |
| 205 // for drag images on win, so we use 1 | |
| 206 static const Color backgroundColor(140, 140, 140); | |
| 207 static const IntSize radii(DragLabelRadius, DragLabelRadius); | |
| 208 IntRect rect(0, 0, imageSize.width(), imageSize.height()); | |
| 209 context.fillRoundedRect(rect, radii, radii, radii, radii, backgroundColor, C
olorSpaceDeviceRGB); | |
| 210 | |
| 211 // Draw the text | |
| 212 static const Color topColor(0, 0, 0, 255); // original alpha = 0.75 | |
| 213 static const Color bottomColor(255, 255, 255, 127); // original alpha = 0.5 | |
| 214 if (drawURLString) { | |
| 215 if (clipURLString) | |
| 216 urlString = StringTruncator::rightTruncate(urlString, imageSize.widt
h() - (DragLabelBorderX * 2.0f), *urlFont, StringTruncator::EnableRoundingHacks)
; | |
| 217 IntPoint textPos(DragLabelBorderX, imageSize.height() - (LabelBorderYOff
set + urlFont->fontMetrics().descent())); | |
| 218 WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, top
Color, bottomColor); | |
| 219 } | |
| 220 | |
| 221 if (clipLabelString) | |
| 222 label = StringTruncator::rightTruncate(label, imageSize.width() - (DragL
abelBorderX * 2.0f), *labelFont, StringTruncator::EnableRoundingHacks); | |
| 223 | |
| 224 IntPoint textPos(DragLabelBorderX, DragLabelBorderY + labelFont->pixelSize()
); | |
| 225 WebCoreDrawDoubledTextAtPoint(context, label, textPos, *labelFont, topColor,
bottomColor); | |
| 226 | |
| 227 deallocContext(contextRef); | |
| 228 DeleteDC(workingDC); | |
| 229 return image; | |
| 230 } | |
| 231 | |
| 232 } | |
| OLD | NEW |