Skip to content

Commit c8d4aa9

Browse files
committed
[GTK][HiDpi] Code cleanup for removal of non-cairo scale path
Fixes #1300
1 parent f0cf578 commit c8d4aa9

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package org.eclipse.swt.tests.manual;
2+
/*******************************************************************************
3+
* Copyright (c) 2020 Syntevo and others.
4+
*
5+
* This program and the accompanying materials
6+
* are made available under the terms of the Eclipse Public License 2.0
7+
* which accompanies this distribution, and is available at
8+
* https://www.eclipse.org/legal/epl-2.0/
9+
*
10+
* SPDX-License-Identifier: EPL-2.0
11+
*
12+
* Contributors:
13+
* Syntevo - initial API and implementation
14+
*******************************************************************************/
15+
import org.eclipse.swt.SWT;
16+
import org.eclipse.swt.custom.CLabel;
17+
import org.eclipse.swt.graphics.GC;
18+
import org.eclipse.swt.graphics.Image;
19+
import org.eclipse.swt.graphics.ImageDataProvider;
20+
import org.eclipse.swt.graphics.Rectangle;
21+
import org.eclipse.swt.internal.DPIUtil;
22+
import org.eclipse.swt.layout.GridData;
23+
import org.eclipse.swt.layout.GridLayout;
24+
import org.eclipse.swt.widgets.Canvas;
25+
import org.eclipse.swt.widgets.Display;
26+
import org.eclipse.swt.widgets.Label;
27+
import org.eclipse.swt.widgets.Shell;
28+
public class Bug568641_GC_drawImage_IAE {
29+
static final int imageSZ = 20;
30+
static Image createTestImage(Display display) {
31+
final Image image = new Image(display, 20, 20);
32+
final GC gc = new GC(image);
33+
final int halfSZ = imageSZ / 2;
34+
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
35+
gc.fillRectangle(0, 0, halfSZ, halfSZ);
36+
gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
37+
gc.fillRectangle(halfSZ, 0, halfSZ, halfSZ);
38+
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
39+
gc.fillRectangle(0, halfSZ, halfSZ, halfSZ);
40+
gc.setBackground(display.getSystemColor(SWT.COLOR_MAGENTA));
41+
gc.fillRectangle(halfSZ, halfSZ, halfSZ, halfSZ);
42+
return image;
43+
}
44+
static Image createImageWithZoom(Image srcImage, int zoom, boolean isProvider) {
45+
final int oldZoom = DPIUtil.getDeviceZoom();
46+
DPIUtil.setDeviceZoom(zoom);
47+
final Image image;
48+
if (isProvider) {
49+
ImageDataProvider imageProvider = _zoom -> srcImage.getImageData(_zoom);
50+
image = new Image(srcImage.getDevice(), imageProvider);
51+
} else {
52+
image = new Image(srcImage.getDevice(), srcImage.getImageData());
53+
}
54+
DPIUtil.setDeviceZoom(oldZoom);
55+
return image;
56+
}
57+
static void drawImage(GC gc, Image srcImage, int zoom, boolean isProvider, int x, int y, boolean simple) {
58+
// Image needs to be created each time, because painting it once
59+
// will update internal state and prevent proper testing
60+
final Image image = createImageWithZoom(srcImage, zoom, isProvider);
61+
if (simple)
62+
gc.drawImage(image, x, y);
63+
else {
64+
final Rectangle bounds = image.getBounds();
65+
gc.drawImage(image, bounds.x, bounds.y, bounds.width, bounds.height, x, y, bounds.width, bounds.height);
66+
}
67+
}
68+
static void verifyBounds(Image srcImage, int zoom, boolean isProvider) {
69+
final Image image = createImageWithZoom(srcImage, zoom, isProvider);
70+
{
71+
final Rectangle bounds = image.getBounds();
72+
int expected = imageSZ;
73+
if ((bounds.x != 0) || (bounds.y != 0) || (bounds.width != expected) || (bounds.height != expected)) {
74+
System.out.println(
75+
"ERROR: Incorrect Image.getBounds(): zoom=" + zoom +
76+
" provider=" + (isProvider ? 'Y' : 'N') +
77+
" expected=" + expected +
78+
" actual=" + bounds.width);
79+
}
80+
}
81+
{
82+
final Rectangle bounds = image.getBounds();
83+
int expected = imageSZ * zoom / 100;
84+
if ((bounds.x != 0) || (bounds.y != 0) || (bounds.width != expected) || (bounds.height != expected)) {
85+
System.out.println(
86+
"ERROR: Incorrect Image.getBoundsInPixels(): zoom=" + zoom +
87+
" provider=" + (isProvider ? 'Y' : 'N') +
88+
" expected=" + expected +
89+
" actual=" + bounds.width);
90+
}
91+
}
92+
}
93+
public static void main(String[] args) {
94+
// System.setProperty("swt.autoScale", "false");
95+
final Display display = new Display();
96+
final Shell shell = new Shell(display);
97+
shell.setLayout(new GridLayout(1, true));
98+
Label hint = new Label(shell, 0);
99+
hint.setText(
100+
"1) Start snippet at DPI=100%\n" +
101+
"2) Check console for errors\n" +
102+
"3) Snippet will crash with IllegalArgumentException in GC.drawImage()\n" +
103+
"\n" +
104+
"For CLabel demo:\n" +
105+
"1) Go to your OS system settings and change Display DPI to 200%\n" +
106+
"2) Start this snippet\n" +
107+
"3) Change Display DPI to 100%\n" +
108+
"4) Snippet will crash with IllegalArgumentException in GC.drawImage()"
109+
);
110+
final Image image = createTestImage(display);
111+
// A demonstration that bug occurs even without trickery
112+
ImageDataProvider imageProvider = zoom -> image.getImageData(zoom);
113+
CLabel label = new CLabel(shell, 0);
114+
label.setImage(new Image(display, imageProvider));
115+
// A more detailed test of all combinations
116+
final int margin = imageSZ;
117+
Canvas canvas = new Canvas(shell, 0);
118+
canvas.setLayoutData(new GridData(10*imageSZ, 5*imageSZ));
119+
canvas.addListener(SWT.Paint, event -> {
120+
int y = 0;
121+
for (int iIsProvider = 0; iIsProvider < 2; iIsProvider++)
122+
{
123+
boolean isProvider = (iIsProvider == 0) ? false : true;
124+
int x = 3;
125+
verifyBounds(image, 100, isProvider);
126+
drawImage(event.gc, image, 100, isProvider, x, y, true);
127+
x += imageSZ + margin;
128+
drawImage(event.gc, image, 100, isProvider, x, y, false);
129+
x += imageSZ + margin;
130+
verifyBounds(image, 200, isProvider);
131+
drawImage(event.gc, image, 200, isProvider, x, y, true);
132+
x += imageSZ + margin;
133+
drawImage(event.gc, image, 200, isProvider, x, y, false);
134+
x += imageSZ + margin;
135+
y += imageSZ + margin;
136+
}
137+
});
138+
shell.pack();
139+
shell.open();
140+
while (!shell.isDisposed()) {
141+
if (!display.readAndDispatch()) {
142+
display.sleep();
143+
}
144+
}
145+
display.dispose();
146+
}
147+
}

0 commit comments

Comments
 (0)