/* * @(#)ButtonFilter.java 1.4 96/04/24 * * Copyright (c) 1994-1996 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.Image; import java.awt.Graphics; import java.awt.Rectangle; import java.util.StringTokenizer; import java.util.Vector; import java.util.Hashtable; import java.net.URL; import java.awt.image.*; import java.net.MalformedURLException; /** * An extensible ImageMap applet class. * The active areas on the image are controlled by ImageArea classes * that can be dynamically loaded over the net. * * @author Jim Graham * @version 1.4, 04/24/96 */ class ButtonFilter extends RGBImageFilter { boolean pressed; int defpercent; int border; int width; int height; ColorModel models[] = new ColorModel[7]; ColorModel origbuttonmodel; public ButtonFilter(boolean press, int p, int b, int w, int h) { pressed = press; defpercent = p; border = b; width = w; height = h; } public void setHints(int hints) { super.setHints(hints & (~ImageConsumer.COMPLETESCANLINES)); } public void setColorModel(ColorModel model) { if (model instanceof IndexColorModel && true) { IndexColorModel icm = (IndexColorModel) model; models[0] = filterIndexColorModel(icm, false, false, 0); models[1] = filterIndexColorModel(icm, true, !pressed, defpercent); models[2] = null; if (pressed) { models[3] = filterIndexColorModel(icm, true, false, defpercent/2); } else { models[3] = models[0]; } models[4] = null; models[5] = filterIndexColorModel(icm, true, pressed, defpercent); models[6] = models[0]; origbuttonmodel = model; consumer.setColorModel(models[3]); } else { super.setColorModel(model); } } public IndexColorModel filterIndexColorModel(IndexColorModel icm, boolean opaque, boolean brighter, int percent) { byte r[] = new byte[256]; byte g[] = new byte[256]; byte b[] = new byte[256]; byte a[] = new byte[256]; int mapsize = icm.getMapSize(); icm.getReds(r); icm.getGreens(g); icm.getBlues(b); if (opaque) { icm.getAlphas(a); for (int i = 0; i < mapsize; i++) { int rgb = filterRGB(icm.getRGB(i), brighter, percent); a[i] = (byte) (rgb >> 24); r[i] = (byte) (rgb >> 16); g[i] = (byte) (rgb >> 8); b[i] = (byte) (rgb >> 0); } } return new IndexColorModel(icm.getPixelSize(), mapsize, r, g, b, a); } /** * Define the ranges of varying highlight for the button. * ranges is an array of 8 values which split up a scanline into * 7 different regions of highlighting effect: * * ranges[0-1] = area outside of left edge of button * ranges[1-2] = area inside UpperLeft highlight region left of center * ranges[2-3] = area requiring custom highlighting left of center * ranges[3-4] = area inside center of button * ranges[4-5] = area requiring custom highlighting right of center * ranges[5-6] = area inside LowerRight highlight region right of center * ranges[6-7] = area outside of right edge of button * ranges[8-9] = y coordinates for which these ranges apply * * Note that ranges[0-1] and ranges[6-7] are empty where the edges of * the button touch the left and right edges of the image (everywhere * on a square button) and ranges[2-3] and ranges[4-5] are only nonempty * in those regions where the UpperLeft highlighting has leaked over * the "top" of the button onto parts of its right edge or where the * LowerRight highlighting has leaked under the "bottom" of the button * onto parts of its left edge (can't happen on square buttons, happens * occasionally on round buttons). */ public void buttonRanges(int y, int ranges[]) { ranges[0] = ranges[1] = 0; if (y < border) { ranges[2] = ranges[3] = ranges[4] = ranges[5] = width - y; ranges[8] = ranges[9] = y; } else if (y > height - border) { ranges[2] = ranges[3] = ranges[4] = ranges[5] = height - y; ranges[8] = ranges[9] = y; } else { ranges[2] = ranges[3] = border; ranges[4] = ranges[5] = width - border; ranges[8] = border; ranges[9] = height - border; } ranges[6] = ranges[7] = width; } private protected int savedranges[]; private protected int[] getRanges(int y) { int ranges[] = savedranges; if (ranges == null) { ranges = savedranges = new int[10]; ranges[8] = ranges[9] = -1; } if (y < ranges[8] || y > ranges[9]) { buttonRanges(y, ranges); } return ranges; } public void setPixels(int x, int y, int w, int h, ColorModel model, byte pixels[], int off, int scansize) { if (model == origbuttonmodel) { int ranges[] = getRanges(y); int x2 = x + w; int y2 = y + h; for (int cy = y; cy < y2; cy++) { if (cy < ranges[8] || cy > ranges[9]) { buttonRanges(cy, ranges); } for (int i = 0; i < 7; i++) { if (x2 > ranges[i] && x < ranges[i+1]) { int cx1 = Math.max(x, ranges[i]); int cx2 = Math.min(x2, ranges[i+1]); if (models[i] == null) { super.setPixels(cx1, cy, cx2 - cx1, 1, model, pixels, off + (cx1 - x), scansize); } else { if (cx1 < cx2) { consumer.setPixels(cx1, cy, cx2 - cx1, 1, models[i], pixels, off + (cx1 - x), scansize); } } } } off += scansize; } } else { super.setPixels(x, y, w, h, model, pixels, off, scansize); } } public int filterRGB(int x, int y, int rgb) { boolean brighter; int percent; if ((x < border && y < height - x) || (y < border && x < width - y)) { brighter = !pressed; percent = defpercent; } else if (x >= width - border || y >= height - border) { brighter = pressed; percent = defpercent; } else if (pressed) { brighter = false; percent = defpercent / 2; } else { return rgb & 0x00ffffff; } return filterRGB(rgb, brighter, percent); } public int filterRGB(int rgb, boolean brighter, int percent) { int r = (rgb >> 16) & 0xff; int g = (rgb >> 8) & 0xff; int b = (rgb >> 0) & 0xff; if (brighter) { r = (255 - ((255 - r) * (100 - percent) / 100)); g = (255 - ((255 - g) * (100 - percent) / 100)); b = (255 - ((255 - b) * (100 - percent) / 100)); } else { r = (r * (100 - percent) / 100); g = (g * (100 - percent) / 100); b = (b * (100 - percent) / 100); } return (rgb & 0xff000000) | (r << 16) | (g << 8) | (b << 0); } }