diff options
author | Simeon Andreev | 2019-05-21 10:30:43 +0000 |
---|---|---|
committer | Simeon Andreev | 2019-06-12 14:13:35 +0000 |
commit | 73ef71fcbec0f8c22797049437f4824612ef3a64 (patch) | |
tree | d6f8790464f7f5d5c87678f5be2d678629f4af3b /bundles | |
parent | a09fd5ce015e751c6e1b365e563e6cba8a65fa3d (diff) | |
download | eclipse.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.java | 55 |
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); } |