package graph; import java.awt.*; import java.util.*; import java.lang.*; import java.awt.image.*; /* ************************************************************************** ** ** Class TextLine ** ************************************************************************** ** Modified from Leigh Brookshaw's graph classes by Michael Cross ** Copyright (C) 1996 Leigh Brookshaw ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ************************************************************************** ** ** This class is designed to bundle together all the information required ** to draw short Strings ** *************************************************************************/ /** * This class is designed to bundle together all the information required * to draw short Strings with subscripts and superscripts * * @version $Revision: 1.10 $, $Date: 1996/09/05 04:53:27 $ * @author Leigh Brookshaw, revised MCC */ public class TextLine extends Object { /* ************* ** ** Constants ** ************/ /** * Center the Text over the point */ public final static int CENTER = 0; /** * Position the Text to the Left of the point */ public final static int LEFT = 1; /** * Position the Text to the Right of the point */ public final static int RIGHT = 2; /** * Format to use when parsing a double */ public final static int SCIENTIFIC = 1; /** * Format to use when parsing a double */ public final static int ALGEBRAIC = 2; /* ** Minimum Point size allowed for script characters */ final static int MINIMUM_SIZE = 6; /* ********************** ** ** Protected Variables ** *********************/ /** * Decrease in size of successive script levels */ protected double script_fraction = 0.8; /** * Superscript offset */ protected double sup_offset = 0.6; /** * Subscript offset */ protected double sub_offset = 0.7; /** * Font to use for text */ protected Font font = null; /** * Text color */ protected Color color = null; /** * Background Color */ protected Color background = null; /** * The text to display */ protected String text = null; /** * The logical name of the font to use */ protected String fontname = "TimesRoman"; /** * The font size */ protected int fontsize = 0; /** * The font style */ protected int fontstyle = Font.PLAIN; /** * Text justification. Either CENTER, LEFT or RIGHT */ protected int justification = LEFT; /** * The width of the text using the current Font */ protected int width = 0; /** * The ascent using the current font */ protected int ascent = 0; /** * The maximum ascent using the current font */ protected int maxAscent = 0; /** * The descent using the current font */ protected int descent = 0; /** * The maximum descent using the current font */ protected int maxDescent = 0; /** * The height using the current font ie ascent+descent+leading */ protected int height = 0; /** * The leading using the current font */ protected int leading = 0; /** * Has the string been parsed! This only needs to be done once * unless the font is altered. */ protected boolean parse = true; /** * Local graphics context. */ protected Graphics lg = null; /** * The parsed string. Each element in the vector represents * a change of context in the string ie font change and offset. */ protected Vector list = new Vector(8,4); /* ********************** ** ** Constructors ** *********************/ /** * Instantiate the class */ public TextLine() { } /** * Instantiate the class. * @param s String to parse. */ public TextLine(String s) { this.text = s; } /** * Instantiate the class * @param s String to parse. * @param f Font to use. */ public TextLine(String s, Font f) { this(s); font = f; if(font == null) return; fontname = f.getName(); fontstyle = f.getStyle(); fontsize = f.getSize(); } /** * Instantiate the class * @param s String to parse. * @param f Font to use. * @param c Color to use * @param j Justification */ public TextLine(String s, Font f, Color c, int j) { this(s,f); color = c; justification = j; } /** * Instantiate the class * @param s String to parse. * @param c Color to use */ public TextLine(String s, Color c) { this(s); color = c; } /** * Instantiate the class * @param f Font to use. * @param c Color to use * @param j Justification */ public TextLine(Font f, Color c, int j) { font = f; color = c; justification = j; if(font == null) return; fontname = f.getName(); fontstyle = f.getStyle(); fontsize = f.getSize(); } /* ***************** ** ** Public Methods ** *****************/ /** * Create a New Textline object copying the state of the existing * object into the new one. The state of the class is the color, * font, and justification ie everything but the string. */ public TextLine copyState() { return new TextLine(font,color,justification); } /** * Copy the state of the parsed Textline into the existing * object. * @param t The TextLine to get the state information from. */ public void copyState(TextLine t) { if(t==null) return; font = t.getFont(); color = t.getColor(); justification = t.getJustification(); if(font == null) return; fontname = font.getName(); fontstyle = font.getStyle(); fontsize = font.getSize(); parse = true; } /** * Set the Font to use with the class * @param f Font */ public void setFont( Font f ) { font = f; fontname = f.getName(); fontstyle = f.getStyle(); fontsize = f.getSize(); parse = true; } /** * Set the String to use with the class * @param s String */ public void setText( String s ) { text = s; parse = true; } /** * Set the Color to use with the class * @param c Color */ public void setColor( Color c ) { color = c; } /** * Set the Background Color to use with the class * @param c Color */ public void setBackground( Color c ) { background = c; } /** * Set the Justification to use with the class * @param t Justification */ public void setJustification( int i ) { switch (i) { case CENTER: justification = CENTER; break; case LEFT: default: justification = LEFT; break; case RIGHT: justification = RIGHT; break; } } /** * @return the font the class is using */ public Font getFont() { return font; } /** * @return the String the class is using. */ public String getText() { return text; } /** * @return the Color the class is using. */ public Color getColor() { return color; } /** * @return the Background Color the class is using. */ public Color getBackground() { return background; } /** * @return the Justification the class is using. */ public int getJustification() { return justification; } /** * @param g Graphics context. * @return the Fontmetrics the class is using. */ public FontMetrics getFM(Graphics g) { if(g==null) return null; if(font==null) return g.getFontMetrics(); else return g.getFontMetrics(font); } /** * @param g Graphics context. * @param ch The character. * @return the width of the character. */ public int charWidth(Graphics g, char ch) { FontMetrics fm; if(g==null) return 0; if(font==null) fm = g.getFontMetrics(); else fm = g.getFontMetrics(font); return fm.charWidth(ch); } /** * @param g Graphics context. * @return the width of the parsed text. */ public int getWidth(Graphics g) { parseText(g); return width; } /** * @param g Graphics context. * @return the height of the parsed text. */ public int getHeight(Graphics g) { parseText(g); return height; } /** * @param g Graphics context. * @return the ascent of the parsed text. */ public int getAscent(Graphics g) { if(g == null) return 0; parseText(g); return ascent; } /** * @param g Graphics context. * @return the maximum ascent of the parsed text. */ public int getMaxAscent(Graphics g) { if(g == null) return 0; parseText(g); return maxAscent; } /** * @param g Graphics context. * @return the descent of the parsed text. */ public int getDescent(Graphics g) { if(g == null) return 0; parseText(g); return descent; } /** * @param g Graphics context. * @return the maximum descent of the parsed text. */ public int getMaxDescent(Graphics g) { if(g == null) return 0; parseText(g); return maxDescent; } /** * @param g Graphics context. * @return the leading of the parsed text. */ public int getLeading(Graphics g) { if(g == null) return 0; parseText(g); return leading; } /** * parse the text. When the text is parsed the width, height, leading * are all calculated. The text will only be truly parsed if * the graphics context has changed or the text has changed or * the font has changed. Otherwise nothing is done when this * method is called. * @param g Graphics context. */ public void parseText(Graphics g) { FontMetrics fm; TextState current = new TextState(); char ch; Stack state = new Stack(); int w = 0; if(lg != g) parse = true; lg = g; if(!parse) return; parse = false; width = 0; leading = 0; ascent = 0; descent = 0; height = 0; maxAscent = 0; maxDescent = 0; if( text == null || g == null) return; list.removeAllElements(); if(font == null) current.f = g.getFont(); else current.f = font; state.push(current); list.addElement(current); fm = g.getFontMetrics(current.f); for(int i=0; itrue if the parse was successful */ public boolean parseDouble(double d) { return parseDouble(d, 7, 6, ALGEBRAIC); } /** * Parse a double value. Number of significant figures is 1 greater than * the precision. * @param d double to parse * @param p precision of the number * return true if the parse was successful */ public boolean parseDouble(double d, int p) { return parseDouble(d, p+1, p, ALGEBRAIC); } /** * Parse a double value * @param d double to parse * @param n number of significant figures * @param p precision of the number * @param f format of the number scientific, algebraic etc. * return true if the parse was successful */ public boolean parseDouble(double d, int n, int p, int f) { double x = d; int left = n - p; double right = 0; int power; int exponent; int i; StringBuffer s = new StringBuffer(n+4); if(left < 0 ) { System.out.println( "TextLine.parseDouble: Precision > significant figures!"); return false; } if(d < 0.0) { x = -d; s.append("-"); } //System.out.println("parseDouble: value = "+x); if( d == 0.0 ) exponent = 0; else exponent = (int)(Math.floor(log10(x))); //Change to internal log //MCC 6/12/97 //System.out.println("parseDouble: exponent = "+exponent); power = exponent - (left - 1); //System.out.println("parseDouble: power = "+power); if( power < 0 ) { for(i=power; i<0; i++) { x *= 10.0; } } else { for(i=0; i