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