Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 462569

Summary: [api] ImageFileNameProvider/ImageDataProvider#getImageData(int) can't determine size of image
Product: [Eclipse Project] Platform Reporter: Markus Keller <markus.kell.r>
Component: SWTAssignee: Niraj Modi <niraj.modi>
Status: VERIFIED FIXED QA Contact:
Severity: major    
Priority: P3 CC: daniel_megert, eclipse, lshanmug, markus.kell.r, niraj.modi, sravankumarl
Version: 4.5Flags: daniel_megert: pmc_approved+
Target Milestone: 4.5 M7   
Hardware: All   
OS: All   
See Also: https://git.eclipse.org/r/44445
https://git.eclipse.org/r/44889
https://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=72e691af6bca78442e18184dc1453e5eecb6f768
Whiteboard:

Description Markus Keller CLA 2015-03-19 09:29:56 EDT
I think there's a fundamental flaw in the new APIs ImageFileNameProvider/ImageDataProvider#getImageData(int). The API Javadocs say:

"If the image is not available for a particular zoom level, please fall back to image of 100% level and return its image data. Note: SWT will throw an exception if this method returns null."

The problem is that SWT doesn't know which zoom level is returned. SWT just gets an image with a certain width/height, but it doesn't know whether the size is in SWT coordinates (zoom == 100) or whether the image contains more pixels than the SWT rectangle it should fit in.

SWT can only only know the actual size by requesting the image for zoom == 100, but this should be avoided unless there's actually a monitor that uses 100% resolution.

The API should be changed to this:

/**
 * Returns the image data for the given zoom level.
 * <p>
 * If no image is available for a particular zoom level, this method should
 * return <code>null</code>. For <code>zoom == 100</code>, returning
 * <code>null</code> in not allowed, and SWT will throw an exception.
 * 
 * @param zoom
 *            The zoom level. Typically 100, 150, or 200.
 * @return the image data, or <code>null</code> iff <code>zoom != 100</code>
 *         and no image is available for the given zoom level
 * @since 3.104
 */
Comment 1 Markus Keller CLA 2015-03-19 14:48:25 EDT
(In reply to Markus Keller from comment #0)
> ... unless there's actually a monitor that uses
> 100% resolution.

Read: ... unless the shell is actually rendered on a monitor that uses 100% res.

This currently doesn't work on the Mac, see bug 462555.


And I missed to describe the unit of the "zoom" parameter:

 * @param zoom
 *            The zoom level in % of the standard resolution (which is
 *            1 physical monitor pixel == 1 SWT logical pixel).
 *            Typically 100, 150, or 200.
Comment 2 Niraj Modi CLA 2015-03-20 08:09:01 EDT
Thanks Markus for your inputs, we will make the JavaDoc & code changes accordingly.

Additionally, SWT will now cross-check on the size of the Image received, as per below contract:
At 100% zoom - 16x16 pixels size image is mandatory, else SWT throws an exception
At 150% zoom - either image can be null or it's 24x24 pixels size, else SWT throws an exception
At 200% zoom - either image can be null or it's 32x32 pixels size, else SWT throws an exception

Hope tweaking the API behavior & JavaDocs on these lines is allowed post M6.
Will share a Gerrit on the same.
Comment 3 Markus Keller CLA 2015-03-20 10:03:44 EDT
(In reply to Niraj Modi from comment #2)
> Additionally, SWT will now cross-check on the size of the Image received, as
> per below contract:
> At 100% zoom - 16x16 pixels size image is mandatory, else SWT throws an
> exception

No, you can't do that. The 16x16 convention is just something we use in the platform for button and item images. The SWT constructors must stay fully general and work for any size of images.

What you could do when you load the 2nd+ zoom level is verify that the image size in the new zoom level matches the size at the previous zoom level (adjusted by the difference in zoom level). However, since that check would only happen when zoom levels are changed dynamically, and since you could run into rounding errors, I'd prefer not to have any such checks.

> Hope tweaking the API behavior & JavaDocs on these lines is allowed post M6.

Yes. And for clearly broken APIs, I wouldn't even expect to need PMC approval.
Comment 4 Dani Megert CLA 2015-03-20 10:15:49 EDT
(In reply to Markus Keller from comment #3)
> > Hope tweaking the API behavior & JavaDocs on these lines is allowed post M6.

+1.
Comment 5 Thomas Singer CLA 2015-03-23 14:30:05 EDT
How to find out this zoom level when using owner-draw, e.g. in tables?
Comment 6 Markus Keller CLA 2015-03-23 15:47:02 EDT
(In reply to Thomas Singer from comment #5)
> How to find out this zoom level when using owner-draw, e.g. in tables?

We're not there yet. But I think this will become more clear after bug 399786 has been tackled. For Mars, we'll keep the good old "SWT coordinates" granularity in the GC APIs. But GC#drawImage(..) eventually needs to take the zoom level into account and choose the right image representation for you (maybe it already does -- didn't check).
Comment 7 Sravan Kumar Lakkimsetti CLA 2015-03-24 02:10:16 EDT
(In reply to Markus Keller from comment #6)
> (In reply to Thomas Singer from comment #5)
> > How to find out this zoom level when using owner-draw, e.g. in tables?
> 
> We're not there yet. But I think this will become more clear after bug
> 399786 has been tackled. For Mars, we'll keep the good old "SWT coordinates"
> granularity in the GC APIs. But GC#drawImage(..) eventually needs to take
> the zoom level into account and choose the right image representation for
> you (maybe it already does -- didn't check).

We have changed the drawImage function to take care of the zoomlevel. So it will use the right representation for the zoom level.
Comment 8 Thomas Singer CLA 2015-03-24 02:32:56 EDT
We are not drawing images but graphics. How we can detect the zoom level for those?
Comment 9 Eclipse Genie CLA 2015-03-24 07:10:26 EDT
New Gerrit change created: https://git.eclipse.org/r/44445
Comment 10 Eclipse Genie CLA 2015-03-31 01:24:51 EDT
New Gerrit change created: https://git.eclipse.org/r/44889
Comment 13 Niraj Modi CLA 2015-04-01 07:27:25 EDT
(In reply to Thomas Singer from comment #8)
> We are not drawing images but graphics. How we can detect the zoom level for
> those?
By drawing graphics, I assume you are using something like Canvas to draw symbols etc..
Ok, as part of enhancement request bug 421383, we did created an internal(non-public) utility method DPIUtil#mapDPIToZoom which maps the DPI value received from public Device.getDPI() to equivalent zoom level.
But this DPIUtil API is needed/valid for Windows and GTK code only, for Cocoa these DPI to zoom mapping doesn't hold true.
Hope this helps, if someone wants to calculate the zoom in their client code for now.

For having public API to detect zoom level, suggest you to raise a separate enhancement request, as we are in API freeze stage for Mars.
Comment 14 Niraj Modi CLA 2015-04-13 09:49:05 EDT
Done with the required changes.. Resolving
Comment 15 Niraj Modi CLA 2015-04-28 11:07:21 EDT
Verified the fix in build: I20150428-0100
Comment 16 Sravan Kumar Lakkimsetti CLA 2015-04-29 02:54:22 EDT
Verified the fix in build: I20150428-0100