@@ -274,26 +274,6 @@ void closeWidget () {
274274 if (event .doit && !isDisposed ()) dispose ();
275275}
276276
277- int compare (ImageData data1 , ImageData data2 , int width , int height , int depth ) {
278- int value1 = Math .abs (data1 .width - width ), value2 = Math .abs (data2 .width - width );
279- if (value1 == value2 ) {
280- int transparent1 = data1 .getTransparencyType ();
281- int transparent2 = data2 .getTransparencyType ();
282- if (transparent1 == transparent2 ) {
283- if (data1 .depth == data2 .depth ) return 0 ;
284- return data1 .depth > data2 .depth && data1 .depth <= depth ? -1 : 1 ;
285- }
286- if (transparent1 == SWT .TRANSPARENCY_ALPHA ) return -1 ;
287- if (transparent2 == SWT .TRANSPARENCY_ALPHA ) return 1 ;
288- if (transparent1 == SWT .TRANSPARENCY_MASK ) return -1 ;
289- if (transparent2 == SWT .TRANSPARENCY_MASK ) return 1 ;
290- if (transparent1 == SWT .TRANSPARENCY_PIXEL ) return -1 ;
291- if (transparent2 == SWT .TRANSPARENCY_PIXEL ) return 1 ;
292- return 0 ;
293- }
294- return value1 < value2 ? -1 : 1 ;
295- }
296-
297277@ Override
298278Widget computeTabGroup () {
299279 return this ;
@@ -882,7 +862,7 @@ public void setImage (Image image) {
882862 setImages (image , null );
883863}
884864
885- void setImages (Image image , Image [] images ) {
865+ private void setImages (Image image , Image [] images ) {
886866 if (smallImage != null ) smallImage .dispose ();
887867 if (largeImage != null ) largeImage .dispose ();
888868 smallImage = largeImage = null ;
@@ -892,23 +872,17 @@ void setImages (Image image, Image [] images) {
892872 smallIcon = largeIcon = image ;
893873 } else {
894874 if (images != null && images .length > 0 ) {
895- int depth = display .getIconDepth ();
896- ImageData [] datas = null ;
897- if (images .length > 1 ) {
898- Image [] bestImages = new Image [images .length ];
899- System .arraycopy (images , 0 , bestImages , 0 , images .length );
900- datas = new ImageData [images .length ];
901- for (int i =0 ; i <datas .length ; i ++) {
902- datas [i ] = images [i ].getImageData ();
903- }
904- images = bestImages ;
905- sort (images , datas , getSystemMetrics (OS .SM_CXSMICON ), getSystemMetrics (OS .SM_CYSMICON ), depth );
906- }
907- smallIcon = images [0 ];
908- if (images .length > 1 ) {
909- sort (images , datas , getSystemMetrics (OS .SM_CXICON ), getSystemMetrics (OS .SM_CYICON ), depth );
910- }
911- largeIcon = images [0 ];
875+ int depth = display .getIconDepth ();
876+
877+ ImageData [] imageData = getImageDataAt100 (images );
878+
879+ int smallIconWidthAt100 = getSystemMetrics (OS .SM_CXSMICON );
880+ int smallIconIndex = findIndexOfClosest (imageData , smallIconWidthAt100 , depth );
881+ smallIcon = images [smallIconIndex ];
882+
883+ int largeIconWidthAt100 = getSystemMetrics (OS .SM_CXICON );
884+ int largeIconIndex = findIndexOfClosest (imageData , largeIconWidthAt100 , depth );
885+ largeIcon = images [largeIconIndex ];
912886 }
913887 }
914888 if (smallIcon != null ) {
@@ -949,6 +923,64 @@ void setImages (Image image, Image [] images) {
949923 }
950924}
951925
926+ private static ImageData [] getImageDataAt100 (Image [] images ) {
927+ ImageData [] datas = new ImageData [images .length ];
928+ for (int i = 0 ; i < images .length ; i ++) {
929+ datas [i ] = images [i ].getImageData (100 );
930+ }
931+ return datas ;
932+ }
933+
934+ private static int findIndexOfClosest (ImageData [] imageData , int targetWidth , int targetDepth ) {
935+ int closestIndex = 0 ;
936+ ImageData closestData = imageData [0 ];
937+ for (int i = 1 ; i < imageData .length ; i ++) {
938+ if (isCloserThan (imageData [i ], closestData , targetWidth , targetDepth )) {
939+ closestIndex = i ;
940+ closestData = imageData [i ];
941+ }
942+ }
943+
944+ return closestIndex ;
945+ }
946+
947+ private static boolean isCloserThan (ImageData dataToTest , ImageData referenceData , int targetWidth , int targetDepth ) {
948+ int diffWidthToTest = Math .abs (dataToTest .width - targetWidth );
949+ int diffReferenceWidth = Math .abs (referenceData .width - targetWidth );
950+
951+ // The closer the width the better
952+ if (diffWidthToTest != diffReferenceWidth )
953+ return diffWidthToTest < diffReferenceWidth ;
954+
955+ int transparencyToTest = dataToTest .getTransparencyType ();
956+ int referenceTransparency = referenceData .getTransparencyType ();
957+
958+ // If they have the same transparency then the bigger the pixel depth (without
959+ // surpassing the target depth) the better
960+ if (transparencyToTest == referenceTransparency ) {
961+ if (dataToTest .depth == referenceData .depth )
962+ return false ;
963+
964+ return dataToTest .depth > referenceData .depth && dataToTest .depth <= targetDepth ;
965+ }
966+
967+ // If they have different transparency, favor (in this order): the one with
968+ // an alpha channel, the one with a mask, the one with a transparency pixel
969+ if (transparencyToTest == SWT .TRANSPARENCY_ALPHA )
970+ return true ;
971+ if (referenceTransparency == SWT .TRANSPARENCY_ALPHA )
972+ return false ;
973+ if (transparencyToTest == SWT .TRANSPARENCY_MASK )
974+ return true ;
975+ if (referenceTransparency == SWT .TRANSPARENCY_MASK )
976+ return false ;
977+ if (transparencyToTest == SWT .TRANSPARENCY_PIXEL )
978+ return true ;
979+ if (referenceTransparency == SWT .TRANSPARENCY_PIXEL )
980+ return false ;
981+ return false ;
982+ }
983+
952984/**
953985 * Sets the receiver's images to the argument, which may
954986 * be an empty array. Images are typically displayed by the
@@ -1313,26 +1345,6 @@ public void setVisible (boolean visible) {
13131345 }
13141346}
13151347
1316- void sort (Image [] images , ImageData [] datas , int width , int height , int depth ) {
1317- /* Shell Sort from K&R, pg 108 */
1318- int length = images .length ;
1319- if (length <= 1 ) return ;
1320- for (int gap =length /2 ; gap >0 ; gap /=2 ) {
1321- for (int i =gap ; i <length ; i ++) {
1322- for (int j =i -gap ; j >=0 ; j -=gap ) {
1323- if (compare (datas [j ], datas [j + gap ], width , height , depth ) >= 0 ) {
1324- Image swap = images [j ];
1325- images [j ] = images [j + gap ];
1326- images [j + gap ] = swap ;
1327- ImageData swapData = datas [j ];
1328- datas [j ] = datas [j + gap ];
1329- datas [j + gap ] = swapData ;
1330- }
1331- }
1332- }
1333- }
1334- }
1335-
13361348@ Override
13371349boolean translateAccelerator (MSG msg ) {
13381350 if (!isEnabled () || !isActive ()) return false ;
0 commit comments