Skip to content

Commit d1d3862

Browse files
committed
Update ImageDataProvider contract
Clarify in the contract that ImageDataProvider implementations are expected to return linearly scaled ImageData based on the zoom level. This commit also extends the strict checks for verifying linear scaling to GTK and Cocoa implementations.
1 parent 9eea8f6 commit d1d3862

File tree

9 files changed

+57
-30
lines changed

9 files changed

+57
-30
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
*/
2828
public abstract class Device implements Drawable {
2929

30+
protected static boolean strictChecks = System.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
3031
/* Debugging */
3132
public static boolean DEBUG;
3233
boolean debug = DEBUG;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,9 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
850850
try {
851851
init (data, 100);
852852
init ();
853+
if (Device.strictChecks) {
854+
DPIUtil.validateLinearScaling(imageDataProvider);
855+
}
853856
ImageData data2x = imageDataProvider.getImageData (200);
854857
if (data2x != null) {
855858
alphaInfo_200 = new AlphaInfo();
@@ -1822,12 +1825,15 @@ public String toString () {
18221825
* @noreference This method is not intended to be referenced by clients.
18231826
*/
18241827
public static void drawScaled(GC gc, ImageData imageData, int width, int height, float scaleFactor) {
1828+
boolean originalStrictChecks = Device.strictChecks;
1829+
Device.strictChecks = false;
18251830
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
18261831
gc.drawImage (imageToDraw, 0, 0, CocoaDPIUtil.pixelToPoint (width), CocoaDPIUtil.pixelToPoint (height),
18271832
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
18281833
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
18291834
*/
18301835
0, 0, Math.round (CocoaDPIUtil.pixelToPoint (width * scaleFactor)), Math.round (CocoaDPIUtil.pixelToPoint (height * scaleFactor)));
1836+
Device.strictChecks = originalStrictChecks;
18311837
imageToDraw.dispose();
18321838
}
18331839

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/graphics/ImageDataProvider.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,31 @@ public interface ImageDataProvider {
2828

2929
/**
3030
* Returns the image data for the given zoom level.
31-
* <p>
32-
* If no image is available for a particular zoom level, this method should
33-
* return <code>null</code>. For <code>zoom == 100</code>, returning
34-
* <code>null</code> is not allowed, and SWT will throw an exception.
31+
*
32+
* <ul>
33+
* <li>
34+
* If no image is available for a particular zoom level, this method should
35+
* return <code>null</code>. For <code>zoom == 100</code>, returning
36+
* <code>null</code> is not allowed, and SWT will throw an exception.
37+
* </li>
38+
* <li>
39+
* Implementations are expected to return {@link ImageData} that is
40+
* <b>linearly scaled</b> with respect to the zoom level.
41+
* For example, if <code>getImageData(100)</code> returns an image of
42+
* width <code>w</code> and height <code>h</code>, then
43+
* <code>getImageData(200)</code> must return an {@link ImageData}
44+
* of width <code>2 * w</code> and height <code>2 * h</code>,
45+
* if a non-{@code null} result is returned.
46+
* </li>
47+
* </ul>
48+
*
3549
*
3650
* @param zoom
3751
* The zoom level in % of the standard resolution (which is 1
3852
* physical monitor pixel == 1 SWT logical point). Typically 100,
3953
* 150, or 200.
40-
* @return the image data, or <code>null</code> if <code>zoom != 100</code>
54+
* @return the linearly scaled image data for the given zoom level,
55+
* or <code>null</code> if <code>zoom != 100</code>
4156
* and no image is available for the given zoom level.
4257
* @since 3.104
4358
*/

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/internal/DPIUtil.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,26 @@ public static int mapZoomToDPI (int zoom) {
223223
return roundedDpi;
224224
}
225225

226+
public static void validateLinearScaling(ImageDataProvider provider) {
227+
final int baseZoom = 100;
228+
final int scaledZoom = 200;
229+
final int scaleFactor = scaledZoom / baseZoom;
230+
ImageData baseImageData = provider.getImageData(baseZoom);
231+
ImageData scaledImageData = provider.getImageData(scaledZoom);
232+
233+
if (scaledImageData == null) {
234+
return;
235+
}
236+
237+
if (scaledImageData.width != scaleFactor * baseImageData.width
238+
|| scaledImageData.height != scaleFactor * baseImageData.height) {
239+
System.err.println(String.format(
240+
"***WARNING: ImageData should be linearly scaled across zooms but size is (%d, %d) at 100%% and (%d, %d) at 200%%.",
241+
baseImageData.width, baseImageData.height, scaledImageData.width, scaledImageData.height));
242+
new Error().printStackTrace(System.err);
243+
}
244+
}
245+
226246
/**
227247
* Represents an element, such as some image data, at a specific zoom level.
228248
*

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
3434
*/
3535
public abstract class Device implements Drawable {
36+
protected static boolean strictChecks = System.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
3637
/**
3738
* @noreference This field is not intended to be referenced by clients.
3839
* @since 3.105

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,9 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
672672
currentDeviceZoom = DPIUtil.getDeviceZoom();
673673
initFromImageDataProvider(currentDeviceZoom);
674674
init ();
675+
if (Device.strictChecks) {
676+
DPIUtil.validateLinearScaling(imageDataProvider);
677+
}
675678
}
676679

677680
/**
@@ -1583,12 +1586,15 @@ public String toString () {
15831586
* @noreference This method is not intended to be referenced by clients.
15841587
*/
15851588
public static void drawScaled(GC gc, ImageData imageData, int width, int height, float scaleFactor) {
1589+
boolean originalStrictChecks = Device.strictChecks;
1590+
Device.strictChecks = false;
15861591
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
15871592
gc.drawImage (imageToDraw, 0, 0, width, height,
15881593
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
15891594
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
15901595
*/
15911596
0, 0, Math.round (width * scaleFactor), Math.round (height * scaleFactor));
1597+
Device.strictChecks = originalStrictChecks;
15921598
imageToDraw.dispose();
15931599
}
15941600

bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@
116116
*/
117117
public class Display extends Device implements Executor {
118118

119-
static boolean strictChecks = System.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
120-
121119
private static final int SLOT_IN_USE = -2;
122120
private static final int LAST_TABLE_INDEX = -1;
123121

@@ -880,7 +878,7 @@ void addWidget (long handle, Widget widget) {
880878
widgetTable = newWidgetTable;
881879
}
882880
int index = freeSlot + 1;
883-
if(strictChecks) {
881+
if(Display.strictChecks) {
884882
long data = OS.g_object_get_qdata (handle, SWT_OBJECT_INDEX);
885883
if(data > 0 && data != index) {
886884
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, ". Potential leak of " + widget + debugInfoForIndex(data - 1));

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
*/
3535
public abstract class Device implements Drawable {
3636

37-
static boolean strictChecks = System.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
37+
protected static boolean strictChecks = System.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
3838

3939
/* Debugging */
4040
public static boolean DEBUG;

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

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -613,32 +613,12 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
613613
": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom.");
614614
}
615615
if (Device.strictChecks) {
616-
validateLinearScaling(imageDataProvider);
616+
DPIUtil.validateLinearScaling(imageDataProvider);
617617
}
618618
init();
619619
this.device.registerResourceWithZoomSupport(this);
620620
}
621621

622-
private void validateLinearScaling(ImageDataProvider provider) {
623-
final int baseZoom = 100;
624-
final int scaledZoom = 200;
625-
final int scaleFactor = scaledZoom / baseZoom;
626-
ImageData baseImageData = provider.getImageData(baseZoom);
627-
ImageData scaledImageData = provider.getImageData(scaledZoom);
628-
629-
if (scaledImageData == null) {
630-
return;
631-
}
632-
633-
if (scaledImageData.width != scaleFactor * baseImageData.width
634-
|| scaledImageData.height != scaleFactor * baseImageData.height) {
635-
System.err.println(String.format(
636-
"***WARNING: ImageData should be linearly scaled across zooms but size is (%d, %d) at 100%% and (%d, %d) at 200%%.",
637-
baseImageData.width, baseImageData.height, scaledImageData.width, scaledImageData.height));
638-
new Error().printStackTrace(System.err);
639-
}
640-
}
641-
642622
/**
643623
* The provided ImageGcDrawer will be called on demand whenever a new variant of the
644624
* Image for an additional zoom is required. Depending on the OS-specific implementation

0 commit comments

Comments
 (0)