Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/print/PeekGraphics.java
41153 views
1
/*
2
* Copyright (c) 1998, 2018, 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.print;
27
28
import java.util.Map;
29
30
import java.awt.BasicStroke;
31
import java.awt.Color;
32
import java.awt.Composite;
33
import java.awt.Graphics;
34
import java.awt.Graphics2D;
35
import java.awt.Font;
36
import java.awt.FontMetrics;
37
import java.awt.font.FontRenderContext;
38
import java.awt.Graphics;
39
import java.awt.GraphicsConfiguration;
40
import java.awt.Image;
41
import java.awt.Paint;
42
import java.awt.Rectangle;
43
import java.awt.Shape;
44
import java.awt.Stroke;
45
import java.awt.RenderingHints;
46
import java.awt.RenderingHints.Key;
47
48
import java.awt.font.GlyphVector;
49
import java.awt.font.TextLayout;
50
51
import java.awt.geom.AffineTransform;
52
import java.awt.geom.Line2D;
53
import java.awt.geom.Point2D;
54
import java.awt.geom.Rectangle2D;
55
import java.awt.geom.RoundRectangle2D;
56
import java.awt.image.BufferedImage;
57
import java.awt.image.BufferedImageOp;
58
import java.awt.image.ImageObserver;
59
import java.awt.image.RenderedImage;
60
import java.awt.image.renderable.RenderableImage;
61
import java.awt.print.PrinterGraphics;
62
import java.awt.print.PrinterJob;
63
64
import java.text.AttributedCharacterIterator;
65
66
import sun.java2d.Spans;
67
68
public class PeekGraphics extends Graphics2D
69
implements PrinterGraphics,
70
ImageObserver,
71
Cloneable {
72
73
/**
74
* Drawing methods will be forwarded to this object.
75
*/
76
Graphics2D mGraphics;
77
78
/**
79
* The PrinterJob controlling the current printing.
80
*/
81
PrinterJob mPrinterJob;
82
83
/**
84
* Keeps track of where drawing occurs on the page.
85
*/
86
private Spans mDrawingArea = new Spans();
87
88
/**
89
* Track information about the types of drawing
90
* performed by the printing application.
91
*/
92
private PeekMetrics mPrintMetrics = new PeekMetrics();
93
94
/**
95
* If true the application will only be drawing AWT style
96
* graphics, no Java2D graphics.
97
*/
98
private boolean mAWTDrawingOnly = false;
99
100
/**
101
* The new PeekGraphics2D will forward state changing
102
* calls to 'graphics'. 'printerJob' is stored away
103
* so that the printing application can get the PrinterJob
104
* if needed.
105
*/
106
public PeekGraphics(Graphics2D graphics, PrinterJob printerJob) {
107
108
mGraphics = graphics;
109
mPrinterJob = printerJob;
110
}
111
112
/**
113
* Return the Graphics2D object that does the drawing
114
* for this instance.
115
*/
116
public Graphics2D getDelegate() {
117
return mGraphics;
118
}
119
120
/**
121
* Set the Graphics2D instance which will do the
122
* drawing.
123
*/
124
public void setDelegate(Graphics2D graphics) {
125
mGraphics = graphics;
126
}
127
128
public PrinterJob getPrinterJob() {
129
return mPrinterJob;
130
}
131
132
/**
133
* The caller promises that only AWT graphics will be drawn.
134
* The print system can use this information to make general
135
* assumptions about the types of graphics to be drawn without
136
* requiring the application to draw the contents multiple
137
* times.
138
*/
139
public void setAWTDrawingOnly() {
140
mAWTDrawingOnly = true;
141
}
142
143
public boolean getAWTDrawingOnly() {
144
return mAWTDrawingOnly;
145
}
146
147
/**
148
* Return a Spans instance describing the parts of the page in
149
* to which drawing occurred.
150
*/
151
public Spans getDrawingArea() {
152
return mDrawingArea;
153
}
154
155
/**
156
* Returns the device configuration associated with this Graphics2D.
157
*/
158
public GraphicsConfiguration getDeviceConfiguration() {
159
return ((RasterPrinterJob)mPrinterJob).getPrinterGraphicsConfig();
160
}
161
162
/* The Delegated Graphics Methods */
163
164
/**
165
* Creates a new {@code Graphics} object that is
166
* a copy of this {@code Graphics} object.
167
* @return a new graphics context that is a copy of
168
* this graphics context.
169
* @since 1.0
170
*/
171
public Graphics create() {
172
PeekGraphics newGraphics = null;
173
174
try {
175
newGraphics = (PeekGraphics) clone();
176
newGraphics.mGraphics = (Graphics2D) mGraphics.create();
177
178
/* This exception can not happen unless this
179
* class no longer implements the Cloneable
180
* interface.
181
*/
182
} catch (CloneNotSupportedException e) {
183
// can never happen.
184
}
185
186
return newGraphics;
187
}
188
189
/**
190
* Translates the origin of the graphics context to the point
191
* (<i>x</i>,&nbsp;<i>y</i>) in the current coordinate system.
192
* Modifies this graphics context so that its new origin corresponds
193
* to the point (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's
194
* original coordinate system. All coordinates used in subsequent
195
* rendering operations on this graphics context will be relative
196
* to this new origin.
197
* @param x the <i>x</i> coordinate.
198
* @param y the <i>y</i> coordinate.
199
* @since 1.0
200
*/
201
public void translate(int x, int y) {
202
mGraphics.translate(x, y);
203
}
204
205
/**
206
* Concatenates the current transform of this Graphics2D with a
207
* translation transformation.
208
* This is equivalent to calling transform(T), where T is an
209
* AffineTransform represented by the following matrix:
210
* <pre>
211
* [ 1 0 tx ]
212
* [ 0 1 ty ]
213
* [ 0 0 1 ]
214
* </pre>
215
*/
216
public void translate(double tx, double ty) {
217
mGraphics.translate(tx, ty);
218
}
219
220
/**
221
* Concatenates the current transform of this Graphics2D with a
222
* rotation transformation.
223
* This is equivalent to calling transform(R), where R is an
224
* AffineTransform represented by the following matrix:
225
* <pre>
226
* [ cos(theta) -sin(theta) 0 ]
227
* [ sin(theta) cos(theta) 0 ]
228
* [ 0 0 1 ]
229
* </pre>
230
* Rotating with a positive angle theta rotates points on the positive
231
* x axis toward the positive y axis.
232
* @param theta The angle of rotation in radians.
233
*/
234
public void rotate(double theta) {
235
mGraphics.rotate(theta);
236
}
237
238
/**
239
* Concatenates the current transform of this Graphics2D with a
240
* translated rotation transformation.
241
* This is equivalent to the following sequence of calls:
242
* <pre>
243
* translate(x, y);
244
* rotate(theta);
245
* translate(-x, -y);
246
* </pre>
247
* Rotating with a positive angle theta rotates points on the positive
248
* x axis toward the positive y axis.
249
* @param theta The angle of rotation in radians.
250
* @param x The x coordinate of the origin of the rotation
251
* @param y The x coordinate of the origin of the rotation
252
*/
253
public void rotate(double theta, double x, double y) {
254
mGraphics.rotate(theta, x, y);
255
}
256
257
/**
258
* Concatenates the current transform of this Graphics2D with a
259
* scaling transformation.
260
* This is equivalent to calling transform(S), where S is an
261
* AffineTransform represented by the following matrix:
262
* <pre>
263
* [ sx 0 0 ]
264
* [ 0 sy 0 ]
265
* [ 0 0 1 ]
266
* </pre>
267
*/
268
public void scale(double sx, double sy) {
269
mGraphics.scale(sx, sy);
270
}
271
272
/**
273
* Concatenates the current transform of this Graphics2D with a
274
* shearing transformation.
275
* This is equivalent to calling transform(SH), where SH is an
276
* AffineTransform represented by the following matrix:
277
* <pre>
278
* [ 1 shx 0 ]
279
* [ shy 1 0 ]
280
* [ 0 0 1 ]
281
* </pre>
282
* @param shx The factor by which coordinates are shifted towards the
283
* positive X axis direction according to their Y coordinate
284
* @param shy The factor by which coordinates are shifted towards the
285
* positive Y axis direction according to their X coordinate
286
*/
287
public void shear(double shx, double shy) {
288
mGraphics.shear(shx, shy);
289
}
290
291
/**
292
* Gets this graphics context's current color.
293
* @return this graphics context's current color.
294
* @see java.awt.Color
295
* @see java.awt.Graphics#setColor
296
* @since 1.0
297
*/
298
public Color getColor() {
299
return mGraphics.getColor();
300
}
301
302
/**
303
* Sets this graphics context's current color to the specified
304
* color. All subsequent graphics operations using this graphics
305
* context use this specified color.
306
* @param c the new rendering color.
307
* @see java.awt.Color
308
* @see java.awt.Graphics#getColor
309
* @since 1.0
310
*/
311
public void setColor(Color c) {
312
mGraphics.setColor(c);
313
}
314
315
/**
316
* Sets the paint mode of this graphics context to overwrite the
317
* destination with this graphics context's current color.
318
* This sets the logical pixel operation function to the paint or
319
* overwrite mode. All subsequent rendering operations will
320
* overwrite the destination with the current color.
321
* @since 1.0
322
*/
323
public void setPaintMode() {
324
mGraphics.setPaintMode();
325
}
326
327
/**
328
* Sets the paint mode of this graphics context to alternate between
329
* this graphics context's current color and the new specified color.
330
* This specifies that logical pixel operations are performed in the
331
* XOR mode, which alternates pixels between the current color and
332
* a specified XOR color.
333
* <p>
334
* When drawing operations are performed, pixels which are the
335
* current color are changed to the specified color, and vice versa.
336
* <p>
337
* Pixels that are of colors other than those two colors are changed
338
* in an unpredictable but reversible manner; if the same figure is
339
* drawn twice, then all pixels are restored to their original values.
340
* @param c1 the XOR alternation color
341
* @since 1.0
342
*/
343
public void setXORMode(Color c1) {
344
mGraphics.setXORMode(c1);
345
}
346
347
/**
348
* Gets the current font.
349
* @return this graphics context's current font.
350
* @see java.awt.Font
351
* @see java.awt.Graphics#setFont
352
* @since 1.0
353
*/
354
public Font getFont() {
355
return mGraphics.getFont();
356
}
357
358
/**
359
* Sets this graphics context's font to the specified font.
360
* All subsequent text operations using this graphics context
361
* use this font.
362
* @param font the font.
363
* @see java.awt.Graphics#getFont
364
* @see java.awt.Graphics#drawChars(char[], int, int, int, int)
365
* @see java.awt.Graphics#drawString(String, int, int)
366
* @see java.awt.Graphics#drawBytes(byte[], int, int, int, int)
367
* @since 1.0
368
*/
369
public void setFont(Font font) {
370
mGraphics.setFont(font);
371
}
372
373
/**
374
* Gets the font metrics for the specified font.
375
* @return the font metrics for the specified font.
376
* @param f the specified font
377
* @see java.awt.Graphics#getFont
378
* @see java.awt.FontMetrics
379
* @see java.awt.Graphics#getFontMetrics()
380
* @since 1.0
381
*/
382
public FontMetrics getFontMetrics(Font f) {
383
return mGraphics.getFontMetrics(f);
384
}
385
386
/**
387
* Get the rendering context of the font
388
* within this Graphics2D context.
389
*/
390
public FontRenderContext getFontRenderContext() {
391
return mGraphics.getFontRenderContext();
392
}
393
394
/**
395
* Returns the bounding rectangle of the current clipping area.
396
* The coordinates in the rectangle are relative to the coordinate
397
* system origin of this graphics context.
398
* @return the bounding rectangle of the current clipping area.
399
* @see java.awt.Graphics#getClip
400
* @see java.awt.Graphics#clipRect
401
* @see java.awt.Graphics#setClip(int, int, int, int)
402
* @see java.awt.Graphics#setClip(Shape)
403
* @since 1.1
404
*/
405
public Rectangle getClipBounds() {
406
return mGraphics.getClipBounds();
407
}
408
409
410
/**
411
* Intersects the current clip with the specified rectangle.
412
* The resulting clipping area is the intersection of the current
413
* clipping area and the specified rectangle.
414
* This method can only be used to make the current clip smaller.
415
* To set the current clip larger, use any of the setClip methods.
416
* Rendering operations have no effect outside of the clipping area.
417
* @param x the x coordinate of the rectangle to intersect the clip with
418
* @param y the y coordinate of the rectangle to intersect the clip with
419
* @param width the width of the rectangle to intersect the clip with
420
* @param height the height of the rectangle to intersect the clip with
421
* @see #setClip(int, int, int, int)
422
* @see #setClip(Shape)
423
*/
424
public void clipRect(int x, int y, int width, int height) {
425
mGraphics.clipRect(x, y, width, height);
426
}
427
428
429
/**
430
* Sets the current clip to the rectangle specified by the given
431
* coordinates.
432
* Rendering operations have no effect outside of the clipping area.
433
* @param x the <i>x</i> coordinate of the new clip rectangle.
434
* @param y the <i>y</i> coordinate of the new clip rectangle.
435
* @param width the width of the new clip rectangle.
436
* @param height the height of the new clip rectangle.
437
* @see java.awt.Graphics#clipRect
438
* @see java.awt.Graphics#setClip(Shape)
439
* @since 1.1
440
*/
441
public void setClip(int x, int y, int width, int height) {
442
mGraphics.setClip(x, y, width, height);
443
}
444
445
/**
446
* Gets the current clipping area.
447
* @return a {@code Shape} object representing the
448
* current clipping area.
449
* @see java.awt.Graphics#getClipBounds
450
* @see java.awt.Graphics#clipRect
451
* @see java.awt.Graphics#setClip(int, int, int, int)
452
* @see java.awt.Graphics#setClip(Shape)
453
* @since 1.1
454
*/
455
public Shape getClip() {
456
return mGraphics.getClip();
457
}
458
459
460
/**
461
* Sets the current clipping area to an arbitrary clip shape.
462
* Not all objects which implement the {@code Shape}
463
* interface can be used to set the clip. The only
464
* {@code Shape} objects which are guaranteed to be
465
* supported are {@code Shape} objects which are
466
* obtained via the {@code getClip} method and via
467
* {@code Rectangle} objects.
468
* @see java.awt.Graphics#getClip()
469
* @see java.awt.Graphics#clipRect
470
* @see java.awt.Graphics#setClip(int, int, int, int)
471
* @since 1.1
472
*/
473
public void setClip(Shape clip) {
474
mGraphics.setClip(clip);
475
}
476
477
478
/**
479
* Copies an area of the component by a distance specified by
480
* {@code dx} and {@code dy}. From the point specified
481
* by {@code x} and {@code y}, this method
482
* copies downwards and to the right. To copy an area of the
483
* component to the left or upwards, specify a negative value for
484
* {@code dx} or {@code dy}.
485
* If a portion of the source rectangle lies outside the bounds
486
* of the component, or is obscured by another window or component,
487
* {@code copyArea} will be unable to copy the associated
488
* pixels. The area that is omitted can be refreshed by calling
489
* the component's {@code paint} method.
490
* @param x the <i>x</i> coordinate of the source rectangle.
491
* @param y the <i>y</i> coordinate of the source rectangle.
492
* @param width the width of the source rectangle.
493
* @param height the height of the source rectangle.
494
* @param dx the horizontal distance to copy the pixels.
495
* @param dy the vertical distance to copy the pixels.
496
* @since 1.0
497
*/
498
public void copyArea(int x, int y, int width, int height,
499
int dx, int dy) {
500
// This method is not supported for printing so we do nothing here.
501
}
502
503
/**
504
* Draws a line, using the current color, between the points
505
* <code>(x1,&nbsp;y1)</code> and <code>(x2,&nbsp;y2)</code>
506
* in this graphics context's coordinate system.
507
* @param x1 the first point's <i>x</i> coordinate.
508
* @param y1 the first point's <i>y</i> coordinate.
509
* @param x2 the second point's <i>x</i> coordinate.
510
* @param y2 the second point's <i>y</i> coordinate.
511
* @since 1.0
512
*/
513
public void drawLine(int x1, int y1, int x2, int y2) {
514
addStrokeShape(new Line2D.Float(x1, y1, x2, y2));
515
mPrintMetrics.draw(this);
516
}
517
518
519
520
/**
521
* Fills the specified rectangle.
522
* The left and right edges of the rectangle are at
523
* {@code x} and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>.
524
* The top and bottom edges are at
525
* {@code y} and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
526
* The resulting rectangle covers an area
527
* {@code width} pixels wide by
528
* {@code height} pixels tall.
529
* The rectangle is filled using the graphics context's current color.
530
* @param x the <i>x</i> coordinate
531
* of the rectangle to be filled.
532
* @param y the <i>y</i> coordinate
533
* of the rectangle to be filled.
534
* @param width the width of the rectangle to be filled.
535
* @param height the height of the rectangle to be filled.
536
* @see java.awt.Graphics#fillRect
537
* @see java.awt.Graphics#clearRect
538
* @since 1.0
539
*/
540
public void fillRect(int x, int y, int width, int height) {
541
542
addDrawingRect(new Rectangle2D.Float(x, y, width, height));
543
mPrintMetrics.fill(this);
544
545
}
546
547
/**
548
* Clears the specified rectangle by filling it with the background
549
* color of the current drawing surface. This operation does not
550
* use the current paint mode.
551
* <p>
552
* Beginning with Java&nbsp;1.1, the background color
553
* of offscreen images may be system dependent. Applications should
554
* use {@code setColor} followed by {@code fillRect} to
555
* ensure that an offscreen image is cleared to a specific color.
556
* @param x the <i>x</i> coordinate of the rectangle to clear.
557
* @param y the <i>y</i> coordinate of the rectangle to clear.
558
* @param width the width of the rectangle to clear.
559
* @param height the height of the rectangle to clear.
560
* @see java.awt.Graphics#fillRect(int, int, int, int)
561
* @see java.awt.Graphics#drawRect
562
* @see java.awt.Graphics#setColor(java.awt.Color)
563
* @see java.awt.Graphics#setPaintMode
564
* @see java.awt.Graphics#setXORMode(java.awt.Color)
565
* @since 1.0
566
*/
567
public void clearRect(int x, int y, int width, int height) {
568
Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width, height);
569
addDrawingRect(rect);
570
mPrintMetrics.clear(this);
571
}
572
573
/**
574
* Draws an outlined round-cornered rectangle using this graphics
575
* context's current color. The left and right edges of the rectangle
576
* are at {@code x} and <code>x&nbsp;+&nbsp;width</code>,
577
* respectively. The top and bottom edges of the rectangle are at
578
* {@code y} and <code>y&nbsp;+&nbsp;height</code>.
579
* @param x the <i>x</i> coordinate of the rectangle to be drawn.
580
* @param y the <i>y</i> coordinate of the rectangle to be drawn.
581
* @param width the width of the rectangle to be drawn.
582
* @param height the height of the rectangle to be drawn.
583
* @param arcWidth the horizontal diameter of the arc
584
* at the four corners.
585
* @param arcHeight the vertical diameter of the arc
586
* at the four corners.
587
* @see java.awt.Graphics#fillRoundRect
588
* @since 1.0
589
*/
590
public void drawRoundRect(int x, int y, int width, int height,
591
int arcWidth, int arcHeight) {
592
addStrokeShape(new RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
593
mPrintMetrics.draw(this);
594
595
}
596
597
/**
598
* Fills the specified rounded corner rectangle with the current color.
599
* The left and right edges of the rectangle
600
* are at {@code x} and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>,
601
* respectively. The top and bottom edges of the rectangle are at
602
* {@code y} and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
603
* @param x the <i>x</i> coordinate of the rectangle to be filled.
604
* @param y the <i>y</i> coordinate of the rectangle to be filled.
605
* @param width the width of the rectangle to be filled.
606
* @param height the height of the rectangle to be filled.
607
* @param arcWidth the horizontal diameter
608
* of the arc at the four corners.
609
* @param arcHeight the vertical diameter
610
* of the arc at the four corners.
611
* @see java.awt.Graphics#drawRoundRect
612
* @since 1.0
613
*/
614
public void fillRoundRect(int x, int y, int width, int height,
615
int arcWidth, int arcHeight) {
616
Rectangle2D.Float rect = new Rectangle2D.Float(x, y,width, height);
617
addDrawingRect(rect);
618
mPrintMetrics.fill(this);
619
}
620
621
/**
622
* Draws the outline of an oval.
623
* The result is a circle or ellipse that fits within the
624
* rectangle specified by the {@code x}, {@code y},
625
* {@code width}, and {@code height} arguments.
626
* <p>
627
* The oval covers an area that is
628
* <code>width&nbsp;+&nbsp;1</code> pixels wide
629
* and <code>height&nbsp;+&nbsp;1</code> pixels tall.
630
* @param x the <i>x</i> coordinate of the upper left
631
* corner of the oval to be drawn.
632
* @param y the <i>y</i> coordinate of the upper left
633
* corner of the oval to be drawn.
634
* @param width the width of the oval to be drawn.
635
* @param height the height of the oval to be drawn.
636
* @see java.awt.Graphics#fillOval
637
* @since 1.0
638
*/
639
public void drawOval(int x, int y, int width, int height) {
640
addStrokeShape(new Rectangle2D.Float(x, y, width, height));
641
mPrintMetrics.draw(this);
642
}
643
644
/**
645
* Fills an oval bounded by the specified rectangle with the
646
* current color.
647
* @param x the <i>x</i> coordinate of the upper left corner
648
* of the oval to be filled.
649
* @param y the <i>y</i> coordinate of the upper left corner
650
* of the oval to be filled.
651
* @param width the width of the oval to be filled.
652
* @param height the height of the oval to be filled.
653
* @see java.awt.Graphics#drawOval
654
* @since 1.0
655
*/
656
public void fillOval(int x, int y, int width, int height) {
657
Rectangle2D.Float rect = new Rectangle2D.Float(x, y, width, height);
658
addDrawingRect(rect);
659
mPrintMetrics.fill(this);
660
661
}
662
663
664
/**
665
* Draws the outline of a circular or elliptical arc
666
* covering the specified rectangle.
667
* <p>
668
* The resulting arc begins at {@code startAngle} and extends
669
* for {@code arcAngle} degrees, using the current color.
670
* Angles are interpreted such that 0&nbsp;degrees
671
* is at the 3&nbsp;o'clock position.
672
* A positive value indicates a counter-clockwise rotation
673
* while a negative value indicates a clockwise rotation.
674
* <p>
675
* The center of the arc is the center of the rectangle whose origin
676
* is (<i>x</i>,&nbsp;<i>y</i>) and whose size is specified by the
677
* {@code width} and {@code height} arguments.
678
* <p>
679
* The resulting arc covers an area
680
* <code>width&nbsp;+&nbsp;1</code> pixels wide
681
* by <code>height&nbsp;+&nbsp;1</code> pixels tall.
682
* @param x the <i>x</i> coordinate of the
683
* upper-left corner of the arc to be drawn.
684
* @param y the <i>y</i> coordinate of the
685
* upper-left corner of the arc to be drawn.
686
* @param width the width of the arc to be drawn.
687
* @param height the height of the arc to be drawn.
688
* @param startAngle the beginning angle.
689
* @param arcAngle the angular extent of the arc,
690
* relative to the start angle.
691
* @see java.awt.Graphics#fillArc
692
* @since 1.0
693
*/
694
public void drawArc(int x, int y, int width, int height,
695
int startAngle, int arcAngle) {
696
addStrokeShape(new Rectangle2D.Float(x, y, width, height));
697
mPrintMetrics.draw(this);
698
699
}
700
701
/**
702
* Fills a circular or elliptical arc covering the specified rectangle.
703
* <p>
704
* The resulting arc begins at {@code startAngle} and extends
705
* for {@code arcAngle} degrees.
706
* Angles are interpreted such that 0&nbsp;degrees
707
* is at the 3&nbsp;o'clock position.
708
* A positive value indicates a counter-clockwise rotation
709
* while a negative value indicates a clockwise rotation.
710
* <p>
711
* The center of the arc is the center of the rectangle whose origin
712
* is (<i>x</i>,&nbsp;<i>y</i>) and whose size is specified by the
713
* {@code width} and {@code height} arguments.
714
* <p>
715
* The resulting arc covers an area
716
* <code>width&nbsp;+&nbsp;1</code> pixels wide
717
* by <code>height&nbsp;+&nbsp;1</code> pixels tall.
718
* @param x the <i>x</i> coordinate of the
719
* upper-left corner of the arc to be filled.
720
* @param y the <i>y</i> coordinate of the
721
* upper-left corner of the arc to be filled.
722
* @param width the width of the arc to be filled.
723
* @param height the height of the arc to be filled.
724
* @param startAngle the beginning angle.
725
* @param arcAngle the angular extent of the arc,
726
* relative to the start angle.
727
* @see java.awt.Graphics#drawArc
728
* @since 1.0
729
*/
730
public void fillArc(int x, int y, int width, int height,
731
int startAngle, int arcAngle) {
732
Rectangle2D.Float rect = new Rectangle2D.Float(x, y,width, height);
733
addDrawingRect(rect);
734
mPrintMetrics.fill(this);
735
736
}
737
738
/**
739
* Draws a sequence of connected lines defined by
740
* arrays of <i>x</i> and <i>y</i> coordinates.
741
* Each pair of (<i>x</i>,&nbsp;<i>y</i>) coordinates defines a point.
742
* The figure is not closed if the first point
743
* differs from the last point.
744
* @param xPoints an array of <i>x</i> points
745
* @param yPoints an array of <i>y</i> points
746
* @param nPoints the total number of points
747
* @see java.awt.Graphics#drawPolygon(int[], int[], int)
748
* @since 1.1
749
*/
750
public void drawPolyline(int[] xPoints, int[] yPoints,
751
int nPoints) {
752
if (nPoints > 0) {
753
int x = xPoints[0];
754
int y = yPoints[0];
755
756
for (int i = 1; i < nPoints; i++) {
757
drawLine(x, y, xPoints[i], yPoints[i]);
758
x = xPoints[i];
759
y = yPoints[i];
760
}
761
}
762
763
}
764
765
/**
766
* Draws a closed polygon defined by
767
* arrays of <i>x</i> and <i>y</i> coordinates.
768
* Each pair of (<i>x</i>,&nbsp;<i>y</i>) coordinates defines a point.
769
* <p>
770
* This method draws the polygon defined by {@code nPoint} line
771
* segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
772
* line segments are line segments from
773
* <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
774
* to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
775
* 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;{@code nPoints}.
776
* The figure is automatically closed by drawing a line connecting
777
* the final point to the first point, if those points are different.
778
* @param xPoints a an array of {@code x} coordinates.
779
* @param yPoints a an array of {@code y} coordinates.
780
* @param nPoints a the total number of points.
781
* @see java.awt.Graphics#fillPolygon
782
* @see java.awt.Graphics#drawPolyline
783
* @since 1.0
784
*/
785
public void drawPolygon(int[] xPoints, int[] yPoints,
786
int nPoints) {
787
if (nPoints > 0) {
788
drawPolyline(xPoints, yPoints, nPoints);
789
drawLine(xPoints[nPoints - 1], yPoints[nPoints - 1],
790
xPoints[0], yPoints[0]);
791
}
792
793
}
794
795
/**
796
* Fills a closed polygon defined by
797
* arrays of <i>x</i> and <i>y</i> coordinates.
798
* <p>
799
* This method draws the polygon defined by {@code nPoint} line
800
* segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
801
* line segments are line segments from
802
* <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
803
* to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
804
* 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;{@code nPoints}.
805
* The figure is automatically closed by drawing a line connecting
806
* the final point to the first point, if those points are different.
807
* <p>
808
* The area inside the polygon is defined using an
809
* even-odd fill rule, also known as the alternating rule.
810
* @param xPoints a an array of {@code x} coordinates.
811
* @param yPoints a an array of {@code y} coordinates.
812
* @param nPoints a the total number of points.
813
* @see java.awt.Graphics#drawPolygon(int[], int[], int)
814
* @since 1.0
815
*/
816
public void fillPolygon(int[] xPoints, int[] yPoints,
817
int nPoints) {
818
if (nPoints > 0) {
819
int minX = xPoints[0];
820
int minY = yPoints[0];
821
int maxX = xPoints[0];
822
int maxY = yPoints[0];
823
824
for (int i = 1; i < nPoints; i++) {
825
826
if (xPoints[i] < minX) {
827
minX = xPoints[i];
828
} else if (xPoints[i] > maxX) {
829
maxX = xPoints[i];
830
}
831
832
if (yPoints[i] < minY) {
833
minY = yPoints[i];
834
} else if (yPoints[i] > maxY) {
835
maxY = yPoints[i];
836
}
837
}
838
839
addDrawingRect(minX, minY, maxX - minX, maxY - minY);
840
}
841
842
mPrintMetrics.fill(this);
843
844
}
845
846
847
/**
848
* Draws the text given by the specified string, using this
849
* graphics context's current font and color. The baseline of the
850
* first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
851
* graphics context's coordinate system.
852
* @param str the string to be drawn.
853
* @param x the <i>x</i> coordinate.
854
* @param y the <i>y</i> coordinate.
855
* @see java.awt.Graphics#drawBytes
856
* @see java.awt.Graphics#drawChars
857
* @since 1.0
858
*/
859
public void drawString(String str, int x, int y) {
860
861
drawString(str, (float)x, (float)y);
862
}
863
864
/**
865
* Draws the text given by the specified iterator, using this
866
* graphics context's current color. The iterator has to specify a font
867
* for each character. The baseline of the
868
* first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
869
* graphics context's coordinate system.
870
* The rendering attributes applied include the clip, transform,
871
* paint or color, and composite attributes.
872
* For characters in script systems such as Hebrew and Arabic,
873
* the glyphs may be draw from right to left, in which case the
874
* coordinate supplied is the location of the leftmost character
875
* on the baseline.
876
* @param iterator the iterator whose text is to be drawn
877
* @param x,y the coordinates where the iterator's text should be drawn.
878
* @see #setPaint
879
* @see java.awt.Graphics#setColor
880
* @see #setTransform
881
* @see #setComposite
882
* @see #setClip
883
*/
884
public void drawString(AttributedCharacterIterator iterator,
885
int x, int y) {
886
887
drawString(iterator, (float)x, (float)y);
888
}
889
890
/**
891
* Draws the text given by the specified iterator, using this
892
* graphics context's current color. The iterator has to specify a font
893
* for each character. The baseline of the
894
* first character is at position (<i>x</i>,&nbsp;<i>y</i>) in this
895
* graphics context's coordinate system.
896
* The rendering attributes applied include the clip, transform,
897
* paint or color, and composite attributes.
898
* For characters in script systems such as Hebrew and Arabic,
899
* the glyphs may be draw from right to left, in which case the
900
* coordinate supplied is the location of the leftmost character
901
* on the baseline.
902
* @param iterator the iterator whose text is to be drawn
903
* @param x,y the coordinates where the iterator's text should be drawn.
904
* @see #setPaint
905
* @see java.awt.Graphics#setColor
906
* @see #setTransform
907
* @see #setComposite
908
* @see #setClip
909
*/
910
public void drawString(AttributedCharacterIterator iterator,
911
float x, float y) {
912
if (iterator == null) {
913
throw new
914
NullPointerException("AttributedCharacterIterator is null");
915
}
916
917
TextLayout layout = new TextLayout(iterator, getFontRenderContext());
918
layout.draw(this, x, y);
919
}
920
921
922
/**
923
* Draws as much of the specified image as is currently available.
924
* The image is drawn with its top-left corner at
925
* (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
926
* space. Transparent pixels in the image do not affect whatever
927
* pixels are already there.
928
* <p>
929
* This method returns immediately in all cases, even if the
930
* complete image has not yet been loaded, and it has not been dithered
931
* and converted for the current output device.
932
* <p>
933
* If the image has not yet been completely loaded, then
934
* {@code drawImage} returns {@code false}. As more of
935
* the image becomes available, the process that draws the image notifies
936
* the specified image observer.
937
* @param img the specified image to be drawn.
938
* @param x the <i>x</i> coordinate.
939
* @param y the <i>y</i> coordinate.
940
* @param observer object to be notified as more of
941
* the image is converted.
942
* @see java.awt.Image
943
* @see java.awt.image.ImageObserver
944
* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
945
* @since 1.0
946
*/
947
public boolean drawImage(Image img, int x, int y,
948
ImageObserver observer) {
949
950
if (img == null) {
951
return true;
952
}
953
954
/* The ImageWaiter creation does not return until the
955
* image is loaded.
956
*/
957
ImageWaiter dim = new ImageWaiter(img);
958
959
addDrawingRect(x, y, dim.getWidth(), dim.getHeight());
960
mPrintMetrics.drawImage(this, img);
961
962
return mGraphics.drawImage(img, x, y, observer);
963
}
964
965
966
/**
967
* Draws as much of the specified image as has already been scaled
968
* to fit inside the specified rectangle.
969
* <p>
970
* The image is drawn inside the specified rectangle of this
971
* graphics context's coordinate space, and is scaled if
972
* necessary. Transparent pixels do not affect whatever pixels
973
* are already there.
974
* <p>
975
* This method returns immediately in all cases, even if the
976
* entire image has not yet been scaled, dithered, and converted
977
* for the current output device.
978
* If the current output representation is not yet complete, then
979
* {@code drawImage} returns {@code false}. As more of
980
* the image becomes available, the process that draws the image notifies
981
* the image observer by calling its {@code imageUpdate} method.
982
* <p>
983
* A scaled version of an image will not necessarily be
984
* available immediately just because an unscaled version of the
985
* image has been constructed for this output device. Each size of
986
* the image may be cached separately and generated from the original
987
* data in a separate image production sequence.
988
* @param img the specified image to be drawn.
989
* @param x the <i>x</i> coordinate.
990
* @param y the <i>y</i> coordinate.
991
* @param width the width of the rectangle.
992
* @param height the height of the rectangle.
993
* @param observer object to be notified as more of
994
* the image is converted.
995
* @see java.awt.Image
996
* @see java.awt.image.ImageObserver
997
* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
998
* @since 1.0
999
*/
1000
public boolean drawImage(Image img, int x, int y,
1001
int width, int height,
1002
ImageObserver observer) {
1003
1004
if (img == null) {
1005
return true;
1006
}
1007
addDrawingRect(x, y, width, height);
1008
mPrintMetrics.drawImage(this, img);
1009
1010
return mGraphics.drawImage(img, x, y, width, height, observer);
1011
1012
}
1013
1014
/**
1015
* Draws as much of the specified image as is currently available.
1016
* The image is drawn with its top-left corner at
1017
* (<i>x</i>,&nbsp;<i>y</i>) in this graphics context's coordinate
1018
* space. Transparent pixels are drawn in the specified
1019
* background color.
1020
* <p>
1021
* This operation is equivalent to filling a rectangle of the
1022
* width and height of the specified image with the given color and then
1023
* drawing the image on top of it, but possibly more efficient.
1024
* <p>
1025
* This method returns immediately in all cases, even if the
1026
* complete image has not yet been loaded, and it has not been dithered
1027
* and converted for the current output device.
1028
* <p>
1029
* If the image has not yet been completely loaded, then
1030
* {@code drawImage} returns {@code false}. As more of
1031
* the image becomes available, the process that draws the image notifies
1032
* the specified image observer.
1033
* @param img the specified image to be drawn.
1034
* @param x the <i>x</i> coordinate.
1035
* @param y the <i>y</i> coordinate.
1036
* @param bgcolor the background color to paint under the
1037
* non-opaque portions of the image.
1038
* @param observer object to be notified as more of
1039
* the image is converted.
1040
* @see java.awt.Image
1041
* @see java.awt.image.ImageObserver
1042
* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1043
* @since 1.0
1044
*/
1045
public boolean drawImage(Image img, int x, int y,
1046
Color bgcolor,
1047
ImageObserver observer) {
1048
1049
if (img == null) {
1050
return true;
1051
}
1052
1053
/* The ImageWaiter creation does not return until the
1054
* image is loaded.
1055
*/
1056
ImageWaiter dim = new ImageWaiter(img);
1057
1058
addDrawingRect(x, y, dim.getWidth(), dim.getHeight());
1059
mPrintMetrics.drawImage(this, img);
1060
1061
return mGraphics.drawImage(img, x, y, bgcolor, observer);
1062
}
1063
1064
1065
/**
1066
* Draws as much of the specified image as has already been scaled
1067
* to fit inside the specified rectangle.
1068
* <p>
1069
* The image is drawn inside the specified rectangle of this
1070
* graphics context's coordinate space, and is scaled if
1071
* necessary. Transparent pixels are drawn in the specified
1072
* background color.
1073
* This operation is equivalent to filling a rectangle of the
1074
* width and height of the specified image with the given color and then
1075
* drawing the image on top of it, but possibly more efficient.
1076
* <p>
1077
* This method returns immediately in all cases, even if the
1078
* entire image has not yet been scaled, dithered, and converted
1079
* for the current output device.
1080
* If the current output representation is not yet complete then
1081
* {@code drawImage} returns {@code false}. As more of
1082
* the image becomes available, the process that draws the image notifies
1083
* the specified image observer.
1084
* <p>
1085
* A scaled version of an image will not necessarily be
1086
* available immediately just because an unscaled version of the
1087
* image has been constructed for this output device. Each size of
1088
* the image may be cached separately and generated from the original
1089
* data in a separate image production sequence.
1090
* @param img the specified image to be drawn.
1091
* @param x the <i>x</i> coordinate.
1092
* @param y the <i>y</i> coordinate.
1093
* @param width the width of the rectangle.
1094
* @param height the height of the rectangle.
1095
* @param bgcolor the background color to paint under the
1096
* non-opaque portions of the image.
1097
* @param observer object to be notified as more of
1098
* the image is converted.
1099
* @see java.awt.Image
1100
* @see java.awt.image.ImageObserver
1101
* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1102
* @since 1.0
1103
*/
1104
public boolean drawImage(Image img, int x, int y,
1105
int width, int height,
1106
Color bgcolor,
1107
ImageObserver observer) {
1108
1109
if (img == null) {
1110
return true;
1111
}
1112
1113
addDrawingRect(x, y, width, height);
1114
mPrintMetrics.drawImage(this, img);
1115
1116
return mGraphics.drawImage(img, x, y, width, height, bgcolor, observer);
1117
1118
}
1119
1120
/**
1121
* Draws as much of the specified area of the specified image as is
1122
* currently available, scaling it on the fly to fit inside the
1123
* specified area of the destination drawable surface. Transparent pixels
1124
* do not affect whatever pixels are already there.
1125
* <p>
1126
* This method returns immediately in all cases, even if the
1127
* image area to be drawn has not yet been scaled, dithered, and converted
1128
* for the current output device.
1129
* If the current output representation is not yet complete then
1130
* {@code drawImage} returns {@code false}. As more of
1131
* the image becomes available, the process that draws the image notifies
1132
* the specified image observer.
1133
* <p>
1134
* This method always uses the unscaled version of the image
1135
* to render the scaled rectangle and performs the required
1136
* scaling on the fly. It does not use a cached, scaled version
1137
* of the image for this operation. Scaling of the image from source
1138
* to destination is performed such that the first coordinate
1139
* of the source rectangle is mapped to the first coordinate of
1140
* the destination rectangle, and the second source coordinate is
1141
* mapped to the second destination coordinate. The subimage is
1142
* scaled and flipped as needed to preserve those mappings.
1143
* @param img the specified image to be drawn
1144
* @param dx1 the <i>x</i> coordinate of the first corner of the
1145
* destination rectangle.
1146
* @param dy1 the <i>y</i> coordinate of the first corner of the
1147
* destination rectangle.
1148
* @param dx2 the <i>x</i> coordinate of the second corner of the
1149
* destination rectangle.
1150
* @param dy2 the <i>y</i> coordinate of the second corner of the
1151
* destination rectangle.
1152
* @param sx1 the <i>x</i> coordinate of the first corner of the
1153
* source rectangle.
1154
* @param sy1 the <i>y</i> coordinate of the first corner of the
1155
* source rectangle.
1156
* @param sx2 the <i>x</i> coordinate of the second corner of the
1157
* source rectangle.
1158
* @param sy2 the <i>y</i> coordinate of the second corner of the
1159
* source rectangle.
1160
* @param observer object to be notified as more of the image is
1161
* scaled and converted.
1162
* @see java.awt.Image
1163
* @see java.awt.image.ImageObserver
1164
* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1165
* @since 1.1
1166
*/
1167
public boolean drawImage(Image img,
1168
int dx1, int dy1, int dx2, int dy2,
1169
int sx1, int sy1, int sx2, int sy2,
1170
ImageObserver observer) {
1171
1172
if (img == null) {
1173
return true;
1174
}
1175
1176
int width = dx2 - dx1;
1177
int height = dy2 - dy1;
1178
1179
addDrawingRect(dx1, dy1, width, height);
1180
mPrintMetrics.drawImage(this, img);
1181
1182
return mGraphics.drawImage(img, dx1, dy1, dx2, dy2,
1183
sx1, sy1, sx2, sy2, observer);
1184
1185
}
1186
1187
1188
/**
1189
* Draws as much of the specified area of the specified image as is
1190
* currently available, scaling it on the fly to fit inside the
1191
* specified area of the destination drawable surface.
1192
* <p>
1193
* Transparent pixels are drawn in the specified background color.
1194
* This operation is equivalent to filling a rectangle of the
1195
* width and height of the specified image with the given color and then
1196
* drawing the image on top of it, but possibly more efficient.
1197
* <p>
1198
* This method returns immediately in all cases, even if the
1199
* image area to be drawn has not yet been scaled, dithered, and converted
1200
* for the current output device.
1201
* If the current output representation is not yet complete then
1202
* {@code drawImage} returns {@code false}. As more of
1203
* the image becomes available, the process that draws the image notifies
1204
* the specified image observer.
1205
* <p>
1206
* This method always uses the unscaled version of the image
1207
* to render the scaled rectangle and performs the required
1208
* scaling on the fly. It does not use a cached, scaled version
1209
* of the image for this operation. Scaling of the image from source
1210
* to destination is performed such that the first coordinate
1211
* of the source rectangle is mapped to the first coordinate of
1212
* the destination rectangle, and the second source coordinate is
1213
* mapped to the second destination coordinate. The subimage is
1214
* scaled and flipped as needed to preserve those mappings.
1215
* @param img the specified image to be drawn
1216
* @param dx1 the <i>x</i> coordinate of the first corner of the
1217
* destination rectangle.
1218
* @param dy1 the <i>y</i> coordinate of the first corner of the
1219
* destination rectangle.
1220
* @param dx2 the <i>x</i> coordinate of the second corner of the
1221
* destination rectangle.
1222
* @param dy2 the <i>y</i> coordinate of the second corner of the
1223
* destination rectangle.
1224
* @param sx1 the <i>x</i> coordinate of the first corner of the
1225
* source rectangle.
1226
* @param sy1 the <i>y</i> coordinate of the first corner of the
1227
* source rectangle.
1228
* @param sx2 the <i>x</i> coordinate of the second corner of the
1229
* source rectangle.
1230
* @param sy2 the <i>y</i> coordinate of the second corner of the
1231
* source rectangle.
1232
* @param bgcolor the background color to paint under the
1233
* non-opaque portions of the image.
1234
* @param observer object to be notified as more of the image is
1235
* scaled and converted.
1236
* @see java.awt.Image
1237
* @see java.awt.image.ImageObserver
1238
* @see java.awt.image.ImageObserver#imageUpdate(java.awt.Image, int, int, int, int, int)
1239
* @since 1.1
1240
*/
1241
public boolean drawImage(Image img,
1242
int dx1, int dy1, int dx2, int dy2,
1243
int sx1, int sy1, int sx2, int sy2,
1244
Color bgcolor,
1245
ImageObserver observer) {
1246
1247
if (img == null) {
1248
return true;
1249
}
1250
1251
int width = dx2 - dx1;
1252
int height = dy2 - dy1;
1253
1254
addDrawingRect(dx1, dy1, width, height);
1255
mPrintMetrics.drawImage(this, img);
1256
1257
return mGraphics.drawImage(img, dx1, dy1, dx2, dy2,
1258
sx1, sy1, sx2, sy2, bgcolor, observer);
1259
1260
}
1261
1262
1263
/**
1264
* Draws an image, applying a transform from image space into user space
1265
* before drawing.
1266
* The transformation from user space into device space is done with
1267
* the current transform in the Graphics2D.
1268
* The given transformation is applied to the image before the
1269
* transform attribute in the Graphics2D state is applied.
1270
* The rendering attributes applied include the clip, transform,
1271
* and composite attributes. Note that the result is
1272
* undefined, if the given transform is noninvertible.
1273
* @param img The image to be drawn.
1274
* @param xform The transformation from image space into user space.
1275
* @see #transform
1276
* @see #setTransform
1277
* @see #setComposite
1278
* @see #clip
1279
* @see #setClip
1280
*/
1281
public void drawRenderedImage(RenderedImage img,
1282
AffineTransform xform) {
1283
1284
if (img == null) {
1285
return;
1286
}
1287
1288
mPrintMetrics.drawImage(this, img);
1289
mDrawingArea.addInfinite();
1290
}
1291
1292
1293
public void drawRenderableImage(RenderableImage img,
1294
AffineTransform xform) {
1295
1296
if (img == null) {
1297
return;
1298
}
1299
1300
mPrintMetrics.drawImage(this, img);
1301
mDrawingArea.addInfinite();
1302
}
1303
1304
/**
1305
* Disposes of this graphics context and releases
1306
* any system resources that it is using.
1307
* A {@code Graphics} object cannot be used after
1308
* {@code dispose} has been called.
1309
* <p>
1310
* When a Java program runs, a large number of {@code Graphics}
1311
* objects can be created within a short time frame.
1312
* Although the finalization process of the garbage collector
1313
* also disposes of the same system resources, it is preferable
1314
* to manually free the associated resources by calling this
1315
* method rather than to rely on a finalization process which
1316
* may not run to completion for a long period of time.
1317
* <p>
1318
* Graphics objects which are provided as arguments to the
1319
* {@code paint} and {@code update} methods
1320
* of components are automatically released by the system when
1321
* those methods return. For efficiency, programmers should
1322
* call {@code dispose} when finished using
1323
* a {@code Graphics} object only if it was created
1324
* directly from a component or another {@code Graphics} object.
1325
* @see java.awt.Graphics#finalize
1326
* @see java.awt.Component#paint
1327
* @see java.awt.Component#update
1328
* @see java.awt.Component#getGraphics
1329
* @see java.awt.Graphics#create
1330
* @since 1.0
1331
*/
1332
public void dispose() {
1333
mGraphics.dispose();
1334
}
1335
1336
/**
1337
* Empty finalizer as no clean up needed here.
1338
*/
1339
@SuppressWarnings("deprecation")
1340
public void finalize() {
1341
}
1342
1343
/* The Delegated Graphics2D Methods */
1344
1345
/**
1346
* Strokes the outline of a Shape using the settings of the current
1347
* graphics state. The rendering attributes applied include the
1348
* clip, transform, paint or color, composite and stroke attributes.
1349
* @param s The shape to be drawn.
1350
* @see #setStroke
1351
* @see #setPaint
1352
* @see java.awt.Graphics#setColor
1353
* @see #transform
1354
* @see #setTransform
1355
* @see #clip
1356
* @see #setClip
1357
* @see #setComposite
1358
*/
1359
public void draw(Shape s) {
1360
addStrokeShape(s);
1361
mPrintMetrics.draw(this);
1362
}
1363
1364
1365
/**
1366
* Draws an image, applying a transform from image space into user space
1367
* before drawing.
1368
* The transformation from user space into device space is done with
1369
* the current transform in the Graphics2D.
1370
* The given transformation is applied to the image before the
1371
* transform attribute in the Graphics2D state is applied.
1372
* The rendering attributes applied include the clip, transform,
1373
* and composite attributes. Note that the result is
1374
* undefined, if the given transform is noninvertible.
1375
* @param img The image to be drawn.
1376
* @param xform The transformation from image space into user space.
1377
* @param obs The image observer to be notified as more of the image
1378
* is converted.
1379
* @see #transform
1380
* @see #setTransform
1381
* @see #setComposite
1382
* @see #clip
1383
* @see #setClip
1384
*/
1385
public boolean drawImage(Image img,
1386
AffineTransform xform,
1387
ImageObserver obs) {
1388
1389
if (img == null) {
1390
return true;
1391
}
1392
1393
mDrawingArea.addInfinite();
1394
mPrintMetrics.drawImage(this, img);
1395
1396
return mGraphics.drawImage(img, xform, obs);
1397
1398
1399
// if (mDrawingArea[0] != null) {
1400
// Rectangle2D.Double bbox = new Rectangle2D.Double();
1401
// Point2D leftTop = new Point2D.Double(0, 0);
1402
// Point2D rightBottom = new Point2D.Double(getImageWidth(img),
1403
// getImageHeight(img));
1404
1405
// xform.transform(leftTop, leftTop);
1406
// xform.transform(rightBottom, rightBottom);
1407
1408
// bbox.setBoundsFromDiagonal(leftTop, rightBottom);
1409
// addDrawingRect(bbox);
1410
1411
// }
1412
}
1413
1414
1415
/**
1416
* Draws a BufferedImage that is filtered with a BufferedImageOp.
1417
* The rendering attributes applied include the clip, transform
1418
* and composite attributes. This is equivalent to:
1419
* <pre>
1420
* img1 = op.filter(img, null);
1421
* drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
1422
* </pre>
1423
* @param op The filter to be applied to the image before drawing.
1424
* @param img The BufferedImage to be drawn.
1425
* @param x,y The location in user space where the image should be drawn.
1426
* @see #transform
1427
* @see #setTransform
1428
* @see #setComposite
1429
* @see #clip
1430
* @see #setClip
1431
*/
1432
public void drawImage(BufferedImage img,
1433
BufferedImageOp op,
1434
int x,
1435
int y) {
1436
1437
if (img == null) {
1438
return;
1439
}
1440
1441
mPrintMetrics.drawImage(this, (RenderedImage) img);
1442
mDrawingArea.addInfinite();
1443
}
1444
1445
1446
/**
1447
* Draws a string of text.
1448
* The rendering attributes applied include the clip, transform,
1449
* paint or color, font and composite attributes.
1450
* @param str The string to be drawn.
1451
* @param x,y The coordinates where the string should be drawn.
1452
* @see #setPaint
1453
* @see java.awt.Graphics#setColor
1454
* @see java.awt.Graphics#setFont
1455
* @see #transform
1456
* @see #setTransform
1457
* @see #setComposite
1458
* @see #clip
1459
* @see #setClip
1460
*/
1461
public void drawString(String str,
1462
float x,
1463
float y) {
1464
1465
if (str.length() == 0) {
1466
return;
1467
}
1468
/* Logical bounds close enough and is used for GlyphVector */
1469
FontRenderContext frc = getFontRenderContext();
1470
Rectangle2D bbox = getFont().getStringBounds(str, frc);
1471
addDrawingRect(bbox, x, y);
1472
mPrintMetrics.drawText(this);
1473
}
1474
1475
/**
1476
* Draws a GlyphVector.
1477
* The rendering attributes applied include the clip, transform,
1478
* paint or color, and composite attributes. The GlyphVector specifies
1479
* individual glyphs from a Font.
1480
* @param g The GlyphVector to be drawn.
1481
* @param x,y The coordinates where the glyphs should be drawn.
1482
* @see #setPaint
1483
* @see java.awt.Graphics#setColor
1484
* @see #transform
1485
* @see #setTransform
1486
* @see #setComposite
1487
* @see #clip
1488
* @see #setClip
1489
*/
1490
public void drawGlyphVector(GlyphVector g,
1491
float x,
1492
float y) {
1493
1494
Rectangle2D bbox = g.getLogicalBounds();
1495
addDrawingRect(bbox, x, y);
1496
mPrintMetrics.drawText(this);
1497
1498
}
1499
1500
/**
1501
* Fills the interior of a Shape using the settings of the current
1502
* graphics state. The rendering attributes applied include the
1503
* clip, transform, paint or color, and composite.
1504
* @see #setPaint
1505
* @see java.awt.Graphics#setColor
1506
* @see #transform
1507
* @see #setTransform
1508
* @see #setComposite
1509
* @see #clip
1510
* @see #setClip
1511
*/
1512
public void fill(Shape s) {
1513
addDrawingRect(s.getBounds());
1514
mPrintMetrics.fill(this);
1515
1516
}
1517
1518
1519
/**
1520
* Checks to see if the outline of a Shape intersects the specified
1521
* Rectangle in device space.
1522
* The rendering attributes taken into account include the
1523
* clip, transform, and stroke attributes.
1524
* @param rect The area in device space to check for a hit.
1525
* @param s The shape to check for a hit.
1526
* @param onStroke Flag to choose between testing the stroked or
1527
* the filled shape.
1528
* @return True if there is a hit, false otherwise.
1529
* @see #setStroke
1530
* @see #fill
1531
* @see #draw
1532
* @see #transform
1533
* @see #setTransform
1534
* @see #clip
1535
* @see #setClip
1536
*/
1537
public boolean hit(Rectangle rect,
1538
Shape s,
1539
boolean onStroke) {
1540
1541
return mGraphics.hit(rect, s, onStroke);
1542
}
1543
1544
/**
1545
* Sets the Composite in the current graphics state. Composite is used
1546
* in all drawing methods such as drawImage, drawString, draw,
1547
* and fill. It specifies how new pixels are to be combined with
1548
* the existing pixels on the graphics device in the rendering process.
1549
* @param comp The Composite object to be used for drawing.
1550
* @see java.awt.Graphics#setXORMode
1551
* @see java.awt.Graphics#setPaintMode
1552
* @see java.awt.AlphaComposite
1553
*/
1554
public void setComposite(Composite comp) {
1555
mGraphics.setComposite(comp);
1556
}
1557
1558
1559
/**
1560
* Sets the Paint in the current graphics state.
1561
* @param paint The Paint object to be used to generate color in
1562
* the rendering process.
1563
* @see java.awt.Graphics#setColor
1564
* @see java.awt.GradientPaint
1565
* @see java.awt.TexturePaint
1566
*/
1567
public void setPaint(Paint paint) {
1568
mGraphics.setPaint(paint);
1569
}
1570
1571
/**
1572
* Sets the Stroke in the current graphics state.
1573
* @param s The Stroke object to be used to stroke a Shape in
1574
* the rendering process.
1575
* @see BasicStroke
1576
*/
1577
public void setStroke(Stroke s) {
1578
mGraphics.setStroke(s);
1579
}
1580
1581
/**
1582
* Sets the preferences for the rendering algorithms.
1583
* Hint categories include controls for rendering quality and
1584
* overall time/quality trade-off in the rendering process.
1585
* @param hintCategory The category of hint to be set.
1586
* @param hintValue The value indicating preferences for the specified
1587
* hint category.
1588
* @see RenderingHints
1589
*/
1590
public void setRenderingHint(Key hintCategory, Object hintValue) {
1591
mGraphics.setRenderingHint(hintCategory, hintValue);
1592
}
1593
1594
/**
1595
* Returns the preferences for the rendering algorithms.
1596
* @param hintCategory The category of hint to be set.
1597
* @return The preferences for rendering algorithms.
1598
* @see RenderingHints
1599
*/
1600
public Object getRenderingHint(Key hintCategory) {
1601
return mGraphics.getRenderingHint(hintCategory);
1602
}
1603
1604
/**
1605
* Sets the preferences for the rendering algorithms.
1606
* Hint categories include controls for rendering quality and
1607
* overall time/quality trade-off in the rendering process.
1608
* @param hints The rendering hints to be set
1609
* @see RenderingHints
1610
*/
1611
public void setRenderingHints(Map<?,?> hints) {
1612
mGraphics.setRenderingHints(hints);
1613
}
1614
1615
/**
1616
* Adds a number of preferences for the rendering algorithms.
1617
* Hint categories include controls for rendering quality and
1618
* overall time/quality trade-off in the rendering process.
1619
* @param hints The rendering hints to be set
1620
* @see RenderingHints
1621
*/
1622
public void addRenderingHints(Map<?,?> hints) {
1623
mGraphics.addRenderingHints(hints);
1624
}
1625
1626
/**
1627
* Gets the preferences for the rendering algorithms.
1628
* Hint categories include controls for rendering quality and
1629
* overall time/quality trade-off in the rendering process.
1630
* @see RenderingHints
1631
*/
1632
public RenderingHints getRenderingHints() {
1633
return mGraphics.getRenderingHints();
1634
}
1635
1636
/**
1637
* Composes a Transform object with the transform in this
1638
* Graphics2D according to the rule last-specified-first-applied.
1639
* If the currrent transform is Cx, the result of composition
1640
* with Tx is a new transform Cx'. Cx' becomes the current
1641
* transform for this Graphics2D.
1642
* Transforming a point p by the updated transform Cx' is
1643
* equivalent to first transforming p by Tx and then transforming
1644
* the result by the original transform Cx. In other words,
1645
* Cx'(p) = Cx(Tx(p)).
1646
* A copy of the Tx is made, if necessary, so further
1647
* modifications to Tx do not affect rendering.
1648
* @param Tx The Transform object to be composed with the current
1649
* transform.
1650
* @see #setTransform
1651
* @see AffineTransform
1652
*/
1653
public void transform(AffineTransform Tx) {
1654
mGraphics.transform(Tx);
1655
}
1656
1657
/**
1658
* Sets the Transform in the current graphics state.
1659
* @param Tx The Transform object to be used in the rendering process.
1660
* @see #transform
1661
* @see AffineTransform
1662
*/
1663
public void setTransform(AffineTransform Tx) {
1664
mGraphics.setTransform(Tx);
1665
}
1666
1667
/**
1668
* Returns the current Transform in the Graphics2D state.
1669
* @see #transform
1670
* @see #setTransform
1671
*/
1672
public AffineTransform getTransform() {
1673
return mGraphics.getTransform();
1674
}
1675
1676
/**
1677
* Returns the current Paint in the Graphics2D state.
1678
* @see #setPaint
1679
* @see java.awt.Graphics#setColor
1680
*/
1681
public Paint getPaint() {
1682
return mGraphics.getPaint();
1683
}
1684
1685
/**
1686
* Returns the current Composite in the Graphics2D state.
1687
* @see #setComposite
1688
*/
1689
public Composite getComposite() {
1690
return mGraphics.getComposite();
1691
}
1692
1693
/**
1694
* Sets the background color in this context used for clearing a region.
1695
* When Graphics2D is constructed for a component, the backgroung color is
1696
* inherited from the component. Setting the background color in the
1697
* Graphics2D context only affects the subsequent clearRect() calls and
1698
* not the background color of the component. To change the background
1699
* of the component, use appropriate methods of the component.
1700
* @param color The background color that should be used in
1701
* subsequent calls to clearRect().
1702
* @see #getBackground
1703
* @see Graphics#clearRect
1704
*/
1705
public void setBackground(Color color) {
1706
mGraphics.setBackground(color);
1707
}
1708
1709
/**
1710
* Returns the background color used for clearing a region.
1711
* @see #setBackground
1712
*/
1713
public Color getBackground() {
1714
return mGraphics.getBackground();
1715
}
1716
1717
/**
1718
* Returns the current Stroke in the Graphics2D state.
1719
* @see #setStroke
1720
*/
1721
public Stroke getStroke() {
1722
return mGraphics.getStroke();
1723
}
1724
1725
/**
1726
* Intersects the current clip with the interior of the specified Shape
1727
* and sets the current clip to the resulting intersection.
1728
* The indicated shape is transformed with the current transform in the
1729
* Graphics2D state before being intersected with the current clip.
1730
* This method is used to make the current clip smaller.
1731
* To make the clip larger, use any setClip method.
1732
* @param s The Shape to be intersected with the current clip.
1733
*/
1734
public void clip(Shape s) {
1735
mGraphics.clip(s);
1736
}
1737
1738
/**
1739
* Return true if the Rectangle {@code rect}
1740
* intersects the area into which the application
1741
* has drawn.
1742
*/
1743
public boolean hitsDrawingArea(Rectangle rect) {
1744
1745
return mDrawingArea.intersects((float) rect.getMinY(),
1746
(float) rect.getMaxY());
1747
}
1748
1749
/**
1750
* Return the object holding the summary of the
1751
* drawing done by the printing application.
1752
*/
1753
public PeekMetrics getMetrics() {
1754
return mPrintMetrics;
1755
}
1756
1757
/* Support Routines for Calculating the Drawing Area */
1758
1759
/**
1760
* Shift the rectangle 'rect' to the position ('x', 'y')
1761
* and add the resulting rectangle to the area representing
1762
* the part of the page which is drawn into.
1763
*/
1764
private void addDrawingRect(Rectangle2D rect, float x, float y) {
1765
1766
addDrawingRect((float) (rect.getX() + x),
1767
(float) (rect.getY() + y),
1768
(float) rect.getWidth(),
1769
(float) rect.getHeight());
1770
1771
}
1772
1773
private void addDrawingRect(float x, float y, float width, float height) {
1774
1775
Rectangle2D.Float bbox = new Rectangle2D.Float(x, y, width, height);
1776
addDrawingRect(bbox);
1777
}
1778
1779
/**
1780
* Add the rectangle 'rect' to the area representing
1781
* the part of the page which is drawn into.
1782
*/
1783
private void addDrawingRect(Rectangle2D rect) {
1784
1785
/* For testing purposes the following line can be uncommented.
1786
When uncommented it causes the entire page to be rasterized
1787
thus eliminating errors caused by a faulty bounding box
1788
calculation.
1789
*/
1790
//mDrawingArea.addInfinite();
1791
1792
1793
1794
AffineTransform matrix = getTransform();
1795
1796
Shape transShape = matrix.createTransformedShape(rect);
1797
1798
Rectangle2D transRect = transShape.getBounds2D();
1799
1800
mDrawingArea.add((float) transRect.getMinY(),
1801
(float) transRect.getMaxY());
1802
1803
1804
}
1805
1806
/**
1807
* Add the stroked shape to the area representing
1808
* the part of the page which is drawn into.
1809
*/
1810
private void addStrokeShape(Shape s) {
1811
Shape transShape = getStroke().createStrokedShape(s);
1812
addDrawingRect(transShape.getBounds2D());
1813
}
1814
1815
/* Image Observer */
1816
1817
/**
1818
* Notify this object when the height or width become available
1819
* for an image.
1820
*/
1821
public synchronized boolean imageUpdate(Image img, int infoFlags,
1822
int x, int y,
1823
int width, int height) {
1824
1825
boolean gotInfo = false;
1826
1827
if((infoFlags & (WIDTH | HEIGHT)) != 0) {
1828
gotInfo = true;
1829
notify();
1830
}
1831
1832
return gotInfo;
1833
}
1834
1835
private synchronized int getImageWidth(Image img) {
1836
1837
/* Wait for the width the image to
1838
* become available.
1839
*/
1840
while (img.getWidth(this) == -1) {
1841
try {
1842
wait();
1843
} catch (InterruptedException e) {
1844
}
1845
}
1846
1847
1848
return img.getWidth(this);
1849
}
1850
1851
private synchronized int getImageHeight(Image img) {
1852
1853
/* Wait for the height the image to
1854
* become available.
1855
*/
1856
while (img.getHeight(this) == -1) {
1857
try {
1858
wait();
1859
} catch (InterruptedException e) {
1860
}
1861
}
1862
1863
1864
return img.getHeight(this);
1865
}
1866
1867
/**
1868
* This private class does not return from its constructor
1869
* until 'img's width and height are available.
1870
*/
1871
protected class ImageWaiter implements ImageObserver {
1872
1873
private int mWidth;
1874
private int mHeight;
1875
private boolean badImage = false;
1876
1877
ImageWaiter(Image img) {
1878
waitForDimensions(img);
1879
}
1880
1881
public int getWidth() {
1882
return mWidth;
1883
}
1884
1885
public int getHeight() {
1886
return mHeight;
1887
}
1888
1889
private synchronized void waitForDimensions(Image img) {
1890
mHeight = img.getHeight(this);
1891
mWidth = img.getWidth(this);
1892
while (!badImage && (mWidth < 0 || mHeight < 0)) {
1893
try {
1894
Thread.sleep(50);
1895
} catch(InterruptedException e) {
1896
// do nothing.
1897
}
1898
mHeight = img.getHeight(this);
1899
mWidth = img.getWidth(this);
1900
}
1901
if (badImage) {
1902
mHeight = 0;
1903
mWidth = 0;
1904
}
1905
}
1906
1907
public synchronized boolean imageUpdate(Image image, int flags,
1908
int x, int y, int w, int h) {
1909
1910
boolean dontCallMeAgain = (flags & (HEIGHT | ABORT | ERROR)) != 0;
1911
badImage = (flags & (ABORT | ERROR)) != 0;
1912
1913
return dontCallMeAgain;
1914
}
1915
1916
}
1917
}
1918
1919