/* * Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and * without fee is hereby granted. * Please refer to the file http://java.sun.com/copy_trademarks.html * for further important copyright and trademark information and to * http://java.sun.com/licensing.html for further important licensing * information for the Java (tm) Technology. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. * * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). SUN * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR * HIGH RISK ACTIVITIES. * */ import java.applet.Applet; import java.awt.Color; import java.awt.Image; import java.awt.Graphics; import java.net.URL; import java.net.MalformedURLException; import java.awt.image.ImageFilter; import java.awt.image.RGBImageFilter; import java.awt.image.ImageProducer; import java.awt.image.FilteredImageSource; import java.util.Hashtable; /** * An applet class that generates colored bullets dynamically. * * The source for the bullet is any GIF image, preferably grayscale. * The colormap of the image is modified to blend between the background * and foreground colors based on the color components in the pixels * of the image. Separate blending is done on the R, G, and B components * of the colors so a grayscale image will produce the most predictable * blending between background and foreground colors. * * @author Jim Graham * @version 1.1, 01/23/96 */ public class AlphaBullet extends Applet { /** * Cache of colors indexed by name or color-spec. */ static Hashtable colorCache = new Hashtable(); /** * Cache of colored bullets indexed by fg,bg,alphaurl. */ static Hashtable bulletCache = new Hashtable(); /** * The final bullet image with the appropriate colors. */ Image bulletImage; /** * Initialize the color hash table. */ static { colorCache.put("red", Color.red); colorCache.put("green", Color.green); colorCache.put("blue", Color.blue); colorCache.put("cyan", Color.cyan); colorCache.put("magenta", Color.magenta); colorCache.put("yellow", Color.yellow); colorCache.put("orange", Color.orange); colorCache.put("pink", Color.pink); colorCache.put("white", Color.white); colorCache.put("black", Color.black); } /** * Generate a color from a specification string. The string * can either be a color name which is looked up in the colorCache * hash table, or it can be a 6 digit hex number which is converted * to a color as RRGGBB. */ private synchronized Color lookupColor(String colorName) { String lowerName = colorName.toLowerCase(); Color newcolor = (Color) colorCache.get(lowerName); if (newcolor != null) return newcolor; int colorval; try { colorval = java.lang.Integer.parseInt(lowerName, 16); } catch (NumberFormatException e) { return Color.black; } int r = (colorval >> 16) & 0xff; int g = (colorval >> 8) & 0xff; int b = colorval & 0xff; newcolor = new Color(r, g, b); colorCache.put(lowerName, newcolor); return newcolor; } /** * Create a bullet bitmap from foreground, background colors and * an alpha image. */ private static synchronized Image makeBullet(AlphaBullet app, Color fg, Color bg, URL url) { String hashName = "" + fg + bg + url; Image bulletImage = (Image) bulletCache.get(hashName); if (bulletImage != null) { return bulletImage; } Image alphaImage = app.getImage(url); ImageFilter imgf = new AlphaColorFilter(fg, bg); ImageProducer imgp = new FilteredImageSource(alphaImage.getSource(), imgf); bulletImage = app.createImage(imgp); bulletCache.put(hashName, bulletImage); return bulletImage; } /** * Initialize the applet. Get parameters. */ public void init() { String attr = getParameter("img"); String dir = (attr != null) ? attr : "images/wave-alpha.gif"; URL url; try { url = new URL(getDocumentBase(), dir); } catch (MalformedURLException e) { return; } attr = getParameter("fg"); Color fg = (attr != null) ? lookupColor(attr) : getForeground(); attr = getParameter("bg"); Color bg = (attr != null) ? lookupColor(attr) : getBackground(); bulletImage = makeBullet(this, fg, bg, url); } /** * Paint the bullet or error indicator. */ public void paint(Graphics g) { if (bulletImage == null || (checkImage(bulletImage, this) & ERROR) != 0) { g.setColor(Color.red); g.fillRect(0, 0, size().width, size().height); } else { g.drawImage(bulletImage, 0, 0, this); } } } /** * The AlphaColorFilter class implements in ImageFilter which * interpolates the colors in an image between a background * color and a foreground color based on the intensity of the * color components in the source image at that location. */ class AlphaColorFilter extends RGBImageFilter { /** * The foreground color used to replace the colors in the * image wherever the color intensities are brightest. */ Color fgColor; /** * The background color used to replace the colors in the * image wherever the color intensities are darkest. */ Color bgColor; /** * Construct an AlphaColorFilter object which performs * interpolation filtering between the specified foreground * and background colors. */ public AlphaColorFilter(Color fg, Color bg) { fgColor = fg; bgColor = bg; canFilterIndexColorModel = true; } /** * Interpolate a color component, given a foreground, background * and alpha value components. */ private int interpolate(int fg, int bg, int alpha) { int newval = (((fg - bg) * alpha) / 255) + bg; return newval; } /** * Filter an individual pixel in the image by interpolating * between the foreground and background colors depending on * the brightness of the pixel in the source image. */ public int filterRGB(int x, int y, int rgb) { int alpha = (rgb >> 24) & 0xff; int red = (rgb >> 16) & 0xff; int green = (rgb >> 8) & 0xff; int blue = (rgb ) & 0xff; red = interpolate(fgColor.getRed(), bgColor.getRed(), red); green = interpolate(fgColor.getGreen(), bgColor.getGreen(), green); blue = interpolate(fgColor.getBlue(), bgColor.getBlue(), blue); return (alpha << 24) | (red << 16) | (green << 8) | (blue); } }