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