001/* RenderingHints.java --
002   Copyright (C) 2000, 2001, 2002, 2004, 2005  Free Software Foundation
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038
039package java.awt;
040
041import java.util.Collection;
042import java.util.Collections;
043import java.util.HashMap;
044import java.util.Iterator;
045import java.util.Map;
046import java.util.Set;
047
048/**
049 * A collection of (key, value) items that provide 'hints' for the 
050 * {@link java.awt.Graphics2D} rendering pipeline.  Because these
051 * items are hints only, they may be ignored by a particular
052 * {@link java.awt.Graphics2D} implementation.
053 *
054 * @author Rolf W. Rasmussen (rolfwr@ii.uib.no)
055 * @author Eric Blake (ebb9@email.byu.edu)
056 */
057public class RenderingHints
058  implements Map<Object,Object>, Cloneable
059{
060  /**
061   * The base class used to represent keys.
062   */
063  public abstract static class Key
064  {
065    private final int key;
066
067    /**
068     * Creates a new key.
069     * 
070     * @param privateKey  the private key.
071     */
072    protected Key(int privateKey)
073    {
074      key = privateKey;
075    }
076
077    /**
078     * Returns <code>true</code> if the specified value is compatible with
079     * this key, and <code>false</code> otherwise.
080     * 
081     * @param value  the value (<code>null</code> permitted).
082     * 
083     * @return A boolean.
084     */
085    public abstract boolean isCompatibleValue(Object value);
086
087    /**
088     * Returns the private key for this instance.
089     * 
090     * @return The private key.
091     */
092    protected final int intKey()
093    {
094      return key;
095    }
096
097    /**
098     * Returns a hash code for the key.
099     * 
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