Skip to content

Commit 705f265

Browse files
committed
First draft for Program Scaling Improvement
1 parent 857ac0b commit 705f265

File tree

9 files changed

+102
-17
lines changed

9 files changed

+102
-17
lines changed

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2022 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -870,6 +870,24 @@ JNIEXPORT jlong JNICALL COM_NATIVE(SHCreateMemStream)
870870
}
871871
#endif
872872

873+
#ifndef NO_SHGetImageList
874+
JNIEXPORT jlong JNICALL COM_NATIVE(SHGetImageList)
875+
(JNIEnv *env, jclass that, jint arg0, jobject arg1, jlongArray arg2)
876+
{
877+
GUID _arg1, *lparg1=NULL;
878+
jlong *lparg2=NULL;
879+
jlong rc = 0;
880+
COM_NATIVE_ENTER(env, that, SHGetImageList_FUNC);
881+
if (arg1) if ((lparg1 = getGUIDFields(env, arg1, &_arg1)) == NULL) goto fail;
882+
if (arg2) if ((lparg2 = (*env)->GetPrimitiveArrayCritical(env, arg2, NULL)) == NULL) goto fail;
883+
rc = (jlong)SHGetImageList(arg0, lparg1, (VOID **)lparg2);
884+
fail:
885+
if (arg2 && lparg2) (*env)->ReleasePrimitiveArrayCritical(env, arg2, lparg2, 0);
886+
COM_NATIVE_EXIT(env, that, SHGetImageList_FUNC);
887+
return rc;
888+
}
889+
#endif
890+
873891
#ifndef NO_STGMEDIUM_1sizeof
874892
JNIEXPORT jint JNICALL COM_NATIVE(STGMEDIUM_1sizeof)
875893
(JNIEnv *env, jclass that)

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com_stats.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2023 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -83,6 +83,7 @@ typedef enum {
8383
RevokeDragDrop_FUNC,
8484
SHCreateItemFromParsingName_FUNC,
8585
SHCreateMemStream_FUNC,
86+
SHGetImageList_FUNC,
8687
STGMEDIUM_1sizeof_FUNC,
8788
StgCreateDocfile_FUNC,
8889
StgIsStorageFile_FUNC,

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3981,6 +3981,18 @@ JNIEXPORT void JNICALL OS_NATIVE(ImageList_1EndDrag)
39813981
}
39823982
#endif
39833983

3984+
#ifndef NO_ImageList_1GetIcon
3985+
JNIEXPORT jlong JNICALL OS_NATIVE(ImageList_1GetIcon)
3986+
(JNIEnv *env, jclass that, jlong arg0, jint arg1, jint arg2)
3987+
{
3988+
jlong rc = 0;
3989+
OS_NATIVE_ENTER(env, that, ImageList_1GetIcon_FUNC);
3990+
rc = (jlong)ImageList_GetIcon((HIMAGELIST)arg0, arg1, (UINT)arg2);
3991+
OS_NATIVE_EXIT(env, that, ImageList_1GetIcon_FUNC);
3992+
return rc;
3993+
}
3994+
#endif
3995+
39843996
#ifndef NO_ImageList_1GetIconSize
39853997
JNIEXPORT jboolean JNICALL OS_NATIVE(ImageList_1GetIconSize)
39863998
(JNIEnv *env, jclass that, jlong arg0, jintArray arg1, jintArray arg2)

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ typedef enum {
310310
ImageList_1DragMove_FUNC,
311311
ImageList_1DragShowNolock_FUNC,
312312
ImageList_1EndDrag_FUNC,
313+
ImageList_1GetIcon_FUNC,
313314
ImageList_1GetIconSize_FUNC,
314315
ImageList_1GetImageCount_FUNC,
315316
ImageList_1Remove_FUNC,

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2022 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0

bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2021 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0

bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/ole/win32/COM.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public class COM extends OS {
107107
public static final GUID IIDIAccessibleImage = IIDFromString("{FE5ABB3D-615E-4f7b-909F-5F0EDA9E8DDE}"); //$NON-NLS-1$
108108
public static final GUID IIDIAccessibleApplication = IIDFromString("{D49DED83-5B25-43F4-9B95-93B44595979E}"); //$NON-NLS-1$
109109
public static final GUID IIDIAccessibleContext = IIDFromString("{77A123E4-5794-44e0-B8BF-DE600C9D29BD}"); //$NON-NLS-1$
110-
110+
public static final GUID IID_IImageList = IIDFromString("{46EB5926-582E-4017-9FDF-E8998DAA0950}");
111111
/** Constants */
112112
public static final int CF_TEXT = 1;
113113
public static final int CF_BITMAP = 2;
@@ -465,6 +465,11 @@ private static GUID IIDFromString(String lpsz) {
465465
* @param ppv cast=(void **)
466466
*/
467467
public static final native int SHCreateItemFromParsingName (char [] pszName, long pbc, GUID riid, long [] ppv);
468+
/**
469+
* @param riid flags=no_out
470+
* @param ppvObj cast=(VOID **),flags=no_in critical
471+
*/
472+
public static final native long SHGetImageList (int iImageList, GUID riid, long[] ppvObj);
468473
/**
469474
* @param pwcsName cast=(const WCHAR *),flags=no_out
470475
* @param ppstgOpen cast=(IStorage **)

bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ public class OS extends C {
661661
public static final int ILC_COLOR8 = 0x8;
662662
public static final int ILC_MASK = 0x1;
663663
public static final int ILC_MIRROR = 0x2000;
664+
public static final int ILD_TRANSPARENT = 0x00000001;
664665
public static final int IMAGE_ICON = 0x1;
665666
public static final int IME_CMODE_FULLSHAPE = 0x8;
666667
public static final int IME_CMODE_KATAKANA = 0x2;
@@ -1209,6 +1210,7 @@ public class OS extends C {
12091210
public static final int SET_FEATURE_ON_PROCESS = 0x2;
12101211
public static final int SHADEBLENDCAPS = 120;
12111212
public static final int SHGFI_ICON = 0x000000100;
1213+
public static final int SHGFI_ICONLOCATION = 0x000001000;
12121214
public static final int SHGFI_SMALLICON= 0x1;
12131215
public static final int SHGFI_LARGEICON= 0x0;
12141216
public static final int SHGFI_USEFILEATTRIBUTES = 0x000000010;
@@ -4458,6 +4460,11 @@ public static int HRESULT_FROM_WIN32(int x) {
44584460
public static final native boolean ShowScrollBar (long hWnd, int wBar, boolean bShow);
44594461
/** @param hWnd cast=(HWND) */
44604462
public static final native boolean ShowWindow (long hWnd, int nCmdShow);
4463+
/**
4464+
* @param himl cast=(HIMAGELIST)
4465+
* @param flags cast=(UINT)
4466+
*/
4467+
public static final native long ImageList_GetIcon (long himl, int i, int flags);
44614468
/**
44624469
* @param hdc cast=(HDC)
44634470
* @param lpdi flags=no_out

bundles/org.eclipse.swt/Eclipse SWT Program/win32/org/eclipse/swt/program/Program.java

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
import org.eclipse.swt.*;
2121
import org.eclipse.swt.graphics.*;
2222
import org.eclipse.swt.internal.*;
23+
import org.eclipse.swt.internal.ole.win32.*;
2324
import org.eclipse.swt.internal.win32.*;
25+
import org.eclipse.swt.widgets.*;
2426

2527
/**
2628
* Instances of this class represent programs and
@@ -384,20 +386,13 @@ public ImageData getImageData (int zoom) {
384386
int initialNativeZoom = getPrimaryMonitorZoomAtStartup();
385387
if (extension != null) {
386388
SHFILEINFO shfi = new SHFILEINFO ();
387-
int flags = OS.SHGFI_ICON | OS.SHGFI_USEFILEATTRIBUTES;
388-
boolean useLargeIcon = 100 * zoom / initialNativeZoom >= 200;
389-
if(useLargeIcon) {
390-
flags |= OS.SHGFI_LARGEICON;
391-
initialNativeZoom *= 2;
392-
} else {
393-
flags |= OS.SHGFI_SMALLICON;
394-
}
389+
int flags = OS.SHGFI_USEFILEATTRIBUTES | OS.SHGFI_ICONLOCATION;
395390
TCHAR pszPath = new TCHAR (0, extension, true);
396391
OS.SHGetFileInfo (pszPath.chars, OS.FILE_ATTRIBUTE_NORMAL, shfi, SHFILEINFO.sizeof, flags);
397-
if (shfi.hIcon != 0) {
398-
Image image = Image.win32_new (null, SWT.ICON, shfi.hIcon, initialNativeZoom);
399-
ImageData imageData = image.getImageData (zoom);
400-
image.dispose ();
392+
if (shfi.iIcon >= 0) {
393+
Image icon = getImageForZoom(zoom, shfi.iIcon);
394+
ImageData imageData = icon.getImageData(zoom);
395+
icon.dispose();
401396
return imageData;
402397
}
403398
}
@@ -434,6 +429,52 @@ private int getPrimaryMonitorZoomAtStartup() {
434429
return DPIUtil.mapDPIToZoom(dpi);
435430
}
436431

432+
private static int ICON_SIZE_AT_100 = 0x3;
433+
434+
private NavigableMap<Integer, Long> getImageListForAllZoomLevel() {
435+
TreeMap<Integer, Long> zoomToHImageList = new TreeMap<>();
436+
int [] allSizes = new int [] {0x0, 0x1, 0x2};
437+
long hImageListAt100 = getImageListForSize(ICON_SIZE_AT_100);
438+
int sizeAt100 = getIconSizeOfImageList(hImageListAt100);
439+
zoomToHImageList.put(100, hImageListAt100);
440+
for (int size : allSizes) {
441+
long hImageList = getImageListForSize(size);
442+
int iconSize = getIconSizeOfImageList(hImageList);
443+
int zoom = (iconSize / sizeAt100) * 100;
444+
zoomToHImageList.put(zoom, hImageList);
445+
}
446+
return zoomToHImageList;
447+
}
448+
449+
private int getIconSizeOfImageList(long hImageList) {
450+
int [] cx = new int [1];
451+
int [] cy = new int [1];
452+
OS.ImageList_GetIconSize(hImageList, cx, cy);
453+
return cx[0];
454+
}
455+
456+
private Image getImageForZoom(int zoom, int index) {
457+
NavigableMap<Integer, Long> zoomToHImageList = getImageListForAllZoomLevel();
458+
int closestHImageList = getClosestKey(zoomToHImageList, zoom);
459+
long hIcon = OS.ImageList_GetIcon(zoomToHImageList.get(closestHImageList), index, OS.ILD_TRANSPARENT);
460+
getImageListForAllZoomLevel().values().forEach(handle -> OS.ImageList_Destroy(handle));
461+
return Image.win32_new(Display.getCurrent(), SWT.ICON, hIcon, zoom);
462+
}
463+
464+
private long getImageListForSize(int size) {
465+
long [] ppv = new long [1];
466+
COM.SHGetImageList(size, COM.IID_IImageList, ppv);
467+
return ppv[0];
468+
}
469+
470+
private Integer getClosestKey(NavigableMap<Integer, Long> map, int x) {
471+
Integer floorKey = map.floorKey(x);
472+
Integer ceilingKey = map.ceilingKey(x);
473+
if (floorKey == null) return ceilingKey;
474+
if (ceilingKey == null) return floorKey;
475+
return (Math.abs(x - floorKey) <= Math.abs(x - ceilingKey)) ? floorKey : ceilingKey;
476+
}
477+
437478
/**
438479
* Returns the receiver's name. This is as short and
439480
* descriptive a name as possible for the program. If

0 commit comments

Comments
 (0)