Bug 421383 - [Graphics] Scaling issues on high DPI displays

Added debug options to:
# Log cases where an "@2x" image could not be found.
# Always load the .png image of the "@2x" version, even if the original image was a .gif.
diff --git a/bundles/org.eclipse.jface/.options b/bundles/org.eclipse.jface/.options
index eee0d58..58b9d9d 100644
--- a/bundles/org.eclipse.jface/.options
+++ b/bundles/org.eclipse.jface/.options
@@ -9,12 +9,18 @@
 # Trace time spent creating URLImageDescriptor images
 org.eclipse.jface/debug/trace/URLImageDescriptor=false
 
+# Log cases where an "@2x" image could not be found.
+org.eclipse.jface/debug/logURLImageDescriptorMissing2x=false
+
 # Switch URLImageDescriptor to load images directly via URL#openStream() (instead of FileLocator#toFileURL(URL))
 org.eclipse.jface/debug/loadURLImageDescriptorDirectly=false
 
 # Switch URLImageDescriptor to load images using the "@2x" convention for high-dpi
 org.eclipse.jface/debug/loadURLImageDescriptor2x=false
 
+# Always load the .png image of the "@2x" version, even if the original image was a .gif.
+org.eclipse.jface/debug/loadURLImageDescriptor2xPngForGif=false
+
 # Log a message if a dialog is opened without a parent
 org.eclipse.jface/debug/dialog/noparent=false
 
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/internal/InternalPolicy.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/internal/InternalPolicy.java
index 81e2116..6f93534 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/internal/InternalPolicy.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/internal/InternalPolicy.java
@@ -61,6 +61,13 @@
 	public static boolean DEBUG_TRACE_URL_IMAGE_DESCRIPTOR = false;
 
 	/**
+	 * (NON-API) Log cases where an "@2x" image could not be found.
+	 *
+	 * @since 3.11
+	 */
+	public static boolean DEBUG_LOG_URL_IMAGE_DESCRIPTOR_MISSING_2x = false;
+
+	/**
 	 * (NON-API) If true, URLImageDescriptor loads images directly via
 	 * URL#openStream(). If false, URLImageDescriptor first tries to use
 	 * FileLocator#toFileURL(URL) and the Image(Device, String) constructor.
@@ -77,6 +84,14 @@
 	public static boolean DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x = false;
 
 	/**
+	 * (NON-API) Always load the .png image of the "@2x" version, even if the
+	 * original image was a .gif.
+	 *
+	 * @since 3.11
+	 */
+	public static boolean DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x_PNG_FOR_GIF = false;
+
+	/**
 	 * (NON-API) A flag to indicate whether the JFace bundle is running inside
 	 * an OSGi container
 	 *
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java
index 403097f..348a971 100644
--- a/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/resource/URLImageDescriptor.java
@@ -144,6 +144,13 @@
 			}
 			return new BufferedInputStream(url.openStream());
 		} catch (IOException e) {
+			if (InternalPolicy.DEBUG_LOG_URL_IMAGE_DESCRIPTOR_MISSING_2x) {
+				String path = url.getPath();
+				if (path.endsWith("@2x.png") || path.endsWith("@1.5x.png")) { //$NON-NLS-1$ //$NON-NLS-2$
+					String message = "High-resolution image missing: " + url; //$NON-NLS-1$
+					Policy.getLog().log(new Status(IStatus.WARNING, Policy.JFACE, message, e));
+				}
+			}
 			return null;
 		}
 	}
@@ -172,6 +179,9 @@
 		if (dot != -1 && (zoom == 150 || zoom == 200)) {
 			String lead = path.substring(0, dot);
 			String tail = path.substring(dot);
+			if (InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x_PNG_FOR_GIF && ".gif".equalsIgnoreCase(tail)) { //$NON-NLS-1$
+				tail = ".png"; //$NON-NLS-1$
+			}
 			String x = zoom == 150 ? "@1.5x" : "@2x"; //$NON-NLS-1$ //$NON-NLS-2$
 			try {
 				String file = lead + x + tail;
@@ -214,6 +224,12 @@
 		} catch (IOException e) {
 			if (logIOException) {
 				Policy.logException(e);
+			} else if (InternalPolicy.DEBUG_LOG_URL_IMAGE_DESCRIPTOR_MISSING_2x) {
+				String path = url.getPath();
+				if (path.endsWith("@2x.png") || path.endsWith("@1.5x.png")) { //$NON-NLS-1$ //$NON-NLS-2$
+					String message = "High-resolution image missing: " + url; //$NON-NLS-1$
+					Policy.getLog().log(new Status(IStatus.WARNING, Policy.JFACE, message, e));
+				}
 			}
 			return null;
 		}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java
index 432e258..c3cc00a 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/JFaceUtil.java
@@ -83,8 +83,10 @@
 			InternalPolicy.DEBUG_LOG_EQUAL_VIEWER_ELEMENTS = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/viewers/equalElements")); //$NON-NLS-1$ //$NON-NLS-2$
 			InternalPolicy.DEBUG_BIDI_UTILS = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/bidiUtils")); //$NON-NLS-1$ //$NON-NLS-2$
 			InternalPolicy.DEBUG_TRACE_URL_IMAGE_DESCRIPTOR = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/trace/URLImageDescriptor")); //$NON-NLS-1$ //$NON-NLS-2$
+			InternalPolicy.DEBUG_LOG_URL_IMAGE_DESCRIPTOR_MISSING_2x = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/logURLImageDescriptorMissing2x")); //$NON-NLS-1$ //$NON-NLS-2$
 			InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_DIRECTLY = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/loadURLImageDescriptorDirectly")); //$NON-NLS-1$ //$NON-NLS-2$
 			InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/loadURLImageDescriptor2x")); //$NON-NLS-1$ //$NON-NLS-2$
+			InternalPolicy.DEBUG_LOAD_URL_IMAGE_DESCRIPTOR_2x_PNG_FOR_GIF = "true".equalsIgnoreCase(Platform.getDebugOption(Policy.JFACE + "/debug/loadURLImageDescriptor2xPngForGif")); //$NON-NLS-1$ //$NON-NLS-2$
 		}
 	}