jdk/src/share/classes/sun/print/PeekGraphics.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1998-2006 Sun Microsystems, Inc.  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.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any 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 }