History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/print/PeekGraphics.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/print/PeekGraphics.java+1918−0
@@ -0,0 +1,1918 @@
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
26package sun.print;
27
28import java.util.Map;
29
30import java.awt.BasicStroke;
31import java.awt.Color;
32import java.awt.Composite;
33import java.awt.Graphics;
34import java.awt.Graphics2D;
35import java.awt.Font;
36import java.awt.FontMetrics;
37import java.awt.font.FontRenderContext;
38import java.awt.Graphics;
39import java.awt.GraphicsConfiguration;
40import java.awt.Image;
41import java.awt.Paint;
42import java.awt.Rectangle;
43import java.awt.Shape;
44import java.awt.Stroke;
45import java.awt.RenderingHints;
46import java.awt.RenderingHints.Key;
47
48import java.awt.font.GlyphVector;
49import java.awt.font.TextLayout;
50
51import java.awt.geom.AffineTransform;
52import java.awt.geom.Line2D;
53import java.awt.geom.Point2D;
54import java.awt.geom.Rectangle2D;
55import java.awt.geom.RoundRectangle2D;
56import java.awt.image.BufferedImage;
57import java.awt.image.BufferedImageOp;
58import java.awt.image.ImageObserver;
59import java.awt.image.RenderedImage;
60import java.awt.image.renderable.RenderableImage;
61import java.awt.print.PrinterGraphics;
62import java.awt.print.PrinterJob;
63
64import java.text.AttributedCharacterIterator;
65
66import sun.java2d.Spans;
67
68public 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}