OSDN Git Service

2005-02-17 Michael Koch <konqueror@gmx.de>
[pf3gnuchains/gcc-fork.git] / libjava / java / awt / RenderingHints.java
1 /* RenderingHints.java --
2    Copyright (C) 2000, 2001, 2002, 2004  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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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.
596    * 
597    * @return A boolean.
598    */
599   public boolean containsKey(Object key)
600   {
601     if (key == null)
602       throw new NullPointerException();
603     return hintMap.containsKey((Key) key);
604   }
605
606   /**
607    * Returns <code>true</code> if the collection of hints contains the
608    * specified value, and <code>false</code> otherwise.
609    * 
610    * @param value  the value.
611    * 
612    * @return A boolean.
613    */
614   public boolean containsValue(Object value)
615   {
616     return hintMap.containsValue(value);
617   }
618
619   /**
620    * Returns the value associated with the specified key.
621    * 
622    * @param key  the key.
623    * 
624    * @return The value.
625    */
626   public Object get(Object key)
627   {
628     return hintMap.get((Key) key);
629   }
630
631   /**
632    * Adds a (key, value) pair to the collection of hints (if the
633    * collection already contains the specified key, then the 
634    * value is updated).
635    * 
636    * @param key  the key.
637    * @param value  the value.
638    * 
639    * @return  the previous value of the key or <code>null</code> if the key
640    * didn't have a value yet.
641    */
642   public Object put(Object key, Object value)
643   {
644     if (key == null || value == null)
645       throw new NullPointerException();
646     if (! ((Key) key).isCompatibleValue(value))
647       throw new IllegalArgumentException();
648     return hintMap.put(key, value);
649   }
650
651   /**
652    * Adds all the hints from a collection to this collection.
653    * 
654    * @param hints  the hint collection.
655    */
656   public void add(RenderingHints hints)
657   {
658     hintMap.putAll(hints);
659   }
660
661   /**
662    * Clears all the hints from this collection.
663    */
664   public void clear()
665   {
666     hintMap.clear();
667   }
668
669   /**
670    * Removes a hint from the collection.
671    * 
672    * @param key  the key.
673    * 
674    * @return The value that was associated with the key, or <code>null</code> if 
675    *         the key was not part of the collection
676    * 
677    * @throws ClassCastException if the key is not a subclass of 
678    *         {@link RenderingHints.Key}.
679    */
680   public Object remove(Object key)
681   {
682     // don't remove the (Key) cast, it is necessary to throw the exception
683     // required by the spec
684     return hintMap.remove((Key) key);  
685   }
686
687   /**
688    * Adds a collection of (key, value) pairs to the collection.
689    * 
690    * @param m  a map containing (key, value) items.
691    * 
692    * @throws ClassCastException if the map contains a key that is not
693    *         a subclass of {@link RenderingHints.Key}.
694    * @throws IllegalArgumentException if the map contains a value that is
695    *         not compatible with its key.
696    */
697   public void putAll(Map m)
698   {
699     // preprocess map to generate appropriate exceptions
700     Iterator iterator = m.keySet().iterator();
701     while (iterator.hasNext())
702       {
703         Key key = (Key) iterator.next();
704         if (!key.isCompatibleValue(m.get(key)))
705           throw new IllegalArgumentException();
706       }
707     // map is OK, update
708     hintMap.putAll(m);
709   }
710
711   /**
712    * Returns a set containing the keys from this collection.
713    * 
714    * @return A set of keys.
715    */
716   public Set keySet()
717   {
718     return hintMap.keySet();
719   }
720
721   /**
722    * Returns a collection of the values from this hint collection.  The
723    * collection is backed by the <code>RenderingHints</code> instance, 
724    * so updates to one will affect the other.
725    * 
726    * @return A collection of values.
727    */
728   public Collection values()
729   {
730     return hintMap.values();
731   }
732
733   /**
734    * Returns a set of entries from the collection.
735    * 
736    * @return A set of entries.
737    */
738   public Set entrySet()
739   {
740     return Collections.unmodifiableSet(hintMap.entrySet());
741   }
742
743   /**
744    * Checks this collection for equality with an arbitrary object.
745    * 
746    * @param o  the object (<code>null</code> permitted)
747    * 
748    * @return A boolean.
749    */
750   public boolean equals(Object o)
751   {
752     return hintMap.equals(o);
753   }
754
755   /**
756    * Returns a hash code for the collection of hints.
757    * 
758    * @return A hash code.
759    */
760   public int hashCode()
761   {
762     return hintMap.hashCode();
763   }
764
765   /**
766    * Creates a clone of this instance.
767    * 
768    * @return A clone.
769    */
770   public Object clone()
771   {
772     try
773       {
774         RenderingHints copy = (RenderingHints) super.clone();
775         copy.hintMap = (HashMap) hintMap.clone();
776         return copy;
777       }
778     catch (CloneNotSupportedException e)
779       {
780         throw (Error) new InternalError().initCause(e); // Impossible
781       }
782   }
783
784   /**
785    * Returns a string representation of this instance.
786    * 
787    * @return A string.
788    */
789   public String toString()
790   {
791     return hintMap.toString();
792   }
793 } // class RenderingHints