/************************************************************************** * Copyright (c) 2001, 2002, 2003 by Acunia N.V. All rights reserved. * * * * This software is copyrighted by and is the sole property of Acunia N.V. * * and its licensors, if any. All rights, title, ownership, or other * * interests in the software remain the property of Acunia N.V. and its * * licensors, if any. * * * * This software may only be used in accordance with the corresponding * * license agreement. Any unauthorized use, duplication, transmission, * * distribution or disclosure of this software is expressly forbidden. * * * * This Copyright notice may not be removed or modified without prior * * written consent of Acunia N.V. * * * * Acunia N.V. reserves the right to modify this software without notice. * * * * Acunia N.V. * * Philips-site 5, box 3 info@acunia.com * * 3001 Leuven http://www.acunia.com * * Belgium - EUROPE * **************************************************************************/ package com.acunia.wonka.rudolph.peers; import java.awt.Color; import java.awt.SystemColor; import java.awt.FontMetrics; /* ** Basic functions for all Rudolph-xxxx-Peer classes: ** => calculates an array of peer drawing colors out ofa given foreground and background ** => provides a number of text dimension functions for the drawing of texts in a peer painter ** @note: Just like the other Rudolph-xxxx-Peer classes, the final user may change the algorithms and implementation ** to his own likes and the definite possibilities of his platform */ /* ** SCROLLBAR PAINT COMMANDS FOR ALL SCROLLBAR USERS */ public class RudolphPeer { /* ** Statics */ public final static int FIELD_NONESELECTED = -1; public final static int COLORFILTER = 2; public final static int COLORWIDTH = 5; public final static int REVERTTOBLACK = 0x60; // a color who's r+g+b is less then 96 is considered black public final static int REVERTTOWHITE = 0xF0; // a color who's r+g+b is less then 240 is considered white /* ** Calculate the Rudolph peer colors */ public static Color[] getBarColors() { Color[] peercolors = new Color[COLORWIDTH]; //5 colors: front,back, white frame, black frame , font(crayon) color // color0 = <background color> peercolors[0] = SystemColor.control; //original front // color1 = <slightly darker> (selections etc..) peercolors[1] = SystemColor.controlShadow; // color2 = <light frame> peercolors[2] = SystemColor.controlHighlight; // color3 = <deep dark frame> if(peercolors[1].equals(SystemColor.controlDkShadow) ) { // color1: <slightly darker> MUST be different from color3 //=> if the originals are equal, make color3 darker peercolors[3] = getDarker(SystemColor.controlDkShadow); } else { // Nothing to grumble: assign color 3 (<deep dark frame>) to be the system's <controlDkShadow> peercolors[3] = SystemColor.controlDkShadow; } // color4 = <foreground color> peercolors[4] = SystemColor.controlText; return peercolors; } public static Color[] getBarColors(Color panelcolor, Color fontcolor) { //security if(panelcolor==null) { panelcolor = SystemColor.scrollbar; } if(fontcolor == null) { fontcolor = SystemColor.windowText; } // assign colors Color[] peercolors = new Color[5]; // color0 = <background color> peercolors[0] = copyOf(panelcolor); // color1 = <slightly darker> (selections etc..) peercolors[1] = getMiddle(panelcolor,Color.gray); peercolors[2] = getBrighter(panelcolor); peercolors[3] = getMiddle(peercolors[1],Color.black); // color4 = <foreground color> peercolors[4] = copyOf(fontcolor); return peercolors; } /* public static Color[] getBarColors(Color panelcolor, Color fontcolor) { //security if(panelcolor==null) { panelcolor = SystemColor.scrollbar; } if(fontcolor == null) { fontcolor = SystemColor.windowText; } // assign colors Color[] peercolors = new Color[5]; // color0 = <background color> peercolors[0] = copyOf(panelcolor); // color1 = <slightly darker> (selections etc..) peercolors[1] = getDarker(panelcolor); //if(panelcolor.equals(Color.black) ) { if((panelcolor.getRed()+panelcolor.getGreen()+panelcolor.getBlue())<= REVERTTOBLACK) { //special case: the selection can't be darker then the original => make selection slightly lighter peercolors[2] = new Color(0xC0,0xC0,0xC0); //light frame peercolors[3] = getMiddle(panelcolor,Color.gray); } else { // color2 = <light frame> peercolors[2] = getBrighter(panelcolor); // color3 = <deep dark frame> peercolors[3] = getDarker(peercolors[1]); } // color4 = <foreground color> peercolors[4] = copyOf(fontcolor); return peercolors; } /* ** set given Rudolph peer colors into Color[5] format: */ public static Color[] getBarColors(Color panelcolor, Color background, Color whiteframe, Color blackframe, Color fontcolor) { Color[] peercolors = new Color[5]; //5 colors: front,back, white frame, black frame , font(crayon) color peercolors[0] = copyOf(panelcolor); //original front peercolors[1] = copyOf(background); // background peercolors[2] = copyOf(whiteframe); peercolors[3] = copyOf(blackframe); peercolors[4] = copyOf(fontcolor); return peercolors; } /* ** alternative algorithms for brighter and darker colors */ /* ** an alternate brighter/darker algorithm : replace each rgb brightness with brightness/filter coefficient */ public static Color getDarker(Color c) { int r=c.getRed()/COLORFILTER; int g=c.getGreen()/COLORFILTER; int b=c.getBlue()/COLORFILTER; if(r+g+b>REVERTTOBLACK) { return new Color(r,g,b); } else { return Color.black; } } /* ** an alternate brighter/darker algorithm : replace each rgb darkness with darkness/filter coefficient ** or for brightnes x=(Color getRed() for instance..) x becomes 0xff- (0xff-x)/filter coef ** or x becomes 0xff(1-1/COLORFILTER) +x/COLORFILTER ==0xff((COLORFILTER-1)/COLORFILTER) + x/COLORFILTER */ public static Color getBrighter(Color c) { int offset = 0xff*(COLORFILTER-1)/COLORFILTER; int r=offset+c.getRed()/COLORFILTER; int g=offset+c.getGreen()/COLORFILTER; int b=offset+c.getBlue()/COLORFILTER; if(r+g+b<REVERTTOWHITE) { return new Color(r,g,b); } else { return Color.white; } } /* ** a general medium function ** x becomes c1x+(c2x-c1x)/ filter coef or x becomes (c1x(COLORFILTER-1)+c2x)/COLORFILTER ** note that(without the adjustments) getDarker(c) equals getMiddle(color.black,c) and getBrighter(c) equals getMiddle(Color.white,c) */ public static Color getMiddle(Color c1, Color c2) { int base = COLORFILTER-1; int r=(base*c1.getRed()+c2.getRed())/COLORFILTER; int g=(base*c1.getGreen()+c2.getGreen())/COLORFILTER; int b=(base*c1.getBlue()+c2.getBlue())/COLORFILTER; return new Color(r,g,b); } /* ** Color clone algorithm: builds a NEW Color-instance equal to the old one */ public static Color copyOf(Color c) { return new Color(c.getRed(), c.getGreen(), c.getBlue()); } /* ** Stub methods for calculating a line of chars to a screen width and back ** Since there are fonts that have a fixed char width and fonts in which every char has his own width, the calculations ** can not be so straightforward as with the lines of text. Consequently we will split up the functions between ** algorithms with a fixed known width and a variable one. As for the variable width, the text itself has to be given ** along the two functions can be simply recognised through their arguments */ /* ** The character containing the caret in a given character array(string)starting at a given offset **. This is also the number of chars of that string before the caret ** In some ways, this is the inverse of FontMetrics.charswidth(char line, int lineoffset, int linelength); ** if FontMetrics fm.charsWidth(line, start, len) = w pixels then RudolphPeer.getChars(w,start,line,fm) = (start+len+1): ** the last character of the string starting at position <start> and having length <len> ** ** @note :If you know that the font you have is a fixed font, consider replacing last = RudolphPeer.getChars(w,start,line,fm) ** with the direct calculation last=start+(w-1)/fm ** ** @returns -2 string null or offset bigger then line.length ** -1 caret before string starts (caret<0) ** 0 <-> line.length()-1 : the number of the char containing the carret = the number of chars BEFORE the carret ** line.length(): the whole line before the carret */ public static int getChars(int width, int lineoffset, char[] line, FontMetrics fm) { if(line==null || lineoffset>=line.length) { return -2; } if(width<0) { return -1; } // count the chars and their width untill carret reached // add as many chars to the offset untill the chars total length does JUST NOT surpass the carret width int len=fm.charWidth(line[lineoffset] ); int lastchar = line.length-1; while(len<width && lineoffset<lastchar) { lineoffset++; len+=fm.charWidth(line[lineoffset]); } // if longer then complete line: return line length return (len<width)?line.length:lineoffset; } /* ** The character containing the caret in a given character array(string)starting at a given offset **. This is also the number of chars of that string before the caret ** A special case of the above, optimalised for fixed width fonts. fontMetrics fm is replaced by the characters fixed ** width fm.getMaxAdvance ** returns -2 string null or offset bigger then line.length ** -1 caret before string starts (caret<0) ** 0 <-> line.length()-1 : the number of the char containing the carret = the number of chars BEFORE the carret ** line.length(): the whole line before the carret */ public static int getChars(int width, int lineoffset, char[] line, int fontwidth) { if(line==null || lineoffset>=line.length) { return -2; } if(width<0) { return -1; } //else int len=lineoffset+width/fontwidth; return (len>line.length)?line.length:len ; } }