@@ -43,6 +43,8 @@ public final class Region extends Resource {
4343
4444 private boolean isDestroyed ;
4545
46+ private int temporaryHandleZoomHint = 0 ;
47+
4648/**
4749 * Constructs a new empty region.
4850 * <p>
@@ -171,11 +173,18 @@ public void add (Region region) {
171173 if (region == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
172174 if (region .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
173175 if (!region .operations .isEmpty ()) {
176+ adoptTemporaryHandleZoomHint (region );
174177 final Operation operation = new OperationWithRegion (Operation ::add , region .operations );
175178 storeAndApplyOperationForAllHandles (operation );
176179 }
177180}
178181
182+ private void adoptTemporaryHandleZoomHint (Region region ) {
183+ if (temporaryHandleZoomHint == 0 && region .temporaryHandleZoomHint != 0 ) {
184+ this .temporaryHandleZoomHint = region .temporaryHandleZoomHint ;
185+ }
186+ }
187+
179188/**
180189 * Returns <code>true</code> if the point specified by the
181190 * arguments is inside the area specified by the receiver,
@@ -373,6 +382,7 @@ public void intersect (Region region) {
373382 if (region == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
374383 if (region .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
375384 if (!region .operations .isEmpty ()) {
385+ adoptTemporaryHandleZoomHint (region );
376386 final Operation operation = new OperationWithRegion (Operation ::intersect , region .operations );
377387 storeAndApplyOperationForAllHandles (operation );
378388 }
@@ -468,6 +478,21 @@ public boolean isEmpty () {
468478 });
469479}
470480
481+ /**
482+ * Specific method for {@link GC#getClipping(Region)} because the current GC
483+ * clipping settings at that specific point in time of executing the getClipping
484+ * method need to be stored.
485+ * <p>
486+ * The context zoom is used as a hint for the case of creating temporary
487+ * handles, such that they can be created for a zoom for which we know that the
488+ * supplier is capable of providing a proper handle.
489+ */
490+ void set (Function <Integer , Long > handleForZoomSupplier , int contextZoom ) {
491+ this .temporaryHandleZoomHint = contextZoom ;
492+ final Operation operation = new OperationWithRegionHandle (Operation ::set , handleForZoomSupplier );
493+ storeAndApplyOperationForAllHandles (operation );
494+ }
495+
471496/**
472497 * Subtracts the given polygon from the collection of polygons
473498 * the receiver maintains to describe its area.
@@ -559,6 +584,7 @@ public void subtract (Region region) {
559584 if (region == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
560585 if (region .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
561586 if (!region .operations .isEmpty ()) {
587+ adoptTemporaryHandleZoomHint (region );
562588 final Operation operation = new OperationWithRegion (Operation ::subtract , region .operations );
563589 storeAndApplyOperationForAllHandles (operation );
564590 }
@@ -612,7 +638,8 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
612638
613639private <T > T applyUsingAnyHandle (Function <RegionHandle , T > function ) {
614640 if (zoomToHandle .isEmpty ()) {
615- return applyUsingTemporaryHandle (device .getDeviceZoom (), operations , function );
641+ int temporaryHandleZoom = temporaryHandleZoomHint != 0 ? temporaryHandleZoomHint : device .getDeviceZoom ();
642+ return applyUsingTemporaryHandle (temporaryHandleZoom , operations , function );
616643 }
617644 return function .apply (zoomToHandle .values ().iterator ().next ());
618645}
@@ -646,6 +673,7 @@ private RegionHandle getRegionHandle(int zoom) {
646673
647674Region copy () {
648675 Region region = new Region ();
676+ region .temporaryHandleZoomHint = temporaryHandleZoomHint ;
649677 region .operations .addAll (operations );
650678 return region ;
651679}
@@ -705,6 +733,8 @@ void apply(RegionHandle regionHandle) {
705733 operationStrategy .apply (this , regionHandle .handle (), regionHandle .zoom ());
706734 }
707735
736+ abstract void set (long handle , int zoom );
737+
708738 abstract void add (long handle , int zoom );
709739
710740 abstract void subtract (long handle , int zoom );
@@ -722,6 +752,11 @@ private static class OperationWithRectangle extends Operation {
722752 this .data = data ;
723753 }
724754
755+ @ Override
756+ void set (long handle , int zoom ) {
757+ throw new UnsupportedOperationException ();
758+ }
759+
725760 @ Override
726761 void add (long handle , int zoom ) {
727762 Rectangle bounds = getScaledRectangle (zoom );
@@ -780,6 +815,11 @@ public OperationWithArray(OperationStrategy operationStrategy, int[] data) {
780815 this .data = data ;
781816 }
782817
818+ @ Override
819+ void set (long handle , int zoom ) {
820+ throw new UnsupportedOperationException ();
821+ }
822+
783823 @ Override
784824 void add (long handle , int zoom ) {
785825 int [] points = getScaledPoints (zoom );
@@ -827,6 +867,11 @@ public OperationWithPoint(OperationStrategy operationStrategy, Point data) {
827867 this .data = data ;
828868 }
829869
870+ @ Override
871+ void set (long handle , int zoom ) {
872+ throw new UnsupportedOperationException ();
873+ }
874+
830875 @ Override
831876 void add (long handle , int zoom ) {
832877 throw new UnsupportedOperationException ();
@@ -858,6 +903,11 @@ private static class OperationWithRegion extends Operation {
858903 this .operations = List .copyOf (operations );
859904 }
860905
906+ @ Override
907+ void set (long handle , int zoom ) {
908+ throw new UnsupportedOperationException ();
909+ }
910+
861911 @ Override
862912 void add (long handle , int zoom ) {
863913 applyUsingTemporaryHandle (zoom , operations , regionHandle -> {
@@ -883,5 +933,41 @@ void intersect(long handle, int zoom) {
883933 void translate (long handle , int zoom ) {
884934 throw new UnsupportedOperationException ();
885935 }
936+
937+ }
938+
939+ private static class OperationWithRegionHandle extends Operation {
940+ private final Function <Integer , Long > handleForZoomProvider ;
941+
942+ OperationWithRegionHandle (OperationStrategy operationStrategy , Function <Integer , Long > handleForZoomSupplier ) {
943+ super (operationStrategy );
944+ this .handleForZoomProvider = handleForZoomSupplier ;
945+ }
946+
947+ @ Override
948+ void set (long handle , int zoom ) {
949+ OS .CombineRgn (handle , handleForZoomProvider .apply (zoom ), 0 , OS .RGN_COPY );
950+ }
951+
952+ @ Override
953+ void subtract (long handle , int zoom ) {
954+ throw new UnsupportedOperationException ();
955+ }
956+
957+ @ Override
958+ void intersect (long handle , int zoom ) {
959+ throw new UnsupportedOperationException ();
960+ }
961+
962+ @ Override
963+ void translate (long handle , int zoom ) {
964+ throw new UnsupportedOperationException ();
965+ }
966+
967+ @ Override
968+ void add (long handle , int zoom ) {
969+ throw new UnsupportedOperationException ();
970+ }
971+
886972}
887973}
0 commit comments