22
22
import org .eclipse .swt .internal .DPIUtil .*;
23
23
import org .eclipse .swt .internal .gdip .*;
24
24
import org .eclipse .swt .internal .win32 .*;
25
+ import org .eclipse .swt .widgets .*;
25
26
26
27
/**
27
28
* Instances of this class are graphics which have been prepared
@@ -363,7 +364,7 @@ public Image(Device device, ImageData data) {
363
364
super (device );
364
365
if (data == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
365
366
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
366
- data = DPIUtil . autoScaleUp (device , new ElementAtZoom <>( data , 100 ) );
367
+ data = scaleImageData (device , 100 , getZoom (), data );
367
368
init (data , getZoom ());
368
369
init ();
369
370
this .device .registerResourceWithZoomSupport (this );
@@ -407,8 +408,8 @@ public Image(Device device, ImageData source, ImageData mask) {
407
408
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
408
409
}
409
410
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
410
- source = DPIUtil . autoScaleUp (device , source );
411
- mask = DPIUtil . autoScaleUp (device , mask );
411
+ source = scaleImageData (device , 100 , getZoom () , source );
412
+ mask = scaleImageData (device , 100 , getZoom () , mask );
412
413
mask = ImageData .convertMask (mask );
413
414
init (this .device , this , source , mask , getZoom ());
414
415
init ();
@@ -471,7 +472,7 @@ public Image(Device device, ImageData source, ImageData mask) {
471
472
public Image (Device device , InputStream stream ) {
472
473
super (device );
473
474
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
474
- ImageData data = DPIUtil . autoScaleUp (device , new ElementAtZoom <>( new ImageData (stream ), 100 ));
475
+ ImageData data = scaleImageData (device , 100 , getZoom (), new ImageData (stream ));
475
476
init (data , getZoom ());
476
477
init ();
477
478
this .device .registerResourceWithZoomSupport (this );
@@ -513,7 +514,7 @@ public Image (Device device, String filename) {
513
514
super (device );
514
515
if (filename == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
515
516
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
516
- ImageData data = DPIUtil . autoScaleUp (device , new ElementAtZoom <>( new ImageData (filename ), 100 ));
517
+ ImageData data = scaleImageData (device , 100 , getZoom (), new ImageData (filename ));
517
518
init (data , getZoom ());
518
519
init ();
519
520
this .device .registerResourceWithZoomSupport (this );
@@ -559,7 +560,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
559
560
init (new ImageData (fileName .element ()), getZoom ());
560
561
}
561
562
} else {
562
- ImageData resizedData = DPIUtil . autoScaleImageData ( device , new ImageData (fileName .element ()), fileName . zoom ( ));
563
+ ImageData resizedData = scaleImageData ( device , fileName . zoom (), getZoom () , new ImageData (fileName .element ()));
563
564
init (resizedData , getZoom ());
564
565
}
565
566
init ();
@@ -600,7 +601,7 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
600
601
this .imageProvider = new ImageDataProviderWrapper (imageDataProvider );
601
602
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
602
603
ElementAtZoom <ImageData > data = DPIUtil .validateAndGetImageDataAtZoom (imageDataProvider , getZoom ());
603
- ImageData resizedData = DPIUtil . scaleImageData (device , data .element (), getZoom (), data .zoom ());
604
+ ImageData resizedData = scaleImageData (device , data .zoom (), getZoom (), data .element ());
604
605
init (resizedData , getZoom ());
605
606
init ();
606
607
this .device .registerResourceWithZoomSupport (this );
@@ -1420,7 +1421,7 @@ public ImageData getImageData (int zoom) {
1420
1421
}
1421
1422
TreeSet <Integer > availableZooms = new TreeSet <>(zoomLevelToImageHandle .keySet ());
1422
1423
int closestZoom = Optional .ofNullable (availableZooms .higher (zoom )).orElse (availableZooms .lower (zoom ));
1423
- return DPIUtil . scaleImageData (device , getImageMetadata (closestZoom ).getImageData (), zoom , closestZoom );
1424
+ return scaleImageData (device , closestZoom , zoom , getImageMetadata (closestZoom ).getImageData ());
1424
1425
}
1425
1426
1426
1427
/**
@@ -2048,6 +2049,41 @@ private void setBackground(Color color, long handle) {
2048
2049
device .internal_dispose_GC (hDC , null );
2049
2050
}
2050
2051
2052
+ private ImageData scaleImageData (Device device , int currentZoom , int targetZoom , ImageData imageData ) {
2053
+ if (imageData == null || targetZoom == currentZoom || (device != null && !device .isAutoScalable ())) return imageData ;
2054
+ float scaleFactor = (float ) targetZoom / (float ) currentZoom ;
2055
+ int width = imageData .width ;
2056
+ int height = imageData .height ;
2057
+ int scaledWidth = Math .round (width * scaleFactor );
2058
+ int scaledHeight = Math .round (height * scaleFactor );
2059
+ boolean useSmoothScaling = DPIUtil .isSmoothScalingEnabled () && imageData .getTransparencyType () != SWT .TRANSPARENCY_MASK ;
2060
+ if (useSmoothScaling ) {
2061
+ return scaleToUsingSmoothScaling (scaledWidth , scaledHeight , imageData );
2062
+ } else {
2063
+ return imageData .scaledTo (scaledWidth , scaledHeight );
2064
+ }
2065
+ }
2066
+
2067
+ private ImageData scaleToUsingSmoothScaling (int width , int height , ImageData imageData ) {
2068
+ Image original = new Image (Display .getCurrent (), (ImageDataProvider ) zoom -> imageData );
2069
+ /* Create a 24 bit image data with alpha channel */
2070
+ final ImageData resultData = new ImageData (width , height , 24 , new PaletteData (0xFF , 0xFF00 , 0xFF0000 ));
2071
+ resultData .alphaData = new byte [width * height ];
2072
+ Image resultImage = new Image (Display .getCurrent (), (ImageDataProvider ) zoom -> resultData );
2073
+ GC gc = new GC (resultImage );
2074
+ gc .setAntialias (SWT .ON );
2075
+ gc .drawImage (original , 0 , 0 , imageData .width , imageData .height ,
2076
+ /* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
2077
+ * Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
2078
+ */
2079
+ 0 , 0 , width , height , false );
2080
+ gc .dispose ();
2081
+ original .dispose ();
2082
+ ImageData result = resultImage .getImageData (resultImage .getZoom ());
2083
+ resultImage .dispose ();
2084
+ return result ;
2085
+ }
2086
+
2051
2087
private int getZoom () {
2052
2088
return DPIUtil .getZoomForAutoscaleProperty (initialNativeZoom );
2053
2089
}
@@ -2138,7 +2174,8 @@ protected Rectangle getBounds(int zoom) {
2138
2174
@ Override
2139
2175
ImageData getImageData (int zoom ) {
2140
2176
ElementAtZoom <String > fileName = DPIUtil .validateAndGetImagePathAtZoom (provider , zoom );
2141
- return DPIUtil .scaleImageData (device , new ImageData (fileName .element ()), zoom , fileName .zoom ());
2177
+ ImageData imageData = new ImageData (fileName .element ());
2178
+ return scaleImageData (device , fileName .zoom (), zoom , imageData );
2142
2179
}
2143
2180
2144
2181
@ Override
@@ -2151,7 +2188,7 @@ ImageHandle getImageMetadata(int zoom) {
2151
2188
if (imageMetadata == null ) init (imageData , zoom );
2152
2189
init ();
2153
2190
} else {
2154
- ImageData resizedData = DPIUtil . scaleImageData (device , imageData , zoom , imageCandidate .zoom ());
2191
+ ImageData resizedData = scaleImageData (device , imageCandidate .zoom (), zoom , imageData );
2155
2192
ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2156
2193
init (newData , zoom );
2157
2194
}
@@ -2201,13 +2238,13 @@ protected Rectangle getBounds(int zoom) {
2201
2238
@ Override
2202
2239
ImageData getImageData (int zoom ) {
2203
2240
ElementAtZoom <ImageData > data = DPIUtil .validateAndGetImageDataAtZoom (provider , zoom );
2204
- return DPIUtil . scaleImageData (device , data .element (), zoom , data .zoom ());
2241
+ return scaleImageData (device , data .zoom (), zoom , data .element ());
2205
2242
}
2206
2243
2207
2244
@ Override
2208
2245
ImageHandle getImageMetadata (int zoom ) {
2209
2246
ElementAtZoom <ImageData > imageCandidate = DPIUtil .validateAndGetImageDataAtZoom (provider , zoom );
2210
- ImageData resizedData = DPIUtil . scaleImageData (device , imageCandidate .element (), zoom , imageCandidate .zoom ());
2247
+ ImageData resizedData = scaleImageData (device , imageCandidate .zoom (), zoom , imageCandidate .element ());
2211
2248
ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
2212
2249
init (newData , zoom );
2213
2250
init ();
0 commit comments