]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/DPIUtil.java
HiDPI scaling for diagram ruler and model activity tracker
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / DPIUtil.java
1 /*******************************************************************************
2  * Copyright (c) 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     Semantum Oy - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.utils;
13
14 import java.awt.Point;
15 import java.awt.Rectangle;
16 import java.awt.Toolkit;
17 import java.awt.geom.Point2D;
18 import java.awt.geom.Rectangle2D;
19
20 /**
21  * @author Tuukka Lehtonen
22  * @since 1.36.0
23  */
24 public class DPIUtil {
25
26         private static boolean initialized = false;
27         private static boolean hasZoom;
28
29         private static float upscaleFactorF;
30         private static double upscaleFactorD;
31         private static float downscaleFactorF;
32         private static double downscaleFactorD;
33
34         private static void initialize() {
35                 if (initialized)
36                         return;
37
38                 double dpi = Toolkit.getDefaultToolkit().getScreenResolution();
39                 double baseDpi = 96;
40                 int zoom = (int) Math.round(100.0 * dpi / baseDpi);
41                 hasZoom = zoom != 100;
42
43                 upscaleFactorD   = dpi / baseDpi;
44                 upscaleFactorF   = (float) upscaleFactorD;
45                 downscaleFactorD = baseDpi / dpi;
46                 downscaleFactorF   = (float) downscaleFactorD;
47
48 //              System.out.format("DPIUtil:%n\tswt zoom = %d%n\tdownscale factor = %f%n\tupscale factor = %f%n",
49 //                              zoom,
50 //                              downscaleFactorD,
51 //                              upscaleFactorD
52 //                              );
53
54                 initialized = true;
55         }
56
57         // Internals
58
59         private static Rectangle scale(float s, Rectangle r, Rectangle target) {
60                 if (s == 1.0f) {
61                         if (r == target)
62                                 return r;
63                         if (target == null) {
64                                 return new Rectangle(r.x, r.y, r.width, r.height);
65                         } else {
66                                 target.x = r.x;
67                                 target.y = r.y;
68                                 target.width = r.width;
69                                 target.height = r.height;
70                                 return target;
71                         }
72                 }
73                 if (target == null) {
74                         return new Rectangle(
75                                         Math.round(r.x*s),
76                                         Math.round(r.y*s),
77                                         Math.round(r.width*s),
78                                         Math.round(r.height*s));
79                 } else {
80                         target.x = Math.round(r.x*s);
81                         target.y = Math.round(r.y*s);
82                         target.width = Math.round(r.width*s);
83                         target.height = Math.round(r.height*s);
84                         return target;
85                 }
86         }
87
88         private static Rectangle2D scale(double s, Rectangle2D r, Rectangle2D target) {
89                 if (s == 1.0) {
90                         if (r == target)
91                                 return r;
92                         if (target == null)
93                                 return (Rectangle2D) r.clone();
94                         target.setFrame(r);
95                         return target;
96                 }
97                 if (target == null)
98                         target = (Rectangle2D) r.clone();
99                 target.setFrame(r.getX()*s, r.getY()*s, r.getWidth()*s, r.getHeight()*s);
100                 return target;
101         }
102
103         private static double downscale0(double x) {
104                 return hasZoom ? x * downscaleFactorD : x;
105         }
106
107         private static int downscaleToInteger0(double x) {
108                 return (int)(hasZoom ? Math.round((double) x * downscaleFactorD) : x);
109         }
110
111         private static int downscale0(int x) {
112                 return hasZoom ? (int) Math.round((double) x * downscaleFactorD) : x;
113         }
114
115         private static double upscale0(double x) {
116                 return hasZoom ? x * upscaleFactorD : x;
117         }
118
119         private static int upscaleToInteger0(double x) {
120                 return (int)(hasZoom ? Math.round((double) x * upscaleFactorD) : x);
121         }
122
123         private static int upscale0(int x) {
124                 return hasZoom ? (int) Math.round((double) x * upscaleFactorD) : x;
125         }
126
127         // Downscaling
128
129         public static double downscale(double x) {
130                 initialize();
131                 return downscale0(x);
132         }
133
134         public static int downscale(int x) {
135                 initialize();
136                 return downscale0(x);
137         }
138
139         public static Point2D downscale(double x, double y) {
140                 initialize();
141                 if (!hasZoom)
142                         return new Point2D.Double(x, y);
143                 double s = downscaleFactorD;
144                 return new Point2D.Double(x * s, y * s);
145         }
146
147         public static Point downscale(int x, int y) {
148                 initialize();
149                 return new Point(downscale0(x), downscale0(y));
150         }
151
152         public static Point2D downscale(Point2D p) {
153                 return downscale(p.getX(), p.getY());
154         }
155
156         public static Point downscaleToInteger(Point2D p) {
157                 initialize();
158                 return new Point(downscaleToInteger0(p.getX()), downscaleToInteger0(p.getY()));
159         }
160
161         public static Rectangle2D downscale(Rectangle2D r, Rectangle2D target) {
162                 initialize();
163                 return scale(downscaleFactorD, r, target);
164         }
165
166         public static Rectangle2D downscale(Rectangle2D r) {
167                 return downscale(r, null);
168         }
169
170         public static Rectangle downscale(Rectangle r, Rectangle target) {
171                 initialize();
172                 return scale(downscaleFactorF, r, target);
173         }
174
175         public static Rectangle downscale(Rectangle r) {
176                 return downscale(r, null);
177         }
178
179         public static Rectangle downscaleToInteger(Rectangle2D r) {
180                 initialize();
181                 return new Rectangle( 
182                                 downscaleToInteger0(r.getMinX()),
183                                 downscaleToInteger0(r.getMinY()),
184                                 downscaleToInteger0(r.getWidth()),
185                                 downscaleToInteger0(r.getHeight()));
186         }
187
188         // Upscaling
189
190         public static double upscale(double x) {
191                 initialize();
192                 return upscale0(x);
193         }
194
195         public static int upscale(int x) {
196                 initialize();
197                 return upscale0(x);
198         }
199
200         public static Point2D upscale(double x, double y) {
201                 initialize();
202                 if (!hasZoom)
203                         return new Point2D.Double(x, y);
204                 double s = upscaleFactorD;
205                 return new Point2D.Double(x * s, y * s);
206         }
207
208         public static Point upscale(int x, int y) {
209                 initialize();
210                 return new Point(upscale0(x), upscale0(y));
211         }
212
213         public static Point2D upscale(Point2D p) {
214                 initialize();
215                 return (hasZoom && p != null) ? upscale(p.getX(), p.getY()) : p;
216         }
217
218         public static Point upscaleToInteger(Point2D p) {
219                 initialize();
220                 return new Point(upscaleToInteger0(p.getX()), upscaleToInteger0(p.getY()));
221         }
222
223         public static Point upscale(Point p) {
224                 initialize();
225                 return (hasZoom && p != null) ? upscale(p.x, p.y) : p;
226         }
227
228         public static Rectangle2D upscale(Rectangle2D r, Rectangle2D target) {
229                 initialize();
230                 return scale(upscaleFactorD, r, target);
231         }
232
233         public static Rectangle upscale(Rectangle r, Rectangle target) {
234                 initialize();
235                 return scale(upscaleFactorF, r, target);
236         }
237
238         public static Rectangle2D upscale(Rectangle2D r) {
239                 return upscale(r, null);
240         }
241
242         public static Rectangle upscale(Rectangle r) {
243                 return upscale(r, null);
244         }
245
246         public static Rectangle upscaleToInteger(Rectangle2D r) {
247                 return new Rectangle( 
248                                 upscaleToInteger0(r.getMinX()),
249                                 upscaleToInteger0(r.getMinY()),
250                                 upscaleToInteger0(r.getWidth()),
251                                 upscaleToInteger0(r.getHeight()));
252         }
253
254 }