Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/print/PeekGraphics.java
38829 views
1
/*
2
* Copyright (c) 1998, 2006, 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</code> object that is
166
* a copy of this <code>Graphics</code> object.
167
* @return a new graphics context that is a copy of
168
* this graphics context.
169
* @since JDK1.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 JDK1.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 JDK1.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 JDK1.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 JDK1.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 JDK1.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 JDK1.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(java.lang.String, int, int)
365
* @see java.awt.Graphics#drawString(byte[], int, int, int, int)
366
* @see java.awt.Graphics#drawBytes(char[], int, int, int, int)
367
* @since JDK1.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 JDK1.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 JDK1.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 JDK1.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</code> 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 JDK1.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</code>
463
* interface can be used to set the clip. The only
464
* <code>Shape</code> objects which are guaranteed to be
465
* supported are <code>Shape</code> objects which are
466
* obtained via the <code>getClip</code> method and via
467
* <code>Rectangle</code> 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 JDK1.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</code> and <code>dy</code>. From the point specified
481
* by <code>x</code> and <code>y</code>, 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</code> or <code>dy</code>.
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</code> 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</code> 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 JDK1.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 JDK1.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</code> and <code>x&nbsp;+&nbsp;width&nbsp;-&nbsp;1</code>.
524
* The top and bottom edges are at
525
* <code>y</code> and <code>y&nbsp;+&nbsp;height&nbsp;-&nbsp;1</code>.
526
* The resulting rectangle covers an area
527
* <code>width</code> pixels wide by
528
* <code>height</code> 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 JDK1.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</code> followed by <code>fillRect</code> 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 JDK1.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</code> and <code>x&nbsp;+&nbsp;width</code>,
577
* respectively. The top and bottom edges of the rectangle are at
578
* <code>y</code> 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 JDK1.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</code> 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</code> 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 JDK1.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>, <code>y</code>,
625
* <code>width</code>, and <code>height</code> 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 JDK1.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 JDK1.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</code> and extends
669
* for <code>arcAngle</code> 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</code> and <code>height</code> 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 JDK1.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</code> and extends
705
* for <code>arcAngle</code> 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</code> and <code>height</code> 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 JDK1.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 JDK1.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</code> 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</code>.
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</code> coordinates.
779
* @param yPoints a an array of <code>y</code> coordinates.
780
* @param nPoints a the total number of points.
781
* @see java.awt.Graphics#fillPolygon
782
* @see java.awt.Graphics#drawPolyline
783
* @since JDK1.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</code> 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</code>.
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</code> coordinates.
811
* @param yPoints a an array of <code>y</code> coordinates.
812
* @param nPoints a the total number of points.
813
* @see java.awt.Graphics#drawPolygon(int[], int[], int)
814
* @since JDK1.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 JDK1.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 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 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</code> returns <code>false</code>. 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 JDK1.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</code> returns <code>false</code>. As more of
980
* the image becomes available, the process that draws the image notifies
981
* the image observer by calling its <code>imageUpdate</code> 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 JDK1.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</code> returns <code>false</code>. 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 JDK1.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</code> returns <code>false</code>. 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 JDK1.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</code> returns <code>false</code>. 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 JDK1.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</code> returns <code>false</code>. 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 JDK1.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</code> object cannot be used after
1308
* <code>dispose</code>has been called.
1309
* <p>
1310
* When a Java program runs, a large number of <code>Graphics</code>
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</code> and <code>update</code> methods
1320
* of components are automatically released by the system when
1321
* those methods return. For efficiency, programmers should
1322
* call <code>dispose</code> when finished using
1323
* a <code>Graphics</code> object only if it was created
1324
* directly from a component or another <code>Graphics</code> 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 JDK1.0
1331
*/
1332
public void dispose() {
1333
mGraphics.dispose();
1334
}
1335
1336
/**
1337
* Empty finalizer as no clean up needed here.
1338
*/
1339
public void finalize() {
1340
}
1341
1342
/* The Delegated Graphics2D Methods */
1343
1344
/**
1345
* Strokes the outline of a Shape using the settings of the current
1346
* graphics state. The rendering attributes applied include the
1347
* clip, transform, paint or color, composite and stroke attributes.
1348
* @param s The shape to be drawn.
1349
* @see #setStroke
1350
* @see #setPaint
1351
* @see java.awt.Graphics#setColor
1352
* @see #transform
1353
* @see #setTransform
1354
* @see #clip
1355
* @see #setClip
1356
* @see #setComposite
1357
*/
1358
public void draw(Shape s) {
1359
addStrokeShape(s);
1360
mPrintMetrics.draw(this);
1361
}
1362
1363
1364
/**
1365
* Draws an image, applying a transform from image space into user space
1366
* before drawing.
1367
* The transformation from user space into device space is done with
1368
* the current transform in the Graphics2D.
1369
* The given transformation is applied to the image before the
1370
* transform attribute in the Graphics2D state is applied.
1371
* The rendering attributes applied include the clip, transform,
1372
* and composite attributes. Note that the result is
1373
* undefined, if the given transform is noninvertible.
1374
* @param img The image to be drawn.
1375
* @param xform The transformation from image space into user space.
1376
* @param obs The image observer to be notified as more of the image
1377
* is converted.
1378
* @see #transform
1379
* @see #setTransform
1380
* @see #setComposite
1381
* @see #clip
1382
* @see #setClip
1383
*/
1384
public boolean drawImage(Image img,
1385
AffineTransform xform,
1386
ImageObserver obs) {
1387
1388
if (img == null) {
1389
return true;
1390
}
1391
1392
mDrawingArea.addInfinite();
1393
mPrintMetrics.drawImage(this, img);
1394
1395
return mGraphics.drawImage(img, xform, obs);
1396
1397
1398
// if (mDrawingArea[0] != null) {
1399
// Rectangle2D.Double bbox = new Rectangle2D.Double();
1400
// Point2D leftTop = new Point2D.Double(0, 0);
1401
// Point2D rightBottom = new Point2D.Double(getImageWidth(img),
1402
// getImageHeight(img));
1403
1404
// xform.transform(leftTop, leftTop);
1405
// xform.transform(rightBottom, rightBottom);
1406
1407
// bbox.setBoundsFromDiagonal(leftTop, rightBottom);
1408
// addDrawingRect(bbox);
1409
1410
// }
1411
}
1412
1413
1414
/**
1415
* Draws a BufferedImage that is filtered with a BufferedImageOp.
1416
* The rendering attributes applied include the clip, transform
1417
* and composite attributes. This is equivalent to:
1418
* <pre>
1419
* img1 = op.filter(img, null);
1420
* drawImage(img1, new AffineTransform(1f,0f,0f,1f,x,y), null);
1421
* </pre>
1422
* @param op The filter to be applied to the image before drawing.
1423
* @param img The BufferedImage to be drawn.
1424
* @param x,y The location in user space where the image should be drawn.
1425
* @see #transform
1426
* @see #setTransform
1427
* @see #setComposite
1428
* @see #clip
1429
* @see #setClip
1430
*/
1431
public void drawImage(BufferedImage img,
1432
BufferedImageOp op,
1433
int x,
1434
int y) {
1435
1436
if (img == null) {
1437
return;
1438
}
1439
1440
mPrintMetrics.drawImage(this, (RenderedImage) img);
1441
mDrawingArea.addInfinite();
1442
}
1443
1444
1445
/**
1446
* Draws a string of text.
1447
* The rendering attributes applied include the clip, transform,
1448
* paint or color, font and composite attributes.
1449
* @param s The string to be drawn.
1450
* @param x,y The coordinates where the string should be drawn.
1451
* @see #setPaint
1452
* @see java.awt.Graphics#setColor
1453
* @see java.awt.Graphics#setFont
1454
* @see #transform
1455
* @see #setTransform
1456
* @see #setComposite
1457
* @see #clip
1458
* @see #setClip
1459
*/
1460
public void drawString(String str,
1461
float x,
1462
float y) {
1463
1464
if (str.length() == 0) {
1465
return;
1466
}
1467
/* Logical bounds close enough and is used for GlyphVector */
1468
FontRenderContext frc = getFontRenderContext();
1469
Rectangle2D bbox = getFont().getStringBounds(str, frc);
1470
addDrawingRect(bbox, x, y);
1471
mPrintMetrics.drawText(this);
1472
}
1473
1474
/**
1475
* Draws a GlyphVector.
1476
* The rendering attributes applied include the clip, transform,
1477
* paint or color, and composite attributes. The GlyphVector specifies
1478
* individual glyphs from a Font.
1479
* @param g The GlyphVector to be drawn.
1480
* @param x,y The coordinates where the glyphs should be drawn.
1481
* @see #setPaint
1482
* @see java.awt.Graphics#setColor
1483
* @see #transform
1484
* @see #setTransform
1485
* @see #setComposite
1486
* @see #clip
1487
* @see #setClip
1488
*/
1489
public void drawGlyphVector(GlyphVector g,
1490
float x,
1491
float y) {
1492
1493
Rectangle2D bbox = g.getLogicalBounds();
1494
addDrawingRect(bbox, x, y);
1495
mPrintMetrics.drawText(this);
1496
1497
}
1498
1499
/**
1500
* Fills the interior of a Shape using the settings of the current
1501
* graphics state. The rendering attributes applied include the
1502
* clip, transform, paint or color, and composite.
1503
* @see #setPaint
1504
* @see java.awt.Graphics#setColor
1505
* @see #transform
1506
* @see #setTransform
1507
* @see #setComposite
1508
* @see #clip
1509
* @see #setClip
1510
*/
1511
public void fill(Shape s) {
1512
addDrawingRect(s.getBounds());
1513
mPrintMetrics.fill(this);
1514
1515
}
1516
1517
1518
/**
1519
* Checks to see if the outline of a Shape intersects the specified
1520
* Rectangle in device space.
1521
* The rendering attributes taken into account include the
1522
* clip, transform, and stroke attributes.
1523
* @param rect The area in device space to check for a hit.
1524
* @param s The shape to check for a hit.
1525
* @param onStroke Flag to choose between testing the stroked or
1526
* the filled shape.
1527
* @return True if there is a hit, false otherwise.
1528
* @see #setStroke
1529
* @see #fill
1530
* @see #draw
1531
* @see #transform
1532
* @see #setTransform
1533
* @see #clip
1534
* @see #setClip
1535
*/
1536
public boolean hit(Rectangle rect,
1537
Shape s,
1538
boolean onStroke) {
1539
1540
return mGraphics.hit(rect, s, onStroke);
1541
}
1542
1543
/**
1544
* Sets the Composite in the current graphics state. Composite is used
1545
* in all drawing methods such as drawImage, drawString, draw,
1546
* and fill. It specifies how new pixels are to be combined with
1547
* the existing pixels on the graphics device in the rendering process.
1548
* @param comp The Composite object to be used for drawing.
1549
* @see java.awt.Graphics#setXORMode
1550
* @see java.awt.Graphics#setPaintMode
1551
* @see AlphaComposite
1552
*/
1553
public void setComposite(Composite comp) {
1554
mGraphics.setComposite(comp);
1555
}
1556
1557
1558
/**
1559
* Sets the Paint in the current graphics state.
1560
* @param paint The Paint object to be used to generate color in
1561
* the rendering process.
1562
* @see java.awt.Graphics#setColor
1563
* @see GradientPaint
1564
* @see TexturePaint
1565
*/
1566
public void setPaint(Paint paint) {
1567
mGraphics.setPaint(paint);
1568
}
1569
1570
/**
1571
* Sets the Stroke in the current graphics state.
1572
* @param s The Stroke object to be used to stroke a Shape in
1573
* the rendering process.
1574
* @see BasicStroke
1575
*/
1576
public void setStroke(Stroke s) {
1577
mGraphics.setStroke(s);
1578
}
1579
1580
/**
1581
* Sets the preferences for the rendering algorithms.
1582
* Hint categories include controls for rendering quality and
1583
* overall time/quality trade-off in the rendering process.
1584
* @param hintCategory The category of hint to be set.
1585
* @param hintValue The value indicating preferences for the specified
1586
* hint category.
1587
* @see RenderingHints
1588
*/
1589
public void setRenderingHint(Key hintCategory, Object hintValue) {
1590
mGraphics.setRenderingHint(hintCategory, hintValue);
1591
}
1592
1593
/**
1594
* Returns the preferences for the rendering algorithms.
1595
* @param hintCategory The category of hint to be set.
1596
* @return The preferences for rendering algorithms.
1597
* @see RenderingHings
1598
*/
1599
public Object getRenderingHint(Key hintCategory) {
1600
return mGraphics.getRenderingHint(hintCategory);
1601
}
1602
1603
/**
1604
* Sets the preferences for the rendering algorithms.
1605
* Hint categories include controls for rendering quality and
1606
* overall time/quality trade-off in the rendering process.
1607
* @param hints The rendering hints to be set
1608
* @see RenderingHints
1609
*/
1610
public void setRenderingHints(Map<?,?> hints) {
1611
mGraphics.setRenderingHints(hints);
1612
}
1613
1614
/**
1615
* Adds a number of preferences for the rendering algorithms.
1616
* Hint categories include controls for rendering quality and
1617
* overall time/quality trade-off in the rendering process.
1618
* @param hints The rendering hints to be set
1619
* @see RenderingHints
1620
*/
1621
public void addRenderingHints(Map<?,?> hints) {
1622
mGraphics.addRenderingHints(hints);
1623
}
1624
1625
/**
1626
* Gets the preferences for the rendering algorithms.
1627
* Hint categories include controls for rendering quality and
1628
* overall time/quality trade-off in the rendering process.
1629
* @see RenderingHints
1630
*/
1631
public RenderingHints getRenderingHints() {
1632
return mGraphics.getRenderingHints();
1633
}
1634
1635
/**
1636
* Composes a Transform object with the transform in this
1637
* Graphics2D according to the rule last-specified-first-applied.
1638
* If the currrent transform is Cx, the result of composition
1639
* with Tx is a new transform Cx'. Cx' becomes the current
1640
* transform for this Graphics2D.
1641
* Transforming a point p by the updated transform Cx' is
1642
* equivalent to first transforming p by Tx and then transforming
1643
* the result by the original transform Cx. In other words,
1644
* Cx'(p) = Cx(Tx(p)).
1645
* A copy of the Tx is made, if necessary, so further
1646
* modifications to Tx do not affect rendering.
1647
* @param Tx The Transform object to be composed with the current
1648
* transform.
1649
* @see #setTransform
1650
* @see TransformChain
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 TransformChain
1662
* @see AffineTransform
1663
*/
1664
public void setTransform(AffineTransform Tx) {
1665
mGraphics.setTransform(Tx);
1666
}
1667
1668
/**
1669
* Returns the current Transform in the Graphics2D state.
1670
* @see #transform
1671
* @see #setTransform
1672
*/
1673
public AffineTransform getTransform() {
1674
return mGraphics.getTransform();
1675
}
1676
1677
/**
1678
* Returns the current Paint in the Graphics2D state.
1679
* @see #setPaint
1680
* @see java.awt.Graphics#setColor
1681
*/
1682
public Paint getPaint() {
1683
return mGraphics.getPaint();
1684
}
1685
1686
/**
1687
* Returns the current Composite in the Graphics2D state.
1688
* @see #setComposite
1689
*/
1690
public Composite getComposite() {
1691
return mGraphics.getComposite();
1692
}
1693
1694
/**
1695
* Sets the background color in this context used for clearing a region.
1696
* When Graphics2D is constructed for a component, the backgroung color is
1697
* inherited from the component. Setting the background color in the
1698
* Graphics2D context only affects the subsequent clearRect() calls and
1699
* not the background color of the component. To change the background
1700
* of the component, use appropriate methods of the component.
1701
* @param color The background color that should be used in
1702
* subsequent calls to clearRect().
1703
* @see getBackground
1704
* @see Graphics.clearRect()
1705
*/
1706
public void setBackground(Color color) {
1707
mGraphics.setBackground(color);
1708
}
1709
1710
/**
1711
* Returns the background color used for clearing a region.
1712
* @see setBackground
1713
*/
1714
public Color getBackground() {
1715
return mGraphics.getBackground();
1716
}
1717
1718
/**
1719
* Returns the current Stroke in the Graphics2D state.
1720
* @see setStroke
1721
*/
1722
public Stroke getStroke() {
1723
return mGraphics.getStroke();
1724
}
1725
1726
/**
1727
* Intersects the current clip with the interior of the specified Shape
1728
* and sets the current clip to the resulting intersection.
1729
* The indicated shape is transformed with the current transform in the
1730
* Graphics2D state before being intersected with the current clip.
1731
* This method is used to make the current clip smaller.
1732
* To make the clip larger, use any setClip method.
1733
* @param s The Shape to be intersected with the current clip.
1734
*/
1735
public void clip(Shape s) {
1736
mGraphics.clip(s);
1737
}
1738
1739
/**
1740
* Return true if the Rectangle <code>rect</code>
1741
* intersects the area into which the application
1742
* has drawn.
1743
*/
1744
public boolean hitsDrawingArea(Rectangle rect) {
1745
1746
return mDrawingArea.intersects((float) rect.getMinY(),
1747
(float) rect.getMaxY());
1748
}
1749
1750
/**
1751
* Return the object holding the summary of the
1752
* drawing done by the printing application.
1753
*/
1754
public PeekMetrics getMetrics() {
1755
return mPrintMetrics;
1756
}
1757
1758
/* Support Routines for Calculating the Drawing Area */
1759
1760
/**
1761
* Shift the rectangle 'rect' to the position ('x', 'y')
1762
* and add the resulting rectangle to the area representing
1763
* the part of the page which is drawn into.
1764
*/
1765
private void addDrawingRect(Rectangle2D rect, float x, float y) {
1766
1767
addDrawingRect((float) (rect.getX() + x),
1768
(float) (rect.getY() + y),
1769
(float) rect.getWidth(),
1770
(float) rect.getHeight());
1771
1772
}
1773
1774
private void addDrawingRect(float x, float y, float width, float height) {
1775
1776
Rectangle2D.Float bbox = new Rectangle2D.Float(x, y, width, height);
1777
addDrawingRect(bbox);
1778
}
1779
1780
/**
1781
* Add the rectangle 'rect' to the area representing
1782
* the part of the page which is drawn into.
1783
*/
1784
private void addDrawingRect(Rectangle2D rect) {
1785
1786
/* For testing purposes the following line can be uncommented.
1787
When uncommented it causes the entire page to be rasterized
1788
thus eliminating errors caused by a faulty bounding box
1789
calculation.
1790
*/
1791
//mDrawingArea.addInfinite();
1792
1793
1794
1795
AffineTransform matrix = getTransform();
1796
1797
Shape transShape = matrix.createTransformedShape(rect);
1798
1799
Rectangle2D transRect = transShape.getBounds2D();
1800
1801
mDrawingArea.add((float) transRect.getMinY(),
1802
(float) transRect.getMaxY());
1803
1804
1805
}
1806
1807
/**
1808
* Add the stroked shape to the area representing
1809
* the part of the page which is drawn into.
1810
*/
1811
private void addStrokeShape(Shape s) {
1812
Shape transShape = getStroke().createStrokedShape(s);
1813
addDrawingRect(transShape.getBounds2D());
1814
}
1815
1816
/* Image Observer */
1817
1818
/**
1819
* Notify this object when the height or width become available
1820
* for an image.
1821
*/
1822
public synchronized boolean imageUpdate(Image img, int infoFlags,
1823
int x, int y,
1824
int width, int height) {
1825
1826
boolean gotInfo = false;
1827
1828
if((infoFlags & (WIDTH | HEIGHT)) != 0) {
1829
gotInfo = true;
1830
notify();
1831
}
1832
1833
return gotInfo;
1834
}
1835
1836
private synchronized int getImageWidth(Image img) {
1837
1838
/* Wait for the width the image to
1839
* become available.
1840
*/
1841
while (img.getWidth(this) == -1) {
1842
try {
1843
wait();
1844
} catch (InterruptedException e) {
1845
}
1846
}
1847
1848
1849
return img.getWidth(this);
1850
}
1851
1852
private synchronized int getImageHeight(Image img) {
1853
1854
/* Wait for the height the image to
1855
* become available.
1856
*/
1857
while (img.getHeight(this) == -1) {
1858
try {
1859
wait();
1860
} catch (InterruptedException e) {
1861
}
1862
}
1863
1864
1865
return img.getHeight(this);
1866
}
1867
1868
/**
1869
* This private class does not return from its constructor
1870
* until 'img's width and height are available.
1871
*/
1872
protected class ImageWaiter implements ImageObserver {
1873
1874
private int mWidth;
1875
private int mHeight;
1876
private boolean badImage = false;
1877
1878
ImageWaiter(Image img) {
1879
waitForDimensions(img);
1880
}
1881
1882
public int getWidth() {
1883
return mWidth;
1884
}
1885
1886
public int getHeight() {
1887
return mHeight;
1888
}
1889
1890
synchronized private void waitForDimensions(Image img) {
1891
mHeight = img.getHeight(this);
1892
mWidth = img.getWidth(this);
1893
while (!badImage && (mWidth < 0 || mHeight < 0)) {
1894
try {
1895
Thread.sleep(50);
1896
} catch(InterruptedException e) {
1897
// do nothing.
1898
}
1899
mHeight = img.getHeight(this);
1900
mWidth = img.getWidth(this);
1901
}
1902
if (badImage) {
1903
mHeight = 0;
1904
mWidth = 0;
1905
}
1906
}
1907
1908
synchronized public boolean imageUpdate(Image image, int flags,
1909
int x, int y, int w, int h) {
1910
1911
boolean dontCallMeAgain = (flags & (HEIGHT | ABORT | ERROR)) != 0;
1912
badImage = (flags & (ABORT | ERROR)) != 0;
1913
1914
return dontCallMeAgain;
1915
}
1916
1917
}
1918
}
1919
1920