Skip to content

Commit 2df298f

Browse files
committed
Smooth Scaling Rounding error fix for win32 #62
This commit contributes to fixing the implementation of Smooth scaling of the ImageData to get rid of the rounding errors because of multiple scale ups and downs with fractional scale factor. The commit moves and modifies the DPIUtil::autoScaleImageData method implementation in ImageData class to adapt the same. contributes to #62 and #127
1 parent 29a2ce3 commit 2df298f

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageData.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,27 @@ int getByteOrder() {
11141114
return depth != 16 ? MSB_FIRST : LSB_FIRST;
11151115
}
11161116

1117+
/**
1118+
* Returns the scaled ImageData using smooth scaling.
1119+
*
1120+
* @since 3.130
1121+
*/
1122+
public ImageData scaleToUsingSmoothScaling(Device device, int width, int height) {
1123+
Image original = new Image (device, (ImageDataProvider) zoom -> this);
1124+
/* Create a 24 bit image data with alpha channel */
1125+
final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
1126+
resultData.alphaData = new byte [width * height];
1127+
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
1128+
GC gc = new GC (resultImage);
1129+
gc.setAntialias (SWT.ON);
1130+
gc.drawImage (original, 0, 0, this.width, this.height, 0, 0, width, height, false);
1131+
gc.dispose ();
1132+
original.dispose ();
1133+
ImageData result = resultImage.getImageData (DPIUtil.getDeviceZoom());
1134+
resultImage.dispose ();
1135+
return result;
1136+
}
1137+
11171138
/**
11181139
* Returns a copy of the receiver which has been stretched or
11191140
* shrunk to the specified size. If either the width or height

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -294,26 +294,9 @@ private static ImageData autoScaleImageData (Device device, final ImageData imag
294294
int scaledHeight = Math.round (height * scaleFactor);
295295
boolean useSmoothScaling = autoScaleMethod == AutoScaleMethod.SMOOTH && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK;
296296
if (useSmoothScaling) {
297-
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
298-
/* Create a 24 bit image data with alpha channel */
299-
final ImageData resultData = new ImageData (scaledWidth, scaledHeight, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
300-
resultData.alphaData = new byte [scaledWidth * scaledHeight];
301-
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
302-
GC gc = new GC (resultImage);
303-
gc.setAntialias (SWT.ON);
304-
gc.drawImage (original, 0, 0, autoScaleDown (width), autoScaleDown (height),
305-
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
306-
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
307-
*/
308-
0, 0, Math.round (autoScaleDown (width * scaleFactor)), Math.round (autoScaleDown (height * scaleFactor)));
309-
gc.dispose ();
310-
original.dispose ();
311-
ImageData result = resultImage.getImageData (getDeviceZoom ());
312-
resultImage.dispose ();
313-
return result;
314-
} else {
315-
return imageData.scaledTo (scaledWidth, scaledHeight);
297+
return imageData.scaleToUsingSmoothScaling(device, scaledWidth, scaledHeight);
316298
}
299+
return imageData.scaledTo (scaledWidth, scaledHeight);
317300
}
318301

319302
/**

0 commit comments

Comments
 (0)