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/**
@@ -539,6 +538,19 @@ private void storeAndApplyOperationForAllHandles(Operation operation) {
539538 zoomToHandle .forEach ((zoom , handle ) -> operation .apply (handle ));
540539}
541540
541+ private <T > T applyOnAnyHandle (Function <TransformHandle , T > function ) {
542+ if (zoomToHandle .isEmpty ()) {
543+ TransformHandle handle = newTransformHandle (DPIUtil .getDeviceZoom ());
544+ try {
545+ return function .apply (handle );
546+ } finally {
547+ handle .destroy ();
548+ }
549+ } else {
550+ return function .apply (zoomToHandle .values ().iterator ().next ());
551+ }
552+ }
553+
542554/**
543555 * Returns a string containing a concise, human-readable
544556 * description of the receiver.
@@ -552,21 +564,27 @@ public String toString() {
552564 getElements (elements );
553565 return "Transform {" + elements [0 ] + "," + elements [1 ] + "," +elements [2 ] + "," +elements [3 ] + "," +elements [4 ] + "," +elements [5 ] + "}" ;
554566}
567+
568+ private TransformHandle newTransformHandle (int zoom ) {
569+ long newHandle = Gdip .Matrix_new (0 , 0 , 0 , 0 , 0 , 0 );
570+ if (newHandle == 0 ) SWT .error (SWT .ERROR_NO_HANDLES );
571+ TransformHandle newTransformHandle = new TransformHandle (newHandle , zoom );
572+ for (Operation operation : operations ) {
573+ operation .apply (newTransformHandle );
574+ }
575+ return newTransformHandle ;
576+ }
577+
555578private TransformHandle getTransformHandle (int zoom ) {
556- if (zoomToHandle .get (zoom ) == null ) {
557- float [] elements = new float [6 ];
558- getElements (elements );
559- elements [4 ] = DPIUtil .scaleUp (device , DPIUtil .scaleDown (device , elements [4 ], initialZoom ), zoom );
560- elements [5 ] = DPIUtil .scaleUp (device , DPIUtil .scaleDown (device , elements [5 ], initialZoom ), zoom );
561- long handle = Gdip .Matrix_new (elements [0 ], elements [1 ], elements [2 ], elements [3 ], elements [4 ], elements [5 ]);
562- TransformHandle transformHandle = new TransformHandle (handle , zoom );
563- zoomToHandle .put (zoom , transformHandle );
564- return transformHandle ;
579+ if (!zoomToHandle .containsKey (zoom )) {
580+ TransformHandle newPathHandle = newTransformHandle (zoom );
581+ zoomToHandle .put (zoom , newPathHandle );
582+ return newPathHandle ;
565583 }
566584 return zoomToHandle .get (zoom );
567585}
568586
569- long getHandle (int zoomLevel ) {
570- return getTransformHandle (zoomLevel ).handle ;
587+ long getHandle (int zoom ) {
588+ return getTransformHandle (zoom ).handle ;
571589}
572590}
0 commit comments