001package com.hfg.graphics;
002
003import java.awt.Font;
004import java.awt.Rectangle;
005import java.awt.font.FontRenderContext;
006import java.awt.geom.Rectangle2D;
007import java.awt.geom.AffineTransform;
008
009import com.hfg.graphics.units.DisplayPPI;
010
011//------------------------------------------------------------------------------
012/**
013 * Text utility functions.
014 * <div>
015 *   @author J. Alex Taylor, hairyfatguy.com
016 * </div>
017 */
018//------------------------------------------------------------------------------
019// com.hfg XML/HTML Coding Library
020//
021// This library is free software; you can redistribute it and/or
022// modify it under the terms of the GNU Lesser General Public
023// License as published by the Free Software Foundation; either
024// version 2.1 of the License, or (at your option) any later version.
025//
026// This library is distributed in the hope that it will be useful,
027// but WITHOUT ANY WARRANTY; without even the implied warranty of
028// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
029// Lesser General Public License for more details.
030//
031// You should have received a copy of the GNU Lesser General Public
032// License along with this library; if not, write to the Free Software
033// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
034//
035// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
036// jataylor@hairyfatguy.com
037//------------------------------------------------------------------------------
038
039public class TextUtil
040{
041   private static FontRenderContext sFRC = new FontRenderContext(new AffineTransform(), true, true);
042
043   private static DisplayPPI sDefaultDisplayPPI = DisplayPPI._96;
044
045   //--------------------------------------------------------------------------
046   /**
047    Calculate the bounding rectangle for the specified string and font using the default of 96 ppi.
048    @param inString the text for which to calculate the bounding rectangle
049    @param inFont   the text for which to calculate the bounding rectangle
050    @return the bounding rectangle for the specified text and font
051    */
052   public static Rectangle getStringRect(String inString, Font inFont)
053   {
054      return getStringRect(inString, inFont, sDefaultDisplayPPI);
055   }
056
057   //--------------------------------------------------------------------------
058   /**
059    Calculate the bounding rectangle for the specified string and font.
060    @param inString the text for which to calculate the bounding rectangle
061    @param inFont   the text for which to calculate the bounding rectangle
062    @return the bounding rectangle for the specified text and font
063    */
064   public static Rectangle getStringRect(String inString, Font inFont, DisplayPPI inPPI)
065   {
066      Rectangle2D rect = inFont.getStringBounds(inString, 0, inString.length(), sFRC);
067
068      float scalingFactor = (inPPI != null ? inPPI : sDefaultDisplayPPI).intValue() / 72f;
069
070      return new Rectangle((int) (rect.getWidth() * scalingFactor), (int) (rect.getHeight() * scalingFactor));
071   }
072
073   //--------------------------------------------------------------------------
074   /**
075    Calculate the bounding rectangle for the specified string and font where the bottom of the
076    rectangle is at the baseline and using the default of 96 ppi. Even strings that don't contain
077    characters that go below the baseline will still have a descent area included in the bounding
078    rectangle if the standard getStringRect() is used.
079    @param inString the text for which to calculate the bounding rectangle
080    @param inFont   the text for which to calculate the bounding rectangle
081    @return the bounding baselined rectangle for the specified text and font
082    */
083   public static Rectangle getStringBaselineRect(String inString, Font inFont)
084   {
085      return getStringBaselineRect(inString, inFont, sDefaultDisplayPPI);
086   }
087
088   //--------------------------------------------------------------------------
089   /**
090    Calculate the bounding rectangle for the specified string and font where the bottom of the
091    rectangle is at the baseline. Even strings that don't contain characters that go below the baseline
092    will still have a descent area included in the bounding rectangle if the standard getStringRect() is used.
093    @param inString the text for which to calculate the bounding rectangle
094    @param inFont   the text for which to calculate the bounding rectangle
095    @param inPPI    the pixels per inch of the display device
096    @return the bounding baselined rectangle for the specified text and font
097    */
098   public static Rectangle getStringBaselineRect(String inString, Font inFont, DisplayPPI inPPI)
099   {
100      Rectangle2D rect = inFont.getStringBounds(inString, 0, inString.length(), sFRC);
101
102      // Subtract the descent (the portion below the baseline)
103      float descent = inFont.getLineMetrics(inString, 0, inString.length(), sFRC).getDescent();
104
105      float scalingFactor = (inPPI != null ? inPPI : sDefaultDisplayPPI).intValue() / 72f;
106
107      return new Rectangle((int) (rect.getWidth() * scalingFactor), (int) ((rect.getHeight() - descent) * scalingFactor));
108   }
109
110}