1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.print;
  27 
  28 import java.awt.geom.AffineTransform;
  29 import java.awt.geom.Point2D;
  30 import java.awt.geom.Rectangle2D;
  31 
  32 import java.lang.annotation.Native;
  33 
  34 /**
  35  * The <code>PageFormat</code> class describes the size and
  36  * orientation of a page to be printed.
  37  */
  38 public class PageFormat implements Cloneable
  39 {
  40 
  41  /* Class Constants */
  42 
  43     /**
  44      *  The origin is at the bottom left of the paper with
  45      *  x running bottom to top and y running left to right.
  46      *  Note that this is not the Macintosh landscape but
  47      *  is the Window's and PostScript landscape.
  48      */
  49     @Native public static final int LANDSCAPE = 0;
  50 
  51     /**
  52      *  The origin is at the top left of the paper with
  53      *  x running to the right and y running down the
  54      *  paper.
  55      */
  56     @Native public static final int PORTRAIT = 1;
  57 
  58     /**
  59      *  The origin is at the top right of the paper with x
  60      *  running top to bottom and y running right to left.
  61      *  Note that this is the Macintosh landscape.
  62      */
  63     @Native public static final int REVERSE_LANDSCAPE = 2;
  64 
  65  /* Instance Variables */
  66 
  67     /**
  68      * A description of the physical piece of paper.
  69      */
  70     private Paper mPaper;
  71 
  72     /**
  73      * The orientation of the current page. This will be
  74      * one of the constants: PORTRAIT, LANDSCAPE, or
  75      * REVERSE_LANDSCAPE,
  76      */
  77     private int mOrientation = PORTRAIT;
  78 
  79  /* Constructors */
  80 
  81     /**
  82      * Creates a default, portrait-oriented
  83      * <code>PageFormat</code>.
  84      */
  85     public PageFormat()
  86     {
  87         mPaper = new Paper();
  88     }
  89 
  90  /* Instance Methods */
  91 
  92     /**
  93      * Makes a copy of this <code>PageFormat</code> with the same
  94      * contents as this <code>PageFormat</code>.
  95      * @return a copy of this <code>PageFormat</code>.
  96      */
  97     public Object clone() {
  98         PageFormat newPage;
  99 
 100         try {
 101             newPage = (PageFormat) super.clone();
 102             newPage.mPaper = (Paper)mPaper.clone();
 103 
 104         } catch (CloneNotSupportedException e) {
 105             e.printStackTrace();
 106             newPage = null;     // should never happen.
 107         }
 108 
 109         return newPage;
 110     }
 111 
 112 
 113     /**
 114      * Returns the width, in 1/72nds of an inch, of the page.
 115      * This method takes into account the orientation of the
 116      * page when determining the width.
 117      * @return the width of the page.
 118      */
 119     public double getWidth() {
 120         double width;
 121         int orientation = getOrientation();
 122 
 123         if (orientation == PORTRAIT) {
 124             width = mPaper.getWidth();
 125         } else {
 126             width = mPaper.getHeight();
 127         }
 128 
 129         return width;
 130     }
 131 
 132     /**
 133      * Returns the height, in 1/72nds of an inch, of the page.
 134      * This method takes into account the orientation of the
 135      * page when determining the height.
 136      * @return the height of the page.
 137      */
 138     public double getHeight() {
 139         double height;
 140         int orientation = getOrientation();
 141 
 142         if (orientation == PORTRAIT) {
 143             height = mPaper.getHeight();
 144         } else {
 145             height = mPaper.getWidth();
 146         }
 147 
 148         return height;
 149     }
 150 
 151     /**
 152      * Returns the x coordinate of the upper left point of the
 153      * imageable area of the <code>Paper</code> object
 154      * associated with this <code>PageFormat</code>.
 155      * This method takes into account the
 156      * orientation of the page.
 157      * @return the x coordinate of the upper left point of the
 158      * imageable area of the <code>Paper</code> object
 159      * associated with this <code>PageFormat</code>.
 160      */
 161     public double getImageableX() {
 162         double x;
 163 
 164         switch (getOrientation()) {
 165 
 166         case LANDSCAPE:
 167             x = mPaper.getHeight()
 168                 - (mPaper.getImageableY() + mPaper.getImageableHeight());
 169             break;
 170 
 171         case PORTRAIT:
 172             x = mPaper.getImageableX();
 173             break;
 174 
 175         case REVERSE_LANDSCAPE:
 176             x = mPaper.getImageableY();
 177             break;
 178 
 179         default:
 180             /* This should never happen since it signifies that the
 181              * PageFormat is in an invalid orientation.
 182              */
 183             throw new InternalError("unrecognized orientation");
 184 
 185         }
 186 
 187         return x;
 188     }
 189 
 190     /**
 191      * Returns the y coordinate of the upper left point of the
 192      * imageable area of the <code>Paper</code> object
 193      * associated with this <code>PageFormat</code>.
 194      * This method takes into account the
 195      * orientation of the page.
 196      * @return the y coordinate of the upper left point of the
 197      * imageable area of the <code>Paper</code> object
 198      * associated with this <code>PageFormat</code>.
 199      */
 200     public double getImageableY() {
 201         double y;
 202 
 203         switch (getOrientation()) {
 204 
 205         case LANDSCAPE:
 206             y = mPaper.getImageableX();
 207             break;
 208 
 209         case PORTRAIT:
 210             y = mPaper.getImageableY();
 211             break;
 212 
 213         case REVERSE_LANDSCAPE:
 214             y = mPaper.getWidth()
 215                 - (mPaper.getImageableX() + mPaper.getImageableWidth());
 216             break;
 217 
 218         default:
 219             /* This should never happen since it signifies that the
 220              * PageFormat is in an invalid orientation.
 221              */
 222             throw new InternalError("unrecognized orientation");
 223 
 224         }
 225 
 226         return y;
 227     }
 228 
 229     /**
 230      * Returns the width, in 1/72nds of an inch, of the imageable
 231      * area of the page. This method takes into account the orientation
 232      * of the page.
 233      * @return the width of the page.
 234      */
 235     public double getImageableWidth() {
 236         double width;
 237 
 238         if (getOrientation() == PORTRAIT) {
 239             width = mPaper.getImageableWidth();
 240         } else {
 241             width = mPaper.getImageableHeight();
 242         }
 243 
 244         return width;
 245     }
 246 
 247     /**
 248      * Return the height, in 1/72nds of an inch, of the imageable
 249      * area of the page. This method takes into account the orientation
 250      * of the page.
 251      * @return the height of the page.
 252      */
 253     public double getImageableHeight() {
 254         double height;
 255 
 256         if (getOrientation() == PORTRAIT) {
 257             height = mPaper.getImageableHeight();
 258         } else {
 259             height = mPaper.getImageableWidth();
 260         }
 261 
 262         return height;
 263     }
 264 
 265 
 266     /**
 267      * Returns a copy of the {@link Paper} object associated
 268      * with this <code>PageFormat</code>.  Changes made to the
 269      * <code>Paper</code> object returned from this method do not
 270      * affect the <code>Paper</code> object of this
 271      * <code>PageFormat</code>.  To update the <code>Paper</code>
 272      * object of this <code>PageFormat</code>, create a new
 273      * <code>Paper</code> object and set it into this
 274      * <code>PageFormat</code> by using the {@link #setPaper(Paper)}
 275      * method.
 276      * @return a copy of the <code>Paper</code> object associated
 277      *          with this <code>PageFormat</code>.
 278      * @see #setPaper
 279      */
 280     public Paper getPaper() {
 281         return (Paper)mPaper.clone();
 282     }
 283 
 284     /**
 285      * Sets the <code>Paper</code> object for this
 286      * <code>PageFormat</code>.
 287      * @param paper the <code>Paper</code> object to which to set
 288      * the <code>Paper</code> object for this <code>PageFormat</code>.
 289      * @exception NullPointerException
 290      *              a null paper instance was passed as a parameter.
 291      * @see #getPaper
 292      */
 293      public void setPaper(Paper paper) {
 294          mPaper = (Paper)paper.clone();
 295      }
 296 
 297     /**
 298      * Sets the page orientation. <code>orientation</code> must be
 299      * one of the constants: PORTRAIT, LANDSCAPE,
 300      * or REVERSE_LANDSCAPE.
 301      * @param orientation the new orientation for the page
 302      * @throws IllegalArgumentException if
 303      *          an unknown orientation was requested
 304      * @see #getOrientation
 305      */
 306     public void setOrientation(int orientation) throws IllegalArgumentException
 307     {
 308         if (0 <= orientation && orientation <= REVERSE_LANDSCAPE) {
 309             mOrientation = orientation;
 310         } else {
 311             throw new IllegalArgumentException();
 312         }
 313     }
 314 
 315     /**
 316      * Returns the orientation of this <code>PageFormat</code>.
 317      * @return this <code>PageFormat</code> object's orientation.
 318      * @see #setOrientation
 319      */
 320     public int getOrientation() {
 321         return mOrientation;
 322     }
 323 
 324     /**
 325      * Returns a transformation matrix that translates user
 326      * space rendering to the requested orientation
 327      * of the page.  The values are placed into the
 328      * array as
 329      * {&nbsp;m00,&nbsp;m10,&nbsp;m01,&nbsp;m11,&nbsp;m02,&nbsp;m12} in
 330      * the form required by the {@link AffineTransform}
 331      * constructor.
 332      * @return the matrix used to translate user space rendering
 333      * to the orientation of the page.
 334      * @see java.awt.geom.AffineTransform
 335      */
 336     public double[] getMatrix() {
 337         double[] matrix = new double[6];
 338 
 339         switch (mOrientation) {
 340 
 341         case LANDSCAPE:
 342             matrix[0] =  0;     matrix[1] = -1;
 343             matrix[2] =  1;     matrix[3] =  0;
 344             matrix[4] =  0;     matrix[5] =  mPaper.getHeight();
 345             break;
 346 
 347         case PORTRAIT:
 348             matrix[0] =  1;     matrix[1] =  0;
 349             matrix[2] =  0;     matrix[3] =  1;
 350             matrix[4] =  0;     matrix[5] =  0;
 351             break;
 352 
 353         case REVERSE_LANDSCAPE:
 354             matrix[0] =  0;                     matrix[1] =  1;
 355             matrix[2] = -1;                     matrix[3] =  0;
 356             matrix[4] =  mPaper.getWidth();     matrix[5] =  0;
 357             break;
 358 
 359         default:
 360             throw new IllegalArgumentException();
 361         }
 362 
 363         return matrix;
 364     }
 365 }