1. /*
  2. * @(#)SwingUtilities2.java 1.2 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing;
  8. import java.awt.*;
  9. import java.awt.font.*;
  10. import java.awt.geom.*;
  11. /**
  12. * A collection of utility methods for Swing.
  13. * <p>
  14. * <b>WARNING:</b> While this class is public, it should not be treated as
  15. * public API and its API may change in incompatable ways between dot dot
  16. * releases and even patch releases. You should not rely on this class even
  17. * existing.
  18. *
  19. * @version 1.2 01/23/03
  20. */
  21. public class SwingUtilities2 {
  22. // Maintain a cache of CACHE_SIZE fonts and the left side bearing
  23. // of the characters falling into the range MIN_CHAR_INDEX to
  24. // MAX_CHAR_INDEX. The values in lsbCache are created as needed.
  25. private static final FontRenderContext DEFAULT_FRC = new FontRenderContext(
  26. null, false, false);
  27. private static final byte UNSET = Byte.MAX_VALUE;
  28. // getLeftSideBearing will consult all characters that fall in the
  29. // range MIN_CHAR_INDEX to MAX_CHAR_INDEX.
  30. private static final int MIN_CHAR_INDEX = (int)'W';
  31. private static final int MAX_CHAR_INDEX = (int)'W' + 1;
  32. // Windows defines 6 font desktop properties, we will therefore only
  33. // cache the metrics for 6 fonts.
  34. private static final int CACHE_SIZE = 6;
  35. // nextIndex in lsbCache and fontCache to insert a font into.
  36. private static int nextIndex;
  37. // Cache of left side bearnings.
  38. private static byte[][] lsbCache;
  39. // Caches of fonts
  40. private static Font[] fontCache;
  41. private static final char[] oneChar = new char[1];
  42. static {
  43. fontCache = new Font[CACHE_SIZE];
  44. lsbCache = new byte[CACHE_SIZE][];
  45. for (int counter = 0; counter < CACHE_SIZE; counter++) {
  46. lsbCache[counter] = new byte[MAX_CHAR_INDEX - MIN_CHAR_INDEX];
  47. reset(lsbCache[counter]);
  48. }
  49. }
  50. /**
  51. * Marks the values in the byte array as needing to be recalculated.
  52. */
  53. private static void reset(byte[] data) {
  54. for (int counter = data.length - 1; counter >= 0; counter--) {
  55. data[counter] = UNSET;
  56. }
  57. }
  58. /**
  59. * Returns the left side bearing of the first character of string. The
  60. * left side bearing is calculated from the passed in font assuming
  61. * a FontRenderContext with the identity transform.
  62. * If the passed in String is less than one character, this
  63. * will throw a StringIndexOutOfBoundsException exception.
  64. */
  65. public static int getLeftSideBearing(Font f, String string) {
  66. char firstChar = string.charAt(0);
  67. return getLeftSideBearing(f, string.charAt(0));
  68. }
  69. /**
  70. * Returns the left side bearing of the first character of string. The
  71. * left side bearing is calculated from the passed in font assuming
  72. * a FontRenderContext with the identity transform.
  73. * If the passed in String is less than one character, this
  74. * will throw a StringIndexOutOfBoundsException exception.
  75. */
  76. public static int getLeftSideBearing(Font f, char firstChar) {
  77. int charIndex = (int)firstChar;
  78. if (charIndex < MAX_CHAR_INDEX && charIndex >= MIN_CHAR_INDEX) {
  79. byte[] lsbs = null;
  80. charIndex -= MIN_CHAR_INDEX;
  81. synchronized(SwingUtilities2.class) {
  82. for (int counter = CACHE_SIZE - 1; counter >= 0;
  83. counter--) {
  84. if (fontCache[counter] == null) {
  85. fontCache[counter] = f;
  86. lsbs = lsbCache[counter];
  87. break;
  88. }
  89. else if (fontCache[counter].equals(f)) {
  90. lsbs = lsbCache[counter];
  91. break;
  92. }
  93. }
  94. if (lsbs == null) {
  95. // no more room
  96. lsbs = lsbCache[nextIndex];
  97. reset(lsbs);
  98. fontCache[nextIndex] = f;
  99. nextIndex = (nextIndex + 1) % CACHE_SIZE;
  100. }
  101. if (lsbs[charIndex] == UNSET) {
  102. lsbs[charIndex] = (byte)_getLeftSideBearing(
  103. f, firstChar);
  104. }
  105. return lsbs[charIndex];
  106. }
  107. }
  108. return 0;
  109. }
  110. /**
  111. * Computes and returns the left side bearing of the specified
  112. * character.
  113. */
  114. private static int _getLeftSideBearing(Font f, char aChar) {
  115. oneChar[0] = aChar;
  116. GlyphVector gv = f.createGlyphVector(DEFAULT_FRC, oneChar);
  117. Rectangle bounds = gv.getGlyphPixelBounds(0, DEFAULT_FRC, 0f, 0f);
  118. return bounds.x;
  119. }
  120. }