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