| /* | |
| * Copyright (c) 1998, 2020, 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.lang.ref.WeakReference; | |
| import java.util.Collection; | |
| import java.util.Collections; | |
| import java.util.HashMap; | |
| import java.util.Map; | |
| import java.util.Set; | |
| import sun.awt.SunHints; | |
| /** | |
| * 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<Object,Object> 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 occurrence 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 static synchronized 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<Key>(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} to test for validity | |
| * @return {@code true} if {@code val} is valid; | |
| * {@code false} 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<Object,Object> 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} 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 transferred 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 receives 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; | |
| /** | |
| * Image resolution variant hint key. | |
| * The {@code RESOLUTION_VARIANT} hint controls which image resolution | |
| * variant should be chosen for image drawing. | |
| * | |
| * <ul> | |
| * <li>{@link #VALUE_RESOLUTION_VARIANT_DEFAULT} | |
| * <li>{@link #VALUE_RESOLUTION_VARIANT_BASE} | |
| * <li>{@link #VALUE_RESOLUTION_VARIANT_SIZE_FIT} | |
| * <li>{@link #VALUE_RESOLUTION_VARIANT_DPI_FIT} | |
| * </ul> | |
| * @since 9 | |
| */ | |
| public static final Key KEY_RESOLUTION_VARIANT = | |
| SunHints.KEY_RESOLUTION_VARIANT; | |
| /** | |
| * Image resolution variant hint value -- an image resolution variant is | |
| * chosen based on a default heuristic which may depend on the policies | |
| * of the platform | |
| * | |
| * @see #KEY_RESOLUTION_VARIANT | |
| * @since 9 | |
| */ | |
| public static final Object VALUE_RESOLUTION_VARIANT_DEFAULT = | |
| SunHints.VALUE_RESOLUTION_VARIANT_DEFAULT; | |
| /** | |
| * Image resolution variant hint value -- the standard resolution of an image | |
| * is always used. | |
| * | |
| * @see #KEY_RESOLUTION_VARIANT | |
| * @since 9 | |
| */ | |
| public static final Object VALUE_RESOLUTION_VARIANT_BASE = | |
| SunHints.VALUE_RESOLUTION_VARIANT_BASE; | |
| /** | |
| * Image resolution variant hint value -- an image resolution variant is | |
| * chosen based on the DPI of the screen and the transform in the Graphics2D | |
| * context. | |
| * | |
| * @see #KEY_RESOLUTION_VARIANT | |
| * @since 9 | |
| */ | |
| public static final Object VALUE_RESOLUTION_VARIANT_SIZE_FIT = | |
| SunHints.VALUE_RESOLUTION_VARIANT_SIZE_FIT; | |
| /** | |
| * Image resolution variant hint value -- an image resolution variant is | |
| * chosen based only on the DPI of the screen. | |
| * | |
| * @see #KEY_RESOLUTION_VARIANT | |
| * @since 9 | |
| */ | |
| public static final Object VALUE_RESOLUTION_VARIANT_DPI_FIT = | |
| SunHints.VALUE_RESOLUTION_VARIANT_DPI_FIT; | |
| /** | |
| * 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} | |
| */ | |
| public RenderingHints(Key key, Object value) { | |
| hintmap.put(key, value); | |
| } | |
| /** | |
| * Returns the number of key-value mappings in this | |
| * {@code RenderingHints}. | |
| * | |
| * @return the number of key-value mappings in this | |
| * {@code RenderingHints}. | |
| */ | |
| public int size() { | |
| return hintmap.size(); | |
| } | |
| /** | |
| * Returns {@code true} if this | |
| * {@code RenderingHints} contains no key-value mappings. | |
| * | |
| * @return {@code true} if this | |
| * {@code RenderingHints} contains no key-value mappings. | |
| */ | |
| public boolean isEmpty() { | |
| return hintmap.isEmpty(); | |
| } | |
| /** | |
| * Returns {@code true} if this {@code RenderingHints} | |
| * contains a mapping for the specified key. | |
| * | |
| * @param key key whose presence in this | |
| * {@code RenderingHints} is to be tested. | |
| * @return {@code true} if this {@code RenderingHints} | |
| * contains a mapping for the specified key. | |
| * @throws ClassCastException if the key can not | |
| * be cast to {@code RenderingHints.Key} | |
| */ | |
| 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} if and only | |
| * if this {@code RenderingHints} | |
| * contains at least one mapping to a value {@code v} such that | |
| * <pre> | |
| * (value==null ? v==null : value.equals(v)) | |
| * </pre>. | |
| * This operation will probably require time linear in the | |
| * {@code RenderingHints} size for most implementations | |
| * of {@code RenderingHints}. | |
| * | |
| * @param value value whose presence in this | |
| * {@code RenderingHints} is to be tested. | |
| * @return {@code true} if this {@code RenderingHints} | |
| * 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} if the key is not mapped to any value in | |
| * this object. | |
| * @throws ClassCastException if the key can not | |
| * be cast to {@code RenderingHints.Key} | |
| * @see #put(Object, Object) | |
| */ | |
| public Object get(Object key) { | |
| return hintmap.get((Key) key); | |
| } | |
| /** | |
| * Maps the specified {@code key} to the specified | |
| * {@code value} in this {@code RenderingHints} object. | |
| * Neither the key nor the value can be {@code null}. | |
| * The value can be retrieved by calling the {@code get} 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} if it did not have one. | |
| * @throws NullPointerException if the key is | |
| * {@code null}. | |
| * @throws ClassCastException if the key can not | |
| * be cast to {@code RenderingHints.Key} | |
| * @throws IllegalArgumentException 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} object to this | |
| * {@code RenderingHints} object. Keys that are present in | |
| * this {@code RenderingHints} object, but not in the specified | |
| * {@code RenderingHints} object are not affected. | |
| * @param hints the set of key/value pairs to be added to this | |
| * {@code RenderingHints} object | |
| */ | |
| public void add(RenderingHints hints) { | |
| hintmap.putAll(hints.hintmap); | |
| } | |
| /** | |
| * Clears this {@code RenderingHints} object of all key/value | |
| * pairs. | |
| */ | |
| public void clear() { | |
| hintmap.clear(); | |
| } | |
| /** | |
| * Removes the key and its corresponding value from this | |
| * {@code RenderingHints} object. This method does nothing if the | |
| * key is not in this {@code RenderingHints} object. | |
| * @param key the rendering hints key that needs to be removed | |
| * @throws ClassCastException if the key can not | |
| * be cast to {@code RenderingHints.Key} | |
| * @return the value to which the key had previously been mapped in this | |
| * {@code RenderingHints} object, or {@code null} | |
| * 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} | |
| * to this {@code RenderingHints}. These mappings replace | |
| * any mappings that this {@code RenderingHints} had for any | |
| * of the keys currently in the specified {@code Map}. | |
| * @param m the specified {@code Map} | |
| * @throws ClassCastException class of a key or value | |
| * in the specified {@code Map} prevents it from being | |
| * stored in this {@code RenderingHints}. | |
| * @throws IllegalArgumentException some aspect | |
| * of a key or value in the specified {@code Map} | |
| * prevents it from being stored in | |
| * this {@code RenderingHints}. | |
| */ | |
| 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} view of the Keys contained in this | |
| * {@code RenderingHints}. The Set is backed by the | |
| * {@code RenderingHints}, so changes to the | |
| * {@code RenderingHints} are reflected in the {@code Set}, | |
| * and vice-versa. If the {@code RenderingHints} is modified | |
| * while an iteration over the {@code Set} is in progress, | |
| * the results of the iteration are undefined. The {@code Set} | |
| * supports element removal, which removes the corresponding | |
| * mapping from the {@code RenderingHints}, via the | |
| * {@code Iterator.remove}, {@code Set.remove}, | |
| * {@code removeAll retainAll}, and | |
| * {@code clear} operations. It does not support | |
| * the {@code add} or {@code addAll} operations. | |
| * | |
| * @return a {@code Set} view of the keys contained | |
| * in this {@code RenderingHints}. | |
| */ | |
| public Set<Object> keySet() { | |
| return hintmap.keySet(); | |
| } | |
| /** | |
| * Returns a {@code Collection} view of the values | |
| * contained in this {@code RenderingHints}. | |
| * The {@code Collection} is backed by the | |
| * {@code RenderingHints}, so changes to | |
| * the {@code RenderingHints} are reflected in | |
| * the {@code Collection}, and vice-versa. | |
| * If the {@code RenderingHints} is modified while | |
| * an iteration over the {@code Collection} is | |
| * in progress, the results of the iteration are undefined. | |
| * The {@code Collection} supports element removal, | |
| * which removes the corresponding mapping from the | |
| * {@code RenderingHints}, via the | |
| * {@code Iterator.remove}, | |
| * {@code Collection.remove}, {@code removeAll}, | |
| * {@code retainAll} and {@code clear} operations. | |
| * It does not support the {@code add} or | |
| * {@code addAll} operations. | |
| * | |
| * @return a {@code Collection} view of the values | |
| * contained in this {@code RenderingHints}. | |
| */ | |
| public Collection<Object> values() { | |
| return hintmap.values(); | |
| } | |
| /** | |
| * Returns a {@code Set} view of the mappings contained | |
| * in this {@code RenderingHints}. Each element in the | |
| * returned {@code Set} is a {@code Map.Entry}. | |
| * The {@code Set} is backed by the {@code RenderingHints}, | |
| * so changes to the {@code RenderingHints} are reflected | |
| * in the {@code Set}. If the {@code RenderingHints} is modified while | |
| * while an iteration over the {@code Set} is in progress, | |
| * the results of the iteration are undefined. | |
| * <p> | |
| * The entrySet returned from a {@code RenderingHints} object | |
| * is not modifiable. | |
| * | |
| * @return a {@code Set} view of the mappings contained in | |
| * this {@code RenderingHints}. | |
| */ | |
| public Set<Map.Entry<Object,Object>> entrySet() { | |
| return Collections.unmodifiableMap(hintmap).entrySet(); | |
| } | |
| /** | |
| * Compares the specified {@code Object} with this | |
| * {@code RenderingHints} for equality. | |
| * Returns {@code true} if the specified object is also a | |
| * {@code Map} and the two {@code Map} objects represent | |
| * the same mappings. More formally, two {@code Map} objects | |
| * {@code t1} and {@code t2} represent the same mappings | |
| * if {@code t1.keySet().equals(t2.keySet())} and for every | |
| * key {@code k} in {@code t1.keySet()}, | |
| * <pre> | |
| * (t1.get(k)==null ? t2.get(k)==null : t1.get(k).equals(t2.get(k))) | |
| * </pre>. | |
| * This ensures that the {@code equals} method works properly across | |
| * different implementations of the {@code Map} interface. | |
| * | |
| * @param o {@code Object} to be compared for equality with | |
| * this {@code RenderingHints}. | |
| * @return {@code true} if the specified {@code Object} | |
| * is equal to this {@code RenderingHints}. | |
| */ | |
| 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}. | |
| * The hash code of a {@code RenderingHints} is defined to be | |
| * the sum of the hashCodes of each {@code Entry} in the | |
| * {@code RenderingHints} object's entrySet view. This ensures that | |
| * {@code t1.equals(t2)} implies that | |
| * {@code t1.hashCode()==t2.hashCode()} for any two {@code Map} | |
| * objects {@code t1} and {@code t2}, as required by the general | |
| * contract of {@code Object.hashCode}. | |
| * | |
| * @return the hash code value for this {@code RenderingHints}. | |
| * @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} object | |
| * that has the same contents as this {@code RenderingHints} | |
| * object. | |
| * @return a clone of this instance. | |
| */ | |
| @SuppressWarnings("unchecked") | |
| public Object clone() { | |
| RenderingHints rh; | |
| try { | |
| rh = (RenderingHints) super.clone(); | |
| if (hintmap != null) { | |
| rh.hintmap = (HashMap<Object,Object>) hintmap.clone(); | |
| } | |
| } catch (CloneNotSupportedException e) { | |
| // this shouldn't happen, since we are Cloneable | |
| throw new InternalError(e); | |
| } | |
| return rh; | |
| } | |
| /** | |
| * Returns a rather long string representation of the hashmap | |
| * which contains the mappings of keys to values for this | |
| * {@code RenderingHints} 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(); | |
| } | |
| } |