1515
1616
1717import java .util .*;
18+ import java .util .function .*;
1819import java .util .stream .*;
1920
2021import org .eclipse .swt .*;
@@ -80,9 +81,8 @@ public Region () {
8081public Region (Device device ) {
8182 super (device );
8283 initialZoom = DPIUtil .getDeviceZoom ();
83- long handle = OS . CreateRectRgn ( 0 , 0 , 0 , 0 );
84+ long handle = newEmptyRegionHandle ( );
8485 zoomToHandle .put (initialZoom , handle );
85- if (handle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
8686 init ();
8787 this .device .registerResourceWithZoomSupport (this );
8888}
@@ -597,6 +597,29 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
597597 zoomToHandle .forEach ((zoom , handle ) -> operation .apply (handle , zoom ));
598598}
599599
600+ private static <T > T applyUsingTemporaryHandle (int zoom , List <Operation > operations , Function <Long , T > function ) {
601+ long temporaryHandle = newRegionHandle (operations , zoom );
602+ try {
603+ return function .apply (temporaryHandle );
604+ } finally {
605+ OS .DeleteObject (temporaryHandle );
606+ }
607+ }
608+
609+ private static long newEmptyRegionHandle () {
610+ long newHandle = OS .CreateRectRgn (0 , 0 , 0 , 0 );
611+ if (newHandle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
612+ return newHandle ;
613+ }
614+
615+ private static long newRegionHandle (List <Operation > operations , int zoom ) {
616+ long newHandle = newEmptyRegionHandle ();
617+ for (Operation operation : operations ) {
618+ operation .apply (newHandle , zoom );
619+ }
620+ return newHandle ;
621+ }
622+
600623/**
601624 * <b>IMPORTANT:</b> This method is not part of the public
602625 * API for Image. It is marked public only so that it
@@ -615,9 +638,9 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
615638 * @noreference This method is not intended to be referenced by clients.
616639 */
617640public static long win32_getHandle (Region region , int zoom ) {
618- if (!region .zoomToHandle .containsKey (zoom )) {
619- long handle = OS . CreateRectRgn ( 0 , 0 , 0 , 0 );
620- for (Operation operation : region .operations ) {
641+ if (!region .zoomToHandle .containsKey (zoom )) {
642+ long handle = newEmptyRegionHandle ( );
643+ for (Operation operation : region .operations ) {
621644 operation .apply (handle , zoom );
622645 }
623646 region .zoomToHandle .put (zoom , handle );
@@ -642,7 +665,7 @@ private interface OperationStrategy {
642665 void apply (Operation operation , long handle , int zoom );
643666}
644667
645- private abstract class Operation {
668+ private abstract static class Operation {
646669 private OperationStrategy operationStrategy ;
647670
648671 Operation (OperationStrategy operationStrategy ) {
@@ -662,7 +685,7 @@ void apply(long handle, int zoom) {
662685 abstract void translate (long handle , int zoom );
663686}
664687
665- private class OperationWithRectangle extends Operation {
688+ private static class OperationWithRectangle extends Operation {
666689
667690 Rectangle data ;
668691
@@ -721,7 +744,7 @@ private Rectangle getScaledRectangle(int zoom) {
721744
722745}
723746
724- private class OperationWithArray extends Operation {
747+ private static class OperationWithArray extends Operation {
725748
726749 int [] data ;
727750
@@ -769,7 +792,7 @@ private int[] getScaledPoints(int zoom) {
769792 }
770793}
771794
772- private class OperationWithPoint extends Operation {
795+ private static class OperationWithPoint extends Operation {
773796
774797 Point data ;
775798
@@ -801,41 +824,38 @@ void translate(long handle, int zoom) {
801824
802825}
803826
804- private class OperationWithRegion extends Operation {
805-
806- Region data ;
827+ private static class OperationWithRegion extends Operation {
828+ private final List <Operation > operations ;
807829
808830 OperationWithRegion (OperationStrategy operationStrategy , Region data ) {
809831 super (operationStrategy );
810- this .data = data ;
832+ this .operations = data . operations ;
811833 }
812834
813835 @ Override
814836 void add (long handle , int zoom ) {
815- long scaledHandle = getHandleForScaledRegion (zoom );
816- OS .CombineRgn (handle , handle , scaledHandle , OS .RGN_OR );
837+ applyUsingTemporaryHandle (zoom , operations , regionHandle -> {
838+ return OS .CombineRgn (handle , handle , regionHandle , OS .RGN_OR );
839+ });
817840 }
818841
819842 @ Override
820843 void subtract (long handle , int zoom ) {
821- long scaledHandle = getHandleForScaledRegion (zoom );
822- OS .CombineRgn (handle , handle , scaledHandle , OS .RGN_DIFF );
844+ applyUsingTemporaryHandle (zoom , operations , regionHandle -> {
845+ return OS .CombineRgn (handle , handle , regionHandle , OS .RGN_DIFF );
846+ });
823847 }
824848
825849 @ Override
826850 void intersect (long handle , int zoom ) {
827- long scaledHandle = getHandleForScaledRegion (zoom );
828- OS .CombineRgn (handle , handle , scaledHandle , OS .RGN_AND );
851+ applyUsingTemporaryHandle (zoom , operations , regionHandle -> {
852+ return OS .CombineRgn (handle , handle , regionHandle , OS .RGN_AND );
853+ });
829854 }
830855
831856 @ Override
832857 void translate (long handle , int zoom ) {
833858 throw new UnsupportedOperationException ();
834859 }
835-
836- private long getHandleForScaledRegion (int zoom ) {
837- if (data .isDisposed () || data == Region .this ) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
838- return win32_getHandle (data , zoom );
839- }
840860}
841861}
0 commit comments