Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java
41152 views
1
/*
2
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.java2d;
27
28
import java.awt.AWTError;
29
import java.awt.Color;
30
import java.awt.Dimension;
31
import java.awt.Font;
32
import java.awt.Graphics2D;
33
import java.awt.GraphicsConfiguration;
34
import java.awt.GraphicsDevice;
35
import java.awt.GraphicsEnvironment;
36
import java.awt.Insets;
37
import java.awt.Point;
38
import java.awt.Rectangle;
39
import java.awt.Toolkit;
40
import java.awt.geom.AffineTransform;
41
import java.awt.image.BufferedImage;
42
import java.awt.peer.ComponentPeer;
43
import java.security.AccessController;
44
import java.util.Locale;
45
import java.util.TreeMap;
46
47
import sun.awt.DisplayChangedListener;
48
import sun.awt.SunDisplayChanger;
49
import sun.font.FontManager;
50
import sun.font.FontManagerFactory;
51
import sun.font.FontManagerForSGE;
52
import sun.java2d.pipe.Region;
53
import sun.security.action.GetPropertyAction;
54
55
/**
56
* This is an implementation of a GraphicsEnvironment object for the
57
* default local GraphicsEnvironment.
58
*
59
* @see GraphicsDevice
60
* @see GraphicsConfiguration
61
*/
62
@SuppressWarnings("removal")
63
public abstract class SunGraphicsEnvironment extends GraphicsEnvironment
64
implements DisplayChangedListener {
65
66
/** Establish the default font to be used by SG2D. */
67
private final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12);
68
69
private static final boolean uiScaleEnabled;
70
private static final double debugScale;
71
72
static {
73
uiScaleEnabled = "true".equals(AccessController.doPrivileged(
74
new GetPropertyAction("sun.java2d.uiScale.enabled", "true")));
75
debugScale = uiScaleEnabled ? getScaleFactor("sun.java2d.uiScale") : -1;
76
}
77
78
protected GraphicsDevice[] screens;
79
80
/**
81
* Returns an array of all of the screen devices.
82
*/
83
public synchronized GraphicsDevice[] getScreenDevices() {
84
GraphicsDevice[] ret = screens;
85
if (ret == null) {
86
int num = getNumScreens();
87
ret = new GraphicsDevice[num];
88
for (int i = 0; i < num; i++) {
89
ret[i] = makeScreenDevice(i);
90
}
91
screens = ret;
92
}
93
return ret;
94
}
95
96
/**
97
* Returns the number of screen devices of this graphics environment.
98
*
99
* @return the number of screen devices of this graphics environment
100
*/
101
protected abstract int getNumScreens();
102
103
/**
104
* Create and return the screen device with the specified number. The
105
* device with number {@code 0} will be the default device (returned
106
* by {@link #getDefaultScreenDevice()}.
107
*
108
* @param screennum the number of the screen to create
109
*
110
* @return the created screen device
111
*/
112
protected abstract GraphicsDevice makeScreenDevice(int screennum);
113
114
/**
115
* Returns the default screen graphics device.
116
*/
117
public GraphicsDevice getDefaultScreenDevice() {
118
GraphicsDevice[] screens = getScreenDevices();
119
if (screens.length == 0) {
120
throw new AWTError("no screen devices");
121
}
122
return screens[0];
123
}
124
125
/**
126
* Returns a Graphics2D object for rendering into the
127
* given BufferedImage.
128
* @throws NullPointerException if BufferedImage argument is null
129
*/
130
public Graphics2D createGraphics(BufferedImage img) {
131
if (img == null) {
132
throw new NullPointerException("BufferedImage cannot be null");
133
}
134
SurfaceData sd = SurfaceData.getPrimarySurfaceData(img);
135
return new SunGraphics2D(sd, Color.white, Color.black, defaultFont);
136
}
137
138
public static FontManagerForSGE getFontManagerForSGE() {
139
FontManager fm = FontManagerFactory.getInstance();
140
return (FontManagerForSGE) fm;
141
}
142
143
/* Modifies the behaviour of a subsequent call to preferLocaleFonts()
144
* to use Mincho instead of Gothic for dialoginput in JA locales
145
* on windows. Not needed on other platforms.
146
*
147
* @deprecated as of JDK9. To be removed in a future release
148
*/
149
@Deprecated
150
public static void useAlternateFontforJALocales() {
151
getFontManagerForSGE().useAlternateFontforJALocales();
152
}
153
154
/**
155
* Returns all fonts available in this environment.
156
*/
157
public Font[] getAllFonts() {
158
FontManagerForSGE fm = getFontManagerForSGE();
159
Font[] installedFonts = fm.getAllInstalledFonts();
160
Font[] created = fm.getCreatedFonts();
161
if (created == null || created.length == 0) {
162
return installedFonts;
163
} else {
164
int newlen = installedFonts.length + created.length;
165
Font [] fonts = java.util.Arrays.copyOf(installedFonts, newlen);
166
System.arraycopy(created, 0, fonts,
167
installedFonts.length, created.length);
168
return fonts;
169
}
170
}
171
172
public String[] getAvailableFontFamilyNames(Locale requestedLocale) {
173
FontManagerForSGE fm = getFontManagerForSGE();
174
String[] installed = fm.getInstalledFontFamilyNames(requestedLocale);
175
/* Use a new TreeMap as used in getInstalledFontFamilyNames
176
* and insert all the keys in lower case, so that the sort order
177
* is the same as the installed families. This preserves historical
178
* behaviour and inserts new families in the right place.
179
* It would have been marginally more efficient to directly obtain
180
* the tree map and just insert new entries, but not so much as
181
* to justify the extra internal interface.
182
*/
183
TreeMap<String, String> map = fm.getCreatedFontFamilyNames();
184
if (map == null || map.size() == 0) {
185
return installed;
186
} else {
187
for (int i=0; i<installed.length; i++) {
188
map.put(installed[i].toLowerCase(requestedLocale),
189
installed[i]);
190
}
191
String[] retval = new String[map.size()];
192
Object [] keyNames = map.keySet().toArray();
193
for (int i=0; i < keyNames.length; i++) {
194
retval[i] = map.get(keyNames[i]);
195
}
196
return retval;
197
}
198
}
199
200
public String[] getAvailableFontFamilyNames() {
201
return getAvailableFontFamilyNames(Locale.getDefault());
202
}
203
204
/**
205
* Return the bounds of a GraphicsDevice, less its screen insets.
206
* See also java.awt.GraphicsEnvironment.getUsableBounds();
207
*/
208
public static Rectangle getUsableBounds(GraphicsDevice gd) {
209
GraphicsConfiguration gc = gd.getDefaultConfiguration();
210
Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
211
Rectangle usableBounds = gc.getBounds();
212
213
usableBounds.x += insets.left;
214
usableBounds.y += insets.top;
215
usableBounds.width -= (insets.left + insets.right);
216
usableBounds.height -= (insets.top + insets.bottom);
217
218
return usableBounds;
219
}
220
221
/**
222
* From the DisplayChangedListener interface; called
223
* when the display mode has been changed.
224
*/
225
public void displayChanged() {
226
// notify screens in device array to do display update stuff
227
for (GraphicsDevice gd : getScreenDevices()) {
228
if (gd instanceof DisplayChangedListener) {
229
((DisplayChangedListener) gd).displayChanged();
230
}
231
}
232
233
// notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and
234
// SurfaceDataProxies) about the display change event
235
displayChanger.notifyListeners();
236
}
237
238
/**
239
* Part of the DisplayChangedListener interface:
240
* propagate this event to listeners
241
*/
242
public void paletteChanged() {
243
displayChanger.notifyPaletteChanged();
244
}
245
246
/**
247
* Returns true when the display is local, false for remote displays.
248
*
249
* @return true when the display is local, false for remote displays
250
*/
251
public abstract boolean isDisplayLocal();
252
253
/*
254
* ----DISPLAY CHANGE SUPPORT----
255
*/
256
257
protected SunDisplayChanger displayChanger = new SunDisplayChanger();
258
259
/**
260
* Add a DisplayChangeListener to be notified when the display settings
261
* are changed.
262
*/
263
public void addDisplayChangedListener(DisplayChangedListener client) {
264
displayChanger.add(client);
265
}
266
267
/**
268
* Remove a DisplayChangeListener from Win32GraphicsEnvironment
269
*/
270
public void removeDisplayChangedListener(DisplayChangedListener client) {
271
displayChanger.remove(client);
272
}
273
274
/*
275
* ----END DISPLAY CHANGE SUPPORT----
276
*/
277
278
/**
279
* Returns true if FlipBufferStrategy with COPIED buffer contents
280
* is preferred for this peer's GraphicsConfiguration over
281
* BlitBufferStrategy, false otherwise.
282
*
283
* The reason FlipBS could be preferred is that in some configurations
284
* an accelerated copy to the screen is supported (like Direct3D 9)
285
*
286
* @return true if flip strategy should be used, false otherwise
287
*/
288
public boolean isFlipStrategyPreferred(ComponentPeer peer) {
289
return false;
290
}
291
292
public static boolean isUIScaleEnabled() {
293
return uiScaleEnabled;
294
}
295
296
public static double getDebugScale() {
297
return debugScale;
298
}
299
300
public static double getScaleFactor(String propertyName) {
301
302
String scaleFactor = AccessController.doPrivileged(
303
new GetPropertyAction(propertyName, "-1"));
304
305
if (scaleFactor == null || scaleFactor.equals("-1")) {
306
return -1;
307
}
308
309
try {
310
double units = 1.0;
311
312
if (scaleFactor.endsWith("x")) {
313
scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 1);
314
} else if (scaleFactor.endsWith("dpi")) {
315
units = 96;
316
scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 3);
317
} else if (scaleFactor.endsWith("%")) {
318
units = 100;
319
scaleFactor = scaleFactor.substring(0, scaleFactor.length() - 1);
320
}
321
322
double scale = Double.parseDouble(scaleFactor);
323
return scale <= 0 ? -1 : scale / units;
324
} catch (NumberFormatException ignored) {
325
return -1;
326
}
327
}
328
329
/**
330
* Returns the graphics configuration which bounds contain the given point.
331
*
332
* @param current the default configuration which is checked in the first
333
* place
334
* @param x the x coordinate of the given point
335
* @param y the y coordinate of the given point
336
* @return the graphics configuration
337
*/
338
public static GraphicsConfiguration getGraphicsConfigurationAtPoint(
339
GraphicsConfiguration current, double x, double y) {
340
if (current.getBounds().contains(x, y)) {
341
return current;
342
}
343
GraphicsEnvironment env = getLocalGraphicsEnvironment();
344
for (GraphicsDevice device : env.getScreenDevices()) {
345
GraphicsConfiguration config = device.getDefaultConfiguration();
346
if (config.getBounds().contains(x, y)) {
347
return config;
348
}
349
}
350
return current;
351
}
352
353
/**
354
* Returns the bounds of the graphics configuration in device space.
355
*
356
* @param config the graphics configuration which bounds are requested
357
* @return the bounds of the area covered by this
358
* {@code GraphicsConfiguration} in device space (pixels)
359
*/
360
public static Rectangle getGCDeviceBounds(GraphicsConfiguration config) {
361
AffineTransform tx = config.getDefaultTransform();
362
Rectangle bounds = config.getBounds();
363
bounds.width *= tx.getScaleX();
364
bounds.height *= tx.getScaleY();
365
return bounds;
366
}
367
368
/**
369
* Converts the size (w, h) from the device space to the user's space using
370
* passed graphics configuration.
371
*
372
* @param gc the graphics configuration to be used for transformation
373
* @param w the width in the device space
374
* @param h the height in the device space
375
* @return the size in the user's space
376
*/
377
public static Dimension toUserSpace(GraphicsConfiguration gc,
378
int w, int h) {
379
AffineTransform tx = gc.getDefaultTransform();
380
return new Dimension(
381
Region.clipRound(w / tx.getScaleX()),
382
Region.clipRound(h / tx.getScaleY())
383
);
384
}
385
386
/**
387
* Converts absolute coordinates from the user's space to the device space
388
* using appropriate device transformation.
389
*
390
* @param x absolute coordinate in the user's space
391
* @param y absolute coordinate in the user's space
392
* @return the point which uses device space (pixels)
393
*/
394
public static Point toDeviceSpaceAbs(int x, int y) {
395
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
396
.getDefaultScreenDevice().getDefaultConfiguration();
397
gc = getGraphicsConfigurationAtPoint(gc, x, y);
398
return toDeviceSpaceAbs(gc, x, y, 0, 0).getLocation();
399
}
400
401
/**
402
* Converts the rectangle from the user's space to the device space using
403
* appropriate device transformation.
404
*
405
* @param rect the rectangle in the user's space
406
* @return the rectangle which uses device space (pixels)
407
*/
408
public static Rectangle toDeviceSpaceAbs(Rectangle rect) {
409
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
410
.getDefaultScreenDevice().getDefaultConfiguration();
411
gc = getGraphicsConfigurationAtPoint(gc, rect.x, rect.y);
412
return toDeviceSpaceAbs(gc, rect.x, rect.y, rect.width, rect.height);
413
}
414
415
/**
416
* Converts absolute coordinates (x, y) and the size (w, h) from the user's
417
* space to the device space using passed graphics configuration.
418
*
419
* @param gc the graphics configuration to be used for transformation
420
* @param x absolute coordinate in the user's space
421
* @param y absolute coordinate in the user's space
422
* @param w the width in the user's space
423
* @param h the height in the user's space
424
* @return the rectangle which uses device space (pixels)
425
*/
426
public static Rectangle toDeviceSpaceAbs(GraphicsConfiguration gc,
427
int x, int y, int w, int h) {
428
AffineTransform tx = gc.getDefaultTransform();
429
Rectangle screen = gc.getBounds();
430
return new Rectangle(
431
screen.x + Region.clipRound((x - screen.x) * tx.getScaleX()),
432
screen.y + Region.clipRound((y - screen.y) * tx.getScaleY()),
433
Region.clipRound(w * tx.getScaleX()),
434
Region.clipRound(h * tx.getScaleY())
435
);
436
}
437
438
/**
439
* Converts coordinates from the user's space to the device space using
440
* appropriate device transformation.
441
*
442
* @param x coordinate in the user's space
443
* @param y coordinate in the user's space
444
* @return the point which uses device space (pixels)
445
*/
446
public static Point toDeviceSpace(int x, int y) {
447
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
448
.getDefaultScreenDevice().getDefaultConfiguration();
449
gc = getGraphicsConfigurationAtPoint(gc, x, y);
450
return toDeviceSpace(gc, x, y, 0, 0).getLocation();
451
}
452
453
/**
454
* Converts coordinates (x, y) and the size (w, h) from the user's
455
* space to the device space using passed graphics configuration.
456
*
457
* @param gc the graphics configuration to be used for transformation
458
* @param x coordinate in the user's space
459
* @param y coordinate in the user's space
460
* @param w the width in the user's space
461
* @param h the height in the user's space
462
* @return the rectangle which uses device space (pixels)
463
*/
464
public static Rectangle toDeviceSpace(GraphicsConfiguration gc,
465
int x, int y, int w, int h) {
466
AffineTransform tx = gc.getDefaultTransform();
467
return new Rectangle(
468
Region.clipRound(x * tx.getScaleX()),
469
Region.clipRound(y * tx.getScaleY()),
470
Region.clipRound(w * tx.getScaleX()),
471
Region.clipRound(h * tx.getScaleY())
472
);
473
}
474
}
475
476