@@ -151,6 +151,11 @@ public final class Image extends Resource implements Drawable {
151
151
*/
152
152
private ImageDataProvider imageDataProvider ;
153
153
154
+ /**
155
+ * ImageGcDrawer to provide a callback to draw on a GC for various zoom levels
156
+ */
157
+ private ImageGcDrawer imageGcDrawer ;
158
+
154
159
/**
155
160
* Style flag used to differentiate normal, gray-scale and disabled images based
156
161
* on image data providers. Without this, a normal and a disabled image of the
@@ -263,6 +268,7 @@ public Image(Device device, Image srcImage, int flag) {
263
268
this .type = srcImage .type ;
264
269
this .imageDataProvider = srcImage .imageDataProvider ;
265
270
this .imageFileNameProvider = srcImage .imageFileNameProvider ;
271
+ this .imageGcDrawer = srcImage .imageGcDrawer ;
266
272
this .styleFlag = srcImage .styleFlag | flag ;
267
273
this .currentDeviceZoom = srcImage .currentDeviceZoom ;
268
274
@@ -661,6 +667,34 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
661
667
init ();
662
668
}
663
669
670
+ /**
671
+ * The provided ImageGcDrawer will be called on demand whenever a new variant of the
672
+ * Image for an additional zoom is required. Depending on the OS specific implementation
673
+ * these calls will be done during the instantiation or later when a new variant is
674
+ * requested
675
+ * <p>
676
+ *
677
+ * @param device the device on which to create the image
678
+ * @param imageGcDrawer the ImageGcDrawer object to be called when a new image variant
679
+ * for another zoom is required.
680
+ * @param width the width of the new image in points
681
+ * @param height the height of the new image in points
682
+ *
683
+ * @exception IllegalArgumentException <ul>
684
+ * <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
685
+ * <li>ERROR_NULL_ARGUMENT - if the ImageGcDrawer is null</li>
686
+ * </ul>
687
+ * @since 3.129
688
+ */
689
+ public Image (Device device , ImageGcDrawer imageGcDrawer , int width , int height ) {
690
+ super (device );
691
+ this .imageGcDrawer = imageGcDrawer ;
692
+ currentDeviceZoom = DPIUtil .getDeviceZoom ();
693
+ ImageData imageData = drawWithImageGcDrawer (currentDeviceZoom );
694
+ init (imageData );
695
+ init ();
696
+ }
697
+
664
698
/**
665
699
* Refreshes the image for the current device scale factor.
666
700
* <p>
@@ -722,6 +756,17 @@ boolean refreshImageForZoom () {
722
756
refreshed = true ;
723
757
currentDeviceZoom = deviceZoomLevel ;
724
758
}
759
+ } else if (imageGcDrawer != null ) {
760
+ int deviceZoomLevel = deviceZoom ;
761
+ if (deviceZoomLevel != currentDeviceZoom ) {
762
+ ImageData data = drawWithImageGcDrawer (deviceZoomLevel );
763
+ /* Release current native resources */
764
+ destroy ();
765
+ init (data );
766
+ init ();
767
+ refreshed = true ;
768
+ currentDeviceZoom = deviceZoomLevel ;
769
+ }
725
770
} else {
726
771
if (!DPIUtil .useCairoAutoScale ()) {
727
772
int deviceZoomLevel = deviceZoom ;
@@ -904,6 +949,8 @@ public boolean equals (Object object) {
904
949
return (styleFlag == image .styleFlag ) && imageDataProvider .equals (image .imageDataProvider );
905
950
} else if (imageFileNameProvider != null && image .imageFileNameProvider != null ) {
906
951
return (styleFlag == image .styleFlag ) && imageFileNameProvider .equals (image .imageFileNameProvider );
952
+ } else if (imageGcDrawer != null && image .imageGcDrawer != null ) {
953
+ return styleFlag == image .styleFlag && imageGcDrawer .equals (image .imageGcDrawer );
907
954
} else {
908
955
return surface == image .surface ;
909
956
}
@@ -1110,11 +1157,33 @@ public ImageData getImageData (int zoom) {
1110
1157
} else if (imageFileNameProvider != null ) {
1111
1158
ElementAtZoom <String > fileName = DPIUtil .validateAndGetImagePathAtZoom (imageFileNameProvider , zoom );
1112
1159
return DPIUtil .scaleImageData (device , new ImageData (fileName .element ()), zoom , fileName .zoom ());
1160
+ } else if (imageGcDrawer != null ) {
1161
+ return drawWithImageGcDrawer (zoom );
1113
1162
} else {
1114
1163
return DPIUtil .scaleImageData (device , getImageDataAtCurrentZoom (), zoom , currentDeviceZoom );
1115
1164
}
1116
1165
}
1117
1166
1167
+
1168
+
1169
+ private ImageData drawWithImageGcDrawer (int zoom ) {
1170
+ if (this .imageGcDrawer != null ) {
1171
+ Image image = new Image (device , width , height );
1172
+ GC gc = new GC (image );
1173
+ try {
1174
+ imageGcDrawer .drawOn (gc );
1175
+ ImageData imageData = image .getImageData (zoom );
1176
+ imageGcDrawer .postProcess (imageData );
1177
+ return imageData ;
1178
+ } finally {
1179
+ gc .dispose ();
1180
+ image .dispose ();
1181
+ }
1182
+ }
1183
+ SWT .error (SWT .ERROR_INVALID_ARGUMENT , null , ": ImageGcDrawer [" + imageGcDrawer + "] is null." );
1184
+ return null ;
1185
+ }
1186
+
1118
1187
/**
1119
1188
* Invokes platform specific functionality to allocate a new image.
1120
1189
* <p>
@@ -1179,6 +1248,8 @@ public int hashCode () {
1179
1248
return imageDataProvider .hashCode ();
1180
1249
} else if (imageFileNameProvider != null ) {
1181
1250
return imageFileNameProvider .hashCode ();
1251
+ } else if (imageGcDrawer != null ) {
1252
+ return imageGcDrawer .hashCode ();
1182
1253
} else {
1183
1254
return (int )surface ;
1184
1255
}
0 commit comments