1515
1616
1717import java .util .*;
18+ import java .util .function .*;
1819import java .util .stream .*;
1920
2021import org .eclipse .swt .*;
@@ -452,8 +453,8 @@ public boolean isEmpty () {
452453 if (isDisposed ()) SWT .error (SWT .ERROR_GRAPHIC_DISPOSED );
453454 RECT rect = new RECT ();
454455 int result = OS .GetRgnBox (getHandleForInitialZoom (), rect );
455- if (result == OS .NULLREGION ) return true ;
456- return ((rect .right - rect .left ) <= 0 ) || ((rect .bottom - rect .top ) <= 0 );
456+ if (result == OS .NULLREGION ) return true ;
457+ return ((rect .right - rect .left ) <= 0 ) || ((rect .bottom - rect .top ) <= 0 );
457458}
458459
459460/**
@@ -600,6 +601,32 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
600601 zoomToHandle .forEach ((zoom , handle ) -> operation .apply (handle , zoom ));
601602}
602603
604+ private <T > T applyUsingAnyMatchingHandle (int zoom , Function <Long , T > function ) {
605+ if (zoomToHandle .containsKey (zoom )) {
606+ return function .apply (zoomToHandle .get (zoom ));
607+ } else {
608+ return applyUsingTemporaryHandle (zoom , function );
609+ }
610+ }
611+
612+ private <T > T applyUsingTemporaryHandle (int zoom , Function <Long , T > function ) {
613+ long temporaryHandle = newRegionHandle (zoom );
614+ try {
615+ return function .apply (temporaryHandle );
616+ } finally {
617+ OS .DeleteObject (temporaryHandle );
618+ }
619+ }
620+
621+ private long newRegionHandle (int zoom ) {
622+ long newHandle = OS .CreateRectRgn (0 , 0 , 0 , 0 );
623+ if (newHandle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
624+ for (Operation operation : operations ) {
625+ operation .apply (newHandle , zoom );
626+ }
627+ return newHandle ;
628+ }
629+
603630/**
604631 * <b>IMPORTANT:</b> This method is not part of the public
605632 * API for Image. It is marked public only so that it
@@ -805,8 +832,7 @@ void translate(long handle, int zoom) {
805832}
806833
807834private class OperationWithRegion extends Operation {
808-
809- Region data ;
835+ private final Region data ;
810836
811837 OperationWithRegion (OperationStrategy operationStrategy , Region data ) {
812838 super (operationStrategy );
@@ -815,30 +841,28 @@ private class OperationWithRegion extends Operation {
815841
816842 @ Override
817843 void add (long handle , int zoom ) {
818- long scaledHandle = getHandleForScaledRegion (zoom );
819- OS .CombineRgn (handle , handle , scaledHandle , OS .RGN_OR );
844+ data .applyUsingAnyMatchingHandle (zoom , regionHandle -> {
845+ return OS .CombineRgn (handle , handle , regionHandle , OS .RGN_OR );
846+ });
820847 }
821848
822849 @ Override
823850 void subtract (long handle , int zoom ) {
824- long scaledHandle = getHandleForScaledRegion (zoom );
825- OS .CombineRgn (handle , handle , scaledHandle , OS .RGN_DIFF );
851+ data .applyUsingAnyMatchingHandle (zoom , regionHandle -> {
852+ return OS .CombineRgn (handle , handle , regionHandle , OS .RGN_DIFF );
853+ });
826854 }
827855
828856 @ Override
829857 void intersect (long handle , int zoom ) {
830- long scaledHandle = getHandleForScaledRegion (zoom );
831- OS .CombineRgn (handle , handle , scaledHandle , OS .RGN_AND );
858+ data .applyUsingAnyMatchingHandle (zoom , regionHandle -> {
859+ return OS .CombineRgn (handle , handle , regionHandle , OS .RGN_AND );
860+ });
832861 }
833862
834863 @ Override
835864 void translate (long handle , int zoom ) {
836865 throw new UnsupportedOperationException ();
837866 }
838-
839- private long getHandleForScaledRegion (int zoom ) {
840- if (data .isDisposed () || data == Region .this ) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
841- return win32_getHandle (data , zoom );
842- }
843867}
844868}
0 commit comments