001 /*
002 * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025 package javax.print.attribute.standard;
026
027 import javax.print.attribute.Attribute;
028 import javax.print.attribute.DocAttribute;
029 import javax.print.attribute.PrintJobAttribute;
030 import javax.print.attribute.PrintRequestAttribute;
031
032 /**
033 * Class MediaPrintableArea is a printing attribute used to distinguish
034 * the printable and non-printable areas of media.
035 * <p>
036 * The printable area is specified to be a rectangle, within the overall
037 * dimensions of a media.
038 * <p>
039 * Most printers cannot print on the entire surface of the media, due
040 * to printer hardware limitations. This class can be used to query
041 * the acceptable values for a supposed print job, and to request an area
042 * within the constraints of the printable area to be used in a print job.
043 * <p>
044 * To query for the printable area, a client must supply a suitable context.
045 * Without specifying at the very least the size of the media being used
046 * no meaningful value for printable area can be obtained.
047 * <p>
048 * The attribute is not described in terms of the distance from the edge
049 * of the paper, in part to emphasise that this attribute is not independent
050 * of a particular media, but must be described within the context of a
051 * choice of other attributes. Additionally it is usually more convenient
052 * for a client to use the printable area.
053 * <p>
054 * The hardware's minimum margins is not just a property of the printer,
055 * but may be a function of the media size, orientation, media type, and
056 * any specified finishings.
057 * <code>PrintService</code> provides the method to query the supported
058 * values of an attribute in a suitable context :
059 * See {@link javax.print.PrintService#getSupportedAttributeValues(Class,DocFlavor, AttributeSet) <code>PrintService.getSupportedAttributeValues()</code>}
060 * <p>
061 * The rectangular printable area is defined thus:
062 * The (x,y) origin is positioned at the top-left of the paper in portrait
063 * mode regardless of the orientation specified in the requesting context.
064 * For example a printable area for A4 paper in portrait or landscape
065 * orientation will have height > width.
066 * <p>
067 * A printable area attribute's values are stored
068 * internally as integers in units of micrometers (µm), where 1 micrometer
069 * = 10<SUP>-6</SUP> meter = 1/1000 millimeter = 1/25400 inch. This permits
070 * dimensions to be represented exactly to a precision of 1/1000 mm (= 1
071 * µm) or 1/100 inch (= 254 µm). If fractional inches are expressed in
072
073 * negative powers of two, this permits dimensions to be represented exactly to
074 * a precision of 1/8 inch (= 3175 µm) but not 1/16 inch (because 1/16 inch
075
076 * does not equal an integral number of µm).
077 * <p>
078 * <B>IPP Compatibility:</B> MediaPrintableArea is not an IPP attribute.
079 */
080
081 public final class MediaPrintableArea implements DocAttribute,
082 PrintRequestAttribute, PrintJobAttribute {
083
084 private int x, y, w, h;
085 private int units;
086
087 private static final long serialVersionUID = -1597171464050795793L;
088
089 /**
090 * Value to indicate units of inches (in). It is actually the conversion
091 * factor by which to multiply inches to yield µm (25400).
092 */
093 public static final int INCH = 25400;
094
095 /**
096 * Value to indicate units of millimeters (mm). It is actually the
097 * conversion factor by which to multiply mm to yield µm (1000).
098 */
099 public static final int MM = 1000;
100
101 /**
102 * Constructs a MediaPrintableArea object from floating point values.
103 * @param x printable x
104 * @param y printable y
105 * @param w printable width
106 * @param h printable height
107 * @param units in which the values are expressed.
108 *
109 * @exception IllegalArgumentException
110 * Thrown if <CODE>x</CODE> < 0 or <CODE>y</CODE> < 0
111 * or <CODE>w</CODE> <= 0 or <CODE>h</CODE> <= 0 or
112 * <CODE>units</CODE> < 1.
113 */
114 public MediaPrintableArea(float x, float y, float w, float h,
115 int units) {
116 if ((x < 0.0) || (y < 0.0) || (w <= 0.0) || (h <= 0.0)
117 || (units < 1)) {
118 throw new IllegalArgumentException(
119 "0 or negative value argument");
120 }
121
122 this .x = (int) (x * units + 0.5f);
123 this .y = (int) (y * units + 0.5f);
124 this .w = (int) (w * units + 0.5f);
125 this .h = (int) (h * units + 0.5f);
126
127 }
128
129 /**
130 * Constructs a MediaPrintableArea object from integer values.
131 * @param x printable x
132 * @param y printable y
133 * @param w printable width
134 * @param h printable height
135 * @param units in which the values are expressed.
136 *
137 * @exception IllegalArgumentException
138 * Thrown if <CODE>x</CODE> < 0 or <CODE>y</CODE> < 0
139 * or <CODE>w</CODE> <= 0 or <CODE>h</CODE> <= 0 or
140 * <CODE>units</CODE> < 1.
141 */
142 public MediaPrintableArea(int x, int y, int w, int h, int units) {
143 if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) || (units < 1)) {
144 throw new IllegalArgumentException(
145 "0 or negative value argument");
146 }
147 this .x = x * units;
148 this .y = y * units;
149 this .w = w * units;
150 this .h = h * units;
151
152 }
153
154 /**
155 * Get the printable area as an array of 4 values in the order
156 * x, y, w, h. The values returned are in the given units.
157 * @param units
158 * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
159 * {@link #MM <CODE>MM</CODE>}.
160 *
161 * @return printable area as array of x, y, w, h in the specified units.
162 *
163 * @exception IllegalArgumentException
164 * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
165 */
166 public float[] getPrintableArea(int units) {
167 return new float[] { getX(units), getY(units), getWidth(units),
168 getHeight(units) };
169 }
170
171 /**
172 * Get the x location of the origin of the printable area in the
173 * specified units.
174 * @param units
175 * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
176 * {@link #MM <CODE>MM</CODE>}.
177 *
178 * @return x location of the origin of the printable area in the
179 * specified units.
180 *
181 * @exception IllegalArgumentException
182 * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
183 */
184 public float getX(int units) {
185 return convertFromMicrometers(x, units);
186 }
187
188 /**
189 * Get the y location of the origin of the printable area in the
190 * specified units.
191 * @param units
192 * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
193 * {@link #MM <CODE>MM</CODE>}.
194 *
195 * @return y location of the origin of the printable area in the
196 * specified units.
197 *
198 * @exception IllegalArgumentException
199 * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
200 */
201 public float getY(int units) {
202 return convertFromMicrometers(y, units);
203 }
204
205 /**
206 * Get the width of the printable area in the specified units.
207 * @param units
208 * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
209 * {@link #MM <CODE>MM</CODE>}.
210 *
211 * @return width of the printable area in the specified units.
212 *
213 * @exception IllegalArgumentException
214 * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
215 */
216 public float getWidth(int units) {
217 return convertFromMicrometers(w, units);
218 }
219
220 /**
221 * Get the height of the printable area in the specified units.
222 * @param units
223 * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
224 * {@link #MM <CODE>MM</CODE>}.
225 *
226 * @return height of the printable area in the specified units.
227 *
228 * @exception IllegalArgumentException
229 * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
230 */
231 public float getHeight(int units) {
232 return convertFromMicrometers(h, units);
233 }
234
235 /**
236 * Returns whether this media margins attribute is equivalent to the passed
237 * in object.
238 * To be equivalent, all of the following conditions must be true:
239 * <OL TYPE=1>
240 * <LI>
241 * <CODE>object</CODE> is not null.
242 * <LI>
243 * <CODE>object</CODE> is an instance of class MediaPrintableArea.
244 * <LI>
245 * The origin and dimensions are the same.
246 * </OL>
247 *
248 * @param object Object to compare to.
249 *
250 * @return True if <CODE>object</CODE> is equivalent to this media margins
251 * attribute, false otherwise.
252 */
253 public boolean equals(Object object) {
254 boolean ret = false;
255 if (object instanceof MediaPrintableArea) {
256 MediaPrintableArea mm = (MediaPrintableArea) object;
257 if (x == mm.x && y == mm.y && w == mm.w && h == mm.h) {
258 ret = true;
259 }
260 }
261 return ret;
262 }
263
264 /**
265 * Get the printing attribute class which is to be used as the "category"
266 * for this printing attribute value.
267 * <P>
268 * For class MediaPrintableArea, the category is
269 * class MediaPrintableArea itself.
270 *
271 * @return Printing attribute class (category), an instance of class
272 * {@link java.lang.Class java.lang.Class}.
273 */
274 public final Class<? extends Attribute> getCategory() {
275 return MediaPrintableArea.class;
276 }
277
278 /**
279 * Get the name of the category of which this attribute value is an
280 * instance.
281 * <P>
282 * For class MediaPrintableArea,
283 * the category name is <CODE>"media-printable-area"</CODE>.
284 * <p>This is not an IPP V1.1 attribute.
285 *
286 * @return Attribute category name.
287 */
288 public final String getName() {
289 return "media-printable-area";
290 }
291
292 /**
293 * Returns a string version of this rectangular size attribute in the
294 * given units.
295 *
296 * @param units
297 * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
298 * {@link #MM <CODE>MM</CODE>}.
299 * @param unitsName
300 * Units name string, e.g. <CODE>"in"</CODE> or <CODE>"mm"</CODE>. If
301 * null, no units name is appended to the result.
302 *
303 * @return String version of this two-dimensional size attribute.
304 *
305 * @exception IllegalArgumentException
306 * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
307 */
308 public String toString(int units, String unitsName) {
309 if (unitsName == null) {
310 unitsName = "";
311 }
312 float[] vals = getPrintableArea(units);
313 String str = "(" + vals[0] + "," + vals[1] + ")->(" + vals[2]
314 + "," + vals[3] + ")";
315 return str + unitsName;
316 }
317
318 /**
319 * Returns a string version of this rectangular size attribute in mm.
320 */
321 public String toString() {
322 return (toString(MM, "mm"));
323 }
324
325 /**
326 * Returns a hash code value for this attribute.
327 */
328 public int hashCode() {
329 return x + 37 * y + 43 * w + 47 * h;
330 }
331
332 private static float convertFromMicrometers(int x, int units) {
333 if (units < 1) {
334 throw new IllegalArgumentException("units is < 1");
335 }
336 return ((float) x) / ((float) units);
337 }
338 }
|