Skip to content

Commit 2ad8c82

Browse files
committed
[win32] Dynamic handle creation for transform
This commit adapts Transform in the win32 implementation to create handles only on demand. If a non-handle specific operation like isIdentity() is called, a temporary handle will be created and disposed afterwards if no handle exists already.
1 parent 54ca587 commit 2ad8c82

File tree

1 file changed

+62
-44
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics

1 file changed

+62
-44
lines changed

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

Lines changed: 62 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.eclipse.swt.graphics;
1515

1616
import java.util.*;
17+
import java.util.function.*;
1718

1819
import org.eclipse.swt.*;
1920
import org.eclipse.swt.internal.*;
@@ -39,12 +40,12 @@
3940
*/
4041
public class Transform extends Resource {
4142

42-
private int initialZoom;
43-
4443
private Map<Integer, TransformHandle> zoomToHandle = new HashMap<>();
4544

4645
private List<Operation> operations = new ArrayList<>();
4746

47+
private boolean isDestroyed;
48+
4849
/**
4950
* Constructs a new identity Transform.
5051
* <p>
@@ -140,12 +141,8 @@ public Transform(Device device, float[] elements) {
140141
*/
141142
public Transform (Device device, float m11, float m12, float m21, float m22, float dx, float dy) {
142143
super(device);
143-
initialZoom = DPIUtil.getDeviceZoom();
144144
this.device.checkGDIP();
145-
long handle = Gdip.Matrix_new(m11, m12, m21, m22,
146-
DPIUtil.scaleUp(this.device, dx, initialZoom), DPIUtil.scaleUp(this.device, dy, initialZoom));
147-
if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
148-
zoomToHandle.put(initialZoom, new TransformHandle(handle, initialZoom));
145+
storeAndApplyOperationForAllHandles(new SetElementsOperation(m11, m12, m21, m22, dx, dy));
149146
init();
150147
this.device.registerResourceWithZoomSupport(this);
151148
}
@@ -162,18 +159,14 @@ void destroy() {
162159
zoomToHandle.values().forEach(TransformHandle::destroy);
163160
zoomToHandle.clear();
164161
operations.clear();
162+
this.isDestroyed = true;
165163
}
166164

167165
@Override
168166
void destroyHandlesExcept(Set<Integer> zoomLevels) {
169-
zoomToHandle.entrySet().removeIf(entry -> {
170-
final Integer zoom = entry.getKey();
171-
if (!zoomLevels.contains(zoom) && zoom != initialZoom) {
172-
entry.getValue().destroy();
173-
return true;
174-
}
175-
return false;
176-
});
167+
// As long as we keep the operations, we can cleanup all handles
168+
zoomToHandle.values().forEach(TransformHandle::destroy);
169+
zoomToHandle.clear();
177170
}
178171

179172
/**
@@ -194,12 +187,14 @@ public void getElements(float[] elements) {
194187
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
195188
if (elements == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
196189
if (elements.length < 6) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
197-
TransformHandle transformHandle = getTransformHandle(initialZoom);
198-
Gdip.Matrix_GetElements(transformHandle.handle, elements);
199-
Drawable drawable = getDevice();
200-
int zoom = transformHandle.zoom;
201-
elements[4] = DPIUtil.scaleDown(drawable, elements[4], zoom);
202-
elements[5] = DPIUtil.scaleDown(drawable, elements[5], zoom);
190+
applyOnAnyHandle(transformHandle -> {
191+
Gdip.Matrix_GetElements(transformHandle.handle, elements);
192+
Drawable drawable = getDevice();
193+
int zoom = transformHandle.zoom;
194+
elements[4] = DPIUtil.scaleDown(drawable, elements[4], zoom);
195+
elements[5] = DPIUtil.scaleDown(drawable, elements[5], zoom);
196+
return true;
197+
});
203198
}
204199

205200
/**
@@ -245,7 +240,7 @@ public void invert() {
245240
*/
246241
@Override
247242
public boolean isDisposed() {
248-
return zoomToHandle.isEmpty();
243+
return this.isDestroyed;
249244
}
250245

251246
/**
@@ -256,8 +251,9 @@ public boolean isDisposed() {
256251
*/
257252
public boolean isIdentity() {
258253
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
259-
TransformHandle transformHandle = getTransformHandle(initialZoom);
260-
return Gdip.Matrix_IsIdentity(transformHandle.handle);
254+
return applyOnAnyHandle(transformHandle -> {
255+
return Gdip.Matrix_IsIdentity(transformHandle.handle);
256+
});
261257
}
262258

263259
/**
@@ -374,15 +370,18 @@ public void transform(float[] pointArray) {
374370
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
375371
if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
376372
Drawable drawable = getDevice();
377-
TransformHandle transformHandle = getTransformHandle(initialZoom);
378-
int length = pointArray.length;
379-
for (int i = 0; i < length; i++) {
380-
pointArray[i] = DPIUtil.scaleUp(drawable, pointArray[i], transformHandle.zoom);
381-
}
382-
Gdip.Matrix_TransformPoints(transformHandle.handle, pointArray, length / 2);
383-
for (int i = 0; i < length; i++) {
384-
pointArray[i] = DPIUtil.scaleDown(drawable, pointArray[i], transformHandle.zoom);
385-
}
373+
applyOnAnyHandle(transformHandle -> {
374+
int length = pointArray.length;
375+
for (int i = 0; i < length; i++) {
376+
pointArray[i] = DPIUtil.scaleUp(drawable, pointArray[i], transformHandle.zoom);
377+
}
378+
Gdip.Matrix_TransformPoints(transformHandle.handle, pointArray, length / 2);
379+
for (int i = 0; i < length; i++) {
380+
pointArray[i] = DPIUtil.scaleDown(drawable, pointArray[i], transformHandle.zoom);
381+
}
382+
return pointArray;
383+
});
384+
386385
}
387386

388387
/**
@@ -501,6 +500,19 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
501500
zoomToHandle.forEach((zoom, handle) -> operation.apply(handle));
502501
}
503502

503+
private <T> T applyOnAnyHandle(Function<TransformHandle, T> function) {
504+
if (zoomToHandle.isEmpty()) {
505+
TransformHandle temporaryHandle = newTransformHandle(DPIUtil.getDeviceZoom());
506+
try {
507+
return function.apply(temporaryHandle);
508+
} finally {
509+
temporaryHandle.destroy();
510+
}
511+
} else {
512+
return function.apply(zoomToHandle.values().iterator().next());
513+
}
514+
}
515+
504516
/**
505517
* Returns a string containing a concise, human-readable
506518
* description of the receiver.
@@ -514,21 +526,27 @@ public String toString() {
514526
getElements(elements);
515527
return "Transform {" + elements [0] + "," + elements [1] + "," +elements [2] + "," +elements [3] + "," +elements [4] + "," +elements [5] + "}";
516528
}
529+
530+
private TransformHandle newTransformHandle(int zoom) {
531+
long newHandle = Gdip.Matrix_new(0, 0, 0, 0, 0, 0);
532+
if (newHandle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
533+
TransformHandle newTransformHandle = new TransformHandle(newHandle, zoom);
534+
for(Operation operation : operations) {
535+
operation.apply(newTransformHandle);
536+
}
537+
return newTransformHandle;
538+
}
539+
517540
private TransformHandle getTransformHandle(int zoom) {
518-
if(zoomToHandle.get(zoom) == null) {
519-
float[] elements = new float[6];
520-
getElements(elements);
521-
elements[4] = DPIUtil.scaleUp(device, DPIUtil.scaleDown(device, elements[4], initialZoom), zoom);
522-
elements[5] = DPIUtil.scaleUp(device, DPIUtil.scaleDown(device, elements[5], initialZoom), zoom);
523-
long handle = Gdip.Matrix_new(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
524-
TransformHandle transformHandle = new TransformHandle(handle, zoom);
525-
zoomToHandle.put(zoom, transformHandle);
526-
return transformHandle;
541+
if (!zoomToHandle.containsKey(zoom)) {
542+
TransformHandle newHandle = newTransformHandle(zoom);
543+
zoomToHandle.put(zoom, newHandle);
544+
return newHandle;
527545
}
528546
return zoomToHandle.get(zoom);
529547
}
530548

531-
long getHandle(int zoomLevel) {
532-
return getTransformHandle(zoomLevel).handle;
549+
long getHandle(int zoom) {
550+
return getTransformHandle(zoom).handle;
533551
}
534552
}

0 commit comments

Comments
 (0)