7a22607a60147e53ff83679f23ab59e5e790abdd
[jalview.git] / src / jalview / bin / HiDPISetting.java
1 package jalview.bin;
2
3 import java.awt.HeadlessException;
4
5 public class HiDPISetting
6 {
7   private static final int hidpiThreshold = 160;
8
9   private static final int hidpiMultiThreshold = 240;
10
11   private static final int bigScreenThreshold = 1400;
12
13   public static final String scalePropertyName = "sun.java2d.uiScale";
14
15   private static final boolean isLinux;
16
17   // private static final boolean isAMac;
18
19   // private static final boolean isWindows;
20
21   public static final String setHiDPIPropertyName = "setHiDPI";
22
23   public static final String setHiDPIScalePropertyName = "setHiDPIScale";
24
25   private static boolean setHiDPI = false;
26
27   private static int setHiDPIScale = 0;
28
29   public static int dpi = 0;
30
31   public static int mindimension = 0;
32
33   public static int width = 0;
34
35   public static int scale = 0;
36
37   public final static int MAX_SCALE = 8;
38
39   private static boolean doneInit = false;
40
41   private static boolean allowScalePropertyArg = false;
42
43   private static ScreenInfo screenInfo = new ScreenInfo();
44
45   static
46   {
47     String system = System.getProperty("os.name") == null ? null
48             : System.getProperty("os.name").toLowerCase();
49     if (system != null)
50     {
51       isLinux = system.indexOf("linux") > -1;
52       // isAMac = system.indexOf("mac") > -1;
53       // isWindows = system.indexOf("windows") > -1;
54     }
55     else
56     {
57       isLinux = false;
58       // isAMac = isWindows = false;
59     }
60   }
61
62   private static void init()
63   {
64     if (doneInit)
65     {
66       return;
67     }
68
69     // get and use command line property values first
70     String setHiDPIProperty = System.getProperty(setHiDPIPropertyName);
71     setHiDPI = setHiDPIProperty != null
72             && setHiDPIProperty.equalsIgnoreCase("true");
73
74     String setHiDPIScaleProperty = System
75             .getProperty(setHiDPIScalePropertyName);
76     if (setHiDPIScaleProperty != null)
77     {
78       try
79       {
80         setHiDPIScale = Integer.parseInt(setHiDPIScaleProperty);
81       } catch (NumberFormatException e)
82       {
83         System.err.println(setHiDPIScalePropertyName + " property give ("
84                 + setHiDPIScaleProperty + ") but not parseable as integer");
85       }
86     }
87     if (setHiDPI && setHiDPIScale > 0)
88     {
89       setHiDPIScale(setHiDPIScale);
90       return;
91     }
92
93     // check to see if the scale property has already been set by something else
94     // (e.g. the OS)
95     String existingProperty = System.getProperty(scalePropertyName);
96     if (existingProperty != null)
97     {
98       try
99       {
100         int existingPropertyVal = Integer.parseInt(existingProperty);
101         System.out.println("Existing " + scalePropertyName + " is "
102                 + existingPropertyVal);
103         if (existingPropertyVal > 1)
104         {
105           setHiDPIScale(existingPropertyVal);
106           return;
107         }
108       } catch (NumberFormatException e)
109       {
110         System.out.println("Could not convert property " + scalePropertyName
111                 + " vale '" + existingProperty + "' to number");
112       }
113     }
114
115     // Try and auto guess a good scale based on reported DPI (not trustworthy)
116     // and screen resolution (more trustworthy)
117
118     // get screen dpi
119     screenInfo = getScreenInfo();
120     try
121     {
122       dpi = screenInfo.getScreenResolution();
123     } catch (HeadlessException e)
124     {
125       System.err.println("Cannot get screen resolution: " + e.getMessage());
126     }
127
128     // try and get screen size height and width
129     try
130     {
131       int height = screenInfo.getScreenHeight();
132       int width = screenInfo.getScreenWidth();
133       // using mindimension in case of portrait screens
134       mindimension = Math.min(height, width);
135     } catch (HeadlessException e)
136     {
137       System.err.println(
138               "Cannot get screen size height and width:" + e.getMessage());
139     }
140
141     // attempt at a formula for scaling based on screen dpi and mindimension.
142     // scale will be an integer >=1. This formula is based on some testing and
143     // guesswork!
144
145     // scale based on reported dpi. if dpi>hidpiThreshold then scale=2+multiples
146     // of hidpiMultiThreshold (else scale=1)
147     // (e.g. dpi of 110 scales 1. dpi of 120 scales 2. dpi of 360 scales 3)
148     int dpiScale = (dpi - hidpiThreshold > 0)
149             ? 2 + ((dpi - hidpiThreshold) / hidpiMultiThreshold)
150             : 1;
151
152     int dimensionScale = 1 + (mindimension / bigScreenThreshold);
153
154     // reject outrageous values -- dpiScale in particular could be mistaken
155     if (dpiScale > MAX_SCALE) {
156       dpiScale = 1;
157     }
158     if (dimensionScale > MAX_SCALE) {
159       dimensionScale = 1;
160     }
161
162     // choose larger of dimensionScale or dpiScale (most likely dimensionScale
163     // as dpiScale often misreported)
164     int autoScale = Math.max(dpiScale, dimensionScale);
165
166     // only make an automatic change if scale is changed and other conditions
167     // (OS is linux) apply, or if setHiDPI has been specified
168     if ((autoScale > 1 && isLinux) || setHiDPI)
169     {
170       setHiDPIScale(autoScale);
171       return;
172     }
173
174     // looks like we're not doing any scaling
175     doneInit = true;
176   }
177
178   public static void setHiDPIScale(int s)
179   {
180     scale = s;
181     allowScalePropertyArg = true;
182     doneInit = true;
183   }
184
185   public static String getScalePropertyArg(int s)
186   {
187     return "-D" + scalePropertyName + "=" + String.valueOf(s);
188   }
189
190   public static String getScalePropertyArg()
191   {
192     init();
193     // HiDPI setting. Just looking at Linux to start with. Test with Windows.
194     return allowScalePropertyArg ? getScalePropertyArg(scale) : null;
195   }
196
197   public static void clear()
198   {
199     setHiDPI = false;
200     setHiDPIScale = 0;
201     dpi = 0;
202     mindimension = 0;
203     width = 0;
204     scale = 0;
205     doneInit = false;
206     allowScalePropertyArg = false;
207   }
208
209   public static void setScreenInfo(ScreenInfo si)
210   {
211     screenInfo = si;
212   }
213
214   public static ScreenInfo getScreenInfo()
215   {
216     if (screenInfo == null)
217     {
218       screenInfo = new ScreenInfo();
219     }
220     return screenInfo;
221   }
222 }