Skip to content

Commit 9620d00

Browse files
arunjose696HeikoKlare
authored andcommitted
Unify strict checks and extend ImageDataProvider checks to GTK and Cocoa
Move strict checks into a separate class. Extend strict check to verify if imageData is linearly scaled by an ImageDataProvider in GTK and Cocoa implementations.
1 parent b1f947e commit 9620d00

File tree

9 files changed

+109
-58
lines changed

9 files changed

+109
-58
lines changed

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

Lines changed: 15 additions & 7 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+
StrictChecks.runIfStrictChecksEnabled(() -> {
854+
DPIUtil.validateLinearScaling(imageDataProvider);
855+
});
853856
ImageData data2x = imageDataProvider.getImageData (200);
854857
if (data2x != null) {
855858
alphaInfo_200 = new AlphaInfo();
@@ -1822,13 +1825,18 @@ 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) {
1825-
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
1826-
gc.drawImage (imageToDraw, 0, 0, CocoaDPIUtil.pixelToPoint (width), CocoaDPIUtil.pixelToPoint (height),
1827-
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1828-
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1829-
*/
1830-
0, 0, Math.round (CocoaDPIUtil.pixelToPoint (width * scaleFactor)), Math.round (CocoaDPIUtil.pixelToPoint (height * scaleFactor)));
1831-
imageToDraw.dispose();
1828+
StrictChecks.runWithStrictChecksDisabled(() -> {
1829+
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
1830+
gc.drawImage(imageToDraw, 0, 0, CocoaDPIUtil.pixelToPoint(width), CocoaDPIUtil.pixelToPoint(height),
1831+
/*
1832+
* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but
1833+
* avoiding rounding errors. Nevertheless, we still have some rounding errors
1834+
* due to the point-based API GC#drawImage(..).
1835+
*/
1836+
0, 0, Math.round(CocoaDPIUtil.pixelToPoint(width * scaleFactor)),
1837+
Math.round(CocoaDPIUtil.pixelToPoint(height * scaleFactor)));
1838+
imageToDraw.dispose();
1839+
});
18321840
}
18331841

18341842
}

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
*
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Yatta Solutions
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Yatta Solutions - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.swt.internal;
15+
16+
public final class StrictChecks {
17+
18+
private static final boolean STRICT_CHECKS_ENABLED = System
19+
.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
20+
21+
private static boolean temporarilyDisabled = false;
22+
23+
private StrictChecks() {
24+
}
25+
26+
public static void runIfStrictChecksEnabled(Runnable runnable) {
27+
if (STRICT_CHECKS_ENABLED && !temporarilyDisabled) {
28+
runnable.run();
29+
}
30+
}
31+
32+
public static void runWithStrictChecksDisabled(Runnable runnable) {
33+
temporarilyDisabled = true;
34+
try {
35+
runnable.run();
36+
} finally {
37+
temporarilyDisabled = false;
38+
}
39+
}
40+
}

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

Lines changed: 14 additions & 7 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+
StrictChecks.runIfStrictChecksEnabled(() -> {
676+
DPIUtil.validateLinearScaling(imageDataProvider);
677+
});
675678
}
676679

677680
/**
@@ -1583,13 +1586,17 @@ 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) {
1586-
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
1587-
gc.drawImage (imageToDraw, 0, 0, width, height,
1588-
/* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but avoiding rounding errors.
1589-
* Nevertheless, we still have some rounding errors due to the point-based API GC#drawImage(..).
1590-
*/
1591-
0, 0, Math.round (width * scaleFactor), Math.round (height * scaleFactor));
1592-
imageToDraw.dispose();
1589+
StrictChecks.runWithStrictChecksDisabled(() -> {
1590+
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
1591+
gc.drawImage(imageToDraw, 0, 0, width, height,
1592+
/*
1593+
* E.g. destWidth here is effectively DPIUtil.autoScaleDown (scaledWidth), but
1594+
* avoiding rounding errors. Nevertheless, we still have some rounding errors
1595+
* due to the point-based API GC#drawImage(..).
1596+
*/
1597+
0, 0, Math.round(width * scaleFactor), Math.round(height * scaleFactor));
1598+
imageToDraw.dispose();
1599+
});
15931600
}
15941601

15951602
}

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

Lines changed: 2 additions & 4 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,12 +878,12 @@ void addWidget (long handle, Widget widget) {
880878
widgetTable = newWidgetTable;
881879
}
882880
int index = freeSlot + 1;
883-
if(strictChecks) {
881+
StrictChecks.runIfStrictChecksEnabled(() -> {
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));
887885
}
888-
}
886+
});
889887
OS.g_object_set_qdata (handle, SWT_OBJECT_INDEX, index);
890888
int oldSlot = freeSlot;
891889
freeSlot = indexTable[oldSlot];

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3258,14 +3258,14 @@ void deregister () {
32583258
if(shellHandle != 0 && !(disposed instanceof Shell)) {
32593259
SWT.error(SWT.ERROR_INVALID_RETURN_VALUE, null, ". Wrong widgetTable entry: " + disposed + " removed for shell: " + this + display.dumpWidgetTableInfo());
32603260
}
3261-
if(Display.strictChecks) {
3261+
StrictChecks.runIfStrictChecksEnabled(() -> {
32623262
Shell[] shells = display.getShells();
32633263
for (Shell shell : shells) {
32643264
if(shell == this) {
32653265
SWT.error(SWT.ERROR_INVALID_RETURN_VALUE, null, ". Disposed shell still in the widgetTable: " + this + display.dumpWidgetTableInfo());
32663266
}
32673267
}
3268-
}
3268+
});
32693269
}
32703270

32713271
boolean requiresUngrab () {

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@
3434
*/
3535
public abstract class Device implements Drawable {
3636

37-
static boolean strictChecks = System.getProperty("org.eclipse.swt.internal.enableStrictChecks") != null;
38-
3937
/* Debugging */
4038
public static boolean DEBUG;
4139
boolean debug = DEBUG;

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,9 @@ private void validateGCState() {
210210
}
211211

212212
void checkGC(int mask) {
213-
if (Device.strictChecks) {
213+
StrictChecks.runIfStrictChecksEnabled(() -> {
214214
validateGCState();
215-
}
215+
});
216216
int state = data.state;
217217
if ((state & mask) == mask) return;
218218
state = (state ^ mask) & mask;
@@ -4402,10 +4402,10 @@ private void init(Drawable drawable, GCData data, long hDC) {
44024402
}
44034403

44044404
private static int extractZoom(long hDC) {
4405-
if (Device.strictChecks) {
4405+
StrictChecks.runIfStrictChecksEnabled(() -> {
44064406
System.err.println("***WARNING: GC is initialized with a missing zoom. This indicates an "
44074407
+ "incompatible custom Drawable implementation.");
4408-
}
4408+
});
44094409
long hwnd = OS.WindowFromDC(hDC);
44104410
long parentWindow = OS.GetAncestor(hwnd, OS.GA_ROOT);
44114411
long monitorParent = OS.MonitorFromWindow(parentWindow, OS.MONITOR_DEFAULTTONEAREST);

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

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -612,33 +612,13 @@ public Image(Device device, ImageDataProvider imageDataProvider) {
612612
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
613613
": ImageDataProvider [" + imageDataProvider + "] returns null ImageData at 100% zoom.");
614614
}
615-
if (Device.strictChecks) {
616-
validateLinearScaling(imageDataProvider);
617-
}
615+
StrictChecks.runIfStrictChecksEnabled(() -> {
616+
DPIUtil.validateLinearScaling(imageDataProvider);
617+
});
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
@@ -851,13 +831,13 @@ public static long win32_getHandle (Image image, int zoom) {
851831
* @noreference This method is not intended to be referenced by clients.
852832
*/
853833
public static void drawScaled(GC gc, ImageData imageData, int width, int height, float scaleFactor) {
854-
boolean originalStrictChecks = Device.strictChecks;
855-
Device.strictChecks = false;
856-
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
857-
gc.drawImage (imageToDraw, 0, 0, width, height,
858-
0, 0, Math.round (width * scaleFactor), Math.round (height * scaleFactor), false);
859-
Device.strictChecks = originalStrictChecks;
860-
imageToDraw.dispose();
834+
835+
StrictChecks.runWithStrictChecksDisabled(() -> {
836+
Image imageToDraw = new Image(gc.device, (ImageDataProvider) zoom -> imageData);
837+
gc.drawImage(imageToDraw, 0, 0, width, height, 0, 0, Math.round(width * scaleFactor),
838+
Math.round(height * scaleFactor), false);
839+
imageToDraw.dispose();
840+
});
861841
}
862842

863843
long [] createGdipImage(Integer zoom) {
@@ -1753,9 +1733,9 @@ private long configureGC(GCData data, ZoomContext zoomContext) {
17531733
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
17541734
}
17551735

1756-
if (Device.strictChecks) {
1736+
StrictChecks.runIfStrictChecksEnabled(() -> {
17571737
checkImageTypeForValidCustomDrawing(zoomContext.targetZoom());
1758-
}
1738+
});
17591739
/* Create a compatible HDC for the device */
17601740
long hDC = device.internal_new_GC(null);
17611741
long imageDC = OS.CreateCompatibleDC(hDC);

0 commit comments

Comments
 (0)