Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@


import java.util.*;
import java.util.List;
import java.util.function.*;
import java.util.stream.*;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.Image.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.gdip.*;
import org.eclipse.swt.internal.win32.*;
import org.eclipse.swt.widgets.*;

/**
* Class <code>GC</code> is where all of the drawing capabilities that are
Expand Down Expand Up @@ -1183,15 +1180,6 @@ void apply() {
drawImage(getImage(), source.x, source.y, source.width, source.height, destination.x, destination.y, destination.width, destination.height, gcZoom, srcImageZoom);
}

private Collection<Integer> getAllCurrentMonitorZooms() {
if (device instanceof Display display) {
return Arrays.stream(display.getMonitors())
.map(Monitor::getZoom)
.collect(Collectors.toSet());
}
return Collections.emptySet();
}

private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) {
if (srcWidth == 1 && srcHeight == 1) {
// One pixel images can use the GC zoom
Expand All @@ -1207,13 +1195,7 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d

float imageScaleFactor = 1f * destWidth / srcWidth;
int imageZoom = Math.round(gcZoom * imageScaleFactor);
if (getAllCurrentMonitorZooms().contains(imageZoom)) {
return imageZoom;
}
if (imageZoom > 150) {
return 200;
}
return 100;
return imageZoom;
}
}

Expand Down Expand Up @@ -1245,24 +1227,46 @@ private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHei
int destWidth, int destHeight, int imageZoom, int scaledImageZoom) {
Rectangle src = Win32DPIUtils.pointToPixel(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), scaledImageZoom);
Rectangle dest = Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom);
Rectangle fullImageBounds = image.getBounds();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can see image.getBounds is called above in case the zoom!=100 can you see if the hack still makes sense, It would make sense to consider if we can stream line these calls

Rectangle fullImageBoundsScaled = Win32DPIUtils.pointToPixel(drawable, fullImageBounds, scaledImageZoom);
Rectangle unscaledSrc = new Rectangle(srcX, srcY, srcWidth, srcHeight);
if (scaledImageZoom != 100) {
/*
* This is a HACK! Due to rounding errors at fractional scale factors,
* the coordinates may be slightly off. The workaround is to restrict
* coordinates to the allowed bounds.
*/
Rectangle b = image.getBounds(scaledImageZoom);
int errX = src.x + src.width - b.width;
int errY = src.y + src.height - b.height;
int errX = src.x + src.width - fullImageBoundsScaled.width;
int errY = src.y + src.height - fullImageBoundsScaled.height;
if (errX != 0 || errY != 0) {
if (errX <= scaledImageZoom / 100 && errY <= scaledImageZoom / 100) {
src.intersect(b);
src.intersect(fullImageBoundsScaled);
} else {
SWT.error (SWT.ERROR_INVALID_ARGUMENT);
}
}
}
drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false, image.getHandle(scaledImageZoom, data.nativeZoom));
image.executeOnImageHandleAtBestFittingSize((tempHandle) -> {
Rectangle newSrc = computeSourceRectangle(tempHandle, fullImageBounds, fullImageBoundsScaled, unscaledSrc, src);
drawImage(image, newSrc.x, newSrc.y, newSrc.width, newSrc.height, dest.x, dest.y, dest.width,
dest.height, false, tempHandle);
}, fullImageBoundsScaled.width, fullImageBoundsScaled.height);
}

private Rectangle computeSourceRectangle(ImageHandle imageHandle, Rectangle fullImageBounds, Rectangle fullImageBoundsScaled, Rectangle unscaledSrc, Rectangle src) {
if (new Rectangle(0, 0, imageHandle.getWidth(), imageHandle.getHeight()).equals(fullImageBoundsScaled)) {
return src;
} else {
/*
* the achieved handle with its drawings has not the required size, thus we calculate the zoom of the handle
*
* with respect to the full 100% image. The point values (x,y,width,height) of the source "part" of the full image will
* be computed to pixels by this zoom.
*/
float scaleFactor = 1f * imageHandle.getWidth() / fullImageBounds.width;
int closestZoomOfHandle = Math.round(scaleFactor * 100);
return Win32DPIUtils.pointToPixel(drawable, unscaledSrc, closestZoomOfHandle);
}
}

private class DrawImageToImageOperation extends ImageOperation {
Expand Down
Loading