home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / un2maiq4 / pjjava / src / pj / awt / weatherimagemap.java < prev    next >
Encoding:
Java Source  |  1996-08-14  |  22.5 KB  |  823 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.     Written by the Personal Journal developers of Dow Jones & Company, Inc.
  4.  
  5.     Dow Jones makes no representations or warranties about 
  6.     the suitability of this software, either express or 
  7.     implied, including but not limited to the implied warranties 
  8.     of merchantability, fitness for a particular purpose, 
  9.     or non-infringement.  Dow Jones will not be liable for 
  10.     any damages suffered by a user as a result of using, 
  11.     modifying or distributing this software or its derivatives.
  12.  
  13.  
  14.     @(#)WeatherImageMap.java  0.00 23-Jan-96
  15.  
  16.         A WeatherImageMap that extends Canvas.
  17.         Most of the code here was borrowed and modified from Java demo(ImageMap).
  18.         This file contains three classes: WeatherImageMap, NameArea, and HighlightFilter.
  19.  
  20.     Authors:
  21.  
  22.         jlee    James Lee
  23.  
  24.  
  25.     Version Ident:
  26.  
  27.         $Header$
  28.  
  29.  
  30.     History:
  31.  
  32.         0.00 23-Jan-96  jlee    Initial Creation
  33.              14-Feb-96  jlee    Corrected a mapping bug: mapping between region and weather report
  34.              19-Mar-96  jlee    Added weather region message functionality
  35.  
  36. ---------------------------------------------------------------------------*/
  37.  
  38. package pj.awt;
  39.  
  40.  
  41. import pj.awt.PjTabNotebook;
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48. import java.awt.Canvas;
  49. import java.awt.Event;
  50. import java.awt.Graphics;
  51. import java.awt.image.*;
  52. import java.awt.Image;
  53. import java.awt.Rectangle;
  54. import java.net.URL;
  55. import java.util.StringTokenizer;
  56. import java.util.Vector;
  57. import java.util.Hashtable;
  58.  
  59.  
  60. import java.util.*;
  61.  
  62.  
  63. /**
  64.  * An extensible WeatherImageMap Canvas class.
  65.  * The active areas on the image are controlled by ImageMapArea classes
  66.  * which are hard-coded in WeatherImageMap class.
  67.  *
  68.  * @author      James Lee
  69.  * @version     0.00 23-Jan-96
  70.  */
  71. public class WeatherImageMap extends Canvas
  72.     {
  73.     // --- Class variables
  74.  
  75.     /**
  76.      * The primary highlight mode to be used.
  77.      */
  78.     static final int    BRIGHTER    = 0;
  79.     static final int    DARKER      = 1;
  80.  
  81.  
  82.  
  83.     // --- Instance variables
  84.  
  85.     /**
  86.      * The unhighlighted image being mapped.
  87.      */
  88.     Image baseImage;
  89.  
  90.     /**
  91.      * The list of image area handling objects;
  92.      */
  93.     ImageMapArea areas[];
  94.  
  95.     /**
  96.      * The primary highlight mode to be used.
  97.      */
  98.     int hlmode    = DARKER;
  99.  
  100.     /**
  101.      * The percentage of highlight to apply for the primary highlight mode.
  102.      */
  103.     int hlpercent = 25;
  104.  
  105.     /**
  106.      * The string array of rectangular area in the weather map.
  107.      */
  108.     private String strRec[];
  109.  
  110.  
  111.     private boolean   fullrepaint        = false;
  112.     private Rectangle repaintrect        = new Rectangle();
  113.     private long lastupdate              = 0;
  114.     private final static long UPDATERATE = 100;
  115.  
  116.     private int pressX;
  117.     private int pressY;
  118.  
  119.  
  120.     // --- Public operations
  121.  
  122.  
  123.     /**
  124.      * Get a rectangular region of the baseImage highlighted according to
  125.      * the primary highlight specification.
  126.      */
  127.     Image getHighlight(int x, int y, int w, int h)
  128.         {
  129.         return getHighlight(x, y, w, h, hlmode, hlpercent);
  130.         }
  131.  
  132.     /**
  133.      * Get a rectangular region of the baseImage with a specific highlight.
  134.      */
  135.     Image getHighlight(int x, int y, int w, int h, int mode, int percent)
  136.         {
  137.         return getHighlight(x, y, w, h, new HighlightFilter(mode == BRIGHTER, percent));
  138.         }
  139.  
  140.     /**
  141.      * Get a rectangular region of the baseImage modified by an image filter.
  142.      */
  143.     Image getHighlight(int x, int y, int w, int h, ImageFilter filter)
  144.         {
  145.         Image cropped = makeImage(baseImage, new CropImageFilter(x, y, w, h));
  146.         return makeImage(cropped, filter);
  147.         }
  148.  
  149.     /**
  150.      * Make the primary highlighted version of the baseImage.
  151.      */
  152.     Image makeImage(Image orig, ImageFilter filter)
  153.         {
  154.         return createImage(new FilteredImageSource(orig.getSource(), filter));
  155.         }
  156.  
  157.     /**
  158.      * public WeatherImageMap constructer and initialize the ImageMapAreas.
  159.      *
  160.      * @param img An image(weather map)
  161.      */
  162.     public WeatherImageMap(Image img)
  163.         {
  164.         baseImage = img;
  165.  
  166.         strRec = new String[10];
  167.         strRec[0] = "87,51,  27,30,  U.S. Northeast";
  168.         strRec[1] = "62,64,  24,28,  U.S. Middle";
  169.         strRec[2] = "78,80,  19,23,  U.S. Southeast";
  170.         strRec[3] = "38,36,  56,33,  Canada";
  171.         strRec[4] = "41,68,  26,31,  U.S. West";
  172.         strRec[5] = "137,47, 33,36,  Europe";
  173.         strRec[6] = "86,101, 44,56,  South America/Caribbean";
  174.         strRec[7] = "167,75, 29,29,  Middle East";
  175.         strRec[8] = "196,49, 75,103, Asia/Australia";
  176.         strRec[9] = "138,84, 36,52,  Africa";
  177.  
  178.         Vector areaVec = new Vector();
  179.         for( int i = 0; i < 10; i++ )
  180.             {
  181.             ImageMapArea newArea;
  182.             newArea = new NameArea();
  183.             newArea.init(this, strRec[i]);
  184.             areaVec.addElement(newArea);
  185.             }
  186.         areas = new ImageMapArea[areaVec.size()];
  187.         areaVec.copyInto(areas);
  188.  
  189.         //Checking image size asynchronously.
  190.         checkSize();
  191.         System.out.println("Debug-WeatherImageMap:constructed");
  192.         }
  193.  
  194.     /**
  195.      * Check the size of this Canvas while the image is being loaded.
  196.      */
  197.     synchronized void checkSize()
  198.         {
  199.         int w = baseImage.getWidth(this);
  200.         int h = baseImage.getHeight(this);
  201.  
  202.         if (w > 0 && h > 0)
  203.             {
  204.             resize(w, h);
  205.             repaintrect.x = repaintrect.y = 0;
  206.             repaintrect.width = w;
  207.             repaintrect.height = h;
  208.             fullrepaint = true;
  209.             repaint();
  210.             }
  211.         }
  212.  
  213.  
  214.  
  215.     /**
  216.      * Handle updates from images being loaded.
  217.      *
  218.      * @param img An Image
  219.      * @param infoflags Image info flags
  220.      * @param x X coordinate of the Image
  221.      * @param y Y coordinate of the Image
  222.      * @param width Width of the Image
  223.      * @param height Height of the Image
  224.      *
  225.      * @return true if image has been changed, false otherwise.
  226.      */
  227.     public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
  228.             {
  229.             if ((infoflags & (WIDTH | HEIGHT)) != 0)
  230.                 {
  231.                 checkSize();
  232.                 }
  233.             if ((infoflags & (SOMEBITS | FRAMEBITS | ALLBITS)) != 0)
  234.                 {
  235.                 repaint(((infoflags & (FRAMEBITS | ALLBITS)) != 0) ? 0 : UPDATERATE, x, y, width, height);
  236.                 }
  237.             return (infoflags & (ALLBITS | ERROR)) == 0;
  238.             }
  239.  
  240.     /**
  241.      * Paint the image and all active highlights.
  242.      *
  243.      * @param g An Graphics object
  244.      */
  245.     public void paint(Graphics g)
  246.         {
  247.         synchronized(this)
  248.             {
  249.             if (fullrepaint)
  250.                 {
  251.                 g = g.create();
  252.                 g.clipRect(repaintrect.x, repaintrect.y, repaintrect.width, repaintrect.height);
  253.                 fullrepaint = false;
  254.                 }
  255.             }
  256.  
  257.         if (baseImage == null)
  258.             {
  259.             return;
  260.             }
  261.  
  262.         g.drawImage(baseImage, 0, 0, this);
  263.  
  264.         if (areas != null)
  265.             {
  266.             for (int i = areas.length; --i >= 0; )
  267.                 {
  268.                 if (areas[i].active || areas[i].entered)
  269.                     {
  270.                     areas[i].setState(g, areas[i].entered);
  271.                     }
  272.                 }
  273.             }
  274.         }
  275.  
  276.     /**
  277.      * Update the active highlights on the image.
  278.      *
  279.      * @param g An Graphics object
  280.      */
  281.     public void update(Graphics g)
  282.         {
  283.         if (fullrepaint)
  284.             {
  285.             paint(g);
  286.             return;
  287.             }
  288.  
  289.         if (baseImage == null)
  290.             {
  291.             return;
  292.             }
  293.  
  294.         g.drawImage(baseImage, 0, 0, this);
  295.  
  296.         if (areas == null)
  297.             {
  298.             return;
  299.             }
  300.  
  301.         // First unhighlight all of the deactivated areas
  302.         for (int i = areas.length; --i >= 0; )
  303.             {
  304.             if (areas[i].active && !areas[i].entered)
  305.                 {
  306.                 areas[i].setState(g, false);
  307.                 }
  308.             }
  309.  
  310.         // Then highlight all of the activated areas
  311.         for (int i = areas.length; --i >= 0; )
  312.             {
  313.             if (areas[i].entered)
  314.                 {
  315.                 areas[i].setState(g, true);
  316.                 }
  317.             }
  318.         }
  319.  
  320.     /**
  321.      * Make sure that no ImageMapAreas are highlighted.
  322.      */
  323.     public void mouseExit()
  324.         {
  325.         boolean changed = false;
  326.  
  327.         for (int i = 0; i < areas.length; i++)
  328.             {
  329.             if (areas[i].active)
  330.                 {
  331.                 areas[i].entered = false;
  332.                 changed = true;
  333.                 }
  334.             }
  335.  
  336.         if (changed)
  337.             {
  338.             repaint();
  339.             }
  340.         }
  341.  
  342.     /**
  343.      * Find the ImageMapAreas that the mouse is in.
  344.      */
  345.     public boolean mouseMove(java.awt.Event evt, int x, int y)
  346.         {
  347.         boolean changed = false;
  348.         boolean propagate = true;
  349.  
  350.         for (int i = 0; i < areas.length; i++)
  351.             {
  352.             if (areas[i].inside(x, y))
  353.                 {
  354.                 areas[i].entered = propagate;
  355.                 if (areas[i].terminal)
  356.                     {
  357.                     propagate = false;
  358.                     }
  359.                 }
  360.             else
  361.                 {
  362.                 areas[i].entered = false;
  363.                 }
  364.  
  365.             if (areas[i].active != areas[i].entered)
  366.                 {
  367.                 changed = true;
  368.                 }
  369.             }//for
  370.  
  371.         if (changed)
  372.             {
  373.             repaint();
  374.             }
  375.  
  376.         return true;
  377.         }//mouseMove
  378.  
  379.  
  380.  
  381.     /**
  382.      * Inform all active ImageMapAreas of a mouse press.
  383.      *
  384.      * @param evt An Event object
  385.      * @param x X coordinate of mouse button press
  386.      * @param y Y coordinate of mouse button press
  387.      */
  388.     public boolean mouseDown(java.awt.Event evt, int x, int y)
  389.         {
  390.         pressX = x;
  391.         pressY = y;
  392.         Event   newEvent;
  393.  
  394.         for (int i = 0; i < areas.length; i++)
  395.             {
  396.             if (areas[i].inside(x, y))
  397.                 {
  398.                 areas[i].press(x, y);
  399.                 if (areas[i].terminal)
  400.                     {
  401.                     newEvent = new Event( this, Event.ACTION_EVENT, ((NameArea)areas[i]).name );
  402.                     postEvent( newEvent );
  403.  
  404.                     break;
  405.                     }
  406.                 }
  407.             }
  408.  
  409.         return true;
  410.         }
  411.  
  412.     /**
  413.      * Inform all active ImageMapAreas of a mouse release.
  414.      * Only those areas that were inside the original mouseDown()
  415.      * are informed of the mouseUp.
  416.      *
  417.      * @param evt An Event object
  418.      * @param x X coordinate of mouse release
  419.      * @param y Y coordinate of mouse release
  420.      */
  421.     public boolean mouseUp(java.awt.Event evt, int x, int y)
  422.         {
  423.         for (int i = 0; i < areas.length; i++)
  424.             {
  425.             if (areas[i].inside(pressX, pressY))
  426.                 {
  427.                 areas[i].lift(x, y);
  428.                 if (areas[i].terminal)
  429.                     {
  430.                     break;
  431.                     }
  432.                 }
  433.             }
  434.         mouseExit();
  435.         return true;
  436.         }
  437.  
  438.     /**
  439.      * Inform all active ImageMapAreas of a mouse drag.
  440.      * Only those areas that were inside the original mouseDown()
  441.      * are informed of the mouseUp.
  442.      *
  443.      * @param evt An Event object
  444.      * @param x X coordinate of mouse drag
  445.      * @param y Y coordinate of mouse drag
  446.      */
  447.     public boolean mouseDrag(java.awt.Event evt, int x, int y)
  448.         {
  449.         mouseMove(evt, x, y);
  450.         for (int i = 0; i < areas.length; i++)
  451.             {
  452.             if (areas[i].inside(pressX, pressY))
  453.                 {
  454.                 areas[i].drag(x, y);
  455.                 if (areas[i].terminal)
  456.                     {
  457.                     break;
  458.                     }
  459.                 }
  460.             }
  461.  
  462.         return true;
  463.         }
  464. }//class WeatherImageMap
  465.  
  466. /**
  467.  * The base ImageMapArea class.
  468.  * This class performs the basic functions that most sub-classed ImageMapArea
  469.  * classes will need and delegates specific actions to the subclasses.
  470.  *
  471.  * @author      Jim Graham, modified by James Lee
  472.  * @version     0.00 23-Jan-96
  473.  */
  474. class ImageMapArea implements ImageObserver
  475.     {
  476.     // --- Instance variables
  477.  
  478.     /** The applet parent that contains this ImageMapArea. */
  479.     WeatherImageMap parent;
  480.  
  481.     /** The X location of the area (if rectangular). */
  482.     int X;
  483.  
  484.     /** The Y location of the area (if rectangular). */
  485.     int Y;
  486.  
  487.     /** The size().width of the area (if rectangular). */
  488.     int W;
  489.  
  490.     /** The size().height of the area (if rectangular). */
  491.     int H;
  492.  
  493.     /**
  494.      * This flag indicates whether the user was in this area during the
  495.      * last scan of mouse locations.
  496.      */
  497.     boolean entered = false;
  498.  
  499.     /** This flag indicates whether the area is currently highlighted. */
  500.     boolean active = false;
  501.  
  502.     /**
  503.      * This flag indicates whether the area is terminal.  Terminal areas
  504.      * prevent any areas which are under them from being activated when
  505.      * the mouse is inside them.  Some areas may wish to change this to
  506.      * false so that they can augment other areas that they are on top of.
  507.      */
  508.     boolean terminal = true;
  509.  
  510.     /**
  511.      * This is the default highlight image if no special effects are
  512.      * needed to draw the highlighted image.  It is created by the
  513.      * default "makeImages()" method.
  514.      */
  515.     Image hlImage;
  516.  
  517.     // --- Public operations
  518.     /**
  519.      * Initialize this ImageMapArea as called from the Canvas.
  520.      * If the subclass does not override this initializer, then it
  521.      * will perform the basic functions of setting the parent Canvas
  522.      * and parsing out 4 numbers from the argument string which specify
  523.      * a rectangular region for the ImageMapArea to act on.
  524.      * The remainder of the argument string is passed to the handleArg()
  525.      * method for more specific handling by the subclass.
  526.      */
  527.     public void init(WeatherImageMap parent, String args)
  528.         {
  529.         this.parent = parent;
  530.  
  531.         StringTokenizer st = new StringTokenizer(args, ", ");
  532.         X = Integer.parseInt(st.nextToken());
  533.         Y = Integer.parseInt(st.nextToken());
  534.         W = Integer.parseInt(st.nextToken());
  535.         H = Integer.parseInt(st.nextToken());
  536.  
  537.         if (st.hasMoreTokens())
  538.             {
  539.             // hasMoreTokens() Skips the trailing comma
  540.             handleArg(st.nextToken(""));
  541.             }
  542.         else
  543.             {
  544.             handleArg(null);
  545.             }
  546.  
  547.         makeImages();
  548.         }
  549.  
  550.     /**
  551.      * This method handles the remainder of the argument string after
  552.      * the standard initializer has parsed off the 4 rectangular
  553.      * parameters.  If the subclass does not override this method,
  554.      * the remainder will be ignored.
  555.      *
  556.      * @param s The remainer of region argument string
  557.      */
  558.     public void handleArg(String s)
  559.         {
  560.         }
  561.  
  562.     /**
  563.      * This method sets the image to be used to render the ImageMapArea
  564.      * when it is highlighted.
  565.      *
  566.      * @param img A rendering image
  567.      */
  568.     public void setHighlight(Image img)
  569.         {
  570.         hlImage = img;
  571.         }
  572.  
  573.     /**
  574.      * This method handles the construction of the various images
  575.      * used to highlight this particular ImageMapArea when the user
  576.      * interacts with it.
  577.      */
  578.     public void makeImages()
  579.         {
  580.         setHighlight(parent.getHighlight(X, Y, W, H));
  581.         }
  582.  
  583.     /**
  584.      * This method tests to see if a point is inside this ImageMapArea.
  585.      * The standard method assumes a rectangular area as parsed by
  586.      * the standard initializer.  If a more complex area is required
  587.      * then this method will have to be overridden by the subclass.
  588.      */
  589.     public boolean inside(int x, int y)
  590.         {
  591.         return (x >= X && x < (X + W) && y >= Y && y < (Y + H));
  592.         }
  593.  
  594.     /**
  595.      * This utility method draws a rectangular subset of a highlight
  596.      * image.
  597.      */
  598.     public void drawImage(Graphics g, Image img, int imgx, int imgy, int x, int y, int w, int h)
  599.         {
  600.         Graphics ng = g.create();
  601.         ng.clipRect(x, y, w, h);
  602.         ng.drawImage(img, imgx, imgy, this);
  603.         ng.finalize();
  604.         }
  605.  
  606.     /**
  607.      * This method handles the updates from drawing the images.
  608.      */
  609.     public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
  610.         {
  611.         if (img == hlImage)
  612.             {
  613.             return parent.imageUpdate(img, infoflags, x + X, y + Y, width, height);
  614.             }
  615.         else
  616.             {
  617.             return false;
  618.             }
  619.         }
  620.  
  621.     /**
  622.      * This utility method shows a string in the status bar.
  623.      */
  624.     public void showStatus(String msg)
  625.         {
  626.         //parent.getAppletContext().showStatus(msg);
  627.         PjTabNotebook.getStatusBar().setMessage( msg );
  628.         }
  629.  
  630.     /**
  631.      * This method highlights the specified area when the user enters
  632.      * it with his mouse.  The standard highlight method is to replace
  633.      * the indicated rectangular area of the image with the primary
  634.      * highlighted image.
  635.      */
  636.     public void highlight(Graphics g, boolean on)
  637.         {
  638.         if (on)
  639.             {
  640.             g.drawImage(hlImage, X, Y, this);
  641.             }
  642.         else
  643.             {
  644.             drawImage(g, parent.baseImage, 0, 0, X, Y, W, H);
  645.             }
  646.         }
  647.  
  648.     /**
  649.      * This method changes the active state of the ImageMapArea, which
  650.      * indicates whether the user is currently "inside" this area.
  651.      * It turns around and calls the highlight method which is likely
  652.      * to have been overridden by subclasses seeking a custom highlight.
  653.      */
  654.     public void setState(Graphics g, boolean on)
  655.         {
  656.         highlight(g, on);
  657.         active = on;
  658.         }
  659.  
  660.     /**
  661.      * The press method is called when the user presses the mouse
  662.      * button inside the ImageMapArea.  The location is supplied, but
  663.      * the standard implementation is to call the overloaded method
  664.      * with no arguments.
  665.      */
  666.     public void press(int x, int y)
  667.         {
  668.         press();
  669.         }
  670.  
  671.     /**
  672.      * The overloaded press method is called when the user presses the
  673.      * mouse button inside the ImageMapArea.  This method can be overridden
  674.      * if the ImageMapArea does not need to know the location of the press.
  675.      */
  676.     public void press()
  677.         {
  678.         }
  679.  
  680.     /**
  681.      * The lift method is called when the user releases the mouse button.
  682.      * The location is supplied, but the standard implementation is to
  683.      * call the overloaded method with no arguments.  Only those ImageMapAreas
  684.      * that were informed of a press will be informed of the corresponding
  685.      * release.
  686.      */
  687.     public void lift(int x, int y)
  688.         {
  689.         lift();
  690.         }
  691.  
  692.     /**
  693.      * The overloaded lift method is called when the user releases the
  694.      * mouse button.  This method can be overridden if the ImageMapArea
  695.      * does not need to know the location of the release.
  696.      */
  697.     public void lift()
  698.         {
  699.         }
  700.  
  701.     /**
  702.      * The drag method is called when the user moves the mouse while
  703.      * the button is pressed.  Only those ImageMapAreas that were informed
  704.      * of a press will be informed of the corresponding mouse movements.
  705.      */
  706.     public void drag(int x, int y)
  707.         {
  708.         }
  709. }
  710.  
  711. /**
  712.  * A message feedback ImageMapArea class.
  713.  * This class extends the basic ImageMapArea Class to show the a given
  714.  * message in the status message area when the user enters this area.
  715.  *
  716.  * @author      Jim Graham, modified by James Lee
  717.  * @version 0.00 23-Jan-96
  718.  */
  719. class NameArea extends ImageMapArea
  720.     {
  721.  
  722.     // --- Instance variables
  723.  
  724.     /** The string to be shown in the status message area. */
  725.     String name;
  726.  
  727.     /**
  728.      * The argument is the string to be displayed in the status message
  729.      * area.  This method also sets this type of area to be non-terminal.
  730.      */
  731.     public void handleArg(String arg)
  732.         {
  733.         name = arg;
  734.         }
  735.  
  736.     /**
  737.      * The highlight method displays the message in addition to the usual
  738.      * graphical highlight feedback.
  739.      */
  740.     public void highlight(Graphics g, boolean on)
  741.         {
  742.         super.highlight(g, on);
  743.         showStatus(on ? name + ": Click the region to view weather" : null);
  744.         }
  745.  
  746.     /**
  747.      * The overloaded press method is called when the user presses the
  748.      * mouse button inside the ImageMapArea.  This method can be overridden
  749.      * if the ImageMapArea does not need to know the location of the press.
  750.      */
  751.     public void press()
  752.         {
  753.         }
  754. }
  755.  
  756. /**
  757.  * This class extends the basic RGBImageFilter Class to brighten or darken
  758.  * the rectangular area.
  759.  *
  760.  * @author      James Lee
  761.  * @version     0.00 23-Jan-96
  762.  */
  763. class HighlightFilter extends RGBImageFilter
  764.     {
  765.  
  766.     // --- Instance variables
  767.     boolean brighter;
  768.     int     percent;
  769.  
  770.     public HighlightFilter(boolean b, int p)
  771.         {
  772.         brighter = b;
  773.         percent = p;
  774.         canFilterIndexColorModel = true;
  775.         }
  776.  
  777.     /**
  778.      * Implements the abstract method in RGBImageFilter.
  779.      * Converts a single input pixel to a single output pixel brightened or darkened.
  780.      */
  781.     public int filterRGB(int x, int y, int rgb)
  782.         {
  783.         int r = (rgb >> 16) & 0xff;
  784.         int g = (rgb >> 8) & 0xff;
  785.         int b = (rgb >> 0) & 0xff;
  786.  
  787.         if (brighter)
  788.             {
  789.             r = (255 - ((255 - r) * (100 - percent) / 100));
  790.             g = (255 - ((255 - g) * (100 - percent) / 100));
  791.             b = (255 - ((255 - b) * (100 - percent) / 100));
  792.             }
  793.         else
  794.             {
  795.             r = (r * (100 - percent) / 100);
  796.             g = (g * (100 - percent) / 100);
  797.             b = (b * (100 - percent) / 100);
  798.             }
  799.  
  800.         if (r < 0)
  801.             r = 0;
  802.  
  803.         if (r > 255)
  804.             r = 255;
  805.  
  806.         if (g < 0)
  807.             g = 0;
  808.  
  809.         if (g > 255)
  810.             g = 255;
  811.  
  812.         if (b < 0)
  813.             b = 0;
  814.  
  815.         if (b > 255)
  816.             b = 255;
  817.  
  818.         return (rgb & 0xff000000) | (r << 16) | (g << 8) | (b << 0);
  819.         }
  820. }
  821.  
  822.  
  823.