diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java index 70632dbc2ca..4fa26210447 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java @@ -548,7 +548,13 @@ void copyAreaInPixels(int srcX, int srcY, int width, int height, int destX, int Cairo.cairo_set_source_surface(handle, data.image.surface, deltaX, deltaY); Cairo.cairo_rectangle(handle, destX, destY, width, height); Cairo.cairo_set_operator(handle, Cairo.CAIRO_OPERATOR_SOURCE); + // As source and target area may be overlapping, we need to draw on + // an intermediate surface to avoid that parts of the source area are + // overwritten before reading it to be copied + Cairo.cairo_push_group(handle); Cairo.cairo_fill(handle); + Cairo.cairo_pop_group_to_source(handle); + Cairo.cairo_paint(handle); } else if (drawable != 0) { Cairo.cairo_save(handle); Cairo.cairo_rectangle(handle, destX, destY, width, height); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java index b51af22f7eb..e518cfda153 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Image.java @@ -1260,11 +1260,7 @@ void init(int width, int height) { this.type = SWT.BITMAP; /* Create the pixmap */ - if (GTK.GTK4) { - surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_RGB24, width, height); - } else { - surface = GDK.gdk_window_create_similar_surface(GDK.gdk_get_default_root_window(), Cairo.CAIRO_CONTENT_COLOR, width, height); - } + surface = Cairo.cairo_image_surface_create(Cairo.CAIRO_FORMAT_ARGB32, width, height); if (surface == 0) SWT.error(SWT.ERROR_NO_HANDLES); // When we create a blank image we need to set it to 100 in GTK3 as we draw using 100% scale. // Cairo will take care of scaling for us when image needs to be scaled. 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 0e0d79f1368..f1b9b6aa808 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 @@ -172,6 +172,52 @@ public void test_copyAreaIIIIII() { assertEquals(":d:", whiteRGB, palette.getRGB(pixel)); } +@Test +public void test_copyAreaIIIIII_overlapingSourceTarget() { + Color red= display.getSystemColor(SWT.COLOR_RED); + Color blue = display.getSystemColor(SWT.COLOR_BLUE); + RGB redRGB = getRealRGB(red); + RGB blueRGB = getRealRGB(blue); + + gc.setBackground(red); + gc.fillRectangle(image.getBounds()); + gc.setBackground(blue); + gc.fillRectangle(0, 100, 200, 100); + + ImageData imageData = image.getImageData(); + PaletteData palette = imageData.palette; + + int pixel = imageData.getPixel(0, 0); + assertEquals(redRGB, palette.getRGB(pixel)); + pixel = imageData.getPixel(0, 105); + assertEquals(blueRGB, palette.getRGB(pixel)); + pixel = imageData.getPixel(0, 155); + assertEquals(blueRGB, palette.getRGB(pixel)); + + gc.copyArea(0, 50, 200, 100, 0, 100); + + imageData = image.getImageData(); + palette = imageData.palette; + + if (DPIUtil.getDeviceZoom() != 100) { + //TODO Fix non integer scaling factors. + if (SwtTestUtil.verbose) { + System.out.println("Excluded test_copyAreaIIIIII(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_graphics_GC)"); + } + return; + } + + pixel = imageData.getPixel(0, 105); + assertEquals(redRGB, palette.getRGB(pixel)); + pixel = imageData.getPixel(0, 145); + assertEquals(redRGB, palette.getRGB(pixel)); + pixel = imageData.getPixel(0, 155); + assertEquals(blueRGB, palette.getRGB(pixel)); + pixel = imageData.getPixel(0, 195); + assertEquals(blueRGB, palette.getRGB(pixel)); +} + + @Test public void test_copyAreaLorg_eclipse_swt_graphics_ImageII() { Color white = display.getSystemColor(SWT.COLOR_WHITE);