1 /* 2 * Copyright (c) 2000, 2017, 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 package javax.print.attribute.standard; 26 27 import javax.print.DocFlavor; 28 import javax.print.attribute.Attribute; 29 import javax.print.attribute.AttributeSet; 30 import javax.print.attribute.DocAttribute; 31 import javax.print.attribute.PrintJobAttribute; 32 import javax.print.attribute.PrintRequestAttribute; 33 34 /** 35 * Class MediaPrintableArea is a printing attribute used to distinguish 36 * the printable and non-printable areas of media. 37 * <p> 38 * The printable area is specified to be a rectangle, within the overall 39 * dimensions of a media. 40 * <p> 41 * Most printers cannot print on the entire surface of the media, due 42 * to printer hardware limitations. This class can be used to query 43 * the acceptable values for a supposed print job, and to request an area 44 * within the constraints of the printable area to be used in a print job. 45 * <p> 46 * To query for the printable area, a client must supply a suitable context. 47 * Without specifying at the very least the size of the media being used 48 * no meaningful value for printable area can be obtained. 49 * <p> 50 * The attribute is not described in terms of the distance from the edge 51 * of the paper, in part to emphasise that this attribute is not independent 52 * of a particular media, but must be described within the context of a 53 * choice of other attributes. Additionally it is usually more convenient 54 * for a client to use the printable area. 55 * <p> 56 * The hardware's minimum margins is not just a property of the printer, 57 * but may be a function of the media size, orientation, media type, and 58 * any specified finishings. 59 * {@code PrintService} provides the method to query the supported 60 * values of an attribute in a suitable context : 61 * See {@link javax.print.PrintService#getSupportedAttributeValues(Class,DocFlavor, AttributeSet) PrintService.getSupportedAttributeValues()} 62 * <p> 63 * The rectangular printable area is defined thus: 64 * The (x,y) origin is positioned at the top-left of the paper in portrait 65 * mode regardless of the orientation specified in the requesting context. 66 * For example a printable area for A4 paper in portrait or landscape 67 * orientation will have height {@literal >} width. 68 * <p> 69 * A printable area attribute's values are stored 70 * internally as integers in units of micrometers (µm), where 1 micrometer 71 * = 10<SUP>-6</SUP> meter = 1/1000 millimeter = 1/25400 inch. This permits 72 * dimensions to be represented exactly to a precision of 1/1000 mm (= 1 73 * µm) or 1/100 inch (= 254 µm). If fractional inches are expressed in 74 75 * negative powers of two, this permits dimensions to be represented exactly to 76 * a precision of 1/8 inch (= 3175 µm) but not 1/16 inch (because 1/16 inch 77 78 * does not equal an integral number of µm). 79 * <p> 80 * <B>IPP Compatibility:</B> MediaPrintableArea is not an IPP attribute. 81 */ 82 83 public final class MediaPrintableArea 84 implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { 85 86 private int x, y, w, h; 87 private int units; 88 89 private static final long serialVersionUID = -1597171464050795793L; 90 91 /** 92 * Value to indicate units of inches (in). It is actually the conversion 93 * factor by which to multiply inches to yield µm (25400). 94 */ 95 public static final int INCH = 25400; 96 97 /** 98 * Value to indicate units of millimeters (mm). It is actually the 99 * conversion factor by which to multiply mm to yield µm (1000). 100 */ 101 public static final int MM = 1000; 102 103 /** 104 * Constructs a MediaPrintableArea object from floating point values. 105 * @param x printable x 106 * @param y printable y 107 * @param w printable width 108 * @param h printable height 109 * @param units in which the values are expressed. 110 * 111 * @exception IllegalArgumentException 112 * Thrown if {@code x < 0} or {@code y < 0} 113 * or {@code w <= 0} or {@code h <= 0} or 114 * {@code units < 1}. 115 */ 116 public MediaPrintableArea(float x, float y, float w, float h, int units) { 117 if ((x < 0.0) || (y < 0.0) || (w <= 0.0) || (h <= 0.0) || 118 (units < 1)) { 119 throw new IllegalArgumentException("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 < 0} or {@code y < 0} 139 * or {@code w <= 0} or {@code h <= 0} or 140 * {@code units < 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) || 144 (units < 1)) { 145 throw new IllegalArgumentException("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 INCH} or 159 * {@link #MM MM}. 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 < 1}. 165 */ 166 public float[] getPrintableArea(int units) { 167 return new float[] { getX(units), getY(units), 168 getWidth(units), 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 INCH} or 176 * {@link #MM MM}. 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 < 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 INCH} or 193 * {@link #MM MM}. 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 < 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 INCH} or 209 * {@link #MM MM}. 210 * 211 * @return width of the printable area in the specified units. 212 * 213 * @exception IllegalArgumentException 214 * (unchecked exception) Thrown if {@code units < 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 INCH} or 224 * {@link #MM MM}. 225 * 226 * @return height of the printable area in the specified units. 227 * 228 * @exception IllegalArgumentException 229 * (unchecked exception) Thrown if {@code units < 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} is not null. 242 * <LI> 243 * {@code object} 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} 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"}. 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 INCH} or 298 * {@link #MM MM}. 299 * @param unitsName 300 * Units name string, e.g. {@code "in"} or {@code "mm"}. 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 < 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]+","+vals[3]+")"; 314 return str + unitsName; 315 } 316 317 /** 318 * Returns a string version of this rectangular size attribute in mm. 319 */ 320 public String toString() { 321 return(toString(MM, "mm")); 322 } 323 324 /** 325 * Returns a hash code value for this attribute. 326 */ 327 public int hashCode() { 328 return x + 37*y + 43*w + 47*h; 329 } 330 331 private static float convertFromMicrometers(int x, int units) { 332 if (units < 1) { 333 throw new IllegalArgumentException("units is < 1"); 334 } 335 return ((float)x) / ((float)units); 336 } 337 }