Skip to content

Commit bce0582

Browse files
committed
Move ImageData scaling logic to Image #62
This commit contributes to moving the logic for scaling the ImageData using GC from DPIUtil to Image for each platform and DPIUtil calls the platform specific code from the method DPIUtil:autoScaleImageData. contributes to #62 and #127
1 parent d4caabf commit bce0582

File tree

4 files changed

+69
-41
lines changed

4 files changed

+69
-41
lines changed

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,5 +1801,28 @@ public String toString () {
18011801
return "Image {" + handle + "}";
18021802
}
18031803

1804+
/**
1805+
* <b>IMPORTANT:</b> This method is not part of the public
1806+
* API for Image. It is marked public only so that it
1807+
* can be shared within the packages provided by SWT.
1808+
*
1809+
* Draws a scaled image using the GC by another image.
1810+
*
1811+
* @param gc the GC to draw on the resulting image
1812+
* @param original the image which is supposed to be scaled and drawn on the resulting image
1813+
* @param width the width of the original image
1814+
* @param height the height of the original image
1815+
* @param scaleFactor the factor with which the image is supposed to be scaled
1816+
*
1817+
* @noreference This method is not intended to be referenced by clients.
1818+
*/
1819+
public static void drawScaled(GC gc, Image original, int width, int height, float scaleFactor) {
1820+
gc.drawImage (original, 0, 0, DPIUtil.autoScaleDown (width), DPIUtil.autoScaleDown (height),
1821+
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1822+
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1823+
*/
1824+
0, 0, Math.round (DPIUtil.autoScaleDown (width * scaleFactor)), Math.round (DPIUtil.autoScaleDown (height * scaleFactor)));
1825+
}
1826+
18041827
}
18051828

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,7 @@ private static ImageData autoScaleImageData (Device device, final ImageData imag
312312
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
313313
GC gc = new GC (resultImage);
314314
gc.setAntialias (SWT.ON);
315-
gc.drawImage (original, 0, 0, autoScaleDown (width), autoScaleDown (height),
316-
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
317-
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
318-
*/
319-
0, 0, Math.round (autoScaleDown (width * scaleFactor)), Math.round (autoScaleDown (height * scaleFactor)));
315+
Image.drawScaled(gc, original, width, height, scaleFactor);
320316
gc.dispose ();
321317
original.dispose ();
322318
ImageData result = resultImage.getImageData (getDeviceZoom ());

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,4 +1551,27 @@ public String toString () {
15511551
return "Image {" + surface + "}";
15521552
}
15531553

1554+
/**
1555+
* <b>IMPORTANT:</b> This method is not part of the public
1556+
* API for Image. It is marked public only so that it
1557+
* can be shared within the packages provided by SWT.
1558+
*
1559+
* Draws a scaled image using the GC by another image.
1560+
*
1561+
* @param gc the GC to draw on the resulting image
1562+
* @param original the image which is supposed to be scaled and drawn on the resulting image
1563+
* @param width the width of the original image
1564+
* @param height the height of the original image
1565+
* @param scaleFactor the factor with which the image is supposed to be scaled
1566+
*
1567+
* @noreference This method is not intended to be referenced by clients.
1568+
*/
1569+
public static void drawScaled(GC gc, Image original, int width, int height, float scaleFactor) {
1570+
gc.drawImage (original, 0, 0, DPIUtil.autoScaleDown (width), DPIUtil.autoScaleDown (height),
1571+
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1572+
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1573+
*/
1574+
0, 0, Math.round (DPIUtil.autoScaleDown (width * scaleFactor)), Math.round (DPIUtil.autoScaleDown (height * scaleFactor)));
1575+
}
1576+
15541577
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,26 @@ public static long win32_getHandle (Image image, int zoom) {
823823
return image.getImageMetadata(zoom).handle;
824824
}
825825

826+
/**
827+
* <b>IMPORTANT:</b> This method is not part of the public
828+
* API for Image. It is marked public only so that it
829+
* can be shared within the packages provided by SWT.
830+
*
831+
* Draws a scaled image using the GC by another image.
832+
*
833+
* @param gc the GC to draw on the resulting image
834+
* @param original the image which is supposed to be scaled and drawn on the resulting image
835+
* @param width the width of the original image
836+
* @param height the height of the original image
837+
* @param scaleFactor the factor with which the image is supposed to be scaled
838+
*
839+
* @noreference This method is not intended to be referenced by clients.
840+
*/
841+
public static void drawScaled(GC gc, Image original, int width, int height, float scaleFactor) {
842+
gc.drawImage (original, 0, 0, width, height,
843+
0, 0, Math.round (width * scaleFactor), Math.round (height * scaleFactor), false);
844+
}
845+
826846
long [] createGdipImage() {
827847
return createGdipImage(this.getZoom());
828848
}
@@ -1254,7 +1274,7 @@ private ImageData getScaledImageData (int zoom) {
12541274
}
12551275
TreeSet<Integer> availableZooms = new TreeSet<>(zoomLevelToImageHandle.keySet());
12561276
int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom));
1257-
return scaleImageData(getImageMetadata(closestZoom).getImageData(), zoom, closestZoom);
1277+
return DPIUtil.scaleImageData (device, getImageMetadata(closestZoom).getImageData(), zoom, closestZoom);
12581278
}
12591279

12601280

@@ -1844,40 +1864,6 @@ public void setBackground(Color color) {
18441864
zoomLevelToImageHandle.values().forEach(imageHandle -> imageHandle.setBackground(backgroundColor));
18451865
}
18461866

1847-
private ImageData scaleImageData(final ImageData imageData, int targetZoom, int currentZoom) {
1848-
if (imageData == null || targetZoom == currentZoom || (device != null && !device.isAutoScalable())) return imageData;
1849-
float scaleFactor = (float) targetZoom / (float) currentZoom;
1850-
int width = imageData.width;
1851-
int height = imageData.height;
1852-
int scaledWidth = Math.round (width * scaleFactor);
1853-
int scaledHeight = Math.round (height * scaleFactor);
1854-
boolean useSmoothScaling = DPIUtil.isSmoothScalingEnabled() && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK;
1855-
if (useSmoothScaling) {
1856-
return scaleToUsingSmoothScaling(scaledWidth, scaledHeight, imageData);
1857-
}
1858-
return imageData.scaledTo (scaledWidth, scaledHeight);
1859-
}
1860-
1861-
private ImageData scaleToUsingSmoothScaling(int width, int height, ImageData imageData) {
1862-
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
1863-
/* Create a 24 bit image data with alpha channel */
1864-
final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
1865-
resultData.alphaData = new byte [width * height];
1866-
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
1867-
GC gc = new GC (resultImage);
1868-
gc.setAntialias (SWT.ON);
1869-
gc.drawImage (original, 0, 0, imageData.width, imageData.height,
1870-
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1871-
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1872-
*/
1873-
0, 0, width, height, false);
1874-
gc.dispose ();
1875-
original.dispose ();
1876-
ImageData result = resultImage.getImageData (resultImage.getZoom());
1877-
resultImage.dispose ();
1878-
return result;
1879-
}
1880-
18811867
private int getZoom() {
18821868
return DPIUtil.getZoomForAutoscaleProperty(initialNativeZoom);
18831869
}
@@ -2254,7 +2240,7 @@ final ImageHandle getImageMetadata(int zoom) {
22542240

22552241
private ImageHandle initializeHandleFromSource(int zoom) {
22562242
ElementAtZoom<ImageData> imageDataAtZoom = loadImageData(zoom);
2257-
ImageData imageData = scaleImageData(imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
2243+
ImageData imageData = DPIUtil.scaleImageData (device,imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
22582244
imageData = adaptImageDataIfDisabledOrGray(imageData);
22592245
return init(imageData, zoom);
22602246
}

0 commit comments

Comments
 (0)