Skip to content

[Win32] Drawing produces asymmetrical results without swt.autoScale=false for 4k monitor with zooming #1596

Open

Description

@tmssngr

Describe the bug
Code that draws a circle and and a line symmetric with 100% zoom causes asymmetric results with 175% zoom factor.

To Reproduce
Run following snippet

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public class HiDpiDrawing {
	public static void main(String[] args) {
//		System.getProperties().putIfAbsent("swt.autoScale", "false");
		final Display display = new Display();

		final Shell shell = new Shell(display);
		shell.addListener(SWT.Paint, event -> {
			final GC gc = event.gc;
			gc.setAntialias(SWT.ON);
			gc.setLineWidth(3);
			final Path path = new Path(display);
			int radius = 3;
			path.moveTo(15, 0);
			path.lineTo(15, 15 - radius);
			path.moveTo(15, 15 + radius);
			path.lineTo(15, 100);
			gc.drawPath(path);
			path.dispose();
			gc.setBackground(gc.getForeground());
			drawOval(gc, radius + 2);
			gc.setBackground(new Color(255, 255, 255));
			drawOval(gc, radius);
		});

		shell.setSize(400, 300);
		shell.open();

		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

		shell.dispose();
	}

	private static void drawOval(GC gc, int radius) {
		gc.fillOval(15 - radius, 15 - radius, 2 * radius + 1, 2 * radius + 1);
	}
}

on Windows with 100% zoom level and with 175% zoom level.

Expected behavior
The dot is always drawn symmetric to the line, no matter what zoom level (otherwise it would look ugly).

Screenshots
With 100% zoom level:
100
close-up:
100%-zoomed
With 175% zoom level:
175
close-up:
175%-zoomed

When removing the // from the comment line, the result looks fine for 175% zoom, too.

Environment:

  1. Select the platform(s) on which the behavior is seen:
    • All OS
    • Windows
    • Linux
    • macOS
  1. Additional OS info (e.g. OS version, Linux Desktop, etc)
    Tried on Windows 11 with 4k monitor.

Activity

  1. tmssngr commented on Nov 15, 2024

    @tmssngr
    ContributorAuthor

    With swt.autoScale=quarter or exact it looks even worse:
    175%-swt autoScale=quarter
    close-up:
    175%-swt autoScale=quarter-zoomed
    Hence it looks like there is no way to draw symmetric elements without setting swt.autoScale=false.

  2. HeikoKlare commented on Nov 15, 2024

    @HeikoKlare
    Contributor

    The oval at 100% is also asymmetric (can be seen in different colors from anti-aliasing), it only becomes more visible at 175% because the calculation is more off. With swt.autoScale=false you just hide that as rendering just still happens at 100%, where the asymmetry is only harder to see.

  3. tmssngr commented on Nov 15, 2024

    @tmssngr
    ContributorAuthor

    Asking users, I reckon 99% would answer the 100% version looks symmetric.

    How do we need to draw these elements that they look fine between 100% and 200% zoom level for 99% of the users?

  4. HeikoKlare commented on Nov 15, 2024

    @HeikoKlare
    Contributor

    Asking users, I reckon 99% would answer the 100% version looks symmetric.

    Might be, but what does that change? Using the 175% version and placing users at 175% the distance of the monitor than when using the 100% version, they will probably also consider it symmetric...
    It's asymmetric, so there seems to be a bug in rendering, which is more visible when using higher scale values. There is nothing better in using swt.autoScale=false than using any other scale value with respect to symmetry. Things are simply just too small to see it when using no scaling for HiDPI monitors.

    How do we need to draw these elements that they look fine between 100% and 200% zoom level for 99% of the users?

    My first impression is that this is a bug in SWT. So there may be no other way than looking into SWT code, finding the cause of the bug, and fixing it.

  5. tmssngr commented on Nov 15, 2024

    @tmssngr
    ContributorAuthor

    With swt.autoScale=false I have the possibility to optimize it for larger zoom levels, because I have control over all pixels, not just control over double-pixels:
    175%-swt autoScale=false
    Close-up:
    175%-swt autoScale=false-zoomed

    IMHO one problem is that pixel coordinates simply are scaled. But there are draw operations like fillXxx that expect the right/lower coordinate outside the drawn area. The other problem is that for most draw operations only int coordinates are allowed, so it scales only to multiples of 2.

    I wonder how other drawing APIs handle such fractional scaling.

  6. laeubi commented on Nov 16, 2024

    @laeubi
    Contributor

    If I look at your snippet I'm not sure you are taking the line width into account correctly, you set a line width of three but I can't find you possibly account for this.

    Beside that, yes only having int coordinates (except for example Path) is a big limitation compared to e.g. AWTs Graphics2D, e.g AWT uses the concept of Shapes what is really convenient and powerful.

  7. tmssngr commented on Nov 18, 2024

    @tmssngr
    ContributorAuthor

    @laeubi In SmartGit we are using the zoom factor (1 or 2) to draw the lines with the correct width. The result looks correct with all zoom levels.

  8. tmssngr commented on Nov 19, 2024

    @tmssngr
    ContributorAuthor

    Assuming following code:

    gc.setLineWidth(1);
    gc.drawLine(0, 1, 10, 1);

    what exactly we can expect to happen for 100% zoom level and especially for 200% zoom level? How wide the line should be with 200% zoom (I'd expect 2 pixels), where exactly it should be drawn, should the line be fully visible if drawn at the coordinate 0?

    Assuming the following code:

    gc.fillRect(1, 1, 10, 5);

    how wide the rect (in pixels) should be with 200% zoom? Which pixels should be covered?

    Should we expect to get the same rendering result on all 3 platforms?

  9. added 2 commits that reference this issue on Nov 21, 2024
  10. tmssngr commented on Nov 21, 2024

    @tmssngr
    ContributorAuthor

    Please give the pull request a try.

  11. BeckerWdf commented on Nov 21, 2024

    @BeckerWdf
    Member

    Please give the pull request a try.

    You mean this one: #1607 ?

  12. tmssngr commented on Nov 22, 2024

    @tmssngr
    ContributorAuthor

    Yes, this the PR #1607. I know that it can't be merged right now because of feature-freeze, but I want you to give it a try.

  13. added a commit that references this issue on Nov 26, 2024
  14. changed the title [-][Win32] Drawing produces unsymmetric results without swt.autoScale=false for 4k monitor with zooming[/-] [+][Win32] Drawing produces asymmetrical results without swt.autoScale=false for 4k monitor with zooming[/+] on Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions