2222import org .eclipse .swt .internal .DPIUtil .*;
2323import org .eclipse .swt .internal .gdip .*;
2424import org .eclipse .swt .internal .win32 .*;
25+ import org .eclipse .swt .widgets .*;
2526
2627/**
2728 * Instances of this class are graphics which have been prepared
@@ -363,7 +364,7 @@ public Image(Device device, ImageData data) {
363364 super (device );
364365 if (data == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
365366 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
366- data = DPIUtil . autoScaleUp (device , new ElementAtZoom <>( data , 100 ) );
367+ data = scaleImageData (device , 100 , getZoom (), data );
367368 init (data , getZoom ());
368369 init ();
369370 this .device .registerResourceWithZoomSupport (this );
@@ -407,8 +408,8 @@ public Image(Device device, ImageData source, ImageData mask) {
407408 SWT .error (SWT .ERROR_INVALID_ARGUMENT );
408409 }
409410 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 );
412413 mask = ImageData .convertMask (mask );
413414 init (this .device , this , source , mask , getZoom ());
414415 init ();
@@ -471,7 +472,7 @@ public Image(Device device, ImageData source, ImageData mask) {
471472public Image (Device device , InputStream stream ) {
472473 super (device );
473474 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 ));
475476 init (data , getZoom ());
476477 init ();
477478 this .device .registerResourceWithZoomSupport (this );
@@ -513,7 +514,7 @@ public Image (Device device, String filename) {
513514 super (device );
514515 if (filename == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
515516 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 ));
517518 init (data , getZoom ());
518519 init ();
519520 this .device .registerResourceWithZoomSupport (this );
@@ -559,7 +560,7 @@ public Image(Device device, ImageFileNameProvider imageFileNameProvider) {
559560 init (new ImageData (fileName .element ()), getZoom ());
560561 }
561562 } 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 ()));
563564 init (resizedData , getZoom ());
564565 }
565566 init ();
@@ -600,7 +601,7 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
600601 this .imageProvider = new ImageDataProviderWrapper (imageDataProvider );
601602 initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
602603 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 ());
604605 init (resizedData , getZoom ());
605606 init ();
606607 this .device .registerResourceWithZoomSupport (this );
@@ -1420,7 +1421,7 @@ public ImageData getImageData (int zoom) {
14201421 }
14211422 TreeSet <Integer > availableZooms = new TreeSet <>(zoomLevelToImageHandle .keySet ());
14221423 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 ());
14241425}
14251426
14261427/**
@@ -2048,6 +2049,41 @@ private void setBackground(Color color, long handle) {
20482049 device .internal_dispose_GC (hDC , null );
20492050}
20502051
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+
20512087private int getZoom () {
20522088 return DPIUtil .getZoomForAutoscaleProperty (initialNativeZoom );
20532089}
@@ -2138,7 +2174,8 @@ protected Rectangle getBounds(int zoom) {
21382174 @ Override
21392175 ImageData getImageData (int zoom ) {
21402176 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 );
21422179 }
21432180
21442181 @ Override
@@ -2151,7 +2188,7 @@ ImageHandle getImageMetadata(int zoom) {
21512188 if (imageMetadata == null ) init (imageData , zoom );
21522189 init ();
21532190 } else {
2154- ImageData resizedData = DPIUtil . scaleImageData (device , imageData , zoom , imageCandidate .zoom ());
2191+ ImageData resizedData = scaleImageData (device , imageCandidate .zoom (), zoom , imageData );
21552192 ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
21562193 init (newData , zoom );
21572194 }
@@ -2201,13 +2238,13 @@ protected Rectangle getBounds(int zoom) {
22012238 @ Override
22022239 ImageData getImageData (int zoom ) {
22032240 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 ());
22052242 }
22062243
22072244 @ Override
22082245 ImageHandle getImageMetadata (int zoom ) {
22092246 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 ());
22112248 ImageData newData = adaptImageDataIfDisabledOrGray (resizedData );
22122249 init (newData , zoom );
22132250 init ();
0 commit comments