DragImageRef scaleDragImage(DragImageRef image, FloatSize scale) { // FIXME: due to the way drag images are done on windows we need // to preprocess the alpha channel <rdar://problem/5015946> if (!image) return 0; IntSize srcSize = dragImageSize(image); IntSize dstSize(static_cast<int>(srcSize.width() * scale.width()), static_cast<int>(srcSize.height() * scale.height())); HBITMAP hbmp = 0; HDC dc = GetDC(0); HDC dstDC = CreateCompatibleDC(dc); if (!dstDC) goto exit; PlatformContextCairo* targetContext; hbmp = allocImage(dstDC, dstSize, &targetContext); if (!hbmp) goto exit; cairo_surface_t* srcImage = createCairoContextFromBitmap(image); // Scale the target surface to the new image size, and flip it // so that when we set the srcImage as the surface it will draw // right-side-up. cairo_t* cr = targetContext->cr(); cairo_translate(cr, 0, dstSize.height()); cairo_scale(cr, scale.width(), -scale.height()); cairo_set_source_surface(cr, srcImage, 0.0, 0.0); // Now we can paint and get the correct result cairo_paint(cr); cairo_surface_destroy(srcImage); deallocContext(targetContext); ::DeleteObject(image); image = 0; exit: if (!hbmp) hbmp = image; if (dstDC) DeleteDC(dstDC); ReleaseDC(0, dc); return hbmp; }
DragImageRef createDragImageFromImage(Image* img, RespectImageOrientationEnum) { HBITMAP hbmp = 0; HDC dc = GetDC(0); HDC workingDC = CreateCompatibleDC(dc); if (!workingDC) goto exit; PlatformContextCairo* drawContext = 0; hbmp = allocImage(workingDC, img->size(), &drawContext); if (!hbmp) goto exit; if (!drawContext) { ::DeleteObject(hbmp); hbmp = 0; } cairo_t* cr = drawContext->cr(); cairo_set_source_rgb(cr, 1.0, 0.0, 1.0); cairo_fill_preserve(cr); NativeImageCairo* srcNativeImage = img->nativeImageForCurrentFrame(); cairo_surface_t* srcImage = (srcNativeImage) ? srcNativeImage->surface() : 0; if (srcImage) { // Draw the image. cairo_set_source_surface(cr, srcImage, 0.0, 0.0); cairo_paint(cr); } deallocContext(drawContext); exit: if (workingDC) DeleteDC(workingDC); ReleaseDC(0, dc); return hbmp; }
DragImageRef createDragImageFromImage(Image* img, ImageOrientationDescription) { HBITMAP hbmp = 0; HDC dc = GetDC(0); HDC workingDC = CreateCompatibleDC(dc); if (!workingDC) goto exit; PlatformContextCairo* drawContext = 0; hbmp = allocImage(workingDC, img->size(), &drawContext); if (!hbmp) goto exit; if (!drawContext) { ::DeleteObject(hbmp); hbmp = 0; } { // This block is required due to the msvc compiler error C2362. cairo_t* cr = drawContext->cr(); cairo_set_source_rgb(cr, 1.0, 0.0, 1.0); cairo_fill_preserve(cr); RefPtr<cairo_surface_t> surface = img->nativeImageForCurrentFrame(); if (surface) { // Draw the image. cairo_set_source_surface(cr, surface.get(), 0.0, 0.0); cairo_paint(cr); } } deallocContext(drawContext); exit: if (workingDC) DeleteDC(workingDC); ReleaseDC(0, dc); return hbmp; }
DragImageRef createDragImageForLink(URL& url, const String& inLabel, FontRenderingMode fontRenderingMode) { // This is more or less an exact match for the Mac OS X code. const Font* labelFont; const Font* urlFont; FontCachePurgePreventer fontCachePurgePreventer; if (fontRenderingMode == AlternateRenderingMode) { static const Font alternateRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, AlternateRenderingMode); static const Font alternateRenderingModeURLFont = dragLabelFont(DragLinkUrlFontSize, false, AlternateRenderingMode); labelFont = &alternateRenderingModeLabelFont; urlFont = &alternateRenderingModeURLFont; } else { static const Font normalRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, NormalRenderingMode); static const Font normalRenderingModeURLFont = dragLabelFont(DragLinkUrlFontSize, false, NormalRenderingMode); labelFont = &normalRenderingModeLabelFont; urlFont = &normalRenderingModeURLFont; } bool drawURLString = true; bool clipURLString = false; bool clipLabelString = false; String urlString = url.string(); String label = inLabel; if (label.isEmpty()) { drawURLString = false; label = urlString; } // First step in drawing the link drag image width. TextRun labelRun(label.impl()); TextRun urlRun(urlString.impl()); IntSize labelSize(labelFont->width(labelRun), labelFont->fontMetrics().ascent() + labelFont->fontMetrics().descent()); if (labelSize.width() > MaxDragLabelStringWidth) { labelSize.setWidth(MaxDragLabelStringWidth); clipLabelString = true; } IntSize urlStringSize; IntSize imageSize(labelSize.width() + DragLabelBorderX * 2, labelSize.height() + DragLabelBorderY * 2); if (drawURLString) { urlStringSize.setWidth(urlFont->width(urlRun)); urlStringSize.setHeight(urlFont->fontMetrics().ascent() + urlFont->fontMetrics().descent()); imageSize.setHeight(imageSize.height() + urlStringSize.height()); if (urlStringSize.width() > MaxDragLabelStringWidth) { imageSize.setWidth(MaxDragLabelWidth); clipURLString = true; } else imageSize.setWidth(std::max(labelSize.width(), urlStringSize.width()) + DragLabelBorderX * 2); } // We now know how big the image needs to be, so we create and // fill the background HWndDC dc(0); auto workingDC = adoptGDIObject(::CreateCompatibleDC(dc)); if (!workingDC) return 0; PlatformGraphicsContext* contextRef; auto image = allocImage(workingDC.get(), imageSize, &contextRef); if (!image) return 0; ::SelectObject(workingDC.get(), image.get()); GraphicsContext context(contextRef); // On Mac alpha is {0.7, 0.7, 0.7, 0.8}, however we can't control alpha // for drag images on win, so we use 1 static const Color backgroundColor(140, 140, 140); static const IntSize radii(DragLabelRadius, DragLabelRadius); IntRect rect(0, 0, imageSize.width(), imageSize.height()); context.fillRoundedRect(FloatRoundedRect(rect, radii, radii, radii, radii), backgroundColor, ColorSpaceDeviceRGB); // Draw the text static const Color topColor(0, 0, 0, 255); // original alpha = 0.75 static const Color bottomColor(255, 255, 255, 127); // original alpha = 0.5 if (drawURLString) { if (clipURLString) urlString = StringTruncator::rightTruncate(urlString, imageSize.width() - (DragLabelBorderX * 2.0f), *urlFont, StringTruncator::EnableRoundingHacks); IntPoint textPos(DragLabelBorderX, imageSize.height() - (LabelBorderYOffset + urlFont->fontMetrics().descent())); WebCoreDrawDoubledTextAtPoint(context, urlString, textPos, *urlFont, topColor, bottomColor); } if (clipLabelString) label = StringTruncator::rightTruncate(label, imageSize.width() - (DragLabelBorderX * 2.0f), *labelFont, StringTruncator::EnableRoundingHacks); IntPoint textPos(DragLabelBorderX, DragLabelBorderY + labelFont->pixelSize()); WebCoreDrawDoubledTextAtPoint(context, label, textPos, *labelFont, topColor, bottomColor); deallocContext(contextRef); return image.leak(); }