| 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 |