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