Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Keller2016-04-11 18:46:37 +0000
committerMarkus Keller2016-05-12 12:39:37 +0000
commit487efd11899ecb2796ce34f118afac7f29e65d2d (patch)
treeb40c6144554665a0aa2a8a33a114a77e789dfd54
parentcc317774a8b42e5e9aaeebb2dc41cb9c38430a23 (diff)
downloadeclipse.platform.swt-487efd11899ecb2796ce34f118afac7f29e65d2d.tar.gz
eclipse.platform.swt-487efd11899ecb2796ce34f118afac7f29e65d2d.tar.xz
eclipse.platform.swt-487efd11899ecb2796ce34f118afac7f29e65d2d.zip
Bug 493462: [HiDPI] Improve autoScale method, default deviceZoom, and system properties
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java3
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java212
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java22
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java52
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java22
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java1
9 files changed, 202 insertions, 117 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
index 1054282ffc..43da3caf15 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/CTabFolder.java
@@ -724,7 +724,7 @@ Image createButtonImage(Display display, int button) {
final ImageData imageData = image.getImageDataAtCurrentZoom();
imageData.transparentPixel = imageData.palette.getPixel(transparent);
image.dispose();
- image = new Image(display, new AutoScaleImageDataProvider(imageData, DPIUtil.getDeviceZoom()));
+ image = new Image(display, new AutoScaleImageDataProvider(display, imageData, DPIUtil.getDeviceZoom()));
return image;
}
void createItem (CTabItem item, int index) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java
index 5eb5319d21..5774b4a04e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TableDragSourceEffect.java
@@ -144,7 +144,8 @@ public class TableDragSourceEffect extends DragSourceEffect {
} else {
data.transparentPixel = shdi.crColorKey << 8;
}
- dragSourceImage = new Image(control.getDisplay(), new AutoScaleImageDataProvider(data, DPIUtil.getDeviceZoom()));
+ Display display = control.getDisplay();
+ dragSourceImage = new Image(display, new AutoScaleImageDataProvider(display, data, DPIUtil.getDeviceZoom()));
OS.SelectObject (memHdc, oldMemBitmap);
OS.DeleteDC (memHdc);
OS.DeleteObject (memDib);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java
index a0e6e99d0e..ea6f9ef13e 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/TreeDragSourceEffect.java
@@ -143,7 +143,8 @@ public class TreeDragSourceEffect extends DragSourceEffect {
} else {
data.transparentPixel = shdi.crColorKey << 8;
}
- dragSourceImage = new Image (control.getDisplay (), new AutoScaleImageDataProvider(data, DPIUtil.getDeviceZoom()));
+ Display display = control.getDisplay ();
+ dragSourceImage = new Image (display, new AutoScaleImageDataProvider(display, data, DPIUtil.getDeviceZoom()));
OS.SelectObject (memHdc, oldMemBitmap);
OS.DeleteDC (memHdc);
OS.DeleteObject (memDib);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java
index b3320fc0f5..6e0df6a655 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java
@@ -971,7 +971,7 @@ public ImageData getImageDataAtCurrentZoom() {
NSBitmapImageRep imageRep = getRepresentation();
return _getImageData(imageRep);
}
- return DPIUtil.autoScaleImageData(getImageData(), DPIUtil.getDeviceZoom(), 100);
+ return DPIUtil.autoScaleImageData(device, getImageData(), DPIUtil.getDeviceZoom(), 100);
} finally {
if (pool != null) pool.release();
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
index 60901a7bfc..90dca7fedf 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java
@@ -30,35 +30,68 @@ import org.eclipse.swt.graphics.*;
*/
public class DPIUtil {
- /* DPI Constants */
- static final int DPI_ZOOM_100 = 96;
- private static final double MIN_ZOOM_INTERVAL = 25;
+ private static final int DPI_ZOOM_100 = 96;
- private static boolean autoScaleEnable = true;
private static int deviceZoom = 100;
- /*
- * The AutoScale functionality is enabled by default on HighDPI monitors &
- * can be disabled by setting below system property to "false"(Ignore case).
+ private static enum AutoScaleMethod { AUTO, NEAREST, SMOOTH }
+ private static AutoScaleMethod autoScaleMethodSetting = AutoScaleMethod.AUTO;
+ private static AutoScaleMethod autoScaleMethod = AutoScaleMethod.NEAREST;
+
+ /**
+ * System property that controls the autoScale functionality.
+ * <ul>
+ * <li><b>false</b>: deviceZoom is set to 100%</li>
+ * <li><b>integer</b>: deviceZoom depends on the current display resolution,
+ * but only uses integer multiples of 100%. The detected native zoom is
+ * generally rounded down (e.g. at 150%, will use 100%), unless close to
+ * the next integer multiple (currently at 175%, will use 200%).</li>
+ * <li><b>quarter</b>: deviceZoom depends on the current display resolution,
+ * but only uses integer multiples of 25%. The detected native zoom is
+ * rounded to the closest permissible value.</li>
+ * <li><b>exact</b>: deviceZoom uses the native zoom (with 1% as minimal
+ * step).</li>
+ * <li><i>&lt;value&gt;</i>: deviceZoom uses the given integer value in
+ * percent as zoom level.</li>
+ * </ul>
+ * The current default is "integer".
+ */
+ private static final String SWT_AUTOSCALE = "swt.autoScale";
+
+ /**
+ * System property that controls the method for scaling images:
+ * <ul>
+ * <li>"nearest": nearest-neighbor interpolation, may look jagged</li>
+ * <li>"smooth": smooth edges, may look blurry</li>
+ * </ul>
+ * The current default is to use "nearest", except on
+ * GTK when the deviceZoom is not an integer multiple of 100%.
+ * The smooth strategy currently doesn't work on Win32 and Cocoa, see
+ * <a href="https://bugs.eclipse.org/493455">bug 493455</a>.
*/
- static final String SWT_ENABLE_AUTOSCALE = "swt.enable.autoScale";
+ private static final String SWT_AUTOSCALE_METHOD = "swt.autoScale.method";
static {
- String value = System.getProperty (SWT_ENABLE_AUTOSCALE);
- if (value != null && "false".equalsIgnoreCase (value))
- autoScaleEnable = false;
+ String value = System.getProperty (SWT_AUTOSCALE_METHOD);
+ if (value != null) {
+ if (AutoScaleMethod.NEAREST.name().equalsIgnoreCase(value)) {
+ autoScaleMethod = autoScaleMethodSetting = AutoScaleMethod.NEAREST;
+ } else if (AutoScaleMethod.SMOOTH.name().equalsIgnoreCase(value)) {
+ autoScaleMethod = autoScaleMethodSetting = AutoScaleMethod.SMOOTH;
+ }
+ }
}
/**
* Auto-scale down ImageData
*/
-public static ImageData autoScaleDown (ImageData imageData) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || imageData == null) return imageData;
- float scaleFactor = getScalingFactor ();
- return imageData.scaledTo (Math.round ((float)imageData.width / scaleFactor), Math.round ((float)imageData.height / scaleFactor));
+public static ImageData autoScaleDown (Device device, final ImageData imageData) {
+ if (deviceZoom == 100 || imageData == null) return imageData;
+ float scaleFactor = 1.0f / getScalingFactor ();
+ return autoScaleImageData(device, imageData, scaleFactor);
}
public static int[] autoScaleDown(int[] pointArray) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || pointArray == null) return pointArray;
+ if (deviceZoom == 100 || pointArray == null) return pointArray;
float scaleFactor = getScalingFactor ();
int [] returnArray = new int[pointArray.length];
for (int i = 0; i < pointArray.length; i++) {
@@ -71,7 +104,7 @@ public static int[] autoScaleDown(int[] pointArray) {
* Auto-scale up float array dimensions.
*/
public static float[] autoScaleDown (float size[]) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || size == null) return size;
+ if (deviceZoom == 100 || size == null) return size;
float scaleFactor = getScalingFactor ();
float scaledSize[] = new float[size.length];
for (int i = 0; i < scaledSize.length; i++) {
@@ -83,7 +116,7 @@ public static float[] autoScaleDown (float size[]) {
* Auto-scale down int dimensions.
*/
public static int autoScaleDown (int size) {
- if (deviceZoom == 100 || !isAutoScaleEnable ()||size == SWT.DEFAULT) return size;
+ if (deviceZoom == 100 || size == SWT.DEFAULT) return size;
float scaleFactor = getScalingFactor ();
return Math.round (size / scaleFactor);
}
@@ -91,7 +124,7 @@ public static int autoScaleDown (int size) {
* Auto-scale down float dimensions.
*/
public static float autoScaleDown (float size) {
- if (deviceZoom == 100 || !isAutoScaleEnable ()||size == SWT.DEFAULT) return size;
+ if (deviceZoom == 100 || size == SWT.DEFAULT) return size;
float scaleFactor = getScalingFactor ();
return (size / scaleFactor);
}
@@ -100,7 +133,7 @@ public static float autoScaleDown (float size) {
* Returns a new scaled down Point.
*/
public static Point autoScaleDown (Point point) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || point == null) return point;
+ if (deviceZoom == 100 || point == null) return point;
float scaleFactor = getScalingFactor ();
Point scaledPoint = new Point (0,0);
scaledPoint.x = Math.round (point.x / scaleFactor);
@@ -112,7 +145,7 @@ public static Point autoScaleDown (Point point) {
* Returns a new scaled down Rectangle.
*/
public static Rectangle autoScaleDown (Rectangle rect) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || rect == null) return rect;
+ if (deviceZoom == 100 || rect == null) return rect;
Rectangle scaledRect = new Rectangle (0,0,0,0);
Point scaledTopLeft = DPIUtil.autoScaleDown (new Point (rect.x, rect.y));
Point scaledBottomRight = DPIUtil.autoScaleDown (new Point (rect.x + rect.width, rect.y + rect.height));
@@ -127,17 +160,60 @@ public static Rectangle autoScaleDown (Rectangle rect) {
/**
* Auto-scale image with ImageData
*/
-public static ImageData autoScaleImageData (ImageData imageData, int targetZoom, int currentZoom) {
- if (!isAutoScaleEnable () || imageData == null || targetZoom == currentZoom) return imageData;
- float scaleFactor = ((float) targetZoom)/((float) currentZoom);
- return imageData.scaledTo (Math.round ((float)imageData.width * scaleFactor), Math.round ((float)imageData.height * scaleFactor));
+public static ImageData autoScaleImageData (Device device, final ImageData imageData, int targetZoom, int currentZoom) {
+ if (deviceZoom == 100 || imageData == null || targetZoom == currentZoom) return imageData;
+ float scaleFactor = (float) targetZoom / (float) currentZoom;
+ return autoScaleImageData(device, imageData, scaleFactor);
+}
+
+private static ImageData autoScaleImageData (Device device, final ImageData imageData, float scaleFactor) {
+ // Guards are already implemented in callers: if (deviceZoom == 100 || imageData == null || scaleFactor == 1.0f) return imageData;
+ int width = imageData.width;
+ int height = imageData.height;
+ int scaledWidth = Math.round ((float) width * scaleFactor);
+ int scaledHeight = Math.round ((float) height * scaleFactor);
+ switch (autoScaleMethod) {
+ case SMOOTH:
+ Image original = new Image (device, new ImageDataProvider () {
+ @Override
+ public ImageData getImageData (int zoom) {
+ return imageData;
+ }
+ });
+
+ /* Create a 24 bit image data with alpha channel */
+ final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
+ resultData.alphaData = new byte [scaledWidth * scaledHeight];
+
+ Image resultImage = new Image (device, new ImageDataProvider () {
+ @Override
+ public ImageData getImageData (int zoom) {
+ return resultData;
+ }
+ });
+ GC gc = new GC (resultImage);
+ gc.setAntialias (SWT.ON);
+ gc.drawImage (original, 0, 0, DPIUtil.autoScaleDown (width), DPIUtil.autoScaleDown (height),
+ /* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
+ * Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
+ */
+ 0, 0, Math.round (DPIUtil.autoScaleDown ((float) width * scaleFactor)), Math.round (DPIUtil.autoScaleDown ((float) height * scaleFactor)));
+ gc.dispose ();
+ original.dispose ();
+ ImageData result = resultImage.getImageDataAtCurrentZoom ();
+ resultImage.dispose ();
+ return result;
+ case NEAREST:
+ default:
+ return imageData.scaledTo (scaledWidth, scaledHeight);
+ }
}
/**
* Returns a new rectangle as per the scaleFactor.
*/
public static Rectangle autoScaleBounds (Rectangle rect, int targetZoom, int currentZoom) {
- if (!isAutoScaleEnable () || rect == null || targetZoom == currentZoom) return rect;
+ if (deviceZoom == 100 || rect == null || targetZoom == currentZoom) return rect;
float scaleFactor = ((float)targetZoom) / (float)currentZoom;
Rectangle returnRect = new Rectangle (0,0,0,0);
returnRect.x = Math.round (rect.x * scaleFactor);
@@ -150,14 +226,14 @@ public static Rectangle autoScaleBounds (Rectangle rect, int targetZoom, int cur
/**
* Auto-scale up ImageData
*/
-public static ImageData autoScaleUp (ImageData imageData) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || imageData == null) return imageData;
+public static ImageData autoScaleUp (Device device, final ImageData imageData) {
+ if (deviceZoom == 100 || imageData == null) return imageData;
float scaleFactor = getScalingFactor ();
- return imageData.scaledTo (Math.round ((float)imageData.width * scaleFactor), Math.round ((float)imageData.height * scaleFactor));
+ return autoScaleImageData(device, imageData, scaleFactor);
}
public static int[] autoScaleUp(int[] pointArray) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || pointArray == null) return pointArray;
+ if (deviceZoom == 100 || pointArray == null) return pointArray;
float scaleFactor = getScalingFactor ();
int [] returnArray = new int[pointArray.length];
for (int i = 0; i < pointArray.length; i++) {
@@ -170,13 +246,13 @@ public static int[] autoScaleUp(int[] pointArray) {
* Auto-scale up int dimensions.
*/
public static int autoScaleUp (int size) {
- if (deviceZoom == 100 || !isAutoScaleEnable ()||size == SWT.DEFAULT) return size;
+ if (deviceZoom == 100 || size == SWT.DEFAULT) return size;
float scaleFactor = getScalingFactor ();
return Math.round (size * scaleFactor);
}
public static float autoScaleUp(float size) {
- if (deviceZoom == 100 || !isAutoScaleEnable ()||size == SWT.DEFAULT) return size;
+ if (deviceZoom == 100 || size == SWT.DEFAULT) return size;
float scaleFactor = getScalingFactor ();
return (size * scaleFactor);
}
@@ -185,7 +261,7 @@ public static float autoScaleUp(float size) {
* Returns a new scaled up Point.
*/
public static Point autoScaleUp (Point point) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || point == null) return point;
+ if (deviceZoom == 100 || point == null) return point;
float scaleFactor = getScalingFactor ();
Point scaledPoint = new Point (0,0);
scaledPoint.x = Math.round (point.x * scaleFactor);
@@ -197,7 +273,7 @@ public static Point autoScaleUp (Point point) {
* Returns a new scaled up Rectangle.
*/
public static Rectangle autoScaleUp (Rectangle rect) {
- if (deviceZoom == 100 || !isAutoScaleEnable () || rect == null) return rect;
+ if (deviceZoom == 100 || rect == null) return rect;
Rectangle scaledRect = new Rectangle (0,0,0,0);
Point scaledTopLeft = DPIUtil.autoScaleUp (new Point (rect.x, rect.y));
Point scaledBottomRight = DPIUtil.autoScaleUp (new Point (rect.x + rect.width, rect.y + rect.height));
@@ -208,39 +284,24 @@ public static Rectangle autoScaleUp (Rectangle rect) {
scaledRect.height = scaledBottomRight.y - scaledTopLeft.y;
return scaledRect;
}
-public static boolean isAutoScaleEnable () {
- return autoScaleEnable;
-}
/**
* Returns Scaling factor from the display
* @return float scaling factor
*/
private static float getScalingFactor () {
- float scalingFactor = 1;
- if (isAutoScaleEnable ()) {
- scalingFactor = getDeviceZoom ()/100f;
- }
- return scalingFactor;
+ return deviceZoom / 100f;
}
/**
- * Compute the zoom value based on the scaleFactor value.
- *
- * @return zoom
- */
-public static int mapSFToZoom (float scaleFactor) {
- return mapDPIToZoom ((int) (scaleFactor * DPI_ZOOM_100));
-}
-/**
* Compute the zoom value based on the DPI value.
*
* @return zoom
*/
public static int mapDPIToZoom (int dpi) {
- double zoom = (double)dpi * 100 / DPI_ZOOM_100; //convert to percentage
- int roundedZoom = (int) (Math.round (zoom / MIN_ZOOM_INTERVAL) * MIN_ZOOM_INTERVAL); //rounding to MIN_ZOOM_INTERVAL steps
- return Math.max(100, roundedZoom); //We are setting the minimum zoom value as 100%. below that it causing too many problems
+ double zoom = (double) dpi * 100 / DPI_ZOOM_100;
+ int roundedZoom = (int) Math.round (zoom);
+ return roundedZoom;
}
/**
* Gets Image data at specified zoom level, if image is missing then
@@ -272,34 +333,59 @@ public static String validateAndGetImagePathAtZoom (ImageFileNameProvider provid
return filename;
}
-/**
- * @return the deviceZoom
- */
public static int getDeviceZoom() {
- return isAutoScaleEnable () ? deviceZoom : 100;
+ return deviceZoom;
}
-/**
- * @param deviceZoom the deviceZoom to set
- */
-public static void setDeviceZoom(int deviceZoom) {
+public static void setDeviceZoom (int nativeDeviceZoom) {
+ int deviceZoom = 0;
+ String value = System.getProperty (SWT_AUTOSCALE);
+ if (value != null) {
+ if ("false".equalsIgnoreCase (value)) {
+ deviceZoom = 100;
+ } else if ("quarter".equalsIgnoreCase (value)) {
+ deviceZoom = (int) (Math.round (nativeDeviceZoom / 25f) * 25);
+ } else if ("exact".equalsIgnoreCase (value)) {
+ deviceZoom = nativeDeviceZoom;
+ } else {
+ try {
+ int zoom = Integer.parseInt (value);
+ deviceZoom = Math.max (Math.min (zoom, 1600), 25);
+ } catch (NumberFormatException e) {
+ // unsupported value, use default
+ }
+ }
+ }
+ if (deviceZoom == 0) { // || "integer".equalsIgnoreCase (value)
+ deviceZoom = Math.max ((nativeDeviceZoom + 25) / 100 * 100, 100);
+ }
+
DPIUtil.deviceZoom = deviceZoom;
System.setProperty("org.eclipse.swt.internal.deviceZoom", Integer.toString(deviceZoom));
+ if (deviceZoom != 100 && autoScaleMethodSetting == AutoScaleMethod.AUTO) {
+ if (deviceZoom / 100 * 100 == deviceZoom || !"gtk".equals(SWT.getPlatform())) {
+ autoScaleMethod = AutoScaleMethod.NEAREST;
+ } else {
+ autoScaleMethod = AutoScaleMethod.SMOOTH;
+ }
+ }
}
/**
* AutoScale ImageDataProvider.
*/
public static final class AutoScaleImageDataProvider implements ImageDataProvider {
+ Device device;
ImageData imageData;
int currentZoom;
- public AutoScaleImageDataProvider(ImageData data, int zoom){
+ public AutoScaleImageDataProvider(Device device, ImageData data, int zoom){
+ this.device = device;
this.imageData = data;
this.currentZoom = zoom;
}
@Override
public ImageData getImageData(int zoom) {
- return DPIUtil.autoScaleImageData(imageData, zoom, currentZoom);
+ return DPIUtil.autoScaleImageData(device, imageData, zoom, currentZoom);
}
}
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
index c593caa28d..25befb40e3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java
@@ -580,7 +580,7 @@ public Image(Device device, ImageData data) {
super(device);
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
currentDeviceZoom = DPIUtil.getDeviceZoom();
- data = DPIUtil.autoScaleUp (data);
+ data = DPIUtil.autoScaleUp (device, data);
init(data);
init();
}
@@ -623,8 +623,8 @@ public Image(Device device, ImageData source, ImageData mask) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
currentDeviceZoom = DPIUtil.getDeviceZoom();
- source = DPIUtil.autoScaleUp (source);
- mask = DPIUtil.autoScaleUp (mask);
+ source = DPIUtil.autoScaleUp (device, source);
+ mask = DPIUtil.autoScaleUp (device, mask);
mask = ImageData.convertMask (mask);
ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data);
image.maskPad = mask.scanlinePad;
@@ -690,7 +690,7 @@ public Image(Device device, InputStream stream) {
super(device);
ImageData data = new ImageData(stream);
currentDeviceZoom = DPIUtil.getDeviceZoom();
- data = DPIUtil.autoScaleUp (data);
+ data = DPIUtil.autoScaleUp (device, data);
init(data);
init();
}
@@ -733,7 +733,7 @@ public Image(Device device, String filename) {
ImageData data = new ImageData(filename);
currentDeviceZoom = DPIUtil.getDeviceZoom();
- data = DPIUtil.autoScaleUp (data);
+ data = DPIUtil.autoScaleUp (device, data);
init(data);
init();
}
@@ -781,7 +781,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
}
} else {
ImageData imageData = new ImageData (filename);
- ImageData resizedData = DPIUtil.autoScaleUp (imageData);
+ ImageData resizedData = DPIUtil.autoScaleUp (device, imageData);
init(resizedData);
}
init ();
@@ -825,7 +825,7 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
if (found[0]) {
init (data);
} else {
- ImageData resizedData = DPIUtil.autoScaleUp (data);
+ ImageData resizedData = DPIUtil.autoScaleUp (device, data);
init (resizedData);
}
init ();
@@ -860,7 +860,7 @@ boolean refreshImageForZoom () {
/* Release current native resources */
destroy ();
ImageData imageData = new ImageData (filename);
- ImageData resizedData = DPIUtil.autoScaleUp (imageData);
+ ImageData resizedData = DPIUtil.autoScaleUp (device, imageData);
init(resizedData);
init ();
refreshed = true;
@@ -883,7 +883,7 @@ boolean refreshImageForZoom () {
if (!found[0]) {
/* Release current native resources */
destroy ();
- ImageData resizedData = DPIUtil.autoScaleImageData(data, deviceZoomLevel, 100);
+ ImageData resizedData = DPIUtil.autoScaleImageData(device, data, deviceZoomLevel, 100);
init(resizedData);
init();
refreshed = true;
@@ -895,7 +895,7 @@ boolean refreshImageForZoom () {
if (deviceZoomLevel != currentDeviceZoom) {
ImageData data = getImageDataAtCurrentZoom();
destroy ();
- ImageData resizedData = DPIUtil.autoScaleImageData(data, deviceZoomLevel, currentDeviceZoom);
+ ImageData resizedData = DPIUtil.autoScaleImageData(device, data, deviceZoomLevel, currentDeviceZoom);
init(resizedData);
init();
refreshed = true;
@@ -1520,7 +1520,7 @@ public ImageData getImageDataAtCurrentZoom () {
*/
ImageData getImageData (int zoom) {
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
- return DPIUtil.autoScaleImageData (getImageDataAtCurrentZoom (), zoom, currentDeviceZoom);
+ return DPIUtil.autoScaleImageData (device, getImageDataAtCurrentZoom (), zoom, currentDeviceZoom);
}
/**
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
index ad91150c4b..2c3f18a1b9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
@@ -927,8 +927,8 @@ void drawFocusInPixels (int x, int y, int width, int height) {
* </ul>
*/
public void drawImage (Image image, int x, int y) {
- x = (x != SWT.DEFAULT ? DPIUtil.autoScaleUp(x) : x);
- y = (y != SWT.DEFAULT ? DPIUtil.autoScaleUp(y) : y);
+ x = DPIUtil.autoScaleUp(x);
+ y = DPIUtil.autoScaleUp(y);
drawImageInPixels(image, x, y);
}
@@ -972,18 +972,6 @@ void drawImageInPixels(Image image, int x, int y) {
* </ul>
*/
public void drawImage (Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight) {
- srcX = (srcX != SWT.DEFAULT ? DPIUtil.autoScaleUp(srcX) : srcX);
- srcY = (srcY != SWT.DEFAULT ? DPIUtil.autoScaleUp(srcY) : srcY);
- srcWidth = (srcWidth != SWT.DEFAULT ? DPIUtil.autoScaleUp(srcWidth) : srcWidth);
- srcHeight = (srcHeight != SWT.DEFAULT ? DPIUtil.autoScaleUp(srcHeight) : srcHeight);
- destX = (destX != SWT.DEFAULT ? DPIUtil.autoScaleUp(destX) : destX);
- destY = (destY != SWT.DEFAULT ? DPIUtil.autoScaleUp(destY) : destY);
- destWidth = (destWidth != SWT.DEFAULT ? DPIUtil.autoScaleUp(destWidth) : destWidth);
- destHeight = (destHeight != SWT.DEFAULT ? DPIUtil.autoScaleUp(destHeight) : destHeight);
- drawImageInPixels(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight);
-}
-
-void drawImageInPixels(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight) {
if (handle == 0) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
if (srcWidth == 0 || srcHeight == 0 || destWidth == 0 || destHeight == 0) return;
if (srcX < 0 || srcY < 0 || srcWidth < 0 || srcHeight < 0 || destWidth < 0 || destHeight < 0) {
@@ -991,7 +979,28 @@ void drawImageInPixels(Image image, int srcX, int srcY, int srcWidth, int srcHei
}
if (image == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
if (image.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- drawImage(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight, false);
+
+ Rectangle src = DPIUtil.autoScaleUp(new Rectangle(srcX, srcY, srcWidth, srcHeight));
+ Rectangle dest = DPIUtil.autoScaleUp(new Rectangle(destX, destY, destWidth, destHeight));
+ int deviceZoom = DPIUtil.getDeviceZoom();
+ if (deviceZoom != 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.getBoundsInPixels();
+ int errX = src.x + src.width - b.width;
+ int errY = src.y + src.height - b.height;
+ if (errX != 0 || errY != 0) {
+ if (errX <= deviceZoom / 100 && errY <= deviceZoom / 100) {
+ src.intersect(b);
+ } 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);
}
void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, int destWidth, int destHeight, boolean simple) {
@@ -1213,18 +1222,7 @@ void drawBitmap(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
srcHeight = destHeight = imgHeight;
} else {
if (srcX + srcWidth > imgWidth || srcY + srcHeight > imgHeight) {
- /*
- * This is a HACK ! Due to auto-scale of dimensions at high DPI
- * display(specifically 150% zoom), rounding error of 1 pixel
- * gets introduced in srcX . Below check detects this particular
- * scenario and adjusts the dimension for 1 pixel grace value.
- */
- if (DPIUtil.isAutoScaleEnable() && DPIUtil.getDeviceZoom() > 100 && ((srcX + srcWidth - imgWidth) == 1)) {
- srcX--;
- }
- else {
- SWT.error(SWT.ERROR_INVALID_ARGUMENT);
- }
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
simple = srcX == 0 && srcY == 0 &&
srcWidth == destWidth && destWidth == imgWidth &&
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
index 1fa7ee94d1..f6b68178bc 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
@@ -495,7 +495,7 @@ public Image(Device device, ImageData data) {
super(device);
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
- data = DPIUtil.autoScaleUp (data);
+ data = DPIUtil.autoScaleUp (device, data);
init(data);
init();
}
@@ -538,8 +538,8 @@ public Image(Device device, ImageData source, ImageData mask) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
currentDeviceZoom = DPIUtil.getDeviceZoom ();
- source = DPIUtil.autoScaleUp(source);
- mask = DPIUtil.autoScaleUp(mask);
+ source = DPIUtil.autoScaleUp(device, source);
+ mask = DPIUtil.autoScaleUp(device, mask);
mask = ImageData.convertMask(mask);
init(this.device, this, source, mask);
init();
@@ -601,7 +601,7 @@ public Image(Device device, ImageData source, ImageData mask) {
public Image (Device device, InputStream stream) {
super(device);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
- ImageData data = DPIUtil.autoScaleUp(new ImageData(stream));
+ ImageData data = DPIUtil.autoScaleUp(device, new ImageData(stream));
init(data);
init();
}
@@ -642,7 +642,7 @@ public Image (Device device, String filename) {
super(device);
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
currentDeviceZoom = DPIUtil.getDeviceZoom ();
- ImageData data = DPIUtil.autoScaleUp(new ImageData(filename));
+ ImageData data = DPIUtil.autoScaleUp(device, new ImageData(filename));
init(data);
init();
}
@@ -686,7 +686,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
initNative (fileName);
if (this.handle == 0) init(new ImageData (fileName));
} else {
- ImageData resizedData = DPIUtil.autoScaleUp (new ImageData (fileName));
+ ImageData resizedData = DPIUtil.autoScaleUp (device, new ImageData (fileName));
init(resizedData);
}
init();
@@ -730,7 +730,7 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
if (found[0]) {
init(data);
} else {
- ImageData resizedData = DPIUtil.autoScaleUp(data);
+ ImageData resizedData = DPIUtil.autoScaleUp(device, data);
init (resizedData);
}
init();
@@ -760,7 +760,7 @@ boolean refreshImageForZoom () {
if (!found[0]) {
/* Release current native resources */
destroy ();
- ImageData resizedData = DPIUtil.autoScaleUp (new ImageData (filename));
+ ImageData resizedData = DPIUtil.autoScaleUp (device, new ImageData (filename));
init(resizedData);
init ();
refreshed = true;
@@ -782,7 +782,7 @@ boolean refreshImageForZoom () {
if (!found[0]) {
/* Release current native resources */
destroy ();
- ImageData resizedData = DPIUtil.autoScaleUp (data);
+ ImageData resizedData = DPIUtil.autoScaleUp (device, data);
init(resizedData);
init();
refreshed = true;
@@ -793,7 +793,7 @@ boolean refreshImageForZoom () {
if (deviceZoomLevel != currentDeviceZoom) {
ImageData data = getImageDataAtCurrentZoom();
destroy ();
- ImageData resizedData = DPIUtil.autoScaleImageData(data, deviceZoomLevel, currentDeviceZoom);
+ ImageData resizedData = DPIUtil.autoScaleImageData(device, data, deviceZoomLevel, currentDeviceZoom);
init(resizedData);
init();
refreshed = true;
@@ -1470,7 +1470,7 @@ public ImageData getImageData() {
}
ImageData getImageData (int zoom) {
- return DPIUtil.autoScaleImageData(this.getImageDataAtCurrentZoom(), zoom, currentDeviceZoom);
+ return DPIUtil.autoScaleImageData(device, this.getImageDataAtCurrentZoom(), zoom, currentDeviceZoom);
}
/**
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java
index cdf4c0cb28..a8d1dcd2fd 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java
@@ -48,7 +48,6 @@ private static final boolean BUG_492569 = SwtTestUtil.isCocoa || SwtTestUtil.isG
@Test
public void test_Constructor() {
Display disp = new Display();
- System.out.println("org.eclipse.swt.internal.DPIUtil.isAutoScaleEnable(): " + DPIUtil.isAutoScaleEnable());
System.out.println("org.eclipse.swt.internal.DPIUtil.getDeviceZoom(): " + DPIUtil.getDeviceZoom());
disp.dispose();
if (SwtTestUtil.isGTK) {

Back to the top