Skip to content

Commit 8934a73

Browse files
committed
GC.setClipping(path) doesn't paint on Linux when transformed #3120
The fix for Bug 531667 (d7ce597) introduced a regression when calling `setClipping(Path)` after `setTransform(Transform)`. The rectangle used when resetting the clip doesn't consider the previously done transformation, producing an empty clip if this rectangle and the `Path` don't intersect. Instead of using the local `clipping` variable (which contains the initial clip when the GC was created), the `resetClipping()` method now uses the rectangle returned by `getClipping()`, which internally applies the transformation matrix. To reproduce, execute the attached snippet. The rectangle in this example should be green, as it is drawn over the red rectangle. Closes #3120
1 parent cc2762f commit 8934a73

2 files changed

Lines changed: 124 additions & 30 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Patrick Ziegler and others.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*
10+
* Contributors:
11+
* Patrick Ziegler - initial API and implementation
12+
*******************************************************************************/
13+
package org.eclipse.swt.tests.gtk.snippets;
14+
15+
import org.eclipse.swt.SWT;
16+
import org.eclipse.swt.graphics.GC;
17+
import org.eclipse.swt.graphics.Path;
18+
import org.eclipse.swt.graphics.Transform;
19+
import org.eclipse.swt.layout.FillLayout;
20+
import org.eclipse.swt.widgets.Display;
21+
import org.eclipse.swt.widgets.Shell;
22+
23+
/**
24+
* Description: {@link GC#setClipping(Path)} doesn't respect a previous call to
25+
* {@link GC#setTransform(Transform)}.
26+
* <ol>
27+
* <li>Run the snippet.</li>
28+
* </ol>
29+
* Expected results: The painted rectangle should be green.<br>
30+
* Actual results: The painted rectangle is red.
31+
*
32+
* @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=531667">Bug
33+
* 531667 - [GTK3] Cannot draw Canvas with Control.print(GC) </a>
34+
*/
35+
public class Issue3120_GC_setClipping_is_wrong_after_transform {
36+
37+
public static void main(String[] args) {
38+
Shell shell = new Shell();
39+
shell.setLayout(new FillLayout());
40+
shell.setSize(600, 300);
41+
42+
Display display = shell.getDisplay();
43+
44+
shell.addPaintListener(event -> {
45+
GC gc = event.gc;
46+
47+
Path p = new Path(display);
48+
p.addRectangle(50, 350, 100, 100);
49+
50+
Transform t = new Transform(display);
51+
t.translate(0, -300);
52+
53+
gc.setTransform(t);
54+
55+
gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
56+
gc.fillPath(p);
57+
gc.setClipping(p);
58+
gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
59+
gc.fillPath(p);
60+
61+
p.dispose();
62+
63+
gc.setTransform(null);
64+
t.dispose();
65+
});
66+
67+
shell.open();
68+
69+
while(!shell.isDisposed()) {
70+
if(!display.readAndDispatch()) {
71+
display.sleep();
72+
}
73+
}
74+
}
75+
}

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import static org.eclipse.swt.internal.DPIUtil.pointToPixel;
1818
import static org.eclipse.swt.tests.junit.SwtTestUtil.assertSWTProblem;
19+
import static org.junit.jupiter.api.Assertions.assertAll;
1920
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2021
import static org.junit.jupiter.api.Assertions.assertEquals;
2122
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -791,42 +792,60 @@ public void test_setBackgroundLorg_eclipse_swt_graphics_Color() {
791792
"No exception thrown for color disposed");
792793
}
793794

795+
@Test
796+
public void test_setClippingIIII_withTransform() {
797+
Transform t = new Transform(gc.getDevice());
798+
t.scale(1.5f,0.5f);
799+
t.translate(-5,-25);
800+
801+
gc.setClipping(0,5,10,20);
802+
gc.setTransform(t);
803+
804+
Rectangle rect = gc.getClipping();
805+
assertAll(
806+
() -> assertEquals(5,rect.x),
807+
() -> assertEquals(35, rect.y),
808+
() -> assertEquals(7,rect.width),
809+
() -> assertEquals(40,rect.height));
810+
}
811+
794812
@Test
795813
public void test_setClippingIIII() {
796-
// intermittently fails on XP for reasons unknown, comment out the test case
797-
// until the problem is figured out
798-
// Canvas canvas = new Canvas(shell, SWT.BORDER);
799-
// shell.setSize(110,110);
800-
// canvas.setSize(100,100);
801-
// shell.open();
802-
// GC testGc = new GC(canvas);
803-
// testGc.setClipping(0,5,10,20);
804-
// Rectangle rect = testGc.getClipping();
805-
// assertTrue(rect.x == 0);
806-
// assertTrue(rect.y == 5);
807-
// assertTrue(rect.width == 10);
808-
// assertTrue(rect.height == 20);
809-
// testGc.dispose();
810-
// canvas.dispose();
814+
gc.setClipping(0,5,10,20);
815+
Rectangle rect = gc.getClipping();
816+
assertAll(
817+
() -> assertEquals(0,rect.x),
818+
() -> assertEquals(5, rect.y),
819+
() -> assertEquals(10,rect.width),
820+
() -> assertEquals(20,rect.height));
821+
}
822+
823+
@Test
824+
public void test_setClippingLorg_eclipse_swt_graphics_Rectangle_withTransform() {
825+
Transform t = new Transform(gc.getDevice());
826+
t.scale(1.5f,0.5f);
827+
t.translate(-5,-25);
828+
829+
gc.setClipping(new Rectangle(0,5,10,20));
830+
gc.setTransform(t);
831+
832+
Rectangle rect = gc.getClipping();
833+
assertAll(
834+
() -> assertEquals(5,rect.x),
835+
() -> assertEquals(35, rect.y),
836+
() -> assertEquals(7,rect.width),
837+
() -> assertEquals(40,rect.height));
811838
}
812839

813840
@Test
814841
public void test_setClippingLorg_eclipse_swt_graphics_Rectangle() {
815-
// intermittently fails on XP for reasons unknown, comment out the test case
816-
// until the problem is figured out
817-
// Canvas canvas = new Canvas(shell, SWT.BORDER);
818-
// shell.setSize(110,110);
819-
// canvas.setSize(100,100);
820-
// shell.open();
821-
// GC testGc = new GC(canvas);
822-
// testGc.setClipping(new Rectangle(0,5,10,20));
823-
// Rectangle rect = testGc.getClipping();
824-
// assertTrue(rect.x == 0);
825-
// assertTrue(rect.y == 5);
826-
// assertTrue(rect.width == 10);
827-
// assertTrue(rect.height == 20);
828-
// testGc.dispose();
829-
// canvas.dispose();
842+
gc.setClipping(new Rectangle(0,5,10,20));
843+
Rectangle rect = gc.getClipping();
844+
assertAll(
845+
() -> assertEquals(0,rect.x),
846+
() -> assertEquals(5, rect.y),
847+
() -> assertEquals(10,rect.width),
848+
() -> assertEquals(20,rect.height));
830849
}
831850

832851
@Test

0 commit comments

Comments
 (0)