@@ -491,13 +491,38 @@ public void copyArea (Image image, int x, int y) {
491491 storeAndApplyOperationForExistingHandle (new CopyAreaToImageOperation (image , x , y ));
492492}
493493
494- private class CopyAreaToImageOperation extends Operation {
495- private final Image image ;
494+ private abstract class ImageOperation extends Operation {
495+ private Image image ;
496+
497+ ImageOperation (Image image ) {
498+ setImage (image );
499+ image .addOnDisposeListener (this ::setCopyOfImage );
500+ }
501+
502+ private void setImage (Image image ) {
503+ this .image = image ;
504+ }
505+
506+ private void setCopyOfImage (Image image ) {
507+ if (!GC .this .isDisposed ()) {
508+ Image copiedImage = new Image (image .device , image , SWT .IMAGE_COPY );
509+ setImage (copiedImage );
510+ registerForDisposal (copiedImage );
511+ }
512+ }
513+
514+ protected Image getImage () {
515+ return image ;
516+ }
517+
518+ }
519+
520+ private class CopyAreaToImageOperation extends ImageOperation {
496521 private final int x ;
497522 private final int y ;
498523
499524 CopyAreaToImageOperation (Image image , int x , int y ) {
500- this . image = image ;
525+ super ( image ) ;
501526 this .x = x ;
502527 this .y = y ;
503528 }
@@ -507,7 +532,7 @@ void apply() {
507532 int zoom = getZoom ();
508533 int scaledX = Win32DPIUtils .pointToPixel (drawable , this .x , zoom );
509534 int scaledY = Win32DPIUtils .pointToPixel (drawable , this .y , zoom );
510- copyAreaInPixels (this . image , scaledX , scaledY );
535+ copyAreaInPixels (getImage () , scaledX , scaledY );
511536 }
512537}
513538
@@ -1013,18 +1038,17 @@ public void drawImage (Image image, int x, int y) {
10131038 storeAndApplyOperationForExistingHandle (new DrawImageOperation (image , new Point (x , y )));
10141039}
10151040
1016- private class DrawImageOperation extends Operation {
1017- private final Image image ;
1041+ private class DrawImageOperation extends ImageOperation {
10181042 private final Point location ;
10191043
10201044 DrawImageOperation (Image image , Point location ) {
1021- this . image = image ;
1045+ super ( image ) ;
10221046 this .location = location ;
10231047 }
10241048
10251049 @ Override
10261050 void apply () {
1027- drawImageInPixels (this . image , Win32DPIUtils .pointToPixel (drawable , this .location , getZoom ()));
1051+ drawImageInPixels (getImage () , Win32DPIUtils .pointToPixel (drawable , this .location , getZoom ()));
10281052 }
10291053
10301054 private void drawImageInPixels (Image image , Point location ) {
@@ -1081,13 +1105,12 @@ void drawImage(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight,
10811105 storeAndApplyOperationForExistingHandle (new DrawImageToImageOperation (srcImage , new Rectangle (srcX , srcY , srcWidth , srcHeight ), new Rectangle (destX , destY , destWidth , destHeight ), simple ));
10821106}
10831107
1084- private class DrawScalingImageToImageOperation extends Operation {
1085- private final Image image ;
1108+ private class DrawScalingImageToImageOperation extends ImageOperation {
10861109 private final Rectangle source ;
10871110 private final Rectangle destination ;
10881111
10891112 DrawScalingImageToImageOperation (Image image , Rectangle source , Rectangle destination ) {
1090- this . image = image ;
1113+ super ( image ) ;
10911114 this .source = source ;
10921115 this .destination = destination ;
10931116 }
@@ -1096,7 +1119,7 @@ private class DrawScalingImageToImageOperation extends Operation {
10961119 void apply () {
10971120 int gcZoom = getZoom ();
10981121 int srcImageZoom = calculateZoomForImage (gcZoom , source .width , source .height , destination .width , destination .height );
1099- drawImage (image , source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , gcZoom , srcImageZoom );
1122+ drawImage (getImage () , source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , gcZoom , srcImageZoom );
11001123 }
11011124
11021125 private Collection <Integer > getAllCurrentMonitorZooms () {
@@ -1154,22 +1177,21 @@ private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHei
11541177 drawImage (image , src .x , src .y , src .width , src .height , dest .x , dest .y , dest .width , dest .height , false , scaledImageZoom );
11551178}
11561179
1157- private class DrawImageToImageOperation extends Operation {
1158- private final Image image ;
1180+ private class DrawImageToImageOperation extends ImageOperation {
11591181 private final Rectangle source ;
11601182 private final Rectangle destination ;
11611183 private final boolean simple ;
11621184
11631185 DrawImageToImageOperation (Image image , Rectangle source , Rectangle destination , boolean simple ) {
1164- this . image = image ;
1186+ super ( image ) ;
11651187 this .source = source ;
11661188 this .destination = destination ;
11671189 this .simple = simple ;
11681190 }
11691191
11701192 @ Override
11711193 void apply () {
1172- drawImage (image , source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , simple , getZoom ());
1194+ drawImage (getImage () , source .x , source .y , source .width , source .height , destination .x , destination .y , destination .width , destination .height , simple , getZoom ());
11731195 }
11741196}
11751197
@@ -1958,14 +1980,20 @@ private class DrawPathOperation extends Operation {
19581980 @ Override
19591981 void apply () {
19601982 Path path = new Path (device , pathData );
1961- long pathHandle = path .getHandle (getZoom ());
1962- if (pathHandle == 0 ) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1963- initGdip ();
1964- checkGC (DRAW );
1965- long gdipGraphics = data .gdipGraphics ;
1966- Gdip .Graphics_TranslateTransform (gdipGraphics , data .gdipXOffset , data .gdipYOffset , Gdip .MatrixOrderPrepend );
1967- Gdip .Graphics_DrawPath (gdipGraphics , data .gdipPen , pathHandle );
1968- Gdip .Graphics_TranslateTransform (gdipGraphics , -data .gdipXOffset , -data .gdipYOffset , Gdip .MatrixOrderPrepend );
1983+ try {
1984+ long pathHandle = path .getHandle (getZoom ());
1985+ if (pathHandle == 0 )
1986+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
1987+ initGdip ();
1988+ checkGC (DRAW );
1989+ long gdipGraphics = data .gdipGraphics ;
1990+ Gdip .Graphics_TranslateTransform (gdipGraphics , data .gdipXOffset , data .gdipYOffset , Gdip .MatrixOrderPrepend );
1991+ Gdip .Graphics_DrawPath (gdipGraphics , data .gdipPen , pathHandle );
1992+ Gdip .Graphics_TranslateTransform (gdipGraphics , -data .gdipXOffset , -data .gdipYOffset ,
1993+ Gdip .MatrixOrderPrepend );
1994+ } finally {
1995+ path .dispose ();
1996+ }
19691997 }
19701998}
19711999
@@ -3272,13 +3300,18 @@ private class FillPathOperation extends Operation {
32723300 @ Override
32733301 void apply () {
32743302 Path path = new Path (device , pathData );
3275- long pathHandle = path .getHandle (getZoom ());
3276- if (pathHandle == 0 ) SWT .error (SWT .ERROR_INVALID_ARGUMENT );
3277- initGdip ();
3278- checkGC (FILL );
3279- int mode = OS .GetPolyFillMode (handle ) == OS .WINDING ? Gdip .FillModeWinding : Gdip .FillModeAlternate ;
3280- Gdip .GraphicsPath_SetFillMode (pathHandle , mode );
3281- Gdip .Graphics_FillPath (data .gdipGraphics , data .gdipBrush , pathHandle );
3303+ try {
3304+ long pathHandle = path .getHandle (getZoom ());
3305+ if (pathHandle == 0 )
3306+ SWT .error (SWT .ERROR_INVALID_ARGUMENT );
3307+ initGdip ();
3308+ checkGC (FILL );
3309+ int mode = OS .GetPolyFillMode (handle ) == OS .WINDING ? Gdip .FillModeWinding : Gdip .FillModeAlternate ;
3310+ Gdip .GraphicsPath_SetFillMode (pathHandle , mode );
3311+ Gdip .Graphics_FillPath (data .gdipGraphics , data .gdipBrush , pathHandle );
3312+ } finally {
3313+ path .dispose ();
3314+ }
32823315 }
32833316}
32843317
@@ -4629,7 +4662,9 @@ private class SetBackgroundOperation extends Operation {
46294662 private final Color color ;
46304663
46314664 SetBackgroundOperation (Color color ) {
4632- this .color = color ;
4665+ RGB rgb = color .getRGB ();
4666+ this .color = new Color (color .getDevice (), rgb );
4667+ registerForDisposal (this .color );
46334668 }
46344669
46354670 @ Override
@@ -4676,6 +4711,7 @@ private class SetBackgroundPatternOperation extends Operation {
46764711
46774712 SetBackgroundPatternOperation (Pattern pattern ) {
46784713 this .pattern = pattern == null ? null : pattern .copy ();
4714+ registerForDisposal (this .pattern );
46794715 }
46804716
46814717 @ Override
@@ -4938,7 +4974,8 @@ private class SetFontOperation extends Operation {
49384974 private final Font font ;
49394975
49404976 SetFontOperation (Font font ) {
4941- this .font = font ;
4977+ this .font = new Font (font .getDevice (), font .getFontData ());
4978+ registerForDisposal (this .font );
49424979 }
49434980
49444981 @ Override
@@ -4973,7 +5010,9 @@ private class SetForegroundOperation extends Operation {
49735010 private final Color color ;
49745011
49755012 SetForegroundOperation (Color color ) {
4976- this .color = color ;
5013+ RGB rgb = color .getRGB ();
5014+ this .color = new Color (color .getDevice (), rgb );
5015+ registerForDisposal (this .color );
49775016 }
49785017
49795018 @ Override
@@ -5019,6 +5058,7 @@ private class SetForegroundPatternOperation extends Operation {
50195058
50205059 SetForegroundPatternOperation (Pattern pattern ) {
50215060 this .pattern = pattern == null ? null : pattern .copy ();
5061+ registerForDisposal (this .pattern );
50225062 }
50235063
50245064 @ Override
@@ -5604,6 +5644,7 @@ private class SetTransformOperation extends Operation {
56045644 float [] elements = new float [6 ];
56055645 transform .getElements (elements );
56065646 this .transform = new Transform (device , elements [0 ], elements [1 ], elements [2 ], elements [3 ], elements [4 ], elements [5 ]);
5647+ registerForDisposal (this .transform );
56075648 } else {
56085649 this .transform = null ;
56095650 }
@@ -5876,8 +5917,36 @@ private void createGcHandle(Drawable drawable, GCData newData, int nativeZoom) {
58765917 }
58775918}
58785919
5920+
5921+ @ Override
5922+ public void dispose () {
5923+ super .dispose ();
5924+ disposeOperations ();
5925+ }
5926+
5927+ private void disposeOperations () {
5928+ for (Operation op : operations ) {
5929+ op .disposeAll ();
5930+ }
5931+ operations .clear ();
5932+ }
5933+
58795934private abstract class Operation {
5935+ private final List <Resource > disposables = new ArrayList <>();
58805936 abstract void apply ();
5937+
5938+ protected void registerForDisposal (Resource resource ) {
5939+ if (resource != null ) {
5940+ disposables .add (resource );
5941+ }
5942+ }
5943+
5944+ void disposeAll () {
5945+ for (Resource r : disposables ) {
5946+ r .dispose ();
5947+ }
5948+ disposables .clear ();
5949+ }
58815950}
58825951}
58835952
0 commit comments