Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public void testRegionMustBeScaledOnHandleOfScaledZoomLevel() {
assertEquals("scaled region's y position should be double of unscaled region", bounds.y * scalingFactor, scaledBounds.y);
}


@Test
public void testRegionMustIntersectProperlyOn175Zoom() {
Display display = Display.getDefault();
Expand All @@ -81,7 +80,24 @@ public void testRegionMustIntersectProperlyOn175Zoom() {
// be rounded independently
boolean shouldNotIntersect = region.intersects(0, 27, 100, 31);
assertFalse(shouldNotIntersect);

region.dispose();
}

@Test
public void testCreateRegionHandleWithDisposedRegionInvolved() {
Display display = Display.getDefault();

Region region = new Region(display);
region.add(0, 0, 100, 100);

Region region2 = new Region(display);
region.add(50, 50, 100, 100);

region.add(region2);

region2.dispose();
Region.win32_getHandle(region, 100);
Region.win32_getHandle(region, 200);
region.dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@


import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import org.eclipse.swt.*;
Expand Down Expand Up @@ -80,9 +81,8 @@ public Region () {
public Region (Device device) {
super(device);
initialZoom = DPIUtil.getDeviceZoom();
long handle = OS.CreateRectRgn (0, 0, 0, 0);
long handle = newEmptyRegionHandle();
zoomToHandle.put(initialZoom, handle);
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
init();
this.device.registerResourceWithZoomSupport(this);
}
Expand Down Expand Up @@ -597,6 +597,29 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
zoomToHandle.forEach((zoom, handle) -> operation.apply(handle, zoom));
}

private static <T> T applyUsingTemporaryHandle(int zoom, List<Operation> operations, Function<Long, T> function) {
long temporaryHandle = newRegionHandle(operations, zoom);
try {
return function.apply(temporaryHandle);
} finally {
OS.DeleteObject(temporaryHandle);
}
}

private static long newEmptyRegionHandle() {
long newHandle = OS.CreateRectRgn (0, 0, 0, 0);
if (newHandle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
return newHandle;
}

private static long newRegionHandle(List<Operation> operations, int zoom) {
long newHandle = newEmptyRegionHandle();
for (Operation operation : operations) {
operation.apply(newHandle, zoom);
}
return newHandle;
}

/**
* <b>IMPORTANT:</b> This method is not part of the public
* API for Image. It is marked public only so that it
Expand All @@ -615,9 +638,9 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
* @noreference This method is not intended to be referenced by clients.
*/
public static long win32_getHandle(Region region, int zoom) {
if(!region.zoomToHandle.containsKey(zoom)) {
long handle = OS.CreateRectRgn(0, 0, 0, 0);
for(Operation operation : region.operations) {
if (!region.zoomToHandle.containsKey(zoom)) {
long handle = newEmptyRegionHandle();
for (Operation operation : region.operations) {
operation.apply(handle, zoom);
}
region.zoomToHandle.put(zoom, handle);
Expand All @@ -642,7 +665,7 @@ private interface OperationStrategy {
void apply(Operation operation, long handle, int zoom);
}

private abstract class Operation {
private abstract static class Operation {
private OperationStrategy operationStrategy;

Operation(OperationStrategy operationStrategy) {
Expand All @@ -662,7 +685,7 @@ void apply(long handle, int zoom) {
abstract void translate(long handle, int zoom);
}

private class OperationWithRectangle extends Operation {
private static class OperationWithRectangle extends Operation {

Rectangle data;

Expand Down Expand Up @@ -721,7 +744,7 @@ private Rectangle getScaledRectangle(int zoom) {

}

private class OperationWithArray extends Operation {
private static class OperationWithArray extends Operation {

int[] data;

Expand Down Expand Up @@ -769,7 +792,7 @@ private int[] getScaledPoints(int zoom) {
}
}

private class OperationWithPoint extends Operation {
private static class OperationWithPoint extends Operation {

Point data;

Expand Down Expand Up @@ -801,41 +824,38 @@ void translate(long handle, int zoom) {

}

private class OperationWithRegion extends Operation {

Region data;
private static class OperationWithRegion extends Operation {
private final List<Operation> operations;

OperationWithRegion(OperationStrategy operationStrategy, Region data) {
super(operationStrategy);
this.data = data;
this.operations = data.operations;
}

@Override
void add(long handle, int zoom) {
long scaledHandle = getHandleForScaledRegion(zoom);
OS.CombineRgn (handle, handle, scaledHandle, OS.RGN_OR);
applyUsingTemporaryHandle(zoom, operations, regionHandle -> {
return OS.CombineRgn (handle, handle, regionHandle, OS.RGN_OR);
});
}

@Override
void subtract(long handle, int zoom) {
long scaledHandle = getHandleForScaledRegion(zoom);
OS.CombineRgn (handle, handle, scaledHandle, OS.RGN_DIFF);
applyUsingTemporaryHandle(zoom, operations, regionHandle -> {
return OS.CombineRgn (handle, handle, regionHandle, OS.RGN_DIFF);
});
}

@Override
void intersect(long handle, int zoom) {
long scaledHandle = getHandleForScaledRegion(zoom);
OS.CombineRgn (handle, handle, scaledHandle, OS.RGN_AND);
applyUsingTemporaryHandle(zoom, operations, regionHandle -> {
return OS.CombineRgn (handle, handle, regionHandle, OS.RGN_AND);
});
}

@Override
void translate(long handle, int zoom) {
throw new UnsupportedOperationException();
}

private long getHandleForScaledRegion(int zoom) {
if (data.isDisposed() || data == Region.this) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
return win32_getHandle(data, zoom);
}
}
}
Loading