PrintAttributes.java revision 651dd4e6ee6510caf9f15c51094a11121af17ec2
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.content.pm.PackageManager; 20import android.content.pm.PackageManager.NameNotFoundException; 21import android.content.res.Resources.NotFoundException; 22import android.os.Parcel; 23import android.os.Parcelable; 24import android.text.TextUtils; 25import android.util.Log; 26 27import com.android.internal.R; 28 29/** 30 * This class represents the attributes of a print job. 31 */ 32public final class PrintAttributes implements Parcelable { 33 34 /** Color mode: Monochrome color scheme, e.g. one color is used. */ 35 public static final int COLOR_MODE_MONOCHROME = 1 << 0; 36 /** Color mode: Color color scheme, e.g. many colors are used. */ 37 public static final int COLOR_MODE_COLOR = 1 << 1; 38 39 private static final int VALID_COLOR_MODES = 40 COLOR_MODE_MONOCHROME | COLOR_MODE_COLOR; 41 42 private MediaSize mMediaSize; 43 private Resolution mResolution; 44 private Margins mMinMargins; 45 46 private int mColorMode; 47 48 PrintAttributes() { 49 /* hide constructor */ 50 } 51 52 private PrintAttributes(Parcel parcel) { 53 mMediaSize = (parcel.readInt() == 1) ? MediaSize.createFromParcel(parcel) : null; 54 mResolution = (parcel.readInt() == 1) ? Resolution.createFromParcel(parcel) : null; 55 mMinMargins = (parcel.readInt() == 1) ? Margins.createFromParcel(parcel) : null; 56 mColorMode = parcel.readInt(); 57 } 58 59 /** 60 * Gets the media size. 61 * 62 * @return The media size or <code>null</code> if not set. 63 */ 64 public MediaSize getMediaSize() { 65 return mMediaSize; 66 } 67 68 /** 69 * Sets the media size. 70 * 71 * @param The media size. 72 * 73 * @hide 74 */ 75 public void setMediaSize(MediaSize mediaSize) { 76 mMediaSize = mediaSize; 77 } 78 79 /** 80 * Gets the resolution. 81 * 82 * @return The resolution or <code>null</code> if not set. 83 */ 84 public Resolution getResolution() { 85 return mResolution; 86 } 87 88 /** 89 * Sets the resolution. 90 * 91 * @param The resolution. 92 * 93 * @hide 94 */ 95 public void setResolution(Resolution resolution) { 96 mResolution = resolution; 97 } 98 99 /** 100 * Gets the minimal margins. If the content does not fit 101 * these margins it will be clipped. 102 * 103 * @return The margins or <code>null</code> if not set. 104 */ 105 public Margins getMinMargins() { 106 return mMinMargins; 107 } 108 109 /** 110 * Sets the minimal margins. If the content does not fit 111 * these margins it will be clipped. 112 * 113 * @param The margins. 114 * 115 * @hide 116 */ 117 public void setMinMargins(Margins margins) { 118 mMinMargins = margins; 119 } 120 121 /** 122 * Gets the color mode. 123 * 124 * @return The color mode or zero if not set. 125 * 126 * @see #COLOR_MODE_COLOR 127 * @see #COLOR_MODE_MONOCHROME 128 */ 129 public int getColorMode() { 130 return mColorMode; 131 } 132 133 /** 134 * Sets the color mode. 135 * 136 * @param The color mode. 137 * 138 * @see #COLOR_MODE_MONOCHROME 139 * @see #COLOR_MODE_COLOR 140 * 141 * @hide 142 */ 143 public void setColorMode(int colorMode) { 144 enforceValidColorMode(colorMode); 145 mColorMode = colorMode; 146 } 147 148 @Override 149 public void writeToParcel(Parcel parcel, int flags) { 150 if (mMediaSize != null) { 151 parcel.writeInt(1); 152 mMediaSize.writeToParcel(parcel); 153 } else { 154 parcel.writeInt(0); 155 } 156 if (mResolution != null) { 157 parcel.writeInt(1); 158 mResolution.writeToParcel(parcel); 159 } else { 160 parcel.writeInt(0); 161 } 162 if (mMinMargins != null) { 163 parcel.writeInt(1); 164 mMinMargins.writeToParcel(parcel); 165 } else { 166 parcel.writeInt(0); 167 } 168 parcel.writeInt(mColorMode); 169 } 170 171 @Override 172 public int describeContents() { 173 return 0; 174 } 175 176 @Override 177 public int hashCode() { 178 final int prime = 31; 179 int result = 1; 180 result = prime * result + mColorMode; 181 result = prime * result + ((mMinMargins == null) ? 0 : mMinMargins.hashCode()); 182 result = prime * result + ((mMediaSize == null) ? 0 : mMediaSize.hashCode()); 183 result = prime * result + ((mResolution == null) ? 0 : mResolution.hashCode()); 184 return result; 185 } 186 187 @Override 188 public boolean equals(Object obj) { 189 if (this == obj) { 190 return true; 191 } 192 if (obj == null) { 193 return false; 194 } 195 if (getClass() != obj.getClass()) { 196 return false; 197 } 198 PrintAttributes other = (PrintAttributes) obj; 199 if (mColorMode != other.mColorMode) { 200 return false; 201 } 202 if (mMinMargins == null) { 203 if (other.mMinMargins != null) { 204 return false; 205 } 206 } else if (!mMinMargins.equals(other.mMinMargins)) { 207 return false; 208 } 209 if (mMediaSize == null) { 210 if (other.mMediaSize != null) { 211 return false; 212 } 213 } else if (!mMediaSize.equals(other.mMediaSize)) { 214 return false; 215 } 216 if (mResolution == null) { 217 if (other.mResolution != null) { 218 return false; 219 } 220 } else if (!mResolution.equals(other.mResolution)) { 221 return false; 222 } 223 return true; 224 } 225 226 @Override 227 public String toString() { 228 StringBuilder builder = new StringBuilder(); 229 builder.append("PrintAttributes{"); 230 builder.append("mediaSize: ").append(mMediaSize); 231 if (mMediaSize != null) { 232 builder.append(", orientation: ").append(mMediaSize.isPortrait() 233 ? "portrait" : "landscape"); 234 } else { 235 builder.append(", orientation: ").append("null"); 236 } 237 builder.append(", resolution: ").append(mResolution); 238 builder.append(", minMargins: ").append(mMinMargins); 239 builder.append(", colorMode: ").append(colorModeToString(mColorMode)); 240 builder.append("}"); 241 return builder.toString(); 242 } 243 244 /** hide */ 245 public void clear() { 246 mMediaSize = null; 247 mResolution = null; 248 mMinMargins = null; 249 mColorMode = 0; 250 } 251 252 /** 253 * @hide 254 */ 255 public void copyFrom(PrintAttributes other) { 256 mMediaSize = other.mMediaSize; 257 mResolution = other.mResolution; 258 mMinMargins = other.mMinMargins; 259 mColorMode = other.mColorMode; 260 } 261 262 /** 263 * This class specifies a supported media size. 264 */ 265 public static final class MediaSize { 266 private static final String LOG_TAG = "MediaSize"; 267 268 // TODO: Verify media sizes and add more standard ones. 269 270 // ISO sizes 271 272 /** ISO A0 media size: 841mm x 1189mm (33.11" x 46.81") */ 273 public static final MediaSize ISO_A0 = 274 new MediaSize("ISO_A0", "android", R.string.mediaSize_iso_a0, 33110, 46810); 275 /** ISO A1 media size: 594mm x 841mm (23.39" x 33.11") */ 276 public static final MediaSize ISO_A1 = 277 new MediaSize("ISO_A1", "android", R.string.mediaSize_iso_a1, 23390, 33110); 278 /** ISO A2 media size: 420mm x 594mm (16.54" x 23.39") */ 279 public static final MediaSize ISO_A2 = 280 new MediaSize("ISO_A2", "android", R.string.mediaSize_iso_a2, 16540, 23390); 281 /** ISO A3 media size: 297mm x 420mm (11.69" x 16.54") */ 282 public static final MediaSize ISO_A3 = 283 new MediaSize("ISO_A3", "android", R.string.mediaSize_iso_a3, 11690, 16540); 284 /** ISO A4 media size: 210mm x 297mm (8.27" x 11.69") */ 285 public static final MediaSize ISO_A4 = 286 new MediaSize("ISO_A4", "android", R.string.mediaSize_iso_a4, 8270, 11690); 287 /** ISO A5 media size: 148mm x 210mm (5.83" x 8.27") */ 288 public static final MediaSize ISO_A5 = 289 new MediaSize("ISO_A5", "android", R.string.mediaSize_iso_a5, 5830, 8270); 290 /** ISO A6 media size: 105mm x 148mm (4.13" x 5.83") */ 291 public static final MediaSize ISO_A6 = 292 new MediaSize("ISO_A6", "android", R.string.mediaSize_iso_a6, 4130, 5830); 293 /** ISO A7 media size: 74mm x 105mm (2.91" x 4.13") */ 294 public static final MediaSize ISO_A7 = 295 new MediaSize("ISO_A7", "android", R.string.mediaSize_iso_a7, 2910, 4130); 296 /** ISO A8 media size: 52mm x 74mm (2.05" x 2.91") */ 297 public static final MediaSize ISO_A8 = 298 new MediaSize("ISO_A8", "android", R.string.mediaSize_iso_a8, 2050, 2910); 299 /** ISO A9 media size: 37mm x 52mm (1.46" x 2.05") */ 300 public static final MediaSize ISO_A9 = 301 new MediaSize("ISO_A9", "android", R.string.mediaSize_iso_a9, 1460, 2050); 302 /** ISO A10 media size: 26mm x 37mm (1.02" x 1.46") */ 303 public static final MediaSize ISO_A10 = 304 new MediaSize("ISO_A10", "android", R.string.mediaSize_iso_a10, 1020, 1460); 305 306 /** ISO B0 media size: 1000mm x 1414mm (39.37" x 55.67") */ 307 public static final MediaSize ISO_B0 = 308 new MediaSize("ISO_B0", "android", R.string.mediaSize_iso_b0, 39370, 55670); 309 /** ISO B1 media size: 707mm x 1000mm (27.83" x 39.37") */ 310 public static final MediaSize ISO_B1 = 311 new MediaSize("ISO_B1", "android", R.string.mediaSize_iso_b1, 27830, 39370); 312 /** ISO B2 media size: 500mm x 707mm (19.69" x 27.83") */ 313 public static final MediaSize ISO_B2 = 314 new MediaSize("ISO_B2", "android", R.string.mediaSize_iso_b2, 19690, 27830); 315 /** ISO B3 media size: 353mm x 500mm (13.90" x 19.69") */ 316 public static final MediaSize ISO_B3 = 317 new MediaSize("ISO_B3", "android", R.string.mediaSize_iso_b3, 13900, 19690); 318 /** ISO B4 media size: 250mm x 353mm (9.84" x 13.90") */ 319 public static final MediaSize ISO_B4 = 320 new MediaSize("ISO_B4", "android", R.string.mediaSize_iso_b4, 9840, 13900); 321 /** ISO B5 media size: 176mm x 250mm (6.93" x 9.84") */ 322 public static final MediaSize ISO_B5 = 323 new MediaSize("ISO_B5", "android", R.string.mediaSize_iso_b5, 6930, 9840); 324 /** ISO B6 media size: 125mm x 176mm (4.92" x 6.93") */ 325 public static final MediaSize ISO_B6 = 326 new MediaSize("ISO_B6", "android", R.string.mediaSize_iso_b6, 4920, 6930); 327 /** ISO B7 media size: 88mm x 125mm (3.46" x 4.92") */ 328 public static final MediaSize ISO_B7 = 329 new MediaSize("ISO_B7", "android", R.string.mediaSize_iso_b7, 3460, 4920); 330 /** ISO B8 media size: 62mm x 88mm (2.44" x 3.46") */ 331 public static final MediaSize ISO_B8 = 332 new MediaSize("ISO_B8", "android", R.string.mediaSize_iso_b8, 2440, 3460); 333 /** ISO B9 media size: 44mm x 62mm (1.73" x 2.44") */ 334 public static final MediaSize ISO_B9 = 335 new MediaSize("ISO_B9", "android", R.string.mediaSize_iso_b9, 1730, 2440); 336 /** ISO B10 media size: 31mm x 44mm (1.22" x 1.73") */ 337 public static final MediaSize ISO_B10 = 338 new MediaSize("ISO_B10", "android", R.string.mediaSize_iso_b10, 1220, 1730); 339 340 /** ISO C0 media size: 917mm x 1297mm (36.10" x 51.06") */ 341 public static final MediaSize ISO_C0 = 342 new MediaSize("ISO_C0", "android", R.string.mediaSize_iso_c0, 36100, 51060); 343 /** ISO C1 media size: 648mm x 917mm (25.51" x 36.10") */ 344 public static final MediaSize ISO_C1 = 345 new MediaSize("ISO_C1", "android", R.string.mediaSize_iso_c1, 25510, 36100); 346 /** ISO C2 media size: 458mm x 648mm (18.03" x 25.51") */ 347 public static final MediaSize ISO_C2 = 348 new MediaSize("ISO_C2", "android", R.string.mediaSize_iso_c2, 18030, 25510); 349 /** ISO C3 media size: 324mm x 458mm (12.76" x 18.03") */ 350 public static final MediaSize ISO_C3 = 351 new MediaSize("ISO_C3", "android", R.string.mediaSize_iso_c3, 12760, 18030); 352 /** ISO C4 media size: 229mm x 324mm (9.02" x 12.76") */ 353 public static final MediaSize ISO_C4 = 354 new MediaSize("ISO_C4", "android", R.string.mediaSize_iso_c4, 9020, 12760); 355 /** ISO C5 media size: 162mm x 229mm (6.38" x 9.02") */ 356 public static final MediaSize ISO_C5 = 357 new MediaSize("ISO_C5", "android", R.string.mediaSize_iso_c5, 6380, 9020); 358 /** ISO C6 media size: 114mm x 162mm (4.49" x 6.38") */ 359 public static final MediaSize ISO_C6 = 360 new MediaSize("ISO_C6", "android", R.string.mediaSize_iso_c6, 4490, 6380); 361 /** ISO C7 media size: 81mm x 114mm (3.19" x 4.49") */ 362 public static final MediaSize ISO_C7 = 363 new MediaSize("ISO_C7", "android", R.string.mediaSize_iso_c7, 3190, 4490); 364 /** ISO C8 media size: 57mm x 81mm (2.24" x 3.19") */ 365 public static final MediaSize ISO_C8 = 366 new MediaSize("ISO_C8", "android", R.string.mediaSize_iso_c8, 2240, 3190); 367 /** ISO C9 media size: 40mm x 57mm (1.57" x 2.24") */ 368 public static final MediaSize ISO_C9 = 369 new MediaSize("ISO_C9", "android", R.string.mediaSize_iso_c9, 1570, 2240); 370 /** ISO C10 media size: 28mm x 40mm (1.10" x 1.57") */ 371 public static final MediaSize ISO_C10 = 372 new MediaSize("ISO_C10", "android", R.string.mediaSize_iso_c10, 1100, 1570); 373 374 // North America 375 376 /** North America Letter media size: 8.5" x 11" */ 377 public static final MediaSize NA_LETTER = 378 new MediaSize("NA_LETTER", "android", R.string.mediaSize_na_letter, 8500, 11000); 379 /** North America Government-Letter media size: 8.0" x 10.5" */ 380 public static final MediaSize NA_GOVT_LETTER = 381 new MediaSize("NA_GOVT_LETTER", "android", 382 R.string.mediaSize_na_gvrnmt_letter, 8000, 10500); 383 /** North America Legal media size: 8.5" x 14" */ 384 public static final MediaSize NA_LEGAL = 385 new MediaSize("NA_LEGAL", "android", R.string.mediaSize_na_legal, 8500, 14000); 386 /** North America Junior Legal media size: 8.0" x 5.0" */ 387 public static final MediaSize NA_JUNIOR_LEGAL = 388 new MediaSize("NA_JUNIOR_LEGAL", "android", 389 R.string.mediaSize_na_junior_legal, 8000, 5000); 390 /** North America Ledger media size: 17" x 11" */ 391 public static final MediaSize NA_LEDGER = 392 new MediaSize("NA_LEDGER", "android", R.string.mediaSize_na_ledger, 17000, 11000); 393 /** North America Tabloid media size: 11" x 17" */ 394 public static final MediaSize NA_TBLOID = 395 new MediaSize("NA_TABLOID", "android", 396 R.string.mediaSize_na_tabloid, 11000, 17000); 397 398 private final String mId; 399 /**@hide */ 400 public final String mLabel; 401 /**@hide */ 402 public final String mPackageName; 403 /**@hide */ 404 public final int mLabelResId; 405 private final int mWidthMils; 406 private final int mHeightMils; 407 408 /** 409 * Creates a new instance. This is the preferred constructor since 410 * it enables the media size label to be shown in a localized fashion 411 * on a locale change. 412 * 413 * @param id The unique media size id. 414 * @param packageName The name of the creating package. 415 * @param labelResId The resource if of a human readable label. 416 * @param widthMils The width in mils (thousands of an inch). 417 * @param heightMils The height in mils (thousands of an inch). 418 * 419 * @throws IllegalArgumentException If the id is empty. 420 * @throws IllegalArgumentException If the label is empty. 421 * @throws IllegalArgumentException If the widthMils is less than or equal to zero. 422 * @throws IllegalArgumentException If the heightMils is less than or equal to zero. 423 * 424 * @hide 425 */ 426 public MediaSize(String id, String packageName, int labelResId, 427 int widthMils, int heightMils) { 428 if (TextUtils.isEmpty(id)) { 429 throw new IllegalArgumentException("id cannot be empty."); 430 } 431 if (TextUtils.isEmpty(packageName)) { 432 throw new IllegalArgumentException("packageName cannot be empty."); 433 } 434 if (labelResId <= 0) { 435 throw new IllegalArgumentException("labelResId must be greater than zero."); 436 } 437 if (widthMils <= 0) { 438 throw new IllegalArgumentException("widthMils " 439 + "cannot be less than or equal to zero."); 440 } 441 if (heightMils <= 0) { 442 throw new IllegalArgumentException("heightMils " 443 + "cannot be less than or euqual to zero."); 444 } 445 mPackageName = packageName; 446 mId = id; 447 mLabelResId = labelResId; 448 mWidthMils = widthMils; 449 mHeightMils = heightMils; 450 mLabel = null; 451 } 452 453 /** 454 * Creates a new instance. 455 * 456 * @param id The unique media size id. 457 * @param label The <strong>internationalized</strong> human readable label. 458 * @param widthMils The width in mils (thousands of an inch). 459 * @param heightMils The height in mils (thousands of an inch). 460 * 461 * @throws IllegalArgumentException If the id is empty. 462 * @throws IllegalArgumentException If the label is empty. 463 * @throws IllegalArgumentException If the widthMils is less than or equal to zero. 464 * @throws IllegalArgumentException If the heightMils is less than or equal to zero. 465 */ 466 public MediaSize(String id, String label, int widthMils, int heightMils) { 467 if (TextUtils.isEmpty(id)) { 468 throw new IllegalArgumentException("id cannot be empty."); 469 } 470 if (TextUtils.isEmpty(label)) { 471 throw new IllegalArgumentException("label cannot be empty."); 472 } 473 if (widthMils <= 0) { 474 throw new IllegalArgumentException("widthMils " 475 + "cannot be less than or equal to zero."); 476 } 477 if (heightMils <= 0) { 478 throw new IllegalArgumentException("heightMils " 479 + "cannot be less than or euqual to zero."); 480 } 481 mId = id; 482 mLabel = label; 483 mWidthMils = widthMils; 484 mHeightMils = heightMils; 485 mLabelResId = 0; 486 mPackageName = null; 487 } 488 489 /** @hide */ 490 public MediaSize(String id, String label, String packageName, 491 int widthMils, int heightMils, int labelResId) { 492 mPackageName = packageName; 493 mId = id; 494 mLabelResId = labelResId; 495 mWidthMils = widthMils; 496 mHeightMils = heightMils; 497 mLabel = label; 498 } 499 500 /** 501 * Gets the unique media size id. 502 * 503 * @return The unique media size id. 504 */ 505 public String getId() { 506 return mId; 507 } 508 509 /** 510 * Gets the human readable media size label. 511 * 512 * @param packageManager The package manager for loading the label. 513 * @return The human readable label. 514 */ 515 public String getLabel(PackageManager packageManager) { 516 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) { 517 try { 518 return packageManager.getResourcesForApplication( 519 mPackageName).getString(mLabelResId); 520 } catch (NotFoundException nfe) { 521 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 522 + " from package " + mPackageName); 523 } catch (NameNotFoundException nnfee) { 524 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 525 + " from package " + mPackageName); 526 } 527 } 528 return mLabel; 529 } 530 531 /** 532 * Gets the media width in mils (thousands of an inch). 533 * 534 * @return The media width. 535 */ 536 public int getWidthMils() { 537 return mWidthMils; 538 } 539 540 /** 541 * Gets the media height in mils (thousands of an inch). 542 * 543 * @return The media height. 544 */ 545 public int getHeightMils() { 546 return mHeightMils; 547 } 548 549 /** 550 * Gets whether this media size is in portrait which is the 551 * height is greater or equal to the width. 552 * 553 * @return True if the media size is in portrait, false if 554 * it is in landscape. 555 */ 556 public boolean isPortrait() { 557 return mHeightMils >= mWidthMils; 558 } 559 560 /** 561 * Returns a new media size in a portrait orientation 562 * which is the height is the greater dimension. 563 * 564 * @return New instance in landscape orientation. 565 */ 566 public MediaSize asPortrait() { 567 return new MediaSize(mId, mLabel, mPackageName, 568 Math.min(mWidthMils, mHeightMils), 569 Math.max(mWidthMils, mHeightMils), 570 mLabelResId); 571 } 572 573 /** 574 * Returns a new media size in a landscape orientation 575 * which is the height is the lesser dimension. 576 * 577 * @return New instance in landscape orientation. 578 */ 579 public MediaSize asLandscape() { 580 return new MediaSize(mId, mLabel, mPackageName, 581 Math.max(mWidthMils, mHeightMils), 582 Math.min(mWidthMils, mHeightMils), 583 mLabelResId); 584 } 585 586 void writeToParcel(Parcel parcel) { 587 parcel.writeString(mId); 588 parcel.writeString(mLabel); 589 parcel.writeString(mPackageName); 590 parcel.writeInt(mWidthMils); 591 parcel.writeInt(mHeightMils); 592 parcel.writeInt(mLabelResId); 593 } 594 595 static MediaSize createFromParcel(Parcel parcel) { 596 return new MediaSize( 597 parcel.readString(), 598 parcel.readString(), 599 parcel.readString(), 600 parcel.readInt(), 601 parcel.readInt(), 602 parcel.readInt()); 603 } 604 605 @Override 606 public int hashCode() { 607 final int prime = 31; 608 int result = 1; 609 result = prime * result + mWidthMils; 610 result = prime * result + mHeightMils; 611 return result; 612 } 613 614 @Override 615 public boolean equals(Object obj) { 616 if (this == obj) { 617 return true; 618 } 619 if (obj == null) { 620 return false; 621 } 622 if (getClass() != obj.getClass()) { 623 return false; 624 } 625 MediaSize other = (MediaSize) obj; 626 if (mWidthMils != other.mWidthMils) { 627 return false; 628 } 629 if (mHeightMils != other.mHeightMils) { 630 return false; 631 } 632 return true; 633 } 634 635 @Override 636 public String toString() { 637 StringBuilder builder = new StringBuilder(); 638 builder.append("MediaSize{"); 639 builder.append("id: ").append(mId); 640 builder.append(", label: ").append(mLabel); 641 builder.append(", packageName: ").append(mPackageName); 642 builder.append(", heightMils: ").append(mHeightMils); 643 builder.append(", widthMils: ").append(mWidthMils); 644 builder.append(", labelResId: ").append(mLabelResId); 645 builder.append("}"); 646 return builder.toString(); 647 } 648 } 649 650 /** 651 * This class specifies a supported resolution in dpi (dots per inch). 652 */ 653 public static final class Resolution { 654 private final String mId; 655 private final String mLabel; 656 private final int mHorizontalDpi; 657 private final int mVerticalDpi; 658 659 /** 660 * Creates a new instance. 661 * 662 * @param id The unique resolution id. 663 * @param label The <strong>internationalized</strong> human readable label. 664 * @param horizontalDpi The horizontal resolution in dpi. 665 * @param verticalDpi The vertical resolution in dpi. 666 * 667 * @throws IllegalArgumentException If the id is empty. 668 * @throws IllegalArgumentException If the label is empty. 669 * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero. 670 * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero. 671 */ 672 public Resolution(String id, String label, int horizontalDpi, int verticalDpi) { 673 if (TextUtils.isEmpty(id)) { 674 throw new IllegalArgumentException("id cannot be empty."); 675 } 676 if (TextUtils.isEmpty(label)) { 677 throw new IllegalArgumentException("label cannot be empty."); 678 } 679 if (horizontalDpi <= 0) { 680 throw new IllegalArgumentException("horizontalDpi " 681 + "cannot be less than or equal to zero."); 682 } 683 if (verticalDpi <= 0) { 684 throw new IllegalArgumentException("verticalDpi" 685 + " cannot be less than or equal to zero."); 686 } 687 mId = id; 688 mLabel = label; 689 mHorizontalDpi = horizontalDpi; 690 mVerticalDpi = verticalDpi; 691 } 692 693 /** 694 * Gets the unique resolution id. 695 * 696 * @return The unique resolution id. 697 */ 698 public String getId() { 699 return mId; 700 } 701 702 /** 703 * Gets the resolution human readable label. 704 * 705 * @return The human readable label. 706 */ 707 public String getLabel() { 708 return mLabel; 709 } 710 711 /** 712 * Gets the vertical resolution in dpi. 713 * 714 * @return The horizontal resolution. 715 */ 716 public int getHorizontalDpi() { 717 return mHorizontalDpi; 718 } 719 720 /** 721 * Gets the vertical resolution in dpi. 722 * 723 * @return The vertical resolution. 724 */ 725 public int getVerticalDpi() { 726 return mVerticalDpi; 727 } 728 729 void writeToParcel(Parcel parcel) { 730 parcel.writeString(mId); 731 parcel.writeString(mLabel); 732 parcel.writeInt(mHorizontalDpi); 733 parcel.writeInt(mVerticalDpi); 734 } 735 736 static Resolution createFromParcel(Parcel parcel) { 737 return new Resolution( 738 parcel.readString(), 739 parcel.readString(), 740 parcel.readInt(), 741 parcel.readInt()); 742 } 743 744 @Override 745 public int hashCode() { 746 final int prime = 31; 747 int result = 1; 748 result = prime * result + mHorizontalDpi; 749 result = prime * result + mVerticalDpi; 750 return result; 751 } 752 753 @Override 754 public boolean equals(Object obj) { 755 if (this == obj) { 756 return true; 757 } 758 if (obj == null) { 759 return false; 760 } 761 if (getClass() != obj.getClass()) { 762 return false; 763 } 764 Resolution other = (Resolution) obj; 765 if (mHorizontalDpi != other.mHorizontalDpi) { 766 return false; 767 } 768 if (mVerticalDpi != other.mVerticalDpi) { 769 return false; 770 } 771 return true; 772 } 773 774 @Override 775 public String toString() { 776 StringBuilder builder = new StringBuilder(); 777 builder.append("Resolution{"); 778 builder.append("id: ").append(mId); 779 builder.append(", label: ").append(mLabel); 780 builder.append(", horizontalDpi: ").append(mHorizontalDpi); 781 builder.append(", verticalDpi: ").append(mVerticalDpi); 782 builder.append("}"); 783 return builder.toString(); 784 } 785 } 786 787 /** 788 * This class specifies content margins. 789 */ 790 public static final class Margins { 791 public static final Margins NO_MARGINS = new Margins(0, 0, 0, 0); 792 793 private final int mLeftMils; 794 private final int mTopMils; 795 private final int mRightMils; 796 private final int mBottomMils; 797 798 /** 799 * Creates a new instance. 800 * 801 * @param leftMils The left margin in mils (thousands of an inch). 802 * @param topMils The top margin in mils (thousands of an inch). 803 * @param rightMils The right margin in mils (thousands of an inch). 804 * @param bottomMils The bottom margin in mils (thousands of an inch). 805 */ 806 public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { 807 mTopMils = topMils; 808 mLeftMils = leftMils; 809 mRightMils = rightMils; 810 mBottomMils = bottomMils; 811 } 812 813 /** 814 * Gets the left margin in mils (thousands of an inch). 815 * 816 * @return The left margin. 817 */ 818 public int getLeftMils() { 819 return mLeftMils; 820 } 821 822 /** 823 * Gets the top margin in mils (thousands of an inch). 824 * 825 * @return The top margin. 826 */ 827 public int getTopMils() { 828 return mTopMils; 829 } 830 831 /** 832 * Gets the right margin in mils (thousands of an inch). 833 * 834 * @return The right margin. 835 */ 836 public int getRightMils() { 837 return mRightMils; 838 } 839 840 /** 841 * Gets the bottom margin in mils (thousands of an inch). 842 * 843 * @return The bottom margin. 844 */ 845 public int getBottomMils() { 846 return mBottomMils; 847 } 848 849 void writeToParcel(Parcel parcel) { 850 parcel.writeInt(mLeftMils); 851 parcel.writeInt(mTopMils); 852 parcel.writeInt(mRightMils); 853 parcel.writeInt(mBottomMils); 854 } 855 856 static Margins createFromParcel(Parcel parcel) { 857 return new Margins( 858 parcel.readInt(), 859 parcel.readInt(), 860 parcel.readInt(), 861 parcel.readInt()); 862 } 863 864 @Override 865 public int hashCode() { 866 final int prime = 31; 867 int result = 1; 868 result = prime * result + mBottomMils; 869 result = prime * result + mLeftMils; 870 result = prime * result + mRightMils; 871 result = prime * result + mTopMils; 872 return result; 873 } 874 875 @Override 876 public boolean equals(Object obj) { 877 if (this == obj) { 878 return true; 879 } 880 if (obj == null) { 881 return false; 882 } 883 if (getClass() != obj.getClass()) { 884 return false; 885 } 886 Margins other = (Margins) obj; 887 if (mBottomMils != other.mBottomMils) { 888 return false; 889 } 890 if (mLeftMils != other.mLeftMils) { 891 return false; 892 } 893 if (mRightMils != other.mRightMils) { 894 return false; 895 } 896 if (mTopMils != other.mTopMils) { 897 return false; 898 } 899 return true; 900 } 901 902 @Override 903 public String toString() { 904 StringBuilder builder = new StringBuilder(); 905 builder.append("Margins{"); 906 builder.append("leftMils: ").append(mLeftMils); 907 builder.append(", topMils: ").append(mTopMils); 908 builder.append(", rightMils: ").append(mRightMils); 909 builder.append(", bottomMils: ").append(mBottomMils); 910 builder.append("}"); 911 return builder.toString(); 912 } 913 } 914 915 static String colorModeToString(int colorMode) { 916 switch (colorMode) { 917 case COLOR_MODE_MONOCHROME: { 918 return "COLOR_MODE_MONOCHROME"; 919 } 920 case COLOR_MODE_COLOR: { 921 return "COLOR_MODE_COLOR"; 922 } 923 default: 924 return "COLOR_MODE_UNKNOWN"; 925 } 926 } 927 928 static void enforceValidColorMode(int colorMode) { 929 if ((colorMode & VALID_COLOR_MODES) == 0 && Integer.bitCount(colorMode) == 1) { 930 throw new IllegalArgumentException("invalid color mode: " + colorMode); 931 } 932 } 933 934 /** 935 * Builder for creating {@link PrintAttributes}. 936 */ 937 public static final class Builder { 938 private final PrintAttributes mAttributes = new PrintAttributes(); 939 940 /** 941 * Sets the media size. 942 * 943 * @param mediaSize The media size. 944 * @return This builder. 945 */ 946 public Builder setMediaSize(MediaSize mediaSize) { 947 mAttributes.setMediaSize(mediaSize); 948 return this; 949 } 950 951 /** 952 * Sets the resolution. 953 * 954 * @param resolution The resolution. 955 * @return This builder. 956 */ 957 public Builder setResolution(Resolution resolution) { 958 mAttributes.setResolution(resolution); 959 return this; 960 } 961 962 /** 963 * Sets the minimal margins. If the content does not fit 964 * these margins it will be clipped. 965 * 966 * @param margins The margins. 967 * @return This builder. 968 */ 969 public Builder setMinMargins(Margins margins) { 970 mAttributes.setMinMargins(margins); 971 return this; 972 } 973 974 /** 975 * Sets the color mode. 976 * 977 * @param colorMode A valid color mode or zero. 978 * @return This builder. 979 * 980 * @see PrintAttributes#COLOR_MODE_MONOCHROME 981 * @see PrintAttributes#COLOR_MODE_COLOR 982 */ 983 public Builder setColorMode(int colorMode) { 984 if (Integer.bitCount(colorMode) > 1) { 985 throw new IllegalArgumentException("can specify at most one colorMode bit."); 986 } 987 mAttributes.setColorMode(colorMode); 988 return this; 989 } 990 991 /** 992 * Creates a new {@link PrintAttributes} instance. 993 * 994 * @return The new instance. 995 */ 996 public PrintAttributes build() { 997 return mAttributes; 998 } 999 } 1000 1001 public static final Parcelable.Creator<PrintAttributes> CREATOR = 1002 new Creator<PrintAttributes>() { 1003 @Override 1004 public PrintAttributes createFromParcel(Parcel parcel) { 1005 return new PrintAttributes(parcel); 1006 } 1007 1008 @Override 1009 public PrintAttributes[] newArray(int size) { 1010 return new PrintAttributes[size]; 1011 } 1012 }; 1013} 1014