Skip to content

Commit fa94196

Browse files
committed
[win32] Create handles with disposed Regions
This commit refactors Region in the win32 implementation to better support multiple handles for different zoom settings by creating all handles only on demand.
1 parent 29753aa commit fa94196

File tree

2 files changed

+61
-24
lines changed

2 files changed

+61
-24
lines changed

bundles/org.eclipse.swt/Eclipse SWT Tests/win32/org/eclipse/swt/graphics/RegionWin32Tests.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ public void testRegionMustBeScaledOnHandleOfScaledZoomLevel() {
5757
assertEquals("scaled region's y position should be double of unscaled region", bounds.y * scalingFactor, scaledBounds.y);
5858
}
5959

60-
6160
@Test
6261
public void testRegionMustIntersectProperlyOn175Zoom() {
6362
Display display = Display.getDefault();
@@ -81,7 +80,24 @@ public void testRegionMustIntersectProperlyOn175Zoom() {
8180
// be rounded independently
8281
boolean shouldNotIntersect = region.intersects(0, 27, 100, 31);
8382
assertFalse(shouldNotIntersect);
84-
83+
region.dispose();
8584
}
8685

86+
@Test
87+
public void testCreateRegionHandleWithDisposedRegionInvolved() {
88+
Display display = Display.getDefault();
89+
90+
Region region = new Region(display);
91+
region.add(0, 0, 100, 100);
92+
93+
Region region2 = new Region(display);
94+
region.add(50, 50, 100, 100);
95+
96+
region.add(region2);
97+
98+
region2.dispose();
99+
Region.win32_getHandle(region, 100);
100+
Region.win32_getHandle(region, 200);
101+
region.dispose();
102+
}
87103
}

bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Region.java

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616

1717
import java.util.*;
18+
import java.util.function.*;
1819
import java.util.stream.*;
1920

2021
import org.eclipse.swt.*;
@@ -597,6 +598,29 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
597598
zoomToHandle.forEach((zoom, handle) -> operation.apply(handle, zoom));
598599
}
599600

601+
private static <T> T applyUsingTemporaryHandle(int zoom, List<Operation> operations, Function<Long, T> function) {
602+
long temporaryHandle = newRegionHandle(operations, zoom);
603+
try {
604+
return function.apply(temporaryHandle);
605+
} finally {
606+
OS.DeleteObject(temporaryHandle);
607+
}
608+
}
609+
610+
private static long newEmptyRegionHandle() {
611+
long newHandle = OS.CreateRectRgn (0, 0, 0, 0);
612+
if (newHandle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
613+
return newHandle;
614+
}
615+
616+
private static long newRegionHandle(List<Operation> operations, int zoom) {
617+
long newHandle = newEmptyRegionHandle();
618+
for (Operation operation : operations) {
619+
operation.apply(newHandle, zoom);
620+
}
621+
return newHandle;
622+
}
623+
600624
/**
601625
* <b>IMPORTANT:</b> This method is not part of the public
602626
* API for Image. It is marked public only so that it
@@ -615,9 +639,9 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
615639
* @noreference This method is not intended to be referenced by clients.
616640
*/
617641
public 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) {
642+
if (!region.zoomToHandle.containsKey(zoom)) {
643+
long handle = newEmptyRegionHandle();
644+
for (Operation operation : region.operations) {
621645
operation.apply(handle, zoom);
622646
}
623647
region.zoomToHandle.put(zoom, handle);
@@ -642,7 +666,7 @@ private interface OperationStrategy {
642666
void apply(Operation operation, long handle, int zoom);
643667
}
644668

645-
private abstract class Operation {
669+
private abstract static class Operation {
646670
private OperationStrategy operationStrategy;
647671

648672
Operation(OperationStrategy operationStrategy) {
@@ -662,7 +686,7 @@ void apply(long handle, int zoom) {
662686
abstract void translate(long handle, int zoom);
663687
}
664688

665-
private class OperationWithRectangle extends Operation {
689+
private static class OperationWithRectangle extends Operation {
666690

667691
Rectangle data;
668692

@@ -721,7 +745,7 @@ private Rectangle getScaledRectangle(int zoom) {
721745

722746
}
723747

724-
private class OperationWithArray extends Operation {
748+
private static class OperationWithArray extends Operation {
725749

726750
int[] data;
727751

@@ -769,7 +793,7 @@ private int[] getScaledPoints(int zoom) {
769793
}
770794
}
771795

772-
private class OperationWithPoint extends Operation {
796+
private static class OperationWithPoint extends Operation {
773797

774798
Point data;
775799

@@ -801,41 +825,38 @@ void translate(long handle, int zoom) {
801825

802826
}
803827

804-
private class OperationWithRegion extends Operation {
805-
806-
Region data;
828+
private static class OperationWithRegion extends Operation {
829+
private final List<Operation> operations;
807830

808831
OperationWithRegion(OperationStrategy operationStrategy, Region data) {
809832
super(operationStrategy);
810-
this.data = data;
833+
this.operations = data.operations;
811834
}
812835

813836
@Override
814837
void add(long handle, int zoom) {
815-
long scaledHandle = getHandleForScaledRegion(zoom);
816-
OS.CombineRgn (handle, handle, scaledHandle, OS.RGN_OR);
838+
applyUsingTemporaryHandle(zoom, operations, regionHandle -> {
839+
return OS.CombineRgn (handle, handle, regionHandle, OS.RGN_OR);
840+
});
817841
}
818842

819843
@Override
820844
void subtract(long handle, int zoom) {
821-
long scaledHandle = getHandleForScaledRegion(zoom);
822-
OS.CombineRgn (handle, handle, scaledHandle, OS.RGN_DIFF);
845+
applyUsingTemporaryHandle(zoom, operations, regionHandle -> {
846+
return OS.CombineRgn (handle, handle, regionHandle, OS.RGN_DIFF);
847+
});
823848
}
824849

825850
@Override
826851
void intersect(long handle, int zoom) {
827-
long scaledHandle = getHandleForScaledRegion(zoom);
828-
OS.CombineRgn (handle, handle, scaledHandle, OS.RGN_AND);
852+
applyUsingTemporaryHandle(zoom, operations, regionHandle -> {
853+
return OS.CombineRgn (handle, handle, regionHandle, OS.RGN_AND);
854+
});
829855
}
830856

831857
@Override
832858
void translate(long handle, int zoom) {
833859
throw new UnsupportedOperationException();
834860
}
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-
}
840861
}
841862
}

0 commit comments

Comments
 (0)