1414package org .eclipse .swt .graphics ;
1515
1616import java .util .*;
17+ import java .util .function .*;
1718
1819import org .eclipse .swt .*;
1920import org .eclipse .swt .internal .*;
3940 */
4041public 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 */
141142public 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
168165void 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
247241public boolean isDisposed () {
248- return zoomToHandle . isEmpty () ;
242+ return this . isDestroyed ;
249243}
250244
251245/**
@@ -256,8 +250,9 @@ public boolean isDisposed() {
256250 */
257251public 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+
533555private 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