jdk/src/share/classes/javax/print/attribute/Size2DSyntax.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 2000-2004 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 
       
    27 package javax.print.attribute;
       
    28 
       
    29 import java.io.Serializable;
       
    30 
       
    31 /**
       
    32  * Class Size2DSyntax is an abstract base class providing the common
       
    33  * implementation of all attributes denoting a size in two dimensions.
       
    34  * <P>
       
    35  * A two-dimensional size attribute's value consists of two items, the X
       
    36  * dimension and the Y dimension. A two-dimensional size attribute may be
       
    37  * constructed by supplying the two values and indicating the units in which the
       
    38  * values are measured. Methods are provided to return a two-dimensional size
       
    39  * attribute's values, indicating the units in which the values are to be
       
    40  * returned. The two most common size units are inches (in) and millimeters
       
    41  * (mm), and exported constants {@link #INCH <CODE>INCH</CODE>} and {@link #MM
       
    42  * <CODE>MM</CODE>} are provided for indicating those units.
       
    43  * <P>
       
    44  * Once constructed, a two-dimensional size attribute's value is immutable.
       
    45  * <P>
       
    46  * <B>Design</B>
       
    47  * <P>
       
    48  * A two-dimensional size attribute's X and Y dimension values are stored
       
    49  * internally as integers in units of micrometers (&#181;m), where 1 micrometer
       
    50  * = 10<SUP>-6</SUP> meter = 1/1000 millimeter = 1/25400 inch. This permits
       
    51  * dimensions to be represented exactly to a precision of 1/1000 mm (= 1
       
    52  * &#181;m) or 1/100 inch (= 254 &#181;m). If fractional inches are expressed in
       
    53  * negative powers of two, this permits dimensions to be represented exactly to
       
    54  * a precision of 1/8 inch (= 3175 &#181;m) but not 1/16 inch (because 1/16 inch
       
    55  * does not equal an integral number of &#181;m).
       
    56  * <P>
       
    57  * Storing the dimensions internally in common units of &#181;m lets two size
       
    58  * attributes be compared without regard to the units in which they were
       
    59  * created; for example, 8.5 in will compare equal to 215.9 mm, as they both are
       
    60  * stored as 215900 &#181;m. For example, a lookup service can
       
    61  * match resolution attributes based on equality of their serialized
       
    62  * representations regardless of the units in which they were created. Using
       
    63  * integers for internal storage allows precise equality comparisons to be done,
       
    64  * which would not be guaranteed if an internal floating point representation
       
    65  * were used. Note that if you're looking for U.S. letter sized media in metric
       
    66  * units, you have to search for a media size of 215.9 x 279.4 mm; rounding off
       
    67  * to an integral 216 x 279 mm will not match.
       
    68  * <P>
       
    69  * The exported constant {@link #INCH <CODE>INCH</CODE>} is actually the
       
    70  * conversion factor by which to multiply a value in inches to get the value in
       
    71  * &#181;m. Likewise, the exported constant {@link #MM <CODE>MM</CODE>} is the
       
    72  * conversion factor by which to multiply a value in mm to get the value in
       
    73  * &#181;m. A client can specify a resolution value in units other than inches
       
    74  * or mm by supplying its own conversion factor. However, since the internal
       
    75  * units of &#181;m was chosen with supporting only the external units of inch
       
    76  * and mm in mind, there is no guarantee that the conversion factor for the
       
    77  * client's units will be an exact integer. If the conversion factor isn't an
       
    78  * exact integer, resolution values in the client's units won't be stored
       
    79  * precisely.
       
    80  * <P>
       
    81  *
       
    82  * @author  Alan Kaminsky
       
    83  */
       
    84 public abstract class Size2DSyntax implements Serializable, Cloneable {
       
    85 
       
    86     private static final long serialVersionUID = 5584439964938660530L;
       
    87 
       
    88     /**
       
    89      * X dimension in units of micrometers (&#181;m).
       
    90      * @serial
       
    91      */
       
    92     private int x;
       
    93 
       
    94     /**
       
    95      * Y dimension in units of micrometers (&#181;m).
       
    96      * @serial
       
    97      */
       
    98     private int y;
       
    99 
       
   100     /**
       
   101      * Value to indicate units of inches (in). It is actually the conversion
       
   102      * factor by which to multiply inches to yield &#181;m (25400).
       
   103      */
       
   104     public static final int INCH = 25400;
       
   105 
       
   106     /**
       
   107      * Value to indicate units of millimeters (mm). It is actually the
       
   108      * conversion factor by which to multiply mm to yield &#181;m (1000).
       
   109      */
       
   110     public static final int MM = 1000;
       
   111 
       
   112 
       
   113     /**
       
   114      * Construct a new two-dimensional size attribute from the given
       
   115      * floating-point values.
       
   116      *
       
   117      * @param  x  X dimension.
       
   118      * @param  y  Y dimension.
       
   119      * @param  units
       
   120      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   121      *     {@link #MM <CODE>MM</CODE>}.
       
   122      *
       
   123      * @exception  IllegalArgumentException
       
   124      *     (Unchecked exception) Thrown if <CODE>x</CODE> < 0 or <CODE>y</CODE>
       
   125      *     < 0 or <CODE>units</CODE> < 1.
       
   126      */
       
   127     protected Size2DSyntax(float x, float y, int units) {
       
   128         if (x < 0.0f) {
       
   129             throw new IllegalArgumentException("x < 0");
       
   130         }
       
   131         if (y < 0.0f) {
       
   132             throw new IllegalArgumentException("y < 0");
       
   133         }
       
   134         if (units < 1) {
       
   135             throw new IllegalArgumentException("units < 1");
       
   136         }
       
   137         this.x = (int) (x * units + 0.5f);
       
   138         this.y = (int) (y * units + 0.5f);
       
   139     }
       
   140 
       
   141     /**
       
   142      * Construct a new two-dimensional size attribute from the given integer
       
   143      * values.
       
   144      *
       
   145      * @param  x  X dimension.
       
   146      * @param  y  Y dimension.
       
   147      * @param  units
       
   148      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   149      *     {@link #MM <CODE>MM</CODE>}.
       
   150      *
       
   151      * @exception  IllegalArgumentException
       
   152      *   (Unchecked exception) Thrown if <CODE>x</CODE> < 0 or <CODE>y</CODE>
       
   153      *    < 0 or <CODE>units</CODE> < 1.
       
   154      */
       
   155     protected Size2DSyntax(int x, int y, int units) {
       
   156         if (x < 0) {
       
   157             throw new IllegalArgumentException("x < 0");
       
   158         }
       
   159         if (y < 0) {
       
   160             throw new IllegalArgumentException("y < 0");
       
   161         }
       
   162         if (units < 1) {
       
   163             throw new IllegalArgumentException("units < 1");
       
   164         }
       
   165         this.x = x * units;
       
   166         this.y = y * units;
       
   167     }
       
   168 
       
   169     /**
       
   170      * Convert a value from micrometers to some other units. The result is
       
   171      * returned as a floating-point number.
       
   172      *
       
   173      * @param  x
       
   174      *     Value (micrometers) to convert.
       
   175      * @param  units
       
   176      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   177      *     {@link #MM <CODE>MM</CODE>}.
       
   178      *
       
   179      * @return  The value of <CODE>x</CODE> converted to the desired units.
       
   180      *
       
   181      * @exception  IllegalArgumentException
       
   182      *     (unchecked exception) Thrown if <CODE>units</CODE> < 1.
       
   183      */
       
   184     private static float convertFromMicrometers(int x, int units) {
       
   185         if (units < 1) {
       
   186             throw new IllegalArgumentException("units is < 1");
       
   187         }
       
   188         return ((float)x) / ((float)units);
       
   189     }
       
   190 
       
   191     /**
       
   192      * Get this two-dimensional size attribute's dimensions in the given units
       
   193      * as floating-point values.
       
   194      *
       
   195      * @param  units
       
   196      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   197      *     {@link #MM <CODE>MM</CODE>}.
       
   198      *
       
   199      * @return  A two-element array with the X dimension at index 0 and the Y
       
   200      *          dimension at index 1.
       
   201      *
       
   202      * @exception  IllegalArgumentException
       
   203      *     (unchecked exception) Thrown if <CODE>units</CODE> < 1.
       
   204      */
       
   205     public float[] getSize(int units) {
       
   206         return new float[] {getX(units), getY(units)};
       
   207     }
       
   208 
       
   209     /**
       
   210      * Returns this two-dimensional size attribute's X dimension in the given
       
   211      * units as a floating-point value.
       
   212      *
       
   213      * @param  units
       
   214      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   215      *     {@link #MM <CODE>MM</CODE>}.
       
   216      *
       
   217      * @return  X dimension.
       
   218      *
       
   219      * @exception  IllegalArgumentException
       
   220      *     (unchecked exception) Thrown if <CODE>units</CODE> < 1.
       
   221      */
       
   222     public float getX(int units) {
       
   223         return convertFromMicrometers(x, units);
       
   224     }
       
   225 
       
   226     /**
       
   227      * Returns this two-dimensional size attribute's Y dimension in the given
       
   228      * units as a floating-point value.
       
   229      *
       
   230      * @param  units
       
   231      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   232      *     {@link #MM <CODE>MM</CODE>}.
       
   233      *
       
   234      * @return  Y dimension.
       
   235      *
       
   236      * @exception  IllegalArgumentException
       
   237      *     (unchecked exception) Thrown if <CODE>units</CODE> < 1.
       
   238      */
       
   239     public float getY(int units) {
       
   240         return convertFromMicrometers(y, units);
       
   241     }
       
   242 
       
   243     /**
       
   244      * Returns a string version of this two-dimensional size attribute in the
       
   245      * given units. The string takes the form <CODE>"<I>X</I>x<I>Y</I>
       
   246      * <I>U</I>"</CODE>, where <I>X</I> is the X dimension, <I>Y</I> is the Y
       
   247      * dimension, and <I>U</I> is the units name. The values are displayed in
       
   248      * floating point.
       
   249      *
       
   250      * @param  units
       
   251      *     Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
       
   252      *     {@link #MM <CODE>MM</CODE>}.
       
   253      * @param  unitsName
       
   254      *     Units name string, e.g. <CODE>"in"</CODE> or <CODE>"mm"</CODE>. If
       
   255      *     null, no units name is appended to the result.
       
   256      *
       
   257      * @return  String version of this two-dimensional size attribute.
       
   258      *
       
   259      * @exception  IllegalArgumentException
       
   260      *     (unchecked exception) Thrown if <CODE>units</CODE> < 1.
       
   261      */
       
   262     public String toString(int units, String unitsName) {
       
   263         StringBuffer result = new StringBuffer();
       
   264         result.append(getX (units));
       
   265         result.append('x');
       
   266         result.append(getY (units));
       
   267         if (unitsName != null) {
       
   268             result.append(' ');
       
   269             result.append(unitsName);
       
   270         }
       
   271         return result.toString();
       
   272     }
       
   273 
       
   274     /**
       
   275      * Returns whether this two-dimensional size attribute is equivalent to the
       
   276      * passed in object. To be equivalent, all of the following conditions must
       
   277      * be true:
       
   278      * <OL TYPE=1>
       
   279      * <LI>
       
   280      * <CODE>object</CODE> is not null.
       
   281      * <LI>
       
   282      * <CODE>object</CODE> is an instance of class Size2DSyntax.
       
   283      * <LI>
       
   284      * This attribute's X dimension is equal to <CODE>object</CODE>'s X
       
   285      * dimension.
       
   286      * <LI>
       
   287      * This attribute's Y dimension is equal to <CODE>object</CODE>'s Y
       
   288      * dimension.
       
   289      * </OL>
       
   290      *
       
   291      * @param  object  Object to compare to.
       
   292      *
       
   293      * @return  True if <CODE>object</CODE> is equivalent to this
       
   294      *          two-dimensional size attribute, false otherwise.
       
   295      */
       
   296     public boolean equals(Object object) {
       
   297         return(object != null &&
       
   298                object instanceof Size2DSyntax &&
       
   299                this.x == ((Size2DSyntax) object).x &&
       
   300                this.y == ((Size2DSyntax) object).y);
       
   301     }
       
   302 
       
   303     /**
       
   304      * Returns a hash code value for this two-dimensional size attribute.
       
   305      */
       
   306     public int hashCode() {
       
   307         return (((x & 0x0000FFFF)      ) |
       
   308                 ((y & 0x0000FFFF) << 16));
       
   309     }
       
   310 
       
   311     /**
       
   312      * Returns a string version of this two-dimensional size attribute. The
       
   313      * string takes the form <CODE>"<I>X</I>x<I>Y</I> um"</CODE>, where
       
   314      * <I>X</I> is the X dimension and <I>Y</I> is the Y dimension.
       
   315      * The values are reported in the internal units of micrometers.
       
   316      */
       
   317     public String toString() {
       
   318         StringBuffer result = new StringBuffer();
       
   319         result.append(x);
       
   320         result.append('x');
       
   321         result.append(y);
       
   322         result.append(" um");
       
   323         return result.toString();
       
   324     }
       
   325 
       
   326     /**
       
   327      * Returns this two-dimensional size attribute's X dimension in units of
       
   328      * micrometers (&#181;m). (For use in a subclass.)
       
   329      *
       
   330      * @return  X dimension (&#181;m).
       
   331      */
       
   332     protected int getXMicrometers(){
       
   333         return x;
       
   334     }
       
   335 
       
   336     /**
       
   337      * Returns this two-dimensional size attribute's Y dimension in units of
       
   338      * micrometers (&#181;m). (For use in a subclass.)
       
   339      *
       
   340      * @return  Y dimension (&#181;m).
       
   341      */
       
   342     protected int getYMicrometers() {
       
   343         return y;
       
   344     }
       
   345 
       
   346 }