Skip to content

Commit 6ff17bd

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 6ff17bd

File tree

4 files changed

+72
-41
lines changed

4 files changed

+72
-41
lines changed

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,5 +1801,29 @@ 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. However, it is not
1808+
* available on all platforms.
1809+
*
1810+
* Draws a scaled image using the GC by another image.
1811+
*
1812+
* @param gc the GC to draw on the resulting image
1813+
* @param original the image which is supposed to be scaled and drawn on the resulting image
1814+
* @param width the width of the original image
1815+
* @param height the height of the original image
1816+
* @param scaleFactor the factor with which the image is supposed to be scaled
1817+
*
1818+
* @noreference This method is not intended to be referenced by clients.
1819+
*/
1820+
public static void drawScaled(GC gc, Image original, int width, int height, float scaleFactor) {
1821+
gc.drawImage (original, 0, 0, DPIUtil.autoScaleDown (width), DPIUtil.autoScaleDown (height),
1822+
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1823+
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1824+
*/
1825+
0, 0, Math.round (DPIUtil.autoScaleDown (width * scaleFactor)), Math.round (DPIUtil.autoScaleDown (height * scaleFactor)));
1826+
}
1827+
18041828
}
18051829

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: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,4 +1551,28 @@ 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. However, it is not
1558+
* available on all platforms.
1559+
*
1560+
* Draws a scaled image using the GC by another image.
1561+
*
1562+
* @param gc the GC to draw on the resulting image
1563+
* @param original the image which is supposed to be scaled and drawn on the resulting image
1564+
* @param width the width of the original image
1565+
* @param height the height of the original image
1566+
* @param scaleFactor the factor with which the image is supposed to be scaled
1567+
*
1568+
* @noreference This method is not intended to be referenced by clients.
1569+
*/
1570+
public static void drawScaled(GC gc, Image original, int width, int height, float scaleFactor) {
1571+
gc.drawImage (original, 0, 0, DPIUtil.autoScaleDown (width), DPIUtil.autoScaleDown (height),
1572+
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1573+
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1574+
*/
1575+
0, 0, Math.round (DPIUtil.autoScaleDown (width * scaleFactor)), Math.round (DPIUtil.autoScaleDown (height * scaleFactor)));
1576+
}
1577+
15541578
}

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

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,27 @@ 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. However, it is not
830+
* available on all platforms.
831+
*
832+
* Draws a scaled image using the GC by another image.
833+
*
834+
* @param gc the GC to draw on the resulting image
835+
* @param original the image which is supposed to be scaled and drawn on the resulting image
836+
* @param width the width of the original image
837+
* @param height the height of the original image
838+
* @param scaleFactor the factor with which the image is supposed to be scaled
839+
*
840+
* @noreference This method is not intended to be referenced by clients.
841+
*/
842+
public static void drawScaled(GC gc, Image original, int width, int height, float scaleFactor) {
843+
gc.drawImage (original, 0, 0, width, height,
844+
0, 0, Math.round (width * scaleFactor), Math.round (height * scaleFactor), false);
845+
}
846+
826847
long [] createGdipImage() {
827848
return createGdipImage(this.getZoom());
828849
}
@@ -1254,7 +1275,7 @@ private ImageData getScaledImageData (int zoom) {
12541275
}
12551276
TreeSet<Integer> availableZooms = new TreeSet<>(zoomLevelToImageHandle.keySet());
12561277
int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom));
1257-
return scaleImageData(getImageMetadata(closestZoom).getImageData(), zoom, closestZoom);
1278+
return DPIUtil.scaleImageData (device, getImageMetadata(closestZoom).getImageData(), zoom, closestZoom);
12581279
}
12591280

12601281

@@ -1844,40 +1865,6 @@ public void setBackground(Color color) {
18441865
zoomLevelToImageHandle.values().forEach(imageHandle -> imageHandle.setBackground(backgroundColor));
18451866
}
18461867

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-
18811868
private int getZoom() {
18821869
return DPIUtil.getZoomForAutoscaleProperty(initialNativeZoom);
18831870
}
@@ -2254,7 +2241,7 @@ final ImageHandle getImageMetadata(int zoom) {
22542241

22552242
private ImageHandle initializeHandleFromSource(int zoom) {
22562243
ElementAtZoom<ImageData> imageDataAtZoom = loadImageData(zoom);
2257-
ImageData imageData = scaleImageData(imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
2244+
ImageData imageData = DPIUtil.scaleImageData (device,imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom());
22582245
imageData = adaptImageDataIfDisabledOrGray(imageData);
22592246
return init(imageData, zoom);
22602247
}

0 commit comments

Comments
 (0)