jdk/src/share/classes/java/awt/RenderingHints.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Sun designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Sun in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    23  * have any questions.
       
    24  */
       
    25 
       
    26 package java.awt;
       
    27 
       
    28 import java.util.Map;
       
    29 import java.util.Set;
       
    30 import java.util.Collection;
       
    31 import java.util.Collections;
       
    32 import java.util.HashMap;
       
    33 import java.util.Iterator;
       
    34 import sun.awt.SunHints;
       
    35 import java.lang.ref.WeakReference;
       
    36 
       
    37 /**
       
    38  * The {@code RenderingHints} class defines and manages collections of
       
    39  * keys and associated values which allow an application to provide input
       
    40  * into the choice of algorithms used by other classes which perform
       
    41  * rendering and image manipulation services.
       
    42  * The {@link java.awt.Graphics2D} class, and classes that implement
       
    43  * {@link java.awt.image.BufferedImageOp} and
       
    44  * {@link java.awt.image.RasterOp} all provide methods to get and
       
    45  * possibly to set individual or groups of {@code RenderingHints}
       
    46  * keys and their associated values.
       
    47  * When those implementations perform any rendering or image manipulation
       
    48  * operations they should examine the values of any {@code RenderingHints}
       
    49  * that were requested by the caller and tailor the algorithms used
       
    50  * accordingly and to the best of their ability.
       
    51  * <p>
       
    52  * Note that since these keys and values are <i>hints</i>, there is
       
    53  * no requirement that a given implementation supports all possible
       
    54  * choices indicated below or that it can respond to requests to
       
    55  * modify its choice of algorithm.
       
    56  * The values of the various hint keys may also interact such that
       
    57  * while all variants of a given key are supported in one situation,
       
    58  * the implementation may be more restricted when the values associated
       
    59  * with other keys are modified.
       
    60  * For example, some implementations may be able to provide several
       
    61  * types of dithering when the antialiasing hint is turned off, but
       
    62  * have little control over dithering when antialiasing is on.
       
    63  * The full set of supported keys and hints may also vary by destination
       
    64  * since runtimes may use different underlying modules to render to
       
    65  * the screen, or to {@link java.awt.image.BufferedImage} objects,
       
    66  * or while printing.
       
    67  * <p>
       
    68  * Implementations are free to ignore the hints completely, but should
       
    69  * try to use an implementation algorithm that is as close as possible
       
    70  * to the request.
       
    71  * If an implementation supports a given algorithm when any value is used
       
    72  * for an associated hint key, then minimally it must do so when the
       
    73  * value for that key is the exact value that specifies the algorithm.
       
    74  * <p>
       
    75  * The keys used to control the hints are all special values that
       
    76  * subclass the associated {@link RenderingHints.Key} class.
       
    77  * Many common hints are expressed below as static constants in this
       
    78  * class, but the list is not meant to be exhaustive.
       
    79  * Other hints may be created by other packages by defining new objects
       
    80  * which subclass the {@code Key} class and defining the associated values.
       
    81  */
       
    82 public class RenderingHints
       
    83     implements Map<Object,Object>, Cloneable
       
    84 {
       
    85     /**
       
    86      * Defines the base type of all keys used along with the
       
    87      * {@link RenderingHints} class to control various
       
    88      * algorithm choices in the rendering and imaging pipelines.
       
    89      * Instances of this class are immutable and unique which
       
    90      * means that tests for matches can be made using the
       
    91      * {@code ==} operator instead of the more expensive
       
    92      * {@code equals()} method.
       
    93      */
       
    94     public abstract static class Key {
       
    95         private static HashMap identitymap = new HashMap(17);
       
    96 
       
    97         private String getIdentity() {
       
    98             // Note that the identity string is dependent on 3 variables:
       
    99             //     - the name of the subclass of Key
       
   100             //     - the identityHashCode of the subclass of Key
       
   101             //     - the integer key of the Key
       
   102             // It is theoretically possible for 2 distinct keys to collide
       
   103             // along all 3 of those attributes in the context of multiple
       
   104             // class loaders, but that occurence will be extremely rare and
       
   105             // we account for that possibility below in the recordIdentity
       
   106             // method by slightly relaxing our uniqueness guarantees if we
       
   107             // end up in that situation.
       
   108             return getClass().getName()+"@"+
       
   109                 Integer.toHexString(System.identityHashCode(getClass()))+":"+
       
   110                 Integer.toHexString(privatekey);
       
   111         }
       
   112 
       
   113         private synchronized static void recordIdentity(Key k) {
       
   114             Object identity = k.getIdentity();
       
   115             Object otherref = identitymap.get(identity);
       
   116             if (otherref != null) {
       
   117                 Key otherkey = (Key) ((WeakReference) otherref).get();
       
   118                 if (otherkey != null && otherkey.getClass() == k.getClass()) {
       
   119                     throw new IllegalArgumentException(identity+
       
   120                                                        " already registered");
       
   121                 }
       
   122                 // Note that this system can fail in a mostly harmless
       
   123                 // way.  If we end up generating the same identity
       
   124                 // String for 2 different classes (a very rare case)
       
   125                 // then we correctly avoid throwing the exception above,
       
   126                 // but we are about to drop through to a statement that
       
   127                 // will replace the entry for the old Key subclass with
       
   128                 // an entry for the new Key subclass.  At that time the
       
   129                 // old subclass will be vulnerable to someone generating
       
   130                 // a duplicate Key instance for it.  We could bail out
       
   131                 // of the method here and let the old identity keep its
       
   132                 // record in the map, but we are more likely to see a
       
   133                 // duplicate key go by for the new class than the old
       
   134                 // one since the new one is probably still in the
       
   135                 // initialization stage.  In either case, the probability
       
   136                 // of loading 2 classes in the same VM with the same name
       
   137                 // and identityHashCode should be nearly impossible.
       
   138             }
       
   139             // Note: Use a weak reference to avoid holding on to extra
       
   140             // objects and classes after they should be unloaded.
       
   141             identitymap.put(identity, new WeakReference(k));
       
   142         }
       
   143 
       
   144         private int privatekey;
       
   145 
       
   146         /**
       
   147          * Construct a key using the indicated private key.  Each
       
   148          * subclass of Key maintains its own unique domain of integer
       
   149          * keys.  No two objects with the same integer key and of the
       
   150          * same specific subclass can be constructed.  An exception
       
   151          * will be thrown if an attempt is made to construct another
       
   152          * object of a given class with the same integer key as a
       
   153          * pre-existing instance of that subclass of Key.
       
   154          * @param privatekey the specified key
       
   155          */
       
   156         protected Key(int privatekey) {
       
   157             this.privatekey = privatekey;
       
   158             recordIdentity(this);
       
   159         }
       
   160 
       
   161         /**
       
   162          * Returns true if the specified object is a valid value
       
   163          * for this Key.
       
   164          * @param val the <code>Object</code> to test for validity
       
   165          * @return <code>true</code> if <code>val</code> is valid;
       
   166          *         <code>false</code> otherwise.
       
   167          */
       
   168         public abstract boolean isCompatibleValue(Object val);
       
   169 
       
   170         /**
       
   171          * Returns the private integer key that the subclass
       
   172          * instantiated this Key with.
       
   173          * @return the private integer key that the subclass
       
   174          * instantiated this Key with.
       
   175          */
       
   176         protected final int intKey() {
       
   177             return privatekey;
       
   178         }
       
   179 
       
   180         /**
       
   181          * The hash code for all Key objects will be the same as the
       
   182          * system identity code of the object as defined by the
       
   183          * System.identityHashCode() method.
       
   184          */
       
   185         public final int hashCode() {
       
   186             return super.hashCode();
       
   187         }
       
   188 
       
   189         /**
       
   190          * The equals method for all Key objects will return the same
       
   191          * result as the equality operator '=='.
       
   192          */
       
   193         public final boolean equals(Object o) {
       
   194             return this == o;
       
   195         }
       
   196     }
       
   197 
       
   198     HashMap hintmap = new HashMap(7);
       
   199 
       
   200     /**
       
   201      * Antialiasing hint key.
       
   202      * The {@code ANTIALIASING} hint controls whether or not the
       
   203      * geometry rendering methods of a {@link Graphics2D} object
       
   204      * will attempt to reduce aliasing artifacts along the edges
       
   205      * of shapes.
       
   206      * <p>
       
   207      * A typical antialiasing algorithm works by blending the existing
       
   208      * colors of the pixels along the boundary of a shape with the
       
   209      * requested fill paint according to the estimated partial pixel
       
   210      * coverage of the shape.
       
   211      * <p>
       
   212      * The allowable values for this hint are
       
   213      * <ul>
       
   214      * <li>{@link #VALUE_ANTIALIAS_ON}
       
   215      * <li>{@link #VALUE_ANTIALIAS_OFF}
       
   216      * <li>{@link #VALUE_ANTIALIAS_DEFAULT}
       
   217      * </ul>
       
   218      */
       
   219     public static final Key KEY_ANTIALIASING =
       
   220         SunHints.KEY_ANTIALIASING;
       
   221 
       
   222     /**
       
   223      * Antialiasing hint value -- rendering is done with antialiasing.
       
   224      * @see #KEY_ANTIALIASING
       
   225      */
       
   226     public static final Object VALUE_ANTIALIAS_ON =
       
   227         SunHints.VALUE_ANTIALIAS_ON;
       
   228 
       
   229     /**
       
   230      * Antialiasing hint value -- rendering is done without antialiasing.
       
   231      * @see #KEY_ANTIALIASING
       
   232      */
       
   233     public static final Object VALUE_ANTIALIAS_OFF =
       
   234         SunHints.VALUE_ANTIALIAS_OFF;
       
   235 
       
   236     /**
       
   237      * Antialiasing hint value -- rendering is done with a default
       
   238      * antialiasing mode chosen by the implementation.
       
   239      * @see #KEY_ANTIALIASING
       
   240      */
       
   241     public static final Object VALUE_ANTIALIAS_DEFAULT =
       
   242          SunHints.VALUE_ANTIALIAS_DEFAULT;
       
   243 
       
   244     /**
       
   245      * Rendering hint key.
       
   246      * The {@code RENDERING} hint is a general hint that provides
       
   247      * a high level recommendation as to whether to bias algorithm
       
   248      * choices more for speed or quality when evaluating tradeoffs.
       
   249      * This hint could be consulted for any rendering or image
       
   250      * manipulation operation, but decisions will usually honor
       
   251      * other, more specific hints in preference to this hint.
       
   252      * <p>
       
   253      * The allowable values for this hint are
       
   254      * <ul>
       
   255      * <li>{@link #VALUE_RENDER_SPEED}
       
   256      * <li>{@link #VALUE_RENDER_QUALITY}
       
   257      * <li>{@link #VALUE_RENDER_DEFAULT}
       
   258      * </ul>
       
   259      */
       
   260     public static final Key KEY_RENDERING =
       
   261          SunHints.KEY_RENDERING;
       
   262 
       
   263     /**
       
   264      * Rendering hint value -- rendering algorithms are chosen
       
   265      * with a preference for output speed.
       
   266      * @see #KEY_RENDERING
       
   267      */
       
   268     public static final Object VALUE_RENDER_SPEED =
       
   269          SunHints.VALUE_RENDER_SPEED;
       
   270 
       
   271     /**
       
   272      * Rendering hint value -- rendering algorithms are chosen
       
   273      * with a preference for output quality.
       
   274      * @see #KEY_RENDERING
       
   275      */
       
   276     public static final Object VALUE_RENDER_QUALITY =
       
   277          SunHints.VALUE_RENDER_QUALITY;
       
   278 
       
   279     /**
       
   280      * Rendering hint value -- rendering algorithms are chosen
       
   281      * by the implementation for a good tradeoff of performance
       
   282      * vs. quality.
       
   283      * @see #KEY_RENDERING
       
   284      */
       
   285     public static final Object VALUE_RENDER_DEFAULT =
       
   286          SunHints.VALUE_RENDER_DEFAULT;
       
   287 
       
   288     /**
       
   289      * Dithering hint key.
       
   290      * The {@code DITHERING} hint controls how closely to approximate
       
   291      * a color when storing into a destination with limited color
       
   292      * resolution.
       
   293      * <p>
       
   294      * Some rendering destinations may support a limited number of
       
   295      * color choices which may not be able to accurately represent
       
   296      * the full spectrum of colors that can result during rendering
       
   297      * operations.
       
   298      * For such a destination the {@code DITHERING} hint controls
       
   299      * whether rendering is done with a flat solid fill of a single
       
   300      * pixel value which is the closest supported color to what was
       
   301      * requested, or whether shapes will be filled with a pattern of
       
   302      * colors which combine to better approximate that color.
       
   303      * <p>
       
   304      * The allowable values for this hint are
       
   305      * <ul>
       
   306      * <li>{@link #VALUE_DITHER_DISABLE}
       
   307      * <li>{@link #VALUE_DITHER_ENABLE}
       
   308      * <li>{@link #VALUE_DITHER_DEFAULT}
       
   309      * </ul>
       
   310      */
       
   311     public static final Key KEY_DITHERING =
       
   312          SunHints.KEY_DITHERING;
       
   313 
       
   314     /**
       
   315      * Dithering hint value -- do not dither when rendering geometry.
       
   316      * @see #KEY_DITHERING
       
   317      */
       
   318     public static final Object VALUE_DITHER_DISABLE =
       
   319          SunHints.VALUE_DITHER_DISABLE;
       
   320 
       
   321     /**
       
   322      * Dithering hint value -- dither when rendering geometry, if needed.
       
   323      * @see #KEY_DITHERING
       
   324      */
       
   325     public static final Object VALUE_DITHER_ENABLE =
       
   326          SunHints.VALUE_DITHER_ENABLE;
       
   327 
       
   328     /**
       
   329      * Dithering hint value -- use a default for dithering chosen by
       
   330      * the implementation.
       
   331      * @see #KEY_DITHERING
       
   332      */
       
   333     public static final Object VALUE_DITHER_DEFAULT =
       
   334          SunHints.VALUE_DITHER_DEFAULT;
       
   335 
       
   336     /**
       
   337      * Text antialiasing hint key.
       
   338      * The {@code TEXT_ANTIALIASING} hint can control the use of
       
   339      * antialiasing algorithms for text independently of the
       
   340      * choice used for shape rendering.
       
   341      * Often an application may want to use antialiasing for text
       
   342      * only and not for other shapes.
       
   343      * Additionally, the algorithms for reducing the aliasing
       
   344      * artifacts for text are often more sophisticated than those
       
   345      * that have been developed for general rendering so this
       
   346      * hint key provides additional values which can control
       
   347      * the choices of some of those text-specific algorithms.
       
   348      * If left in the {@code DEFAULT} state, this hint will
       
   349      * generally defer to the value of the regular
       
   350      * {@link #KEY_ANTIALIASING} hint key.
       
   351      * <p>
       
   352      * The allowable values for this hint are
       
   353      * <ul>
       
   354      * <li>{@link #VALUE_TEXT_ANTIALIAS_ON}
       
   355      * <li>{@link #VALUE_TEXT_ANTIALIAS_OFF}
       
   356      * <li>{@link #VALUE_TEXT_ANTIALIAS_DEFAULT}
       
   357      * <li>{@link #VALUE_TEXT_ANTIALIAS_GASP}
       
   358      * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB}
       
   359      * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_HBGR}
       
   360      * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_VRGB}
       
   361      * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_VBGR}
       
   362      * </ul>
       
   363      */
       
   364     public static final Key KEY_TEXT_ANTIALIASING =
       
   365          SunHints.KEY_TEXT_ANTIALIASING;
       
   366 
       
   367     /**
       
   368      * Text antialiasing hint value -- text rendering is done with
       
   369      * some form of antialiasing.
       
   370      * @see #KEY_TEXT_ANTIALIASING
       
   371      */
       
   372     public static final Object VALUE_TEXT_ANTIALIAS_ON =
       
   373          SunHints.VALUE_TEXT_ANTIALIAS_ON;
       
   374 
       
   375     /**
       
   376      * Text antialiasing hint value -- text rendering is done without
       
   377      * any form of antialiasing.
       
   378      * @see #KEY_TEXT_ANTIALIASING
       
   379      */
       
   380     public static final Object VALUE_TEXT_ANTIALIAS_OFF =
       
   381          SunHints.VALUE_TEXT_ANTIALIAS_OFF;
       
   382 
       
   383     /**
       
   384      * Text antialiasing hint value -- text rendering is done according
       
   385      * to the {@link #KEY_ANTIALIASING} hint or a default chosen by the
       
   386      * implementation.
       
   387      * @see #KEY_TEXT_ANTIALIASING
       
   388      */
       
   389     public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT =
       
   390          SunHints.VALUE_TEXT_ANTIALIAS_DEFAULT;
       
   391 
       
   392     /**
       
   393      * Text antialiasing hint value -- text rendering is requested to
       
   394      * use information in the font resource which specifies for each point
       
   395      * size whether to apply {@link #VALUE_TEXT_ANTIALIAS_ON} or
       
   396      * {@link #VALUE_TEXT_ANTIALIAS_OFF}.
       
   397      * <p>
       
   398      * TrueType fonts typically provide this information in the 'gasp' table.
       
   399      * In the absence of this information, the behaviour for a particular
       
   400      * font and size is determined by implementation defaults.
       
   401      * <p>
       
   402      * <i>Note:</i>A font designer will typically carefully hint a font for
       
   403      * the most common user interface point sizes. Consequently the 'gasp'
       
   404      * table will likely specify to use only hinting at those sizes and not
       
   405      * "smoothing". So in many cases the resulting text display is
       
   406      * equivalent to {@code VALUE_TEXT_ANTIALIAS_OFF}.
       
   407      * This may be unexpected but is correct.
       
   408      * <p>
       
   409      * Logical fonts which are composed of multiple physical fonts will for
       
   410      * consistency will use the setting most appropriate for the overall
       
   411      * composite font.
       
   412      *
       
   413      * @see #KEY_TEXT_ANTIALIASING
       
   414      * @since 1.6
       
   415      */
       
   416     public static final Object VALUE_TEXT_ANTIALIAS_GASP =
       
   417          SunHints.VALUE_TEXT_ANTIALIAS_GASP;
       
   418 
       
   419     /**
       
   420      * Text antialiasing hint value -- request that text be displayed
       
   421      * optimised for an LCD display with subpixels in order from display
       
   422      * left to right of R,G,B such that the horizontal subpixel resolution
       
   423      * is three times that of the full pixel horizontal resolution (HRGB).
       
   424      * This is the most common configuration.
       
   425      * Selecting this hint for displays with one of the other LCD subpixel
       
   426      * configurations will likely result in unfocused text.
       
   427      * <p>
       
   428      * <i>Notes:</i><br>
       
   429      * An implementation when choosing whether to apply any of the
       
   430      * LCD text hint values may take into account factors including requiring
       
   431      * color depth of the destination to be at least 15 bits per pixel
       
   432      * (ie 5 bits per color component),
       
   433      * characteristics of a font such as whether embedded bitmaps may
       
   434      * produce better results, or when displaying to a non-local networked
       
   435      * display device enabling it only if suitable protocols are available,
       
   436      * or ignoring the hint if performing very high resolution rendering
       
   437      * or the target device is not appropriate: eg when printing.
       
   438      * <p>
       
   439      * These hints can equally be applied when rendering to software images,
       
   440      * but these images may not then be suitable for general export, as the
       
   441      * text will have been rendered appropriately for a specific subpixel
       
   442      * organisation. Also lossy images are not a good choice, nor image
       
   443      * formats such as GIF which have limited colors.
       
   444      * So unless the image is destined solely for rendering on a
       
   445      * display device with the same configuration, some other text
       
   446      * anti-aliasing hint such as
       
   447      * {@link #VALUE_TEXT_ANTIALIAS_ON}
       
   448      * may be a better choice.
       
   449      * <p>Selecting a value which does not match the LCD display in use
       
   450      * will likely lead to a degradation in text quality.
       
   451      * On display devices (ie CRTs) which do not have the same characteristics
       
   452      * as LCD displays, the overall effect may appear similar to standard text
       
   453      * anti-aliasing, but the quality may be degraded by color distortion.
       
   454      * Analog connected LCD displays may also show little advantage over
       
   455      * standard text-antialiasing and be similar to CRTs.
       
   456      * <p>
       
   457      * In other words for the best results use an LCD display with a digital
       
   458      * display connector and specify the appropriate sub-pixel configuration.
       
   459      *
       
   460      * @see #KEY_TEXT_ANTIALIASING
       
   461      * @since 1.6
       
   462      */
       
   463     public static final Object VALUE_TEXT_ANTIALIAS_LCD_HRGB =
       
   464          SunHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;
       
   465 
       
   466     /**
       
   467      * Text antialiasing hint value -- request that text be displayed
       
   468      * optimised for an LCD display with subpixels in order from display
       
   469      * left to right of B,G,R such that the horizontal subpixel resolution
       
   470      * is three times that of the full pixel horizontal resolution (HBGR).
       
   471      * This is a much less common configuration than HRGB.
       
   472      * Selecting this hint for displays with one of the other LCD subpixel
       
   473      * configurations will likely result in unfocused text.
       
   474      * See {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB},
       
   475      * for more information on when this hint is applied.
       
   476      *
       
   477      * @see #KEY_TEXT_ANTIALIASING
       
   478      * @since 1.6
       
   479      */
       
   480     public static final Object VALUE_TEXT_ANTIALIAS_LCD_HBGR =
       
   481          SunHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;
       
   482 
       
   483     /**
       
   484      * Text antialiasing hint value -- request that text be displayed
       
   485      * optimised for an LCD display with subpixel organisation from display
       
   486      * top to bottom of R,G,B such that the vertical subpixel resolution is
       
   487      * three times that of the full pixel vertical resolution (VRGB).
       
   488      * Vertical orientation is very uncommon and probably mainly useful
       
   489      * for a physically rotated display.
       
   490      * Selecting this hint for displays with one of the other LCD subpixel
       
   491      * configurations will likely result in unfocused text.
       
   492      * See {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB},
       
   493      * for more information on when this hint is applied.
       
   494      *
       
   495      * @see #KEY_TEXT_ANTIALIASING
       
   496      * @since 1.6
       
   497      */
       
   498     public static final Object VALUE_TEXT_ANTIALIAS_LCD_VRGB =
       
   499          SunHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;
       
   500 
       
   501     /**
       
   502      * Text antialiasing hint value -- request that text be displayed
       
   503      * optimised for an LCD display with subpixel organisation from display
       
   504      * top to bottom of B,G,R such that the vertical subpixel resolution is
       
   505      * three times that of the full pixel vertical resolution (VBGR).
       
   506      * Vertical orientation is very uncommon and probably mainly useful
       
   507      * for a physically rotated display.
       
   508      * Selecting this hint for displays with one of the other LCD subpixel
       
   509      * configurations will likely result in unfocused text.
       
   510      * See {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB},
       
   511      * for more information on when this hint is applied.
       
   512      *
       
   513      * @see #KEY_TEXT_ANTIALIASING
       
   514      * @since 1.6
       
   515      */
       
   516     public static final Object VALUE_TEXT_ANTIALIAS_LCD_VBGR =
       
   517          SunHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;
       
   518 
       
   519 
       
   520     /**
       
   521      * LCD text contrast rendering hint key.
       
   522      * The value is an <code>Integer</code> object which is used as a text
       
   523      * contrast adjustment when used in conjunction with an LCD text
       
   524      * anti-aliasing hint such as
       
   525      * {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB}.
       
   526      * <ul>
       
   527      * <li>Values should be a positive integer in the range 100 to 250.
       
   528      * <li>A lower value (eg 100) corresponds to higher contrast text when
       
   529      * displaying dark text on a light background.
       
   530      * <li>A higher value (eg 200) corresponds to lower contrast text when
       
   531      * displaying dark text on a light background.
       
   532      * <li>A typical useful value is in the narrow range 140-180.
       
   533      * <li>If no value is specified, a system or implementation default value
       
   534      * will be applied.
       
   535      * </ul>
       
   536      * The default value can be expected to be adequate for most purposes,
       
   537      * so clients should rarely need to specify a value for this hint unless
       
   538      * they have concrete information as to an appropriate value.
       
   539      * A higher value does not mean a higher contrast, in fact the opposite
       
   540      * is true.
       
   541      * The correction is applied in a similar manner to a gamma adjustment
       
   542      * for non-linear perceptual luminance response of display systems, but
       
   543      * does not indicate a full correction for this.
       
   544      *
       
   545      * @see #KEY_TEXT_ANTIALIASING
       
   546      * @since 1.6
       
   547      */
       
   548     public static final Key KEY_TEXT_LCD_CONTRAST =
       
   549         SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST;
       
   550 
       
   551     /**
       
   552      * Font fractional metrics hint key.
       
   553      * The {@code FRACTIONALMETRICS} hint controls whether the positioning
       
   554      * of individual character glyphs takes into account the sub-pixel
       
   555      * accuracy of the scaled character advances of the font or whether
       
   556      * such advance vectors are rounded to an integer number of whole
       
   557      * device pixels.
       
   558      * This hint only recommends how much accuracy should be used to
       
   559      * position the glyphs and does not specify or recommend whether or
       
   560      * not the actual rasterization or pixel bounds of the glyph should
       
   561      * be modified to match.
       
   562      * <p>
       
   563      * Rendering text to a low resolution device like a screen will
       
   564      * necessarily involve a number of rounding operations as the
       
   565      * high quality and very precise definition of the shape and
       
   566      * metrics of the character glyphs must be matched to discrete
       
   567      * device pixels.
       
   568      * Ideally the positioning of glyphs during text layout would be
       
   569      * calculated by scaling the design metrics in the font according
       
   570      * to the point size, but then the scaled advance width will not
       
   571      * necessarily be an integer number of pixels.
       
   572      * If the glyphs are positioned with sub-pixel accuracy according
       
   573      * to these scaled design metrics then the rasterization would
       
   574      * ideally need to be adjusted for each possible sub-pixel origin.
       
   575      * <p>
       
   576      * Unfortunately, scaling each glyph customized to its exact
       
   577      * subpixel origin during text layout would be prohibitively
       
   578      * expensive so a simplified system based on integer device
       
   579      * positions is typically used to lay out the text.
       
   580      * The rasterization of the glyph and the scaled advance width
       
   581      * are both adjusted together to yield text that looks good at
       
   582      * device resolution and has consistent integer pixel distances
       
   583      * between glyphs that help the glyphs look uniformly and
       
   584      * consistently spaced and readable.
       
   585      * <p>
       
   586      * This process of rounding advance widths for rasterized glyphs
       
   587      * to integer distances means that the character density and the
       
   588      * overall length of a string of text will be different from the
       
   589      * theoretical design measurements due to the accumulation of
       
   590      * a series of small differences in the adjusted widths of
       
   591      * each glyph.
       
   592      * The specific differences will be different for each glyph,
       
   593      * some being wider and some being narrower than their theoretical
       
   594      * design measurements.
       
   595      * Thus the overall difference in character density and length
       
   596      * will vary by a number of factors including the font, the
       
   597      * specific device resolution being targeted, and the glyphs
       
   598      * chosen to represent the string being rendered.
       
   599      * As a result, rendering the same string at multiple device
       
   600      * resolutions can yield widely varying metrics for whole strings.
       
   601      * <p>
       
   602      * When {@code FRACTIONALMETRICS} are enabled, the true font design
       
   603      * metrics are scaled by the point size and used for layout with
       
   604      * sub-pixel accuracy.
       
   605      * The average density of glyphs and total length of a long
       
   606      * string of characters will therefore more closely match the
       
   607      * theoretical design of the font, but readability may be affected
       
   608      * since individual pairs of characters may not always appear to
       
   609      * be consistent distances apart depending on how the sub-pixel
       
   610      * accumulation of the glyph origins meshes with the device pixel
       
   611      * grid.
       
   612      * Enabling this hint may be desirable when text layout is being
       
   613      * performed that must be consistent across a wide variety of
       
   614      * output resolutions.
       
   615      * Specifically, this hint may be desirable in situations where
       
   616      * the layout of text is being previewed on a low resolution
       
   617      * device like a screen for output that will eventually be
       
   618      * rendered on a high resolution printer or typesetting device.
       
   619      * <p>
       
   620      * When disabled, the scaled design metrics are rounded or adjusted
       
   621      * to integer distances for layout.
       
   622      * The distances between any specific pair of glyphs will be more
       
   623      * uniform on the device, but the density and total length of long
       
   624      * strings may no longer match the theoretical intentions of the
       
   625      * font designer.
       
   626      * Disabling this hint will typically produce more readable results
       
   627      * on low resolution devices like computer monitors.
       
   628      * <p>
       
   629      * The allowable values for this key are
       
   630      * <ul>
       
   631      * <li>{@link #VALUE_FRACTIONALMETRICS_OFF}
       
   632      * <li>{@link #VALUE_FRACTIONALMETRICS_ON}
       
   633      * <li>{@link #VALUE_FRACTIONALMETRICS_DEFAULT}
       
   634      * </ul>
       
   635      */
       
   636     public static final Key KEY_FRACTIONALMETRICS =
       
   637          SunHints.KEY_FRACTIONALMETRICS;
       
   638 
       
   639     /**
       
   640      * Font fractional metrics hint value -- character glyphs are
       
   641      * positioned with advance widths rounded to pixel boundaries.
       
   642      * @see #KEY_FRACTIONALMETRICS
       
   643      */
       
   644     public static final Object VALUE_FRACTIONALMETRICS_OFF =
       
   645          SunHints.VALUE_FRACTIONALMETRICS_OFF;
       
   646 
       
   647     /**
       
   648      * Font fractional metrics hint value -- character glyphs are
       
   649      * positioned with sub-pixel accuracy.
       
   650      * @see #KEY_FRACTIONALMETRICS
       
   651      */
       
   652     public static final Object VALUE_FRACTIONALMETRICS_ON =
       
   653          SunHints.VALUE_FRACTIONALMETRICS_ON;
       
   654 
       
   655     /**
       
   656      * Font fractional metrics hint value -- character glyphs are
       
   657      * positioned with accuracy chosen by the implementation.
       
   658      * @see #KEY_FRACTIONALMETRICS
       
   659      */
       
   660     public static final Object VALUE_FRACTIONALMETRICS_DEFAULT =
       
   661          SunHints.VALUE_FRACTIONALMETRICS_DEFAULT;
       
   662 
       
   663     /**
       
   664      * Interpolation hint key.
       
   665      * The {@code INTERPOLATION} hint controls how image pixels are
       
   666      * filtered or resampled during an image rendering operation.
       
   667      * <p>
       
   668      * Implicitly images are defined to provide color samples at
       
   669      * integer coordinate locations.
       
   670      * When images are rendered upright with no scaling onto a
       
   671      * destination, the choice of which image pixels map to which
       
   672      * device pixels is obvious and the samples at the integer
       
   673      * coordinate locations in the image are transfered to the
       
   674      * pixels at the corresponding integer locations on the device
       
   675      * pixel grid one for one.
       
   676      * When images are rendered in a scaled, rotated, or otherwise
       
   677      * transformed coordinate system, then the mapping of device
       
   678      * pixel coordinates back to the image can raise the question
       
   679      * of what color sample to use for the continuous coordinates
       
   680      * that lie between the integer locations of the provided image
       
   681      * samples.
       
   682      * Interpolation algorithms define functions which provide a
       
   683      * color sample for any continuous coordinate in an image based
       
   684      * on the color samples at the surrounding integer coordinates.
       
   685      * <p>
       
   686      * The allowable values for this hint are
       
   687      * <ul>
       
   688      * <li>{@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR}
       
   689      * <li>{@link #VALUE_INTERPOLATION_BILINEAR}
       
   690      * <li>{@link #VALUE_INTERPOLATION_BICUBIC}
       
   691      * </ul>
       
   692      */
       
   693     public static final Key KEY_INTERPOLATION =
       
   694          SunHints.KEY_INTERPOLATION;
       
   695 
       
   696     /**
       
   697      * Interpolation hint value -- the color sample of the nearest
       
   698      * neighboring integer coordinate sample in the image is used.
       
   699      * Conceptually the image is viewed as a grid of unit-sized
       
   700      * square regions of color centered around the center of each
       
   701      * image pixel.
       
   702      * <p>
       
   703      * As the image is scaled up, it will look correspondingly blocky.
       
   704      * As the image is scaled down, the colors for source pixels will
       
   705      * be either used unmodified, or skipped entirely in the output
       
   706      * representation.
       
   707      *
       
   708      * @see #KEY_INTERPOLATION
       
   709      */
       
   710     public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR =
       
   711          SunHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
       
   712 
       
   713     /**
       
   714      * Interpolation hint value -- the color samples of the 4 nearest
       
   715      * neighboring integer coordinate samples in the image are
       
   716      * interpolated linearly to produce a color sample.
       
   717      * Conceptually the image is viewed as a set of infinitely small
       
   718      * point color samples which have value only at the centers of
       
   719      * integer coordinate pixels and the space between those pixel
       
   720      * centers is filled with linear ramps of colors that connect
       
   721      * adjacent discrete samples in a straight line.
       
   722      * <p>
       
   723      * As the image is scaled up, there are no blocky edges between
       
   724      * the colors in the image as there are with
       
   725      * {@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR NEAREST_NEIGHBOR},
       
   726      * but the blending may show some subtle discontinuities along the
       
   727      * horizontal and vertical edges that line up with the samples
       
   728      * caused by a sudden change in the slope of the interpolation
       
   729      * from one side of a sample to the other.
       
   730      * As the image is scaled down, more image pixels have their
       
   731      * color samples represented in the resulting output since each
       
   732      * output pixel recieves color information from up to 4 image
       
   733      * pixels.
       
   734      *
       
   735      * @see #KEY_INTERPOLATION
       
   736      */
       
   737     public static final Object VALUE_INTERPOLATION_BILINEAR =
       
   738          SunHints.VALUE_INTERPOLATION_BILINEAR;
       
   739 
       
   740     /**
       
   741      * Interpolation hint value -- the color samples of 9 nearby
       
   742      * integer coordinate samples in the image are interpolated using
       
   743      * a cubic function in both {@code X} and {@code Y} to produce
       
   744      * a color sample.
       
   745      * Conceptually the view of the image is very similar to the view
       
   746      * used in the {@link #VALUE_INTERPOLATION_BILINEAR BILINEAR}
       
   747      * algorithm except that the ramps of colors that connect between
       
   748      * the samples are curved and have better continuity of slope
       
   749      * as they cross over between sample boundaries.
       
   750      * <p>
       
   751      * As the image is scaled up, there are no blocky edges and the
       
   752      * interpolation should appear smoother and with better depictions
       
   753      * of any edges in the original image than with {@code BILINEAR}.
       
   754      * As the image is scaled down, even more of the original color
       
   755      * samples from the original image will have their color information
       
   756      * carried through and represented.
       
   757      *
       
   758      * @see #KEY_INTERPOLATION
       
   759      */
       
   760     public static final Object VALUE_INTERPOLATION_BICUBIC =
       
   761          SunHints.VALUE_INTERPOLATION_BICUBIC;
       
   762 
       
   763     /**
       
   764      * Alpha interpolation hint key.
       
   765      * The {@code ALPHA_INTERPOLATION} hint is a general hint that
       
   766      * provides a high level recommendation as to whether to bias
       
   767      * alpha blending algorithm choices more for speed or quality
       
   768      * when evaluating tradeoffs.
       
   769      * <p>
       
   770      * This hint could control the choice of alpha blending
       
   771      * calculations that sacrifice some precision to use fast
       
   772      * lookup tables or lower precision SIMD instructions.
       
   773      * This hint could also control whether or not the color
       
   774      * and alpha values are converted into a linear color space
       
   775      * during the calculations for a more linear visual effect
       
   776      * at the expense of additional per-pixel calculations.
       
   777      * <p>
       
   778      * The allowable values for this hint are
       
   779      * <ul>
       
   780      * <li>{@link #VALUE_ALPHA_INTERPOLATION_SPEED}
       
   781      * <li>{@link #VALUE_ALPHA_INTERPOLATION_QUALITY}
       
   782      * <li>{@link #VALUE_ALPHA_INTERPOLATION_DEFAULT}
       
   783      * </ul>
       
   784      */
       
   785     public static final Key KEY_ALPHA_INTERPOLATION =
       
   786          SunHints.KEY_ALPHA_INTERPOLATION;
       
   787 
       
   788     /**
       
   789      * Alpha interpolation hint value -- alpha blending algorithms
       
   790      * are chosen with a preference for calculation speed.
       
   791      * @see #KEY_ALPHA_INTERPOLATION
       
   792      */
       
   793     public static final Object VALUE_ALPHA_INTERPOLATION_SPEED =
       
   794          SunHints.VALUE_ALPHA_INTERPOLATION_SPEED;
       
   795 
       
   796     /**
       
   797      * Alpha interpolation hint value -- alpha blending algorithms
       
   798      * are chosen with a preference for precision and visual quality.
       
   799      * @see #KEY_ALPHA_INTERPOLATION
       
   800      */
       
   801     public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY =
       
   802          SunHints.VALUE_ALPHA_INTERPOLATION_QUALITY;
       
   803 
       
   804     /**
       
   805      * Alpha interpolation hint value -- alpha blending algorithms
       
   806      * are chosen by the implementation for a good tradeoff of
       
   807      * performance vs. quality.
       
   808      * @see #KEY_ALPHA_INTERPOLATION
       
   809      */
       
   810     public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT =
       
   811          SunHints.VALUE_ALPHA_INTERPOLATION_DEFAULT;
       
   812 
       
   813     /**
       
   814      * Color rendering hint key.
       
   815      * The {@code COLOR_RENDERING} hint controls the accuracy of
       
   816      * approximation and conversion when storing colors into a
       
   817      * destination image or surface.
       
   818      * <p>
       
   819      * When a rendering or image manipulation operation produces
       
   820      * a color value that must be stored into a destination, it
       
   821      * must first convert that color into a form suitable for
       
   822      * storing into the destination image or surface.
       
   823      * Minimally, the color components must be converted to bit
       
   824      * representations and ordered in the correct order or an
       
   825      * index into a color lookup table must be chosen before
       
   826      * the data can be stored into the destination memory.
       
   827      * Without this minimal conversion, the data in the destination
       
   828      * would likely represent random, incorrect or possibly even
       
   829      * unsupported values.
       
   830      * Algorithms to quickly convert the results of rendering
       
   831      * operations into the color format of most common destinations
       
   832      * are well known and fairly optimal to execute.
       
   833      * <p>
       
   834      * Simply performing the most basic color format conversion to
       
   835      * store colors into a destination can potentially ignore a
       
   836      * difference in the calibration of the
       
   837      * {@link java.awt.color.ColorSpace}
       
   838      * of the source and destination or other factors such as the
       
   839      * linearity of the gamma correction.
       
   840      * Unless the source and destination {@code ColorSpace} are
       
   841      * identical, to correctly perform a rendering operation with
       
   842      * the most care taken for the accuracy of the colors being
       
   843      * represented, the source colors should be converted to a
       
   844      * device independent {@code ColorSpace} and the results then
       
   845      * converted back to the destination {@code ColorSpace}.
       
   846      * Furthermore, if calculations such as the blending of multiple
       
   847      * source colors are to be performed during the rendering
       
   848      * operation, greater visual clarity can be achieved if the
       
   849      * intermediate device independent {@code ColorSpace} is
       
   850      * chosen to have a linear relationship between the values
       
   851      * being calculated and the perception of the human eye to
       
   852      * the response curves of the output device.
       
   853      * <p>
       
   854      * The allowable values for this hint are
       
   855      * <ul>
       
   856      * <li>{@link #VALUE_COLOR_RENDER_SPEED}
       
   857      * <li>{@link #VALUE_COLOR_RENDER_QUALITY}
       
   858      * <li>{@link #VALUE_COLOR_RENDER_DEFAULT}
       
   859      * </ul>
       
   860      */
       
   861     public static final Key KEY_COLOR_RENDERING =
       
   862          SunHints.KEY_COLOR_RENDERING;
       
   863 
       
   864     /**
       
   865      * Color rendering hint value -- perform the fastest color
       
   866      * conversion to the format of the output device.
       
   867      * @see #KEY_COLOR_RENDERING
       
   868      */
       
   869     public static final Object VALUE_COLOR_RENDER_SPEED =
       
   870          SunHints.VALUE_COLOR_RENDER_SPEED;
       
   871 
       
   872     /**
       
   873      * Color rendering hint value -- perform the color conversion
       
   874      * calculations with the highest accuracy and visual quality.
       
   875      * @see #KEY_COLOR_RENDERING
       
   876      */
       
   877     public static final Object VALUE_COLOR_RENDER_QUALITY =
       
   878          SunHints.VALUE_COLOR_RENDER_QUALITY;
       
   879 
       
   880     /**
       
   881      * Color rendering hint value -- perform color conversion
       
   882      * calculations as chosen by the implementation to represent
       
   883      * the best available tradeoff between performance and
       
   884      * accuracy.
       
   885      * @see #KEY_COLOR_RENDERING
       
   886      */
       
   887     public static final Object VALUE_COLOR_RENDER_DEFAULT =
       
   888          SunHints.VALUE_COLOR_RENDER_DEFAULT;
       
   889 
       
   890     /**
       
   891      * Stroke normalization control hint key.
       
   892      * The {@code STROKE_CONTROL} hint controls whether a rendering
       
   893      * implementation should or is allowed to modify the geometry
       
   894      * of rendered shapes for various purposes.
       
   895      * <p>
       
   896      * Some implementations may be able to use an optimized platform
       
   897      * rendering library which may be faster than traditional software
       
   898      * rendering algorithms on a given platform, but which may also
       
   899      * not support floating point coordinates.
       
   900      * Some implementations may also have sophisticated algorithms
       
   901      * which perturb the coordinates of a path so that wide lines
       
   902      * appear more uniform in width and spacing.
       
   903      * <p>
       
   904      * If an implementation performs any type of modification or
       
   905      * "normalization" of a path, it should never move the coordinates
       
   906      * by more than half a pixel in any direction.
       
   907      * <p>
       
   908      * The allowable values for this hint are
       
   909      * <ul>
       
   910      * <li>{@link #VALUE_STROKE_NORMALIZE}
       
   911      * <li>{@link #VALUE_STROKE_PURE}
       
   912      * <li>{@link #VALUE_STROKE_DEFAULT}
       
   913      * </ul>
       
   914      * @since 1.3
       
   915      */
       
   916     public static final Key KEY_STROKE_CONTROL =
       
   917         SunHints.KEY_STROKE_CONTROL;
       
   918 
       
   919     /**
       
   920      * Stroke normalization control hint value -- geometry may be
       
   921      * modified or left pure depending on the tradeoffs in a given
       
   922      * implementation.
       
   923      * Typically this setting allows an implementation to use a fast
       
   924      * integer coordinate based platform rendering library, but does
       
   925      * not specifically request normalization for uniformity or
       
   926      * aesthetics.
       
   927      *
       
   928      * @see #KEY_STROKE_CONTROL
       
   929      * @since 1.3
       
   930      */
       
   931     public static final Object VALUE_STROKE_DEFAULT =
       
   932         SunHints.VALUE_STROKE_DEFAULT;
       
   933 
       
   934     /**
       
   935      * Stroke normalization control hint value -- geometry should
       
   936      * be normalized to improve uniformity or spacing of lines and
       
   937      * overall aesthetics.
       
   938      * Note that different normalization algorithms may be more
       
   939      * successful than others for given input paths.
       
   940      *
       
   941      * @see #KEY_STROKE_CONTROL
       
   942      * @since 1.3
       
   943      */
       
   944     public static final Object VALUE_STROKE_NORMALIZE =
       
   945         SunHints.VALUE_STROKE_NORMALIZE;
       
   946 
       
   947     /**
       
   948      * Stroke normalization control hint value -- geometry should
       
   949      * be left unmodified and rendered with sub-pixel accuracy.
       
   950      *
       
   951      * @see #KEY_STROKE_CONTROL
       
   952      * @since 1.3
       
   953      */
       
   954     public static final Object VALUE_STROKE_PURE =
       
   955         SunHints.VALUE_STROKE_PURE;
       
   956 
       
   957     /**
       
   958      * Constructs a new object with keys and values initialized
       
   959      * from the specified Map object which may be null.
       
   960      * @param init a map of key/value pairs to initialize the hints
       
   961      *          or null if the object should be empty
       
   962      */
       
   963     public RenderingHints(Map<Key,?> init) {
       
   964         if (init != null) {
       
   965             hintmap.putAll(init);
       
   966         }
       
   967     }
       
   968 
       
   969     /**
       
   970      * Constructs a new object with the specified key/value pair.
       
   971      * @param key the key of the particular hint property
       
   972      * @param value the value of the hint property specified with
       
   973      * <code>key</code>
       
   974      */
       
   975     public RenderingHints(Key key, Object value) {
       
   976         hintmap.put(key, value);
       
   977     }
       
   978 
       
   979     /**
       
   980      * Returns the number of key-value mappings in this
       
   981      * <code>RenderingHints</code>.
       
   982      *
       
   983      * @return the number of key-value mappings in this
       
   984      * <code>RenderingHints</code>.
       
   985      */
       
   986     public int size() {
       
   987         return hintmap.size();
       
   988     }
       
   989 
       
   990     /**
       
   991      * Returns <code>true</code> if this
       
   992      * <code>RenderingHints</code> contains no key-value mappings.
       
   993      *
       
   994      * @return <code>true</code> if this
       
   995      * <code>RenderingHints</code> contains no key-value mappings.
       
   996      */
       
   997     public boolean isEmpty() {
       
   998         return hintmap.isEmpty();
       
   999     }
       
  1000 
       
  1001     /**
       
  1002      * Returns <code>true</code> if this <code>RenderingHints</code>
       
  1003      *  contains a mapping for the specified key.
       
  1004      *
       
  1005      * @param key key whose presence in this
       
  1006      * <code>RenderingHints</code> is to be tested.
       
  1007      * @return <code>true</code> if this <code>RenderingHints</code>
       
  1008      *          contains a mapping for the specified key.
       
  1009      * @exception <code>ClassCastException</code> if the key can not
       
  1010      *            be cast to <code>RenderingHints.Key</code>
       
  1011      */
       
  1012     public boolean containsKey(Object key) {
       
  1013         return hintmap.containsKey((Key) key);
       
  1014     }
       
  1015 
       
  1016     /**
       
  1017      * Returns true if this RenderingHints maps one or more keys to the
       
  1018      * specified value.
       
  1019      * More formally, returns <code>true</code> if and only
       
  1020      * if this <code>RenderingHints</code>
       
  1021      * contains at least one mapping to a value <code>v</code> such that
       
  1022      * <pre>
       
  1023      * (value==null ? v==null : value.equals(v))
       
  1024      * </pre>.
       
  1025      * This operation will probably require time linear in the
       
  1026      * <code>RenderingHints</code> size for most implementations
       
  1027      * of <code>RenderingHints</code>.
       
  1028      *
       
  1029      * @param value value whose presence in this
       
  1030      *          <code>RenderingHints</code> is to be tested.
       
  1031      * @return <code>true</code> if this <code>RenderingHints</code>
       
  1032      *           maps one or more keys to the specified value.
       
  1033      */
       
  1034     public boolean containsValue(Object value) {
       
  1035         return hintmap.containsValue(value);
       
  1036     }
       
  1037 
       
  1038     /**
       
  1039      * Returns the value to which the specified key is mapped.
       
  1040      * @param   key   a rendering hint key
       
  1041      * @return  the value to which the key is mapped in this object or
       
  1042      *          <code>null</code> if the key is not mapped to any value in
       
  1043      *          this object.
       
  1044      * @exception <code>ClassCastException</code> if the key can not
       
  1045      *            be cast to <code>RenderingHints.Key</code>
       
  1046      * @see     #put(Object, Object)
       
  1047      */
       
  1048     public Object get(Object key) {
       
  1049         return hintmap.get((Key) key);
       
  1050     }
       
  1051 
       
  1052     /**
       
  1053      * Maps the specified <code>key</code> to the specified
       
  1054      * <code>value</code> in this <code>RenderingHints</code> object.
       
  1055      * Neither the key nor the value can be <code>null</code>.
       
  1056      * The value can be retrieved by calling the <code>get</code> method
       
  1057      * with a key that is equal to the original key.
       
  1058      * @param      key     the rendering hint key.
       
  1059      * @param      value   the rendering hint value.
       
  1060      * @return     the previous value of the specified key in this object
       
  1061      *             or <code>null</code> if it did not have one.
       
  1062      * @exception <code>NullPointerException</code> if the key is
       
  1063      *            <code>null</code>.
       
  1064      * @exception <code>ClassCastException</code> if the key can not
       
  1065      *            be cast to <code>RenderingHints.Key</code>
       
  1066      * @exception <code>IllegalArgumentException</code> if the
       
  1067      *            {@link Key#isCompatibleValue(java.lang.Object)
       
  1068      *                   Key.isCompatibleValue()}
       
  1069      *            method of the specified key returns false for the
       
  1070      *            specified value
       
  1071      * @see     #get(Object)
       
  1072      */
       
  1073     public Object put(Object key, Object value) {
       
  1074         if (!((Key) key).isCompatibleValue(value)) {
       
  1075             throw new IllegalArgumentException(value+
       
  1076                                                " incompatible with "+
       
  1077                                                key);
       
  1078         }
       
  1079         return hintmap.put((Key) key, value);
       
  1080     }
       
  1081 
       
  1082     /**
       
  1083      * Adds all of the keys and corresponding values from the specified
       
  1084      * <code>RenderingHints</code> object to this
       
  1085      * <code>RenderingHints</code> object. Keys that are present in
       
  1086      * this <code>RenderingHints</code> object, but not in the specified
       
  1087      * <code>RenderingHints</code> object are not affected.
       
  1088      * @param hints the set of key/value pairs to be added to this
       
  1089      * <code>RenderingHints</code> object
       
  1090      */
       
  1091     public void add(RenderingHints hints) {
       
  1092         hintmap.putAll(hints.hintmap);
       
  1093     }
       
  1094 
       
  1095     /**
       
  1096      * Clears this <code>RenderingHints</code> object of all key/value
       
  1097      * pairs.
       
  1098      */
       
  1099     public void clear() {
       
  1100         hintmap.clear();
       
  1101     }
       
  1102 
       
  1103     /**
       
  1104      * Removes the key and its corresponding value from this
       
  1105      * <code>RenderingHints</code> object. This method does nothing if the
       
  1106      * key is not in this <code>RenderingHints</code> object.
       
  1107      * @param   key   the rendering hints key that needs to be removed
       
  1108      * @exception <code>ClassCastException</code> if the key can not
       
  1109      *            be cast to <code>RenderingHints.Key</code>
       
  1110      * @return  the value to which the key had previously been mapped in this
       
  1111      *          <code>RenderingHints</code> object, or <code>null</code>
       
  1112      *          if the key did not have a mapping.
       
  1113      */
       
  1114     public Object remove(Object key) {
       
  1115         return hintmap.remove((Key) key);
       
  1116     }
       
  1117 
       
  1118     /**
       
  1119      * Copies all of the mappings from the specified <code>Map</code>
       
  1120      * to this <code>RenderingHints</code>.  These mappings replace
       
  1121      * any mappings that this <code>RenderingHints</code> had for any
       
  1122      * of the keys currently in the specified <code>Map</code>.
       
  1123      * @param m the specified <code>Map</code>
       
  1124      * @exception <code>ClassCastException</code> class of a key or value
       
  1125      *          in the specified <code>Map</code> prevents it from being
       
  1126      *          stored in this <code>RenderingHints</code>.
       
  1127      * @exception <code>IllegalArgumentException</code> some aspect
       
  1128      *          of a key or value in the specified <code>Map</code>
       
  1129      *           prevents it from being stored in
       
  1130      *            this <code>RenderingHints</code>.
       
  1131      */
       
  1132     public void putAll(Map<?,?> m) {
       
  1133         // ## javac bug?
       
  1134         //if (m instanceof RenderingHints) {
       
  1135         if (RenderingHints.class.isInstance(m)) {
       
  1136             //hintmap.putAll(((RenderingHints) m).hintmap);
       
  1137             for (Map.Entry<?,?> entry : m.entrySet())
       
  1138                 hintmap.put(entry.getKey(), entry.getValue());
       
  1139         } else {
       
  1140             // Funnel each key/value pair through our protected put method
       
  1141             for (Map.Entry<?,?> entry : m.entrySet())
       
  1142                 put(entry.getKey(), entry.getValue());
       
  1143         }
       
  1144     }
       
  1145 
       
  1146     /**
       
  1147      * Returns a <code>Set</code> view of the Keys contained in this
       
  1148      * <code>RenderingHints</code>.  The Set is backed by the
       
  1149      * <code>RenderingHints</code>, so changes to the
       
  1150      * <code>RenderingHints</code> are reflected in the <code>Set</code>,
       
  1151      * and vice-versa.  If the <code>RenderingHints</code> is modified
       
  1152      * while an iteration over the <code>Set</code> is in progress,
       
  1153      * the results of the iteration are undefined.  The <code>Set</code>
       
  1154      * supports element removal, which removes the corresponding
       
  1155      * mapping from the <code>RenderingHints</code>, via the
       
  1156      * <code>Iterator.remove</code>, <code>Set.remove</code>,
       
  1157      * <code>removeAll</code> <code>retainAll</code>, and
       
  1158      * <code>clear</code> operations.  It does not support
       
  1159      * the <code>add</code> or <code>addAll</code> operations.
       
  1160      *
       
  1161      * @return a <code>Set</code> view of the keys contained
       
  1162      * in this <code>RenderingHints</code>.
       
  1163      */
       
  1164     public Set<Object> keySet() {
       
  1165         return hintmap.keySet();
       
  1166     }
       
  1167 
       
  1168     /**
       
  1169      * Returns a <code>Collection</code> view of the values
       
  1170      * contained in this <code>RenderinHints</code>.
       
  1171      * The <code>Collection</code> is backed by the
       
  1172      * <code>RenderingHints</code>, so changes to
       
  1173      * the <code>RenderingHints</code> are reflected in
       
  1174      * the <code>Collection</code>, and vice-versa.
       
  1175      * If the <code>RenderingHints</code> is modified while
       
  1176      * an iteration over the <code>Collection</code> is
       
  1177      * in progress, the results of the iteration are undefined.
       
  1178      * The <code>Collection</code> supports element removal,
       
  1179      * which removes the corresponding mapping from the
       
  1180      * <code>RenderingHints</code>, via the
       
  1181      * <code>Iterator.remove</code>,
       
  1182      * <code>Collection.remove</code>, <code>removeAll</code>,
       
  1183      * <code>retainAll</code> and <code>clear</code> operations.
       
  1184      * It does not support the <code>add</code> or
       
  1185      * <code>addAll</code> operations.
       
  1186      *
       
  1187      * @return a <code>Collection</code> view of the values
       
  1188      *          contained in this <code>RenderingHints</code>.
       
  1189      */
       
  1190     public Collection<Object> values() {
       
  1191         return hintmap.values();
       
  1192     }
       
  1193 
       
  1194     /**
       
  1195      * Returns a <code>Set</code> view of the mappings contained
       
  1196      * in this <code>RenderingHints</code>.  Each element in the
       
  1197      * returned <code>Set</code> is a <code>Map.Entry</code>.
       
  1198      * The <code>Set</code> is backed by the <code>RenderingHints</code>,
       
  1199      * so changes to the <code>RenderingHints</code> are reflected
       
  1200      * in the <code>Set</code>, and vice-versa.  If the
       
  1201      * <code>RenderingHints</code> is modified while
       
  1202      * while an iteration over the <code>Set</code> is in progress,
       
  1203      * the results of the iteration are undefined.
       
  1204      * <p>
       
  1205      * The entrySet returned from a <code>RenderingHints</code> object
       
  1206      * is not modifiable.
       
  1207      *
       
  1208      * @return a <code>Set</code> view of the mappings contained in
       
  1209      * this <code>RenderingHints</code>.
       
  1210      */
       
  1211     public Set<Map.Entry<Object,Object>> entrySet() {
       
  1212         return Collections.unmodifiableMap(hintmap).entrySet();
       
  1213     }
       
  1214 
       
  1215     /**
       
  1216      * Compares the specified <code>Object</code> with this
       
  1217      * <code>RenderingHints</code> for equality.
       
  1218      * Returns <code>true</code> if the specified object is also a
       
  1219      * <code>Map</code> and the two <code>Map</code> objects represent
       
  1220      * the same mappings.  More formally, two <code>Map</code> objects
       
  1221      * <code>t1</code> and <code>t2</code> represent the same mappings
       
  1222      * if <code>t1.keySet().equals(t2.keySet())</code> and for every
       
  1223      * key <code>k</code> in <code>t1.keySet()</code>,
       
  1224      * <pre>
       
  1225      * (t1.get(k)==null ? t2.get(k)==null : t1.get(k).equals(t2.get(k)))
       
  1226      * </pre>.
       
  1227      * This ensures that the <code>equals</code> method works properly across
       
  1228      * different implementations of the <code>Map</code> interface.
       
  1229      *
       
  1230      * @param o <code>Object</code> to be compared for equality with
       
  1231      * this <code>RenderingHints</code>.
       
  1232      * @return <code>true</code> if the specified <code>Object</code>
       
  1233      * is equal to this <code>RenderingHints</code>.
       
  1234      */
       
  1235     public boolean equals(Object o) {
       
  1236         if (o instanceof RenderingHints) {
       
  1237             return hintmap.equals(((RenderingHints) o).hintmap);
       
  1238         } else if (o instanceof Map) {
       
  1239             return hintmap.equals(o);
       
  1240         }
       
  1241         return false;
       
  1242     }
       
  1243 
       
  1244     /**
       
  1245      * Returns the hash code value for this <code>RenderingHints</code>.
       
  1246      * The hash code of a <code>RenderingHints</code> is defined to be
       
  1247      * the sum of the hashCodes of each <code>Entry</code> in the
       
  1248      * <code>RenderingHints</code> object's entrySet view.  This ensures that
       
  1249      * <code>t1.equals(t2)</code> implies that
       
  1250      * <code>t1.hashCode()==t2.hashCode()</code> for any two <code>Map</code>
       
  1251      * objects <code>t1</code> and <code>t2</code>, as required by the general
       
  1252      * contract of <code>Object.hashCode</code>.
       
  1253      *
       
  1254      * @return the hash code value for this <code>RenderingHints</code>.
       
  1255      * @see java.util.Map.Entry#hashCode()
       
  1256      * @see Object#hashCode()
       
  1257      * @see Object#equals(Object)
       
  1258      * @see #equals(Object)
       
  1259      */
       
  1260     public int hashCode() {
       
  1261         return hintmap.hashCode();
       
  1262     }
       
  1263 
       
  1264     /**
       
  1265      * Creates a clone of this <code>RenderingHints</code> object
       
  1266      * that has the same contents as this <code>RenderingHints</code>
       
  1267      * object.
       
  1268      * @return a clone of this instance.
       
  1269      */
       
  1270     public Object clone() {
       
  1271         RenderingHints rh;
       
  1272         try {
       
  1273             rh = (RenderingHints) super.clone();
       
  1274             if (hintmap != null) {
       
  1275                 rh.hintmap = (HashMap) hintmap.clone();
       
  1276             }
       
  1277         } catch (CloneNotSupportedException e) {
       
  1278             // this shouldn't happen, since we are Cloneable
       
  1279             throw new InternalError();
       
  1280         }
       
  1281 
       
  1282         return rh;
       
  1283     }
       
  1284 
       
  1285     /**
       
  1286      * Returns a rather long string representation of the hashmap
       
  1287      * which contains the mappings of keys to values for this
       
  1288      * <code>RenderingHints</code> object.
       
  1289      * @return  a string representation of this object.
       
  1290      */
       
  1291     public String toString() {
       
  1292         if (hintmap == null) {
       
  1293             return getClass().getName() + "@" +
       
  1294                 Integer.toHexString(hashCode()) +
       
  1295                 " (0 hints)";
       
  1296         }
       
  1297 
       
  1298         return hintmap.toString();
       
  1299     }
       
  1300 }