1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.print; 18 19 import android.content.pm.PackageManager; 20 import android.content.pm.PackageManager.NameNotFoundException; 21 import android.content.res.Resources.NotFoundException; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.text.TextUtils; 25 import android.util.ArrayMap; 26 import android.util.Log; 27 28 import com.android.internal.R; 29 30 import java.util.Map; 31 32 /** 33 * This class represents the attributes of a print job. These attributes 34 * describe how the printed content should be laid out. For example, the 35 * print attributes may state that the content should be laid out on a 36 * letter size with 300 DPI (dots per inch) resolution, have a margin of 37 * 10 mills (thousand of an inch) on all sides, and be black and white. 38 */ 39 public final class PrintAttributes implements Parcelable { 40 /** Color mode: Monochrome color scheme, for example one color is used. */ 41 public static final int COLOR_MODE_MONOCHROME = 1 << 0; 42 /** Color mode: Color color scheme, for example many colors are used. */ 43 public static final int COLOR_MODE_COLOR = 1 << 1; 44 45 private static final int VALID_COLOR_MODES = 46 COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR; 47 48 /** Duplex mode: No duplexing. */ 49 public static final int DUPLEX_MODE_NONE = 1 << 0; 50 /** Duplex mode: Pages are turned sideways along the long edge - like a book. */ 51 public static final int DUPLEX_MODE_LONG_EDGE = 1 << 1; 52 /** Duplex mode: Pages are turned upwards along the short edge - like a notpad. */ 53 public static final int DUPLEX_MODE_SHORT_EDGE = 1 << 2; 54 55 private static final int VALID_DUPLEX_MODES = 56 DUPLEX_MODE_NONE | DUPLEX_MODE_LONG_EDGE | DUPLEX_MODE_SHORT_EDGE; 57 58 private MediaSize mMediaSize; 59 private Resolution mResolution; 60 private Margins mMinMargins; 61 62 private int mColorMode; 63 private int mDuplexMode = DUPLEX_MODE_NONE; 64 PrintAttributes()65 PrintAttributes() { 66 /* hide constructor */ 67 } 68 PrintAttributes(Parcel parcel)69 private PrintAttributes(Parcel parcel) { 70 mMediaSize = (parcel.readInt() == 1) ? MediaSize.createFromParcel(parcel) : null; 71 mResolution = (parcel.readInt() == 1) ? Resolution.createFromParcel(parcel) : null; 72 mMinMargins = (parcel.readInt() == 1) ? Margins.createFromParcel(parcel) : null; 73 mColorMode = parcel.readInt(); 74 mDuplexMode = parcel.readInt(); 75 } 76 77 /** 78 * Gets the media size. 79 * 80 * @return The media size or <code>null</code> if not set. 81 */ getMediaSize()82 public MediaSize getMediaSize() { 83 return mMediaSize; 84 } 85 86 /** 87 * Sets the media size. 88 * 89 * @param mediaSize The media size. 90 * 91 * @hide 92 */ setMediaSize(MediaSize mediaSize)93 public void setMediaSize(MediaSize mediaSize) { 94 mMediaSize = mediaSize; 95 } 96 97 /** 98 * Gets the resolution. 99 * 100 * @return The resolution or <code>null</code> if not set. 101 */ getResolution()102 public Resolution getResolution() { 103 return mResolution; 104 } 105 106 /** 107 * Sets the resolution. 108 * 109 * @param resolution The resolution. 110 * 111 * @hide 112 */ setResolution(Resolution resolution)113 public void setResolution(Resolution resolution) { 114 mResolution = resolution; 115 } 116 117 /** 118 * Gets the minimal margins. If the content does not fit 119 * these margins it will be clipped. 120 * <p> 121 * <strong>These margins are physically imposed by the printer and they 122 * are <em>not</em> rotated, i.e. they are the same for both portrait and 123 * landscape. For example, a printer may not be able to print in a stripe 124 * on both left and right sides of the page. 125 * </strong> 126 * </p> 127 * 128 * @return The margins or <code>null</code> if not set. 129 */ getMinMargins()130 public Margins getMinMargins() { 131 return mMinMargins; 132 } 133 134 /** 135 * Sets the minimal margins. If the content does not fit 136 * these margins it will be clipped. 137 * <p> 138 * <strong>These margins are physically imposed by the printer and they 139 * are <em>not</em> rotated, i.e. they are the same for both portrait and 140 * landscape. For example, a printer may not be able to print in a stripe 141 * on both left and right sides of the page. 142 * </strong> 143 * </p> 144 * 145 * @param margins The margins. 146 * 147 * @hide 148 */ setMinMargins(Margins margins)149 public void setMinMargins(Margins margins) { 150 mMinMargins = margins; 151 } 152 153 /** 154 * Gets the color mode. 155 * 156 * @return The color mode or zero if not set. 157 * 158 * @see #COLOR_MODE_COLOR 159 * @see #COLOR_MODE_MONOCHROME 160 */ getColorMode()161 public int getColorMode() { 162 return mColorMode; 163 } 164 165 /** 166 * Sets the color mode. 167 * 168 * @param colorMode The color mode. 169 * 170 * @see #COLOR_MODE_MONOCHROME 171 * @see #COLOR_MODE_COLOR 172 * 173 * @hide 174 */ setColorMode(int colorMode)175 public void setColorMode(int colorMode) { 176 enforceValidColorMode(colorMode); 177 mColorMode = colorMode; 178 } 179 180 /** 181 * Gets whether this print attributes are in portrait orientation, 182 * which is the media size is in portrait and all orientation dependent 183 * attributes such as resolution and margins are properly adjusted. 184 * 185 * @return Whether this print attributes are in portrait. 186 * 187 * @hide 188 */ isPortrait()189 public boolean isPortrait() { 190 return mMediaSize.isPortrait(); 191 } 192 193 /** 194 * Gets the duplex mode. 195 * 196 * @return The duplex mode. 197 * 198 * @see #DUPLEX_MODE_NONE 199 * @see #DUPLEX_MODE_LONG_EDGE 200 * @see #DUPLEX_MODE_SHORT_EDGE 201 */ getDuplexMode()202 public int getDuplexMode() { 203 return mDuplexMode; 204 } 205 206 /** 207 * Sets the duplex mode. 208 * 209 * @param duplexMode The duplex mode. 210 * 211 * @see #DUPLEX_MODE_NONE 212 * @see #DUPLEX_MODE_LONG_EDGE 213 * @see #DUPLEX_MODE_SHORT_EDGE 214 * 215 * @hide 216 */ setDuplexMode(int duplexMode)217 public void setDuplexMode(int duplexMode) { 218 enforceValidDuplexMode(duplexMode); 219 mDuplexMode = duplexMode; 220 } 221 222 /** 223 * Gets a new print attributes instance which is in portrait orientation, 224 * which is the media size is in portrait and all orientation dependent 225 * attributes such as resolution and margins are properly adjusted. 226 * 227 * @return New instance in portrait orientation if this one is in 228 * landscape, otherwise this instance. 229 * 230 * @hide 231 */ asPortrait()232 public PrintAttributes asPortrait() { 233 if (isPortrait()) { 234 return this; 235 } 236 237 PrintAttributes attributes = new PrintAttributes(); 238 239 // Rotate the media size. 240 attributes.setMediaSize(getMediaSize().asPortrait()); 241 242 // Rotate the resolution. 243 Resolution oldResolution = getResolution(); 244 Resolution newResolution = new Resolution( 245 oldResolution.getId(), 246 oldResolution.getLabel(), 247 oldResolution.getVerticalDpi(), 248 oldResolution.getHorizontalDpi()); 249 attributes.setResolution(newResolution); 250 251 // Do not rotate the physical margins. 252 attributes.setMinMargins(getMinMargins()); 253 254 attributes.setColorMode(getColorMode()); 255 attributes.setDuplexMode(getDuplexMode()); 256 257 return attributes; 258 } 259 260 /** 261 * Gets a new print attributes instance which is in landscape orientation, 262 * which is the media size is in landscape and all orientation dependent 263 * attributes such as resolution and margins are properly adjusted. 264 * 265 * @return New instance in landscape orientation if this one is in 266 * portrait, otherwise this instance. 267 * 268 * @hide 269 */ asLandscape()270 public PrintAttributes asLandscape() { 271 if (!isPortrait()) { 272 return this; 273 } 274 275 PrintAttributes attributes = new PrintAttributes(); 276 277 // Rotate the media size. 278 attributes.setMediaSize(getMediaSize().asLandscape()); 279 280 // Rotate the resolution. 281 Resolution oldResolution = getResolution(); 282 Resolution newResolution = new Resolution( 283 oldResolution.getId(), 284 oldResolution.getLabel(), 285 oldResolution.getVerticalDpi(), 286 oldResolution.getHorizontalDpi()); 287 attributes.setResolution(newResolution); 288 289 // Do not rotate the physical margins. 290 attributes.setMinMargins(getMinMargins()); 291 292 attributes.setColorMode(getColorMode()); 293 attributes.setDuplexMode(getDuplexMode()); 294 295 return attributes; 296 } 297 298 @Override writeToParcel(Parcel parcel, int flags)299 public void writeToParcel(Parcel parcel, int flags) { 300 if (mMediaSize != null) { 301 parcel.writeInt(1); 302 mMediaSize.writeToParcel(parcel); 303 } else { 304 parcel.writeInt(0); 305 } 306 if (mResolution != null) { 307 parcel.writeInt(1); 308 mResolution.writeToParcel(parcel); 309 } else { 310 parcel.writeInt(0); 311 } 312 if (mMinMargins != null) { 313 parcel.writeInt(1); 314 mMinMargins.writeToParcel(parcel); 315 } else { 316 parcel.writeInt(0); 317 } 318 parcel.writeInt(mColorMode); 319 parcel.writeInt(mDuplexMode); 320 } 321 322 @Override describeContents()323 public int describeContents() { 324 return 0; 325 } 326 327 @Override hashCode()328 public int hashCode() { 329 final int prime = 31; 330 int result = 1; 331 result = prime * result + mColorMode; 332 result = prime * result + mDuplexMode; 333 result = prime * result + ((mMinMargins == null) ? 0 : mMinMargins.hashCode()); 334 result = prime * result + ((mMediaSize == null) ? 0 : mMediaSize.hashCode()); 335 result = prime * result + ((mResolution == null) ? 0 : mResolution.hashCode()); 336 return result; 337 } 338 339 @Override equals(Object obj)340 public boolean equals(Object obj) { 341 if (this == obj) { 342 return true; 343 } 344 if (obj == null) { 345 return false; 346 } 347 if (getClass() != obj.getClass()) { 348 return false; 349 } 350 PrintAttributes other = (PrintAttributes) obj; 351 if (mColorMode != other.mColorMode) { 352 return false; 353 } 354 if (mDuplexMode != other.mDuplexMode) { 355 return false; 356 } 357 if (mMinMargins == null) { 358 if (other.mMinMargins != null) { 359 return false; 360 } 361 } else if (!mMinMargins.equals(other.mMinMargins)) { 362 return false; 363 } 364 if (mMediaSize == null) { 365 if (other.mMediaSize != null) { 366 return false; 367 } 368 } else if (!mMediaSize.equals(other.mMediaSize)) { 369 return false; 370 } 371 if (mResolution == null) { 372 if (other.mResolution != null) { 373 return false; 374 } 375 } else if (!mResolution.equals(other.mResolution)) { 376 return false; 377 } 378 return true; 379 } 380 381 @Override toString()382 public String toString() { 383 StringBuilder builder = new StringBuilder(); 384 builder.append("PrintAttributes{"); 385 builder.append("mediaSize: ").append(mMediaSize); 386 if (mMediaSize != null) { 387 builder.append(", orientation: ").append(mMediaSize.isPortrait() 388 ? "portrait" : "landscape"); 389 } else { 390 builder.append(", orientation: ").append("null"); 391 } 392 builder.append(", resolution: ").append(mResolution); 393 builder.append(", minMargins: ").append(mMinMargins); 394 builder.append(", colorMode: ").append(colorModeToString(mColorMode)); 395 builder.append(", duplexMode: ").append(duplexModeToString(mDuplexMode)); 396 builder.append("}"); 397 return builder.toString(); 398 } 399 400 /** @hide */ clear()401 public void clear() { 402 mMediaSize = null; 403 mResolution = null; 404 mMinMargins = null; 405 mColorMode = 0; 406 mDuplexMode = DUPLEX_MODE_NONE; 407 } 408 409 /** 410 * @hide 411 */ copyFrom(PrintAttributes other)412 public void copyFrom(PrintAttributes other) { 413 mMediaSize = other.mMediaSize; 414 mResolution = other.mResolution; 415 mMinMargins = other.mMinMargins; 416 mColorMode = other.mColorMode; 417 mDuplexMode = other.mDuplexMode; 418 } 419 420 /** 421 * This class specifies a supported media size. Media size is the 422 * dimension of the media on which the content is printed. For 423 * example, the {@link #NA_LETTER} media size designates a page 424 * with size 8.5" x 11". 425 */ 426 public static final class MediaSize { 427 private static final String LOG_TAG = "MediaSize"; 428 429 private static final Map<String, MediaSize> sIdToMediaSizeMap = 430 new ArrayMap<String, MediaSize>(); 431 432 /** 433 * Unknown media size in portrait mode. 434 * <p> 435 * <strong>Note: </strong>This is for specifying orientation without media 436 * size. You should not use the dimensions reported by this instance. 437 * </p> 438 */ 439 public static final MediaSize UNKNOWN_PORTRAIT = 440 new MediaSize("UNKNOWN_PORTRAIT", "android", 441 R.string.mediasize_unknown_portrait, 1, Integer.MAX_VALUE); 442 443 /** 444 * Unknown media size in landscape mode. 445 * <p> 446 * <strong>Note: </strong>This is for specifying orientation without media 447 * size. You should not use the dimensions reported by this instance. 448 * </p> 449 */ 450 public static final MediaSize UNKNOWN_LANDSCAPE = 451 new MediaSize("UNKNOWN_LANDSCAPE", "android", 452 R.string.mediasize_unknown_landscape, Integer.MAX_VALUE, 1); 453 454 // ISO sizes 455 456 /** ISO A0 media size: 841mm x 1189mm (33.11" x 46.81") */ 457 public static final MediaSize ISO_A0 = 458 new MediaSize("ISO_A0", "android", R.string.mediasize_iso_a0, 33110, 46810); 459 /** ISO A1 media size: 594mm x 841mm (23.39" x 33.11") */ 460 public static final MediaSize ISO_A1 = 461 new MediaSize("ISO_A1", "android", R.string.mediasize_iso_a1, 23390, 33110); 462 /** ISO A2 media size: 420mm x 594mm (16.54" x 23.39") */ 463 public static final MediaSize ISO_A2 = 464 new MediaSize("ISO_A2", "android", R.string.mediasize_iso_a2, 16540, 23390); 465 /** ISO A3 media size: 297mm x 420mm (11.69" x 16.54") */ 466 public static final MediaSize ISO_A3 = 467 new MediaSize("ISO_A3", "android", R.string.mediasize_iso_a3, 11690, 16540); 468 /** ISO A4 media size: 210mm x 297mm (8.27" x 11.69") */ 469 public static final MediaSize ISO_A4 = 470 new MediaSize("ISO_A4", "android", R.string.mediasize_iso_a4, 8270, 11690); 471 /** ISO A5 media size: 148mm x 210mm (5.83" x 8.27") */ 472 public static final MediaSize ISO_A5 = 473 new MediaSize("ISO_A5", "android", R.string.mediasize_iso_a5, 5830, 8270); 474 /** ISO A6 media size: 105mm x 148mm (4.13" x 5.83") */ 475 public static final MediaSize ISO_A6 = 476 new MediaSize("ISO_A6", "android", R.string.mediasize_iso_a6, 4130, 5830); 477 /** ISO A7 media size: 74mm x 105mm (2.91" x 4.13") */ 478 public static final MediaSize ISO_A7 = 479 new MediaSize("ISO_A7", "android", R.string.mediasize_iso_a7, 2910, 4130); 480 /** ISO A8 media size: 52mm x 74mm (2.05" x 2.91") */ 481 public static final MediaSize ISO_A8 = 482 new MediaSize("ISO_A8", "android", R.string.mediasize_iso_a8, 2050, 2910); 483 /** ISO A9 media size: 37mm x 52mm (1.46" x 2.05") */ 484 public static final MediaSize ISO_A9 = 485 new MediaSize("ISO_A9", "android", R.string.mediasize_iso_a9, 1460, 2050); 486 /** ISO A10 media size: 26mm x 37mm (1.02" x 1.46") */ 487 public static final MediaSize ISO_A10 = 488 new MediaSize("ISO_A10", "android", R.string.mediasize_iso_a10, 1020, 1460); 489 490 /** ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67") */ 491 public static final MediaSize ISO_B0 = 492 new MediaSize("ISO_B0", "android", R.string.mediasize_iso_b0, 39370, 55670); 493 /** ISO B1 media size: 707mm x 1000mm (27.83" x 39.37") */ 494 public static final MediaSize ISO_B1 = 495 new MediaSize("ISO_B1", "android", R.string.mediasize_iso_b1, 27830, 39370); 496 /** ISO B2 media size: 500mm x 707mm (19.69" x 27.83") */ 497 public static final MediaSize ISO_B2 = 498 new MediaSize("ISO_B2", "android", R.string.mediasize_iso_b2, 19690, 27830); 499 /** ISO B3 media size: 353mm x 500mm (13.90" x 19.69") */ 500 public static final MediaSize ISO_B3 = 501 new MediaSize("ISO_B3", "android", R.string.mediasize_iso_b3, 13900, 19690); 502 /** ISO B4 media size: 250mm x 353mm (9.84" x 13.90") */ 503 public static final MediaSize ISO_B4 = 504 new MediaSize("ISO_B4", "android", R.string.mediasize_iso_b4, 9840, 13900); 505 /** ISO B5 media size: 176mm x 250mm (6.93" x 9.84") */ 506 public static final MediaSize ISO_B5 = 507 new MediaSize("ISO_B5", "android", R.string.mediasize_iso_b5, 6930, 9840); 508 /** ISO B6 media size: 125mm x 176mm (4.92" x 6.93") */ 509 public static final MediaSize ISO_B6 = 510 new MediaSize("ISO_B6", "android", R.string.mediasize_iso_b6, 4920, 6930); 511 /** ISO B7 media size: 88mm x 125mm (3.46" x 4.92") */ 512 public static final MediaSize ISO_B7 = 513 new MediaSize("ISO_B7", "android", R.string.mediasize_iso_b7, 3460, 4920); 514 /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46") */ 515 public static final MediaSize ISO_B8 = 516 new MediaSize("ISO_B8", "android", R.string.mediasize_iso_b8, 2440, 3460); 517 /** ISO B9 media size: 44mm x 62mm (1.73" x 2.44") */ 518 public static final MediaSize ISO_B9 = 519 new MediaSize("ISO_B9", "android", R.string.mediasize_iso_b9, 1730, 2440); 520 /** ISO B10 media size: 31mm x 44mm (1.22" x 1.73") */ 521 public static final MediaSize ISO_B10 = 522 new MediaSize("ISO_B10", "android", R.string.mediasize_iso_b10, 1220, 1730); 523 524 /** ISO C0 media size: 917mm x 1297mm (36.10" x 51.06") */ 525 public static final MediaSize ISO_C0 = 526 new MediaSize("ISO_C0", "android", R.string.mediasize_iso_c0, 36100, 51060); 527 /** ISO C1 media size: 648mm x 917mm (25.51" x 36.10") */ 528 public static final MediaSize ISO_C1 = 529 new MediaSize("ISO_C1", "android", R.string.mediasize_iso_c1, 25510, 36100); 530 /** ISO C2 media size: 458mm x 648mm (18.03" x 25.51") */ 531 public static final MediaSize ISO_C2 = 532 new MediaSize("ISO_C2", "android", R.string.mediasize_iso_c2, 18030, 25510); 533 /** ISO C3 media size: 324mm x 458mm (12.76" x 18.03") */ 534 public static final MediaSize ISO_C3 = 535 new MediaSize("ISO_C3", "android", R.string.mediasize_iso_c3, 12760, 18030); 536 /** ISO C4 media size: 229mm x 324mm (9.02" x 12.76") */ 537 public static final MediaSize ISO_C4 = 538 new MediaSize("ISO_C4", "android", R.string.mediasize_iso_c4, 9020, 12760); 539 /** ISO C5 media size: 162mm x 229mm (6.38" x 9.02") */ 540 public static final MediaSize ISO_C5 = 541 new MediaSize("ISO_C5", "android", R.string.mediasize_iso_c5, 6380, 9020); 542 /** ISO C6 media size: 114mm x 162mm (4.49" x 6.38") */ 543 public static final MediaSize ISO_C6 = 544 new MediaSize("ISO_C6", "android", R.string.mediasize_iso_c6, 4490, 6380); 545 /** ISO C7 media size: 81mm x 114mm (3.19" x 4.49") */ 546 public static final MediaSize ISO_C7 = 547 new MediaSize("ISO_C7", "android", R.string.mediasize_iso_c7, 3190, 4490); 548 /** ISO C8 media size: 57mm x 81mm (2.24" x 3.19") */ 549 public static final MediaSize ISO_C8 = 550 new MediaSize("ISO_C8", "android", R.string.mediasize_iso_c8, 2240, 3190); 551 /** ISO C9 media size: 40mm x 57mm (1.57" x 2.24") */ 552 public static final MediaSize ISO_C9 = 553 new MediaSize("ISO_C9", "android", R.string.mediasize_iso_c9, 1570, 2240); 554 /** ISO C10 media size: 28mm x 40mm (1.10" x 1.57") */ 555 public static final MediaSize ISO_C10 = 556 new MediaSize("ISO_C10", "android", R.string.mediasize_iso_c10, 1100, 1570); 557 558 // North America 559 560 /** North America Letter media size: 8.5" x 11" (279mm x 216mm) */ 561 public static final MediaSize NA_LETTER = 562 new MediaSize("NA_LETTER", "android", R.string.mediasize_na_letter, 8500, 11000); 563 /** North America Government-Letter media size: 8.0" x 10.5" (203mm x 267mm) */ 564 public static final MediaSize NA_GOVT_LETTER = 565 new MediaSize("NA_GOVT_LETTER", "android", 566 R.string.mediasize_na_gvrnmt_letter, 8000, 10500); 567 /** North America Legal media size: 8.5" x 14" (216mm x 356mm) */ 568 public static final MediaSize NA_LEGAL = 569 new MediaSize("NA_LEGAL", "android", R.string.mediasize_na_legal, 8500, 14000); 570 /** North America Junior Legal media size: 8.0" x 5.0" (203mm × 127mm) */ 571 public static final MediaSize NA_JUNIOR_LEGAL = 572 new MediaSize("NA_JUNIOR_LEGAL", "android", 573 R.string.mediasize_na_junior_legal, 8000, 5000); 574 /** North America Ledger media size: 17" x 11" (432mm × 279mm) */ 575 public static final MediaSize NA_LEDGER = 576 new MediaSize("NA_LEDGER", "android", R.string.mediasize_na_ledger, 17000, 11000); 577 /** North America Tabloid media size: 11" x 17" (279mm × 432mm) */ 578 public static final MediaSize NA_TABLOID = 579 new MediaSize("NA_TABLOID", "android", 580 R.string.mediasize_na_tabloid, 11000, 17000); 581 /** North America Index Card 3x5 media size: 3" x 5" (76mm x 127mm) */ 582 public static final MediaSize NA_INDEX_3X5 = 583 new MediaSize("NA_INDEX_3X5", "android", 584 R.string.mediasize_na_index_3x5, 3000, 5000); 585 /** North America Index Card 4x6 media size: 4" x 6" (102mm x 152mm) */ 586 public static final MediaSize NA_INDEX_4X6 = 587 new MediaSize("NA_INDEX_4X6", "android", 588 R.string.mediasize_na_index_4x6, 4000, 6000); 589 /** North America Index Card 5x8 media size: 5" x 8" (127mm x 203mm) */ 590 public static final MediaSize NA_INDEX_5X8 = 591 new MediaSize("NA_INDEX_5X8", "android", 592 R.string.mediasize_na_index_5x8, 5000, 8000); 593 /** North America Monarch media size: 7.25" x 10.5" (184mm x 267mm) */ 594 public static final MediaSize NA_MONARCH = 595 new MediaSize("NA_MONARCH", "android", 596 R.string.mediasize_na_monarch, 7250, 10500); 597 /** North America Quarto media size: 8" x 10" (203mm x 254mm) */ 598 public static final MediaSize NA_QUARTO = 599 new MediaSize("NA_QUARTO", "android", 600 R.string.mediasize_na_quarto, 8000, 10000); 601 /** North America Foolscap media size: 8" x 13" (203mm x 330mm) */ 602 public static final MediaSize NA_FOOLSCAP = 603 new MediaSize("NA_FOOLSCAP", "android", 604 R.string.mediasize_na_foolscap, 8000, 13000); 605 606 // Chinese 607 608 /** Chinese ROC 8K media size: 270mm x 390mm (10.629" x 15.3543") */ 609 public static final MediaSize ROC_8K = 610 new MediaSize("ROC_8K", "android", 611 R.string.mediasize_chinese_roc_8k, 10629, 15354); 612 /** Chinese ROC 16K media size: 195mm x 270mm (7.677" x 10.629") */ 613 public static final MediaSize ROC_16K = 614 new MediaSize("ROC_16K", "android", 615 R.string.mediasize_chinese_roc_16k, 7677, 10629); 616 617 /** Chinese PRC 1 media size: 102mm x 165mm (4.015" x 6.496") */ 618 public static final MediaSize PRC_1 = 619 new MediaSize("PRC_1", "android", 620 R.string.mediasize_chinese_prc_1, 4015, 6496); 621 /** Chinese PRC 2 media size: 102mm x 176mm (4.015" x 6.929") */ 622 public static final MediaSize PRC_2 = 623 new MediaSize("PRC_2", "android", 624 R.string.mediasize_chinese_prc_2, 4015, 6929); 625 /** Chinese PRC 3 media size: 125mm x 176mm (4.921" x 6.929") */ 626 public static final MediaSize PRC_3 = 627 new MediaSize("PRC_3", "android", 628 R.string.mediasize_chinese_prc_3, 4921, 6929); 629 /** Chinese PRC 4 media size: 110mm x 208mm (4.330" x 8.189") */ 630 public static final MediaSize PRC_4 = 631 new MediaSize("PRC_4", "android", 632 R.string.mediasize_chinese_prc_4, 4330, 8189); 633 /** Chinese PRC 5 media size: 110mm x 220mm (4.330" x 8.661") */ 634 public static final MediaSize PRC_5 = 635 new MediaSize("PRC_5", "android", 636 R.string.mediasize_chinese_prc_5, 4330, 8661); 637 /** Chinese PRC 6 media size: 120mm x 320mm (4.724" x 12.599") */ 638 public static final MediaSize PRC_6 = 639 new MediaSize("PRC_6", "android", 640 R.string.mediasize_chinese_prc_6, 4724, 12599); 641 /** Chinese PRC 7 media size: 160mm x 230mm (6.299" x 9.055") */ 642 public static final MediaSize PRC_7 = 643 new MediaSize("PRC_7", "android", 644 R.string.mediasize_chinese_prc_7, 6299, 9055); 645 /** Chinese PRC 8 media size: 120mm x 309mm (4.724" x 12.165") */ 646 public static final MediaSize PRC_8 = 647 new MediaSize("PRC_8", "android", 648 R.string.mediasize_chinese_prc_8, 4724, 12165); 649 /** Chinese PRC 9 media size: 229mm x 324mm (9.016" x 12.756") */ 650 public static final MediaSize PRC_9 = 651 new MediaSize("PRC_9", "android", 652 R.string.mediasize_chinese_prc_9, 9016, 12756); 653 /** Chinese PRC 10 media size: 324mm x 458mm (12.756" x 18.032") */ 654 public static final MediaSize PRC_10 = 655 new MediaSize("PRC_10", "android", 656 R.string.mediasize_chinese_prc_10, 12756, 18032); 657 658 /** Chinese PRC 16k media size: 146mm x 215mm (5.749" x 8.465") */ 659 public static final MediaSize PRC_16K = 660 new MediaSize("PRC_16K", "android", 661 R.string.mediasize_chinese_prc_16k, 5749, 8465); 662 /** Chinese Pa Kai media size: 267mm x 389mm (10.512" x 15.315") */ 663 public static final MediaSize OM_PA_KAI = 664 new MediaSize("OM_PA_KAI", "android", 665 R.string.mediasize_chinese_om_pa_kai, 10512, 15315); 666 /** Chinese Dai Pa Kai media size: 275mm x 395mm (10.827" x 15.551") */ 667 public static final MediaSize OM_DAI_PA_KAI = 668 new MediaSize("OM_DAI_PA_KAI", "android", 669 R.string.mediasize_chinese_om_dai_pa_kai, 10827, 15551); 670 /** Chinese Jurro Ku Kai media size: 198mm x 275mm (7.796" x 10.827") */ 671 public static final MediaSize OM_JUURO_KU_KAI = 672 new MediaSize("OM_JUURO_KU_KAI", "android", 673 R.string.mediasize_chinese_om_jurro_ku_kai, 7796, 10827); 674 675 // Japanese 676 677 /** Japanese JIS B10 media size: 32mm x 45mm (1.259" x 1.772") */ 678 public static final MediaSize JIS_B10 = 679 new MediaSize("JIS_B10", "android", 680 R.string.mediasize_japanese_jis_b10, 1259, 1772); 681 /** Japanese JIS B9 media size: 45mm x 64mm (1.772" x 2.52") */ 682 public static final MediaSize JIS_B9 = 683 new MediaSize("JIS_B9", "android", 684 R.string.mediasize_japanese_jis_b9, 1772, 2520); 685 /** Japanese JIS B8 media size: 64mm x 91mm (2.52" x 3.583") */ 686 public static final MediaSize JIS_B8 = 687 new MediaSize("JIS_B8", "android", 688 R.string.mediasize_japanese_jis_b8, 2520, 3583); 689 /** Japanese JIS B7 media size: 91mm x 128mm (3.583" x 5.049") */ 690 public static final MediaSize JIS_B7 = 691 new MediaSize("JIS_B7", "android", 692 R.string.mediasize_japanese_jis_b7, 3583, 5049); 693 /** Japanese JIS B6 media size: 128mm x 182mm (5.049" x 7.165") */ 694 public static final MediaSize JIS_B6 = 695 new MediaSize("JIS_B6", "android", 696 R.string.mediasize_japanese_jis_b6, 5049, 7165); 697 /** Japanese JIS B5 media size: 182mm x 257mm (7.165" x 10.118") */ 698 public static final MediaSize JIS_B5 = 699 new MediaSize("JIS_B5", "android", 700 R.string.mediasize_japanese_jis_b5, 7165, 10118); 701 /** Japanese JIS B4 media size: 257mm x 364mm (10.118" x 14.331") */ 702 public static final MediaSize JIS_B4 = 703 new MediaSize("JIS_B4", "android", 704 R.string.mediasize_japanese_jis_b4, 10118, 14331); 705 /** Japanese JIS B3 media size: 364mm x 515mm (14.331" x 20.276") */ 706 public static final MediaSize JIS_B3 = 707 new MediaSize("JIS_B3", "android", 708 R.string.mediasize_japanese_jis_b3, 14331, 20276); 709 /** Japanese JIS B2 media size: 515mm x 728mm (20.276" x 28.661") */ 710 public static final MediaSize JIS_B2 = 711 new MediaSize("JIS_B2", "android", 712 R.string.mediasize_japanese_jis_b2, 20276, 28661); 713 /** Japanese JIS B1 media size: 728mm x 1030mm (28.661" x 40.551") */ 714 public static final MediaSize JIS_B1 = 715 new MediaSize("JIS_B1", "android", 716 R.string.mediasize_japanese_jis_b1, 28661, 40551); 717 /** Japanese JIS B0 media size: 1030mm x 1456mm (40.551" x 57.323") */ 718 public static final MediaSize JIS_B0 = 719 new MediaSize("JIS_B0", "android", 720 R.string.mediasize_japanese_jis_b0, 40551, 57323); 721 722 /** Japanese JIS Exec media size: 216mm x 330mm (8.504" x 12.992") */ 723 public static final MediaSize JIS_EXEC = 724 new MediaSize("JIS_EXEC", "android", 725 R.string.mediasize_japanese_jis_exec, 8504, 12992); 726 727 /** Japanese Chou4 media size: 90mm x 205mm (3.543" x 8.071") */ 728 public static final MediaSize JPN_CHOU4 = 729 new MediaSize("JPN_CHOU4", "android", 730 R.string.mediasize_japanese_chou4, 3543, 8071); 731 /** Japanese Chou3 media size: 120mm x 235mm (4.724" x 9.252") */ 732 public static final MediaSize JPN_CHOU3 = 733 new MediaSize("JPN_CHOU3", "android", 734 R.string.mediasize_japanese_chou3, 4724, 9252); 735 /** Japanese Chou2 media size: 111.1mm x 146mm (4.374" x 5.748") */ 736 public static final MediaSize JPN_CHOU2 = 737 new MediaSize("JPN_CHOU2", "android", 738 R.string.mediasize_japanese_chou2, 4374, 5748); 739 740 /** Japanese Hagaki media size: 100mm x 148mm (3.937" x 5.827") */ 741 public static final MediaSize JPN_HAGAKI = 742 new MediaSize("JPN_HAGAKI", "android", 743 R.string.mediasize_japanese_hagaki, 3937, 5827); 744 /** Japanese Oufuku media size: 148mm x 200mm (5.827" x 7.874") */ 745 public static final MediaSize JPN_OUFUKU = 746 new MediaSize("JPN_OUFUKU", "android", 747 R.string.mediasize_japanese_oufuku, 5827, 7874); 748 749 /** Japanese Kahu media size: 240mm x 322.1mm (9.449" x 12.681") */ 750 public static final MediaSize JPN_KAHU = 751 new MediaSize("JPN_KAHU", "android", 752 R.string.mediasize_japanese_kahu, 9449, 12681); 753 /** Japanese Kaku2 media size: 240mm x 332mm (9.449" x 13.071") */ 754 public static final MediaSize JPN_KAKU2 = 755 new MediaSize("JPN_KAKU2", "android", 756 R.string.mediasize_japanese_kaku2, 9449, 13071); 757 758 /** Japanese You4 media size: 105mm x 235mm (4.134" x 9.252") */ 759 public static final MediaSize JPN_YOU4 = 760 new MediaSize("JPN_YOU4", "android", 761 R.string.mediasize_japanese_you4, 4134, 9252); 762 763 private final String mId; 764 /**@hide */ 765 public final String mLabel; 766 /**@hide */ 767 public final String mPackageName; 768 /**@hide */ 769 public final int mLabelResId; 770 private final int mWidthMils; 771 private final int mHeightMils; 772 773 /** 774 * Creates a new instance. 775 * 776 * @param id The unique media size id. 777 * @param packageName The name of the creating package. 778 * @param labelResId The resource if of a human readable label. 779 * @param widthMils The width in mils (thousands of an inch). 780 * @param heightMils The height in mils (thousands of an inch). 781 * 782 * @throws IllegalArgumentException If the id is empty or the label 783 * is empty or the widthMils is less than or equal to zero or the 784 * heightMils is less than or equal to zero. 785 * 786 * @hide 787 */ MediaSize(String id, String packageName, int labelResId, int widthMils, int heightMils)788 public MediaSize(String id, String packageName, int labelResId, 789 int widthMils, int heightMils) { 790 if (TextUtils.isEmpty(id)) { 791 throw new IllegalArgumentException("id cannot be empty."); 792 } 793 if (TextUtils.isEmpty(packageName)) { 794 throw new IllegalArgumentException("packageName cannot be empty."); 795 } 796 if (labelResId <= 0) { 797 throw new IllegalArgumentException("labelResId must be greater than zero."); 798 } 799 if (widthMils <= 0) { 800 throw new IllegalArgumentException("widthMils " 801 + "cannot be less than or equal to zero."); 802 } 803 if (heightMils <= 0) { 804 throw new IllegalArgumentException("heightMils " 805 + "cannot be less than or euqual to zero."); 806 } 807 mPackageName = packageName; 808 mId = id; 809 mLabelResId = labelResId; 810 mWidthMils = widthMils; 811 mHeightMils = heightMils; 812 mLabel = null; 813 814 // Build this mapping only for predefined media sizes. 815 sIdToMediaSizeMap.put(mId, this); 816 } 817 818 /** 819 * Creates a new instance. 820 * 821 * @param id The unique media size id. It is unique amongst other media sizes 822 * supported by the printer. 823 * @param label The <strong>localized</strong> human readable label. 824 * @param widthMils The width in mils (thousands of an inch). 825 * @param heightMils The height in mils (thousands of an inch). 826 * 827 * @throws IllegalArgumentException If the id is empty or the label is empty 828 * or the widthMils is less than or equal to zero or the heightMils is less 829 * than or equal to zero. 830 */ MediaSize(String id, String label, int widthMils, int heightMils)831 public MediaSize(String id, String label, int widthMils, int heightMils) { 832 if (TextUtils.isEmpty(id)) { 833 throw new IllegalArgumentException("id cannot be empty."); 834 } 835 if (TextUtils.isEmpty(label)) { 836 throw new IllegalArgumentException("label cannot be empty."); 837 } 838 if (widthMils <= 0) { 839 throw new IllegalArgumentException("widthMils " 840 + "cannot be less than or equal to zero."); 841 } 842 if (heightMils <= 0) { 843 throw new IllegalArgumentException("heightMils " 844 + "cannot be less than or euqual to zero."); 845 } 846 mId = id; 847 mLabel = label; 848 mWidthMils = widthMils; 849 mHeightMils = heightMils; 850 mLabelResId = 0; 851 mPackageName = null; 852 } 853 854 /** @hide */ MediaSize(String id, String label, String packageName, int widthMils, int heightMils, int labelResId)855 public MediaSize(String id, String label, String packageName, 856 int widthMils, int heightMils, int labelResId) { 857 mPackageName = packageName; 858 mId = id; 859 mLabelResId = labelResId; 860 mWidthMils = widthMils; 861 mHeightMils = heightMils; 862 mLabel = label; 863 } 864 865 /** 866 * Gets the unique media size id. It is unique amongst other media sizes 867 * supported by the printer. 868 * <p> 869 * This id is defined by the client that generated the media size 870 * instance and should not be interpreted by other parties. 871 * </p> 872 * 873 * @return The unique media size id. 874 */ getId()875 public String getId() { 876 return mId; 877 } 878 879 /** 880 * Gets the human readable media size label. 881 * 882 * @param packageManager The package manager for loading the label. 883 * @return The human readable label. 884 */ getLabel(PackageManager packageManager)885 public String getLabel(PackageManager packageManager) { 886 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) { 887 try { 888 return packageManager.getResourcesForApplication( 889 mPackageName).getString(mLabelResId); 890 } catch (NotFoundException nfe) { 891 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 892 + " from package " + mPackageName); 893 } catch (NameNotFoundException nnfee) { 894 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 895 + " from package " + mPackageName); 896 } 897 } 898 return mLabel; 899 } 900 901 /** 902 * Gets the media width in mils (thousands of an inch). 903 * 904 * @return The media width. 905 */ getWidthMils()906 public int getWidthMils() { 907 return mWidthMils; 908 } 909 910 /** 911 * Gets the media height in mils (thousands of an inch). 912 * 913 * @return The media height. 914 */ getHeightMils()915 public int getHeightMils() { 916 return mHeightMils; 917 } 918 919 /** 920 * Gets whether this media size is in portrait which is the 921 * height is greater or equal to the width. 922 * 923 * @return True if the media size is in portrait, false if 924 * it is in landscape. 925 */ isPortrait()926 public boolean isPortrait() { 927 return mHeightMils >= mWidthMils; 928 } 929 930 /** 931 * Returns a new media size instance in a portrait orientation, 932 * which is the height is the greater dimension. 933 * 934 * @return New instance in landscape orientation if this one 935 * is in landscape, otherwise this instance. 936 */ asPortrait()937 public MediaSize asPortrait() { 938 if (isPortrait()) { 939 return this; 940 } 941 return new MediaSize(mId, mLabel, mPackageName, 942 Math.min(mWidthMils, mHeightMils), 943 Math.max(mWidthMils, mHeightMils), 944 mLabelResId); 945 } 946 947 /** 948 * Returns a new media size instance in a landscape orientation, 949 * which is the height is the lesser dimension. 950 * 951 * @return New instance in landscape orientation if this one 952 * is in portrait, otherwise this instance. 953 */ asLandscape()954 public MediaSize asLandscape() { 955 if (!isPortrait()) { 956 return this; 957 } 958 return new MediaSize(mId, mLabel, mPackageName, 959 Math.max(mWidthMils, mHeightMils), 960 Math.min(mWidthMils, mHeightMils), 961 mLabelResId); 962 } 963 writeToParcel(Parcel parcel)964 void writeToParcel(Parcel parcel) { 965 parcel.writeString(mId); 966 parcel.writeString(mLabel); 967 parcel.writeString(mPackageName); 968 parcel.writeInt(mWidthMils); 969 parcel.writeInt(mHeightMils); 970 parcel.writeInt(mLabelResId); 971 } 972 createFromParcel(Parcel parcel)973 static MediaSize createFromParcel(Parcel parcel) { 974 return new MediaSize( 975 parcel.readString(), 976 parcel.readString(), 977 parcel.readString(), 978 parcel.readInt(), 979 parcel.readInt(), 980 parcel.readInt()); 981 } 982 983 @Override hashCode()984 public int hashCode() { 985 final int prime = 31; 986 int result = 1; 987 result = prime * result + mWidthMils; 988 result = prime * result + mHeightMils; 989 return result; 990 } 991 992 @Override equals(Object obj)993 public boolean equals(Object obj) { 994 if (this == obj) { 995 return true; 996 } 997 if (obj == null) { 998 return false; 999 } 1000 if (getClass() != obj.getClass()) { 1001 return false; 1002 } 1003 MediaSize other = (MediaSize) obj; 1004 if (mWidthMils != other.mWidthMils) { 1005 return false; 1006 } 1007 if (mHeightMils != other.mHeightMils) { 1008 return false; 1009 } 1010 return true; 1011 } 1012 1013 @Override toString()1014 public String toString() { 1015 StringBuilder builder = new StringBuilder(); 1016 builder.append("MediaSize{"); 1017 builder.append("id: ").append(mId); 1018 builder.append(", label: ").append(mLabel); 1019 builder.append(", packageName: ").append(mPackageName); 1020 builder.append(", heightMils: ").append(mHeightMils); 1021 builder.append(", widthMils: ").append(mWidthMils); 1022 builder.append(", labelResId: ").append(mLabelResId); 1023 builder.append("}"); 1024 return builder.toString(); 1025 } 1026 1027 /** 1028 * Gets a standard media size given its id. 1029 * 1030 * @param id The media size id. 1031 * @return The media size for the given id or null. 1032 * 1033 * @hide 1034 */ getStandardMediaSizeById(String id)1035 public static MediaSize getStandardMediaSizeById(String id) { 1036 return sIdToMediaSizeMap.get(id); 1037 } 1038 } 1039 1040 /** 1041 * This class specifies a supported resolution in DPI (dots per inch). 1042 * Resolution defines how many points with different color can be placed 1043 * on one inch in horizontal or vertical direction of the target media. 1044 * For example, a printer with 600 DPI can produce higher quality images 1045 * the one with 300 DPI resolution. 1046 */ 1047 public static final class Resolution { 1048 private final String mId; 1049 private final String mLabel; 1050 private final int mHorizontalDpi; 1051 private final int mVerticalDpi; 1052 1053 /** 1054 * Creates a new instance. 1055 * 1056 * @param id The unique resolution id. It is unique amongst other resolutions 1057 * supported by the printer. 1058 * @param label The <strong>localized</strong> human readable label. 1059 * @param horizontalDpi The horizontal resolution in DPI (dots per inch). 1060 * @param verticalDpi The vertical resolution in DPI (dots per inch). 1061 * 1062 * @throws IllegalArgumentException If the id is empty or the label is empty 1063 * or the horizontalDpi is less than or equal to zero or the verticalDpi is 1064 * less than or equal to zero. 1065 */ Resolution(String id, String label, int horizontalDpi, int verticalDpi)1066 public Resolution(String id, String label, int horizontalDpi, int verticalDpi) { 1067 if (TextUtils.isEmpty(id)) { 1068 throw new IllegalArgumentException("id cannot be empty."); 1069 } 1070 if (TextUtils.isEmpty(label)) { 1071 throw new IllegalArgumentException("label cannot be empty."); 1072 } 1073 if (horizontalDpi <= 0) { 1074 throw new IllegalArgumentException("horizontalDpi " 1075 + "cannot be less than or equal to zero."); 1076 } 1077 if (verticalDpi <= 0) { 1078 throw new IllegalArgumentException("verticalDpi" 1079 + " cannot be less than or equal to zero."); 1080 } 1081 mId = id; 1082 mLabel = label; 1083 mHorizontalDpi = horizontalDpi; 1084 mVerticalDpi = verticalDpi; 1085 } 1086 1087 /** 1088 * Gets the unique resolution id. It is unique amongst other resolutions 1089 * supported by the printer. 1090 * <p> 1091 * This id is defined by the client that generated the resolution 1092 * instance and should not be interpreted by other parties. 1093 * </p> 1094 * 1095 * @return The unique resolution id. 1096 */ getId()1097 public String getId() { 1098 return mId; 1099 } 1100 1101 /** 1102 * Gets the resolution human readable label. 1103 * 1104 * @return The human readable label. 1105 */ getLabel()1106 public String getLabel() { 1107 return mLabel; 1108 } 1109 1110 /** 1111 * Gets the horizontal resolution in DPI (dots per inch). 1112 * 1113 * @return The horizontal resolution. 1114 */ getHorizontalDpi()1115 public int getHorizontalDpi() { 1116 return mHorizontalDpi; 1117 } 1118 1119 /** 1120 * Gets the vertical resolution in DPI (dots per inch). 1121 * 1122 * @return The vertical resolution. 1123 */ getVerticalDpi()1124 public int getVerticalDpi() { 1125 return mVerticalDpi; 1126 } 1127 writeToParcel(Parcel parcel)1128 void writeToParcel(Parcel parcel) { 1129 parcel.writeString(mId); 1130 parcel.writeString(mLabel); 1131 parcel.writeInt(mHorizontalDpi); 1132 parcel.writeInt(mVerticalDpi); 1133 } 1134 createFromParcel(Parcel parcel)1135 static Resolution createFromParcel(Parcel parcel) { 1136 return new Resolution( 1137 parcel.readString(), 1138 parcel.readString(), 1139 parcel.readInt(), 1140 parcel.readInt()); 1141 } 1142 1143 @Override hashCode()1144 public int hashCode() { 1145 final int prime = 31; 1146 int result = 1; 1147 result = prime * result + mHorizontalDpi; 1148 result = prime * result + mVerticalDpi; 1149 return result; 1150 } 1151 1152 @Override equals(Object obj)1153 public boolean equals(Object obj) { 1154 if (this == obj) { 1155 return true; 1156 } 1157 if (obj == null) { 1158 return false; 1159 } 1160 if (getClass() != obj.getClass()) { 1161 return false; 1162 } 1163 Resolution other = (Resolution) obj; 1164 if (mHorizontalDpi != other.mHorizontalDpi) { 1165 return false; 1166 } 1167 if (mVerticalDpi != other.mVerticalDpi) { 1168 return false; 1169 } 1170 return true; 1171 } 1172 1173 @Override toString()1174 public String toString() { 1175 StringBuilder builder = new StringBuilder(); 1176 builder.append("Resolution{"); 1177 builder.append("id: ").append(mId); 1178 builder.append(", label: ").append(mLabel); 1179 builder.append(", horizontalDpi: ").append(mHorizontalDpi); 1180 builder.append(", verticalDpi: ").append(mVerticalDpi); 1181 builder.append("}"); 1182 return builder.toString(); 1183 } 1184 } 1185 1186 /** 1187 * This class specifies content margins. Margins define the white space 1188 * around the content where the left margin defines the amount of white 1189 * space on the left of the content and so on. 1190 */ 1191 public static final class Margins { 1192 public static final Margins NO_MARGINS = new Margins(0, 0, 0, 0); 1193 1194 private final int mLeftMils; 1195 private final int mTopMils; 1196 private final int mRightMils; 1197 private final int mBottomMils; 1198 1199 /** 1200 * Creates a new instance. 1201 * 1202 * @param leftMils The left margin in mils (thousands of an inch). 1203 * @param topMils The top margin in mils (thousands of an inch). 1204 * @param rightMils The right margin in mils (thousands of an inch). 1205 * @param bottomMils The bottom margin in mils (thousands of an inch). 1206 */ Margins(int leftMils, int topMils, int rightMils, int bottomMils)1207 public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { 1208 mTopMils = topMils; 1209 mLeftMils = leftMils; 1210 mRightMils = rightMils; 1211 mBottomMils = bottomMils; 1212 } 1213 1214 /** 1215 * Gets the left margin in mils (thousands of an inch). 1216 * 1217 * @return The left margin. 1218 */ getLeftMils()1219 public int getLeftMils() { 1220 return mLeftMils; 1221 } 1222 1223 /** 1224 * Gets the top margin in mils (thousands of an inch). 1225 * 1226 * @return The top margin. 1227 */ getTopMils()1228 public int getTopMils() { 1229 return mTopMils; 1230 } 1231 1232 /** 1233 * Gets the right margin in mils (thousands of an inch). 1234 * 1235 * @return The right margin. 1236 */ getRightMils()1237 public int getRightMils() { 1238 return mRightMils; 1239 } 1240 1241 /** 1242 * Gets the bottom margin in mils (thousands of an inch). 1243 * 1244 * @return The bottom margin. 1245 */ getBottomMils()1246 public int getBottomMils() { 1247 return mBottomMils; 1248 } 1249 writeToParcel(Parcel parcel)1250 void writeToParcel(Parcel parcel) { 1251 parcel.writeInt(mLeftMils); 1252 parcel.writeInt(mTopMils); 1253 parcel.writeInt(mRightMils); 1254 parcel.writeInt(mBottomMils); 1255 } 1256 createFromParcel(Parcel parcel)1257 static Margins createFromParcel(Parcel parcel) { 1258 return new Margins( 1259 parcel.readInt(), 1260 parcel.readInt(), 1261 parcel.readInt(), 1262 parcel.readInt()); 1263 } 1264 1265 @Override hashCode()1266 public int hashCode() { 1267 final int prime = 31; 1268 int result = 1; 1269 result = prime * result + mBottomMils; 1270 result = prime * result + mLeftMils; 1271 result = prime * result + mRightMils; 1272 result = prime * result + mTopMils; 1273 return result; 1274 } 1275 1276 @Override equals(Object obj)1277 public boolean equals(Object obj) { 1278 if (this == obj) { 1279 return true; 1280 } 1281 if (obj == null) { 1282 return false; 1283 } 1284 if (getClass() != obj.getClass()) { 1285 return false; 1286 } 1287 Margins other = (Margins) obj; 1288 if (mBottomMils != other.mBottomMils) { 1289 return false; 1290 } 1291 if (mLeftMils != other.mLeftMils) { 1292 return false; 1293 } 1294 if (mRightMils != other.mRightMils) { 1295 return false; 1296 } 1297 if (mTopMils != other.mTopMils) { 1298 return false; 1299 } 1300 return true; 1301 } 1302 1303 @Override toString()1304 public String toString() { 1305 StringBuilder builder = new StringBuilder(); 1306 builder.append("Margins{"); 1307 builder.append("leftMils: ").append(mLeftMils); 1308 builder.append(", topMils: ").append(mTopMils); 1309 builder.append(", rightMils: ").append(mRightMils); 1310 builder.append(", bottomMils: ").append(mBottomMils); 1311 builder.append("}"); 1312 return builder.toString(); 1313 } 1314 } 1315 colorModeToString(int colorMode)1316 static String colorModeToString(int colorMode) { 1317 switch (colorMode) { 1318 case COLOR_MODE_MONOCHROME: { 1319 return "COLOR_MODE_MONOCHROME"; 1320 } 1321 case COLOR_MODE_COLOR: { 1322 return "COLOR_MODE_COLOR"; 1323 } 1324 default: { 1325 return "COLOR_MODE_UNKNOWN"; 1326 } 1327 } 1328 } 1329 duplexModeToString(int duplexMode)1330 static String duplexModeToString(int duplexMode) { 1331 switch (duplexMode) { 1332 case DUPLEX_MODE_NONE: { 1333 return "DUPLEX_MODE_NONE"; 1334 } 1335 case DUPLEX_MODE_LONG_EDGE: { 1336 return "DUPLEX_MODE_LONG_EDGE"; 1337 } 1338 case DUPLEX_MODE_SHORT_EDGE: { 1339 return "DUPLEX_MODE_SHORT_EDGE"; 1340 } 1341 default: { 1342 return "DUPLEX_MODE_UNKNOWN"; 1343 } 1344 } 1345 } 1346 enforceValidColorMode(int colorMode)1347 static void enforceValidColorMode(int colorMode) { 1348 if ((colorMode & VALID_COLOR_MODES) == 0 || Integer.bitCount(colorMode) != 1) { 1349 throw new IllegalArgumentException("invalid color mode: " + colorMode); 1350 } 1351 } 1352 enforceValidDuplexMode(int duplexMode)1353 static void enforceValidDuplexMode(int duplexMode) { 1354 if ((duplexMode & VALID_DUPLEX_MODES) == 0 || Integer.bitCount(duplexMode) != 1) { 1355 throw new IllegalArgumentException("invalid duplex mode: " + duplexMode); 1356 } 1357 } 1358 1359 /** 1360 * Builder for creating {@link PrintAttributes}. 1361 */ 1362 public static final class Builder { 1363 private final PrintAttributes mAttributes = new PrintAttributes(); 1364 1365 /** 1366 * Sets the media size. 1367 * 1368 * @param mediaSize The media size. 1369 * @return This builder. 1370 */ setMediaSize(MediaSize mediaSize)1371 public Builder setMediaSize(MediaSize mediaSize) { 1372 mAttributes.setMediaSize(mediaSize); 1373 return this; 1374 } 1375 1376 /** 1377 * Sets the resolution. 1378 * 1379 * @param resolution The resolution. 1380 * @return This builder. 1381 */ setResolution(Resolution resolution)1382 public Builder setResolution(Resolution resolution) { 1383 mAttributes.setResolution(resolution); 1384 return this; 1385 } 1386 1387 /** 1388 * Sets the minimal margins. If the content does not fit 1389 * these margins it will be clipped. 1390 * 1391 * @param margins The margins. 1392 * @return This builder. 1393 */ setMinMargins(Margins margins)1394 public Builder setMinMargins(Margins margins) { 1395 mAttributes.setMinMargins(margins); 1396 return this; 1397 } 1398 1399 /** 1400 * Sets the color mode. 1401 * 1402 * @param colorMode A valid color mode or zero. 1403 * @return This builder. 1404 * 1405 * @see PrintAttributes#COLOR_MODE_MONOCHROME 1406 * @see PrintAttributes#COLOR_MODE_COLOR 1407 */ setColorMode(int colorMode)1408 public Builder setColorMode(int colorMode) { 1409 mAttributes.setColorMode(colorMode); 1410 return this; 1411 } 1412 1413 /** 1414 * Sets the duplex mode. 1415 * 1416 * @param duplexMode A valid duplex mode or zero. 1417 * @return This builder. 1418 * 1419 * @see PrintAttributes#DUPLEX_MODE_NONE 1420 * @see PrintAttributes#DUPLEX_MODE_LONG_EDGE 1421 * @see PrintAttributes#DUPLEX_MODE_SHORT_EDGE 1422 */ setDuplexMode(int duplexMode)1423 public Builder setDuplexMode(int duplexMode) { 1424 mAttributes.setDuplexMode(duplexMode); 1425 return this; 1426 } 1427 1428 /** 1429 * Creates a new {@link PrintAttributes} instance. 1430 * <p> 1431 * If you do not specify a duplex mode, the default 1432 * {@link #DUPLEX_MODE_NONE} will be used. 1433 * </p> 1434 * 1435 * @return The new instance. 1436 */ build()1437 public PrintAttributes build() { 1438 return mAttributes; 1439 } 1440 } 1441 1442 public static final Parcelable.Creator<PrintAttributes> CREATOR = 1443 new Creator<PrintAttributes>() { 1444 @Override 1445 public PrintAttributes createFromParcel(Parcel parcel) { 1446 return new PrintAttributes(parcel); 1447 } 1448 1449 @Override 1450 public PrintAttributes[] newArray(int size) { 1451 return new PrintAttributes[size]; 1452 } 1453 }; 1454 } 1455