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