History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/RenderingHints.java (1 of 18352 files). Show all

Unified · Split

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