Source for java.awt.RenderingHints

   1: /* RenderingHints.java --
   2:    Copyright (C) 2000, 2001, 2002, 2004, 2005  Free Software Foundation
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.awt;
  40: 
  41: import java.util.Collection;
  42: import java.util.Collections;
  43: import java.util.HashMap;
  44: import java.util.Iterator;
  45: import java.util.Map;
  46: import java.util.Set;
  47: 
  48: /**
  49:  * A collection of (key, value) items that provide 'hints' for the 
  50:  * {@link java.awt.Graphics2D} rendering pipeline.  Because these
  51:  * items are hints only, they may be ignored by a particular
  52:  * {@link java.awt.Graphics2D} implementation.
  53:  *
  54:  * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
  55:  * @author Eric Blake (ebb9@email.byu.edu)
  56:  */
  57: public class RenderingHints implements Map, Cloneable
  58: {
  59:   /**
  60:    * The base class used to represent keys.
  61:    */
  62:   public abstract static class Key
  63:   {
  64:     private final int key;
  65: 
  66:     /**
  67:      * Creates a new key.
  68:      * 
  69:      * @param privateKey  the private key.
  70:      */
  71:     protected Key(int privateKey)
  72:     {
  73:       key = privateKey;
  74:     }
  75: 
  76:     /**
  77:      * Returns <code>true</code> if the specified value is compatible with
  78:      * this key, and <code>false</code> otherwise.
  79:      * 
  80:      * @param value  the value (<code>null</code> permitted).
  81:      * 
  82:      * @return A boolean.
  83:      */
  84:     public abstract boolean isCompatibleValue(Object value);
  85: 
  86:     /**
  87:      * Returns the private key for this instance.
  88:      * 
  89:      * @return The private key.
  90:      */
  91:     protected final int intKey()
  92:     {
  93:       return key;
  94:     }
  95: 
  96:     /**
  97:      * Returns a hash code for the key.
  98:      * 
  99:      * @return A hash code.
 100:      */
 101:     public final int hashCode()
 102:     {
 103:       return System.identityHashCode(this);
 104:     }
 105: 
 106:     /**
 107:      * Checks this key for equality with an arbitrary object.
 108:      * 
 109:      * @param other  the object (<code>null</code> permitted)
 110:      * 
 111:      * @return A boolean.
 112:      */
 113:     public final boolean equals(Object other)
 114:     {
 115:       return this == other;
 116:     }
 117:   } // class Key
 118: 
 119:   private static final class KeyImpl extends Key
 120:   {
 121:     final String description;
 122:     final Object v1;
 123:     final Object v2;
 124:     final Object v3;
 125: 
 126:     KeyImpl(int privateKey, String description,
 127:             Object v1, Object v2, Object v3)
 128:     {
 129:       super(privateKey);
 130:       this.description = description;
 131:       this.v1 = v1;
 132:       this.v2 = v2;
 133:       this.v3 = v3;
 134:     }
 135: 
 136:     /**
 137:      * Returns <code>true</code> if the specified value is compatible with
 138:      * this key, and <code>false</code> otherwise.
 139:      * 
 140:      * @param value  the value (<code>null</code> permitted).
 141:      * 
 142:      * @return A boolean.
 143:      */
 144:     public boolean isCompatibleValue(Object value)
 145:     {
 146:       return value == v1 || value == v2 || value == v3;
 147:     }
 148: 
 149:     /**
 150:      * Returns a string representation of the key.
 151:      * 
 152:      * @return A string.
 153:      */
 154:     public String toString()
 155:     {
 156:       return description;
 157:     }
 158:   } // class KeyImpl
 159: 
 160:   private HashMap hintMap = new HashMap();
 161: 
 162:   /**
 163:    * A key for the 'antialiasing' hint.  Permitted values are:
 164:    * <p>
 165:    * <table>
 166:    * <tr>
 167:    *   <td>{@link #VALUE_ANTIALIAS_OFF}</td>
 168:    *   <td>Render without antialiasing (better speed).</td>
 169:    * </tr>
 170:    * <tr>
 171:    *   <td>{@link #VALUE_ANTIALIAS_ON}</td>
 172:    *   <td>Render with antialiasing (better quality).</td>
 173:    * </tr>
 174:    * <tr>
 175:    *   <td>{@link #VALUE_ANTIALIAS_DEFAULT}</td>
 176:    *   <td>Use the default value for antialiasing.</td>
 177:    * </tr>
 178:    * </table>
 179:    */
 180:   public static final Key KEY_ANTIALIASING;
 181: 
 182:   /**
 183:    * This value is for use with the {@link #KEY_ANTIALIASING} key.
 184:    */
 185:   public static final Object VALUE_ANTIALIAS_ON
 186:     = "Antialiased rendering mode";
 187: 
 188:   /**
 189:    * This value is for use with the {@link #KEY_ANTIALIASING} key.
 190:    */
 191:   public static final Object VALUE_ANTIALIAS_OFF
 192:     = "Nonantialiased rendering mode";
 193: 
 194:   /**
 195:    * This value is for use with the {@link #KEY_ANTIALIASING} key.
 196:    */
 197:   public static final Object VALUE_ANTIALIAS_DEFAULT
 198:     = "Default antialiasing rendering mode";
 199: 
 200:   /**
 201:    * A key for the 'rendering' hint.  Permitted values are:
 202:    * <p>
 203:    * <table>
 204:    * <tr>
 205:    *   <td>{@link #VALUE_RENDER_SPEED}</td>
 206:    *   <td>Prefer speed over quality when rendering.</td>
 207:    * </tr>
 208:    * <tr>
 209:    *   <td>{@link #VALUE_RENDER_QUALITY}</td>
 210:    *   <td>Prefer quality over speed when rendering.</td>
 211:    * </tr>
 212:    * <tr>
 213:    *   <td>{@link #VALUE_RENDER_DEFAULT}</td>
 214:    *   <td>Use the default value for quality vs. speed when rendering.</td>
 215:    * </tr>
 216:    * </table>
 217:    */
 218:   public static final Key KEY_RENDERING;
 219: 
 220:   /**
 221:    * This value is for use with the {@link #KEY_RENDERING} key.
 222:    */
 223:   public static final Object VALUE_RENDER_SPEED
 224:     = "Fastest rendering methods";
 225: 
 226:   /**
 227:    * This value is for use with the {@link #KEY_RENDERING} key.
 228:    */
 229:   public static final Object VALUE_RENDER_QUALITY
 230:     = "Highest quality rendering methods";
 231: 
 232:   /**
 233:    * This value is for use with the {@link #KEY_RENDERING} key.
 234:    */
 235:   public static final Object VALUE_RENDER_DEFAULT
 236:     = "Default rendering methods";
 237: 
 238:   /**
 239:    * A key for the 'dithering' hint.  Permitted values are:
 240:    * <p>
 241:    * <table>
 242:    * <tr>
 243:    *   <td>{@link #VALUE_DITHER_DISABLE}</td>
 244:    *   <td>Disable dithering.</td>
 245:    * </tr>
 246:    * <tr>
 247:    *   <td>{@link #VALUE_DITHER_ENABLE}</td>
 248:    *   <td>Enable dithering.</td>
 249:    * </tr>
 250:    * <tr>
 251:    *   <td>{@link #VALUE_DITHER_DEFAULT}</td>
 252:    *   <td>Use the default value for dithering.</td>
 253:    * </tr>
 254:    * </table>
 255:    */
 256:   public static final Key KEY_DITHERING;
 257: 
 258:   /**
 259:    * This value is for use with the {@link #KEY_DITHERING} key.
 260:    */
 261:   public static final Object VALUE_DITHER_DISABLE
 262:     = "Nondithered rendering mode";
 263: 
 264:   /**
 265:    * This value is for use with the {@link #KEY_DITHERING} key.
 266:    */
 267:   public static final Object VALUE_DITHER_ENABLE
 268:     = "Dithered rendering mode";
 269: 
 270:   /**
 271:    * This value is for use with the {@link #KEY_DITHERING} key.
 272:    */
 273:   public static final Object VALUE_DITHER_DEFAULT
 274:     = "Default dithering mode";
 275: 
 276:   /**
 277:    * A key for the 'text antialiasing' hint.  Permitted values are:
 278:    * <p>
 279:    * <table>
 280:    * <tr>
 281:    *   <td>{@link #VALUE_TEXT_ANTIALIAS_ON}</td>
 282:    *   <td>Render text with antialiasing (better quality usually).</td>
 283:    * </tr>
 284:    * <tr>
 285:    *   <td>{@link #VALUE_TEXT_ANTIALIAS_OFF}</td>
 286:    *   <td>Render test without antialiasing (better speed).</td>
 287:    * </tr>
 288:    * <tr>
 289:    *   <td>{@link #VALUE_TEXT_ANTIALIAS_DEFAULT}</td>
 290:    *   <td>Use the default value for text antialiasing.</td>
 291:    * </tr>
 292:    * </table>
 293:    */
 294:   public static final Key KEY_TEXT_ANTIALIASING;
 295: 
 296:   /**
 297:    * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
 298:    */
 299:   public static final Object VALUE_TEXT_ANTIALIAS_ON
 300:     = "Antialiased text mode";
 301: 
 302:   /**
 303:    * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
 304:    */
 305:   public static final Object VALUE_TEXT_ANTIALIAS_OFF
 306:     = "Nonantialiased text mode";
 307: 
 308:   /**
 309:    * This value is for use with the {@link #KEY_TEXT_ANTIALIASING} key.
 310:    */
 311:   public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT
 312:     = "Default antialiasing text mode";
 313: 
 314:   /**
 315:    * A key for the 'fractional metrics' hint.  Permitted values are:
 316:    * <p>
 317:    * <table>
 318:    * <tr>
 319:    *   <td>{@link #VALUE_FRACTIONALMETRICS_OFF}</td>
 320:    *   <td>Render text with fractional metrics off.</td>
 321:    * </tr>
 322:    * <tr>
 323:    *   <td>{@link #VALUE_FRACTIONALMETRICS_ON}</td>
 324:    *   <td>Render text with fractional metrics on.</td>
 325:    * </tr>
 326:    * <tr>
 327:    *   <td>{@link #VALUE_FRACTIONALMETRICS_DEFAULT}</td>
 328:    *   <td>Use the default value for fractional metrics.</td>
 329:    * </tr>
 330:    * </table>
 331:    */
 332:   public static final Key KEY_FRACTIONALMETRICS;
 333: 
 334:   /**
 335:    * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
 336:    */
 337:   public static final Object VALUE_FRACTIONALMETRICS_OFF
 338:     = "Integer text metrics mode";
 339: 
 340:   /**
 341:    * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
 342:    */
 343:   public static final Object VALUE_FRACTIONALMETRICS_ON
 344:     = "Fractional text metrics mode";
 345: 
 346:   /**
 347:    * This value is for use with the {@link #KEY_FRACTIONALMETRICS} key.
 348:    */
 349:   public static final Object VALUE_FRACTIONALMETRICS_DEFAULT
 350:     = "Default fractional text metrics mode";
 351: 
 352:   /**
 353:    * A key for the 'interpolation' hint.  Permitted values are:
 354:    * <p>
 355:    * <table>
 356:    * <tr>
 357:    *   <td>{@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR}</td>
 358:    *   <td>Use nearest neighbour interpolation.</td>
 359:    * </tr>
 360:    * <tr>
 361:    *   <td>{@link #VALUE_INTERPOLATION_BILINEAR}</td>
 362:    *   <td>Use bilinear interpolation.</td>
 363:    * </tr>
 364:    * <tr>
 365:    *   <td>{@link #VALUE_INTERPOLATION_BICUBIC}</td>
 366:    *   <td>Use bicubic interpolation.</td>
 367:    * </tr>
 368:    * </table>
 369:    */
 370:   public static final Key KEY_INTERPOLATION;
 371: 
 372:   /**
 373:    * This value is for use with the {@link #KEY_INTERPOLATION} key.
 374:    */
 375:   public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR
 376:     = "Nearest Neighbor image interpolation mode";
 377: 
 378:   /**
 379:    * This value is for use with the {@link #KEY_INTERPOLATION} key.
 380:    */
 381:   public static final Object VALUE_INTERPOLATION_BILINEAR
 382:     = "Bilinear image interpolation mode";
 383: 
 384:   /**
 385:    * This value is for use with the {@link #KEY_INTERPOLATION} key.
 386:    */
 387:   public static final Object VALUE_INTERPOLATION_BICUBIC
 388:     = "Bicubic image interpolation mode";
 389: 
 390:   /**
 391:    * A key for the 'alpha interpolation' hint.  Permitted values are:
 392:    * <p>
 393:    * <table>
 394:    * <tr>
 395:    *   <td>{@link #VALUE_ALPHA_INTERPOLATION_SPEED}</td>
 396:    *   <td>Prefer speed over quality.</td>
 397:    * </tr>
 398:    * <tr>
 399:    *   <td>{@link #VALUE_ALPHA_INTERPOLATION_QUALITY}</td>
 400:    *   <td>Prefer quality over speed.</td>
 401:    * </tr>
 402:    * <tr>
 403:    *   <td>{@link #VALUE_ALPHA_INTERPOLATION_DEFAULT}</td>
 404:    *   <td>Use the default setting.</td>
 405:    * </tr>
 406:    * </table>
 407:    */
 408:   public static final Key KEY_ALPHA_INTERPOLATION;
 409: 
 410:   /**
 411:    * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
 412:    */
 413:   public static final Object VALUE_ALPHA_INTERPOLATION_SPEED
 414:     = "Fastest alpha blending methods";
 415: 
 416:   /**
 417:    * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
 418:    */
 419:   public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY
 420:     = "Highest quality alpha blending methods";
 421: 
 422:   /**
 423:    * This value is for use with the {@link #KEY_ALPHA_INTERPOLATION} key.
 424:    */
 425:   public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT
 426:     = "Default alpha blending methods";
 427: 
 428:   /**
 429:    * A key for the 'color rendering' hint.  Permitted values are:
 430:    * <p>
 431:    * <table>
 432:    * <tr>
 433:    *   <td>{@link #VALUE_COLOR_RENDER_SPEED}</td>
 434:    *   <td>Prefer speed over quality.</td>
 435:    * </tr>
 436:    * <tr>
 437:    *   <td>{@link #VALUE_COLOR_RENDER_QUALITY}</td>
 438:    *   <td>Prefer quality over speed.</td>
 439:    * </tr>
 440:    * <tr>
 441:    *   <td>{@link #VALUE_COLOR_RENDER_DEFAULT}</td>
 442:    *   <td>Use the default setting.</td>
 443:    * </tr>
 444:    * </table>
 445:    */
 446:   public static final Key KEY_COLOR_RENDERING;
 447: 
 448:   /**
 449:    * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
 450:    */
 451:   public static final Object VALUE_COLOR_RENDER_SPEED
 452:     = "Fastest color rendering mode";
 453: 
 454:   /**
 455:    * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
 456:    */
 457:   public static final Object VALUE_COLOR_RENDER_QUALITY
 458:     = "Highest quality color rendering mode";
 459: 
 460:   /**
 461:    * This value is for use with the {@link #KEY_COLOR_RENDERING} key.
 462:    */
 463:   public static final Object VALUE_COLOR_RENDER_DEFAULT
 464:     = "Default color rendering mode";
 465: 
 466:   /**
 467:    * A key for the 'stroke control' hint.  Permitted values are:
 468:    * <p>
 469:    * <table>
 470:    * <tr>
 471:    *   <td>{@link #VALUE_STROKE_DEFAULT}</td>
 472:    *   <td>Use the default setting.</td>
 473:    * </tr>
 474:    * <tr>
 475:    *   <td>{@link #VALUE_STROKE_NORMALIZE}</td>
 476:    *   <td>XXX</td>
 477:    * </tr>
 478:    * <tr>
 479:    *   <td>{@link #VALUE_STROKE_PURE}</td>
 480:    *   <td>XXX</td>
 481:    * </tr>
 482:    * </table>
 483:    */
 484:   public static final Key KEY_STROKE_CONTROL;
 485: 
 486:   /**
 487:    * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
 488:    */
 489:   public static final Object VALUE_STROKE_DEFAULT
 490:     = "Default stroke normalization";
 491: 
 492:   /**
 493:    * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
 494:    */
 495:   public static final Object VALUE_STROKE_NORMALIZE
 496:     = "Normalize strokes for consistent rendering";
 497: 
 498:   /**
 499:    * This value is for use with the {@link #KEY_STROKE_CONTROL} key.
 500:    */
 501:   public static final Object VALUE_STROKE_PURE
 502:     = "Pure stroke conversion for accurate paths";
 503: 
 504:   static
 505:   {
 506:     KEY_ANTIALIASING = new KeyImpl(1, "Global antialiasing enable key",
 507:                                    VALUE_ANTIALIAS_ON,
 508:                                    VALUE_ANTIALIAS_OFF,
 509:                                    VALUE_ANTIALIAS_DEFAULT);
 510:     KEY_RENDERING = new KeyImpl(2, "Global rendering quality key",
 511:                                 VALUE_RENDER_SPEED,
 512:                                 VALUE_RENDER_QUALITY,
 513:                                 VALUE_RENDER_DEFAULT);
 514:     KEY_DITHERING = new KeyImpl(3, "Dithering quality key",
 515:                                 VALUE_DITHER_DISABLE,
 516:                                 VALUE_DITHER_ENABLE,
 517:                                 VALUE_DITHER_DEFAULT);
 518:     KEY_TEXT_ANTIALIASING
 519:       = new KeyImpl(4, "Text-specific antialiasing enable key",
 520:                     VALUE_TEXT_ANTIALIAS_ON,
 521:                     VALUE_TEXT_ANTIALIAS_OFF,
 522:                     VALUE_TEXT_ANTIALIAS_DEFAULT);
 523:     KEY_FRACTIONALMETRICS = new KeyImpl(5, "Fractional metrics enable key",
 524:                                         VALUE_FRACTIONALMETRICS_OFF,
 525:                                         VALUE_FRACTIONALMETRICS_ON,
 526:                                         VALUE_FRACTIONALMETRICS_DEFAULT);
 527:     KEY_INTERPOLATION = new KeyImpl(6, "Image interpolation method key",
 528:                                     VALUE_INTERPOLATION_NEAREST_NEIGHBOR,
 529:                                     VALUE_INTERPOLATION_BILINEAR,
 530:                                     VALUE_INTERPOLATION_BICUBIC);
 531:     KEY_ALPHA_INTERPOLATION
 532:       = new KeyImpl(7, "Alpha blending interpolation method key",
 533:                     VALUE_ALPHA_INTERPOLATION_SPEED,
 534:                     VALUE_ALPHA_INTERPOLATION_QUALITY,
 535:                     VALUE_ALPHA_INTERPOLATION_DEFAULT);
 536:     KEY_COLOR_RENDERING = new KeyImpl(8, "Color rendering quality key",
 537:                                       VALUE_COLOR_RENDER_SPEED,
 538:                                       VALUE_COLOR_RENDER_QUALITY,
 539:                                       VALUE_COLOR_RENDER_DEFAULT);
 540:     KEY_STROKE_CONTROL = new KeyImpl(9, "Stroke normalization control key",
 541:                                      VALUE_STROKE_DEFAULT,
 542:                                      VALUE_STROKE_NORMALIZE,
 543:                                      VALUE_STROKE_PURE);
 544:   }
 545: 
 546:   /**
 547:    * Creates a new collection of hints containing all the (key, value) pairs
 548:    * in the specified map.
 549:    * 
 550:    * @param init  a map containing a collection of hints (<code>null</code> 
 551:    *              permitted).
 552:    */
 553:   public RenderingHints(Map init)
 554:   {
 555:     if (init != null)
 556:       putAll(init);
 557:   }
 558: 
 559:   /**
 560:    * Creates a new collection containing a single (key, value) pair.
 561:    * 
 562:    * @param key  the key.
 563:    * @param value  the value.
 564:    */
 565:   public RenderingHints(Key key, Object value)
 566:   {
 567:     put(key, value);
 568:   }
 569: 
 570:   /**
 571:    * Returns the number of hints in the collection.
 572:    * 
 573:    * @return The number of hints.
 574:    */
 575:   public int size()
 576:   {
 577:     return hintMap.size();
 578:   }
 579: 
 580:   /**
 581:    * Returns <code>true</code> if there are no hints in the collection,
 582:    * and <code>false</code> otherwise.
 583:    * 
 584:    * @return A boolean.
 585:    */
 586:   public boolean isEmpty()
 587:   {
 588:     return hintMap.isEmpty();
 589:   }
 590: 
 591:   /**
 592:    * Returns <code>true</code> if the collection of hints contains the
 593:    * specified key, and <code>false</code> otherwise.
 594:    * 
 595:    * @param key  the key (<code>null</code> not permitted).
 596:    * 
 597:    * @return A boolean.
 598:    * 
 599:    * @throws NullPointerException if <code>key</code> is <code>null</code>.
 600:    * @throws ClassCastException if <code>key</code> is not a {@link Key}.
 601:    */
 602:   public boolean containsKey(Object key)
 603:   {
 604:     if (key == null)
 605:       throw new NullPointerException();
 606:     // don't remove the cast, it is necessary to throw the required exception
 607:     return hintMap.containsKey((Key) key);
 608:   }
 609: 
 610:   /**
 611:    * Returns <code>true</code> if the collection of hints contains the
 612:    * specified value, and <code>false</code> otherwise.
 613:    * 
 614:    * @param value  the value.
 615:    * 
 616:    * @return A boolean.
 617:    */
 618:   public boolean containsValue(Object value)
 619:   {
 620:     return hintMap.containsValue(value);
 621:   }
 622: 
 623:   /**
 624:    * Returns the value associated with the specified key, or <code>null</code>
 625:    * if there is no value defined for the key.
 626:    * 
 627:    * @param key  the key (<code>null</code> permitted).
 628:    * 
 629:    * @return The value (possibly <code>null</code>).
 630:    * 
 631:    * @throws ClassCastException if <code>key</code> is not a {@link Key}.
 632:    * 
 633:    * @see #containsKey(Object)
 634:    */
 635:   public Object get(Object key)
 636:   {
 637:     // don't remove the cast, it is necessary to throw the required exception
 638:     return hintMap.get((Key) key);
 639:   }
 640: 
 641:   /**
 642:    * Adds a (key, value) pair to the collection of hints (if the
 643:    * collection already contains the specified key, then the 
 644:    * value is updated).
 645:    * 
 646:    * @param key  the key.
 647:    * @param value  the value.
 648:    * 
 649:    * @return  the previous value of the key or <code>null</code> if the key
 650:    * didn't have a value yet.
 651:    */
 652:   public Object put(Object key, Object value)
 653:   {
 654:     if (key == null || value == null)
 655:       throw new NullPointerException();
 656:     if (! ((Key) key).isCompatibleValue(value))
 657:       throw new IllegalArgumentException();
 658:     return hintMap.put(key, value);
 659:   }
 660: 
 661:   /**
 662:    * Adds all the hints from a collection to this collection.
 663:    * 
 664:    * @param hints  the hint collection.
 665:    */
 666:   public void add(RenderingHints hints)
 667:   {
 668:     hintMap.putAll(hints);
 669:   }
 670: 
 671:   /**
 672:    * Clears all the hints from this collection.
 673:    */
 674:   public void clear()
 675:   {
 676:     hintMap.clear();
 677:   }
 678: 
 679:   /**
 680:    * Removes a hint from the collection.
 681:    * 
 682:    * @param key  the key.
 683:    * 
 684:    * @return The value that was associated with the key, or <code>null</code> if 
 685:    *         the key was not part of the collection
 686:    * 
 687:    * @throws ClassCastException if the key is not a subclass of 
 688:    *         {@link RenderingHints.Key}.
 689:    */
 690:   public Object remove(Object key)
 691:   {
 692:     // don't remove the (Key) cast, it is necessary to throw the exception
 693:     // required by the spec
 694:     return hintMap.remove((Key) key);  
 695:   }
 696: 
 697:   /**
 698:    * Adds a collection of (key, value) pairs to the collection.
 699:    * 
 700:    * @param m  a map containing (key, value) items.
 701:    * 
 702:    * @throws ClassCastException if the map contains a key that is not
 703:    *         a subclass of {@link RenderingHints.Key}.
 704:    * @throws IllegalArgumentException if the map contains a value that is
 705:    *         not compatible with its key.
 706:    */
 707:   public void putAll(Map m)
 708:   {
 709:     // preprocess map to generate appropriate exceptions
 710:     Iterator iterator = m.keySet().iterator();
 711:     while (iterator.hasNext())
 712:       {
 713:     Key key = (Key) iterator.next();
 714:     if (!key.isCompatibleValue(m.get(key)))
 715:       throw new IllegalArgumentException();
 716:       }
 717:     // map is OK, update
 718:     hintMap.putAll(m);
 719:   }
 720: 
 721:   /**
 722:    * Returns a set containing the keys from this collection.
 723:    * 
 724:    * @return A set of keys.
 725:    */
 726:   public Set keySet()
 727:   {
 728:     return hintMap.keySet();
 729:   }
 730: 
 731:   /**
 732:    * Returns a collection of the values from this hint collection.  The
 733:    * collection is backed by the <code>RenderingHints</code> instance, 
 734:    * so updates to one will affect the other.
 735:    * 
 736:    * @return A collection of values.
 737:    */
 738:   public Collection values()
 739:   {
 740:     return hintMap.values();
 741:   }
 742: 
 743:   /**
 744:    * Returns a set of entries from the collection.
 745:    * 
 746:    * @return A set of entries.
 747:    */
 748:   public Set entrySet()
 749:   {
 750:     return Collections.unmodifiableSet(hintMap.entrySet());
 751:   }
 752: 
 753:   /**
 754:    * Checks this collection for equality with an arbitrary object.
 755:    * 
 756:    * @param o  the object (<code>null</code> permitted)
 757:    * 
 758:    * @return A boolean.
 759:    */
 760:   public boolean equals(Object o)
 761:   {
 762:     return hintMap.equals(o);
 763:   }
 764: 
 765:   /**
 766:    * Returns a hash code for the collection of hints.
 767:    * 
 768:    * @return A hash code.
 769:    */
 770:   public int hashCode()
 771:   {
 772:     return hintMap.hashCode();
 773:   }
 774: 
 775:   /**
 776:    * Creates a clone of this instance.
 777:    * 
 778:    * @return A clone.
 779:    */
 780:   public Object clone()
 781:   {
 782:     try
 783:       {
 784:         RenderingHints copy = (RenderingHints) super.clone();
 785:         copy.hintMap = (HashMap) hintMap.clone();
 786:         return copy;
 787:       }
 788:     catch (CloneNotSupportedException e)
 789:       {
 790:         throw (Error) new InternalError().initCause(e); // Impossible
 791:       }
 792:   }
 793: 
 794:   /**
 795:    * Returns a string representation of this instance.
 796:    * 
 797:    * @return A string.
 798:    */
 799:   public String toString()
 800:   {
 801:     return hintMap.toString();
 802:   }
 803: } // class RenderingHints