1/*
2 * Copyright (c) 1999, 2016, 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
26package sun.java2d.loops;
27
28import java.awt.image.ColorModel;
29import sun.awt.image.PixelConverter;
30import java.util.HashMap;
31
32/**
33 * A SurfaceType object provides a chained description of a type of
34 * drawing surface.  The object will provide a single String constant
35 * descriptor which is one way of viewing or accessing a particular
36 * drawing surface as well as a pointer to another SurfaceType which
37 * describes the same drawing surface in a different (typically more
38 * generalized) way.
39 * <p>
40 * A more specific description of a surface is considered a "subtype"
41 * and a more general description is considered a "supertype".  Thus,
42 * the deriveSubType method provides a way to create a new SurfaceType
43 * that is related to but more specific than an existing SurfaceType and
44 * the getSuperType method provides a way to ask a given SurfaceType
45 * for a more general way to describe the same surface.
46 * <p>
47 * Note that you cannot construct a brand new root for a chain since
48 * the constructor is private.  Every chain of types must at some point
49 * derive from the Any node provided here using the deriveSubType()
50 * method.  The presence of this common Any node on every chain
51 * ensures that all chains end with the DESC_ANY descriptor so that
52 * a suitable General GraphicsPrimitive object can be obtained for
53 * the indicated surface if all of the more specific searches fail.
54 */
55public final class SurfaceType {
56
57    private static int unusedUID = 1;
58    private static HashMap<String, Integer> surfaceUIDMap = new HashMap<>(100);
59
60    /*
61     * CONSTANTS USED BY ALL PRIMITIVES TO DESCRIBE THE SURFACES
62     * THEY CAN OPERATE ON
63     */
64
65    /**
66     * surface is unknown color model or sample model.
67     */
68    public static final String
69        DESC_ANY            = "Any Surface";
70
71    /**
72     * common surface formats defined in BufferedImage
73     */
74    public static final String
75        DESC_INT_RGB        = "Integer RGB";
76    public static final String
77        DESC_INT_ARGB       = "Integer ARGB";
78    public static final String
79        DESC_INT_ARGB_PRE   = "Integer ARGB Premultiplied";
80    public static final String
81        DESC_INT_BGR        = "Integer BGR";
82    public static final String
83        DESC_3BYTE_BGR      = "3 Byte BGR";
84    public static final String
85        DESC_4BYTE_ABGR     = "4 Byte ABGR";
86    public static final String
87        DESC_4BYTE_ABGR_PRE = "4 Byte ABGR Premultiplied";
88    public static final String
89        DESC_USHORT_565_RGB = "Short 565 RGB";
90    public static final String
91        DESC_USHORT_555_RGB = "Short 555 RGB";
92    public static final String
93        DESC_USHORT_555_RGBx= "Short 555 RGBx";
94    public static final String
95        DESC_USHORT_4444_ARGB= "Short 4444 ARGB";
96    public static final String
97        DESC_BYTE_GRAY      = "8-bit Gray";
98    public static final String
99        DESC_USHORT_INDEXED = "16-bit Indexed";
100    public static final String
101        DESC_USHORT_GRAY    = "16-bit Gray";
102    public static final String
103        DESC_BYTE_BINARY    = "Packed Binary Bitmap";
104    public static final String
105        DESC_BYTE_INDEXED   = "8-bit Indexed";
106
107    /**
108     * wildcard format which indicates that the GraphicsPrimitive
109     * is independent of the color model on an IntegerComponent
110     * sample model surface
111     */
112    public static final String DESC_ANY_INT = "Any Discrete Integer";
113
114    /**
115     * wildcard format which indicates that the GraphicsPrimitive
116     * is independent of the color model on a ShortComponent
117     * sample model surface
118     */
119    public static final String DESC_ANY_SHORT = "Any Discrete Short";
120
121    /**
122     * wildcard format which indicates that the GraphicsPrimitive
123     * is independent of the color model on a ByteComponent
124     * sample model surface
125     */
126    public static final String DESC_ANY_BYTE = "Any Discrete Byte";
127
128    /**
129     * wildcard format which indicates that the GraphicsPrimitive
130     * operates on a surface with 3 component interleaved Raster and
131     * sample model and a ComponentColorModel with an arbitrary ordering
132     * of the RGB channels
133     */
134    public static final String DESC_ANY_3BYTE = "Any 3 Byte Component";
135
136    /**
137     * wildcard format which indicates that the GraphicsPrimitive
138     * operates on a surface with 4 component interleaved Raster and
139     * sample model and a ComponentColorModel with an arbitrary ordering
140     * of the ARGB channels
141     */
142    public static final String DESC_ANY_4BYTE = "Any 4 Byte Component";
143
144    /**
145     * wildcard format which indicates that the GraphicsPrimitive
146     * operates on a surface with a single component IntegerComponent
147     * sample model and a DirectColorModel with an arbitrary ordering
148     * of the RGB channels
149     */
150    public static final String DESC_ANY_INT_DCM = "Any Integer DCM";
151
152    /**
153     * additional IntegerComponent types common on Windows
154     */
155    public static final String DESC_INT_RGBx = "Integer RGBx";
156    public static final String DESC_INT_BGRx = "Integer BGRx";
157
158    /**
159     * additional 3 byte format common on Windows
160     */
161    public static final String DESC_3BYTE_RGB = "3 Byte RGB";
162
163    /**
164     * common formats for BITMASK transparency.
165     */
166    public static final String DESC_INT_ARGB_BM     = "Int ARGB (Bitmask)";
167    public static final String DESC_BYTE_INDEXED_BM = "8-bit Indexed (Bitmask)";
168
169    /**
170     * Opaque 8-bit indexed images
171     */
172    public static final String
173        DESC_BYTE_INDEXED_OPAQUE = "8-bit Indexed (Opaque)";
174
175    /**
176     * Special Gray Scale types for rendering loops.  Really indexed
177     * types, but colormap has all gray values.
178     */
179    public static final String DESC_INDEX8_GRAY  = "8-bit Palettized Gray";
180    public static final String DESC_INDEX12_GRAY = "12-bit Palettized Gray";
181
182    public static final String
183        DESC_BYTE_BINARY_1BIT = "Packed Binary 1-bit Bitmap";
184    public static final String
185        DESC_BYTE_BINARY_2BIT = "Packed Binary 2-bit Bitmap";
186    public static final String
187        DESC_BYTE_BINARY_4BIT = "Packed Binary 4-bit Bitmap";
188
189    /**
190     * Special type for describing the sources of loops that render the
191     * current foreground color or paint instead of copying colors from
192     * a source surface.
193     */
194    public static final String DESC_ANY_PAINT      = "Paint Object";
195    public static final String DESC_ANY_COLOR      = "Single Color";
196    public static final String DESC_OPAQUE_COLOR   = "Opaque Color";
197    public static final String
198        DESC_GRADIENT_PAINT        = "Gradient Paint";
199    public static final String
200        DESC_OPAQUE_GRADIENT_PAINT = "Opaque Gradient Paint";
201    public static final String
202        DESC_TEXTURE_PAINT         = "Texture Paint";
203    public static final String
204        DESC_OPAQUE_TEXTURE_PAINT  = "Opaque Texture Paint";
205    public static final String
206        DESC_LINEAR_GRADIENT_PAINT        = "Linear Gradient Paint";
207    public static final String
208        DESC_OPAQUE_LINEAR_GRADIENT_PAINT = "Opaque Linear Gradient Paint";
209    public static final String
210        DESC_RADIAL_GRADIENT_PAINT        = "Radial Gradient Paint";
211    public static final String
212        DESC_OPAQUE_RADIAL_GRADIENT_PAINT = "Opaque Radial Gradient Paint";
213
214    /*
215     * END OF SURFACE TYPE CONSTANTS
216     */
217
218
219    /**
220     * The root SurfaceType object for all chains of surface descriptions.
221     * The root uses the default PixelConverter object, which uses a given
222     * ColorModel object to calculate its pixelFor() values when asked.
223     * Any SurfaceType objects that are not created with a specific
224     * PixelConverter object will inherit this behavior from the root.
225     */
226    public static final SurfaceType Any =
227        new SurfaceType(null, DESC_ANY, PixelConverter.instance);
228
229    /*
230     * START OF SurfaceType OBJECTS FOR THE VARIOUS CONSTANTS
231     */
232
233    public static final SurfaceType
234        AnyInt            = Any.deriveSubType(DESC_ANY_INT);
235    public static final SurfaceType
236        AnyShort          = Any.deriveSubType(DESC_ANY_SHORT);
237    public static final SurfaceType
238        AnyByte           = Any.deriveSubType(DESC_ANY_BYTE);
239    public static final SurfaceType
240        AnyByteBinary     = Any.deriveSubType(DESC_BYTE_BINARY);
241    public static final SurfaceType
242        Any3Byte          = Any.deriveSubType(DESC_ANY_3BYTE);
243    public static final SurfaceType
244        Any4Byte          = Any.deriveSubType(DESC_ANY_4BYTE);
245    public static final SurfaceType
246        AnyDcm            = AnyInt.deriveSubType(DESC_ANY_INT_DCM);
247
248    public static final SurfaceType
249        Custom            = Any;
250    public static final SurfaceType IntRgb =
251        AnyDcm.deriveSubType(DESC_INT_RGB, PixelConverter.Xrgb.instance);
252
253    public static final SurfaceType IntArgb =
254        AnyDcm.deriveSubType(DESC_INT_ARGB, PixelConverter.Argb.instance);
255
256    public static final SurfaceType IntArgbPre =
257        AnyDcm.deriveSubType(DESC_INT_ARGB_PRE,
258                             PixelConverter.ArgbPre.instance);
259
260    public static final SurfaceType IntBgr =
261        AnyDcm.deriveSubType(DESC_INT_BGR, PixelConverter.Xbgr.instance);
262
263    public static final SurfaceType ThreeByteBgr =
264        Any3Byte.deriveSubType(DESC_3BYTE_BGR, PixelConverter.Xrgb.instance);
265
266    public static final SurfaceType FourByteAbgr =
267        Any4Byte.deriveSubType(DESC_4BYTE_ABGR, PixelConverter.Rgba.instance);
268
269    public static final SurfaceType FourByteAbgrPre =
270        Any4Byte.deriveSubType(DESC_4BYTE_ABGR_PRE,
271                               PixelConverter.RgbaPre.instance);
272
273    public static final SurfaceType Ushort565Rgb =
274        AnyShort.deriveSubType(DESC_USHORT_565_RGB,
275                               PixelConverter.Ushort565Rgb.instance);
276
277    public static final SurfaceType Ushort555Rgb =
278        AnyShort.deriveSubType(DESC_USHORT_555_RGB,
279                               PixelConverter.Ushort555Rgb.instance);
280
281    public static final SurfaceType Ushort555Rgbx =
282        AnyShort.deriveSubType(DESC_USHORT_555_RGBx,
283                               PixelConverter.Ushort555Rgbx.instance);
284
285    public static final SurfaceType Ushort4444Argb =
286        AnyShort.deriveSubType(DESC_USHORT_4444_ARGB,
287                               PixelConverter.Ushort4444Argb.instance);
288
289    public static final SurfaceType UshortIndexed =
290        AnyShort.deriveSubType(DESC_USHORT_INDEXED);
291
292    public static final SurfaceType ByteGray =
293        AnyByte.deriveSubType(DESC_BYTE_GRAY,
294                              PixelConverter.ByteGray.instance);
295
296    public static final SurfaceType UshortGray =
297        AnyShort.deriveSubType(DESC_USHORT_GRAY,
298                               PixelConverter.UshortGray.instance);
299
300    public static final SurfaceType ByteBinary1Bit =
301        AnyByteBinary.deriveSubType(DESC_BYTE_BINARY_1BIT);
302    public static final SurfaceType ByteBinary2Bit =
303        AnyByteBinary.deriveSubType(DESC_BYTE_BINARY_2BIT);
304    public static final SurfaceType ByteBinary4Bit =
305        AnyByteBinary.deriveSubType(DESC_BYTE_BINARY_4BIT);
306
307    public static final SurfaceType ByteIndexed =
308        AnyByte.deriveSubType(DESC_BYTE_INDEXED);
309
310    public static final SurfaceType IntRgbx =
311        AnyDcm.deriveSubType(DESC_INT_RGBx, PixelConverter.Rgbx.instance);
312
313    public static final SurfaceType IntBgrx =
314        AnyDcm.deriveSubType(DESC_INT_BGRx, PixelConverter.Bgrx.instance);
315
316    public static final SurfaceType ThreeByteRgb =
317        Any3Byte.deriveSubType(DESC_3BYTE_RGB, PixelConverter.Xbgr.instance);
318
319    public static final SurfaceType IntArgbBm =
320        AnyDcm.deriveSubType(DESC_INT_ARGB_BM, PixelConverter.ArgbBm.instance);
321
322    public static final SurfaceType ByteIndexedBm =
323        ByteIndexed.deriveSubType(DESC_BYTE_INDEXED_BM);
324
325    public static final SurfaceType ByteIndexedOpaque =
326        ByteIndexedBm.deriveSubType(DESC_BYTE_INDEXED_OPAQUE);
327
328    public static final SurfaceType Index8Gray =
329        ByteIndexedOpaque.deriveSubType(DESC_INDEX8_GRAY);
330
331    public static final SurfaceType Index12Gray =
332        Any.deriveSubType(DESC_INDEX12_GRAY);
333
334    public static final SurfaceType AnyPaint =
335        Any.deriveSubType(DESC_ANY_PAINT);
336
337    public static final SurfaceType AnyColor =
338        AnyPaint.deriveSubType(DESC_ANY_COLOR);
339
340    public static final SurfaceType OpaqueColor =
341        AnyColor.deriveSubType(DESC_OPAQUE_COLOR);
342
343    public static final SurfaceType GradientPaint =
344        AnyPaint.deriveSubType(DESC_GRADIENT_PAINT);
345    public static final SurfaceType OpaqueGradientPaint =
346        GradientPaint.deriveSubType(DESC_OPAQUE_GRADIENT_PAINT);
347
348    public static final SurfaceType LinearGradientPaint =
349        AnyPaint.deriveSubType(DESC_LINEAR_GRADIENT_PAINT);
350    public static final SurfaceType OpaqueLinearGradientPaint =
351        LinearGradientPaint.deriveSubType(DESC_OPAQUE_LINEAR_GRADIENT_PAINT);
352
353    public static final SurfaceType RadialGradientPaint =
354        AnyPaint.deriveSubType(DESC_RADIAL_GRADIENT_PAINT);
355    public static final SurfaceType OpaqueRadialGradientPaint =
356        RadialGradientPaint.deriveSubType(DESC_OPAQUE_RADIAL_GRADIENT_PAINT);
357
358    public static final SurfaceType TexturePaint =
359        AnyPaint.deriveSubType(DESC_TEXTURE_PAINT);
360    public static final SurfaceType OpaqueTexturePaint =
361        TexturePaint.deriveSubType(DESC_OPAQUE_TEXTURE_PAINT);
362
363    /*
364     * END OF SurfaceType OBJECTS FOR THE VARIOUS CONSTANTS
365     */
366
367    /**
368     * Return a new SurfaceType object which uses this object as its
369     * more general "supertype" descriptor.  If no operation can be
370     * found that manipulates the type of surface described more exactly
371     * by desc, then this object will define the more relaxed specification
372     * of the surface that can be used to find a more general operator.
373     */
374    public SurfaceType deriveSubType(String desc) {
375        return new SurfaceType(this, desc);
376    }
377
378    public SurfaceType deriveSubType(String desc,
379                                     PixelConverter pixelConverter) {
380        return new SurfaceType(this, desc, pixelConverter);
381    }
382
383    private int uniqueID;
384    private String desc;
385    private SurfaceType next;
386    protected PixelConverter pixelConverter;
387
388    private SurfaceType(SurfaceType parent, String desc,
389                        PixelConverter pixelConverter) {
390        next = parent;
391        this.desc = desc;
392        this.uniqueID = makeUniqueID(desc);
393        this.pixelConverter = pixelConverter;
394    }
395
396    private SurfaceType(SurfaceType parent, String desc) {
397        next = parent;
398        this.desc = desc;
399        this.uniqueID = makeUniqueID(desc);
400        this.pixelConverter = parent.pixelConverter;
401    }
402
403    public static synchronized int makeUniqueID(String desc) {
404        Integer i = surfaceUIDMap.get(desc);
405
406        if (i == null) {
407            if (unusedUID > 255) {
408                throw new InternalError("surface type id overflow");
409            }
410            i = Integer.valueOf(unusedUID++);
411            surfaceUIDMap.put(desc, i);
412        }
413        return i.intValue();
414    }
415
416    public int getUniqueID() {
417        return uniqueID;
418    }
419
420    public String getDescriptor() {
421        return desc;
422    }
423
424    public SurfaceType getSuperType() {
425        return next;
426    }
427
428    public PixelConverter getPixelConverter() {
429        return pixelConverter;
430    }
431
432    public int pixelFor(int rgb, ColorModel cm) {
433        return pixelConverter.rgbToPixel(rgb, cm);
434    }
435
436    public int rgbFor(int pixel, ColorModel cm) {
437        return pixelConverter.pixelToRgb(pixel, cm);
438    }
439
440    public int getAlphaMask() {
441        return pixelConverter.getAlphaMask();
442    }
443
444    public int hashCode() {
445        return desc.hashCode();
446    }
447
448    public boolean equals(Object o) {
449        if (o instanceof SurfaceType) {
450            return (((SurfaceType) o).uniqueID == this.uniqueID);
451        }
452        return false;
453    }
454
455    public String toString() {
456        return desc;
457    }
458
459}
460