@@ -43,6 +43,8 @@ public final class Region extends Resource {
43
43
44
44
private boolean isDestroyed ;
45
45
46
+ private int temporaryHandleZoomHint = 0 ;
47
+
46
48
/**
47
49
* Constructs a new empty region.
48
50
* <p>
@@ -171,11 +173,18 @@ public void add (Region region) {
171
173
if (region == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
172
174
if (region .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
173
175
if (!region .operations .isEmpty ()) {
176
+ adoptTemporaryHandleZoomHint (region );
174
177
final Operation operation = new OperationWithRegion (Operation ::add , region .operations );
175
178
storeAndApplyOperationForAllHandles (operation );
176
179
}
177
180
}
178
181
182
+ private void adoptTemporaryHandleZoomHint (Region region ) {
183
+ if (temporaryHandleZoomHint == 0 && region .temporaryHandleZoomHint != 0 ) {
184
+ this .temporaryHandleZoomHint = region .temporaryHandleZoomHint ;
185
+ }
186
+ }
187
+
179
188
/**
180
189
* Returns <code>true</code> if the point specified by the
181
190
* arguments is inside the area specified by the receiver,
@@ -373,6 +382,7 @@ public void intersect (Region region) {
373
382
if (region == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
374
383
if (region .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
375
384
if (!region .operations .isEmpty ()) {
385
+ adoptTemporaryHandleZoomHint (region );
376
386
final Operation operation = new OperationWithRegion (Operation ::intersect , region .operations );
377
387
storeAndApplyOperationForAllHandles (operation );
378
388
}
@@ -468,6 +478,21 @@ public boolean isEmpty () {
468
478
});
469
479
}
470
480
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
+
471
496
/**
472
497
* Subtracts the given polygon from the collection of polygons
473
498
* the receiver maintains to describe its area.
@@ -559,6 +584,7 @@ public void subtract (Region region) {
559
584
if (region == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
560
585
if (region .isDisposed ()) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
561
586
if (!region .operations .isEmpty ()) {
587
+ adoptTemporaryHandleZoomHint (region );
562
588
final Operation operation = new OperationWithRegion (Operation ::subtract , region .operations );
563
589
storeAndApplyOperationForAllHandles (operation );
564
590
}
@@ -612,7 +638,8 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
612
638
613
639
private <T > T applyUsingAnyHandle (Function <RegionHandle , T > function ) {
614
640
if (zoomToHandle .isEmpty ()) {
615
- return applyUsingTemporaryHandle (device .getDeviceZoom (), operations , function );
641
+ int temporaryHandleZoom = temporaryHandleZoomHint != 0 ? temporaryHandleZoomHint : device .getDeviceZoom ();
642
+ return applyUsingTemporaryHandle (temporaryHandleZoom , operations , function );
616
643
}
617
644
return function .apply (zoomToHandle .values ().iterator ().next ());
618
645
}
@@ -646,6 +673,7 @@ private RegionHandle getRegionHandle(int zoom) {
646
673
647
674
Region copy () {
648
675
Region region = new Region ();
676
+ region .temporaryHandleZoomHint = temporaryHandleZoomHint ;
649
677
region .operations .addAll (operations );
650
678
return region ;
651
679
}
@@ -705,6 +733,8 @@ void apply(RegionHandle regionHandle) {
705
733
operationStrategy .apply (this , regionHandle .handle (), regionHandle .zoom ());
706
734
}
707
735
736
+ abstract void set (long handle , int zoom );
737
+
708
738
abstract void add (long handle , int zoom );
709
739
710
740
abstract void subtract (long handle , int zoom );
@@ -722,6 +752,11 @@ private static class OperationWithRectangle extends Operation {
722
752
this .data = data ;
723
753
}
724
754
755
+ @ Override
756
+ void set (long handle , int zoom ) {
757
+ throw new UnsupportedOperationException ();
758
+ }
759
+
725
760
@ Override
726
761
void add (long handle , int zoom ) {
727
762
Rectangle bounds = getScaledRectangle (zoom );
@@ -780,6 +815,11 @@ public OperationWithArray(OperationStrategy operationStrategy, int[] data) {
780
815
this .data = data ;
781
816
}
782
817
818
+ @ Override
819
+ void set (long handle , int zoom ) {
820
+ throw new UnsupportedOperationException ();
821
+ }
822
+
783
823
@ Override
784
824
void add (long handle , int zoom ) {
785
825
int [] points = getScaledPoints (zoom );
@@ -827,6 +867,11 @@ public OperationWithPoint(OperationStrategy operationStrategy, Point data) {
827
867
this .data = data ;
828
868
}
829
869
870
+ @ Override
871
+ void set (long handle , int zoom ) {
872
+ throw new UnsupportedOperationException ();
873
+ }
874
+
830
875
@ Override
831
876
void add (long handle , int zoom ) {
832
877
throw new UnsupportedOperationException ();
@@ -858,6 +903,11 @@ private static class OperationWithRegion extends Operation {
858
903
this .operations = List .copyOf (operations );
859
904
}
860
905
906
+ @ Override
907
+ void set (long handle , int zoom ) {
908
+ throw new UnsupportedOperationException ();
909
+ }
910
+
861
911
@ Override
862
912
void add (long handle , int zoom ) {
863
913
applyUsingTemporaryHandle (zoom , operations , regionHandle -> {
@@ -883,5 +933,41 @@ void intersect(long handle, int zoom) {
883
933
void translate (long handle , int zoom ) {
884
934
throw new UnsupportedOperationException ();
885
935
}
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
+
886
972
}
887
973
}
0 commit comments