Skip to content

Commit f03d8f0

Browse files
akoch-yattaHeikoKlare
authored andcommitted
[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 0368a6b commit f03d8f0

File tree

1 file changed

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

1 file changed

+62
-45
lines changed

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

Lines changed: 62 additions & 45 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
}
@@ -161,19 +158,14 @@ void destroy() {
161158
device.deregisterResourceWithZoomSupport(this);
162159
zoomToHandle.values().forEach(TransformHandle::destroy);
163160
zoomToHandle.clear();
164-
operations.clear();
161+
this.isDestroyed = true;
165162
}
166163

167164
@Override
168165
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-
});
166+
// As long as we keep the operations, we can cleanup all handles
167+
zoomToHandle.values().forEach(TransformHandle::destroy);
168+
zoomToHandle.clear();
177169
}
178170

179171
/**
@@ -194,12 +186,14 @@ public void getElements(float[] elements) {
194186
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
195187
if (elements == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
196188
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);
189+
applyUsingAnyHandle(transformHandle -> {
190+
Gdip.Matrix_GetElements(transformHandle.handle, elements);
191+
Drawable drawable = getDevice();
192+
int zoom = transformHandle.zoom;
193+
elements[4] = DPIUtil.scaleDown(drawable, elements[4], zoom);
194+
elements[5] = DPIUtil.scaleDown(drawable, elements[5], zoom);
195+
return true;
196+
});
203197
}
204198

205199
/**
@@ -245,7 +239,7 @@ public void invert() {
245239
*/
246240
@Override
247241
public boolean isDisposed() {
248-
return zoomToHandle.isEmpty();
242+
return this.isDestroyed;
249243
}
250244

251245
/**
@@ -256,8 +250,9 @@ public boolean isDisposed() {
256250
*/
257251
public boolean isIdentity() {
258252
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
259-
TransformHandle transformHandle = getTransformHandle(initialZoom);
260-
return Gdip.Matrix_IsIdentity(transformHandle.handle);
253+
return applyUsingAnyHandle(transformHandle -> {
254+
return Gdip.Matrix_IsIdentity(transformHandle.handle);
255+
});
261256
}
262257

263258
/**
@@ -374,15 +369,18 @@ public void transform(float[] pointArray) {
374369
if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
375370
if (pointArray == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
376371
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-
}
372+
applyUsingAnyHandle(transformHandle -> {
373+
int length = pointArray.length;
374+
for (int i = 0; i < length; i++) {
375+
pointArray[i] = DPIUtil.scaleUp(drawable, pointArray[i], transformHandle.zoom);
376+
}
377+
Gdip.Matrix_TransformPoints(transformHandle.handle, pointArray, length / 2);
378+
for (int i = 0; i < length; i++) {
379+
pointArray[i] = DPIUtil.scaleDown(drawable, pointArray[i], transformHandle.zoom);
380+
}
381+
return pointArray;
382+
});
383+
386384
}
387385

388386
/**
@@ -517,6 +515,19 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
517515
zoomToHandle.forEach((zoom, handle) -> operation.apply(handle));
518516
}
519517

518+
private <T> T applyUsingAnyHandle(Function<TransformHandle, T> function) {
519+
if (zoomToHandle.isEmpty()) {
520+
TransformHandle temporaryHandle = newTransformHandle(DPIUtil.getDeviceZoom());
521+
try {
522+
return function.apply(temporaryHandle);
523+
} finally {
524+
temporaryHandle.destroy();
525+
}
526+
} else {
527+
return function.apply(zoomToHandle.values().iterator().next());
528+
}
529+
}
530+
520531
/**
521532
* Returns a string containing a concise, human-readable
522533
* description of the receiver.
@@ -530,21 +541,27 @@ public String toString() {
530541
getElements(elements);
531542
return "Transform {" + elements [0] + "," + elements [1] + "," +elements [2] + "," +elements [3] + "," +elements [4] + "," +elements [5] + "}";
532543
}
544+
545+
private TransformHandle newTransformHandle(int zoom) {
546+
long newHandle = Gdip.Matrix_new(0, 0, 0, 0, 0, 0);
547+
if (newHandle == 0) SWT.error(SWT.ERROR_NO_HANDLES);
548+
TransformHandle newTransformHandle = new TransformHandle(newHandle, zoom);
549+
for(Operation operation : operations) {
550+
operation.apply(newTransformHandle);
551+
}
552+
return newTransformHandle;
553+
}
554+
533555
private TransformHandle getTransformHandle(int zoom) {
534-
if(zoomToHandle.get(zoom) == null) {
535-
float[] elements = new float[6];
536-
getElements(elements);
537-
elements[4] = DPIUtil.scaleUp(device, DPIUtil.scaleDown(device, elements[4], initialZoom), zoom);
538-
elements[5] = DPIUtil.scaleUp(device, DPIUtil.scaleDown(device, elements[5], initialZoom), zoom);
539-
long handle = Gdip.Matrix_new(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
540-
TransformHandle transformHandle = new TransformHandle(handle, zoom);
541-
zoomToHandle.put(zoom, transformHandle);
542-
return transformHandle;
556+
if (!zoomToHandle.containsKey(zoom)) {
557+
TransformHandle newHandle = newTransformHandle(zoom);
558+
zoomToHandle.put(zoom, newHandle);
559+
return newHandle;
543560
}
544561
return zoomToHandle.get(zoom);
545562
}
546563

547-
long getHandle(int zoomLevel) {
548-
return getTransformHandle(zoomLevel).handle;
564+
long getHandle(int zoom) {
565+
return getTransformHandle(zoom).handle;
549566
}
550567
}

0 commit comments

Comments
 (0)