Skip to content

Commit 3cd4ddf

Browse files
committed
WIP
1 parent ba58796 commit 3cd4ddf

File tree

2 files changed

+138
-1
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT

2 files changed

+138
-1
lines changed

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Image.java

+67-1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ public final class Image extends Resource implements Drawable {
135135
*/
136136
private ImageDataProvider imageDataProvider;
137137

138+
/**
139+
* ImageGcDrawer to provide a callback to draw on a GC for various zoom levels
140+
*/
141+
private ImageGcDrawer imageGcDrawer;
142+
138143
/**
139144
* Style flag used to differentiate normal, gray-scale and disabled images based
140145
* on image data providers. Without this, a normal and a disabled image of the
@@ -384,8 +389,9 @@ public Image(Device device, Image srcImage, int flag) {
384389

385390
imageFileNameProvider = srcImage.imageFileNameProvider;
386391
imageDataProvider = srcImage.imageDataProvider;
392+
imageGcDrawer = srcImage.imageGcDrawer;
387393
this.styleFlag = srcImage.styleFlag | flag;
388-
if (imageFileNameProvider != null || imageDataProvider != null) {
394+
if (imageFileNameProvider != null || imageDataProvider != null ||srcImage.imageGcDrawer != null) {
389395
/* If source image has 200% representation then create the 200% representation for the new image & apply flag */
390396
NSBitmapImageRep rep200 = srcImage.getRepresentation (200);
391397
if (rep200 != null) createRepFromSourceAndApplyFlag(rep200, srcWidth * 2, srcHeight * 2, flag);
@@ -843,6 +849,62 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
843849
}
844850
}
845851

852+
/**
853+
* The provided ImageGcDrawer will be called on demand whenever a new variant of the
854+
* Image for an additional zoom is required. Depending on the OS specific implementation
855+
* these calls will be done during the instantiation or later when a new variant is
856+
* requested
857+
* <p>
858+
*
859+
* @param device the device on which to create the image
860+
* @param imageGcDrawer the ImageGcDrawer object to be called when a new image variant
861+
* for another zoom is required.
862+
* @param width the width of the new image in points
863+
* @param height the height of the new image in points
864+
*
865+
* @exception IllegalArgumentException <ul>
866+
* <li>ERROR_NULL_ARGUMENT - if device is null and there is no current device</li>
867+
* <li>ERROR_NULL_ARGUMENT - if the ImageGcDrawer is null</li>
868+
* </ul>
869+
* @since 3.129
870+
*/
871+
public Image(Device device, ImageGcDrawer imageGcDrawer, int width, int height) {
872+
super(device);
873+
if (imageGcDrawer == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
874+
this.imageGcDrawer = imageGcDrawer;
875+
ImageData data = drawWithImageGcDrawer(imageGcDrawer, width, height, 100);
876+
if (data == null) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
877+
NSAutoreleasePool pool = null;
878+
if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init();
879+
try {
880+
init (data);
881+
init ();
882+
ImageData data2x = drawWithImageGcDrawer(imageGcDrawer, width, height, 200);
883+
if (data2x != null) {
884+
alphaInfo_200 = new AlphaInfo();
885+
NSBitmapImageRep rep = createRepresentation (data2x, alphaInfo_200);
886+
handle.addRepresentation(rep);
887+
rep.release();
888+
}
889+
} finally {
890+
if (pool != null) pool.release();
891+
}
892+
}
893+
894+
private ImageData drawWithImageGcDrawer(ImageGcDrawer imageGcDrawer, int width, int height, int zoom) {
895+
Image image = new Image(device, width, height);
896+
GC gc = new GC(image);
897+
try {
898+
imageGcDrawer.drawOn(gc);
899+
ImageData imageData = image.getImageData(zoom);
900+
imageGcDrawer.postProcess(imageData);
901+
return imageData;
902+
} finally {
903+
gc.dispose();
904+
image.dispose();
905+
}
906+
}
907+
846908
private AlphaInfo _getAlphaInfoAtCurrentZoom (NSBitmapImageRep rep) {
847909
int deviceZoom = DPIUtil.getDeviceZoom();
848910
if (deviceZoom != 100 && (imageFileNameProvider != null || imageDataProvider != null)) {
@@ -1121,6 +1183,8 @@ public boolean equals (Object object) {
11211183
return styleFlag == image.styleFlag && imageDataProvider.equals (image.imageDataProvider);
11221184
} else if (imageFileNameProvider != null && image.imageFileNameProvider != null) {
11231185
return styleFlag == image.styleFlag && imageFileNameProvider.equals (image.imageFileNameProvider);
1186+
} else if (imageGcDrawer != null && image.imageGcDrawer != null) {
1187+
return styleFlag == image.styleFlag && imageGcDrawer.equals (image.imageGcDrawer);
11241188
} else {
11251189
return handle == image.handle;
11261190
}
@@ -1357,6 +1421,8 @@ public int hashCode () {
13571421
return imageDataProvider.hashCode();
13581422
} else if (imageFileNameProvider != null) {
13591423
return imageFileNameProvider.hashCode();
1424+
} else if (imageGcDrawer != null) {
1425+
return imageGcDrawer.hashCode();
13601426
} else {
13611427
return handle != null ? (int)handle.id : 0;
13621428
}

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java

+71
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ public final class Image extends Resource implements Drawable {
151151
*/
152152
private ImageDataProvider imageDataProvider;
153153

154+
/**
155+
* ImageGcDrawer to provide a callback to draw on a GC for various zoom levels
156+
*/
157+
private ImageGcDrawer imageGcDrawer;
158+
154159
/**
155160
* Style flag used to differentiate normal, gray-scale and disabled images based
156161
* 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) {
263268
this.type = srcImage.type;
264269
this.imageDataProvider = srcImage.imageDataProvider;
265270
this.imageFileNameProvider = srcImage.imageFileNameProvider;
271+
this.imageGcDrawer = srcImage.imageGcDrawer;
266272
this.styleFlag = srcImage.styleFlag | flag;
267273
this.currentDeviceZoom = srcImage.currentDeviceZoom;
268274

@@ -661,6 +667,34 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
661667
init ();
662668
}
663669

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+
664698
/**
665699
* Refreshes the image for the current device scale factor.
666700
* <p>
@@ -722,6 +756,17 @@ boolean refreshImageForZoom () {
722756
refreshed = true;
723757
currentDeviceZoom = deviceZoomLevel;
724758
}
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+
}
725770
} else {
726771
if (!DPIUtil.useCairoAutoScale()) {
727772
int deviceZoomLevel = deviceZoom;
@@ -904,6 +949,8 @@ public boolean equals (Object object) {
904949
return (styleFlag == image.styleFlag) && imageDataProvider.equals (image.imageDataProvider);
905950
} else if (imageFileNameProvider != null && image.imageFileNameProvider != null) {
906951
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);
907954
} else {
908955
return surface == image.surface;
909956
}
@@ -1110,11 +1157,33 @@ public ImageData getImageData (int zoom) {
11101157
} else if (imageFileNameProvider != null) {
11111158
ElementAtZoom<String> fileName = DPIUtil.validateAndGetImagePathAtZoom (imageFileNameProvider, zoom);
11121159
return DPIUtil.scaleImageData (device, new ImageData (fileName.element()), zoom, fileName.zoom());
1160+
} else if (imageGcDrawer != null) {
1161+
return drawWithImageGcDrawer(zoom);
11131162
} else {
11141163
return DPIUtil.scaleImageData (device, getImageDataAtCurrentZoom (), zoom, currentDeviceZoom);
11151164
}
11161165
}
11171166

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+
11181187
/**
11191188
* Invokes platform specific functionality to allocate a new image.
11201189
* <p>
@@ -1179,6 +1248,8 @@ public int hashCode () {
11791248
return imageDataProvider.hashCode();
11801249
} else if (imageFileNameProvider != null) {
11811250
return imageFileNameProvider.hashCode();
1251+
} else if (imageGcDrawer != null) {
1252+
return imageGcDrawer.hashCode();
11821253
} else {
11831254
return (int)surface;
11841255
}

0 commit comments

Comments
 (0)