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