Skip to content

Commit 76a8eb4

Browse files
committed
Move ImageData scaling logic to Image #62
This commit contributes to moving the logic for scaling the ImageData from DPIUtil to Image for each platform and use their own paltform specific implementations. The method gets rid of the methods specific to scaling ImageData, which are autoScaleImageData, scaleImageData, autoScaleUp and autoScaleDown from DPIUtil. contributes to #62 and #127
1 parent 04d20e9 commit 76a8eb4

File tree

5 files changed

+142
-99
lines changed

5 files changed

+142
-99
lines changed

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

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,39 @@ public ImageData getImageData(int zoom) {
14081408
} finally {
14091409
if (pool != null) pool.release();
14101410
}
1411-
return DPIUtil.scaleImageData (device, getImageData(100), zoom, 100);
1411+
imageData imageData = getImageData(100);
1412+
return scaledTo (imageData, zoom, 100, DPIUtil.getScalingType(imageData));
1413+
}
1414+
1415+
private ImageData scaledTo(ImageData imageData, int targetZoom, int currentZoom, int scaleType) {
1416+
if (imageData == null || currentZoom == targetZoom || !device.isAutoScalable()) {
1417+
return imageData;
1418+
}
1419+
float scaleFactor = (float) targetZoom / (float) currentZoom;
1420+
int scaledWidth = Math.round (imageData.width * scaleFactor);
1421+
int scaledHeight = Math.round (imageData.height * scaleFactor);
1422+
switch (scaleType) {
1423+
case SWT.SMOOTH:
1424+
return scaleUsingSmoothScaling(imageData, scaledWidth, scaledHeight);
1425+
default:
1426+
return imageData.scaledTo(scaledWidth, scaledHeight);
1427+
}
1428+
}
1429+
1430+
private ImageData scaleUsingSmoothScaling(ImageData imageData, int width, int height) {
1431+
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
1432+
/* Create a 24 bit image data with alpha channel */
1433+
final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
1434+
resultData.alphaData = new byte [width * height];
1435+
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
1436+
GC gc = new GC (resultImage);
1437+
gc.setAntialias (SWT.ON);
1438+
gc.drawImage (original, 0, 0, imageData.width, imageData.height, 0, 0, width, height, false);
1439+
gc.dispose ();
1440+
original.dispose ();
1441+
ImageData result = resultImage.getImageData (DPIUtil.getDeviceZoom());
1442+
resultImage.dispose ();
1443+
return result;
14121444
}
14131445

14141446
/** Returns the best available representation. May be 100% or 200% iff there is an image provider. */

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

Lines changed: 14 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,6 @@ private static enum AutoScaleMethod { AUTO, NEAREST, SMOOTH }
109109
}
110110
}
111111

112-
/**
113-
* Auto-scale down ImageData
114-
*/
115-
public static ImageData autoScaleDown (Device device, final ImageData imageData) {
116-
if (deviceZoom == 100 || imageData == null || (device != null && !device.isAutoScalable())) return imageData;
117-
float scaleFactor = 1.0f / getScalingFactor (deviceZoom);
118-
return autoScaleImageData(device, imageData, scaleFactor);
119-
}
120-
121112
public static int[] autoScaleDown(int[] pointArray) {
122113
if (deviceZoom == 100 || pointArray == null) return pointArray;
123114
float scaleFactor = getScalingFactor (deviceZoom);
@@ -272,47 +263,15 @@ public static Rectangle scaleDown(Drawable drawable, Rectangle rect, int zoom) {
272263
return scaleDown (rect, zoom);
273264
}
274265

275-
/**
276-
* Auto-scale image with ImageData
277-
*/
278-
public static ImageData scaleImageData (Device device, final ImageData imageData, int targetZoom, int currentZoom) {
279-
if (imageData == null || targetZoom == currentZoom || (device != null && !device.isAutoScalable())) return imageData;
280-
float scaleFactor = (float) targetZoom / (float) currentZoom;
281-
return autoScaleImageData(device, imageData, scaleFactor);
282-
}
283-
284-
285-
public static ImageData scaleImageData (Device device, final ElementAtZoom<ImageData> elementAtZoom, int targetZoom) {
286-
return scaleImageData(device, elementAtZoom.element(), targetZoom, elementAtZoom.zoom());
287-
}
288-
289-
private static ImageData autoScaleImageData (Device device, final ImageData imageData, float scaleFactor) {
290-
// Guards are already implemented in callers: if (deviceZoom == 100 || imageData == null || scaleFactor == 1.0f) return imageData;
291-
int width = imageData.width;
292-
int height = imageData.height;
293-
int scaledWidth = Math.round (width * scaleFactor);
294-
int scaledHeight = Math.round (height * scaleFactor);
295-
boolean useSmoothScaling = autoScaleMethod == AutoScaleMethod.SMOOTH && imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK;
296-
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);
266+
public static int getScalingType(ImageData imageData) {
267+
switch(autoScaleMethod) {
268+
case SMOOTH:
269+
if (imageData.getTransparencyType() != SWT.TRANSPARENCY_MASK) {
270+
return SWT.SMOOTH;
271+
}
272+
return SWT.DEFAULT;
273+
default:
274+
return SWT.DEFAULT;
316275
}
317276
}
318277

@@ -330,22 +289,6 @@ public static Rectangle scaleBounds (Rectangle rect, int targetZoom, int current
330289
return returnRect;
331290
}
332291

333-
/**
334-
* Auto-scale ImageData to device zoom that are at given zoom factor.
335-
*/
336-
public static ImageData autoScaleImageData (Device device, final ImageData imageData, int imageDataZoomFactor) {
337-
if (deviceZoom == imageDataZoomFactor || imageData == null || (device != null && !device.isAutoScalable())) return imageData;
338-
float scaleFactor = (float) deviceZoom / imageDataZoomFactor;
339-
return autoScaleImageData(device, imageData, scaleFactor);
340-
}
341-
342-
/**
343-
* Auto-scale up ImageData to device zoom that is at 100%.
344-
*/
345-
public static ImageData autoScaleUp (Device device, final ImageData imageData) {
346-
return autoScaleImageData(device, imageData, 100);
347-
}
348-
349292
public static int[] autoScaleUp(int[] pointArray) {
350293
return scaleUp(pointArray, deviceZoom);
351294
}
@@ -738,7 +681,11 @@ public AutoScaleImageDataProvider(Device device, ImageData data, int zoom){
738681
}
739682
@Override
740683
public ImageData getImageData(int zoom) {
741-
return DPIUtil.scaleImageData(device, imageData, zoom, currentZoom);
684+
Image image = new Image(device, imageData);
685+
int adjustedZoom = (int) ((float) getDeviceZoom() / (float) currentZoom) * zoom;
686+
ImageData imageData = image.getImageData(adjustedZoom);
687+
image.dispose();
688+
return imageData;
742689
}
743690
}
744691
}

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

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ public Image(Device device, ImageData data) {
423423
super(device);
424424
if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
425425
currentDeviceZoom = DPIUtil.getDeviceZoom();
426-
data = DPIUtil.autoScaleUp (device, data);
426+
data = scaledTo(data, DPIUtil.getDeviceZoom(), 100, DPIUtil.getScalingType(data));
427427
init(data);
428428
init();
429429
}
@@ -466,8 +466,8 @@ public Image(Device device, ImageData source, ImageData mask) {
466466
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
467467
}
468468
currentDeviceZoom = DPIUtil.getDeviceZoom();
469-
source = DPIUtil.autoScaleUp (device, source);
470-
mask = DPIUtil.autoScaleUp (device, mask);
469+
source = scaledTo(source, currentDeviceZoom, 100, DPIUtil.getScalingType(source));
470+
mask = scaledTo(mask, currentDeviceZoom, 100, DPIUtil.getScalingType(mask));
471471
mask = ImageData.convertMask (mask);
472472
ImageData image = new ImageData(source.width, source.height, source.depth, source.palette, source.scanlinePad, source.data);
473473
image.maskPad = mask.scanlinePad;
@@ -533,7 +533,7 @@ public Image(Device device, InputStream stream) {
533533
super(device);
534534
currentDeviceZoom = DPIUtil.getDeviceZoom();
535535
ElementAtZoom<ImageData> image = ImageDataLoader.load(stream, FileFormat.DEFAULT_ZOOM, currentDeviceZoom);
536-
ImageData data = DPIUtil.scaleImageData(device, image, currentDeviceZoom);
536+
ImageData data = scaledTo(image.element(), currentDeviceZoom, image.zoom(), DPIUtil.getScalingType(image.element()));
537537
init(data);
538538
init();
539539
}
@@ -575,7 +575,7 @@ public Image(Device device, String filename) {
575575
if (filename == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
576576
currentDeviceZoom = DPIUtil.getDeviceZoom();
577577
ElementAtZoom<ImageData> image = ImageDataLoader.load(filename, FileFormat.DEFAULT_ZOOM, currentDeviceZoom);
578-
ImageData data = DPIUtil.scaleImageData(device, image, currentDeviceZoom);
578+
ImageData data = scaledTo(image.element(), currentDeviceZoom, image.zoom(), DPIUtil.getScalingType(image.element()));
579579
init(data);
580580
init();
581581
}
@@ -744,7 +744,7 @@ boolean refreshImageForZoom () {
744744
if (deviceZoomLevel != currentDeviceZoom) {
745745
ImageData data = getImageDataAtCurrentZoom();
746746
destroy ();
747-
ImageData resizedData = DPIUtil.scaleImageData(device, data, deviceZoomLevel, currentDeviceZoom);
747+
ImageData resizedData = scaledTo(data, deviceZoomLevel, currentDeviceZoom, DPIUtil.getScalingType(data));
748748
init(resizedData);
749749
init();
750750
refreshed = true;
@@ -778,15 +778,15 @@ private void initFromFileNameProvider(int zoom) {
778778
ElementAtZoom<ImageData> imageDataAtZoom = ImageDataLoader.load(fileForZoom.element(), fileForZoom.zoom(), zoom);
779779
ImageData imageData = imageDataAtZoom.element();
780780
if (imageDataAtZoom.zoom() != zoom) {
781-
imageData = DPIUtil.scaleImageData(device, imageDataAtZoom, zoom);
781+
imageData = scaledTo(imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom(), DPIUtil.getScalingType(imageData));
782782
}
783783
init(imageData);
784784
}
785785
}
786786

787787
private void initFromImageDataProvider(int zoom) {
788788
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom);
789-
ImageData resizedData = DPIUtil.scaleImageData (device, data.element(), zoom, data.zoom());
789+
ImageData resizedData = scaledTo(data.element(), zoom, data.zoom(), DPIUtil.getScalingType(data.element()));
790790
init(resizedData);
791791
}
792792

@@ -1146,17 +1146,50 @@ public ImageData getImageData (int zoom) {
11461146
return getImageDataAtCurrentZoom();
11471147
} else if (imageDataProvider != null) {
11481148
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (imageDataProvider, zoom);
1149-
return DPIUtil.scaleImageData (device, data.element(), zoom, data.zoom());
1149+
return scaledTo(data.element(), zoom, data.zoom(), DPIUtil.getScalingType(data.element()));
11501150
} else if (imageFileNameProvider != null) {
11511151
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, zoom);
1152-
return DPIUtil.scaleImageData (device, new ImageData (fileName.element()), zoom, fileName.zoom());
1152+
ImageData imageData = new ImageData (fileName.element());
1153+
return scaledTo(imageData, zoom, fileName.zoom(), DPIUtil.getScalingType(imageData));
11531154
} else if (imageGcDrawer != null) {
11541155
return drawWithImageGcDrawer(width, height, zoom);
11551156
} else {
1156-
return DPIUtil.scaleImageData (device, getImageDataAtCurrentZoom (), zoom, currentDeviceZoom);
1157+
ImageData imageData = getImageDataAtCurrentZoom ();
1158+
return scaledTo(imageData, zoom, currentDeviceZoom, DPIUtil.getScalingType(imageData));
11571159
}
11581160
}
11591161

1162+
private ImageData scaledTo(ImageData imageData, int targetZoom, int currentZoom, int scaleType) {
1163+
if (imageData == null || currentZoom == targetZoom || !device.isAutoScalable()) {
1164+
return imageData;
1165+
}
1166+
float scaleFactor = (float) targetZoom / (float) currentZoom;
1167+
int scaledWidth = Math.round (imageData.width * scaleFactor);
1168+
int scaledHeight = Math.round (imageData.height * scaleFactor);
1169+
switch (scaleType) {
1170+
case SWT.SMOOTH:
1171+
return scaleUsingSmoothScaling(imageData, scaledWidth, scaledHeight);
1172+
default:
1173+
return imageData.scaledTo(scaledWidth, scaledHeight);
1174+
}
1175+
}
1176+
1177+
private ImageData scaleUsingSmoothScaling(ImageData imageData, int width, int height) {
1178+
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
1179+
/* Create a 24 bit image data with alpha channel */
1180+
final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
1181+
resultData.alphaData = new byte [width * height];
1182+
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
1183+
GC gc = new GC (resultImage);
1184+
gc.setAntialias (SWT.ON);
1185+
gc.drawImage (original, 0, 0, imageData.width, imageData.height, 0, 0, width, height, false);
1186+
gc.dispose ();
1187+
original.dispose ();
1188+
ImageData result = resultImage.getImageData (DPIUtil.getDeviceZoom());
1189+
resultImage.dispose ();
1190+
return result;
1191+
}
1192+
11601193
private ImageData drawWithImageGcDrawer(int width, int height, int zoom) {
11611194
Image image = new Image(device, width, height);
11621195
GC gc = new GC(image);

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -372,15 +372,21 @@ public static Long win32_getHandle (Cursor cursor, int zoom) {
372372
if (cursor.source == null) {
373373
cursor.setHandleForZoomLevel(cursor.handle, zoom);
374374
} else {
375-
ImageData source = DPIUtil.scaleImageData(cursor.device, cursor.source, zoom, DEFAULT_ZOOM);
375+
Image image;
376+
ImageData source, mask;
377+
Cursor newCursor;
378+
image = new Image(cursor.device, cursor.source);
379+
source = image.getImageData(zoom);
380+
image.dispose();
376381
if (cursor.isIcon) {
377-
Cursor newCursor = new Cursor(cursor.device, source, cursor.hotspotX, cursor.hotspotY);
378-
cursor.setHandleForZoomLevel(newCursor.handle, zoom);
382+
newCursor = new Cursor(cursor.device, source, cursor.hotspotX, cursor.hotspotY);
379383
} else {
380-
ImageData mask = DPIUtil.scaleImageData(cursor.device, cursor.mask, zoom, DEFAULT_ZOOM);
381-
Cursor newCursor = new Cursor(cursor.device, source, mask, cursor.hotspotX, cursor.hotspotY);
382-
cursor.setHandleForZoomLevel(newCursor.handle, zoom);
384+
image = new Image(cursor.device, cursor.mask);
385+
mask = image.getImageData(zoom);
386+
image.dispose();
387+
newCursor = new Cursor(cursor.device, source, mask, cursor.hotspotX, cursor.hotspotY);
383388
}
389+
cursor.setHandleForZoomLevel(newCursor.handle, zoom);
384390
}
385391
return cursor.zoomLevelToHandle.get(zoom);
386392
}

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

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,39 @@ private ImageData getScaledImageData (int zoom) {
12651265
}
12661266
TreeSet<Integer> availableZooms = new TreeSet<>(zoomLevelToImageHandle.keySet());
12671267
int closestZoom = Optional.ofNullable(availableZooms.higher(zoom)).orElse(availableZooms.lower(zoom));
1268-
return DPIUtil.scaleImageData (device, getImageMetadata(closestZoom).getImageData(), zoom, closestZoom);
1268+
ImageData imageData = getImageMetadata(closestZoom).getImageData();
1269+
return scaledTo(imageData, zoom, closestZoom, DPIUtil.getScalingType(imageData));
1270+
}
1271+
1272+
private ImageData scaledTo(ImageData imageData, int targetZoom, int currentZoom, int scaleType) {
1273+
if (imageData == null || currentZoom == targetZoom || !device.isAutoScalable()) {
1274+
return imageData;
1275+
}
1276+
float scaleFactor = (float) targetZoom / (float) currentZoom;
1277+
int scaledWidth = Math.round (imageData.width * scaleFactor);
1278+
int scaledHeight = Math.round (imageData.height * scaleFactor);
1279+
switch (scaleType) {
1280+
case SWT.SMOOTH:
1281+
return scaleUsingSmoothScaling(imageData, scaledWidth, scaledHeight);
1282+
default:
1283+
return imageData.scaledTo(scaledWidth, scaledHeight);
1284+
}
1285+
}
1286+
1287+
private ImageData scaleUsingSmoothScaling(ImageData imageData, int width, int height) {
1288+
Image original = new Image (device, (ImageDataProvider) zoom -> imageData);
1289+
/* Create a 24 bit image data with alpha channel */
1290+
final ImageData resultData = new ImageData (width, height, 24, new PaletteData (0xFF, 0xFF00, 0xFF0000));
1291+
resultData.alphaData = new byte [width * height];
1292+
Image resultImage = new Image (device, (ImageDataProvider) zoom -> resultData);
1293+
GC gc = new GC (resultImage);
1294+
gc.setAntialias (SWT.ON);
1295+
gc.drawImage (original, 0, 0, imageData.width, imageData.height, 0, 0, width, height, false);
1296+
gc.dispose ();
1297+
original.dispose ();
1298+
ImageData result = resultImage.getImageData (resultImage.getZoom());
1299+
resultImage.dispose ();
1300+
return result;
12691301
}
12701302

12711303

@@ -1933,7 +1965,7 @@ ImageData getImageData(int zoom) {
19331965
return getScaledImageData(zoom);
19341966
}
19351967
ElementAtZoom<ImageData> loadedImageData = loadImageData(zoom);
1936-
return DPIUtil.scaleImageData(device, loadedImageData, zoom);
1968+
return scaledTo(loadedImageData.element(), zoom, loadedImageData.zoom(), DPIUtil.getScalingType(loadedImageData.element()));
19371969
}
19381970

19391971
@Override
@@ -1991,8 +2023,8 @@ protected Rectangle getBounds(int zoom) {
19912023

19922024
@Override
19932025
protected ElementAtZoom<ImageData> loadImageData(int zoom) {
1994-
ImageData scaledSource = DPIUtil.scaleImageData(device, srcAt100, zoom, 100);
1995-
ImageData scaledMask = DPIUtil.scaleImageData(device, maskAt100, zoom, 100);
2026+
ImageData scaledSource = scaledTo(srcAt100, zoom, 100, DPIUtil.getScalingType(srcAt100));
2027+
ImageData scaledMask = scaledTo(maskAt100, zoom, 100, DPIUtil.getScalingType(maskAt100));
19962028
scaledMask = ImageData.convertMask(scaledMask);
19972029
ImageData mergedData = applyMask(scaledSource, scaledMask);
19982030
return new ElementAtZoom<>(mergedData, zoom);
@@ -2192,18 +2224,11 @@ ImageData getImageData(int zoom) {
21922224
imageDataAtZoom = new ElementAtZoom<>(nativeInitializedImage.getImageData(), fileForZoom.zoom());
21932225
destroyHandleForZoom(zoom);
21942226
}
2195-
ImageData imageData = scaleIfNecessary(imageDataAtZoom, zoom);
2227+
ImageData imageData = scaledTo(imageDataAtZoom.element(), zoom, imageDataAtZoom.zoom(), DPIUtil.getScalingType(imageDataAtZoom.element()));
21962228
imageData = adaptImageDataIfDisabledOrGray(imageData);
21972229
return imageData;
21982230
}
21992231

2200-
private ImageData scaleIfNecessary(ElementAtZoom<ImageData> imageDataAtZoom, int zoom) {
2201-
if (imageDataAtZoom.zoom() != zoom) {
2202-
return DPIUtil.scaleImageData(device, imageDataAtZoom, zoom);
2203-
}
2204-
return imageDataAtZoom.element();
2205-
}
2206-
22072232
@Override
22082233
ImageHandle getImageMetadata(int zoom) {
22092234
ImageData imageData = getImageData(zoom);
@@ -2423,13 +2448,13 @@ private class ImageDataProviderWrapper extends BaseImageProviderWrapper<ImageDat
24232448
@Override
24242449
ImageData getImageData(int zoom) {
24252450
ElementAtZoom<ImageData> data = DPIUtil.validateAndGetImageDataAtZoom (provider, zoom);
2426-
return DPIUtil.scaleImageData (device, data.element(), zoom, data.zoom());
2451+
return scaledTo(data.element(), zoom, data.zoom(), DPIUtil.getScalingType(data.element()));
24272452
}
24282453

24292454
@Override
24302455
ImageHandle getImageMetadata(int zoom) {
24312456
ElementAtZoom<ImageData> imageCandidate = DPIUtil.validateAndGetImageDataAtZoom (provider, zoom);
2432-
ImageData resizedData = DPIUtil.scaleImageData (device, imageCandidate.element(), zoom, imageCandidate.zoom());
2457+
ImageData resizedData = scaledTo(imageCandidate.element(), zoom, imageCandidate.zoom(), DPIUtil.getScalingType(imageCandidate.element()));
24332458
ImageData newData = adaptImageDataIfDisabledOrGray(resizedData);
24342459
init(newData, zoom);
24352460
return zoomLevelToImageHandle.get(zoom);

0 commit comments

Comments
 (0)