1 /*
2 * Copyright (c) 1998, 2013, 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<Object,Object> 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 occurrence 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 static synchronized 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<Key>(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} to test for validity
165 * @return {@code true} if {@code val} is valid;
166 * {@code false} 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<Object,Object> 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} 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 transferred 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 receives 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 * Image resolution variant hint key.
959 * The {@code RESOLUTION_VARIANT} hint controls which image resolution
960 * variant should be chosen for image drawing.
961 *
962 * <ul>
963 * <li>{@link #VALUE_RESOLUTION_VARIANT_DEFAULT}
964 * <li>{@link #VALUE_RESOLUTION_VARIANT_BASE}
965 * <li>{@link #VALUE_RESOLUTION_VARIANT_SIZE_FIT}
966 * <li>{@link #VALUE_RESOLUTION_VARIANT_DPI_FIT}
967 * </ul>
968 * @since 9
969 */
970 public static final Key KEY_RESOLUTION_VARIANT =
971 SunHints.KEY_RESOLUTION_VARIANT;
972
973 /**
974 * Image resolution variant hint value -- an image resolution variant is
975 * chosen based on a default heuristic which may depend on the policies
976 * of the platform
977 *
978 * @see #KEY_RESOLUTION_VARIANT
979 * @since 9
980 */
981 public static final Object VALUE_RESOLUTION_VARIANT_DEFAULT =
982 SunHints.VALUE_RESOLUTION_VARIANT_DEFAULT;
983
984 /**
985 * Image resolution variant hint value -- the standard resolution of an image
986 * is always used.
987 *
988 * @see #KEY_RESOLUTION_VARIANT
989 * @since 9
990 */
991 public static final Object VALUE_RESOLUTION_VARIANT_BASE =
992 SunHints.VALUE_RESOLUTION_VARIANT_BASE;
993
994 /**
995 * Image resolution variant hint value -- an image resolution variant is
996 * chosen based on the DPI of the screen and the transform in the Graphics2D
997 * context.
998 *
999 * @see #KEY_RESOLUTION_VARIANT
1000 * @since 9
1001 */
1002 public static final Object VALUE_RESOLUTION_VARIANT_SIZE_FIT =
1003 SunHints.VALUE_RESOLUTION_VARIANT_SIZE_FIT;
1004
1005 /**
1006 * Image resolution variant hint value -- an image resolution variant is
1007 * chosen based only on the DPI of the screen.
1008 *
1009 * @see #KEY_RESOLUTION_VARIANT
1010 * @since 9
1011 */
1012 public static final Object VALUE_RESOLUTION_VARIANT_DPI_FIT =
1013 SunHints.VALUE_RESOLUTION_VARIANT_DPI_FIT;
1014
1015 /**
1016 * Constructs a new object with keys and values initialized
1017 * from the specified Map object which may be null.
1018 * @param init a map of key/value pairs to initialize the hints
1019 * or null if the object should be empty
1020 */
1021 public RenderingHints(Map<Key,?> init) {
1022 if (init != null) {
1023 hintmap.putAll(init);
1024 }
1025 }
1026
1027 /**
1028 * Constructs a new object with the specified key/value pair.
1029 * @param key the key of the particular hint property
1030 * @param value the value of the hint property specified with
1031 * {@code key}
1032 */
1033 public RenderingHints(Key key, Object value) {
1034 hintmap.put(key, value);
1035 }
1036
1037 /**
1038 * Returns the number of key-value mappings in this
1039 * {@code RenderingHints}.
1040 *
1041 * @return the number of key-value mappings in this
1042 * {@code RenderingHints}.
1043 */
1044 public int size() {
1045 return hintmap.size();
1046 }
1047
1048 /**
1049 * Returns {@code true} if this
1050 * {@code RenderingHints} contains no key-value mappings.
1051 *
1052 * @return {@code true} if this
1053 * {@code RenderingHints} contains no key-value mappings.
1054 */
1055 public boolean isEmpty() {
1056 return hintmap.isEmpty();
1057 }
1058
1059 /**
1060 * Returns {@code true} if this {@code RenderingHints}
1061 * contains a mapping for the specified key.
1062 *
1063 * @param key key whose presence in this
1064 * {@code RenderingHints} is to be tested.
1065 * @return {@code true} if this {@code RenderingHints}
1066 * contains a mapping for the specified key.
1067 * @exception ClassCastException if the key can not
1068 * be cast to {@code RenderingHints.Key}
1069 */
1070 public boolean containsKey(Object key) {
1071 return hintmap.containsKey((Key) key);
1072 }
1073
1074 /**
1075 * Returns true if this RenderingHints maps one or more keys to the
1076 * specified value.
1077 * More formally, returns {@code true} if and only
1078 * if this {@code RenderingHints}
1079 * contains at least one mapping to a value {@code v} such that
1080 * <pre>
1081 * (value==null ? v==null : value.equals(v))
1082 * </pre>.
1083 * This operation will probably require time linear in the
1084 * {@code RenderingHints} size for most implementations
1085 * of {@code RenderingHints}.
1086 *
1087 * @param value value whose presence in this
1088 * {@code RenderingHints} is to be tested.
1089 * @return {@code true} if this {@code RenderingHints}
1090 * maps one or more keys to the specified value.
1091 */
1092 public boolean containsValue(Object value) {
1093 return hintmap.containsValue(value);
1094 }
1095
1096 /**
1097 * Returns the value to which the specified key is mapped.
1098 * @param key a rendering hint key
1099 * @return the value to which the key is mapped in this object or
1100 * {@code null} if the key is not mapped to any value in
1101 * this object.
1102 * @exception ClassCastException if the key can not
1103 * be cast to {@code RenderingHints.Key}
1104 * @see #put(Object, Object)
1105 */
1106 public Object get(Object key) {
1107 return hintmap.get((Key) key);
1108 }
1109
1110 /**
1111 * Maps the specified {@code key} to the specified
1112 * {@code value} in this {@code RenderingHints} object.
1113 * Neither the key nor the value can be {@code null}.
1114 * The value can be retrieved by calling the {@code get} method
1115 * with a key that is equal to the original key.
1116 * @param key the rendering hint key.
1117 * @param value the rendering hint value.
1118 * @return the previous value of the specified key in this object
1119 * or {@code null} if it did not have one.
1120 * @exception NullPointerException if the key is
1121 * {@code null}.
1122 * @exception ClassCastException if the key can not
1123 * be cast to {@code RenderingHints.Key}
1124 * @exception IllegalArgumentException if the
1125 * {@link Key#isCompatibleValue(java.lang.Object)
1126 * Key.isCompatibleValue()}
1127 * method of the specified key returns false for the
1128 * specified value
1129 * @see #get(Object)
1130 */
1131 public Object put(Object key, Object value) {
1132 if (!((Key) key).isCompatibleValue(value)) {
1133 throw new IllegalArgumentException(value+
1134 " incompatible with "+
1135 key);
1136 }
1137 return hintmap.put((Key) key, value);
1138 }
1139
1140 /**
1141 * Adds all of the keys and corresponding values from the specified
1142 * {@code RenderingHints} object to this
1143 * {@code RenderingHints} object. Keys that are present in
1144 * this {@code RenderingHints} object, but not in the specified
1145 * {@code RenderingHints} object are not affected.
1146 * @param hints the set of key/value pairs to be added to this
1147 * {@code RenderingHints} object
1148 */
1149 public void add(RenderingHints hints) {
1150 hintmap.putAll(hints.hintmap);
1151 }
1152
1153 /**
1154 * Clears this {@code RenderingHints} object of all key/value
1155 * pairs.
1156 */
1157 public void clear() {
1158 hintmap.clear();
1159 }
1160
1161 /**
1162 * Removes the key and its corresponding value from this
1163 * {@code RenderingHints} object. This method does nothing if the
1164 * key is not in this {@code RenderingHints} object.
1165 * @param key the rendering hints key that needs to be removed
1166 * @exception ClassCastException if the key can not
1167 * be cast to {@code RenderingHints.Key}
1168 * @return the value to which the key had previously been mapped in this
1169 * {@code RenderingHints} object, or {@code null}
1170 * if the key did not have a mapping.
1171 */
1172 public Object remove(Object key) {
1173 return hintmap.remove((Key) key);
1174 }
1175
1176 /**
1177 * Copies all of the mappings from the specified {@code Map}
1178 * to this {@code RenderingHints}. These mappings replace
1179 * any mappings that this {@code RenderingHints} had for any
1180 * of the keys currently in the specified {@code Map}.
1181 * @param m the specified {@code Map}
1182 * @exception ClassCastException class of a key or value
1183 * in the specified {@code Map} prevents it from being
1184 * stored in this {@code RenderingHints}.
1185 * @exception IllegalArgumentException some aspect
1186 * of a key or value in the specified {@code Map}
1187 * prevents it from being stored in
1188 * this {@code RenderingHints}.
1189 */
1190 public void putAll(Map<?,?> m) {
1191 // ## javac bug?
1192 //if (m instanceof RenderingHints) {
1193 if (RenderingHints.class.isInstance(m)) {
1194 //hintmap.putAll(((RenderingHints) m).hintmap);
1195 for (Map.Entry<?,?> entry : m.entrySet())
1196 hintmap.put(entry.getKey(), entry.getValue());
1197 } else {
1198 // Funnel each key/value pair through our protected put method
1199 for (Map.Entry<?,?> entry : m.entrySet())
1200 put(entry.getKey(), entry.getValue());
1201 }
1202 }
1203
1204 /**
1205 * Returns a {@code Set} view of the Keys contained in this
1206 * {@code RenderingHints}. The Set is backed by the
1207 * {@code RenderingHints}, so changes to the
1208 * {@code RenderingHints} are reflected in the {@code Set},
1209 * and vice-versa. If the {@code RenderingHints} is modified
1210 * while an iteration over the {@code Set} is in progress,
1211 * the results of the iteration are undefined. The {@code Set}
1212 * supports element removal, which removes the corresponding
1213 * mapping from the {@code RenderingHints}, via the
1214 * {@code Iterator.remove}, {@code Set.remove},
1215 * {@code removeAll retainAll}, and
1216 * {@code clear} operations. It does not support
1217 * the {@code add} or {@code addAll} operations.
1218 *
1219 * @return a {@code Set} view of the keys contained
1220 * in this {@code RenderingHints}.
1221 */
1222 public Set<Object> keySet() {
1223 return hintmap.keySet();
1224 }
1225
1226 /**
1227 * Returns a {@code Collection} view of the values
1228 * contained in this {@code RenderingHints}.
1229 * The {@code Collection} is backed by the
1230 * {@code RenderingHints}, so changes to
1231 * the {@code RenderingHints} are reflected in
1232 * the {@code Collection}, and vice-versa.
1233 * If the {@code RenderingHints} is modified while
1234 * an iteration over the {@code Collection} is
1235 * in progress, the results of the iteration are undefined.
1236 * The {@code Collection} supports element removal,
1237 * which removes the corresponding mapping from the
1238 * {@code RenderingHints}, via the
1239 * {@code Iterator.remove},
1240 * {@code Collection.remove}, {@code removeAll},
1241 * {@code retainAll} and {@code clear} operations.
1242 * It does not support the {@code add} or
1243 * {@code addAll} operations.
1244 *
1245 * @return a {@code Collection} view of the values
1246 * contained in this {@code RenderingHints}.
1247 */
1248 public Collection<Object> values() {
1249 return hintmap.values();
1250 }
1251
1252 /**
1253 * Returns a {@code Set} view of the mappings contained
1254 * in this {@code RenderingHints}. Each element in the
1255 * returned {@code Set} is a {@code Map.Entry}.
1256 * The {@code Set} is backed by the {@code RenderingHints},
1257 * so changes to the {@code RenderingHints} are reflected
1258 * in the {@code Set}, and vice-versa. If the
1259 * {@code RenderingHints} is modified while
1260 * while an iteration over the {@code Set} is in progress,
1261 * the results of the iteration are undefined.
1262 * <p>
1263 * The entrySet returned from a {@code RenderingHints} object
1264 * is not modifiable.
1265 *
1266 * @return a {@code Set} view of the mappings contained in
1267 * this {@code RenderingHints}.
1268 */
1269 public Set<Map.Entry<Object,Object>> entrySet() {
1270 return Collections.unmodifiableMap(hintmap).entrySet();
1271 }
1272
1273 /**
1274 * Compares the specified {@code Object} with this
1275 * {@code RenderingHints} for equality.
1276 * Returns {@code true} if the specified object is also a
1277 * {@code Map} and the two {@code Map} objects represent
1278 * the same mappings. More formally, two {@code Map} objects
1279 * {@code t1} and {@code t2} represent the same mappings
1280 * if {@code t1.keySet().equals(t2.keySet())} and for every
1281 * key {@code k} in {@code t1.keySet()},
1282 * <pre>
1283 * (t1.get(k)==null ? t2.get(k)==null : t1.get(k).equals(t2.get(k)))
1284 * </pre>.
1285 * This ensures that the {@code equals} method works properly across
1286 * different implementations of the {@code Map} interface.
1287 *
1288 * @param o {@code Object} to be compared for equality with
1289 * this {@code RenderingHints}.
1290 * @return {@code true} if the specified {@code Object}
1291 * is equal to this {@code RenderingHints}.
1292 */
1293 public boolean equals(Object o) {
1294 if (o instanceof RenderingHints) {
1295 return hintmap.equals(((RenderingHints) o).hintmap);
1296 } else if (o instanceof Map) {
1297 return hintmap.equals(o);
1298 }
1299 return false;
1300 }
1301
1302 /**
1303 * Returns the hash code value for this {@code RenderingHints}.
1304 * The hash code of a {@code RenderingHints} is defined to be
1305 * the sum of the hashCodes of each {@code Entry} in the
1306 * {@code RenderingHints} object's entrySet view. This ensures that
1307 * {@code t1.equals(t2)} implies that
1308 * {@code t1.hashCode()==t2.hashCode()} for any two {@code Map}
1309 * objects {@code t1} and {@code t2}, as required by the general
1310 * contract of {@code Object.hashCode}.
1311 *
1312 * @return the hash code value for this {@code RenderingHints}.
1313 * @see java.util.Map.Entry#hashCode()
1314 * @see Object#hashCode()
1315 * @see Object#equals(Object)
1316 * @see #equals(Object)
1317 */
1318 public int hashCode() {
1319 return hintmap.hashCode();
1320 }
1321
1322 /**
1323 * Creates a clone of this {@code RenderingHints} object
1324 * that has the same contents as this {@code RenderingHints}
1325 * object.
1326 * @return a clone of this instance.
1327 */
1328 @SuppressWarnings("unchecked")
1329 public Object clone() {
1330 RenderingHints rh;
1331 try {
1332 rh = (RenderingHints) super.clone();
1333 if (hintmap != null) {
1334 rh.hintmap = (HashMap<Object,Object>) hintmap.clone();
1335 }
1336 } catch (CloneNotSupportedException e) {
1337 // this shouldn't happen, since we are Cloneable
1338 throw new InternalError(e);
1339 }
1340
1341 return rh;
1342 }
1343
1344 /**
1345 * Returns a rather long string representation of the hashmap
1346 * which contains the mappings of keys to values for this
1347 * {@code RenderingHints} object.
1348 * @return a string representation of this object.
1349 */
1350 public String toString() {
1351 if (hintmap == null) {
1352 return getClass().getName() + "@" +
1353 Integer.toHexString(hashCode()) +
1354 " (0 hints)";
1355 }
1356
1357 return hintmap.toString();
1358 }
1359 }
1360