1. /*
  2. * @(#)MediaPrintableArea.java 1.12 04/05/05
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.print.attribute.standard;
  8. import javax.print.attribute.Attribute;
  9. import javax.print.attribute.DocAttribute;
  10. import javax.print.attribute.PrintJobAttribute;
  11. import javax.print.attribute.PrintRequestAttribute;
  12. /**
  13. * Class MediaPrintableArea is a printing attribute used to distinguish
  14. * the printable and non-printable areas of media.
  15. * <p>
  16. * The printable area is specified to be a rectangle, within the overall
  17. * dimensions of a media.
  18. * <p>
  19. * Most printers cannot print on the entire surface of the media, due
  20. * to printer hardware limitations. This class can be used to query
  21. * the acceptable values for a supposed print job, and to request an area
  22. * within the constraints of the printable area to be used in a print job.
  23. * <p>
  24. * To query for the printable area, a client must supply a suitable context.
  25. * Without specifying at the very least the size of the media being used
  26. * no meaningful value for printable area can be obtained.
  27. * <p>
  28. * The attribute is not described in terms of the distance from the edge
  29. * of the paper, in part to emphasise that this attribute is not independent
  30. * of a particular media, but must be described within the context of a
  31. * choice of other attributes. Additionally it is usually more convenient
  32. * for a client to use the printable area.
  33. * <p>
  34. * The hardware's minimum margins is not just a property of the printer,
  35. * but may be a function of the media size, orientation, media type, and
  36. * any specified finishings.
  37. * <code>PrintService</code> provides the method to query the supported
  38. * values of an attribute in a suitable context :
  39. * See {@link javax.print.PrintService#getSupportedAttributeValues(Class,DocFlavor, AttributeSet) <code>PrintService.getSupportedAttributeValues()</code>}
  40. * <p>
  41. * The rectangular printable area is defined thus:
  42. * The (x,y) origin is positioned at the top-left of the paper in portrait
  43. * mode regardless of the orientation specified in the requesting context.
  44. * For example a printable area for A4 paper in portrait or landscape
  45. * orientation will have height > width.
  46. * <p>
  47. * A printable area attribute's values are stored
  48. * internally as integers in units of micrometers (µm), where 1 micrometer
  49. * = 10<SUP>-6</SUP> meter = 1/1000 millimeter = 1/25400 inch. This permits
  50. * dimensions to be represented exactly to a precision of 1/1000 mm (= 1
  51. * µm) or 1/100 inch (= 254 µm). If fractional inches are expressed in
  52. * negative powers of two, this permits dimensions to be represented exactly to
  53. * a precision of 1/8 inch (= 3175 µm) but not 1/16 inch (because 1/16 inch
  54. * does not equal an integral number of µm).
  55. * <p>
  56. * <B>IPP Compatibility:</B> MediaPrintableArea is not an IPP attribute.
  57. */
  58. public final class MediaPrintableArea
  59. implements DocAttribute, PrintRequestAttribute, PrintJobAttribute {
  60. private int x, y, w, h;
  61. private int units;
  62. private static final long serialVersionUID = -1597171464050795793L;
  63. /**
  64. * Value to indicate units of inches (in). It is actually the conversion
  65. * factor by which to multiply inches to yield µm (25400).
  66. */
  67. public static final int INCH = 25400;
  68. /**
  69. * Value to indicate units of millimeters (mm). It is actually the
  70. * conversion factor by which to multiply mm to yield µm (1000).
  71. */
  72. public static final int MM = 1000;
  73. /**
  74. * Constructs a MediaPrintableArea object from floating point values.
  75. * @param x printable x
  76. * @param y printable y
  77. * @param w printable width
  78. * @param h printable height
  79. * @param units in which the values are expressed.
  80. *
  81. * @exception IllegalArgumentException
  82. * Thrown if <CODE>x</CODE> < 0 or <CODE>y</CODE> < 0
  83. * or <CODE>w</CODE> <= 0 or <CODE>h</CODE> <= 0 or
  84. * <CODE>units</CODE> < 1.
  85. */
  86. public MediaPrintableArea(float x, float y, float w, float h, int units) {
  87. if ((x < 0.0) || (y < 0.0) || (w <= 0.0) || (h <= 0.0) ||
  88. (units < 1)) {
  89. throw new IllegalArgumentException("0 or negative value argument");
  90. }
  91. this.x = (int) (x * units + 0.5f);
  92. this.y = (int) (y * units + 0.5f);
  93. this.w = (int) (w * units + 0.5f);
  94. this.h = (int) (h * units + 0.5f);
  95. }
  96. /**
  97. * Constructs a MediaPrintableArea object from integer values.
  98. * @param x printable x
  99. * @param y printable y
  100. * @param w printable width
  101. * @param h printable height
  102. * @param units in which the values are expressed.
  103. *
  104. * @exception IllegalArgumentException
  105. * Thrown if <CODE>x</CODE> < 0 or <CODE>y</CODE> < 0
  106. * or <CODE>w</CODE> <= 0 or <CODE>h</CODE> <= 0 or
  107. * <CODE>units</CODE> < 1.
  108. */
  109. public MediaPrintableArea(int x, int y, int w, int h, int units) {
  110. if ((x < 0) || (y < 0) || (w <= 0) || (h <= 0) ||
  111. (units < 1)) {
  112. throw new IllegalArgumentException("0 or negative value argument");
  113. }
  114. this.x = x * units;
  115. this.y = y * units;
  116. this.w = w * units;
  117. this.h = h * units;
  118. }
  119. /**
  120. * Get the printable area as an array of 4 values in the order
  121. * x, y, w, h. The values returned are in the given units.
  122. * @param units
  123. * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
  124. * {@link #MM <CODE>MM</CODE>}.
  125. *
  126. * @return printable area as array of x, y, w, h in the specified units.
  127. *
  128. * @exception IllegalArgumentException
  129. * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
  130. */
  131. public float[] getPrintableArea(int units) {
  132. return new float[] { getX(units), getY(units),
  133. getWidth(units), getHeight(units) };
  134. }
  135. /**
  136. * Get the x location of the origin of the printable area in the
  137. * specified units.
  138. * @param units
  139. * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
  140. * {@link #MM <CODE>MM</CODE>}.
  141. *
  142. * @return x location of the origin of the printable area in the
  143. * specified units.
  144. *
  145. * @exception IllegalArgumentException
  146. * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
  147. */
  148. public float getX(int units) {
  149. return convertFromMicrometers(x, units);
  150. }
  151. /**
  152. * Get the y location of the origin of the printable area in the
  153. * specified units.
  154. * @param units
  155. * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
  156. * {@link #MM <CODE>MM</CODE>}.
  157. *
  158. * @return y location of the origin of the printable area in the
  159. * specified units.
  160. *
  161. * @exception IllegalArgumentException
  162. * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
  163. */
  164. public float getY(int units) {
  165. return convertFromMicrometers(y, units);
  166. }
  167. /**
  168. * Get the width of the printable area in the specified units.
  169. * @param units
  170. * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
  171. * {@link #MM <CODE>MM</CODE>}.
  172. *
  173. * @return width of the printable area in the specified units.
  174. *
  175. * @exception IllegalArgumentException
  176. * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
  177. */
  178. public float getWidth(int units) {
  179. return convertFromMicrometers(w, units);
  180. }
  181. /**
  182. * Get the height of the printable area in the specified units.
  183. * @param units
  184. * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
  185. * {@link #MM <CODE>MM</CODE>}.
  186. *
  187. * @return height of the printable area in the specified units.
  188. *
  189. * @exception IllegalArgumentException
  190. * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
  191. */
  192. public float getHeight(int units) {
  193. return convertFromMicrometers(h, units);
  194. }
  195. /**
  196. * Returns whether this media margins attribute is equivalent to the passed
  197. * in object.
  198. * To be equivalent, all of the following conditions must be true:
  199. * <OL TYPE=1>
  200. * <LI>
  201. * <CODE>object</CODE> is not null.
  202. * <LI>
  203. * <CODE>object</CODE> is an instance of class MediaPrintableArea.
  204. * <LI>
  205. * The origin and dimensions are the same.
  206. * </OL>
  207. *
  208. * @param object Object to compare to.
  209. *
  210. * @return True if <CODE>object</CODE> is equivalent to this media margins
  211. * attribute, false otherwise.
  212. */
  213. public boolean equals(Object object) {
  214. boolean ret = false;
  215. if (object instanceof MediaPrintableArea) {
  216. MediaPrintableArea mm = (MediaPrintableArea)object;
  217. if (x == mm.x && y == mm.y && w == mm.w && h == mm.h) {
  218. ret = true;
  219. }
  220. }
  221. return ret;
  222. }
  223. /**
  224. * Get the printing attribute class which is to be used as the "category"
  225. * for this printing attribute value.
  226. * <P>
  227. * For class MediaPrintableArea, the category is
  228. * class MediaPrintableArea itself.
  229. *
  230. * @return Printing attribute class (category), an instance of class
  231. * {@link java.lang.Class java.lang.Class}.
  232. */
  233. public final Class<? extends Attribute> getCategory() {
  234. return MediaPrintableArea.class;
  235. }
  236. /**
  237. * Get the name of the category of which this attribute value is an
  238. * instance.
  239. * <P>
  240. * For class MediaPrintableArea,
  241. * the category name is <CODE>"media-printable-area"</CODE>.
  242. * <p>This is not an IPP V1.1 attribute.
  243. *
  244. * @return Attribute category name.
  245. */
  246. public final String getName() {
  247. return "media-printable-area";
  248. }
  249. /**
  250. * Returns a string version of this rectangular size attribute in the
  251. * given units.
  252. *
  253. * @param units
  254. * Unit conversion factor, e.g. {@link #INCH <CODE>INCH</CODE>} or
  255. * {@link #MM <CODE>MM</CODE>}.
  256. * @param unitsName
  257. * Units name string, e.g. <CODE>"in"</CODE> or <CODE>"mm"</CODE>. If
  258. * null, no units name is appended to the result.
  259. *
  260. * @return String version of this two-dimensional size attribute.
  261. *
  262. * @exception IllegalArgumentException
  263. * (unchecked exception) Thrown if <CODE>units</CODE> < 1.
  264. */
  265. public String toString(int units, String unitsName) {
  266. if (unitsName == null) {
  267. unitsName = "";
  268. }
  269. float []vals = getPrintableArea(units);
  270. String str = "("+vals[0]+","+vals[1]+")->("+vals[2]+","+vals[3]+")";
  271. return str + unitsName;
  272. }
  273. /**
  274. * Returns a string version of this rectangular size attribute in mm.
  275. */
  276. public String toString() {
  277. return(toString(MM, "mm"));
  278. }
  279. /**
  280. * Returns a hash code value for this attribute.
  281. */
  282. public int hashCode() {
  283. return x + 37*y + 43*w + 47*h;
  284. }
  285. private static float convertFromMicrometers(int x, int units) {
  286. if (units < 1) {
  287. throw new IllegalArgumentException("units is < 1");
  288. }
  289. return ((float)x) / ((float)units);
  290. }
  291. }