Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/demo/share/jfc/J2Ddemo/java2d/Intro.java
41155 views
1
/*
2
*
3
* Copyright (c) 2007, 2018, 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.Color.BLACK;
36
import static java.awt.Color.GRAY;
37
import static java.awt.Color.RED;
38
import static java.awt.Color.WHITE;
39
import static java.awt.Color.YELLOW;
40
import java.awt.AlphaComposite;
41
import java.awt.BorderLayout;
42
import java.awt.Color;
43
import java.awt.Composite;
44
import java.awt.Dimension;
45
import java.awt.Font;
46
import java.awt.FontMetrics;
47
import java.awt.GradientPaint;
48
import java.awt.Graphics;
49
import java.awt.Graphics2D;
50
import java.awt.Image;
51
import java.awt.Paint;
52
import java.awt.Point;
53
import java.awt.Rectangle;
54
import java.awt.RenderingHints;
55
import java.awt.Shape;
56
import java.awt.TexturePaint;
57
import java.awt.Toolkit;
58
import java.awt.event.ActionEvent;
59
import java.awt.event.ActionListener;
60
import java.awt.event.MouseAdapter;
61
import java.awt.event.MouseEvent;
62
import java.awt.event.WindowAdapter;
63
import java.awt.event.WindowEvent;
64
import java.awt.event.WindowListener;
65
import java.awt.font.FontRenderContext;
66
import java.awt.font.TextLayout;
67
import java.awt.geom.AffineTransform;
68
import java.awt.geom.Arc2D;
69
import java.awt.geom.Ellipse2D;
70
import java.awt.geom.FlatteningPathIterator;
71
import java.awt.geom.GeneralPath;
72
import java.awt.geom.Line2D;
73
import java.awt.geom.PathIterator;
74
import java.awt.geom.Point2D;
75
import java.awt.geom.Rectangle2D;
76
import java.awt.image.BufferedImage;
77
import java.util.ArrayList;
78
import java.util.Arrays;
79
import java.util.List;
80
import javax.swing.JButton;
81
import javax.swing.JFrame;
82
import javax.swing.JPanel;
83
import javax.swing.JScrollPane;
84
import javax.swing.JSlider;
85
import javax.swing.JTable;
86
import javax.swing.border.BevelBorder;
87
import javax.swing.border.CompoundBorder;
88
import javax.swing.border.EmptyBorder;
89
import javax.swing.border.EtchedBorder;
90
import javax.swing.border.TitledBorder;
91
import javax.swing.event.ChangeEvent;
92
import javax.swing.event.ChangeListener;
93
import javax.swing.event.TableModelEvent;
94
import javax.swing.table.AbstractTableModel;
95
import javax.swing.table.TableColumn;
96
import javax.swing.table.TableModel;
97
98
99
/**
100
* Introduction to the J2Ddemo.
101
*
102
* @author Brian Lichtenwalter
103
* @author Alexander Kouznetsov
104
*/
105
@SuppressWarnings("serial")
106
public class Intro extends JPanel {
107
108
private static final Color myBlack = new Color(20, 20, 20);
109
private static final Color myWhite = new Color(240, 240, 255);
110
private static final Color myRed = new Color(149, 43, 42);
111
private static final Color myBlue = new Color(94, 105, 176);
112
private static final Color myYellow = new Color(255, 255, 140);
113
private ScenesTable scenesTable;
114
private boolean doTable;
115
private final Surface surface;
116
117
public Intro() {
118
EmptyBorder eb = new EmptyBorder(80, 110, 80, 110);
119
BevelBorder bb = new BevelBorder(BevelBorder.LOWERED);
120
setBorder(new CompoundBorder(eb, bb));
121
setLayout(new BorderLayout());
122
setBackground(GRAY);
123
setToolTipText("click for scene table");
124
add(surface = new Surface());
125
addMouseListener(new MouseAdapter() {
126
127
@Override
128
public void mouseClicked(MouseEvent e) {
129
removeAll();
130
if ((doTable = !doTable)) {
131
setToolTipText("click for animation");
132
surface.stop();
133
if (scenesTable == null) {
134
scenesTable = new ScenesTable(Intro.this);
135
}
136
add(scenesTable);
137
} else {
138
setToolTipText("click for scene table");
139
surface.start();
140
add(surface);
141
}
142
revalidate();
143
repaint();
144
}
145
});
146
}
147
148
public void start() {
149
if (!doTable) {
150
surface.start();
151
}
152
}
153
154
public void stop() {
155
if (!doTable) {
156
surface.stop();
157
}
158
}
159
160
public static void main(String[] argv) {
161
final Intro intro = new Intro();
162
WindowListener l = new WindowAdapter() {
163
164
@Override
165
public void windowClosing(WindowEvent e) {
166
System.exit(0);
167
}
168
169
@Override
170
public void windowDeiconified(WindowEvent e) {
171
intro.start();
172
}
173
174
@Override
175
public void windowIconified(WindowEvent e) {
176
intro.stop();
177
}
178
};
179
JFrame f = new JFrame("Java2D(TM) Demo - Intro");
180
f.addWindowListener(l);
181
f.getContentPane().add("Center", intro);
182
f.pack();
183
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
184
int w = 720;
185
int h = 510;
186
f.setLocation(screenSize.width / 2 - w / 2, screenSize.height / 2 - h
187
/ 2);
188
f.setSize(w, h);
189
f.setVisible(true);
190
intro.start();
191
}
192
193
194
/**
195
* ScenesTable is the list of scenes known to the Director.
196
* Scene participation, scene name and scene pause amount columns.
197
* Global animation delay for scene's steps.
198
*/
199
static class ScenesTable extends JPanel implements ActionListener,
200
ChangeListener {
201
private final Intro intro;
202
private JTable table;
203
private TableModel dataModel;
204
205
@SuppressWarnings("LeakingThisInConstructor")
206
public ScenesTable(final Intro intro) {
207
this.intro = intro;
208
209
setBackground(WHITE);
210
setLayout(new BorderLayout());
211
final String[] names = { "", "Scenes", "Pause" };
212
213
dataModel = new AbstractTableModel() {
214
215
@Override
216
public int getColumnCount() {
217
return names.length;
218
}
219
220
@Override
221
public int getRowCount() {
222
return intro.surface.director.size();
223
}
224
225
@Override
226
public Object getValueAt(int row, int col) {
227
Surface.Scene scene = intro.surface.director.get(row);
228
if (col == 0) {
229
return scene.participate;
230
} else if (col == 1) {
231
return scene.name;
232
} else {
233
return scene.pauseAmt;
234
}
235
}
236
237
@Override
238
public String getColumnName(int col) {
239
return names[col];
240
}
241
242
@Override
243
public Class<?> getColumnClass(int c) {
244
return getValueAt(0, c).getClass();
245
}
246
247
@Override
248
public boolean isCellEditable(int row, int col) {
249
return col != 1 ? true : false;
250
}
251
252
@Override
253
public void setValueAt(Object aValue, int row, int col) {
254
Surface.Scene scene = intro.surface.director.get(row);
255
if (col == 0) {
256
scene.participate = aValue;
257
} else if (col == 1) {
258
scene.name = aValue;
259
} else {
260
scene.pauseAmt = aValue;
261
}
262
}
263
};
264
265
table = new JTable(dataModel);
266
TableColumn col = table.getColumn("");
267
col.setWidth(16);
268
col.setMinWidth(16);
269
col.setMaxWidth(20);
270
col = table.getColumn("Pause");
271
col.setWidth(60);
272
col.setMinWidth(60);
273
col.setMaxWidth(60);
274
table.sizeColumnsToFit(0);
275
276
JScrollPane scrollpane = new JScrollPane(table);
277
add(scrollpane);
278
279
JPanel panel = new JPanel(new BorderLayout());
280
JButton b = new JButton("Unselect All");
281
b.setHorizontalAlignment(JButton.LEFT);
282
Font font = new Font(Font.SERIF, Font.PLAIN, 10);
283
b.setFont(font);
284
b.addActionListener(this);
285
panel.add("West", b);
286
287
JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 200,
288
(int) intro.surface.sleepAmt);
289
slider.addChangeListener(this);
290
TitledBorder tb = new TitledBorder(new EtchedBorder());
291
tb.setTitleFont(font);
292
tb.setTitle("Anim delay = " + String.valueOf(intro.surface.sleepAmt)
293
+ " ms");
294
slider.setBorder(tb);
295
slider.setPreferredSize(new Dimension(140, 40));
296
slider.setMinimumSize(new Dimension(100, 40));
297
slider.setMaximumSize(new Dimension(180, 40));
298
panel.add("East", slider);
299
300
add("South", panel);
301
}
302
303
@Override
304
public void actionPerformed(ActionEvent e) {
305
JButton b = (JButton) e.getSource();
306
b.setSelected(!b.isSelected());
307
b.setText(b.isSelected() ? "Select All" : "Unselect All");
308
for (int i = 0; i < intro.surface.director.size(); i++) {
309
Surface.Scene scene = intro.surface.director.get(i);
310
scene.participate = Boolean.valueOf(!b.isSelected());
311
}
312
table.tableChanged(new TableModelEvent(dataModel));
313
}
314
315
@Override
316
public void stateChanged(ChangeEvent e) {
317
JSlider slider = (JSlider) e.getSource();
318
int value = slider.getValue();
319
TitledBorder tb = (TitledBorder) slider.getBorder();
320
tb.setTitle("Anim delay = " + String.valueOf(value) + " ms");
321
intro.surface.sleepAmt = (long) value;
322
slider.repaint();
323
}
324
} // End ScenesTable class
325
326
327
/**
328
* Surface is the stage where the Director plays its scenes.
329
*/
330
static class Surface extends JPanel implements Runnable {
331
332
private final Image dukeanim, duke;
333
private BufferedImage bimg;
334
public Director director;
335
public int index;
336
public long sleepAmt = 30;
337
private Thread thread;
338
339
@SuppressWarnings("LeakingThisInConstructor")
340
public Surface() {
341
setBackground(myBlack);
342
setLayout(new BorderLayout());
343
addMouseListener(new MouseAdapter() {
344
345
@Override
346
public void mouseClicked(MouseEvent e) {
347
if (thread == null) {
348
start();
349
} else {
350
stop();
351
}
352
}
353
});
354
dukeanim = DemoImages.getImage("duke.running.gif", this);
355
duke = DemoImages.getImage("duke.png", this);
356
director = new Director(this);
357
}
358
359
public FontMetrics getMetrics(Font font) {
360
return getFontMetrics(font);
361
}
362
363
@Override
364
public void paint(Graphics g) {
365
Dimension d = getSize();
366
if (d.width <= 0 || d.height <= 0) {
367
return;
368
}
369
if (bimg == null || bimg.getWidth() != d.width || bimg.getHeight()
370
!= d.height) {
371
bimg = getGraphicsConfiguration().createCompatibleImage(d.width,
372
d.height);
373
// reset future scenes
374
for (int i = index + 1; i < director.size(); i++) {
375
(director.get(i)).reset(d.width, d.height);
376
}
377
}
378
379
Scene scene = director.get(index);
380
if (scene.index <= scene.length) {
381
if (thread != null) {
382
scene.step(d.width, d.height);
383
}
384
385
Graphics2D g2 = bimg.createGraphics();
386
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
387
RenderingHints.VALUE_ANTIALIAS_ON);
388
g2.setBackground(getBackground());
389
g2.clearRect(0, 0, d.width, d.height);
390
391
scene.render(d.width, d.height, g2);
392
393
if (thread != null) {
394
// increment scene.index after scene.render
395
scene.index++;
396
}
397
g2.dispose();
398
}
399
g.drawImage(bimg, 0, 0, this);
400
}
401
402
public void start() {
403
if (thread == null) {
404
thread = new Thread(this);
405
thread.setPriority(Thread.MIN_PRIORITY);
406
thread.setName("Intro");
407
thread.start();
408
}
409
}
410
411
public synchronized void stop() {
412
if (thread != null) {
413
thread.interrupt();
414
}
415
thread = null;
416
notifyAll();
417
}
418
419
public void reset() {
420
index = 0;
421
Dimension d = getSize();
422
for (Scene scene : director) {
423
scene.reset(d.width, d.height);
424
}
425
}
426
427
@Override
428
@SuppressWarnings("SleepWhileHoldingLock")
429
public void run() {
430
431
Thread me = Thread.currentThread();
432
433
while (thread == me && !isShowing() || getSize().width <= 0) {
434
try {
435
Thread.sleep(500);
436
} catch (InterruptedException e) {
437
return;
438
}
439
}
440
441
if (index == 0) {
442
reset();
443
}
444
445
while (thread == me) {
446
Scene scene = director.get(index);
447
if (((Boolean) scene.participate).booleanValue()) {
448
repaint();
449
try {
450
Thread.sleep(sleepAmt);
451
} catch (InterruptedException e) {
452
break;
453
}
454
if (scene.index > scene.length) {
455
scene.pause();
456
if (++index >= director.size()) {
457
reset();
458
}
459
}
460
} else {
461
if (++index >= director.size()) {
462
reset();
463
}
464
}
465
}
466
thread = null;
467
}
468
469
470
/**
471
* Part is a piece of the scene. Classes must implement Part
472
* in order to participate in a scene.
473
*/
474
interface Part {
475
476
public void reset(int newwidth, int newheight);
477
478
public void step(int w, int h);
479
480
public void render(int w, int h, Graphics2D g2);
481
482
public int getBegin();
483
484
public int getEnd();
485
}
486
487
488
/**
489
* Director is the holder of the scenes, their names & pause amounts
490
* between scenes.
491
*/
492
static class Director extends ArrayList<Scene> {
493
494
GradientPaint gp = new GradientPaint(0, 40, myBlue, 38, 2, myBlack);
495
Font f1 = new Font(Font.SERIF, Font.PLAIN, 200);
496
Font f2 = new Font(Font.SERIF, Font.PLAIN, 120);
497
Font f3 = new Font(Font.SERIF, Font.PLAIN, 72);
498
499
public Director(Surface surf) {
500
Object[][][] partsInfo = {
501
{ { "J - scale text on gradient", "0" },
502
{ new GpE(GpE.BURI, myBlack, myBlue, 0, 20),
503
new TxE("J", f1, TxE.SCI, myYellow, 2, 20) } },
504
{ { "2 - scale & rotate text on gradient", "0" },
505
{ new GpE(GpE.BURI, myBlue, myBlack, 0, 22),
506
new TxE("2", f1, TxE.RI | TxE.SCI, myYellow, 2, 22) } },
507
{ { "D - scale text on gradient", "0" },
508
{ new GpE(GpE.BURI, myBlack, myBlue, 0, 20),
509
new TxE("D", f1, TxE.SCI, myYellow, 2, 20) } },
510
{ { "J2D demo - scale & rotate text on gradient", "1000" },
511
{ new GpE(GpE.SIH, myBlue, myBlack, 0, 40),
512
new TxE("J2D demo", f2, TxE.RI | TxE.SCI, myYellow, 0, 40) } },
513
{ { "Previous scene dither dissolve out", "0" },
514
{ new DdE(0, 20, 1, surf) } },
515
{ { "Graphics Features", "999" },
516
{ new Temp(Temp.RECT, null, 0, 15),
517
new Temp(Temp.IMG, surf.duke, 2, 15),
518
new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 130),
519
new Features(Features.GRAPHICS, 16, 130, surf) } },
520
{ { "J2D demo - texture text on gradient", "1000" },
521
{ new GpE(GpE.WI, myBlue, myBlack, 0, 20),
522
new GpE(GpE.WD, myBlue, myBlack, 21, 40),
523
new TpE(TpE.OI | TpE.NF, myBlack, myYellow, 4, 0, 10),
524
new TpE(TpE.OD | TpE.NF, myBlack, myYellow, 4, 11, 20),
525
new TpE(TpE.OI | TpE.NF | TpE.HAF, myBlack, myYellow, 5,
526
21, 40),
527
new TxE("J2D demo", f2, 0, null, 0, 40) } },
528
{ { "Previous scene random close out", "0" },
529
{ new CoE(CoE.RAND, 0, 20, surf) } },
530
{ { "Text Features", "999" },
531
{ new Temp(Temp.RECT, null, 0, 15),
532
new Temp(Temp.IMG, surf.duke, 2, 15),
533
new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 130),
534
new Features(Features.TEXT, 16, 130, surf) } },
535
{ { "J2D demo - composite text on texture", "1000" },
536
{ new TpE(TpE.RI, myBlack, gp, 40, 0, 20),
537
new TpE(TpE.RD, myBlack, gp, 40, 21, 40),
538
new TpE(TpE.RI, myBlack, gp, 40, 41, 60),
539
new TxE("J2D demo", f2, TxE.AC, myYellow, 0, 60) } },
540
{ { "Previous scene dither dissolve out", "0" },
541
{ new DdE(0, 20, 4, surf) } },
542
{ { "Imaging Features", "999" },
543
{ new Temp(Temp.RECT, null, 0, 15),
544
new Temp(Temp.IMG, surf.duke, 2, 15),
545
new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 130),
546
new Features(Features.IMAGES, 16, 130, surf) } },
547
{ { "J2D demo - text on gradient", "1000" },
548
{ new GpE(GpE.SDH, myBlue, myBlack, 0, 20),
549
new GpE(GpE.SIH, myBlue, myBlack, 21, 40),
550
new GpE(GpE.SDH, myBlue, myBlack, 41, 50),
551
new GpE(GpE.INC | GpE.NF, myRed, myYellow, 0, 50),
552
new TxE("J2D demo", f2, TxE.NOP, null, 0, 50) } },
553
{ { "Previous scene ellipse close out", "0" },
554
{ new CoE(CoE.OVAL, 0, 20, surf) } },
555
{ { "Color Features", "999" },
556
{ new Temp(Temp.RECT, null, 0, 15),
557
new Temp(Temp.IMG, surf.duke, 2, 15),
558
new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 99),
559
new Features(Features.COLOR, 16, 99, surf) } },
560
{ { "J2D demo - composite and rotate text on paints", "2000" },
561
{ new GpE(GpE.BURI, myBlack, myBlue, 0, 20),
562
new GpE(GpE.BURD, myBlack, myBlue, 21, 30),
563
new TpE(TpE.OI | TpE.HAF, myBlack, myBlue, 10, 31, 40),
564
new TxE("J2D demo", f2, TxE.AC | TxE.RI, myYellow, 0, 40) } },
565
{ { "Previous scene subimage transform out", "0" },
566
{ new SiE(60, 60, 0, 40, surf) } },
567
{ { "CREDITS - transform in", "1000" },
568
{ new LnE(LnE.ACI | LnE.ZOOMI | LnE.RI, 0, 60),
569
new TxE("CREDITS", f3, TxE.AC | TxE.SCI, RED, 20, 30),
570
new TxE("CREDITS", f3, TxE.SCXD, RED, 31, 38),
571
new TxE("CREDITS", f3, TxE.SCXI, RED, 39, 48),
572
new TxE("CREDITS", f3, TxE.SCXD, RED, 49, 54),
573
new TxE("CREDITS", f3, TxE.SCXI, RED, 55, 60) } },
574
{ { "CREDITS - transform out", "0" },
575
{ new LnE(LnE.ACD | LnE.ZOOMD | LnE.RD, 0, 45),
576
new TxE("CREDITS", f3, 0, RED, 0, 9),
577
new TxE("CREDITS", f3, TxE.SCD | TxE.RD, RED, 10, 30) } },
578
{ { "Contributors", "1000" },
579
{ new Temp(Temp.RECT, null, 0, 30),
580
new Temp(Temp.IMG, surf.dukeanim, 4, 30),
581
new Temp(Temp.RNA | Temp.INA, surf.dukeanim, 31, 200),
582
new Contributors(34, 200, surf) } }, };
583
584
for (Object[][] partInfo : partsInfo) {
585
List<Part> parts = new ArrayList<Part>();
586
for (Object part : partInfo[1]) {
587
parts.add((Part) part);
588
}
589
add(new Scene(parts, partInfo[0][0], partInfo[0][1]));
590
}
591
}
592
}
593
594
595
/**
596
* Scene is the manager of the parts.
597
*/
598
static class Scene extends Object {
599
600
public Object name;
601
public Object participate = Boolean.TRUE;
602
public Object pauseAmt;
603
public List<Part> parts;
604
public int index;
605
public int length;
606
607
public Scene(List<Part> parts, Object name, Object pauseAmt) {
608
this.name = name;
609
this.parts = parts;
610
this.pauseAmt = pauseAmt;
611
for (Part part : parts) {
612
int partLength = part.getEnd();
613
if (partLength > length) {
614
length = partLength;
615
}
616
}
617
}
618
619
public void reset(int w, int h) {
620
index = 0;
621
for (int i = 0; i < parts.size(); i++) {
622
(parts.get(i)).reset(w, h);
623
}
624
}
625
626
public void step(int w, int h) {
627
for (int i = 0; i < parts.size(); i++) {
628
Part part = parts.get(i);
629
if (index >= part.getBegin() && index <= part.getEnd()) {
630
part.step(w, h);
631
}
632
}
633
}
634
635
public void render(int w, int h, Graphics2D g2) {
636
for (int i = 0; i < parts.size(); i++) {
637
Part part = parts.get(i);
638
if (index >= part.getBegin() && index <= part.getEnd()) {
639
part.render(w, h, g2);
640
}
641
}
642
}
643
644
public void pause() {
645
try {
646
Thread.sleep(Long.parseLong((String) pauseAmt));
647
} catch (Exception ignored) {
648
}
649
System.gc();
650
}
651
} // End Scene class
652
653
654
/**
655
* Text Effect. Transformation of characters. Clip or fill.
656
*/
657
static final class TxE implements Part {
658
659
static final int INC = 1;
660
static final int DEC = 2;
661
static final int R = 4; // rotate
662
static final int RI = R | INC;
663
static final int RD = R | DEC;
664
static final int SC = 8; // scale
665
static final int SCI = SC | INC;
666
static final int SCD = SC | DEC;
667
static final int SCX = 16; // scale invert x
668
static final int SCXI = SCX | SC | INC;
669
static final int SCXD = SCX | SC | DEC;
670
static final int SCY = 32; // scale invert y
671
static final int SCYI = SCY | SC | INC;
672
static final int SCYD = SCY | SC | DEC;
673
static final int AC = 64; // AlphaComposite
674
static final int CLIP = 128; // Clipping
675
static final int NOP = 512; // No Paint
676
private int beginning, ending;
677
private int type;
678
private double rIncr, sIncr;
679
private double sx, sy, rotate;
680
private Shape[] shapes, txShapes;
681
private int sw;
682
private int numRev;
683
private Paint paint;
684
685
public TxE(String text,
686
Font font,
687
int type,
688
Paint paint,
689
int beg,
690
int end) {
691
this.type = type;
692
this.paint = paint;
693
this.beginning = beg;
694
this.ending = end;
695
696
setIncrements(2);
697
698
char[] chars = text.toCharArray();
699
shapes = new Shape[chars.length];
700
txShapes = new Shape[chars.length];
701
FontRenderContext frc = new FontRenderContext(null, true, true);
702
TextLayout tl = new TextLayout(text, font, frc);
703
sw = (int) tl.getOutline(null).getBounds().getWidth();
704
for (int j = 0; j < chars.length; j++) {
705
String s = String.valueOf(chars[j]);
706
shapes[j] = new TextLayout(s, font, frc).getOutline(null);
707
}
708
}
709
710
public void setIncrements(double numRevolutions) {
711
this.numRev = (int) numRevolutions;
712
rIncr = 360.0 / ((ending - beginning) / numRevolutions);
713
sIncr = 1.0 / (ending - beginning);
714
if ((type & SCX) != 0 || (type & SCY) != 0) {
715
sIncr *= 2;
716
}
717
if ((type & DEC) != 0) {
718
rIncr = -rIncr;
719
sIncr = -sIncr;
720
}
721
}
722
723
@Override
724
public void reset(int w, int h) {
725
if (type == SCXI) {
726
sx = -1.0;
727
sy = 1.0;
728
} else if (type == SCYI) {
729
sx = 1.0;
730
sy = -1.0;
731
} else {
732
sx = sy = (type & DEC) != 0 ? 1.0 : 0.0;
733
}
734
rotate = 0;
735
}
736
737
@Override
738
public void step(int w, int h) {
739
740
float charWidth = w / 2 - sw / 2;
741
742
for (int i = 0; i < shapes.length; i++) {
743
AffineTransform at = new AffineTransform();
744
Rectangle2D maxBounds = shapes[i].getBounds();
745
at.translate(charWidth, h / 2 + maxBounds.getHeight() / 2);
746
charWidth += (float) maxBounds.getWidth() + 1;
747
Shape shape = at.createTransformedShape(shapes[i]);
748
Rectangle2D b1 = shape.getBounds2D();
749
750
if ((type & R) != 0) {
751
at.rotate(Math.toRadians(rotate));
752
}
753
if ((type & SC) != 0) {
754
at.scale(sx, sy);
755
}
756
shape = at.createTransformedShape(shapes[i]);
757
Rectangle2D b2 = shape.getBounds2D();
758
759
double xx = (b1.getX() + b1.getWidth() / 2)
760
- (b2.getX() + b2.getWidth() / 2);
761
double yy = (b1.getY() + b1.getHeight() / 2)
762
- (b2.getY() + b2.getHeight() / 2);
763
AffineTransform toCenterAT = new AffineTransform();
764
toCenterAT.translate(xx, yy);
765
toCenterAT.concatenate(at);
766
txShapes[i] = toCenterAT.createTransformedShape(shapes[i]);
767
}
768
// avoid over rotation
769
if (Math.abs(rotate) <= numRev * 360) {
770
rotate += rIncr;
771
if ((type & SCX) != 0) {
772
sx += sIncr;
773
} else if ((type & SCY) != 0) {
774
sy += sIncr;
775
} else {
776
sx += sIncr;
777
sy += sIncr;
778
}
779
}
780
}
781
782
@Override
783
public void render(int w, int h, Graphics2D g2) {
784
Composite saveAC = null;
785
if ((type & AC) != 0 && sx > 0 && sx < 1) {
786
saveAC = g2.getComposite();
787
g2.setComposite(AlphaComposite.getInstance(
788
AlphaComposite.SRC_OVER, (float) sx));
789
}
790
GeneralPath path = null;
791
if ((type & CLIP) != 0) {
792
path = new GeneralPath();
793
}
794
if (paint != null) {
795
g2.setPaint(paint);
796
}
797
for (int i = 0; i < txShapes.length; i++) {
798
if ((type & CLIP) != 0) {
799
path.append(txShapes[i], false);
800
} else {
801
g2.fill(txShapes[i]);
802
}
803
}
804
if ((type & CLIP) != 0) {
805
g2.clip(path);
806
}
807
if (saveAC != null) {
808
g2.setComposite(saveAC);
809
}
810
}
811
812
@Override
813
public int getBegin() {
814
return beginning;
815
}
816
817
@Override
818
public int getEnd() {
819
return ending;
820
}
821
} // End TxE class
822
823
824
/**
825
* GradientPaint Effect. Burst, split, horizontal and
826
* vertical gradient fill effects.
827
*/
828
static class GpE implements Part {
829
830
static final int INC = 1; // increasing
831
static final int DEC = 2; // decreasing
832
static final int CNT = 4; // center
833
static final int WID = 8; // width
834
static final int WI = WID | INC;
835
static final int WD = WID | DEC;
836
static final int HEI = 16; // height
837
static final int HI = HEI | INC;
838
static final int HD = HEI | DEC;
839
static final int SPL = 32 | CNT; // split
840
static final int SIW = SPL | INC | WID;
841
static final int SDW = SPL | DEC | WID;
842
static final int SIH = SPL | INC | HEI;
843
static final int SDH = SPL | DEC | HEI;
844
static final int BUR = 64 | CNT; // burst
845
static final int BURI = BUR | INC;
846
static final int BURD = BUR | DEC;
847
static final int NF = 128; // no fill
848
private Color c1, c2;
849
private int beginning, ending;
850
private float incr, index;
851
private List<Rectangle2D> rect = new ArrayList<Rectangle2D>();
852
private List<GradientPaint> grad = new ArrayList<GradientPaint>();
853
private int type;
854
855
public GpE(int type, Color c1, Color c2, int beg, int end) {
856
this.type = type;
857
this.c1 = c1;
858
this.c2 = c2;
859
this.beginning = beg;
860
this.ending = end;
861
}
862
863
@Override
864
public void reset(int w, int h) {
865
incr = 1.0f / (ending - beginning);
866
if ((type & CNT) != 0) {
867
incr /= 2.3f;
868
}
869
if ((type & CNT) != 0 && (type & INC) != 0) {
870
index = 0.5f;
871
} else if ((type & DEC) != 0) {
872
index = 1.0f;
873
incr = -incr;
874
} else {
875
index = 0.0f;
876
}
877
index += incr;
878
}
879
880
@Override
881
public void step(int w, int h) {
882
rect.clear();
883
grad.clear();
884
885
if ((type & WID) != 0) {
886
float w2 = 0, x1 = 0, x2 = 0;
887
if ((type & SPL) != 0) {
888
w2 = w * 0.5f;
889
x1 = w * (1.0f - index);
890
x2 = w * index;
891
} else {
892
w2 = w * index;
893
x1 = x2 = w2;
894
}
895
rect.add(new Rectangle2D.Float(0, 0, w2, h));
896
rect.add(new Rectangle2D.Float(w2, 0, w - w2, h));
897
grad.add(new GradientPaint(0, 0, c1, x1, 0, c2));
898
grad.add(new GradientPaint(x2, 0, c2, w, 0, c1));
899
} else if ((type & HEI) != 0) {
900
float h2 = 0, y1 = 0, y2 = 0;
901
if ((type & SPL) != 0) {
902
h2 = h * 0.5f;
903
y1 = h * (1.0f - index);
904
y2 = h * index;
905
} else {
906
h2 = h * index;
907
y1 = y2 = h2;
908
}
909
rect.add(new Rectangle2D.Float(0, 0, w, h2));
910
rect.add(new Rectangle2D.Float(0, h2, w, h - h2));
911
grad.add(new GradientPaint(0, 0, c1, 0, y1, c2));
912
grad.add(new GradientPaint(0, y2, c2, 0, h, c1));
913
} else if ((type & BUR) != 0) {
914
915
float w2 = w / 2;
916
float h2 = h / 2;
917
918
rect.add(new Rectangle2D.Float(0, 0, w2, h2));
919
rect.add(new Rectangle2D.Float(w2, 0, w2, h2));
920
rect.add(new Rectangle2D.Float(0, h2, w2, h2));
921
rect.add(new Rectangle2D.Float(w2, h2, w2, h2));
922
923
float x1 = w * (1.0f - index);
924
float x2 = w * index;
925
float y1 = h * (1.0f - index);
926
float y2 = h * index;
927
928
grad.add(new GradientPaint(0, 0, c1, x1, y1, c2));
929
grad.add(new GradientPaint(w, 0, c1, x2, y1, c2));
930
grad.add(new GradientPaint(0, h, c1, x1, y2, c2));
931
grad.add(new GradientPaint(w, h, c1, x2, y2, c2));
932
} else if ((type & NF) != 0) {
933
float y = h * index;
934
grad.add(new GradientPaint(0, 0, c1, 0, y, c2));
935
}
936
937
if ((type & INC) != 0 || (type & DEC) != 0) {
938
index += incr;
939
}
940
}
941
942
@Override
943
public void render(int w, int h, Graphics2D g2) {
944
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
945
RenderingHints.VALUE_ANTIALIAS_OFF);
946
for (int i = 0; i < grad.size(); i++) {
947
g2.setPaint(grad.get(i));
948
if ((type & NF) == 0) {
949
g2.fill(rect.get(i));
950
}
951
}
952
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
953
RenderingHints.VALUE_ANTIALIAS_ON);
954
}
955
956
@Override
957
public int getBegin() {
958
return beginning;
959
}
960
961
@Override
962
public int getEnd() {
963
return ending;
964
}
965
} // End GpE class
966
967
968
/**
969
* TexturePaint Effect. Expand and collapse a texture.
970
*/
971
static final class TpE implements Part {
972
973
static final int INC = 1; // increasing
974
static final int DEC = 2; // decreasing
975
static final int OVAL = 4; // oval
976
static final int RECT = 8; // rectangle
977
static final int HAF = 16; // half oval or rect size
978
static final int NF = 32; // no fill
979
static final int OI = OVAL | INC;
980
static final int OD = OVAL | DEC;
981
static final int RI = RECT | INC;
982
static final int RD = RECT | DEC;
983
private Paint p1, p2;
984
private int beginning, ending;
985
private float incr, index;
986
private TexturePaint texture;
987
private int type;
988
private int size;
989
private BufferedImage bimg;
990
private Rectangle rect;
991
992
public TpE(int type, Paint p1, Paint p2, int size,
993
int beg, int end) {
994
this.type = type;
995
this.p1 = p1;
996
this.p2 = p2;
997
this.beginning = beg;
998
this.ending = end;
999
setTextureSize(size);
1000
}
1001
1002
public void setTextureSize(int size) {
1003
this.size = size;
1004
bimg = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
1005
rect = new Rectangle(0, 0, size, size);
1006
}
1007
1008
@Override
1009
public void reset(int w, int h) {
1010
incr = (float) (size) / (float) (ending - beginning);
1011
if ((type & HAF) != 0) {
1012
incr /= 2;
1013
}
1014
if ((type & DEC) != 0) {
1015
index = size;
1016
if ((type & HAF) != 0) {
1017
index /= 2;
1018
}
1019
incr = -incr;
1020
} else {
1021
index = 0.0f;
1022
}
1023
index += incr;
1024
}
1025
1026
@Override
1027
public void step(int w, int h) {
1028
Graphics2D g2 = bimg.createGraphics();
1029
g2.setPaint(p1);
1030
g2.fillRect(0, 0, size, size);
1031
g2.setPaint(p2);
1032
if ((type & OVAL) != 0) {
1033
g2.fill(new Ellipse2D.Float(0, 0, index, index));
1034
} else if ((type & RECT) != 0) {
1035
g2.fill(new Rectangle2D.Float(0, 0, index, index));
1036
}
1037
texture = new TexturePaint(bimg, rect);
1038
g2.dispose();
1039
index += incr;
1040
}
1041
1042
@Override
1043
public void render(int w, int h, Graphics2D g2) {
1044
g2.setPaint(texture);
1045
if ((type & NF) == 0) {
1046
g2.fillRect(0, 0, w, h);
1047
}
1048
}
1049
1050
@Override
1051
public int getBegin() {
1052
return beginning;
1053
}
1054
1055
@Override
1056
public int getEnd() {
1057
return ending;
1058
}
1059
} // End TpE class
1060
1061
1062
/**
1063
* Close out effect. Close out the buffered image with different
1064
* geometry shapes.
1065
*/
1066
static class CoE implements Part {
1067
private final Surface surf;
1068
static final int WID = 1;
1069
static final int HEI = 2;
1070
static final int OVAL = 4;
1071
static final int RECT = 8;
1072
static final int RAND = 16;
1073
static final int ARC = 32;
1074
private int type;
1075
private int beginning, ending;
1076
private BufferedImage bimg;
1077
private Shape shape;
1078
private double zoom, extent;
1079
private double zIncr, eIncr;
1080
private boolean doRandom;
1081
1082
public CoE(int type, int beg, int end, Surface surf) {
1083
this.type = type;
1084
this.beginning = beg;
1085
this.ending = end;
1086
this.surf = surf;
1087
zIncr = -(2.0 / (ending - beginning));
1088
eIncr = 360.0 / (ending - beginning);
1089
doRandom = (type & RAND) != 0;
1090
}
1091
1092
@Override
1093
public void reset(int w, int h) {
1094
if (doRandom) {
1095
int num = (int) (Math.random() * 5.0);
1096
switch (num) {
1097
case 0:
1098
type = OVAL;
1099
break;
1100
case 1:
1101
type = RECT;
1102
break;
1103
case 2:
1104
type = RECT | WID;
1105
break;
1106
case 3:
1107
type = RECT | HEI;
1108
break;
1109
case 4:
1110
type = ARC;
1111
break;
1112
default:
1113
type = OVAL;
1114
}
1115
}
1116
shape = null;
1117
bimg = null;
1118
extent = 360.0;
1119
zoom = 2.0;
1120
}
1121
1122
@Override
1123
public void step(int w, int h) {
1124
if (bimg == null) {
1125
int biw = surf.bimg.getWidth();
1126
int bih = surf.bimg.getHeight();
1127
bimg = new BufferedImage(biw, bih,
1128
BufferedImage.TYPE_INT_RGB);
1129
Graphics2D big = bimg.createGraphics();
1130
big.drawImage(surf.bimg, 0, 0, null);
1131
}
1132
double z = Math.min(w, h) * zoom;
1133
if ((type & OVAL) != 0) {
1134
shape = new Ellipse2D.Double(w / 2 - z / 2, h / 2 - z / 2, z,
1135
z);
1136
} else if ((type & ARC) != 0) {
1137
shape = new Arc2D.Double(-100, -100, w + 200, h + 200, 90,
1138
extent, Arc2D.PIE);
1139
extent -= eIncr;
1140
} else if ((type & RECT) != 0) {
1141
if ((type & WID) != 0) {
1142
shape = new Rectangle2D.Double(w / 2 - z / 2, 0, z, h);
1143
} else if ((type & HEI) != 0) {
1144
shape = new Rectangle2D.Double(0, h / 2 - z / 2, w, z);
1145
} else {
1146
shape = new Rectangle2D.Double(w / 2 - z / 2, h / 2 - z
1147
/ 2, z, z);
1148
}
1149
}
1150
zoom += zIncr;
1151
}
1152
1153
@Override
1154
public void render(int w, int h, Graphics2D g2) {
1155
g2.clip(shape);
1156
g2.drawImage(bimg, 0, 0, null);
1157
}
1158
1159
@Override
1160
public int getBegin() {
1161
return beginning;
1162
}
1163
1164
@Override
1165
public int getEnd() {
1166
return ending;
1167
}
1168
} // End CoE class
1169
1170
1171
/**
1172
* Dither Dissolve Effect. For each successive step in the animation,
1173
* a pseudo-random starting horizontal position is chosen using list,
1174
* and then the corresponding points created from xlist and ylist are
1175
* blacked out for the current "chunk". The x and y chunk starting
1176
* positions are each incremented by the associated chunk size, and
1177
* this process is repeated for the number of "steps" in the
1178
* animation, causing an equal number of pseudo-randomly picked
1179
* "blocks" to be blacked out during each step of the animation.
1180
*/
1181
static class DdE implements Part {
1182
private final Surface surf;
1183
private int beginning, ending;
1184
private BufferedImage bimg;
1185
private Graphics2D big;
1186
private List<Integer> list, xlist, ylist;
1187
private int xeNum, yeNum; // element number
1188
private int xcSize, ycSize; // chunk size
1189
private int inc;
1190
private int blocksize;
1191
1192
public DdE(int beg, int end, int blocksize, Surface surf) {
1193
this.beginning = beg;
1194
this.ending = end;
1195
this.blocksize = blocksize;
1196
this.surf = surf;
1197
}
1198
1199
private void createShuffledLists() {
1200
int width = bimg.getWidth();
1201
int height = bimg.getHeight();
1202
xlist = new ArrayList<Integer>(width);
1203
ylist = new ArrayList<Integer>(height);
1204
list = new ArrayList<Integer>(ending - beginning + 1);
1205
for (int i = 0; i < width; i++) {
1206
xlist.add(i, i);
1207
}
1208
for (int i = 0; i < height; i++) {
1209
ylist.add(i, i);
1210
}
1211
for (int i = 0; i < (ending - beginning + 1); i++) {
1212
list.add(i, i);
1213
}
1214
java.util.Collections.shuffle(xlist);
1215
java.util.Collections.shuffle(ylist);
1216
java.util.Collections.shuffle(list);
1217
}
1218
1219
@Override
1220
public void reset(int w, int h) {
1221
bimg = null;
1222
}
1223
1224
@Override
1225
public void step(int w, int h) {
1226
if (inc > ending) {
1227
bimg = null;
1228
}
1229
if (bimg == null) {
1230
int biw = surf.bimg.getWidth();
1231
int bih = surf.bimg.getHeight();
1232
bimg = new BufferedImage(biw, bih,
1233
BufferedImage.TYPE_INT_RGB);
1234
createShuffledLists();
1235
big = bimg.createGraphics();
1236
big.drawImage(surf.bimg, 0, 0, null);
1237
xcSize = (xlist.size() / (ending - beginning)) + 1;
1238
ycSize = (ylist.size() / (ending - beginning)) + 1;
1239
xeNum = 0;
1240
inc = 0;
1241
}
1242
xeNum = xcSize * (list.get(inc)).intValue();
1243
yeNum = -ycSize;
1244
inc++;
1245
}
1246
1247
@Override
1248
public void render(int w, int h, Graphics2D g2) {
1249
big.setColor(myBlack);
1250
1251
for (int k = 0; k <= (ending - beginning); k++) {
1252
if ((xeNum + xcSize) > xlist.size()) {
1253
xeNum = 0;
1254
} else {
1255
xeNum += xcSize;
1256
}
1257
yeNum += ycSize;
1258
1259
for (int i = xeNum; i < xeNum + xcSize && i < xlist.size();
1260
i++) {
1261
for (int j = yeNum; j < yeNum + ycSize && j
1262
< ylist.size(); j++) {
1263
int xval = (xlist.get(i)).intValue();
1264
int yval = (ylist.get(j)).intValue();
1265
if (((xval % blocksize) == 0) && ((yval % blocksize)
1266
== 0)) {
1267
big.fillRect(xval, yval, blocksize, blocksize);
1268
}
1269
}
1270
}
1271
}
1272
1273
g2.drawImage(bimg, 0, 0, null);
1274
}
1275
1276
@Override
1277
public int getBegin() {
1278
return beginning;
1279
}
1280
1281
@Override
1282
public int getEnd() {
1283
return ending;
1284
}
1285
} // End DdE class
1286
1287
1288
/**
1289
* Subimage effect. Subimage the scene's buffered
1290
* image then rotate and scale down the subimages.
1291
*/
1292
static class SiE implements Part {
1293
private final Surface surf;
1294
private int beginning, ending;
1295
private BufferedImage bimg;
1296
private double rIncr, sIncr;
1297
private double scale, rotate;
1298
private int siw, sih;
1299
private List<BufferedImage> subs = new ArrayList<BufferedImage>(20);
1300
private List<Point> pts = new ArrayList<Point>(20);
1301
1302
public SiE(int siw, int sih, int beg, int end, Surface surf) {
1303
this.siw = siw;
1304
this.sih = sih;
1305
this.beginning = beg;
1306
this.ending = end;
1307
this.surf = surf;
1308
rIncr = 360.0 / (ending - beginning);
1309
sIncr = 1.0 / (ending - beginning);
1310
}
1311
1312
@Override
1313
public void reset(int w, int h) {
1314
scale = 1.0;
1315
rotate = 0.0;
1316
bimg = null;
1317
subs.clear();
1318
pts.clear();
1319
}
1320
1321
@Override
1322
public void step(int w, int h) {
1323
if (bimg == null) {
1324
int biw = surf.bimg.getWidth();
1325
int bih = surf.bimg.getHeight();
1326
bimg = new BufferedImage(biw, bih,
1327
BufferedImage.TYPE_INT_RGB);
1328
Graphics2D big = bimg.createGraphics();
1329
big.drawImage(surf.bimg, 0, 0, null);
1330
for (int x = 0; x < w && scale > 0.0; x += siw) {
1331
int ww = x + siw < w ? siw : w - x;
1332
for (int y = 0; y < h; y += sih) {
1333
int hh = y + sih < h ? sih : h - y;
1334
subs.add(bimg.getSubimage(x, y, ww, hh));
1335
pts.add(new Point(x, y));
1336
}
1337
}
1338
}
1339
1340
rotate += rIncr;
1341
scale -= sIncr;
1342
}
1343
1344
@Override
1345
public void render(int w, int h, Graphics2D g2) {
1346
AffineTransform saveTx = g2.getTransform();
1347
g2.setColor(myBlue);
1348
for (int i = 0; i < subs.size() && scale > 0.0; i++) {
1349
BufferedImage bi = subs.get(i);
1350
Point p = pts.get(i);
1351
int ww = bi.getWidth();
1352
int hh = bi.getHeight();
1353
AffineTransform at = new AffineTransform();
1354
at.rotate(Math.toRadians(rotate), p.x + ww / 2, p.y + hh / 2);
1355
at.translate(p.x, p.y);
1356
at.scale(scale, scale);
1357
1358
Rectangle b1 = new Rectangle(0, 0, ww, hh);
1359
Shape shape = at.createTransformedShape(b1);
1360
Rectangle2D b2 = shape.getBounds2D();
1361
double xx = (p.x + ww / 2) - (b2.getX() + b2.getWidth() / 2);
1362
double yy = (p.y + hh / 2)
1363
- (b2.getY() + b2.getHeight() / 2);
1364
AffineTransform toCenterAT = new AffineTransform();
1365
toCenterAT.translate(xx, yy);
1366
toCenterAT.concatenate(at);
1367
1368
g2.setTransform(toCenterAT);
1369
g2.drawImage(bi, 0, 0, null);
1370
g2.draw(b1);
1371
}
1372
g2.setTransform(saveTx);
1373
}
1374
1375
@Override
1376
public int getBegin() {
1377
return beginning;
1378
}
1379
1380
@Override
1381
public int getEnd() {
1382
return ending;
1383
}
1384
} // End SiE class
1385
1386
1387
/**
1388
* Line Effect. Flattened ellipse with lines from the center
1389
* to the edge. Expand or collapse the ellipse. Fade in or out
1390
* the lines.
1391
*/
1392
static class LnE implements Part {
1393
1394
static final int INC = 1;
1395
static final int DEC = 2;
1396
static final int R = 4; // rotate
1397
static final int ZOOM = 8; // zoom
1398
static final int AC = 32; // AlphaComposite
1399
static final int RI = R | INC;
1400
static final int RD = R | DEC;
1401
static final int ZOOMI = ZOOM | INC;
1402
static final int ZOOMD = ZOOM | DEC;
1403
static final int ACI = AC | INC;
1404
static final int ACD = AC | DEC;
1405
private int beginning, ending;
1406
private double rIncr, rotate;
1407
private double zIncr, zoom;
1408
private List<Point2D.Double> pts = new ArrayList<Point2D.Double>();
1409
private float alpha, aIncr;
1410
private int type;
1411
1412
public LnE(int type, int beg, int end) {
1413
this.type = type;
1414
this.beginning = beg;
1415
this.ending = end;
1416
float range = ending - beginning;
1417
rIncr = 360.0f / range;
1418
aIncr = 0.9f / range;
1419
zIncr = 2.0f / range;
1420
if ((type & DEC) != 0) {
1421
rIncr = -rIncr;
1422
aIncr = -aIncr;
1423
zIncr = -zIncr;
1424
}
1425
}
1426
1427
public void generatePts(int w, int h, double sizeF) {
1428
pts.clear();
1429
double size = Math.min(w, h) * sizeF;
1430
Ellipse2D ellipse = new Ellipse2D.Double(w / 2 - size / 2, h / 2 - size
1431
/ 2, size, size);
1432
PathIterator pi = ellipse.getPathIterator(null, 0.8);
1433
while (!pi.isDone()) {
1434
double[] pt = new double[6];
1435
switch (pi.currentSegment(pt)) {
1436
case FlatteningPathIterator.SEG_MOVETO:
1437
case FlatteningPathIterator.SEG_LINETO:
1438
pts.add(new Point2D.Double(pt[0], pt[1]));
1439
}
1440
pi.next();
1441
}
1442
}
1443
1444
@Override
1445
public void reset(int w, int h) {
1446
if ((type & DEC) != 0) {
1447
rotate = 360;
1448
alpha = 1.0f;
1449
zoom = 2.0;
1450
} else {
1451
rotate = alpha = 0;
1452
zoom = 0;
1453
}
1454
if ((type & ZOOM) == 0) {
1455
generatePts(w, h, 0.5);
1456
}
1457
}
1458
1459
@Override
1460
public void step(int w, int h) {
1461
if ((type & ZOOM) != 0) {
1462
generatePts(w, h, zoom += zIncr);
1463
}
1464
if ((type & RI) != 0 || (type & RI) != 0) {
1465
rotate += rIncr;
1466
}
1467
if ((type & ACI) != 0 || (type & ACD) != 0) {
1468
alpha += aIncr;
1469
}
1470
}
1471
1472
@Override
1473
public void render(int w, int h, Graphics2D g2) {
1474
Composite saveAC = null;
1475
if ((type & AC) != 0 && alpha >= 0 && alpha <= 1) {
1476
saveAC = g2.getComposite();
1477
g2.setComposite(AlphaComposite.getInstance(
1478
AlphaComposite.SRC_OVER, alpha));
1479
}
1480
AffineTransform saveTx = null;
1481
if ((type & R) != 0) {
1482
saveTx = g2.getTransform();
1483
AffineTransform at = new AffineTransform();
1484
at.rotate(Math.toRadians(rotate), w / 2, h / 2);
1485
g2.setTransform(at);
1486
}
1487
Point2D p1 = new Point2D.Double(w / 2, h / 2);
1488
g2.setColor(YELLOW);
1489
for (Point2D pt : pts) {
1490
g2.draw(new Line2D.Float(p1, pt));
1491
}
1492
if (saveTx != null) {
1493
g2.setTransform(saveTx);
1494
}
1495
if (saveAC != null) {
1496
g2.setComposite(saveAC);
1497
}
1498
}
1499
1500
@Override
1501
public int getBegin() {
1502
return beginning;
1503
}
1504
1505
@Override
1506
public int getEnd() {
1507
return ending;
1508
}
1509
} // End LnE class
1510
1511
1512
/**
1513
* Template for Features & Contributors consisting of translating
1514
* blue and red rectangles and an image going from transparent to
1515
* opaque.
1516
*/
1517
static class Temp implements Part {
1518
1519
static final int NOANIM = 1;
1520
static final int RECT = 2;
1521
static final int IMG = 4;
1522
static final int RNA = RECT | NOANIM;
1523
static final int INA = IMG | NOANIM;
1524
private int beginning, ending;
1525
private float alpha, aIncr;
1526
private int type;
1527
private Rectangle rect1, rect2;
1528
private int x, y, xIncr, yIncr;
1529
private Image img;
1530
1531
public Temp(int type, Image img, int beg, int end) {
1532
this.type = type;
1533
this.img = img;
1534
this.beginning = beg;
1535
this.ending = end;
1536
aIncr = 0.9f / (ending - beginning);
1537
if ((type & NOANIM) != 0) {
1538
alpha = 1.0f;
1539
}
1540
}
1541
1542
@Override
1543
public void reset(int w, int h) {
1544
rect1 = new Rectangle(8, 20, w - 20, 30);
1545
rect2 = new Rectangle(20, 8, 30, h - 20);
1546
if ((type & NOANIM) == 0) {
1547
alpha = 0.0f;
1548
xIncr = w / (ending - beginning);
1549
yIncr = h / (ending - beginning);
1550
x = w + (int) (xIncr * 1.4);
1551
y = h + (int) (yIncr * 1.4);
1552
}
1553
}
1554
1555
@Override
1556
public void step(int w, int h) {
1557
if ((type & NOANIM) != 0) {
1558
return;
1559
}
1560
if ((type & RECT) != 0) {
1561
rect1.setLocation(x -= xIncr, 20);
1562
rect2.setLocation(20, y -= yIncr);
1563
}
1564
if ((type & IMG) != 0) {
1565
alpha += aIncr;
1566
}
1567
}
1568
1569
@Override
1570
public void render(int w, int h, Graphics2D g2) {
1571
if ((type & RECT) != 0) {
1572
g2.setColor(myBlue);
1573
g2.fill(rect1);
1574
g2.setColor(myRed);
1575
g2.fill(rect2);
1576
}
1577
if ((type & IMG) != 0) {
1578
Composite saveAC = g2.getComposite();
1579
if (alpha >= 0 && alpha <= 1) {
1580
g2.setComposite(AlphaComposite.getInstance(
1581
AlphaComposite.SRC_OVER, alpha));
1582
}
1583
g2.drawImage(img, 30, 30, null);
1584
g2.setComposite(saveAC);
1585
}
1586
}
1587
1588
@Override
1589
public int getBegin() {
1590
return beginning;
1591
}
1592
1593
@Override
1594
public int getEnd() {
1595
return ending;
1596
}
1597
} // End Temp class
1598
1599
1600
/**
1601
* Features of Java2D(TM). Single character advancement effect.
1602
*/
1603
static class Features implements Part {
1604
1605
static final int GRAPHICS = 0;
1606
static final int TEXT = 1;
1607
static final int IMAGES = 2;
1608
static final int COLOR = 3;
1609
static final Font font1 = new Font(Font.SERIF, Font.BOLD, 38);
1610
static final Font font2 = new Font(Font.SERIF, Font.PLAIN, 24);
1611
private final FontMetrics fm1;
1612
private final FontMetrics fm2;
1613
private static final String[][] table = { { "Graphics", "Antialiased rendering",
1614
"Bezier paths",
1615
"Transforms", "Compositing", "Stroking parameters" },
1616
{ "Text", "Extended font support",
1617
"Advanced text layout", "Dynamic font loading",
1618
"AttributeSets for font customization" },
1619
{ "Images", "Flexible image layouts",
1620
"Extended imaging operations",
1621
" Convolutions, Lookup Tables",
1622
"RenderableImage interface" },
1623
{ "Color", "ICC profile support", "Color conversion",
1624
"Arbitrary color spaces" } };
1625
private String[] list;
1626
private int beginning, ending;
1627
private int strH;
1628
private int endIndex, listIndex;
1629
private List<String> v = new ArrayList<String>();
1630
1631
public Features(int type, int beg, int end, Surface surf) {
1632
list = table[type];
1633
this.beginning = beg;
1634
this.ending = end;
1635
fm1 = surf.getMetrics(font1);
1636
fm2 = surf.getMetrics(font2);
1637
}
1638
1639
@Override
1640
public void reset(int w, int h) {
1641
strH = (fm2.getAscent() + fm2.getDescent());
1642
endIndex = 1;
1643
listIndex = 0;
1644
v.clear();
1645
v.add(list[listIndex].substring(0, endIndex));
1646
}
1647
1648
@Override
1649
public void step(int w, int h) {
1650
if (listIndex < list.length) {
1651
if (++endIndex > list[listIndex].length()) {
1652
if (++listIndex < list.length) {
1653
endIndex = 1;
1654
v.add(list[listIndex].substring(0, endIndex));
1655
}
1656
} else {
1657
v.set(listIndex, list[listIndex].substring(0, endIndex));
1658
}
1659
}
1660
}
1661
1662
@Override
1663
public void render(int w, int h, Graphics2D g2) {
1664
g2.setColor(myWhite);
1665
g2.setFont(font1);
1666
g2.drawString(v.get(0), 90, 85);
1667
g2.setFont(font2);
1668
for (int i = 1, y = 90; i < v.size(); i++) {
1669
g2.drawString(v.get(i), 120, y += strH);
1670
}
1671
}
1672
1673
@Override
1674
public int getBegin() {
1675
return beginning;
1676
}
1677
1678
@Override
1679
public int getEnd() {
1680
return ending;
1681
}
1682
} // End Features class
1683
1684
1685
/**
1686
* Scrolling text of Java2D(TM) contributors.
1687
*/
1688
static class Contributors implements Part {
1689
1690
private static final String[] members = {
1691
"Brian Lichtenwalter", "Jeannette Hung",
1692
"Thanh Nguyen", "Jim Graham", "Jerry Evans",
1693
"John Raley", "Michael Peirce", "Robert Kim",
1694
"Jennifer Ball", "Deborah Adair", "Paul Charlton",
1695
"Dmitry Feld", "Gregory Stone", "Richard Blanchard",
1696
"Link Perry", "Phil Race", "Vincent Hardy",
1697
"Parry Kejriwal", "Doug Felt", "Rekha Rangarajan",
1698
"Paula Patel", "Michael Bundschuh", "Joe Warzecha",
1699
"Joey Beheler", "Aastha Bhardwaj", "Daniel Rice",
1700
"Chris Campbell", "Shinsuke Fukuda", "Dmitri Trembovetski",
1701
"Chet Haase", "Jennifer Godinez", "Nicholas Talian",
1702
"Raul Vera", "Ankit Patel", "Ilya Bagrak",
1703
"Praveen Mohan", "Rakesh Menon"
1704
};
1705
private static final Font font = new Font(Font.SERIF, Font.PLAIN, 26);
1706
private final FontMetrics fm;
1707
private int beginning, ending;
1708
private int nStrs, strH, index, yh, height;
1709
private List<String> v = new ArrayList<String>();
1710
private List<String> cast =
1711
new ArrayList<String>(members.length + 3);
1712
private int counter, cntMod;
1713
private GradientPaint gp;
1714
1715
public Contributors(int beg, int end, Surface surf) {
1716
this.beginning = beg;
1717
this.ending = end;
1718
fm = surf.getMetrics(font);
1719
java.util.Arrays.sort(members);
1720
cast.add("CONTRIBUTORS");
1721
cast.add(" ");
1722
cast.addAll(Arrays.asList(members));
1723
cast.add(" ");
1724
cast.add(" ");
1725
cntMod = (ending - beginning) / cast.size() - 1;
1726
}
1727
1728
@Override
1729
public void reset(int w, int h) {
1730
v.clear();
1731
strH = (fm.getAscent() + fm.getDescent());
1732
nStrs = (h - 40) / strH + 1;
1733
height = strH * (nStrs - 1) + 48;
1734
index = 0;
1735
gp = new GradientPaint(0, h / 2, WHITE, 0, h + 20, BLACK);
1736
counter = 0;
1737
}
1738
1739
@Override
1740
public void step(int w, int h) {
1741
if (counter++ % cntMod == 0) {
1742
if (index < cast.size()) {
1743
v.add(cast.get(index));
1744
}
1745
if ((v.size() == nStrs || index >= cast.size()) && !v.
1746
isEmpty()) {
1747
v.remove(0);
1748
}
1749
++index;
1750
}
1751
}
1752
1753
@Override
1754
public void render(int w, int h, Graphics2D g2) {
1755
g2.setPaint(gp);
1756
g2.setFont(font);
1757
double remainder = counter % cntMod;
1758
double incr = 1.0 - remainder / cntMod;
1759
incr = incr == 1.0 ? 0 : incr;
1760
int y = (int) (incr * strH);
1761
1762
if (index >= cast.size()) {
1763
y = yh + y;
1764
} else {
1765
y = yh = height - v.size() * strH + y;
1766
}
1767
for (String s : v) {
1768
g2.drawString(s, w / 2 - fm.stringWidth(s) / 2, y += strH);
1769
}
1770
}
1771
1772
@Override
1773
public int getBegin() {
1774
return beginning;
1775
}
1776
1777
@Override
1778
public int getEnd() {
1779
return ending;
1780
}
1781
} // End Contributors class
1782
} // End Surface class
1783
} // End Intro class
1784
1785
1786