Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/demo/share/jfc/J2Ddemo/java2d/Surface.java
41154 views
1
/*
2
*
3
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
*
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
*
12
* - Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* - Neither the name of Oracle nor the names of its
17
* contributors may be used to endorse or promote products derived
18
* from this software without specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
package java2d;
33
34
35
import static java.awt.RenderingHints.KEY_ANTIALIASING;
36
import static java.awt.RenderingHints.KEY_RENDERING;
37
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF;
38
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON;
39
import static java.awt.RenderingHints.VALUE_RENDER_QUALITY;
40
import static java.awt.RenderingHints.VALUE_RENDER_SPEED;
41
import java.awt.AlphaComposite;
42
import java.awt.Color;
43
import java.awt.Dimension;
44
import java.awt.Font;
45
import java.awt.Frame;
46
import java.awt.GradientPaint;
47
import java.awt.Graphics;
48
import java.awt.Graphics2D;
49
import java.awt.Image;
50
import java.awt.Paint;
51
import java.awt.Toolkit;
52
import java.awt.event.WindowAdapter;
53
import java.awt.event.WindowEvent;
54
import java.awt.image.BufferedImage;
55
import java.awt.image.DataBuffer;
56
import java.awt.image.DataBufferByte;
57
import java.awt.image.DataBufferInt;
58
import java.awt.image.DataBufferUShort;
59
import java.awt.image.DirectColorModel;
60
import java.awt.image.IndexColorModel;
61
import java.awt.image.Raster;
62
import java.awt.image.WritableRaster;
63
import java.awt.print.PageFormat;
64
import java.awt.print.Printable;
65
import java.awt.print.PrinterException;
66
import java.util.logging.Level;
67
import java.util.logging.Logger;
68
import javax.swing.JPanel;
69
import javax.swing.RepaintManager;
70
71
72
/**
73
* Surface is the base class for the 2d rendering demos. Demos must
74
* implement the render() method. Subclasses for Surface are
75
* AnimatingSurface, ControlsSurface and AnimatingControlsSurface.
76
*/
77
@SuppressWarnings("serial")
78
public abstract class Surface extends JPanel implements Printable {
79
80
public Object AntiAlias = VALUE_ANTIALIAS_ON;
81
public Object Rendering = VALUE_RENDER_SPEED;
82
public AlphaComposite composite;
83
public Paint texture;
84
public String perfStr; // PerformanceMonitor
85
public BufferedImage bimg;
86
public int imageType;
87
public String name;
88
public boolean clearSurface = true;
89
// Demos using animated gif's that implement ImageObserver set dontThread.
90
public boolean dontThread;
91
public AnimatingSurface animating;
92
protected long sleepAmount = 50;
93
private long orig, start, frame;
94
private Toolkit toolkit;
95
private boolean perfMonitor, outputPerf;
96
private int biw, bih;
97
private boolean clearOnce;
98
private boolean toBeInitialized = true;
99
100
public Surface() {
101
setDoubleBuffered(this instanceof AnimatingSurface);
102
toolkit = getToolkit();
103
name = this.getClass().getSimpleName();
104
setImageType(0);
105
106
// To launch an individual demo with the performance str output :
107
// java -Dj2ddemo.perf= -cp J2Ddemo.jar demos.Clipping.ClipAnim
108
try {
109
if (System.getProperty("j2ddemo.perf") != null) {
110
perfMonitor = outputPerf = true;
111
}
112
} catch (Exception ex) {
113
}
114
if (this instanceof AnimatingSurface) {
115
animating = (AnimatingSurface) this;
116
}
117
}
118
119
protected Image getImage(String name) {
120
return DemoImages.getImage(name, this);
121
}
122
123
protected Font getFont(String name) {
124
return DemoFonts.getFont(name);
125
}
126
127
public int getImageType() {
128
return imageType;
129
}
130
131
public final void setImageType(int imgType) {
132
if (imgType == 0) {
133
imageType = 1;
134
} else {
135
imageType = imgType;
136
}
137
bimg = null;
138
}
139
140
public void setAntiAlias(boolean aa) {
141
AntiAlias = aa ? VALUE_ANTIALIAS_ON : VALUE_ANTIALIAS_OFF;
142
}
143
144
public void setRendering(boolean rd) {
145
Rendering = rd ? VALUE_RENDER_QUALITY : VALUE_RENDER_SPEED;
146
}
147
148
public void setTexture(Object obj) {
149
if (obj instanceof GradientPaint) {
150
texture = new GradientPaint(0, 0, Color.white,
151
getSize().width * 2, 0, Color.green);
152
} else {
153
texture = (Paint) obj;
154
}
155
}
156
157
public void setComposite(boolean cp) {
158
composite = cp
159
? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)
160
: null;
161
}
162
163
public void setMonitor(boolean pm) {
164
perfMonitor = pm;
165
}
166
167
public void setSleepAmount(long amount) {
168
sleepAmount = amount;
169
}
170
171
public long getSleepAmount() {
172
return sleepAmount;
173
}
174
175
public BufferedImage createBufferedImage(Graphics2D g2,
176
int w,
177
int h,
178
int imgType) {
179
BufferedImage bi = null;
180
if (imgType == 0) {
181
bi = g2.getDeviceConfiguration().
182
createCompatibleImage(w, h);
183
} else if (imgType > 0 && imgType < 14) {
184
bi = new BufferedImage(w, h, imgType);
185
} else if (imgType == 14) {
186
bi = createBinaryImage(w, h, 2);
187
} else if (imgType == 15) {
188
bi = createBinaryImage(w, h, 4);
189
} else if (imgType == 16) {
190
bi = createSGISurface(w, h, 32);
191
} else if (imgType == 17) {
192
bi = createSGISurface(w, h, 16);
193
}
194
return bi;
195
}
196
// Lookup tables for BYTE_BINARY 1, 2 and 4 bits.
197
private static final byte[] lut1Arr = new byte[] { 0, (byte) 255 };
198
private static final byte[] lut2Arr = new byte[] { 0, (byte) 85, (byte) 170, (byte) 255 };
199
private static final byte[] lut4Arr = new byte[] { 0, (byte) 17, (byte) 34, (byte) 51,
200
(byte) 68, (byte) 85, (byte) 102, (byte) 119,
201
(byte) 136, (byte) 153, (byte) 170, (byte) 187,
202
(byte) 204, (byte) 221, (byte) 238, (byte) 255 };
203
204
private BufferedImage createBinaryImage(int w, int h, int pixelBits) {
205
int bytesPerRow = w * pixelBits / 8;
206
if (w * pixelBits % 8 != 0) {
207
bytesPerRow++;
208
}
209
byte[] imageData = new byte[h * bytesPerRow];
210
IndexColorModel cm = null;
211
switch (pixelBits) {
212
case 1:
213
cm = new IndexColorModel(pixelBits, lut1Arr.length,
214
lut1Arr, lut1Arr, lut1Arr);
215
break;
216
case 2:
217
cm = new IndexColorModel(pixelBits, lut2Arr.length,
218
lut2Arr, lut2Arr, lut2Arr);
219
break;
220
case 4:
221
cm = new IndexColorModel(pixelBits, lut4Arr.length,
222
lut4Arr, lut4Arr, lut4Arr);
223
break;
224
default:
225
Logger.getLogger(Surface.class.getName()).log(Level.SEVERE,
226
null, new Exception("Invalid # of bit per pixel"));
227
}
228
229
DataBuffer db = new DataBufferByte(imageData, imageData.length);
230
WritableRaster r = Raster.createPackedRaster(db, w, h, pixelBits, null);
231
return new BufferedImage(cm, r, false, null);
232
}
233
234
private BufferedImage createSGISurface(int w, int h, int pixelBits) {
235
int rMask32 = 0xFF000000;
236
int rMask16 = 0xF800;
237
int gMask32 = 0x00FF0000;
238
int gMask16 = 0x07C0;
239
int bMask32 = 0x0000FF00;
240
int bMask16 = 0x003E;
241
242
DirectColorModel dcm = null;
243
DataBuffer db = null;
244
WritableRaster wr = null;
245
switch (pixelBits) {
246
case 16:
247
short[] imageDataUShort = new short[w * h];
248
dcm = new DirectColorModel(16, rMask16, gMask16, bMask16);
249
db = new DataBufferUShort(imageDataUShort,
250
imageDataUShort.length);
251
wr = Raster.createPackedRaster(db, w, h, w,
252
new int[] { rMask16, gMask16, bMask16 },
253
null);
254
break;
255
case 32:
256
int[] imageDataInt = new int[w * h];
257
dcm = new DirectColorModel(32, rMask32, gMask32, bMask32);
258
db = new DataBufferInt(imageDataInt, imageDataInt.length);
259
wr = Raster.createPackedRaster(db, w, h, w,
260
new int[] { rMask32, gMask32, bMask32 },
261
null);
262
break;
263
default:
264
Logger.getLogger(Surface.class.getName()).log(Level.SEVERE,
265
null, new Exception("Invalid # of bit per pixel"));
266
}
267
268
return new BufferedImage(dcm, wr, false, null);
269
}
270
271
public Graphics2D createGraphics2D(int width,
272
int height,
273
BufferedImage bi,
274
Graphics g) {
275
276
Graphics2D g2 = null;
277
278
if (bi != null) {
279
g2 = bi.createGraphics();
280
} else {
281
g2 = (Graphics2D) g;
282
}
283
284
g2.setBackground(getBackground());
285
g2.setRenderingHint(KEY_ANTIALIASING, AntiAlias);
286
g2.setRenderingHint(KEY_RENDERING, Rendering);
287
288
if (clearSurface || clearOnce) {
289
g2.clearRect(0, 0, width, height);
290
clearOnce = false;
291
}
292
293
if (texture != null) {
294
// set composite to opaque for texture fills
295
g2.setComposite(AlphaComposite.SrcOver);
296
g2.setPaint(texture);
297
g2.fillRect(0, 0, width, height);
298
}
299
300
if (composite != null) {
301
g2.setComposite(composite);
302
}
303
304
return g2;
305
}
306
307
// ...demos that extend Surface must implement this routine...
308
public abstract void render(int w, int h, Graphics2D g2);
309
310
/**
311
* It's possible to turn off double-buffering for just the repaint
312
* calls invoked directly on the non double buffered component.
313
* This can be done by overriding paintImmediately() (which is called
314
* as a result of repaint) and getting the current RepaintManager and
315
* turning off double buffering in the RepaintManager before calling
316
* super.paintImmediately(g).
317
*/
318
@Override
319
public void paintImmediately(int x, int y, int w, int h) {
320
RepaintManager repaintManager = null;
321
boolean save = true;
322
if (!isDoubleBuffered()) {
323
repaintManager = RepaintManager.currentManager(this);
324
save = repaintManager.isDoubleBufferingEnabled();
325
repaintManager.setDoubleBufferingEnabled(false);
326
}
327
super.paintImmediately(x, y, w, h);
328
329
if (repaintManager != null) {
330
repaintManager.setDoubleBufferingEnabled(save);
331
}
332
}
333
334
@Override
335
public void paint(Graphics g) {
336
337
super.paint(g);
338
339
Dimension d = getSize();
340
341
if (biw != d.width || bih != d.height) {
342
toBeInitialized = true;
343
biw = d.width;
344
bih = d.height;
345
}
346
347
if (imageType == 1) {
348
bimg = null;
349
} else if (bimg == null || toBeInitialized) {
350
bimg = createBufferedImage((Graphics2D) g,
351
d.width, d.height, imageType - 2);
352
clearOnce = true;
353
}
354
355
if (toBeInitialized) {
356
if (animating != null) {
357
animating.reset(d.width, d.height);
358
}
359
toBeInitialized = false;
360
startClock();
361
}
362
363
if (animating != null && animating.running()) {
364
animating.step(d.width, d.height);
365
}
366
Graphics2D g2 = createGraphics2D(d.width, d.height, bimg, g);
367
render(d.width, d.height, g2);
368
g2.dispose();
369
370
if (bimg != null) {
371
g.drawImage(bimg, 0, 0, null);
372
toolkit.sync();
373
}
374
375
if (perfMonitor) {
376
LogPerformance();
377
}
378
}
379
380
@Override
381
public int print(Graphics g, PageFormat pf, int pi) throws PrinterException {
382
if (pi >= 1) {
383
return Printable.NO_SUCH_PAGE;
384
}
385
386
Graphics2D g2d = (Graphics2D) g;
387
g2d.translate(pf.getImageableX(), pf.getImageableY());
388
g2d.translate(pf.getImageableWidth() / 2,
389
pf.getImageableHeight() / 2);
390
391
Dimension d = getSize();
392
393
double scale = Math.min(pf.getImageableWidth() / d.width,
394
pf.getImageableHeight() / d.height);
395
if (scale < 1.0) {
396
g2d.scale(scale, scale);
397
}
398
399
g2d.translate(-d.width / 2.0, -d.height / 2.0);
400
401
if (bimg == null) {
402
Graphics2D g2 = createGraphics2D(d.width, d.height, null, g2d);
403
render(d.width, d.height, g2);
404
g2.dispose();
405
} else {
406
g2d.drawImage(bimg, 0, 0, this);
407
}
408
409
return Printable.PAGE_EXISTS;
410
}
411
412
public void startClock() {
413
orig = System.currentTimeMillis();
414
start = orig;
415
frame = 0;
416
}
417
private static final int REPORTFRAMES = 30;
418
419
private void LogPerformance() {
420
if ((frame % REPORTFRAMES) == 0) {
421
long end = System.currentTimeMillis();
422
long rel = (end - start);
423
if (frame == 0) {
424
perfStr = name + " " + rel + " ms";
425
if (animating == null || !animating.running()) {
426
frame = -1;
427
}
428
} else {
429
String s1 = Float.toString((REPORTFRAMES / (rel / 1000.0f)));
430
s1 = (s1.length() < 4) ? s1.substring(0, s1.length()) : s1.
431
substring(0, 4);
432
perfStr = name + " " + s1 + " fps";
433
}
434
if (outputPerf) {
435
System.out.println(perfStr);
436
}
437
start = end;
438
}
439
++frame;
440
}
441
442
// System.out graphics state information.
443
public void verbose(GlobalControls controls) {
444
String str = " " + name + " ";
445
if (animating != null && animating.running()) {
446
str = str.concat(" Running");
447
} else if (this instanceof AnimatingSurface) {
448
str = str.concat(" Stopped");
449
}
450
451
if (controls != null) {
452
str = str.concat(" " + controls.screenCombo.getSelectedItem());
453
}
454
455
str.concat((AntiAlias == VALUE_ANTIALIAS_ON) ? " ANTIALIAS_ON "
456
: " ANTIALIAS_OFF ");
457
str.concat((Rendering == VALUE_RENDER_QUALITY) ? "RENDER_QUALITY "
458
: "RENDER_SPEED ");
459
460
if (texture != null) {
461
str = str.concat("Texture ");
462
}
463
464
if (composite != null) {
465
str = str.concat("Composite=" + composite.getAlpha() + " ");
466
}
467
468
Runtime r = Runtime.getRuntime();
469
r.gc();
470
float freeMemory = r.freeMemory();
471
float totalMemory = r.totalMemory();
472
str = str.concat(((totalMemory - freeMemory) / 1024) + "K used");
473
System.out.println(str);
474
}
475
476
public static void createDemoFrame(Surface surface) {
477
final DemoPanel dp = new DemoPanel(surface, new DemoInstVarsAccessorImplBase());
478
Frame f = new Frame("J2D Demo - " + surface.name);
479
f.addWindowListener(new WindowAdapter() {
480
481
@Override
482
public void windowClosing(WindowEvent e) {
483
System.exit(0);
484
}
485
486
@Override
487
public void windowDeiconified(WindowEvent e) {
488
dp.start();
489
}
490
491
@Override
492
public void windowIconified(WindowEvent e) {
493
dp.stop();
494
}
495
});
496
f.add("Center", dp);
497
f.pack();
498
f.setSize(new Dimension(500, 300));
499
f.setVisible(true);
500
if (surface.animating != null) {
501
surface.animating.start();
502
}
503
}
504
}
505
506