//
// 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 );
   }   
}

 

Ads help maintain this website.