/*
 * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.awt;

import java.util.Map;
import java.util.Set;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import sun.awt.SunHints;
import java.lang.ref.WeakReference;

/**
 * The {@code RenderingHints} class defines and manages collections of
 * keys and associated values which allow an application to provide input
 * into the choice of algorithms used by other classes which perform
 * rendering and image manipulation services.
 * The {@link java.awt.Graphics2D} class, and classes that implement
 * {@link java.awt.image.BufferedImageOp} and
 * {@link java.awt.image.RasterOp} all provide methods to get and
 * possibly to set individual or groups of {@code RenderingHints}
 * keys and their associated values.
 * When those implementations perform any rendering or image manipulation
 * operations they should examine the values of any {@code RenderingHints}
 * that were requested by the caller and tailor the algorithms used
 * accordingly and to the best of their ability.
 * <p>
 * Note that since these keys and values are <i>hints</i>, there is
 * no requirement that a given implementation supports all possible
 * choices indicated below or that it can respond to requests to
 * modify its choice of algorithm.
 * The values of the various hint keys may also interact such that
 * while all variants of a given key are supported in one situation,
 * the implementation may be more restricted when the values associated
 * with other keys are modified.
 * For example, some implementations may be able to provide several
 * types of dithering when the antialiasing hint is turned off, but
 * have little control over dithering when antialiasing is on.
 * The full set of supported keys and hints may also vary by destination
 * since runtimes may use different underlying modules to render to
 * the screen, or to {@link java.awt.image.BufferedImage} objects,
 * or while printing.
 * <p>
 * Implementations are free to ignore the hints completely, but should
 * try to use an implementation algorithm that is as close as possible
 * to the request.
 * If an implementation supports a given algorithm when any value is used
 * for an associated hint key, then minimally it must do so when the
 * value for that key is the exact value that specifies the algorithm.
 * <p>
 * The keys used to control the hints are all special values that
 * subclass the associated {@link RenderingHints.Key} class.
 * Many common hints are expressed below as static constants in this
 * class, but the list is not meant to be exhaustive.
 * Other hints may be created by other packages by defining new objects
 * which subclass the {@code Key} class and defining the associated values.
 */
public class RenderingHints
    implements Map<Object,Object>, Cloneable
{
    /**
     * Defines the base type of all keys used along with the
     * {@link RenderingHints} class to control various
     * algorithm choices in the rendering and imaging pipelines.
     * Instances of this class are immutable and unique which
     * means that tests for matches can be made using the
     * {@code ==} operator instead of the more expensive
     * {@code equals()} method.
     */
    public abstract static class Key {
        private static HashMap identitymap = new HashMap(17);

        private String getIdentity() {
            // Note that the identity string is dependent on 3 variables:
            //     - the name of the subclass of Key
            //     - the identityHashCode of the subclass of Key
            //     - the integer key of the Key
            // It is theoretically possible for 2 distinct keys to collide
            // along all 3 of those attributes in the context of multiple
            // class loaders, but that occurence will be extremely rare and
            // we account for that possibility below in the recordIdentity
            // method by slightly relaxing our uniqueness guarantees if we
            // end up in that situation.
            return getClass().getName()+"@"+
                Integer.toHexString(System.identityHashCode(getClass()))+":"+
                Integer.toHexString(privatekey);
        }

        private synchronized static void recordIdentity(Key k) {
            Object identity = k.getIdentity();
            Object otherref = identitymap.get(identity);
            if (otherref != null) {
                Key otherkey = (Key) ((WeakReference) otherref).get();
                if (otherkey != null && otherkey.getClass() == k.getClass()) {
                    throw new IllegalArgumentException(identity+
                                                       " already registered");
                }
                // Note that this system can fail in a mostly harmless
                // way.  If we end up generating the same identity
                // String for 2 different classes (a very rare case)
                // then we correctly avoid throwing the exception above,
                // but we are about to drop through to a statement that
                // will replace the entry for the old Key subclass with
                // an entry for the new Key subclass.  At that time the
                // old subclass will be vulnerable to someone generating
                // a duplicate Key instance for it.  We could bail out
                // of the method here and let the old identity keep its
                // record in the map, but we are more likely to see a
                // duplicate key go by for the new class than the old
                // one since the new one is probably still in the
                // initialization stage.  In either case, the probability
                // of loading 2 classes in the same VM with the same name
                // and identityHashCode should be nearly impossible.
            }
            // Note: Use a weak reference to avoid holding on to extra
            // objects and classes after they should be unloaded.
            identitymap.put(identity, new WeakReference(k));
        }

        private int privatekey;

        /**
         * Construct a key using the indicated private key.  Each
         * subclass of Key maintains its own unique domain of integer
         * keys.  No two objects with the same integer key and of the
         * same specific subclass can be constructed.  An exception
         * will be thrown if an attempt is made to construct another
         * object of a given class with the same integer key as a
         * pre-existing instance of that subclass of Key.
         * @param privatekey the specified key
         */
        protected Key(int privatekey) {
            this.privatekey = privatekey;
            recordIdentity(this);
        }

        /**
         * Returns true if the specified object is a valid value
         * for this Key.
         * @param val the <code>Object</code> to test for validity
         * @return <code>true</code> if <code>val</code> is valid;
         *         <code>false</code> otherwise.
         */
        public abstract boolean isCompatibleValue(Object val);

        /**
         * Returns the private integer key that the subclass
         * instantiated this Key with.
         * @return the private integer key that the subclass
         * instantiated this Key with.
         */
        protected final int intKey() {
            return privatekey;
        }

        /**
         * The hash code for all Key objects will be the same as the
         * system identity code of the object as defined by the
         * System.identityHashCode() method.
         */
        public final int hashCode() {
            return super.hashCode();
        }

        /**
         * The equals method for all Key objects will return the same
         * result as the equality operator '=='.
         */
        public final boolean equals(Object o) {
            return this == o;
        }
    }

    HashMap hintmap = new HashMap(7);

    /**
     * Antialiasing hint key.
     * The {@code ANTIALIASING} hint controls whether or not the
     * geometry rendering methods of a {@link Graphics2D} object
     * will attempt to reduce aliasing artifacts along the edges
     * of shapes.
     * <p>
     * A typical antialiasing algorithm works by blending the existing
     * colors of the pixels along the boundary of a shape with the
     * requested fill paint according to the estimated partial pixel
     * coverage of the shape.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_ANTIALIAS_ON}
     * <li>{@link #VALUE_ANTIALIAS_OFF}
     * <li>{@link #VALUE_ANTIALIAS_DEFAULT}
     * </ul>
     */
    public static final Key KEY_ANTIALIASING =
        SunHints.KEY_ANTIALIASING;

    /**
     * Antialiasing hint value -- rendering is done with antialiasing.
     * @see #KEY_ANTIALIASING
     */
    public static final Object VALUE_ANTIALIAS_ON =
        SunHints.VALUE_ANTIALIAS_ON;

    /**
     * Antialiasing hint value -- rendering is done without antialiasing.
     * @see #KEY_ANTIALIASING
     */
    public static final Object VALUE_ANTIALIAS_OFF =
        SunHints.VALUE_ANTIALIAS_OFF;

    /**
     * Antialiasing hint value -- rendering is done with a default
     * antialiasing mode chosen by the implementation.
     * @see #KEY_ANTIALIASING
     */
    public static final Object VALUE_ANTIALIAS_DEFAULT =
         SunHints.VALUE_ANTIALIAS_DEFAULT;

    /**
     * Rendering hint key.
     * The {@code RENDERING} hint is a general hint that provides
     * a high level recommendation as to whether to bias algorithm
     * choices more for speed or quality when evaluating tradeoffs.
     * This hint could be consulted for any rendering or image
     * manipulation operation, but decisions will usually honor
     * other, more specific hints in preference to this hint.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_RENDER_SPEED}
     * <li>{@link #VALUE_RENDER_QUALITY}
     * <li>{@link #VALUE_RENDER_DEFAULT}
     * </ul>
     */
    public static final Key KEY_RENDERING =
         SunHints.KEY_RENDERING;

    /**
     * Rendering hint value -- rendering algorithms are chosen
     * with a preference for output speed.
     * @see #KEY_RENDERING
     */
    public static final Object VALUE_RENDER_SPEED =
         SunHints.VALUE_RENDER_SPEED;

    /**
     * Rendering hint value -- rendering algorithms are chosen
     * with a preference for output quality.
     * @see #KEY_RENDERING
     */
    public static final Object VALUE_RENDER_QUALITY =
         SunHints.VALUE_RENDER_QUALITY;

    /**
     * Rendering hint value -- rendering algorithms are chosen
     * by the implementation for a good tradeoff of performance
     * vs. quality.
     * @see #KEY_RENDERING
     */
    public static final Object VALUE_RENDER_DEFAULT =
         SunHints.VALUE_RENDER_DEFAULT;

    /**
     * Dithering hint key.
     * The {@code DITHERING} hint controls how closely to approximate
     * a color when storing into a destination with limited color
     * resolution.
     * <p>
     * Some rendering destinations may support a limited number of
     * color choices which may not be able to accurately represent
     * the full spectrum of colors that can result during rendering
     * operations.
     * For such a destination the {@code DITHERING} hint controls
     * whether rendering is done with a flat solid fill of a single
     * pixel value which is the closest supported color to what was
     * requested, or whether shapes will be filled with a pattern of
     * colors which combine to better approximate that color.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_DITHER_DISABLE}
     * <li>{@link #VALUE_DITHER_ENABLE}
     * <li>{@link #VALUE_DITHER_DEFAULT}
     * </ul>
     */
    public static final Key KEY_DITHERING =
         SunHints.KEY_DITHERING;

    /**
     * Dithering hint value -- do not dither when rendering geometry.
     * @see #KEY_DITHERING
     */
    public static final Object VALUE_DITHER_DISABLE =
         SunHints.VALUE_DITHER_DISABLE;

    /**
     * Dithering hint value -- dither when rendering geometry, if needed.
     * @see #KEY_DITHERING
     */
    public static final Object VALUE_DITHER_ENABLE =
         SunHints.VALUE_DITHER_ENABLE;

    /**
     * Dithering hint value -- use a default for dithering chosen by
     * the implementation.
     * @see #KEY_DITHERING
     */
    public static final Object VALUE_DITHER_DEFAULT =
         SunHints.VALUE_DITHER_DEFAULT;

    /**
     * Text antialiasing hint key.
     * The {@code TEXT_ANTIALIASING} hint can control the use of
     * antialiasing algorithms for text independently of the
     * choice used for shape rendering.
     * Often an application may want to use antialiasing for text
     * only and not for other shapes.
     * Additionally, the algorithms for reducing the aliasing
     * artifacts for text are often more sophisticated than those
     * that have been developed for general rendering so this
     * hint key provides additional values which can control
     * the choices of some of those text-specific algorithms.
     * If left in the {@code DEFAULT} state, this hint will
     * generally defer to the value of the regular
     * {@link #KEY_ANTIALIASING} hint key.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_TEXT_ANTIALIAS_ON}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_OFF}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_DEFAULT}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_GASP}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_HBGR}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_VRGB}
     * <li>{@link #VALUE_TEXT_ANTIALIAS_LCD_VBGR}
     * </ul>
     */
    public static final Key KEY_TEXT_ANTIALIASING =
         SunHints.KEY_TEXT_ANTIALIASING;

    /**
     * Text antialiasing hint value -- text rendering is done with
     * some form of antialiasing.
     * @see #KEY_TEXT_ANTIALIASING
     */
    public static final Object VALUE_TEXT_ANTIALIAS_ON =
         SunHints.VALUE_TEXT_ANTIALIAS_ON;

    /**
     * Text antialiasing hint value -- text rendering is done without
     * any form of antialiasing.
     * @see #KEY_TEXT_ANTIALIASING
     */
    public static final Object VALUE_TEXT_ANTIALIAS_OFF =
         SunHints.VALUE_TEXT_ANTIALIAS_OFF;

    /**
     * Text antialiasing hint value -- text rendering is done according
     * to the {@link #KEY_ANTIALIASING} hint or a default chosen by the
     * implementation.
     * @see #KEY_TEXT_ANTIALIASING
     */
    public static final Object VALUE_TEXT_ANTIALIAS_DEFAULT =
         SunHints.VALUE_TEXT_ANTIALIAS_DEFAULT;

    /**
     * Text antialiasing hint value -- text rendering is requested to
     * use information in the font resource which specifies for each point
     * size whether to apply {@link #VALUE_TEXT_ANTIALIAS_ON} or
     * {@link #VALUE_TEXT_ANTIALIAS_OFF}.
     * <p>
     * TrueType fonts typically provide this information in the 'gasp' table.
     * In the absence of this information, the behaviour for a particular
     * font and size is determined by implementation defaults.
     * <p>
     * <i>Note:</i>A font designer will typically carefully hint a font for
     * the most common user interface point sizes. Consequently the 'gasp'
     * table will likely specify to use only hinting at those sizes and not
     * "smoothing". So in many cases the resulting text display is
     * equivalent to {@code VALUE_TEXT_ANTIALIAS_OFF}.
     * This may be unexpected but is correct.
     * <p>
     * Logical fonts which are composed of multiple physical fonts will for
     * consistency will use the setting most appropriate for the overall
     * composite font.
     *
     * @see #KEY_TEXT_ANTIALIASING
     * @since 1.6
     */
    public static final Object VALUE_TEXT_ANTIALIAS_GASP =
         SunHints.VALUE_TEXT_ANTIALIAS_GASP;

    /**
     * Text antialiasing hint value -- request that text be displayed
     * optimised for an LCD display with subpixels in order from display
     * left to right of R,G,B such that the horizontal subpixel resolution
     * is three times that of the full pixel horizontal resolution (HRGB).
     * This is the most common configuration.
     * Selecting this hint for displays with one of the other LCD subpixel
     * configurations will likely result in unfocused text.
     * <p>
     * <i>Notes:</i><br>
     * An implementation when choosing whether to apply any of the
     * LCD text hint values may take into account factors including requiring
     * color depth of the destination to be at least 15 bits per pixel
     * (ie 5 bits per color component),
     * characteristics of a font such as whether embedded bitmaps may
     * produce better results, or when displaying to a non-local networked
     * display device enabling it only if suitable protocols are available,
     * or ignoring the hint if performing very high resolution rendering
     * or the target device is not appropriate: eg when printing.
     * <p>
     * These hints can equally be applied when rendering to software images,
     * but these images may not then be suitable for general export, as the
     * text will have been rendered appropriately for a specific subpixel
     * organisation. Also lossy images are not a good choice, nor image
     * formats such as GIF which have limited colors.
     * So unless the image is destined solely for rendering on a
     * display device with the same configuration, some other text
     * anti-aliasing hint such as
     * {@link #VALUE_TEXT_ANTIALIAS_ON}
     * may be a better choice.
     * <p>Selecting a value which does not match the LCD display in use
     * will likely lead to a degradation in text quality.
     * On display devices (ie CRTs) which do not have the same characteristics
     * as LCD displays, the overall effect may appear similar to standard text
     * anti-aliasing, but the quality may be degraded by color distortion.
     * Analog connected LCD displays may also show little advantage over
     * standard text-antialiasing and be similar to CRTs.
     * <p>
     * In other words for the best results use an LCD display with a digital
     * display connector and specify the appropriate sub-pixel configuration.
     *
     * @see #KEY_TEXT_ANTIALIASING
     * @since 1.6
     */
    public static final Object VALUE_TEXT_ANTIALIAS_LCD_HRGB =
         SunHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB;

    /**
     * Text antialiasing hint value -- request that text be displayed
     * optimised for an LCD display with subpixels in order from display
     * left to right of B,G,R such that the horizontal subpixel resolution
     * is three times that of the full pixel horizontal resolution (HBGR).
     * This is a much less common configuration than HRGB.
     * Selecting this hint for displays with one of the other LCD subpixel
     * configurations will likely result in unfocused text.
     * See {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB},
     * for more information on when this hint is applied.
     *
     * @see #KEY_TEXT_ANTIALIASING
     * @since 1.6
     */
    public static final Object VALUE_TEXT_ANTIALIAS_LCD_HBGR =
         SunHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR;

    /**
     * Text antialiasing hint value -- request that text be displayed
     * optimised for an LCD display with subpixel organisation from display
     * top to bottom of R,G,B such that the vertical subpixel resolution is
     * three times that of the full pixel vertical resolution (VRGB).
     * Vertical orientation is very uncommon and probably mainly useful
     * for a physically rotated display.
     * Selecting this hint for displays with one of the other LCD subpixel
     * configurations will likely result in unfocused text.
     * See {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB},
     * for more information on when this hint is applied.
     *
     * @see #KEY_TEXT_ANTIALIASING
     * @since 1.6
     */
    public static final Object VALUE_TEXT_ANTIALIAS_LCD_VRGB =
         SunHints.VALUE_TEXT_ANTIALIAS_LCD_VRGB;

    /**
     * Text antialiasing hint value -- request that text be displayed
     * optimised for an LCD display with subpixel organisation from display
     * top to bottom of B,G,R such that the vertical subpixel resolution is
     * three times that of the full pixel vertical resolution (VBGR).
     * Vertical orientation is very uncommon and probably mainly useful
     * for a physically rotated display.
     * Selecting this hint for displays with one of the other LCD subpixel
     * configurations will likely result in unfocused text.
     * See {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB},
     * for more information on when this hint is applied.
     *
     * @see #KEY_TEXT_ANTIALIASING
     * @since 1.6
     */
    public static final Object VALUE_TEXT_ANTIALIAS_LCD_VBGR =
         SunHints.VALUE_TEXT_ANTIALIAS_LCD_VBGR;


    /**
     * LCD text contrast rendering hint key.
     * The value is an <code>Integer</code> object which is used as a text
     * contrast adjustment when used in conjunction with an LCD text
     * anti-aliasing hint such as
     * {@link #VALUE_TEXT_ANTIALIAS_LCD_HRGB}.
     * <ul>
     * <li>Values should be a positive integer in the range 100 to 250.
     * <li>A lower value (eg 100) corresponds to higher contrast text when
     * displaying dark text on a light background.
     * <li>A higher value (eg 200) corresponds to lower contrast text when
     * displaying dark text on a light background.
     * <li>A typical useful value is in the narrow range 140-180.
     * <li>If no value is specified, a system or implementation default value
     * will be applied.
     * </ul>
     * The default value can be expected to be adequate for most purposes,
     * so clients should rarely need to specify a value for this hint unless
     * they have concrete information as to an appropriate value.
     * A higher value does not mean a higher contrast, in fact the opposite
     * is true.
     * The correction is applied in a similar manner to a gamma adjustment
     * for non-linear perceptual luminance response of display systems, but
     * does not indicate a full correction for this.
     *
     * @see #KEY_TEXT_ANTIALIASING
     * @since 1.6
     */
    public static final Key KEY_TEXT_LCD_CONTRAST =
        SunHints.KEY_TEXT_ANTIALIAS_LCD_CONTRAST;

    /**
     * Font fractional metrics hint key.
     * The {@code FRACTIONALMETRICS} hint controls whether the positioning
     * of individual character glyphs takes into account the sub-pixel
     * accuracy of the scaled character advances of the font or whether
     * such advance vectors are rounded to an integer number of whole
     * device pixels.
     * This hint only recommends how much accuracy should be used to
     * position the glyphs and does not specify or recommend whether or
     * not the actual rasterization or pixel bounds of the glyph should
     * be modified to match.
     * <p>
     * Rendering text to a low resolution device like a screen will
     * necessarily involve a number of rounding operations as the
     * high quality and very precise definition of the shape and
     * metrics of the character glyphs must be matched to discrete
     * device pixels.
     * Ideally the positioning of glyphs during text layout would be
     * calculated by scaling the design metrics in the font according
     * to the point size, but then the scaled advance width will not
     * necessarily be an integer number of pixels.
     * If the glyphs are positioned with sub-pixel accuracy according
     * to these scaled design metrics then the rasterization would
     * ideally need to be adjusted for each possible sub-pixel origin.
     * <p>
     * Unfortunately, scaling each glyph customized to its exact
     * subpixel origin during text layout would be prohibitively
     * expensive so a simplified system based on integer device
     * positions is typically used to lay out the text.
     * The rasterization of the glyph and the scaled advance width
     * are both adjusted together to yield text that looks good at
     * device resolution and has consistent integer pixel distances
     * between glyphs that help the glyphs look uniformly and
     * consistently spaced and readable.
     * <p>
     * This process of rounding advance widths for rasterized glyphs
     * to integer distances means that the character density and the
     * overall length of a string of text will be different from the
     * theoretical design measurements due to the accumulation of
     * a series of small differences in the adjusted widths of
     * each glyph.
     * The specific differences will be different for each glyph,
     * some being wider and some being narrower than their theoretical
     * design measurements.
     * Thus the overall difference in character density and length
     * will vary by a number of factors including the font, the
     * specific device resolution being targeted, and the glyphs
     * chosen to represent the string being rendered.
     * As a result, rendering the same string at multiple device
     * resolutions can yield widely varying metrics for whole strings.
     * <p>
     * When {@code FRACTIONALMETRICS} are enabled, the true font design
     * metrics are scaled by the point size and used for layout with
     * sub-pixel accuracy.
     * The average density of glyphs and total length of a long
     * string of characters will therefore more closely match the
     * theoretical design of the font, but readability may be affected
     * since individual pairs of characters may not always appear to
     * be consistent distances apart depending on how the sub-pixel
     * accumulation of the glyph origins meshes with the device pixel
     * grid.
     * Enabling this hint may be desirable when text layout is being
     * performed that must be consistent across a wide variety of
     * output resolutions.
     * Specifically, this hint may be desirable in situations where
     * the layout of text is being previewed on a low resolution
     * device like a screen for output that will eventually be
     * rendered on a high resolution printer or typesetting device.
     * <p>
     * When disabled, the scaled design metrics are rounded or adjusted
     * to integer distances for layout.
     * The distances between any specific pair of glyphs will be more
     * uniform on the device, but the density and total length of long
     * strings may no longer match the theoretical intentions of the
     * font designer.
     * Disabling this hint will typically produce more readable results
     * on low resolution devices like computer monitors.
     * <p>
     * The allowable values for this key are
     * <ul>
     * <li>{@link #VALUE_FRACTIONALMETRICS_OFF}
     * <li>{@link #VALUE_FRACTIONALMETRICS_ON}
     * <li>{@link #VALUE_FRACTIONALMETRICS_DEFAULT}
     * </ul>
     */
    public static final Key KEY_FRACTIONALMETRICS =
         SunHints.KEY_FRACTIONALMETRICS;

    /**
     * Font fractional metrics hint value -- character glyphs are
     * positioned with advance widths rounded to pixel boundaries.
     * @see #KEY_FRACTIONALMETRICS
     */
    public static final Object VALUE_FRACTIONALMETRICS_OFF =
         SunHints.VALUE_FRACTIONALMETRICS_OFF;

    /**
     * Font fractional metrics hint value -- character glyphs are
     * positioned with sub-pixel accuracy.
     * @see #KEY_FRACTIONALMETRICS
     */
    public static final Object VALUE_FRACTIONALMETRICS_ON =
         SunHints.VALUE_FRACTIONALMETRICS_ON;

    /**
     * Font fractional metrics hint value -- character glyphs are
     * positioned with accuracy chosen by the implementation.
     * @see #KEY_FRACTIONALMETRICS
     */
    public static final Object VALUE_FRACTIONALMETRICS_DEFAULT =
         SunHints.VALUE_FRACTIONALMETRICS_DEFAULT;

    /**
     * Interpolation hint key.
     * The {@code INTERPOLATION} hint controls how image pixels are
     * filtered or resampled during an image rendering operation.
     * <p>
     * Implicitly images are defined to provide color samples at
     * integer coordinate locations.
     * When images are rendered upright with no scaling onto a
     * destination, the choice of which image pixels map to which
     * device pixels is obvious and the samples at the integer
     * coordinate locations in the image are transfered to the
     * pixels at the corresponding integer locations on the device
     * pixel grid one for one.
     * When images are rendered in a scaled, rotated, or otherwise
     * transformed coordinate system, then the mapping of device
     * pixel coordinates back to the image can raise the question
     * of what color sample to use for the continuous coordinates
     * that lie between the integer locations of the provided image
     * samples.
     * Interpolation algorithms define functions which provide a
     * color sample for any continuous coordinate in an image based
     * on the color samples at the surrounding integer coordinates.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR}
     * <li>{@link #VALUE_INTERPOLATION_BILINEAR}
     * <li>{@link #VALUE_INTERPOLATION_BICUBIC}
     * </ul>
     */
    public static final Key KEY_INTERPOLATION =
         SunHints.KEY_INTERPOLATION;

    /**
     * Interpolation hint value -- the color sample of the nearest
     * neighboring integer coordinate sample in the image is used.
     * Conceptually the image is viewed as a grid of unit-sized
     * square regions of color centered around the center of each
     * image pixel.
     * <p>
     * As the image is scaled up, it will look correspondingly blocky.
     * As the image is scaled down, the colors for source pixels will
     * be either used unmodified, or skipped entirely in the output
     * representation.
     *
     * @see #KEY_INTERPOLATION
     */
    public static final Object VALUE_INTERPOLATION_NEAREST_NEIGHBOR =
         SunHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;

    /**
     * Interpolation hint value -- the color samples of the 4 nearest
     * neighboring integer coordinate samples in the image are
     * interpolated linearly to produce a color sample.
     * Conceptually the image is viewed as a set of infinitely small
     * point color samples which have value only at the centers of
     * integer coordinate pixels and the space between those pixel
     * centers is filled with linear ramps of colors that connect
     * adjacent discrete samples in a straight line.
     * <p>
     * As the image is scaled up, there are no blocky edges between
     * the colors in the image as there are with
     * {@link #VALUE_INTERPOLATION_NEAREST_NEIGHBOR NEAREST_NEIGHBOR},
     * but the blending may show some subtle discontinuities along the
     * horizontal and vertical edges that line up with the samples
     * caused by a sudden change in the slope of the interpolation
     * from one side of a sample to the other.
     * As the image is scaled down, more image pixels have their
     * color samples represented in the resulting output since each
     * output pixel recieves color information from up to 4 image
     * pixels.
     *
     * @see #KEY_INTERPOLATION
     */
    public static final Object VALUE_INTERPOLATION_BILINEAR =
         SunHints.VALUE_INTERPOLATION_BILINEAR;

    /**
     * Interpolation hint value -- the color samples of 9 nearby
     * integer coordinate samples in the image are interpolated using
     * a cubic function in both {@code X} and {@code Y} to produce
     * a color sample.
     * Conceptually the view of the image is very similar to the view
     * used in the {@link #VALUE_INTERPOLATION_BILINEAR BILINEAR}
     * algorithm except that the ramps of colors that connect between
     * the samples are curved and have better continuity of slope
     * as they cross over between sample boundaries.
     * <p>
     * As the image is scaled up, there are no blocky edges and the
     * interpolation should appear smoother and with better depictions
     * of any edges in the original image than with {@code BILINEAR}.
     * As the image is scaled down, even more of the original color
     * samples from the original image will have their color information
     * carried through and represented.
     *
     * @see #KEY_INTERPOLATION
     */
    public static final Object VALUE_INTERPOLATION_BICUBIC =
         SunHints.VALUE_INTERPOLATION_BICUBIC;

    /**
     * Alpha interpolation hint key.
     * The {@code ALPHA_INTERPOLATION} hint is a general hint that
     * provides a high level recommendation as to whether to bias
     * alpha blending algorithm choices more for speed or quality
     * when evaluating tradeoffs.
     * <p>
     * This hint could control the choice of alpha blending
     * calculations that sacrifice some precision to use fast
     * lookup tables or lower precision SIMD instructions.
     * This hint could also control whether or not the color
     * and alpha values are converted into a linear color space
     * during the calculations for a more linear visual effect
     * at the expense of additional per-pixel calculations.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_ALPHA_INTERPOLATION_SPEED}
     * <li>{@link #VALUE_ALPHA_INTERPOLATION_QUALITY}
     * <li>{@link #VALUE_ALPHA_INTERPOLATION_DEFAULT}
     * </ul>
     */
    public static final Key KEY_ALPHA_INTERPOLATION =
         SunHints.KEY_ALPHA_INTERPOLATION;

    /**
     * Alpha interpolation hint value -- alpha blending algorithms
     * are chosen with a preference for calculation speed.
     * @see #KEY_ALPHA_INTERPOLATION
     */
    public static final Object VALUE_ALPHA_INTERPOLATION_SPEED =
         SunHints.VALUE_ALPHA_INTERPOLATION_SPEED;

    /**
     * Alpha interpolation hint value -- alpha blending algorithms
     * are chosen with a preference for precision and visual quality.
     * @see #KEY_ALPHA_INTERPOLATION
     */
    public static final Object VALUE_ALPHA_INTERPOLATION_QUALITY =
         SunHints.VALUE_ALPHA_INTERPOLATION_QUALITY;

    /**
     * Alpha interpolation hint value -- alpha blending algorithms
     * are chosen by the implementation for a good tradeoff of
     * performance vs. quality.
     * @see #KEY_ALPHA_INTERPOLATION
     */
    public static final Object VALUE_ALPHA_INTERPOLATION_DEFAULT =
         SunHints.VALUE_ALPHA_INTERPOLATION_DEFAULT;

    /**
     * Color rendering hint key.
     * The {@code COLOR_RENDERING} hint controls the accuracy of
     * approximation and conversion when storing colors into a
     * destination image or surface.
     * <p>
     * When a rendering or image manipulation operation produces
     * a color value that must be stored into a destination, it
     * must first convert that color into a form suitable for
     * storing into the destination image or surface.
     * Minimally, the color components must be converted to bit
     * representations and ordered in the correct order or an
     * index into a color lookup table must be chosen before
     * the data can be stored into the destination memory.
     * Without this minimal conversion, the data in the destination
     * would likely represent random, incorrect or possibly even
     * unsupported values.
     * Algorithms to quickly convert the results of rendering
     * operations into the color format of most common destinations
     * are well known and fairly optimal to execute.
     * <p>
     * Simply performing the most basic color format conversion to
     * store colors into a destination can potentially ignore a
     * difference in the calibration of the
     * {@link java.awt.color.ColorSpace}
     * of the source and destination or other factors such as the
     * linearity of the gamma correction.
     * Unless the source and destination {@code ColorSpace} are
     * identical, to correctly perform a rendering operation with
     * the most care taken for the accuracy of the colors being
     * represented, the source colors should be converted to a
     * device independent {@code ColorSpace} and the results then
     * converted back to the destination {@code ColorSpace}.
     * Furthermore, if calculations such as the blending of multiple
     * source colors are to be performed during the rendering
     * operation, greater visual clarity can be achieved if the
     * intermediate device independent {@code ColorSpace} is
     * chosen to have a linear relationship between the values
     * being calculated and the perception of the human eye to
     * the response curves of the output device.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_COLOR_RENDER_SPEED}
     * <li>{@link #VALUE_COLOR_RENDER_QUALITY}
     * <li>{@link #VALUE_COLOR_RENDER_DEFAULT}
     * </ul>
     */
    public static final Key KEY_COLOR_RENDERING =
         SunHints.KEY_COLOR_RENDERING;

    /**
     * Color rendering hint value -- perform the fastest color
     * conversion to the format of the output device.
     * @see #KEY_COLOR_RENDERING
     */
    public static final Object VALUE_COLOR_RENDER_SPEED =
         SunHints.VALUE_COLOR_RENDER_SPEED;

    /**
     * Color rendering hint value -- perform the color conversion
     * calculations with the highest accuracy and visual quality.
     * @see #KEY_COLOR_RENDERING
     */
    public static final Object VALUE_COLOR_RENDER_QUALITY =
         SunHints.VALUE_COLOR_RENDER_QUALITY;

    /**
     * Color rendering hint value -- perform color conversion
     * calculations as chosen by the implementation to represent
     * the best available tradeoff between performance and
     * accuracy.
     * @see #KEY_COLOR_RENDERING
     */
    public static final Object VALUE_COLOR_RENDER_DEFAULT =
         SunHints.VALUE_COLOR_RENDER_DEFAULT;

    /**
     * Stroke normalization control hint key.
     * The {@code STROKE_CONTROL} hint controls whether a rendering
     * implementation should or is allowed to modify the geometry
     * of rendered shapes for various purposes.
     * <p>
     * Some implementations may be able to use an optimized platform
     * rendering library which may be faster than traditional software
     * rendering algorithms on a given platform, but which may also
     * not support floating point coordinates.
     * Some implementations may also have sophisticated algorithms
     * which perturb the coordinates of a path so that wide lines
     * appear more uniform in width and spacing.
     * <p>
     * If an implementation performs any type of modification or
     * "normalization" of a path, it should never move the coordinates
     * by more than half a pixel in any direction.
     * <p>
     * The allowable values for this hint are
     * <ul>
     * <li>{@link #VALUE_STROKE_NORMALIZE}
     * <li>{@link #VALUE_STROKE_PURE}
     * <li>{@link #VALUE_STROKE_DEFAULT}
     * </ul>
     * @since 1.3
     */
    public static final Key KEY_STROKE_CONTROL =
        SunHints.KEY_STROKE_CONTROL;

    /**
     * Stroke normalization control hint value -- geometry may be
     * modified or left pure depending on the tradeoffs in a given
     * implementation.
     * Typically this setting allows an implementation to use a fast
     * integer coordinate based platform rendering library, but does
     * not specifically request normalization for uniformity or
     * aesthetics.
     *
     * @see #KEY_STROKE_CONTROL
     * @since 1.3
     */
    public static final Object VALUE_STROKE_DEFAULT =
        SunHints.VALUE_STROKE_DEFAULT;

    /**
     * Stroke normalization control hint value -- geometry should
     * be normalized to improve uniformity or spacing of lines and
     * overall aesthetics.
     * Note that different normalization algorithms may be more
     * successful than others for given input paths.
     *
     * @see #KEY_STROKE_CONTROL
     * @since 1.3
     */
    public static final Object VALUE_STROKE_NORMALIZE =
        SunHints.VALUE_STROKE_NORMALIZE;

    /**
     * Stroke normalization control hint value -- geometry should
     * be left unmodified and rendered with sub-pixel accuracy.
     *
     * @see #KEY_STROKE_CONTROL
     * @since 1.3
     */
    public static final Object VALUE_STROKE_PURE =
        SunHints.VALUE_STROKE_PURE;

    /**
     * Constructs a new object with keys and values initialized
     * from the specified Map object which may be null.
     * @param init a map of key/value pairs to initialize the hints
     *          or null if the object should be empty
     */
    public RenderingHints(Map<Key,?> init) {
        if (init != null) {
            hintmap.putAll(init);
        }
    }

    /**
     * Constructs a new object with the specified key/value pair.
     * @param key the key of the particular hint property
     * @param value the value of the hint property specified with
     * <code>key</code>
     */
    public RenderingHints(Key key, Object value) {
        hintmap.put(key, value);
    }

    /**
     * Returns the number of key-value mappings in this
     * <code>RenderingHints</code>.
     *
     * @return the number of key-value mappings in this
     * <code>RenderingHints</code>.
     */
    public int size() {
        return hintmap.size();
    }

    /**
     * Returns <code>true</code> if this
     * <code>RenderingHints</code> contains no key-value mappings.
     *
     * @return <code>true</code> if this
     * <code>RenderingHints</code> contains no key-value mappings.
     */
    public boolean isEmpty() {
        return hintmap.isEmpty();
    }

    /**
     * Returns <code>true</code> if this <code>RenderingHints</code>
     *  contains a mapping for the specified key.
     *
     * @param key key whose presence in this
     * <code>RenderingHints</code> is to be tested.
     * @return <code>true</code> if this <code>RenderingHints</code>
     *          contains a mapping for the specified key.
     * @exception <code>ClassCastException</code> if the key can not
     *            be cast to <code>RenderingHints.Key</code>
     */
    public boolean containsKey(Object key) {
        return hintmap.containsKey((Key) key);
    }

    /**
     * Returns true if this RenderingHints maps one or more keys to the
     * specified value.
     * More formally, returns <code>true</code> if and only
     * if this <code>RenderingHints</code>
     * contains at least one mapping to a value <code>v</code> such that
     * <pre>
     * (value==null ? v==null : value.equals(v))
     * </pre>.
     * This operation will probably require time linear in the
     * <code>RenderingHints</code> size for most implementations
     * of <code>RenderingHints</code>.
     *
     * @param value value whose presence in this
     *          <code>RenderingHints</code> is to be tested.
     * @return <code>true</code> if this <code>RenderingHints</code>
     *           maps one or more keys to the specified value.
     */
    public boolean containsValue(Object value) {
        return hintmap.containsValue(value);
    }

    /**
     * Returns the value to which the specified key is mapped.
     * @param   key   a rendering hint key
     * @return  the value to which the key is mapped in this object or
     *          <code>null</code> if the key is not mapped to any value in
     *          this object.
     * @exception <code>ClassCastException</code> if the key can not
     *            be cast to <code>RenderingHints.Key</code>
     * @see     #put(Object, Object)
     */
    public Object get(Object key) {
        return hintmap.get((Key) key);
    }

    /**
     * Maps the specified <code>key</code> to the specified
     * <code>value</code> in this <code>RenderingHints</code> object.
     * Neither the key nor the value can be <code>null</code>.
     * The value can be retrieved by calling the <code>get</code> method
     * with a key that is equal to the original key.
     * @param      key     the rendering hint key.
     * @param      value   the rendering hint value.
     * @return     the previous value of the specified key in this object
     *             or <code>null</code> if it did not have one.
     * @exception <code>NullPointerException</code> if the key is
     *            <code>null</code>.
     * @exception <code>ClassCastException</code> if the key can not
     *            be cast to <code>RenderingHints.Key</code>
     * @exception <code>IllegalArgumentException</code> if the
     *            {@link Key#isCompatibleValue(java.lang.Object)
     *                   Key.isCompatibleValue()}
     *            method of the specified key returns false for the
     *            specified value
     * @see     #get(Object)
     */
    public Object put(Object key, Object value) {
        if (!((Key) key).isCompatibleValue(value)) {
            throw new IllegalArgumentException(value+
                                               " incompatible with "+
                                               key);
        }
        return hintmap.put((Key) key, value);
    }

    /**
     * Adds all of the keys and corresponding values from the specified
     * <code>RenderingHints</code> object to this
     * <code>RenderingHints</code> object. Keys that are present in
     * this <code>RenderingHints</code> object, but not in the specified
     * <code>RenderingHints</code> object are not affected.
     * @param hints the set of key/value pairs to be added to this
     * <code>RenderingHints</code> object
     */
    public void add(RenderingHints hints) {
        hintmap.putAll(hints.hintmap);
    }

    /**
     * Clears this <code>RenderingHints</code> object of all key/value
     * pairs.
     */
    public void clear() {
        hintmap.clear();
    }

    /**
     * Removes the key and its corresponding value from this
     * <code>RenderingHints</code> object. This method does nothing if the
     * key is not in this <code>RenderingHints</code> object.
     * @param   key   the rendering hints key that needs to be removed
     * @exception <code>ClassCastException</code> if the key can not
     *            be cast to <code>RenderingHints.Key</code>
     * @return  the value to which the key had previously been mapped in this
     *          <code>RenderingHints</code> object, or <code>null</code>
     *          if the key did not have a mapping.
     */
    public Object remove(Object key) {
        return hintmap.remove((Key) key);
    }

    /**
     * Copies all of the mappings from the specified <code>Map</code>
     * to this <code>RenderingHints</code>.  These mappings replace
     * any mappings that this <code>RenderingHints</code> had for any
     * of the keys currently in the specified <code>Map</code>.
     * @param m the specified <code>Map</code>
     * @exception <code>ClassCastException</code> class of a key or value
     *          in the specified <code>Map</code> prevents it from being
     *          stored in this <code>RenderingHints</code>.
     * @exception <code>IllegalArgumentException</code> some aspect
     *          of a key or value in the specified <code>Map</code>
     *           prevents it from being stored in
     *            this <code>RenderingHints</code>.
     */
    public void putAll(Map<?,?> m) {
        // ## javac bug?
        //if (m instanceof RenderingHints) {
        if (RenderingHints.class.isInstance(m)) {
            //hintmap.putAll(((RenderingHints) m).hintmap);
            for (Map.Entry<?,?> entry : m.entrySet())
                hintmap.put(entry.getKey(), entry.getValue());
        } else {
            // Funnel each key/value pair through our protected put method
            for (Map.Entry<?,?> entry : m.entrySet())
                put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * Returns a <code>Set</code> view of the Keys contained in this
     * <code>RenderingHints</code>.  The Set is backed by the
     * <code>RenderingHints</code>, so changes to the
     * <code>RenderingHints</code> are reflected in the <code>Set</code>,
     * and vice-versa.  If the <code>RenderingHints</code> is modified
     * while an iteration over the <code>Set</code> is in progress,
     * the results of the iteration are undefined.  The <code>Set</code>
     * supports element removal, which removes the corresponding
     * mapping from the <code>RenderingHints</code>, via the
     * <code>Iterator.remove</code>, <code>Set.remove</code>,
     * <code>removeAll</code> <code>retainAll</code>, and
     * <code>clear</code> operations.  It does not support
     * the <code>add</code> or <code>addAll</code> operations.
     *
     * @return a <code>Set</code> view of the keys contained
     * in this <code>RenderingHints</code>.
     */
    public Set<Object> keySet() {
        return hintmap.keySet();
    }

    /**
     * Returns a <code>Collection</code> view of the values
     * contained in this <code>RenderinHints</code>.
     * The <code>Collection</code> is backed by the
     * <code>RenderingHints</code>, so changes to
     * the <code>RenderingHints</code> are reflected in
     * the <code>Collection</code>, and vice-versa.
     * If the <code>RenderingHints</code> is modified while
     * an iteration over the <code>Collection</code> is
     * in progress, the results of the iteration are undefined.
     * The <code>Collection</code> supports element removal,
     * which removes the corresponding mapping from the
     * <code>RenderingHints</code>, via the
     * <code>Iterator.remove</code>,
     * <code>Collection.remove</code>, <code>removeAll</code>,
     * <code>retainAll</code> and <code>clear</code> operations.
     * It does not support the <code>add</code> or
     * <code>addAll</code> operations.
     *
     * @return a <code>Collection</code> view of the values
     *          contained in this <code>RenderingHints</code>.
     */
    public Collection<Object> values() {
        return hintmap.values();
    }

    /**
     * Returns a <code>Set</code> view of the mappings contained
     * in this <code>RenderingHints</code>.  Each element in the
     * returned <code>Set</code> is a <code>Map.Entry</code>.
     * The <code>Set</code> is backed by the <code>RenderingHints</code>,
     * so changes to the <code>RenderingHints</code> are reflected
     * in the <code>Set</code>, and vice-versa.  If the
     * <code>RenderingHints</code> is modified while
     * while an iteration over the <code>Set</code> is in progress,
     * the results of the iteration are undefined.
     * <p>
     * The entrySet returned from a <code>RenderingHints</code> object
     * is not modifiable.
     *
     * @return a <code>Set</code> view of the mappings contained in
     * this <code>RenderingHints</code>.
     */
    public Set<Map.Entry<Object,Object>> entrySet() {
        return Collections.unmodifiableMap(hintmap).entrySet();
    }

    /**
     * Compares the specified <code>Object</code> with this
     * <code>RenderingHints</code> for equality.
     * Returns <code>true</code> if the specified object is also a
     * <code>Map</code> and the two <code>Map</code> objects represent
     * the same mappings.  More formally, two <code>Map</code> objects
     * <code>t1</code> and <code>t2</code> represent the same mappings
     * if <code>t1.keySet().equals(t2.keySet())</code> and for every
     * key <code>k</code> in <code>t1.keySet()</code>,
     * <pre>
     * (t1.get(k)==null ? t2.get(k)==null : t1.get(k).equals(t2.get(k)))
     * </pre>.
     * This ensures that the <code>equals</code> method works properly across
     * different implementations of the <code>Map</code> interface.
     *
     * @param o <code>Object</code> to be compared for equality with
     * this <code>RenderingHints</code>.
     * @return <code>true</code> if the specified <code>Object</code>
     * is equal to this <code>RenderingHints</code>.
     */
    public boolean equals(Object o) {
        if (o instanceof RenderingHints) {
            return hintmap.equals(((RenderingHints) o).hintmap);
        } else if (o instanceof Map) {
            return hintmap.equals(o);
        }
        return false;
    }

    /**
     * Returns the hash code value for this <code>RenderingHints</code>.
     * The hash code of a <code>RenderingHints</code> is defined to be
     * the sum of the hashCodes of each <code>Entry</code> in the
     * <code>RenderingHints</code> object's entrySet view.  This ensures that
     * <code>t1.equals(t2)</code> implies that
     * <code>t1.hashCode()==t2.hashCode()</code> for any two <code>Map</code>
     * objects <code>t1</code> and <code>t2</code>, as required by the general
     * contract of <code>Object.hashCode</code>.
     *
     * @return the hash code value for this <code>RenderingHints</code>.
     * @see java.util.Map.Entry#hashCode()
     * @see Object#hashCode()
     * @see Object#equals(Object)
     * @see #equals(Object)
     */
    public int hashCode() {
        return hintmap.hashCode();
    }

    /**
     * Creates a clone of this <code>RenderingHints</code> object
     * that has the same contents as this <code>RenderingHints</code>
     * object.
     * @return a clone of this instance.
     */
    public Object clone() {
        RenderingHints rh;
        try {
            rh = (RenderingHints) super.clone();
            if (hintmap != null) {
                rh.hintmap = (HashMap) hintmap.clone();
            }
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError();
        }

        return rh;
    }

    /**
     * Returns a rather long string representation of the hashmap
     * which contains the mappings of keys to values for this
     * <code>RenderingHints</code> object.
     * @return  a string representation of this object.
     */
    public String toString() {
        if (hintmap == null) {
            return getClass().getName() + "@" +
                Integer.toHexString(hashCode()) +
                " (0 hints)";
        }

        return hintmap.toString();
    }
}
