Bug 399786 - [Cocoa][GTK][Win32][Retina] GC#draw*(..) needs to support high-DPI images (was: Line numbers in editors are blurry)
Summary: [Cocoa][GTK][Win32][Retina] GC#draw*(..) needs to support high-DPI images (wa...
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.2.1   Edit
Hardware: All All
: P3 blocker with 9 votes (vote)
Target Milestone: 4.6 M6   Edit
Assignee: Sravan Kumar Lakkimsetti CLA
QA Contact:
URL: https://wiki.eclipse.org/High_DPI_ope...
Whiteboard:
Keywords:
: 486428 488052 (view as bug list)
Depends on: 97506 421383 489451
Blocks: 382972 385122 462952 479614 488913
  Show dependency tree
 
Reported: 2013-02-02 16:49 EST by gossi CLA
Modified: 2016-12-14 09:14 EST (History)
22 users (show)

See Also:


Attachments
Screen Shot of blurry line numbers on OSX with retina display. (237.31 KB, image/jpeg)
2013-08-29 10:41 EDT, Thomas Darimont CLA
no flags Details
Screen Shot of clear line numbers on OSX with retina display with patch. (225.85 KB, image/png)
2013-08-29 10:42 EDT, Thomas Darimont CLA
no flags Details
Proof of concept patch for clear line numbers on OSX with Retina displays. (4.45 KB, patch)
2013-08-29 11:07 EDT, Thomas Darimont CLA
no flags Details | Diff
Snippet367 on Mac10.10@2x (203.44 KB, image/png)
2015-04-21 15:44 EDT, Markus Keller CLA
no flags Details
Snippet367 on Windows7@200% (178.99 KB, image/png)
2015-04-21 15:45 EDT, Markus Keller CLA
no flags Details
Snippet367 on Ubuntu14.04/GTK3 (System Settings > Display > Scale: 2) (82.73 KB, image/png)
2015-04-21 19:24 EDT, Markus Keller CLA
no flags Details
snippet367 on Ubuntu 14.04/GTK3 with hi-dpi monitor(150%) (42.53 KB, image/png)
2015-04-22 02:35 EDT, Sravan Kumar Lakkimsetti CLA
no flags Details
Win7@200dpi (134.84 KB, image/png)
2015-04-27 14:09 EDT, Markus Keller CLA
no flags Details
Screenshot on linux with auto scaling (45.58 KB, image/png)
2015-10-19 09:15 EDT, Sravan Kumar Lakkimsetti CLA
no flags Details
Snapshot of eclipse on GTK2 with auto scaling and 150% screen(ubuntu 15.04) (221.33 KB, image/png)
2015-11-03 06:13 EST, Sravan Kumar Lakkimsetti CLA
no flags Details
Snapshot of eclipse on GTK3 with auto scaling and 150% screen(ubuntu 15.04) (219.02 KB, image/png)
2015-11-03 06:15 EST, Sravan Kumar Lakkimsetti CLA
no flags Details
Screenshot of eclipse on high dpi screen (157.00 KB, image/jpeg)
2015-11-06 09:14 EST, Ahmed Gawad CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description gossi CLA 2013-02-02 16:49:29 EST
If you enable line numbers in editors, they are blurry on retina/hi-dpi displays.
Comment 1 Markus Keller CLA 2013-02-04 06:07:33 EST
org.eclipse.jface.text.source.LineNumberRulerColumn#doubleBufferPaint(GC) implements the line number ruler via double-buffering. We first use GC#drawString(..) to draw into a buffer Image and then use GC#drawImage(..) to update the Canvas.

The problem is that the intermediate Image loses the retina resolution, see bug 382972. Bug 298936 has some history on why the code is like this.
Comment 2 Thomas Darimont CLA 2013-08-29 10:41:49 EDT
Created attachment 234965 [details]
Screen Shot of blurry line numbers on OSX with retina display.
Comment 3 Thomas Darimont CLA 2013-08-29 10:42:48 EDT
Created attachment 234967 [details]
Screen Shot of clear line numbers on OSX with retina display with patch.

... this was my first try to patch an eclipse bug.
Comment 4 Thomas Darimont CLA 2013-08-29 11:07:40 EDT
Created attachment 234969 [details]
Proof of concept patch for clear line numbers on OSX with Retina displays.

The provided patch (0001) is just a prove of concept implementation.
It is probably not the final solution since it is very messy and specific to OSX (with retina displays) but may be this could be a move towards the right direction :)

Cheers,
Thomas
Comment 5 Markus Keller CLA 2013-08-29 11:34:22 EDT
(In reply to comment #4)
This patch cannot be applied to master cleanly, and it is missing imports. While it may "fix" the blurriness, it would need many more changes to also fix Quick Diff and other code that also draws into rulers.

The right direction is to fix bug 382972.
Comment 6 Markus Keller CLA 2015-03-23 15:39:24 EDT
AFAICS, the solution will need to provide two parts:

a) The Image(Device, int, int) constructor should create a multi-representation Image that can use a high-DPI representation when a GC is drawing to it in a high-DPI window.

b) The GC#draw(..) methods need to apply coordinate scaling when drawing onto a high-DPI image representation.

In 4.6, we can think about adding new GC APIs that would allow pixel-perfect drawing in high-DPI images.
Comment 7 Markus Keller CLA 2015-03-23 16:06:02 EDT
Comment 6 was based on these observations (on Mac OS X 10.10):

- Line numbers are still blurry.

- When I hack LineNumberRulerColumn#doubleBufferPaint(GC) and replace line

	fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);

with

	fBuffer= new Image(fCanvas.getDisplay(), new ImageDataProvider() {
		public ImageData getImageData(int zoom) {
			ImageData imageData= new Image(fCanvas.getDisplay(),
					size.x * zoom / 100,
					size.y * zoom / 100
					).getImageData();
			return imageData;
		}
	});

, then:
- on a non-retina monitor, I don't see any line numbers 
- on a retina monitor, I see half-sized line numbers squeezed to the lower-left corner of the line number ruler area
Comment 8 Markus Keller CLA 2015-04-21 15:39:42 EDT
Houston, we have a problem.

SWT's image and font APIs are currently not platform-independent for high-resolution displays.

Comparing
- a Mac OS X 10.10 retina display with
- a Windows 7 profile with display set to 200%:

- On the Mac, the coordinate system (e.g. for placing Composites) stays in 100% resolution points. Image objects created by the old constructors also use the 100% resolution points (e.g. to compute the size of an image). When rendered, the image's bitmap information is automatically scaled, so that a every image point is rendered using 4 display pixels. Paint listeners on a Canvas and GC#drawText(...) methods also use 100% resolution points. Fonts keep their size.
=> Pros: Coordinates are stable and predictable.
=> Cons: Images are blurry by default. Clients have no way to interact with actual pixels or directly draw on a high-resolution surface, except when using a PaintListener on a Canvas. When working with Images/ImageDatas, the only way to support full resolution is to use the new Image constructors and then provide different images per resolution => needs extensive changes in clients' drawing code.

- On Windows, the coordinate system is adapted to the resolution and there is no automatic pixel doubling. Images are always rendered at 1 image point == 1 SWT pixel, i.e. regular images appear too small (1/2 the expected width/height) on a "200%" display.
Fonts are rendered larger than at 100% resolution, and a few UI elements are also scaled (scroll bars, window trims, but not lines with 1-point width or borders of a Text widget).
=> Pros: No blurry images.
=> Cons: Regular icons are too small (see "tiny icons" complaints in bug 421383). PaintListener-drawings on Canvas are inconsistent with 100% resolution drawings (e.g. default line width stays 1 px; point coordinates change their meaning w.r.t. rendered text size and resolution-dependent images).

The SWT API should shield clients from such platform differences.

I've extended Snippet 367 to show these differences: http://git.eclipse.org/c/platform/eclipse.platform.swt.git/plain/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java?id=8863fe5bcaba7d54c854e48a6069254ae72cec51
Comment 9 Markus Keller CLA 2015-04-21 15:44:31 EDT
Created attachment 252595 [details]
Snippet367 on Mac10.10@2x
Comment 10 Markus Keller CLA 2015-04-21 15:45:16 EDT
Created attachment 252596 [details]
Snippet367 on Windows7@200%
Comment 11 Markus Keller CLA 2015-04-21 19:24:11 EDT
Created attachment 252604 [details]
Snippet367 on Ubuntu14.04/GTK3 (System Settings > Display > Scale: 2)
Comment 12 Sravan Kumar Lakkimsetti CLA 2015-04-22 02:35:11 EDT
Created attachment 252616 [details]
snippet367 on Ubuntu 14.04/GTK3 with hi-dpi monitor(150%)
Comment 13 Markus Keller CLA 2015-04-22 06:20:46 EDT
Comment on attachment 252604 [details]
Snippet367 on Ubuntu14.04/GTK3 (System Settings > Display > Scale: 2)

Fixed typo in description: This was actually on 14.04 (old Mac mini; 32-bit).
(AFAIK, 12.04 didn't have a screen resolution setting.)
 
System Settings > Displays > Scale for menu and title bars: 2

It's strange that my screenshot looks so much different from comment 12.
Comment 14 Sravan Kumar Lakkimsetti CLA 2015-04-22 08:26:38 EDT
since the native support for scaling is available only from GTK3.10 onwards, swt has a implementation for calculating dpi based on the monitor dimensions. This implementation is there in Display.getDpi()/Display.getScreenDpi() call. This API call is used for calculating dpi used to render the images.

Probably this is the reason why you are seeing the difference
Comment 15 Markus Keller CLA 2015-04-22 09:06:02 EDT
Comment on attachment 252604 [details]
Snippet367 on Ubuntu14.04/GTK3 (System Settings > Display > Scale: 2)

(In reply to Sravan Kumar Lakkimsetti from bug 399786 comment #14)
Thanks for the explanation, that fits perfectly. I just have a regular FullHD monitor and I only set the scale to factor 2 in the OS settings. Opened bug 465195.
Comment 16 Markus Keller CLA 2015-04-27 14:09:17 EDT
Created attachment 252811 [details]
Win7@200dpi

(In reply to Markus Keller from comment #8)
> Windows cons: Regular icons are too small (see "tiny icons" complaints in bug
> 421383).

Here's a screenshot with the first cut of high-dpi support enabled in the platform (bug 459412 comment 8). As long as some bundles/icons have not been updated to include the high-dpi version for the current scaling factor, the mix of small and big icons makes the product look even worse than with small icons only.
Comment 17 Randy Hudson CLA 2015-05-20 16:32:21 EDT
There is no reason for the ruler to do its own double-buffering.  SWT has supported this since 3.1:

fCanvas= new Canvas(parentControl, SWT.NO_FOCUS ) {

(around line 585) should just be:

fCanvas= new Canvas(parentControl, SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED ) {

...and then get rid of the unnecessary Image buffer code.
Comment 18 Matthias Becker CLA 2015-09-23 03:46:21 EDT
(In reply to Randy Hudson from comment #17)
> There is no reason for the ruler to do its own double-buffering.  SWT has
> supported this since 3.1:
> 
> fCanvas= new Canvas(parentControl, SWT.NO_FOCUS ) {
> 
> (around line 585) should just be:
> 
> fCanvas= new Canvas(parentControl, SWT.NO_FOCUS | SWT.DOUBLE_BUFFERED ) {
> 
> ...and then get rid of the unnecessary Image buffer code.

That code did use "SWT.DOUBLE_BUFFERED" in the past but it was changed with a fix for bug 298936 (see https://github.com/eclipse/eclipse.platform.text/commit/8954f26949d4e371e0efdc0019d0c7209c7ab53a) Maybe Markus Keller knows more details.
Comment 19 Sravan Kumar Lakkimsetti CLA 2015-10-19 09:15:26 EDT
Created attachment 257350 [details]
Screenshot on linux with auto scaling
Comment 20 Eclipse Genie CLA 2015-10-19 09:18:56 EDT
New Gerrit change created: https://git.eclipse.org/r/58445
Comment 21 Sravan Kumar Lakkimsetti CLA 2015-10-19 09:26:18 EDT
Hi Markus,

I have done some changes to the gc code and I am able to achieve auto scaling for snippet367. 

The problematic area I have is 
1. We will also need an API to turn on/off the autoscaling, need to discuss/decide:
- what the API should look like -  
- what should be the default - turned on or off

2. How to handle Canvas

Can you please review this bug and bug 462952?

Thanks
Sravan
Comment 22 Markus Keller CLA 2015-10-23 14:47:00 EDT
(In reply to Eclipse Genie from comment #20)
> New Gerrit change created: https://git.eclipse.org/r/58445

I don't think a global state like Device#enableAutoScaling should be part of the solution for this bug. Since Eclipse applications are not monolithic, all solutions that require a global switch and fixes in every single SWT client are doomed to fail.


Comment 8 describes the behavioral differences between the Mac and Win/GTK models. I'll describe the problem again and propose a solution for a platform-independent SWT API.

Existing client code assumes 1 logical SWT point == 1 pixel on screen (=100%), and a reasonable default resolution (72dpi or 96dpi -- long story, but not relevant here). With HiDPI screens, we have a fundamental problem on each platform, but it's not the same everywhere, but depends on how the OSes added support for HiDPI.

The hard problem for SWT is that the SWT APIs need to be platform-independent. That means we have to take a decision which platform's solution should be the model for SWTs API on all platforms. Currently, platform differences are passed on to clients, which runs counter the basic idea that SWT apps should be portable. 

## Mac ##
The PaintListener only seems to give access to the old "default resolution" logical pixel world. However, the drawing routines behind the GC on a Canvas "cheat" on a HiDPI screen: They silently keep multiple image representations, and when drawing text or lines in HiDPI, they use the high-resolution rep and scale the font size and line widths so that the result looks crisp.
=> In case 1 of Snippet367, everything looks good.

In case 2, the masquerade breaks down, because the SWT Image only contains a low-resolution bitmap. And since ImageData#data gives complete access to the bitmap, HiDPI support cannot be implemented completely transparently by SWT. We need new APIs for that. Solution attempts and their problems:
  (a) clients need to implement PaintListeners that know about the screen resolution (problem: breaks all old clients)
  (b) Image would get something like "ImageData getImageData(int zoom)", which would allow clients to get bitmaps at different resolutions (problem: are these always available? What about images created with one of the old constructors?)
  (c) GC would get a new constructor "GC(Drawable drawable, int zoom, int style)", whose implementation would automatically scale fonts and lines
  (d) let old Image constructors always create images at 100% and only support HiDPI through multi-rep constructors (problem: would keep some images unnecessarily blurry)

## Windows & GTK ##
The PaintListener currently gives direct access to the screen pixels. This breaks every client that e.g. assumes a 50x50 point square is about the size of a finger tip / physical keyboard key. It also breaks clients that assume a 1 point line is clearly visible and a 2 point line looks "thick". Since fonts quickly become unreadable when they become too tiny, Win & GTK chose to silently scale fonts (and thereby also layouts that are based on font height and width). I.e. when a PaintListener on a Canvas should render a text in 9 pt on a 200% resolution screen, the OS actually draws with a 18 pt font.

Since images and lines are not scaled along with the font, you run into the "tiny icons" and "thin lines" problems. This was +/- acceptable as long as scaling only went from about 75% to 150%. In todays HiDPI screens, I don't think this is a sustainable solution, since it effectively requires every PaintListener to become resolution-aware. I.e. it's a breaking change for every client of SWT APIs.


I think the best solution is to declare the Mac model the default for SWT and add Image#getImageData(int zoom) to solve special cases like the line number ruler. Win & GTK implementations should be adjusted so that they behave the "Mac" way. I.e.:

- keep SWT logical coordinates at the "default resolution" and only provide access to screen pixels in new APIs

- when drawing in a GC for a Canvas (PaintListener):
  - only use the high-resolution image representation internally, but talk to SWT clients in default resolution coordinates
  - automatic font scaling is fine in this case (makes text sharper)
  - also need to scale line widths on Win&GTK
  - in GC#drawImage(..), use the corresponding resolution from the given Image


The hard questions are:

- Should the old Image constructors on the Mac also create high-resolutions NSImageReps? We need to avoid unnecessary overhead here. See also bug 462555, which already shows a problem with the APIs added for Mars.

- How to deal with the constructors of GC that take an Image? For performance reasons, SWT can't always draw n versions of images if the given Image is one with multiple representations.

The best solution I see is to use the current resolution (max resolution of all attached monitors) in these cases, and provide a listener on Shell where clients can be notified about resolution changes that may require Images to be re-created.

On the Mac, this will require fixes in Image and GC:
- new Images need to be created with a rep for the current resolution (AFAICS, they currently only get the 100% resolution)
- when drawing in a GC for an Image, make sure the right font size, line width, image reps are used. Images may need to be scaled if the right resolution is not available.
- Javadoc of GC constructors need to specify that drawing operations on multi-representation images will only be applied to the currently active representation.
Comment 23 Sravan Kumar Lakkimsetti CLA 2015-11-03 06:13:35 EST
Created attachment 257697 [details]
Snapshot of eclipse on GTK2 with auto scaling and 150% screen(ubuntu 15.04)
Comment 24 Sravan Kumar Lakkimsetti CLA 2015-11-03 06:15:18 EST
Created attachment 257698 [details]
Snapshot of eclipse on GTK3 with auto scaling and 150% screen(ubuntu 15.04)
Comment 25 Ahmed Gawad CLA 2015-11-06 09:14:37 EST
Created attachment 257785 [details]
Screenshot of eclipse on high dpi screen

After applying latest patch on Win32, Still some icons (e.g. package explorer) are not scaled as per attached screenshot.
Comment 26 Sravan Kumar Lakkimsetti CLA 2015-11-09 00:45:37 EST
(In reply to Ahmed Gawad from comment #25)
> Created attachment 257785 [details]
> Screenshot of eclipse on high dpi screen
> 
> After applying latest patch on Win32, Still some icons (e.g. package
> explorer) are not scaled as per attached screenshot.

Sorry this change is done only on linux. Windows changes are not yet done. So you may not have seen the changes yet.

Once the changes for windows are done we update this bug
Comment 27 Eclipse Genie CLA 2015-11-12 11:11:56 EST
New Gerrit change created: https://git.eclipse.org/r/60235
Comment 28 Markus Keller CLA 2016-01-07 03:07:15 EST
Branch slakkimsetti/NeonhiDpiWork is on a good track. Here are a few issues I found:

The lookup for scale-factor in Device#getScalingFactor() doesn't work on my external DVI monitor. Excerpt from
$ gsettings list-recursively
on my Ubuntu 14.04 with "Scale for menu and title bars" set to 1.5:

org.gnome.eog.fullscreen upscale true
org.gnome.desktop.interface scaling-factor uint32 1
org.gnome.desktop.interface text-scaling-factor 1.5
org.gnome.eog.fullscreen upscale true
com.ubuntu.user-interface scale-factor {'VGA1': 8, 'DVI1': 12}
com.canonical.Unity.Interface text-scale-factor 1.0

You can't hardcode your local monitor port names in SWT. I guess you'll have to consider all monitors and take the maximal value that is currently present.

Do not add the Rectangle#scale(float) API at this time. It is not necessary, and it's probably not the right solution, because the int values make it prone to rounding errors.

I would expect Device#getDPI() to return scaled values.

Don't add API Resource#getEnableAutoScaling(). It's not at the right level.

I don't know if GTK currently supports separate DPI settings per monitor (I only have single-monitor machine). Anyway, all new APIs need to take this scenario into account, since the Mac and latest Windows versions do support it.

And I guess you're aware that Snippet367 still shows issues when painting directly to a Canvas.
Comment 29 Sravan Kumar Lakkimsetti CLA 2016-01-20 05:18:51 EST
There is suggestion to change the coordinate system on Gtk and Windows so we are working on that
Comment 30 Sravan Kumar Lakkimsetti CLA 2016-02-02 05:47:38 EST
*** Bug 486428 has been marked as a duplicate of this bug. ***
Comment 31 Markus Keller CLA 2016-02-10 06:12:14 EST
Device#getDeviceZoom() still doesn't work on my machine. Your guess that the com.ubuntu.user-interface scale-factor setting could be ordered by monitor was wrong. My system apparently has two ports, but the VGA port is not in use. OS.gdk_screen_get_n_monitors(screen) returns 1.

Fixed with http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=7c09ad04d6cb6523cccfb76938db05435fc59549
Comment 32 Markus Keller CLA 2016-02-11 06:19:03 EST
* When running Snippet367 at 200%, I saw that GC#drawRoundRectangle(..) only drew 1-pixel lines, but I would have expected 2-pixel lines. The default line width in scaled GCs should be 2 (in all APIs that draw lines).
GC#setLineWidth(int) has some evasive talk about line width 0. Nevertheless, we have to assume that clients just expect to get lines of width 1 if they didn't set a width; and 1px * 200% = 2px.

As you're already aware, there are still problems with the initial shell size. Furthermore, the "5. 50x50 box" in Snippet367 is too small. At 200%, the black box should use 100x100 screen pixels, but it only occupies 50x50.

* We need to make sure we get the APIs right now. We're already way past the schedule, and I still see things like Image#_getBounds(). Callers should use #getBounds(int) with the current zoom level.

When designing APIs, you need to shift your viewpoint to the client perspective and forget about the implementation for a while. Existing SWT APIs should continue to use SWT coordinates (usually called "points").

The big exception is ImageData, which deals with raw image data. There, clients that use the new APIs (those with an "int zoom" parameter) need to make sure they know at which zoom level the ImageData should be interpreted. I don't think ImageData#scaled makes sense. The old Image(Device, ImageData [..]) constructors should always assume the ImageData is at 100% and then zoom the image if necessary. Clients that want to support HiDPI images need to switch over to the constructor that takes an ImageDataProvider, and to the #get*(.., int zoom) APIs.

* Device#getDeviceZoom() gets called very often. The result needs to be cached.

When I'm back on 2016-02-22, these things should be done, and the API Javadocs should be in a presentable state (complete sentences; phrased towards the client, and not using terms like "the client").
Comment 33 Sravan Kumar Lakkimsetti CLA 2016-02-12 00:47:39 EST
(In reply to Markus Keller from comment #32)
> * When running Snippet367 at 200%, I saw that GC#drawRoundRectangle(..) only
> drew 1-pixel lines, but I would have expected 2-pixel lines. The default
> line width in scaled GCs should be 2 (in all APIs that draw lines).
> GC#setLineWidth(int) has some evasive talk about line width 0. 
-- I will check this problem


Nevertheless,
> we have to assume that clients just expect to get lines of width 1 if they
> didn't set a width; and 1px * 200% = 2px.
> 
> As you're already aware, there are still problems with the initial shell
> size. Furthermore, the "5. 50x50 box" in Snippet367 is too small. At 200%,
> the black box should use 100x100 screen pixels, but it only occupies 50x50.
> 
> * We need to make sure we get the APIs right now. We're already way past the
> schedule, and I still see things like Image#_getBounds(). Callers should use
> #getBounds(int) with the current zoom level.
> 
> When designing APIs, you need to shift your viewpoint to the client
> perspective and forget about the implementation for a while. Existing SWT
> APIs should continue to use SWT coordinates (usually called "points").
> 
> The big exception is ImageData, which deals with raw image data. There,
> clients that use the new APIs (those with an "int zoom" parameter) need to
> make sure they know at which zoom level the ImageData should be interpreted.
> I don't think ImageData#scaled makes sense.
-- this is done to solve specific problem where Image is created, image data is extracted and them again image is created using the imagedata. This very often done in the client code


 The old Image(Device, ImageData
> [..]) constructors should always assume the ImageData is at 100% and then
> zoom the image if necessary. Clients that want to support HiDPI images need
> to switch over to the constructor that takes an ImageDataProvider, and to
> the #get*(.., int zoom) APIs.
> 
> * Device#getDeviceZoom() gets called very often. The result needs to be
> cached.

-- This I have a plan to action on how get this fixed. I should be able to complete by that time


> 
> When I'm back on 2016-02-22, these things should be done, and the API
> Javadocs should be in a presentable state (complete sentences; phrased
> towards the client, and not using terms like "the client").
Comment 34 Markus Keller CLA 2016-02-12 06:39:56 EST
(In reply to Sravan Kumar Lakkimsetti from comment #33)
> > I don't think ImageData#scaled makes sense.
> -- this is done to solve specific problem where Image is created, image data
> is extracted and them again image is created using the imagedata. This very
> often done in the client code

I don't think so. E.g. with 200% zoom, existing client code that calls Image#getImageData() will get a scaled down ImageData with half the width/height of the internal data. When they call the Image(Device, ImageData) constructor and pass the same ImageData, the constructor always has to scale up the data.

The ImageData#scaled is only "necessary" to support broken client code that didn't entirely switch to the zoom-aware APIs. We should not try to hide problems due to broken code. And the boolean scaled will fall down as soon as the user switches the zoom level or we support separate zoom levels per monitor.
Client code that contains ImageData in their own APIs needs to offer zoom-aware variants of their APIs, similar to what SWT had to do in Image.

Another API problem: Class DPIUtil should be made package-private or moved into an internal package.
Comment 35 Sravan Kumar Lakkimsetti CLA 2016-02-12 07:38:45 EST
(In reply to Markus Keller from comment #34)
> (In reply to Sravan Kumar Lakkimsetti from comment #33)
> > > I don't think ImageData#scaled makes sense.
> > -- this is done to solve specific problem where Image is created, image data
> > is extracted and them again image is created using the imagedata. This very
> > often done in the client code
> 
> I don't think so. E.g. with 200% zoom, existing client code that calls
> Image#getImageData() will get a scaled down ImageData with half the
> width/height of the internal data. When they call the Image(Device,
> ImageData) constructor and pass the same ImageData, the constructor always
> has to scale up the data.
> 
> The ImageData#scaled is only "necessary" to support broken client code that
> didn't entirely switch to the zoom-aware APIs. We should not try to hide
> problems due to broken code. And the boolean scaled will fall down as soon
> as the user switches the zoom level or we support separate zoom levels per
> monitor.
> Client code that contains ImageData in their own APIs needs to offer
> zoom-aware variants of their APIs, similar to what SWT had to do in Image.
> 

-- Let me have a relook at this.
> Another API problem: Class DPIUtil should be made package-private or moved
> into an internal package.
-- We will be moving to Internal package
Comment 36 Sravan Kumar Lakkimsetti CLA 2016-02-19 00:33:45 EST
*** Bug 488052 has been marked as a duplicate of this bug. ***
Comment 38 Eclipse Genie CLA 2016-02-25 15:07:45 EST
New Gerrit change created: https://git.eclipse.org/r/67364
Comment 39 Eclipse Genie CLA 2016-02-25 15:08:09 EST
New Gerrit change created: https://git.eclipse.org/r/67365
Comment 40 Markus Keller CLA 2016-03-03 16:32:37 EST
We're making good progress in the slakkimsetti/HighDPIChangesforNeon branch.

Niraj and Sravan, please coordinate an API cleanup, so that I can eventually start a bigger review pass.

Problems that should be fixed:
- no API Tools errors against the 4.5.2 API Baseline (win32, I'm looking at you)
- no *inPixels(..) methods should be added, and no other unnecessary APIs
Hint: Use Compare With > API Baseline... on the project, and check against 4.5.2 or against a recent I-build
- no Javadocs on internal *inPixels(..) methods. I see many copied docs from API methods. These copies have a few problems:
  - Content is already out of date, since it deals with points, not pixels.
  - They will inevitably get more out-of-sync when API docs get updated.
  - They make it hard to see what's API and what not.
Comment 42 Eclipse Genie CLA 2016-03-14 07:17:42 EDT
New Gerrit change created: https://git.eclipse.org/r/68334
Comment 44 Jan Hurst CLA 2016-03-15 08:46:21 EDT
Hi, I've been following a while as I was impacted on a Surface Pro 4 and used various hacks/fixes on earlier versions...
 
Using Eclipse 4.5.2 64bit under Windows 8.1 I am also seeing small icons. Curiously, if I "Run as administrator" the icons appear to be scaled "corrctly", that is GUI seems well scaled including icons. Is this expected? Happy to provide further info if it is helpful.

Regards,
Jan
Comment 46 Matthias Becker CLA 2016-06-03 08:08:40 EDT
I tested the last Neon RC. The line numbers are still blurry on my MacBook.
Comment 47 Markus Keller CLA 2016-06-03 09:32:26 EDT
(In reply to Matthias Becker from comment #46)
> I tested the last Neon RC. The line numbers are still blurry on my MacBook.

Yes, sorry about that. We ran out of time for Neon. Bug 489451 will finally fix the blurry line numbers.