//
// HersheyFont.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
/*****************************************************************************/
//
// Copyright (c) James P. Buzbee 1996
// House Blend Software
//
// jbuzbee@nyx.net
// Version 1.1 Dec 11 1996
// Version 1.2 Sep 18 1997
// Version 1.3 Feb 28 1998
// Version 1.4 Aug 13 2000 : J++ bug workaround by Paul Emory Sullivan
// Version 1.x Sep 20 2001 - adapted to visad/PlotText usage
//
// Permission to use, copy, modify, and distribute this software
// for any use is hereby granted provided
// this notice is kept intact within the source file
// This is freeware, use it as desired !
//
// Very loosly based on code with authors listed as :
// Alan Richardson, Pete Holzmann, James Hurt
/*****************************************************************************/
package visad.util;
import java.io. *;
import java.net.URL;
/**
HersheyFont supports the Hershey Fonts for VisAD.
Adapted from the original code by Buzbee (see source)
*/
public class HersheyFont {
private final static int MAX_CHARACTERS = 256;
private final static int MAX_POINTS = 300;
protected final static int X = 0;
protected final static int Y = 1;
private String copyright = "Copyright (c) James P. Buzbee Mar 30, 1996";
protected String name;
protected char characterVectors[][][] = new char[MAX_CHARACTERS][2][MAX_POINTS];
protected int numberOfPoints[] = new int[MAX_CHARACTERS];
protected int characterMinX[];
protected int characterMaxX[];
protected int characterSetMinY;
protected int characterSetMaxY;
protected int characterSetMinX;
protected int characterSetMaxX;
protected int charactersInSet;
protected boolean fixedWidth = false;
/** Default constructor. Use the font 'futural'
*
* Supplied fonts are:
* futural, timesr, timesrb, cursive, futuram, rowmans,
* rowmant, meteorology
*
* All other fonts supplied by Bizbee are available at the
* VisAD web site.
*
* More info at: http://batbox.org/font.html
*
*/
public HersheyFont() {
this("futural");
}
/**
* Get a Hershey Font by name. This constructor form will
* add a .jhf extension to the name given and read it as a
* Resourse from the visad/util directory.
*
* Supplied fonts are:
* futural, timesr, timesrb, cursive, futuram, rowmans,
* rowmant, meteorology
*
* All other fonts supplied by Bizbee are available at the
* VisAD web site.
*
* @param fontName name of the Hershey font to use
*
*/
public HersheyFont (String fontName)
{
name = fontName;
try
{
// open the font file
//InputStream fontStream = new FileInputStream (fontName);
String fn = fontName+".jhf";
InputStream fontStream = HersheyFont.class.getResourceAsStream(fn);
// load the font file
LoadHersheyFont (fontName, fontStream);
// close the font file
fontStream.close ();
}
catch (Exception e)
{
System.out.println ("Error processing HersheyFont named "+fontName+": "+e);
}
return;
}
/**
* Get a Hershey Font by URL and name. You must give the
* complete filename (e.g., futural.jhf) as well as the URL
*
* @param base is the base URL of the file
* @param fontName the name of the fontfile (include .jhf extension)
*
*/
public HersheyFont (URL base, String fontName)
{
name = fontName;
try
{
// open the font file
InputStream fontStream = new URL (base, fontName).openStream ();
// load the font file
LoadHersheyFont (fontName, fontStream);
// close the font file
fontStream.close ();
}
catch (Exception e)
{
System.out.println ("Error processing font "+fontName+": "+e);
}
return;
}
/**
* Get a Hershey Font by URL. You must give the
* complete filename (e.g., futural.jhf) as part of the URL
*
* @param base is the URL of the file (e.g.,
* http://www.ssec.wisc.edu/visad/futural.jhf)
*
*/
public HersheyFont (URL base)
{
name = base.toString ();
try
{
// open the font file
InputStream fontStream = base.openStream ();
// load the font file
LoadHersheyFont (name, fontStream);
// close the font file
fontStream.close ();
}
catch (Exception e)
{
System.out.println ("Error processing font "+name+": "+e);
}
return;
}
/**
* See if o is equal to this
* @return true if they have the same name
*/
public boolean equals(Object o) {
if (!(o instanceof HersheyFont)) {
return false;
}
HersheyFont that = (HersheyFont) o;
return this.name.equals(that.name);
}
/**
* Get the hashcode
* @return the hashcode
*/
public int hasCode() {
return name.hashCode();
}
/** get the maximum number of points (segments) allowed
*
* @return value of max number of segments allowed.
*
*/
public int getMaxPoints() {
return MAX_POINTS;
}
/** get the minimum X coordinate values for all characters
*
* @return array of minimum X coordinates
*
*/
public int[] getCharacterMinX () { return characterMinX; }
/** get the maximum X coordinate values for all characters
*
* @return array of maximum X coordinates
*
*/
public int[] getCharacterMaxX () { return characterMaxX; }
/** get the minimum Y coordiante value for all characters
*
* @return minimum Y coordinate value for all characters in thie font
*
*/
public int getCharacterSetMinY() { return characterSetMinY; }
/** get the maximum Y coordiante value for all characters
*
* @return maximum Y coordinate value for all characters in thie font
*
*/
public int getCharacterSetMaxY() { return characterSetMaxY; }
/** get the minimum X coordiante value for all characters
*
* @return minimum X coordinate value for all characters in thie font
*
*/
public int getCharacterSetMinX() { return characterSetMinX; }
/** get the maximum X coordiante value for all characters
*
* @return maximum X coordinate value for all characters in thie font
*
*/
public int getCharacterSetMaxX() { return characterSetMaxX; }
/** get the minimum Y coordiante value for all characters
*
* @return minimum Y coordinate value for all characters in thie font
*
*/
public int getCharactersInSet() { return charactersInSet; }
/** get the number of points for the i-th character
*
* @param i the index of the character
*
* @return the number of data points for this character
*
*/
public int getNumberOfPoints(int i) {
if (i < characterVectors.length) {
return (numberOfPoints[i]);
} else {
return 0;
}
}
/** get the vector of X and Y coordinates for the i-th character
*
* @param i the index of the character
* @return array[2][number_points] for this character
*
*/
public char[][] getCharacterVector(int i) {
if (i < characterVectors.length) {
return (characterVectors[i]);
} else {
return null;
}
}
/** set whether this font is 'fixed width' or not (not =
* proportional spacing)
*
* Right now, only the 'wmo' font is defaulted to fixed.
*/
public void setFixedWidth(boolean fw) {
fixedWidth = fw;
return;
}
/** indicate whether this is a fixed-width font
*
* @return true if name indicates fixed with (wmo...)
*
*/
public boolean getFixedWidth() {
fixedWidth = false;
if (name.toLowerCase().startsWith("wmo")) fixedWidth = true;
// others?
return fixedWidth;
}
/** indicate whether this is a cursive font
*
* @return true if name contains "cursive"
*
*/
public boolean getIsCursive() {
return ( (name.toLowerCase().indexOf("cursive") != -1) );
}
private int getInt (InputStream file, int n) throws IOException
{
if (file == null) return (-1);
char[] buf;
int c;
int j = 0;
buf = new char[n];
// for the specified number of characters
for (int i = 0; i < n; i++)
{
c = file.read ();
// get character and discard spare newlines
while ((c == '\n') || (c == '\r'))
{
c = file.read ();
}
// if we hit end of file
if (c == -1)
{
// return an error
return (c);
}
// if this is not a blank
if ((char) c != ' ')
{
// save the character
buf[j++] = (char) c;
}
}
// return the decimal equivilent of the string
return (Integer.parseInt (String.copyValueOf (buf, 0, j)));
}
/******************************************************************************/
/***********************************************************/
private int fontAdjustment (String fontname)
{
int xadjust = 0;
// if we do not have a script type font
if (fontname.indexOf ("scri") < 0 )
{
// if we have a gothic font
if (fontname.indexOf ("goth") >= 0)
{
xadjust = 2;
}
else
{
xadjust = 3;
}
}
return (xadjust);
}
/******************************************************************************/
private void LoadHersheyFont (String fontname, InputStream fontStream)
{
if (fontStream == null) return;
int character, n;
int c;
int xadjust = fontAdjustment (fontname);
try
{
// loop through the characters in the file ...
character = 0;
// while we have not processed all of the characters
while (true)
{
// if we cannot read the next field
if (getInt (fontStream, 5) < 1)
{
// we are done, set the font specification for num chars
charactersInSet = character;
// break the read loop
break;
}
else
{
// get the number of vertices in this character
n = getInt (fontStream, 3);
// save it
numberOfPoints[character] = n;
// read in the vertice coordinates ...
for (int i = 0; i < n; i++)
{
// if we are at the end of the line
if ((i == 32) || (i == 68) || (i == 104) || (i == 140))
{
// skip the carriage return
fontStream.read ();
}
// get the next character
c = fontStream.read ();
// if this is a return ( we have a DOS style file )
if (c == '\n')
{
// throw it away and get another
c = fontStream.read ();
}
// get the x coordinate
characterVectors[character][X][i] = (char) c;
// read the y coordinate
characterVectors[character][Y][i] = (char) fontStream.read ();
}
// skip the carriage return
fontStream.read ();
// increment the character counter
character++;
}
}
// determine the size of each character ...
characterMinX = new int[charactersInSet];
characterMaxX = new int[charactersInSet];
// initialize ...
characterSetMinY = 1000;
characterSetMaxY = -1000;
characterSetMinX = 1000;
characterSetMaxX = -1000;
// loop through each character ( except the space character )
for (int j = 1; j < charactersInSet; j++)
{
// calculate the size
calculateCharacterSize (j, xadjust);
}
// handle the space character - if the 'a' character is defined
if (((int) 'a' - (int) ' ') <= charactersInSet)
{
// make the space character the same size as the 'a'
characterMinX[0] = characterMinX[(int) 'a' - (int) ' '];
characterMaxX[0] = characterMaxX[(int) 'a' - (int) ' '];
}
else
{
// make the space char the same size as the last char
characterMinX[0] = characterMinX[charactersInSet - 1];
characterMaxX[0] = characterMaxX[charactersInSet - 1];
}
}
catch (IOException e)
{
System.out.println (e);
}
return;
}
/*************************************************************************************/
protected void calculateCharacterSize (int j, int xadj)
{
int cx,cy;
characterMinX[j] = 1000;
characterMaxX[j] = -1000;
// for all the vertices in the character
for (int i = 1; i < numberOfPoints[j]; i++)
{
cx = (int) characterVectors[j][X][i];
cy = (int) characterVectors[j][Y][i];
// if this is not a "skip"
if (cx != ' ')
{
// if this is less than our current minimum
if (cx < characterMinX[j])
{
// save it
characterMinX[j] = cx;
}
if (cx < characterSetMinX) characterSetMinX = cx;
// if this is greater than our current maximum
if ( cx > characterMaxX[j])
{
// save it
characterMaxX[j] = cx;
}
if (cx > characterSetMaxX) characterSetMaxX = cx;
// if this is less than our current minimum
if (cy < characterSetMinY)
{
// save it
characterSetMinY = cy;
}
// if this is greater than our current maximum
if (cy > characterSetMaxY)
{
// save it
characterSetMaxY = cy;
}
}
}
characterMinX[j] -= xadj;
characterMaxX[j] += xadj;
}
/******************************************************************************/
public String toString()
{
return( "HersheyFont: "+name );
}
}