| /* |
| * 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(); |
| } |
| } |