Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
HiDPISetting | 28 | 72 | 33 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package jalview.bin; | |
22 | ||
23 | import java.awt.HeadlessException; | |
24 | import java.util.Locale; | |
25 | ||
26 | import jalview.util.ErrorLog; | |
27 | ||
28 | public class HiDPISetting | |
29 | { | |
30 | private static final int hidpiThreshold = 160; | |
31 | ||
32 | private static final int hidpiMultiThreshold = 240; | |
33 | ||
34 | private static final int bigScreenThreshold = 1400; | |
35 | ||
36 | public static final String scalePropertyName = "sun.java2d.uiScale"; | |
37 | ||
38 | private static final boolean isLinux; | |
39 | ||
40 | // private static final boolean isAMac; | |
41 | ||
42 | // private static final boolean isWindows; | |
43 | ||
44 | public static final String setHiDPIPropertyName = "setHiDPI"; | |
45 | ||
46 | public static final String setHiDPIScalePropertyName = "setHiDPIScale"; | |
47 | ||
48 | private static boolean setHiDPI = false; | |
49 | ||
50 | private static int setHiDPIScale = 0; | |
51 | ||
52 | public static int dpi = 0; | |
53 | ||
54 | public static int mindimension = 0; | |
55 | ||
56 | public static int width = 0; | |
57 | ||
58 | public static int scale = 0; | |
59 | ||
60 | public final static int MAX_SCALE = 8; | |
61 | ||
62 | private static boolean doneInit = false; | |
63 | ||
64 | private static boolean allowScalePropertyArg = false; | |
65 | ||
66 | private static ScreenInfo screenInfo = new ScreenInfo(); | |
67 | ||
68 | 1 | static |
69 | { | |
70 | 1 | String system = System.getProperty("os.name") == null ? null |
71 | : System.getProperty("os.name").toLowerCase(Locale.ROOT); | |
72 | 1 | if (system != null) |
73 | { | |
74 | 1 | isLinux = system.indexOf("linux") > -1; |
75 | // isAMac = system.indexOf("mac") > -1; | |
76 | // isWindows = system.indexOf("windows") > -1; | |
77 | } | |
78 | else | |
79 | { | |
80 | 0 | isLinux = false; |
81 | // isAMac = isWindows = false; | |
82 | } | |
83 | } | |
84 | ||
85 | 6 | private static void init() |
86 | { | |
87 | 6 | if (doneInit) |
88 | { | |
89 | 0 | return; |
90 | } | |
91 | ||
92 | // get and use command line property values first | |
93 | 6 | String setHiDPIProperty = System.getProperty(setHiDPIPropertyName); |
94 | 6 | boolean setHiDPIPropertyBool = Boolean.parseBoolean(setHiDPIProperty); |
95 | ||
96 | // allow -DsetHiDPI=false to turn off HiDPI scaling | |
97 | 6 | if (setHiDPIProperty != null && !setHiDPIPropertyBool) |
98 | { | |
99 | 0 | clear(); |
100 | 0 | doneInit = true; |
101 | 0 | return; |
102 | } | |
103 | ||
104 | 6 | setHiDPI = setHiDPIProperty != null && setHiDPIPropertyBool; |
105 | ||
106 | 6 | String setHiDPIScaleProperty = System |
107 | .getProperty(setHiDPIScalePropertyName); | |
108 | 6 | if (setHiDPIScaleProperty != null) |
109 | { | |
110 | 0 | try |
111 | { | |
112 | 0 | setHiDPIScale = Integer.parseInt(setHiDPIScaleProperty); |
113 | // if setHiDPIScale property is validly set and setHiDPI property wasn't | |
114 | // attempted to be set we assume setHiDPIScale to be true | |
115 | 0 | if (setHiDPIProperty == null) |
116 | { | |
117 | 0 | setHiDPI = true; |
118 | } | |
119 | } catch (NumberFormatException e) | |
120 | { | |
121 | 0 | ErrorLog.errPrintln(setHiDPIScalePropertyName + " property give (" |
122 | + setHiDPIScaleProperty + ") but not parseable as integer"); | |
123 | } | |
124 | } | |
125 | 6 | if (setHiDPI && setHiDPIScale > 0) |
126 | { | |
127 | 0 | setHiDPIScale(setHiDPIScale); |
128 | 0 | return; |
129 | } | |
130 | ||
131 | // check to see if the scale property has already been set by something else | |
132 | // (e.g. the OS) | |
133 | 6 | String existingProperty = System.getProperty(scalePropertyName); |
134 | 6 | if (existingProperty != null) |
135 | { | |
136 | 0 | try |
137 | { | |
138 | 0 | int existingPropertyVal = Integer.parseInt(existingProperty); |
139 | 0 | ErrorLog.outPrintln("Existing " + scalePropertyName + " is " |
140 | + existingPropertyVal); | |
141 | 0 | if (existingPropertyVal > 1) |
142 | { | |
143 | 0 | setHiDPIScale(existingPropertyVal); |
144 | 0 | return; |
145 | } | |
146 | } catch (NumberFormatException e) | |
147 | { | |
148 | 0 | ErrorLog.outPrintln( |
149 | "Could not convert property " + scalePropertyName | |
150 | + " vale '" + existingProperty + "' to number"); | |
151 | } | |
152 | } | |
153 | ||
154 | // Try and auto guess a good scale based on reported DPI (not trustworthy) | |
155 | // and screen resolution (more trustworthy) | |
156 | ||
157 | // get screen dpi | |
158 | 6 | screenInfo = getScreenInfo(); |
159 | 6 | try |
160 | { | |
161 | 6 | dpi = screenInfo.getScreenResolution(); |
162 | } catch (HeadlessException e) | |
163 | { | |
164 | 0 | if (isLinux) |
165 | { | |
166 | 0 | ErrorLog.errPrintln( |
167 | "Cannot get screen resolution: " + e.getMessage()); | |
168 | } | |
169 | } | |
170 | ||
171 | // try and get screen size height and width | |
172 | 6 | try |
173 | { | |
174 | 6 | int height = screenInfo.getScreenHeight(); |
175 | 6 | int width = screenInfo.getScreenWidth(); |
176 | // using mindimension in case of portrait screens | |
177 | 6 | mindimension = Math.min(height, width); |
178 | } catch (HeadlessException e) | |
179 | { | |
180 | 0 | if (isLinux) |
181 | { | |
182 | 0 | ErrorLog.errPrintln("Cannot get screen size height and width:" |
183 | + e.getMessage()); | |
184 | } | |
185 | } | |
186 | ||
187 | // attempt at a formula for scaling based on screen dpi and mindimension. | |
188 | // scale will be an integer >=1. This formula is based on some testing and | |
189 | // guesswork! | |
190 | ||
191 | // scale based on reported dpi. if dpi>hidpiThreshold then scale=2+multiples | |
192 | // of hidpiMultiThreshold (else scale=1) | |
193 | // (e.g. dpi of 110 scales 1. dpi of 120 scales 2. dpi of 360 scales 3) | |
194 | 6 | int dpiScale = (dpi - hidpiThreshold > 0) |
195 | ? 2 + ((dpi - hidpiThreshold) / hidpiMultiThreshold) | |
196 | : 1; | |
197 | ||
198 | 6 | int dimensionScale = 1 + (mindimension / bigScreenThreshold); |
199 | ||
200 | // reject outrageous values -- dpiScale in particular could be mistaken | |
201 | 6 | if (dpiScale > MAX_SCALE) |
202 | { | |
203 | 0 | dpiScale = 1; |
204 | } | |
205 | 6 | if (dimensionScale > MAX_SCALE) |
206 | { | |
207 | 0 | dimensionScale = 1; |
208 | } | |
209 | ||
210 | // choose larger of dimensionScale or dpiScale (most likely dimensionScale | |
211 | // as dpiScale often misreported) | |
212 | 6 | int autoScale = Math.max(dpiScale, dimensionScale); |
213 | ||
214 | // only make an automatic change if scale is changed and other conditions | |
215 | // (OS is linux) apply, or if setHiDPI has been specified | |
216 | 6 | if ((autoScale > 1 && isLinux) || setHiDPI) |
217 | { | |
218 | 3 | setHiDPIScale(autoScale); |
219 | 3 | return; |
220 | } | |
221 | ||
222 | // looks like we're not doing any scaling | |
223 | 3 | doneInit = true; |
224 | } | |
225 | ||
226 | 3 | public static void setHiDPIScale(int s) |
227 | { | |
228 | 3 | scale = s; |
229 | 3 | allowScalePropertyArg = true; |
230 | 3 | doneInit = true; |
231 | } | |
232 | ||
233 | 7 | public static String getScalePropertyArg(int s) |
234 | { | |
235 | 7 | return "-D" + scalePropertyName + "=" + String.valueOf(s); |
236 | } | |
237 | ||
238 | 6 | public static String getScalePropertyArg() |
239 | { | |
240 | 6 | init(); |
241 | // HiDPI setting. Just looking at Linux to start with. Test with Windows. | |
242 | 6 | return allowScalePropertyArg ? getScalePropertyArg(scale) : null; |
243 | } | |
244 | ||
245 | 6 | public static void clear() |
246 | { | |
247 | 6 | setHiDPI = false; |
248 | 6 | setHiDPIScale = 0; |
249 | 6 | dpi = 0; |
250 | 6 | mindimension = 0; |
251 | 6 | width = 0; |
252 | 6 | scale = 0; |
253 | 6 | doneInit = false; |
254 | 6 | allowScalePropertyArg = false; |
255 | } | |
256 | ||
257 | 6 | public static void setScreenInfo(ScreenInfo si) |
258 | { | |
259 | 6 | screenInfo = si; |
260 | } | |
261 | ||
262 | 12 | public static ScreenInfo getScreenInfo() |
263 | { | |
264 | 12 | if (screenInfo == null) |
265 | { | |
266 | 0 | screenInfo = new ScreenInfo(); |
267 | } | |
268 | 12 | return screenInfo; |
269 | } | |
270 | } |