diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3120_GC_setClipping_is_wrong_after_transform.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3120_GC_setClipping_is_wrong_after_transform.java
new file mode 100644
index 0000000000..c3529a0bd1
--- /dev/null
+++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Issue3120_GC_setClipping_is_wrong_after_transform.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Patrick Ziegler and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Patrick Ziegler - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.swt.tests.gtk.snippets;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Path;
+import org.eclipse.swt.graphics.Transform;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Description: {@link GC#setClipping(Path)} doesn't respect a previous call to
+ * {@link GC#setTransform(Transform)}.
+ *
+ * - Run the snippet.
+ *
+ * Expected results: The painted rectangle should be green.
+ * Actual results: The painted rectangle is red.
+ *
+ * @see Bug
+ * 531667 - [GTK3] Cannot draw Canvas with Control.print(GC)
+ */
+public class Issue3120_GC_setClipping_is_wrong_after_transform {
+
+ public static void main(String[] args) {
+ Shell shell = new Shell();
+ shell.setLayout(new FillLayout());
+ shell.setSize(600, 300);
+
+ Display display = shell.getDisplay();
+
+ shell.addPaintListener(event -> {
+ GC gc = event.gc;
+
+ Path p = new Path(display);
+ p.addRectangle(50, 350, 100, 100);
+
+ Transform t = new Transform(display);
+ t.translate(0, -300);
+
+ gc.setTransform(t);
+
+ gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
+ gc.fillPath(p);
+ gc.setClipping(p);
+ gc.setBackground(display.getSystemColor(SWT.COLOR_GREEN));
+ gc.fillPath(p);
+
+ p.dispose();
+
+ gc.setTransform(null);
+ t.dispose();
+ });
+
+ shell.open();
+
+ while(!shell.isDisposed()) {
+ if(!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java
index 563f4cbecb..1aea90fb92 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_graphics_GC.java
@@ -16,6 +16,7 @@
import static org.eclipse.swt.internal.DPIUtil.pointToPixel;
import static org.eclipse.swt.tests.junit.SwtTestUtil.assertSWTProblem;
+import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -45,6 +46,7 @@
import org.eclipse.swt.graphics.ImageGcDrawer;
import org.eclipse.swt.graphics.LineAttributes;
import org.eclipse.swt.graphics.PaletteData;
+import org.eclipse.swt.graphics.Path;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
@@ -791,42 +793,102 @@ public void test_setBackgroundLorg_eclipse_swt_graphics_Color() {
"No exception thrown for color disposed");
}
+@Test
+public void test_setClippingIIII_withTransform() {
+ Transform t = new Transform(gc.getDevice());
+ t.scale(1.5f,0.5f);
+ t.translate(-5,-25);
+
+ gc.setClipping(0,5,10,20);
+ gc.setTransform(t);
+ t.dispose();
+
+ Rectangle rect = gc.getClipping();
+ assertAll(
+ () -> assertEquals(5,rect.x),
+ () -> assertEquals(35, rect.y),
+ () -> assertEquals(7,rect.width),
+ () -> assertEquals(40,rect.height));
+
+}
+
@Test
public void test_setClippingIIII() {
- // intermittently fails on XP for reasons unknown, comment out the test case
- // until the problem is figured out
-// Canvas canvas = new Canvas(shell, SWT.BORDER);
-// shell.setSize(110,110);
-// canvas.setSize(100,100);
-// shell.open();
-// GC testGc = new GC(canvas);
-// testGc.setClipping(0,5,10,20);
-// Rectangle rect = testGc.getClipping();
-// assertTrue(rect.x == 0);
-// assertTrue(rect.y == 5);
-// assertTrue(rect.width == 10);
-// assertTrue(rect.height == 20);
-// testGc.dispose();
-// canvas.dispose();
+ gc.setClipping(0,5,10,20);
+ Rectangle rect = gc.getClipping();
+ assertAll(
+ () -> assertEquals(0,rect.x),
+ () -> assertEquals(5, rect.y),
+ () -> assertEquals(10,rect.width),
+ () -> assertEquals(20,rect.height));
+}
+
+@Test
+public void test_setClippingLorg_eclipse_swt_graphics_Rectangle_withTransform() {
+ Transform t = new Transform(gc.getDevice());
+ t.scale(1.5f,0.5f);
+ t.translate(-5,-25);
+
+ gc.setClipping(new Rectangle(0,5,10,20));
+ gc.setTransform(t);
+ t.dispose();
+
+ Rectangle rect = gc.getClipping();
+ assertAll(
+ () -> assertEquals(5,rect.x),
+ () -> assertEquals(35, rect.y),
+ () -> assertEquals(7,rect.width),
+ () -> assertEquals(40,rect.height));
+
}
@Test
public void test_setClippingLorg_eclipse_swt_graphics_Rectangle() {
- // intermittently fails on XP for reasons unknown, comment out the test case
- // until the problem is figured out
-// Canvas canvas = new Canvas(shell, SWT.BORDER);
-// shell.setSize(110,110);
-// canvas.setSize(100,100);
-// shell.open();
-// GC testGc = new GC(canvas);
-// testGc.setClipping(new Rectangle(0,5,10,20));
-// Rectangle rect = testGc.getClipping();
-// assertTrue(rect.x == 0);
-// assertTrue(rect.y == 5);
-// assertTrue(rect.width == 10);
-// assertTrue(rect.height == 20);
-// testGc.dispose();
-// canvas.dispose();
+ gc.setClipping(new Rectangle(0,5,10,20));
+ Rectangle rect = gc.getClipping();
+ assertAll(
+ () -> assertEquals(0,rect.x),
+ () -> assertEquals(5, rect.y),
+ () -> assertEquals(10,rect.width),
+ () -> assertEquals(20,rect.height));
+}
+
+@Test
+public void test_setClippingLorg_eclipse_swt_graphics_Path_withTransform() {
+ Transform t = new Transform(gc.getDevice());
+ t.scale(1.5f,0.5f);
+ t.translate(-5,-25);
+
+ Path p = new Path(gc.getDevice());
+ p.addRectangle(0, 5, 10, 20);
+
+ gc.setClipping(p);
+ p.dispose();
+ gc.setTransform(t);
+ t.dispose();
+
+ Rectangle rect = gc.getClipping();
+ assertAll(
+ () -> assertEquals(5,rect.x),
+ () -> assertEquals(35, rect.y),
+ () -> assertEquals(7,rect.width),
+ () -> assertEquals(40,rect.height));
+
+ t.dispose();
+}
+
+@Test
+public void test_setClippingLorg_eclipse_swt_graphics_Path() {
+ Path p = new Path(gc.getDevice());
+ p.addRectangle(0, 5, 10, 20);
+ gc.setClipping(p);
+ p.dispose();
+ Rectangle rect = gc.getClipping();
+ assertAll(
+ () -> assertEquals(0,rect.x),
+ () -> assertEquals(5, rect.y),
+ () -> assertEquals(10,rect.width),
+ () -> assertEquals(20,rect.height));
}
@Test