Skip to content

Unexpected sizing when drawing an Image with ImageGcDrawer on a GC on zoom != 100 #554

@akoch-yatta

Description

@akoch-yatta

Description
If you execute the following snippet on a monitor != 100%, you will see:

Executed on 175% primary monitor
Image

Expected would be
Image

It is caused by the call

drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false, image.getHandle(scaledImageZoom, data.nativeZoom));

in GC#drawImage. The calculated value for scaledImageZoom will be 100% in this scenario, while data.nativeZoom is 175%.

The original idea behind this behavior is to properly render images with autoScale modes != quarter, so e.g. on a 125% monitor with mode integer200, it is necessary that e.g. the fonts will still be rendered with 125% instead of the autoscaled zoom of 100.

Important: This issue can only occur in the combination of Image+GC, because of the implementation in Image#getHandle(int, int)and its delegation of the zooms to AbstractImageProviderWrapper#getFittingZoomContext. That will alawys return a ZoomContext using scaledImageZoom except when Image#memGc is!= null or the ImageGcDrawer is used.

Important: Any change here could break scenarios either with the default mode integer200 or a fixed zoom like -Dswt.autoScale=150

Reproduction
Execute the following Snippet with a primary monitor != 100%

public class Snippet10 {
	public static void main(String[] args) {
		final Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setText("Advanced Graphics");
		FontData fd = shell.getFont().getFontData()[0];
		final Font font = new Font(display, fd.getName(), 60, SWT.BOLD | SWT.ITALIC);
		final ImageGcDrawer imageGcDrawer = (gc, imageWidth, imageHeight) -> {
			gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
			gc.fillOval(0, 0, imageWidth, imageHeight);
		};
		final Image image = new Image(display,imageGcDrawer, 640, 480);
		final Rectangle rect = image.getBounds();
		shell.addListener(SWT.Paint, event -> {
			GC gc1 = event.gc;
			Transform tr = new Transform(display);
			tr.translate(50, 120);
			tr.rotate(-30);
			gc1.drawImage(image, 0, 0, rect.width, rect.height, 0, 0, rect.width / 2, rect.height / 2);
			gc1.setAlpha(100);
			gc1.setTransform(tr);
			Path path = new Path(display);
			path.addString("SWT", 0, 0, font);
			gc1.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
			gc1.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
			gc1.fillPath(path);
			gc1.drawPath(path);
			tr.dispose();
			path.dispose();
		});
		shell.setSize(shell.computeSize(rect.width / 2, rect.height / 2));
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		image.dispose();
		font.dispose();
		display.dispose();
	}
}

Metadata

Metadata

Assignees

Labels

HiDPIA HiDPI-Related Issue or FeatureSWTIssue for SWT

Type

No type

Projects

Status

👀 In Review

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions