PrintAttributes.java revision 773f54de3de9bce7b6f915aa47ed686b161d77aa
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 public MediaSize(String id, String packageName, int labelResId, 417 int widthMils, int heightMils) { 418 if (TextUtils.isEmpty(id)) { 419 throw new IllegalArgumentException("id cannot be empty."); 420 } 421 if (TextUtils.isEmpty(packageName)) { 422 throw new IllegalArgumentException("packageName cannot be empty."); 423 } 424 if (labelResId <= 0) { 425 throw new IllegalArgumentException("labelResId must be greater than zero."); 426 } 427 if (widthMils <= 0) { 428 throw new IllegalArgumentException("widthMils " 429 + "cannot be less than or equal to zero."); 430 } 431 if (heightMils <= 0) { 432 throw new IllegalArgumentException("heightMils " 433 + "cannot be less than or euqual to zero."); 434 } 435 mPackageName = packageName; 436 mId = id; 437 mLabelResId = labelResId; 438 mWidthMils = widthMils; 439 mHeightMils = heightMils; 440 mLabel = null; 441 } 442 443 /** 444 * Creates a new instance. You should use this constructor as a fallback 445 * in cases when you do not have a localized string for the label. 446 * 447 * @param id The unique media size id. 448 * @param label The <strong>internationalized</strong> human readable label. 449 * @param widthMils The width in mils (thousands of an inch). 450 * @param heightMils The height in mils (thousands of an inch). 451 * 452 * @throws IllegalArgumentException If the id is empty. 453 * @throws IllegalArgumentException If the label is empty. 454 * @throws IllegalArgumentException If the widthMils is less than or equal to zero. 455 * @throws IllegalArgumentException If the heightMils is less than or equal to zero. 456 */ 457 public MediaSize(String id, String label, int widthMils, int heightMils) { 458 if (TextUtils.isEmpty(id)) { 459 throw new IllegalArgumentException("id cannot be empty."); 460 } 461 if (TextUtils.isEmpty(label)) { 462 throw new IllegalArgumentException("label cannot be empty."); 463 } 464 if (widthMils <= 0) { 465 throw new IllegalArgumentException("widthMils " 466 + "cannot be less than or equal to zero."); 467 } 468 if (heightMils <= 0) { 469 throw new IllegalArgumentException("heightMils " 470 + "cannot be less than or euqual to zero."); 471 } 472 mId = id; 473 mLabel = label; 474 mWidthMils = widthMils; 475 mHeightMils = heightMils; 476 mLabelResId = 0; 477 mPackageName = null; 478 } 479 480 /** @hide */ 481 public MediaSize(String id, String label, String packageName, 482 int widthMils, int heightMils, int labelResId) { 483 mPackageName = packageName; 484 mId = id; 485 mLabelResId = labelResId; 486 mWidthMils = widthMils; 487 mHeightMils = heightMils; 488 mLabel = label; 489 } 490 491 /** 492 * Gets the unique media size id. 493 * 494 * @return The unique media size id. 495 */ 496 public String getId() { 497 return mId; 498 } 499 500 /** 501 * Gets the human readable media size label. 502 * 503 * @param packageManager The package manager for loading the label. 504 * @return The human readable label. 505 */ 506 public String getLabel(PackageManager packageManager) { 507 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) { 508 try { 509 return packageManager.getResourcesForApplication( 510 mPackageName).getString(mLabelResId); 511 } catch (NotFoundException nfe) { 512 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 513 + " from package " + mPackageName); 514 } catch (NameNotFoundException nnfee) { 515 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 516 + " from package " + mPackageName); 517 } 518 } 519 return mLabel; 520 } 521 522 /** 523 * Gets the media width in mils (thousands of an inch). 524 * 525 * @return The media width. 526 */ 527 public int getWidthMils() { 528 return mWidthMils; 529 } 530 531 /** 532 * Gets the media height in mils (thousands of an inch). 533 * 534 * @return The media height. 535 */ 536 public int getHeightMils() { 537 return mHeightMils; 538 } 539 540 /** 541 * Gets whether this media size is in portrait which is the 542 * height is greater or equal to the width. 543 * 544 * @return True if the media size is in portrait, false if 545 * it is in landscape. 546 */ 547 public boolean isPortrait() { 548 return mHeightMils >= mWidthMils; 549 } 550 551 /** 552 * Returns a new media size in a portrait orientation 553 * which is the height is the lesser dimension. 554 * 555 * @return New instance in landscape orientation. 556 */ 557 public MediaSize asPortrait() { 558 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) { 559 return new MediaSize(mId, mPackageName, mLabelResId, 560 Math.min(mWidthMils, mHeightMils), 561 Math.max(mWidthMils, mHeightMils)); 562 } else { 563 return new MediaSize(mId, mLabel, 564 Math.min(mWidthMils, mHeightMils), 565 Math.max(mWidthMils, mHeightMils)); 566 } 567 } 568 569 /** 570 * Returns a new media size in a landscape orientation 571 * which is the height is the greater dimension. 572 * 573 * @return New instance in landscape orientation. 574 */ 575 public MediaSize asLandscape() { 576 return new MediaSize(mId, mLabel, 577 Math.max(mWidthMils, mHeightMils), 578 Math.min(mWidthMils, mHeightMils)); 579 } 580 581 void writeToParcel(Parcel parcel) { 582 parcel.writeString(mId); 583 parcel.writeString(mLabel); 584 parcel.writeString(mPackageName); 585 parcel.writeInt(mWidthMils); 586 parcel.writeInt(mHeightMils); 587 parcel.writeInt(mLabelResId); 588 } 589 590 static MediaSize createFromParcel(Parcel parcel) { 591 return new MediaSize( 592 parcel.readString(), 593 parcel.readString(), 594 parcel.readString(), 595 parcel.readInt(), 596 parcel.readInt(), 597 parcel.readInt()); 598 } 599 600 @Override 601 public int hashCode() { 602 final int prime = 31; 603 int result = 1; 604 result = prime * result + ((mId == null) ? 0 : mId.hashCode()); 605 result = prime * result + mWidthMils; 606 result = prime * result + mHeightMils; 607 return result; 608 } 609 610 @Override 611 public boolean equals(Object obj) { 612 if (this == obj) { 613 return true; 614 } 615 if (obj == null) { 616 return false; 617 } 618 if (getClass() != obj.getClass()) { 619 return false; 620 } 621 MediaSize other = (MediaSize) obj; 622 if (!TextUtils.equals(mId, other.mId)) { 623 return false; 624 } 625 if (mWidthMils != other.mWidthMils) { 626 return false; 627 } 628 if (mHeightMils != other.mHeightMils) { 629 return false; 630 } 631 return true; 632 } 633 634 @Override 635 public String toString() { 636 StringBuilder builder = new StringBuilder(); 637 builder.append("MediaSize{"); 638 builder.append("id: ").append(mId); 639 builder.append(", label: ").append(mLabel); 640 builder.append(", packageName: ").append(mPackageName); 641 builder.append(", heightMils: ").append(mHeightMils); 642 builder.append(", widthMils: ").append(mWidthMils); 643 builder.append(", labelResId: ").append(mLabelResId); 644 builder.append("}"); 645 return builder.toString(); 646 } 647 } 648 649 /** 650 * This class specifies a supported resolution in dpi (dots per inch). 651 */ 652 public static final class Resolution { 653 private static final String LOG_TAG = "Resolution"; 654 655 private final String mId; 656 /**@hide */ 657 public final String mLabel; 658 /**@hide */ 659 public final String mPackageName; 660 /**@hide */ 661 public final int mLabelResId; 662 private final int mHorizontalDpi; 663 private final int mVerticalDpi; 664 665 /** 666 * Creates a new instance. This is the preferred constructor since 667 * it enables the resolution label to be shown in a localized fashion 668 * on a locale change. 669 * 670 * @param id The unique resolution id. 671 * @param packageName The name of the creating package. 672 * @param labelResId The resource id of a human readable label. 673 * @param horizontalDpi The horizontal resolution in dpi. 674 * @param verticalDpi The vertical resolution in dpi. 675 * 676 * @throws IllegalArgumentException If the id is empty. 677 * @throws IllegalArgumentException If the label is empty. 678 * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero. 679 * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero. 680 */ 681 public Resolution(String id, String packageName, int labelResId, 682 int horizontalDpi, int verticalDpi) { 683 if (TextUtils.isEmpty(id)) { 684 throw new IllegalArgumentException("id cannot be empty."); 685 } 686 if (TextUtils.isEmpty(packageName)) { 687 throw new IllegalArgumentException("packageName cannot be empty."); 688 } 689 if (labelResId <= 0) { 690 throw new IllegalArgumentException("labelResId must be greater than zero."); 691 } 692 if (horizontalDpi <= 0) { 693 throw new IllegalArgumentException("horizontalDpi " 694 + "cannot be less than or equal to zero."); 695 } 696 if (verticalDpi <= 0) { 697 throw new IllegalArgumentException("verticalDpi" 698 + " cannot be less than or equal to zero."); 699 } 700 mId = id; 701 mPackageName = packageName; 702 mLabelResId = labelResId; 703 mHorizontalDpi = horizontalDpi; 704 mVerticalDpi = verticalDpi; 705 mLabel = null; 706 } 707 708 /** 709 * Creates a new instance. You should use this constructor as a fallback 710 * in cases when you do not have a localized string for the label. 711 * 712 * @param id The unique resolution id. 713 * @param label The <strong>internationalized</strong> human readable label. 714 * @param horizontalDpi The horizontal resolution in dpi. 715 * @param verticalDpi The vertical resolution in dpi. 716 * 717 * @throws IllegalArgumentException If the id is empty. 718 * @throws IllegalArgumentException If the label is empty. 719 * @throws IllegalArgumentException If the horizontalDpi is less than or equal to zero. 720 * @throws IllegalArgumentException If the verticalDpi is less than or equal to zero. 721 */ 722 public Resolution(String id, String label, int horizontalDpi, int verticalDpi) { 723 if (TextUtils.isEmpty(id)) { 724 throw new IllegalArgumentException("id cannot be empty."); 725 } 726 if (TextUtils.isEmpty(label)) { 727 throw new IllegalArgumentException("label cannot be empty."); 728 } 729 if (horizontalDpi <= 0) { 730 throw new IllegalArgumentException("horizontalDpi " 731 + "cannot be less than or equal to zero."); 732 } 733 if (verticalDpi <= 0) { 734 throw new IllegalArgumentException("verticalDpi" 735 + " cannot be less than or equal to zero."); 736 } 737 mId = id; 738 mLabel = label; 739 mHorizontalDpi = horizontalDpi; 740 mVerticalDpi = verticalDpi; 741 mPackageName = null; 742 mLabelResId = 0; 743 } 744 745 /** @hide */ 746 public Resolution(String id, String label, String packageName, 747 int horizontalDpi, int verticalDpi, int labelResId) { 748 mId = id; 749 mPackageName = packageName; 750 mLabelResId = labelResId; 751 mHorizontalDpi = horizontalDpi; 752 mVerticalDpi = verticalDpi; 753 mLabel = label; 754 } 755 756 /** 757 * Gets the unique resolution id. 758 * 759 * @return The unique resolution id. 760 */ 761 public String getId() { 762 return mId; 763 } 764 765 /** 766 * Gets the resolution human readable label. 767 * 768 * @param packageManager The package manager for loading the label. 769 * @return The human readable label. 770 */ 771 public String getLabel(PackageManager packageManager) { 772 if (!TextUtils.isEmpty(mPackageName) && mLabelResId > 0) { 773 try { 774 return packageManager.getResourcesForApplication( 775 mPackageName).getString(mLabelResId); 776 } catch (NotFoundException nfe) { 777 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 778 + " from package " + mPackageName); 779 } catch (NameNotFoundException nnfee) { 780 Log.w(LOG_TAG, "Could not load resouce" + mLabelResId 781 + " from package " + mPackageName); 782 } 783 } 784 return mLabel; 785 } 786 787 /** 788 * Gets the vertical resolution in dpi. 789 * 790 * @return The horizontal resolution. 791 */ 792 public int getHorizontalDpi() { 793 return mHorizontalDpi; 794 } 795 796 /** 797 * Gets the vertical resolution in dpi. 798 * 799 * @return The vertical resolution. 800 */ 801 public int getVerticalDpi() { 802 return mVerticalDpi; 803 } 804 805 void writeToParcel(Parcel parcel) { 806 parcel.writeString(mId); 807 parcel.writeString(mLabel); 808 parcel.writeString(mPackageName); 809 parcel.writeInt(mHorizontalDpi); 810 parcel.writeInt(mVerticalDpi); 811 parcel.writeInt(mLabelResId); 812 } 813 814 static Resolution createFromParcel(Parcel parcel) { 815 return new Resolution( 816 parcel.readString(), 817 parcel.readString(), 818 parcel.readString(), 819 parcel.readInt(), 820 parcel.readInt(), 821 parcel.readInt()); 822 } 823 824 @Override 825 public int hashCode() { 826 final int prime = 31; 827 int result = 1; 828 result = prime * result + ((mId == null) ? 0 : mId.hashCode()); 829 result = prime * result + mHorizontalDpi; 830 result = prime * result + mVerticalDpi; 831 return result; 832 } 833 834 @Override 835 public boolean equals(Object obj) { 836 if (this == obj) { 837 return true; 838 } 839 if (obj == null) { 840 return false; 841 } 842 if (getClass() != obj.getClass()) { 843 return false; 844 } 845 Resolution other = (Resolution) obj; 846 if (!TextUtils.equals(mId, other.mId)) { 847 return false; 848 } 849 if (mHorizontalDpi != other.mHorizontalDpi) { 850 return false; 851 } 852 if (mVerticalDpi != other.mVerticalDpi) { 853 return false; 854 } 855 return true; 856 } 857 858 @Override 859 public String toString() { 860 StringBuilder builder = new StringBuilder(); 861 builder.append("Resolution{"); 862 builder.append("id: ").append(mId); 863 builder.append(", label: ").append(mLabel); 864 builder.append(", packageName: ").append(mPackageName); 865 builder.append(", horizontalDpi: ").append(mHorizontalDpi); 866 builder.append(", verticalDpi: ").append(mVerticalDpi); 867 builder.append(", labelResId: ").append(mLabelResId); 868 builder.append("}"); 869 return builder.toString(); 870 } 871 } 872 873 /** 874 * This class specifies content margins. 875 */ 876 public static final class Margins { 877 public static final Margins NO_MARGINS = new Margins(0, 0, 0, 0); 878 879 private final int mLeftMils; 880 private final int mTopMils; 881 private final int mRightMils; 882 private final int mBottomMils; 883 884 /** 885 * Creates a new instance. 886 * 887 * @param leftMils The left margin in mils (thousands of an inch). 888 * @param topMils The top margin in mils (thousands of an inch). 889 * @param rightMils The right margin in mils (thousands of an inch). 890 * @param bottomMils The bottom margin in mils (thousands of an inch). 891 */ 892 public Margins(int leftMils, int topMils, int rightMils, int bottomMils) { 893 if (leftMils > rightMils) { 894 throw new IllegalArgumentException("leftMils cannot be less than rightMils."); 895 } 896 if (topMils > bottomMils) { 897 throw new IllegalArgumentException("topMils cannot be less than bottomMils."); 898 } 899 mTopMils = topMils; 900 mLeftMils = leftMils; 901 mRightMils = rightMils; 902 mBottomMils = bottomMils; 903 } 904 905 /** 906 * Gets the left margin in mils (thousands of an inch). 907 * 908 * @return The left margin. 909 */ 910 public int getLeftMils() { 911 return mLeftMils; 912 } 913 914 /** 915 * Gets the top margin in mils (thousands of an inch). 916 * 917 * @return The top margin. 918 */ 919 public int getTopMils() { 920 return mTopMils; 921 } 922 923 /** 924 * Gets the right margin in mils (thousands of an inch). 925 * 926 * @return The right margin. 927 */ 928 public int getRightMils() { 929 return mRightMils; 930 } 931 932 /** 933 * Gets the bottom margin in mils (thousands of an inch). 934 * 935 * @return The bottom margin. 936 */ 937 public int getBottomMils() { 938 return mBottomMils; 939 } 940 941 void writeToParcel(Parcel parcel) { 942 parcel.writeInt(mLeftMils); 943 parcel.writeInt(mTopMils); 944 parcel.writeInt(mRightMils); 945 parcel.writeInt(mBottomMils); 946 } 947 948 static Margins createFromParcel(Parcel parcel) { 949 return new Margins( 950 parcel.readInt(), 951 parcel.readInt(), 952 parcel.readInt(), 953 parcel.readInt()); 954 } 955 956 @Override 957 public int hashCode() { 958 final int prime = 31; 959 int result = 1; 960 result = prime * result + mBottomMils; 961 result = prime * result + mLeftMils; 962 result = prime * result + mRightMils; 963 result = prime * result + mTopMils; 964 return result; 965 } 966 967 @Override 968 public boolean equals(Object obj) { 969 if (this == obj) { 970 return true; 971 } 972 if (obj == null) { 973 return false; 974 } 975 if (getClass() != obj.getClass()) { 976 return false; 977 } 978 Margins other = (Margins) obj; 979 if (mBottomMils != other.mBottomMils) { 980 return false; 981 } 982 if (mLeftMils != other.mLeftMils) { 983 return false; 984 } 985 if (mRightMils != other.mRightMils) { 986 return false; 987 } 988 if (mTopMils != other.mTopMils) { 989 return false; 990 } 991 return true; 992 } 993 994 @Override 995 public String toString() { 996 StringBuilder builder = new StringBuilder(); 997 builder.append("Margins{"); 998 builder.append("leftMils: ").append(mLeftMils); 999 builder.append(", topMils: ").append(mTopMils); 1000 builder.append(", rightMils: ").append(mRightMils); 1001 builder.append(", bottomMils: ").append(mBottomMils); 1002 builder.append("}"); 1003 return builder.toString(); 1004 } 1005 } 1006 1007 static String colorModeToString(int colorMode) { 1008 switch (colorMode) { 1009 case COLOR_MODE_MONOCHROME: { 1010 return "COLOR_MODE_MONOCHROME"; 1011 } 1012 case COLOR_MODE_COLOR: { 1013 return "COLOR_MODE_COLOR"; 1014 } 1015 default: 1016 return "COLOR_MODE_UNKNOWN"; 1017 } 1018 } 1019 1020 static void enforceValidColorMode(int colorMode) { 1021 if ((colorMode & VALID_COLOR_MODES) == 0 && Integer.bitCount(colorMode) == 1) { 1022 throw new IllegalArgumentException("invalid color mode: " + colorMode); 1023 } 1024 } 1025 1026 /** 1027 * Builder for creating {@link PrintAttributes}. 1028 */ 1029 public static final class Builder { 1030 private final PrintAttributes mAttributes = new PrintAttributes(); 1031 1032 /** 1033 * Sets the media size. 1034 * 1035 * @param mediaSize The media size. 1036 * @return This builder. 1037 */ 1038 public Builder setMediaSize(MediaSize mediaSize) { 1039 mAttributes.setMediaSize(mediaSize); 1040 return this; 1041 } 1042 1043 /** 1044 * Sets the resolution. 1045 * 1046 * @param resolution The resolution. 1047 * @return This builder. 1048 */ 1049 public Builder setResolution(Resolution resolution) { 1050 mAttributes.setResolution(resolution); 1051 return this; 1052 } 1053 1054 /** 1055 * Sets the margins. 1056 * 1057 * @param margins The margins. 1058 * @return This builder. 1059 */ 1060 public Builder setMargins(Margins margins) { 1061 mAttributes.setMargins(margins); 1062 return this; 1063 } 1064 1065 /** 1066 * Sets the color mode. 1067 * 1068 * @param colorMode A valid color mode or zero. 1069 * @return This builder. 1070 * 1071 * @see PrintAttributes#COLOR_MODE_MONOCHROME 1072 * @see PrintAttributes#COLOR_MODE_COLOR 1073 */ 1074 public Builder setColorMode(int colorMode) { 1075 if (Integer.bitCount(colorMode) > 1) { 1076 throw new IllegalArgumentException("can specify at most one colorMode bit."); 1077 } 1078 mAttributes.setColorMode(colorMode); 1079 return this; 1080 } 1081 1082 /** 1083 * Creates a new {@link PrintAttributes} instance. 1084 * 1085 * @return The new instance. 1086 */ 1087 public PrintAttributes create() { 1088 return mAttributes; 1089 } 1090 } 1091 1092 public static final Parcelable.Creator<PrintAttributes> CREATOR = 1093 new Creator<PrintAttributes>() { 1094 @Override 1095 public PrintAttributes createFromParcel(Parcel parcel) { 1096 return new PrintAttributes(parcel); 1097 } 1098 1099 @Override 1100 public PrintAttributes[] newArray(int size) { 1101 return new PrintAttributes[size]; 1102 } 1103 }; 1104} 1105