/* * @(#)SwingUtilities2.java 1.2 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.sun.java.swing; import java.awt.*; import java.awt.font.*; import java.awt.geom.*; /** * A collection of utility methods for Swing. *
* WARNING: While this class is public, it should not be treated as * public API and its API may change in incompatable ways between dot dot * releases and even patch releases. You should not rely on this class even * existing. * * @version 1.2 01/23/03 */ public class SwingUtilities2 { // Maintain a cache of CACHE_SIZE fonts and the left side bearing // of the characters falling into the range MIN_CHAR_INDEX to // MAX_CHAR_INDEX. The values in lsbCache are created as needed. private static final FontRenderContext DEFAULT_FRC = new FontRenderContext( null, false, false); private static final byte UNSET = Byte.MAX_VALUE; // getLeftSideBearing will consult all characters that fall in the // range MIN_CHAR_INDEX to MAX_CHAR_INDEX. private static final int MIN_CHAR_INDEX = (int)'W'; private static final int MAX_CHAR_INDEX = (int)'W' + 1; // Windows defines 6 font desktop properties, we will therefore only // cache the metrics for 6 fonts. private static final int CACHE_SIZE = 6; // nextIndex in lsbCache and fontCache to insert a font into. private static int nextIndex; // Cache of left side bearnings. private static byte[][] lsbCache; // Caches of fonts private static Font[] fontCache; private static final char[] oneChar = new char[1]; static { fontCache = new Font[CACHE_SIZE]; lsbCache = new byte[CACHE_SIZE][]; for (int counter = 0; counter < CACHE_SIZE; counter++) { lsbCache[counter] = new byte[MAX_CHAR_INDEX - MIN_CHAR_INDEX]; reset(lsbCache[counter]); } } /** * Marks the values in the byte array as needing to be recalculated. */ private static void reset(byte[] data) { for (int counter = data.length - 1; counter >= 0; counter--) { data[counter] = UNSET; } } /** * Returns the left side bearing of the first character of string. The * left side bearing is calculated from the passed in font assuming * a FontRenderContext with the identity transform. * If the passed in String is less than one character, this * will throw a StringIndexOutOfBoundsException exception. */ public static int getLeftSideBearing(Font f, String string) { char firstChar = string.charAt(0); return getLeftSideBearing(f, string.charAt(0)); } /** * Returns the left side bearing of the first character of string. The * left side bearing is calculated from the passed in font assuming * a FontRenderContext with the identity transform. * If the passed in String is less than one character, this * will throw a StringIndexOutOfBoundsException exception. */ public static int getLeftSideBearing(Font f, char firstChar) { int charIndex = (int)firstChar; if (charIndex < MAX_CHAR_INDEX && charIndex >= MIN_CHAR_INDEX) { byte[] lsbs = null; charIndex -= MIN_CHAR_INDEX; synchronized(SwingUtilities2.class) { for (int counter = CACHE_SIZE - 1; counter >= 0; counter--) { if (fontCache[counter] == null) { fontCache[counter] = f; lsbs = lsbCache[counter]; break; } else if (fontCache[counter].equals(f)) { lsbs = lsbCache[counter]; break; } } if (lsbs == null) { // no more room lsbs = lsbCache[nextIndex]; reset(lsbs); fontCache[nextIndex] = f; nextIndex = (nextIndex + 1) % CACHE_SIZE; } if (lsbs[charIndex] == UNSET) { lsbs[charIndex] = (byte)_getLeftSideBearing( f, firstChar); } return lsbs[charIndex]; } } return 0; } /** * Computes and returns the left side bearing of the specified * character. */ private static int _getLeftSideBearing(Font f, char aChar) { oneChar[0] = aChar; GlyphVector gv = f.createGlyphVector(DEFAULT_FRC, oneChar); Rectangle bounds = gv.getGlyphPixelBounds(0, DEFAULT_FRC, 0f, 0f); return bounds.x; } }