Bug 1315660 - Fixed upscaling of drag and drop thumbnail.
MozReview-Commit-ID: 9M2zIrce3Lj
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -4943,17 +4943,17 @@ PresShell::PaintRangePaintInfo(const nsT
{
nsPresContext* pc = GetPresContext();
if (!pc || aArea.width == 0 || aArea.height == 0)
return nullptr;
// use the rectangle to create the surface
nsIntRect pixelArea = aArea.ToOutsidePixels(pc->AppUnitsPerDevPixel());
- // if the image should not be resized, the scale, relative to the original image, must be 1
+ // if the image should not be resized, scale must be 1
float scale = 1.0;
nsIntRect rootScreenRect =
GetRootFrame()->GetScreenRectInAppUnits().ToNearestPixels(
pc->AppUnitsPerDevPixel());
nsRect maxSize;
pc->DeviceContext()->GetClientRect(maxSize);
@@ -4965,31 +4965,33 @@ PresShell::PaintRangePaintInfo(const nsT
if (aFlags & RENDER_IS_IMAGE) {
// get max screensize
nscoord maxWidth = pc->AppUnitsToDevPixels(maxSize.width);
nscoord maxHeight = pc->AppUnitsToDevPixels(maxSize.height);
// resize image relative to the screensize
// get best height/width relative to screensize
float bestHeight = float(maxHeight)*RELATIVE_SCALEFACTOR;
float bestWidth = float(maxWidth)*RELATIVE_SCALEFACTOR;
- // get scalefactor to reach bestWidth
- scale = bestWidth / float(pixelArea.width);
+ // calculate scale for bestWidth
+ float adjustedScale = bestWidth / float(pixelArea.width);
// get the worst height (height when width is perfect)
- float worstHeight = float(pixelArea.height)*scale;
+ float worstHeight = float(pixelArea.height)*adjustedScale;
// get the difference of best and worst height
float difference = bestHeight - worstHeight;
- // half the difference and add it to worstHeight,
- // then get scalefactor to reach this
- scale = (worstHeight + difference / 2) / float(pixelArea.height);
+ // halve the difference and add it to worstHeight to get
+ // the best compromise between bestHeight and bestWidth,
+ // then calculate the corresponding scale factor
+ adjustedScale = (worstHeight + difference / 2) / float(pixelArea.height);
+ // prevent upscaling
+ scale = std::min(scale, adjustedScale);
} else {
// get half of max screensize
nscoord maxWidth = pc->AppUnitsToDevPixels(maxSize.width >> 1);
nscoord maxHeight = pc->AppUnitsToDevPixels(maxSize.height >> 1);
if (pixelArea.width > maxWidth || pixelArea.height > maxHeight) {
- scale = 1.0;
// divide the maximum size by the image size in both directions. Whichever
// direction produces the smallest result determines how much should be
// scaled.
if (pixelArea.width > maxWidth)
scale = std::min(scale, float(maxWidth) / pixelArea.width);
if (pixelArea.height > maxHeight)
scale = std::min(scale, float(maxHeight) / pixelArea.height);
}
--- a/widget/nsBaseDragService.cpp
+++ b/widget/nsBaseDragService.cpp
@@ -662,27 +662,32 @@ nsBaseDragService::DrawDrag(nsIDOMNode*
if (renderFlags) {
nsCOMPtr<nsIDOMNode> child;
nsCOMPtr<nsIDOMNodeList> childList;
uint32_t length;
uint32_t count = 0;
nsAutoString childNodeName;
- if (NS_SUCCEEDED(dragNode->GetChildNodes(getter_AddRefs(childList))) &&
+ // check if the dragged node itself is an img element
+ if (NS_SUCCEEDED(dragNode->GetNodeName(childNodeName)) &&
+ childNodeName.LowerCaseEqualsLiteral("img")) {
+ renderFlags = renderFlags | nsIPresShell::RENDER_IS_IMAGE;
+ } else if (
+ NS_SUCCEEDED(dragNode->GetChildNodes(getter_AddRefs(childList))) &&
NS_SUCCEEDED(childList->GetLength(&length))) {
- // check every childnode for being a img-tag
+ // check every childnode for being an img element
while (count < length) {
if (NS_FAILED(childList->Item(count, getter_AddRefs(child))) ||
NS_FAILED(child->GetNodeName(childNodeName))) {
break;
}
- // here the node is checked for being a img-tag
+ // here the node is checked for being an img element
if (childNodeName.LowerCaseEqualsLiteral("img")) {
- // if the dragnnode contains a image, set RENDER_IS_IMAGE flag
+ // if the dragnode contains an image, set RENDER_IS_IMAGE flag
renderFlags = renderFlags | nsIPresShell::RENDER_IS_IMAGE;
break;
}
count++;
}
}
}
LayoutDeviceIntPoint pnt(aScreenDragRect->TopLeft());