@@ -372,7 +372,7 @@ public Image(Device device, ImageData data) {
372
372
if (data == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
373
373
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
374
374
int deviceZoom = getZoom ();
375
- data = DPIUtil . scaleImageData (device , new ElementAtZoom <>( data , 100 ), deviceZoom );
375
+ data = scaleImageData (data , deviceZoom , 100 );
376
376
init (data , deviceZoom );
377
377
init ();
378
378
this .device .registerResourceWithZoomSupport (this );
@@ -416,8 +416,8 @@ public Image(Device device, ImageData source, ImageData mask) {
416
416
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
417
417
}
418
418
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
419
- source = DPIUtil . autoScaleUp ( device , source );
420
- mask = DPIUtil . autoScaleUp ( device , mask );
419
+ source = scaleImageData ( source , getZoom (), 100 );
420
+ mask = scaleImageData ( mask , getZoom (), 100 );
421
421
mask = ImageData .convertMask (mask );
422
422
initIconHandle (this .device , source , mask , getZoom ());
423
423
init ();
@@ -481,7 +481,8 @@ public Image (Device device, InputStream stream) {
481
481
super (device );
482
482
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
483
483
int deviceZoom = getZoom ();
484
- ImageData data = DPIUtil .scaleImageData (device , ImageDataLoader .load (stream , FileFormat .DEFAULT_ZOOM , deviceZoom ), deviceZoom );
484
+ ElementAtZoom <ImageData > imageCandidate = ImageDataLoader .load (stream , FileFormat .DEFAULT_ZOOM , deviceZoom );
485
+ ImageData data = scaleImageData (imageCandidate .element (), deviceZoom , imageCandidate .zoom ());
485
486
init (data , deviceZoom );
486
487
init ();
487
488
this .device .registerResourceWithZoomSupport (this );
@@ -524,7 +525,8 @@ public Image (Device device, String filename) {
524
525
if (filename == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
525
526
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
526
527
int deviceZoom = getZoom ();
527
- ImageData data = DPIUtil .scaleImageData (device , ImageDataLoader .load (filename , FileFormat .DEFAULT_ZOOM , deviceZoom ), deviceZoom );
528
+ ElementAtZoom <ImageData > imageCandidate = ImageDataLoader .load (filename , FileFormat .DEFAULT_ZOOM , deviceZoom );
529
+ ImageData data = scaleImageData (imageCandidate .element (), deviceZoom , imageCandidate .zoom ());
528
530
init (data , deviceZoom );
529
531
init ();
530
532
this .device .registerResourceWithZoomSupport (this );
@@ -1264,7 +1266,7 @@ private ImageData getScaledImageData (int zoom) {
1264
1266
}
1265
1267
TreeSet <Integer > availableZooms = new TreeSet <>(zoomLevelToImageHandle .keySet ());
1266
1268
int closestZoom = Optional .ofNullable (availableZooms .higher (zoom )).orElse (availableZooms .lower (zoom ));
1267
- return DPIUtil . scaleImageData ( device , getImageMetadata (closestZoom ).getImageData (), zoom , closestZoom );
1269
+ return scaleImageData ( getImageMetadata (closestZoom ).getImageData (), zoom , closestZoom );
1268
1270
}
1269
1271
1270
1272
@@ -1854,6 +1856,40 @@ public void setBackground(Color color) {
1854
1856
zoomLevelToImageHandle .values ().forEach (imageHandle -> imageHandle .setBackground (backgroundColor ));
1855
1857
}
1856
1858
1859
+ private ImageData scaleImageData (final ImageData imageData , int targetZoom , int currentZoom ) {
1860
+ if (imageData == null || targetZoom == currentZoom || (device != null && !device .isAutoScalable ())) return imageData ;
1861
+ float scaleFactor = (float ) targetZoom / (float ) currentZoom ;
1862
+ int width = imageData .width ;
1863
+ int height = imageData .height ;
1864
+ int scaledWidth = Math .round (width * scaleFactor );
1865
+ int scaledHeight = Math .round (height * scaleFactor );
1866
+ boolean useSmoothScaling = DPIUtil .isSmoothScalingEnabled () && imageData .getTransparencyType () != SWT .TRANSPARENCY_MASK ;
1867
+ if (useSmoothScaling ) {
1868
+ return scaleToUsingSmoothScaling (scaledWidth , scaledHeight , imageData );
1869
+ }
1870
+ return imageData .scaledTo (scaledWidth , scaledHeight );
1871
+ }
1872
+
1873
+ private ImageData scaleToUsingSmoothScaling (int width , int height , ImageData imageData ) {
1874
+ Image original = new Image (device , (ImageDataProvider ) zoom -> imageData );
1875
+ /* Create a 24 bit image data with alpha channel */
1876
+ final ImageData resultData = new ImageData (width , height , 24 , new PaletteData (0xFF , 0xFF00 , 0xFF0000 ));
1877
+ resultData .alphaData = new byte [width * height ];
1878
+ Image resultImage = new Image (device , (ImageDataProvider ) zoom -> resultData );
1879
+ GC gc = new GC (resultImage );
1880
+ gc .setAntialias (SWT .ON );
1881
+ gc .drawImage (original , 0 , 0 , imageData .width , imageData .height ,
1882
+ /* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1883
+ * Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1884
+ */
1885
+ 0 , 0 , width , height , false );
1886
+ gc .dispose ();
1887
+ original .dispose ();
1888
+ ImageData result = resultImage .getImageData (resultImage .getZoom ());
1889
+ resultImage .dispose ();
1890
+ return result ;
1891
+ }
1892
+
1857
1893
private int getZoom () {
1858
1894
return DPIUtil .getZoomForAutoscaleProperty (initialNativeZoom );
1859
1895
}
@@ -2073,7 +2109,7 @@ ImageData getImageData(int zoom) {
2073
2109
2074
2110
private ImageData scaleIfNecessary (ElementAtZoom <ImageData > imageDataAtZoom , int zoom ) {
2075
2111
if (imageDataAtZoom .zoom () != zoom ) {
2076
- return DPIUtil . scaleImageData (device , imageDataAtZoom , zoom );
2112
+ return scaleImageData (imageDataAtZoom . element (), zoom , imageDataAtZoom . zoom () );
2077
2113
} else {
2078
2114
return imageDataAtZoom .element ();
2079
2115
}
@@ -2298,13 +2334,13 @@ private class ImageDataProviderWrapper extends BaseImageProviderWrapper<ImageDat
2298
2334
@ Override
2299
2335
ImageData getImageData (int zoom ) {
2300
2336
ElementAtZoom <ImageData > data = DPIUtil .validateAndGetImageDataAtZoom (provider , zoom );
2301
- return DPIUtil . scaleImageData ( device , data .element (), zoom , data .zoom ());
2337
+ return scaleImageData ( data .element (), zoom , data .zoom ());
2302
2338
}
2303
2339
2304
2340
@ Override
2305
2341
ImageHandle getImageMetadata (int zoom ) {
2306
2342
ElementAtZoom <ImageData > imageCandidate = DPIUtil .validateAndGetImageDataAtZoom (provider , zoom );
2307
- ImageData resizedData = DPIUtil . scaleImageData ( device , imageCandidate .element (), zoom , imageCandidate .zoom ());
2343
+ ImageData resizedData = scaleImageData ( imageCandidate .element (), zoom , imageCandidate .zoom ());
2308
2344
ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2309
2345
init (newData , zoom );
2310
2346
return zoomLevelToImageHandle .get (zoom );
0 commit comments