@@ -371,9 +371,7 @@ public Image(Device device, ImageData data) {
371
371
super (device );
372
372
if (data == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
373
373
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
374
- int deviceZoom = getZoom ();
375
- data = scaleImageData (data , deviceZoom , 100 );
376
- init (data , deviceZoom );
374
+ this .imageProvider = new PlainImageDataProviderWrapper (data );
377
375
init ();
378
376
this .device .registerResourceWithZoomSupport (this );
379
377
}
@@ -416,10 +414,7 @@ public Image(Device device, ImageData source, ImageData mask) {
416
414
SWT .error (SWT .ERROR_INVALID_ARGUMENT );
417
415
}
418
416
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
419
- source = scaleImageData (source , getZoom (), 100 );
420
- mask = scaleImageData (mask , getZoom (), 100 );
421
- mask = ImageData .convertMask (mask );
422
- initIconHandle (this .device , source , mask , getZoom ());
417
+ this .imageProvider = new MaskedImageDataProviderWrapper (source , mask );
423
418
init ();
424
419
this .device .registerResourceWithZoomSupport (this );
425
420
}
@@ -479,11 +474,9 @@ public Image(Device device, ImageData source, ImageData mask) {
479
474
*/
480
475
public Image (Device device , InputStream stream ) {
481
476
super (device );
477
+ if (stream == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
482
478
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
483
- int deviceZoom = getZoom ();
484
- ElementAtZoom <ImageData > imageCandidate = ImageDataLoader .load (stream , FileFormat .DEFAULT_ZOOM , deviceZoom );
485
- ImageData data = scaleImageData (imageCandidate .element (), deviceZoom , imageCandidate .zoom ());
486
- init (data , deviceZoom );
479
+ this .imageProvider = new ImageDataLoaderStreamProviderWrapper (stream );
487
480
init ();
488
481
this .device .registerResourceWithZoomSupport (this );
489
482
}
@@ -524,10 +517,16 @@ public Image (Device device, String filename) {
524
517
super (device );
525
518
if (filename == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
526
519
initialNativeZoom = DPIUtil .getNativeDeviceZoom ();
527
- int deviceZoom = getZoom ();
528
- ElementAtZoom <ImageData > imageCandidate = ImageDataLoader .load (filename , FileFormat .DEFAULT_ZOOM , deviceZoom );
529
- ImageData data = scaleImageData (imageCandidate .element (), deviceZoom , imageCandidate .zoom ());
530
- init (data , deviceZoom );
520
+ this .imageProvider = new ImageFileNameProviderWrapper (zoom -> {
521
+ if (zoom == 100 ) {
522
+ return filename ;
523
+ }
524
+ return null ;
525
+ });
526
+ if (imageProvider .getImageData (100 ) == null ) {
527
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null ,
528
+ ": [" + filename + "] returns null ImageData at 100% zoom." );
529
+ }
531
530
init ();
532
531
this .device .registerResourceWithZoomSupport (this );
533
532
}
@@ -1947,6 +1946,131 @@ protected void destroy() {
1947
1946
}
1948
1947
}
1949
1948
1949
+ private abstract class ImageFromImageDataProviderWrapper extends AbstractImageProviderWrapper {
1950
+
1951
+ protected abstract ElementAtZoom <ImageData > loadImageData (int zoom );
1952
+
1953
+ void initImage () {
1954
+ // As the init call configured some Image attributes (e.g. type)
1955
+ // it must be called
1956
+ ImageData imageDataAt100 = getImageData (100 );
1957
+ init (imageDataAt100 , 100 );
1958
+ destroyHandleForZoom (100 );
1959
+ }
1960
+
1961
+ @ Override
1962
+ ImageData getImageData (int zoom ) {
1963
+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1964
+ return zoomLevelToImageHandle .get (zoom ).getImageData ();
1965
+ }
1966
+ if (!zoomLevelToImageHandle .isEmpty ()) {
1967
+ return getScaledImageData (zoom );
1968
+ }
1969
+ ElementAtZoom <ImageData > loadedImageData = loadImageData (zoom );
1970
+ return DPIUtil .scaleImageData (device , loadedImageData , zoom );
1971
+ }
1972
+
1973
+ @ Override
1974
+ ImageHandle getImageMetadata (int zoom ) {
1975
+ if (zoomLevelToImageHandle .containsKey (zoom )) {
1976
+ return zoomLevelToImageHandle .get (zoom );
1977
+ } else {
1978
+ ImageData scaledImageData = getImageData (zoom );
1979
+ ImageHandle imageHandle = init (scaledImageData , zoom );
1980
+ return imageHandle ;
1981
+ }
1982
+ }
1983
+ }
1984
+
1985
+ private class PlainImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
1986
+ private ImageData imageDataAt100 ;
1987
+
1988
+ PlainImageDataProviderWrapper (ImageData imageData ) {
1989
+ this .imageDataAt100 = (ImageData ) imageData .clone ();
1990
+ initImage ();
1991
+ }
1992
+
1993
+ @ Override
1994
+ protected Rectangle getBounds (int zoom ) {
1995
+ Rectangle rectangle = new Rectangle (0 , 0 , imageDataAt100 .width , imageDataAt100 .height );
1996
+ return DPIUtil .scaleUp (rectangle , zoom );
1997
+ }
1998
+
1999
+ @ Override
2000
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2001
+ return new ElementAtZoom <>(imageDataAt100 , 100 );
2002
+ }
2003
+
2004
+ @ Override
2005
+ AbstractImageProviderWrapper createCopy (Image image ) {
2006
+ return image .new PlainImageDataProviderWrapper (this .imageDataAt100 );
2007
+ }
2008
+ }
2009
+
2010
+ private class MaskedImageDataProviderWrapper extends ImageFromImageDataProviderWrapper {
2011
+ private final ImageData srcAt100 ;
2012
+ private final ImageData maskAt100 ;
2013
+
2014
+ MaskedImageDataProviderWrapper (ImageData srcAt100 , ImageData maskAt100 ) {
2015
+ this .srcAt100 = (ImageData ) srcAt100 .clone ();
2016
+ this .maskAt100 = (ImageData ) maskAt100 .clone ();
2017
+ initImage ();
2018
+ }
2019
+
2020
+ @ Override
2021
+ protected Rectangle getBounds (int zoom ) {
2022
+ Rectangle rectangle = new Rectangle (0 , 0 , srcAt100 .width , srcAt100 .height );
2023
+ return DPIUtil .scaleUp (rectangle , zoom );
2024
+ }
2025
+
2026
+ @ Override
2027
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2028
+ ImageData scaledSource = DPIUtil .scaleImageData (device , srcAt100 , zoom , 100 );
2029
+ ImageData scaledMask = DPIUtil .scaleImageData (device , maskAt100 , zoom , 100 );
2030
+ scaledMask = ImageData .convertMask (scaledMask );
2031
+ ImageData mergedData = applyMask (scaledSource , scaledMask );
2032
+ return new ElementAtZoom <>(mergedData , zoom );
2033
+ }
2034
+
2035
+ @ Override
2036
+ AbstractImageProviderWrapper createCopy (Image image ) {
2037
+ return image .new MaskedImageDataProviderWrapper (this .srcAt100 , this .maskAt100 );
2038
+ }
2039
+ }
2040
+
2041
+ private class ImageDataLoaderStreamProviderWrapper extends ImageFromImageDataProviderWrapper {
2042
+ private byte [] inputStreamData ;
2043
+
2044
+ ImageDataLoaderStreamProviderWrapper (InputStream inputStream ) {
2045
+ try {
2046
+ this .inputStreamData = inputStream .readAllBytes ();
2047
+ initImage ();
2048
+ } catch (IOException e ) {
2049
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , e );
2050
+ }
2051
+ }
2052
+
2053
+ private ImageDataLoaderStreamProviderWrapper (byte [] inputStreamData ) {
2054
+ this .inputStreamData = inputStreamData ;
2055
+ }
2056
+
2057
+ @ Override
2058
+ protected ElementAtZoom <ImageData > loadImageData (int zoom ) {
2059
+ return ImageDataLoader .load (new ByteArrayInputStream (inputStreamData ), FileFormat .DEFAULT_ZOOM , zoom );
2060
+ }
2061
+
2062
+ @ Override
2063
+ protected Rectangle getBounds (int zoom ) {
2064
+ ImageData scaledImageData = getImageData (zoom );
2065
+ return new Rectangle (0 , 0 , scaledImageData .width , scaledImageData .height );
2066
+ }
2067
+
2068
+ @ Override
2069
+ AbstractImageProviderWrapper createCopy (Image image ) {
2070
+ return new ImageDataLoaderStreamProviderWrapper (inputStreamData );
2071
+ }
2072
+ }
2073
+
1950
2074
private class PlainImageProviderWrapper extends AbstractImageProviderWrapper {
1951
2075
private final int width ;
1952
2076
private final int height ;
0 commit comments