home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / FontMetrics.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  21.5 KB  |  544 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)FontMetrics.java    1.37 98/10/22
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt;
  16.  
  17. import java.awt.Graphics2D;
  18. import java.awt.font.FontRenderContext;
  19. import java.awt.font.LineMetrics;
  20. import java.awt.geom.Rectangle2D;
  21. import java.text.CharacterIterator;
  22.  
  23. /**
  24.  * The <code>FontMetrics</code> class defines a font metrics object, which
  25.  * encapsulates information about the rendering of a particular font on a
  26.  * particular screen. Note that the implementations of these methods are
  27.  * inefficient, so they are usually overridden with more efficient
  28.  * toolkit-specific implementations.
  29.  * <p>
  30.  * <b>Note to subclassers</b>: Since many of these methods form closed,
  31.  * mutually recursive loops, you must take care that you implement
  32.  * at least one of the methods in each such loop to prevent
  33.  * infinite recursion when your subclass is used.
  34.  * In particular, the following is the minimal suggested set of methods
  35.  * to override in order to ensure correctness and prevent infinite
  36.  * recursion (though other subsets are equally feasible):
  37.  * <ul>
  38.  * <li>{@link #getAscent()}
  39.  * <li>{@link #getLeading()}
  40.  * <li>{@link #getMaxAdvance()}
  41.  * <li>{@link #charWidth(char)}
  42.  * <li>{@link #charsWidth(char[], int, int)}
  43.  * </ul>
  44.  * <p>
  45.  * <img src="doc-files/FontMetrics-1.gif" border=15 align
  46.  * ALIGN=right HSPACE=10 VSPACE=7>
  47.  * When an application asks AWT to place a character at the position
  48.  * (<i>x</i>, <i>y</i>), the character is placed so that its
  49.  * reference point (shown as the dot in the accompanying image) is
  50.  * put at that position. The reference point specifies a horizontal
  51.  * line called the <i>baseline</i> of the character. In normal
  52.  * printing, the baselines of characters should align.
  53.  * <p>
  54.  * In addition, every character in a font has an <i>ascent</i>, a
  55.  * <i>descent</i>, and an <i>advance width</i>. The ascent is the
  56.  * amount by which the character ascends above the baseline. The
  57.  * descent is the amount by which the character descends below the
  58.  * baseline. The advance width indicates the position at which AWT
  59.  * should place the next character.
  60.  * <p>
  61.  * If the current character is placed with its reference point
  62.  * at the position (<i>x</i>, <i>y</i>), and
  63.  * the character's advance width is <i>w</i>, then the new
  64.  * character is placed with its reference point at the position
  65.  * (<i>x </i><code>+</code><i> w</i>, <i>y</i>).
  66.  * The advance width is often, but not necessarily, the same as the width
  67.  * of a character's bounding box. In particular, oblique and
  68.  * italic fonts often have characters whose top-right corner extends
  69.  * slightly beyond the advance width.
  70.  * <p>
  71.  * An array of characters or a string can also have an ascent, a
  72.  * descent, and an advance width. The ascent of the array is the
  73.  * maximum ascent of any character in the array. The descent is the
  74.  * maximum descent of any character in the array. The advance width
  75.  * is the sum of the advance widths of each of the characters in the
  76.  * array.
  77.  * @version     1.21 03/18/98
  78.  * @author     Jim Graham
  79.  * @see         java.awt.Font
  80.  * @since       JDK1.0
  81.  */
  82. public abstract class FontMetrics implements java.io.Serializable {
  83.  
  84.     static {
  85.         /* ensure that the necessary native libraries are loaded */
  86.     Toolkit.loadLibraries();
  87.         initIDs();
  88.     }
  89.  
  90.     /**
  91.      * The actual {@link Font} from which the font metrics are
  92.      * created. 
  93.      * This cannot be null.
  94.      *
  95.      * @serial
  96.      * @see #getFont()
  97.      */
  98.     protected Font font;
  99.  
  100.     /*
  101.      * JDK 1.1 serialVersionUID
  102.      */
  103.     private static final long serialVersionUID = 1681126225205050147L;
  104.  
  105.     /**
  106.      * Creates a new <code>FontMetrics</code> object for finding out
  107.      * height and width information about the specified <code>Font</code> 
  108.      * and specific character glyphs in that <code>Font</code>.
  109.      * @param     font the <code>Font</code>
  110.      * @see       java.awt.Font
  111.      */
  112.     protected FontMetrics(Font font) {
  113.     this.font = font;
  114.     }
  115.  
  116.     /**
  117.      * Gets the <code>Font</code> described by this
  118.      * <code>FontMetrics</code> object.
  119.      * @return    the <code>Font</code> described by this 
  120.      * <code>FontMetrics</code> object.
  121.      */
  122.     public Font getFont() {
  123.     return font;
  124.     }
  125.  
  126.     /**
  127.      * Determines the <em>standard leading</em> of the 
  128.      * <code>Font</code> described by this <code>FontMetrics</code>
  129.      * object.  The standard leading, or
  130.      * interline spacing, is the logical amount of space to be reserved
  131.      * between the descent of one line of text and the ascent of the next
  132.      * line. The height metric is calculated to include this extra space.
  133.      * @return    the standard leading of the <code>Font</code>.
  134.      * @see   #getHeight()
  135.      * @see   #getAscent()
  136.      * @see   #getDescent()
  137.      */
  138.     public int getLeading() {
  139.     return 0;
  140.     }
  141.  
  142.     /**
  143.      * Determines the <em>font ascent</em> of the <code>Font</code> 
  144.      * described by this <code>FontMetrics</code> object. The font ascent
  145.      * is the distance from the font's baseline to the top of most
  146.      * alphanumeric characters. Some characters in the <code>Font</code> 
  147.      * might extend above the font ascent line.
  148.      * @return     the font ascent of the <code>Font</code>.
  149.      * @see        #getMaxAscent()
  150.      */
  151.     public int getAscent() {
  152.     return font.getSize();
  153.     }
  154.  
  155.     /**
  156.      * Determines the <em>font descent</em> of the <code>Font</code> 
  157.      * described by this
  158.      * <code>FontMetrics</code> object. The font descent is the distance
  159.      * from the font's baseline to the bottom of most alphanumeric
  160.      * characters with descenders. Some characters in the
  161.      * <code>Font</code> might extend
  162.      * below the font descent line.
  163.      * @return     the font descent of the <code>Font</code>.
  164.      * @see        #getMaxDescent()
  165.      */
  166.     public int getDescent() {
  167.     return 0;
  168.     }
  169.  
  170.     /**
  171.      * Gets the standard height of a line of text in this font.  This
  172.      * is the distance between the baseline of adjacent lines of text.
  173.      * It is the sum of the leading + ascent + descent.  There is no
  174.      * guarantee that lines of text spaced at this distance are
  175.      * disjoint; such lines may overlap if some characters overshoot
  176.      * either the standard ascent or the standard descent metric.
  177.      * @return    the standard height of the font.
  178.      * @see       #getLeading()
  179.      * @see       #getAscent()
  180.      * @see       #getDescent()
  181.      */
  182.     public int getHeight() {
  183.     return getLeading() + getAscent() + getDescent();
  184.     }
  185.  
  186.     /**
  187.      * Determines the maximum ascent of the <code>Font</code> 
  188.      * described by this <code>FontMetrics</code> object.  No character 
  189.      * extends further above the font's baseline than this height.
  190.      * @return    the maximum ascent of any character in the 
  191.      * <code>Font</code>.
  192.      * @see       #getAscent()
  193.      */
  194.     public int getMaxAscent() {
  195.     return getAscent();
  196.     }
  197.  
  198.     /**
  199.      * Determines the maximum descent of the <code>Font</code> 
  200.      * described by this <code>FontMetrics</code> object.  No character 
  201.      * extends further below the font's baseline than this height.
  202.      * @return    the maximum descent of any character in the
  203.      * <code>Font</code>.
  204.      * @see       #getDescent()
  205.      */
  206.     public int getMaxDescent() {
  207.     return getDescent();
  208.     }
  209.  
  210.     /**
  211.      * For backward compatibility only.
  212.      * @see #getMaxDescent()
  213.      * @deprecated As of JDK version 1.1.1,
  214.      * replaced by <code>getMaxDescent()</code>.
  215.      */
  216.     public int getMaxDecent() {
  217.     return getMaxDescent();
  218.     }
  219.  
  220.     /**
  221.      * Gets the maximum advance width of any character in this 
  222.      * <code>Font</code>.  The advance width is the amount by which the
  223.      * current point is moved from one character to the next in a line of
  224.      * text.
  225.      * @return    the maximum advance width of any character
  226.      *            in the <code>Font</code>, or <code>-1</code> if the
  227.      *            maximum advance width is not known.
  228.      */
  229.     public int getMaxAdvance() {
  230.     return -1;
  231.     }
  232.  
  233.     /**
  234.      * Returns the advance width of the specified character in this 
  235.      * <code>Font</code>.
  236.      * The advance width is the amount by which the current point is
  237.      * moved from one character to the next in a line of text.
  238.      * @param ch the character to be measured
  239.      * @return    the advance width of the specified <code>char</code>
  240.      *                 in the <code>Font</code> described by this
  241.      *            <code>FontMetrics</code> object.
  242.      * @see       #charsWidth(char[], int, int)
  243.      * @see       #stringWidth(String)
  244.      */
  245.     public int charWidth(int ch) {
  246.     return charWidth((char)ch);
  247.     }
  248.  
  249.     /**
  250.      * Returns the advance width of the specified character in this 
  251.      * <code>Font</code>.
  252.      * The advance width is the amount by which the current point is
  253.      * moved from one character to the next in a line of text.
  254.      * @param ch the character to be measured
  255.      * @return     the advance width of the specified <code>char</code>
  256.      *                  in the <code>Font</code> described by this 
  257.      *            <code>FontMetrics</code> object.
  258.      * @see        #charsWidth(char[], int, int)
  259.      * @see        #stringWidth(String)
  260.      */
  261.     public int charWidth(char ch) {
  262.     if (ch < 256) {
  263.         return getWidths()[ch];
  264.     }
  265.     char data[] = {ch};
  266.     return charsWidth(data, 0, 1);
  267.     }
  268.  
  269.     /**
  270.      * Returns the total advance width for showing the specified 
  271.      * <code>String</code> in this <code>Font</code>. The advance width is
  272.      * the amount by which the current point is moved from one character
  273.      * to the next in a line of text.
  274.      * @param str the <code>String</code> to be measured
  275.      * @return    the advance width of the specified <code>String</code>
  276.      *                  in the <code>Font</code> described by this
  277.      *            <code>FontMetrics</code>.
  278.      * @see       #bytesWidth(byte[], int, int)
  279.      * @see       #charsWidth(char[], int, int)
  280.      */
  281.     public int stringWidth(String str) {
  282.     int len = str.length();
  283.     char data[] = new char[len];
  284.     str.getChars(0, len, data, 0);
  285.     return charsWidth(data, 0, len);
  286.     }
  287.  
  288.     /**
  289.      * Returns the total advance width for showing the specified array
  290.      * of characters in this <code>Font</code>.  The advance width is the
  291.      * amount by which the current point is moved from one character to
  292.      * the next in a line of text.
  293.      * @param data the array of characters to be measured
  294.      * @param off the start offset of the characters in the array
  295.      * @param len the number of characters to be measured from the array
  296.      * @return    the advance width of the subarray of the specified
  297.      *               <code>char</code> array in the font described by
  298.      *               this <code>FontMetrics</code> object.
  299.      * @see       #charWidth(int)
  300.      * @see       #charWidth(char)
  301.      * @see       #bytesWidth(byte[], int, int)
  302.      * @see       #stringWidth(String)
  303.      */
  304.     public int charsWidth(char data[], int off, int len) {
  305.     return stringWidth(new String(data, off, len));
  306.     }
  307.  
  308.     /**
  309.      * Returns the total advance width for showing the specified array
  310.      * of bytes in this <code>Font</code>.
  311.      * The advance width is the amount by which the current point is
  312.      * moved from one character to the next in a line of text.
  313.      * @param data the array of bytes to be measured
  314.      * @param off the start offset of the bytes in the array
  315.      * @param len the number of bytes to be measured from the array
  316.      * @return    the advance width of the subarray of the specified
  317.      *               <code>byte</code> array in the <code>Font</code> 
  318.      *            described by
  319.      *               this <code>FontMetrics</code> object.
  320.      * @see       #charsWidth(char[], int, int)
  321.      * @see       #stringWidth(String)
  322.      */
  323.     public int bytesWidth(byte data[], int off, int len) {
  324.     return stringWidth(new String(data, 0, off, len));
  325.     }
  326.  
  327.     /**
  328.      * Gets the advance widths of the first 256 characters in the 
  329.      * <code>Font</code>.  The advance width is the amount by which the
  330.      * current point is moved from one character to the next in a line of
  331.      * text.
  332.      * @return    an array storing the advance widths of the
  333.      *                 characters in the <code>Font</code>
  334.      *                 described by this <code>FontMetrics</code> object.
  335.      */
  336.     public int[] getWidths() {
  337.     int widths[] = new int[256];
  338.     for (char ch = 0 ; ch < 256 ; ch++) {
  339.         widths[ch] = charWidth(ch);
  340.     }
  341.     return widths;
  342.     }
  343.  
  344.     /**
  345.      * Checks to see if the <code>Font</code> has uniform line metrics.  A 
  346.      * composite font may consist of several different fonts to cover
  347.      * various character sets.  In such cases, the 
  348.      * <code>FontLineMetrics</code> objects are not uniform.  
  349.      * Different fonts may have a different ascent, descent, metrics and
  350.      * so on.  This information is sometimes necessary for line 
  351.      * measuring and line breaking.
  352.      * @return <code>true</code> if the font has uniform line metrics;
  353.      * <code>false</code> otherwise.
  354.      * @see java.awt.Font#hasUniformLineMetrics()
  355.      */
  356.     public boolean hasUniformLineMetrics() {
  357.         return font.hasUniformLineMetrics();
  358.     }
  359.  
  360.     /**
  361.      * Returns the {@link LineMetrics} object for the specified
  362.      * <code>String</code> in the specified {@link Graphics} context.
  363.      * @param str the specified <code>String</code>
  364.      * @param context the specified <code>Graphics</code> context
  365.      * @return a <code>LineMetrics</code> object created with the
  366.      * specified <code>String</code> and <code>Graphics</code> context.
  367.      * @see java.awt.Font#getLineMetrics(String, FontRenderContext)
  368.      */
  369.     public LineMetrics getLineMetrics( String str, Graphics context) {
  370.         return font.getLineMetrics(str, myFRC(context));
  371.     }
  372.  
  373.     /**
  374.      * Returns the {@link LineMetrics} object for the specified
  375.      * <code>String</code> in the specified {@link Graphics} context.
  376.      * @param str the specified <code>String</code>
  377.      * @param beginIndex the initial offset of <code>str</code>
  378.      * @param limit the length of <code>str</code>
  379.      * @param context the specified <code>Graphics</code> context
  380.      * @return a <code>LineMetrics</code> object created with the
  381.      * specified <code>String</code> and <code>Graphics</code> context.
  382.      * @see java.awt.Font#getLineMetrics(String, int, int, FontRenderContext)
  383.      */
  384.     public LineMetrics getLineMetrics( String str,
  385.                                             int beginIndex, int limit,
  386.                                             Graphics context) {
  387.         return font.getLineMetrics(str, beginIndex, limit, myFRC(context));
  388.     }
  389.  
  390.     /**
  391.      * Returns the {@link LineMetrics} object for the specified
  392.      * character array in the specified {@link Graphics} context.
  393.      * @param chars the specified character array
  394.      * @param beginIndex the initial offset of <code>chars</code>
  395.      * @param limit the length of <code>chars</code>
  396.      * @param context the specified <code>Graphics</code> context
  397.      * @return a <code>LineMetrics</code> object created with the
  398.      * specified character array and <code>Graphics</code> context.
  399.      * @see java.awt.Font#getLineMetrics(char[], int, int, FontRenderContext)
  400.      */
  401.     public LineMetrics getLineMetrics(char [] chars,
  402.                                             int beginIndex, int limit,
  403.                                             Graphics context) {
  404.         return font.getLineMetrics(
  405.                                 chars, beginIndex, limit, myFRC(context));
  406.     }
  407.  
  408.     /**
  409.      * Returns the {@link LineMetrics} object for the specified
  410.      * {@link CharacterIterator} in the specified {@link Graphics} 
  411.      * context.
  412.      * @param ci the specified <code>CharacterIterator</code>
  413.      * @param beginIndex the initial offset in <code>ci</code>
  414.      * @param limit the end index of <code>ci</code>
  415.      * @param context the specified <code>Graphics</code> context
  416.      * @return a <code>LineMetrics</code> object created with the
  417.      * specified arguments.
  418.      * @see java.awt.Font#getLineMetrics(CharacterIterator, int, int, FontRenderContext)
  419.      */
  420.     public LineMetrics getLineMetrics(CharacterIterator ci,
  421.                                             int beginIndex, int limit,
  422.                                             Graphics context) {
  423.         return font.getLineMetrics(ci, beginIndex, limit, myFRC(context));
  424.     }
  425.  
  426.     /**
  427.      * Returns the bounds of the specified <code>String</code> in the
  428.      * specified <code>Graphics</code> context.  The bounds is used
  429.      * to layout the <code>String</code>.
  430.      * @param str the specified <code>String</code>   
  431.      * @param context the specified <code>Graphics</code> context
  432.      * @return a {@link Rectangle2D} that is the bounding box of the
  433.      * specified <code>String</code> in the specified
  434.      * <code>Graphics</code> context.
  435.      * @see java.awt.Font#getStringBounds(String, FontRenderContext)
  436.      */
  437.     public Rectangle2D getStringBounds( String str, Graphics context) {
  438.         return font.getStringBounds(str, myFRC(context));
  439.     }
  440.  
  441.     /**
  442.      * Returns the bounds of the specified <code>String</code> in the
  443.      * specified <code>Graphics</code> context.  The bounds is used
  444.      * to layout the <code>String</code>.
  445.      * @param str the specified <code>String</code>
  446.      * @param beginIndex the offset of the beginning of <code>str</code>
  447.      * @param limit the length of <code>str</code>
  448.      * @param context the specified <code>Graphics</code> context
  449.      * @return a <code>Rectangle2D</code> that is the bounding box of the
  450.      * specified <code>String</code> in the specified
  451.      * <code>Graphics</code> context.
  452.      * @see java.awt.Font#getStringBounds(String, int, int, FontRenderContext)
  453.      */
  454.     public Rectangle2D getStringBounds( String str,
  455.                                         int beginIndex, int limit,
  456.                                         Graphics context) {
  457.         return font.getStringBounds(str, beginIndex, limit,
  458.                                         myFRC(context));
  459.     }
  460.  
  461.    /**
  462.      * Returns the bounds of the specified array of characters
  463.      * in the specified <code>Graphics</code> context.
  464.      * The bounds is used to layout the <code>String</code>
  465.      * created with the specified array of characters,
  466.      * <code>beginIndex</code> and <code>limit</code>.
  467.      * @param chars an array of characters
  468.      * @param beginIndex the initial offset of the array of
  469.      * characters
  470.      * @param limit the length of the array of characters
  471.      * @param context the specified <code>Graphics</code> context
  472.      * @return a <code>Rectangle2D</code> that is the bounding box of the
  473.      * specified character array in the specified
  474.      * <code>Graphics</code> context. 
  475.      * @see java.awt.Font#getStringBounds(char[], int, int, FontRenderContext)
  476.      */ 
  477.     public Rectangle2D getStringBounds( char [] chars,
  478.                                         int beginIndex, int limit,
  479.                                         Graphics context) {
  480.         return font.getStringBounds(chars, beginIndex, limit,
  481.                                         myFRC(context));
  482.     }
  483.  
  484.    /**
  485.      * Returns the bounds of the characters indexed in the specified
  486.      * <code>CharacterIterator</code> in the
  487.      * specified <code>Graphics</code> context.  
  488.      * @param ci the specified <code>CharacterIterator</code> 
  489.      * @param beginIndex the initial offset in <code>ci</code>
  490.      * @param limit the end index of <code>ci</code>
  491.      * @param context the specified <code>Graphics</code> context
  492.      * @return a <code>Rectangle2D</code> that is the bounding box of the
  493.      * characters indexed in the specified <code>CharacterIterator</code>
  494.      * in the specified <code>Graphics</code> context.
  495.      * @see java.awt.Font#getStringBounds(CharacterIterator, int, int, FontRenderContext)
  496.      */
  497.     public Rectangle2D getStringBounds(CharacterIterator ci,
  498.                                         int beginIndex, int limit,
  499.                                         Graphics context) {
  500.         return font.getStringBounds(ci, beginIndex, limit,
  501.                                         myFRC(context));
  502.     }
  503.  
  504.     /**
  505.      * Returns the bounds for the character with the maximum bounds
  506.      * in the specified <code>Graphics</code> context.
  507.      * @param context the specified <code>Graphics</code> context
  508.      * @return a <code>Rectangle2D</code> that is the 
  509.      * bounding box for the character with the maximum bounds.
  510.      * @see java.awt.Font#getMaxCharBounds(FontRenderContext)
  511.      */       
  512.     public Rectangle2D getMaxCharBounds(Graphics context) {
  513.         return font.getMaxCharBounds(myFRC(context));
  514.     }
  515.  
  516.     private FontRenderContext myFRC(Graphics context) {
  517.         if (context instanceof Graphics2D) {
  518.             return ((Graphics2D)context).getFontRenderContext();
  519.         }
  520.         return new FontRenderContext(null, false, false);
  521.     }
  522.  
  523.  
  524.     /**
  525.      * Returns a representation of this <code>FontMetrics</code>
  526.      * object's values as a <code>String</code>.
  527.      * @return    a <code>String</code> representation of this 
  528.      * <code>FontMetrics</code> object.
  529.      * @since     JDK1.0.
  530.      */
  531.     public String toString() {
  532.     return getClass().getName() +
  533.         "[font=" + getFont() +
  534.         "ascent=" + getAscent() +
  535.         ", descent=" + getDescent() +
  536.         ", height=" + getHeight() + "]";
  537.     }
  538.  
  539.     /**
  540.      * Initialize JNI field and method IDs
  541.      */
  542.     private static native void initIDs();
  543. }
  544.