2
|
1 |
/*
|
|
2 |
* Copyright 1998-2006 Sun Microsystems, Inc. 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. Sun designates this
|
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
|
9 |
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
23 |
* have any 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 |
}
|