Home » openjdk-7 » java » awt » [javadoc | source]

    1   /*
    2    * Copyright (c) 1998, 2006, Oracle and/or its affiliates. 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.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * 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   }

Home » openjdk-7 » java » awt » [javadoc | source]