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}
@@ -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
168166void 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
247242public boolean isDisposed () {
248- return zoomToHandle . isEmpty () ;
243+ return this . isDestroyed ;
249244}
250245
251246/**
@@ -256,8 +251,9 @@ public boolean isDisposed() {
256251 */
257252public 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+
517540private 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