Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimeon Andreev2019-05-21 10:30:43 +0000
committerSimeon Andreev2019-06-12 14:13:35 +0000
commit73ef71fcbec0f8c22797049437f4824612ef3a64 (patch)
treed6f8790464f7f5d5c87678f5be2d678629f4af3b /bundles
parenta09fd5ce015e751c6e1b365e563e6cba8a65fa3d (diff)
downloadeclipse.platform.swt-73ef71fcbec0f8c22797049437f4824612ef3a64.tar.gz
eclipse.platform.swt-73ef71fcbec0f8c22797049437f4824612ef3a64.tar.xz
eclipse.platform.swt-73ef71fcbec0f8c22797049437f4824612ef3a64.zip
Bug 545226 - [GTK3] GC transforms don't affect GC.getClipping()
Changes done to fix bug 531667 and follow-up problems introduce a regression. Namely, the result of GC.getClipping() is incorrect. Drawing is correct, but the bounds returned by GC.getClipping() are not affected by transformations set by the user on the GC object. This is not consistent with previous behaviour and with behaviour on other platforms (e.g. Windows 10). This change re-adds the necessary transformations, in order to have a consistent GC.getClipping() result. A snippet is added that showcases the problem. Change-Id: I33b06bb8338215f52cb02d248564b792a750067e Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
Diffstat (limited to 'bundles')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/GC.java55
1 files changed, 54 insertions, 1 deletions
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 61386eda38..a841d7e07a 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
@@ -13,6 +13,8 @@
*******************************************************************************/
package org.eclipse.swt.graphics;
+import java.util.*;
+
import org.eclipse.swt.*;
import org.eclipse.swt.internal.*;
import org.eclipse.swt.internal.cairo.*;
@@ -2054,7 +2056,53 @@ Rectangle getClippingInPixels() {
if (clipRgn != 0) {
/* Convert clipping to device space if needed */
if (data.clippingTransform != null && GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) {
- clipRgn = convertRgn(clipRgn, data.clippingTransform);
+ clipRgn = convertRgn(clipRgn, data.clippingTransform);
+ Cairo.cairo_region_intersect(rgn, clipRgn);
+ Cairo.cairo_region_destroy(clipRgn);
+ } else if (!Arrays.equals(data.clippingTransform, currentTransform) && GTK.GTK_VERSION >= OS.VERSION (3, 14, 0)) {
+ double[] clippingTransform;
+ if (currentTransform != null && data.clippingTransform == null) {
+ /*
+ * User actions in this case are:
+ * 1. Set clipping.
+ * 2. Set a transformation B.
+ *
+ * The clipping was specified before transformation B was set.
+ * So to convert it to the new space, we just invert the transformation B.
+ */
+ clippingTransform = currentTransform.clone();
+ Cairo.cairo_matrix_invert(clippingTransform);
+ } else if (currentTransform != null && data.clippingTransform != null) {
+ /*
+ * User actions in this case are:
+ * 1. Set a transformation A.
+ * 2. Set clipping.
+ * 3. Set a different transformation B. This is global and wipes out transformation A.
+ *
+ * Since step 3. wipes out transformation A, we must apply A on the clipping rectangle to have
+ * the correct clipping rectangle after transformation A is wiped.
+ * Then, we apply the inverted transformation B on the resulting clipping,
+ * to convert it to the new space (which results after applying B).
+ */
+ clippingTransform = new double[6];
+ double[] invertedCurrentTransform = currentTransform.clone();
+ Cairo.cairo_matrix_invert(invertedCurrentTransform);
+ Cairo.cairo_matrix_multiply(clippingTransform, data.clippingTransform, invertedCurrentTransform);
+ } else {
+ /*
+ * User actions in this case are:
+ * 1. Set a transformation A.
+ * 2. Set clipping.
+ * 3. Wipe the transformation A (i.e. call GC.setTransformation(A)).
+ *
+ * We must apply transformation A on the clipping, to convert it to the new space.
+ */
+ clippingTransform = data.clippingTransform.clone();
+ }
+ long oldRgn = rgn;
+ rgn = convertRgn(rgn, clippingTransform);
+ Cairo.cairo_region_destroy(oldRgn);
+ clipRgn = convertRgn(clipRgn, clippingTransform);
Cairo.cairo_region_intersect(rgn, clipRgn);
Cairo.cairo_region_destroy(clipRgn);
} else {
@@ -3047,6 +3095,11 @@ void setClipping(long clipRgn) {
if (GTK.GTK_VERSION < OS.VERSION (3, 14, 0)) {
if (data.clippingTransform == null) data.clippingTransform = new double[6];
Cairo.cairo_get_matrix(cairo, data.clippingTransform);
+ } else if (currentTransform != null) {
+ // store the current transformation, to use it when the user requests clipping bounds
+ data.clippingTransform = currentTransform.clone();
+ } else {
+ data.clippingTransform = null;
}
setCairoClip(data.damageRgn, clipRgn);
}

Back to the top