14
14
package org .eclipse .swt .graphics ;
15
15
16
16
import java .util .*;
17
+ import java .util .function .*;
17
18
18
19
import org .eclipse .swt .*;
19
20
import org .eclipse .swt .internal .*;
39
40
*/
40
41
public class Transform extends Resource {
41
42
42
- private int initialZoom ;
43
-
44
43
private Map <Integer , TransformHandle > zoomToHandle = new HashMap <>();
45
44
46
45
private List <Operation > operations = new ArrayList <>();
47
46
47
+ private boolean isDestroyed ;
48
+
48
49
/**
49
50
* Constructs a new identity Transform.
50
51
* <p>
@@ -140,12 +141,8 @@ public Transform(Device device, float[] elements) {
140
141
*/
141
142
public Transform (Device device , float m11 , float m12 , float m21 , float m22 , float dx , float dy ) {
142
143
super (device );
143
- initialZoom = DPIUtil .getDeviceZoom ();
144
144
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 ));
149
146
init ();
150
147
this .device .registerResourceWithZoomSupport (this );
151
148
}
@@ -161,19 +158,14 @@ void destroy() {
161
158
device .deregisterResourceWithZoomSupport (this );
162
159
zoomToHandle .values ().forEach (TransformHandle ::destroy );
163
160
zoomToHandle .clear ();
164
- operations . clear () ;
161
+ this . isDestroyed = true ;
165
162
}
166
163
167
164
@ Override
168
165
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 ();
177
169
}
178
170
179
171
/**
@@ -194,12 +186,14 @@ public void getElements(float[] elements) {
194
186
if (isDisposed ()) SWT .error (SWT .ERROR_GRAPHIC_DISPOSED );
195
187
if (elements == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
196
188
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
+ });
203
197
}
204
198
205
199
/**
@@ -245,7 +239,7 @@ public void invert() {
245
239
*/
246
240
@ Override
247
241
public boolean isDisposed () {
248
- return zoomToHandle . isEmpty () ;
242
+ return this . isDestroyed ;
249
243
}
250
244
251
245
/**
@@ -256,8 +250,9 @@ public boolean isDisposed() {
256
250
*/
257
251
public boolean isIdentity () {
258
252
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
+ });
261
256
}
262
257
263
258
/**
@@ -374,15 +369,18 @@ public void transform(float[] pointArray) {
374
369
if (isDisposed ()) SWT .error (SWT .ERROR_GRAPHIC_DISPOSED );
375
370
if (pointArray == null ) SWT .error (SWT .ERROR_NULL_ARGUMENT );
376
371
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
+
386
384
}
387
385
388
386
/**
@@ -517,6 +515,19 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
517
515
zoomToHandle .forEach ((zoom , handle ) -> operation .apply (handle ));
518
516
}
519
517
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
+
520
531
/**
521
532
* Returns a string containing a concise, human-readable
522
533
* description of the receiver.
@@ -530,21 +541,27 @@ public String toString() {
530
541
getElements (elements );
531
542
return "Transform {" + elements [0 ] + "," + elements [1 ] + "," +elements [2 ] + "," +elements [3 ] + "," +elements [4 ] + "," +elements [5 ] + "}" ;
532
543
}
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
+
533
555
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 ;
543
560
}
544
561
return zoomToHandle .get (zoom );
545
562
}
546
563
547
- long getHandle (int zoomLevel ) {
548
- return getTransformHandle (zoomLevel ).handle ;
564
+ long getHandle (int zoom ) {
565
+ return getTransformHandle (zoom ).handle ;
549
566
}
550
567
}
0 commit comments