001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hssf.usermodel;
019:
020: import java.util.HashMap;
021: import java.util.Map;
022: import java.util.Properties;
023: import java.util.StringTokenizer;
024:
025: /**
026: * Stores width and height details about a font.
027: *
028: * @author Glen Stampoultzis (glens at apache.org)
029: */
030: public class FontDetails {
031: private String fontName;
032: private int height;
033: private Map charWidths = new HashMap();
034:
035: /**
036: * Construct the font details with the given name and height.
037: *
038: * @param fontName The font name.
039: * @param height The height of the font.
040: */
041: public FontDetails(String fontName, int height) {
042: this .fontName = fontName;
043: this .height = height;
044: }
045:
046: public String getFontName() {
047: return fontName;
048: }
049:
050: public int getHeight() {
051: return height;
052: }
053:
054: public void addChar(char c, int width) {
055: charWidths.put(new Character(c), new Integer(width));
056: }
057:
058: /**
059: * Retrieves the width of the specified character. If the metrics for
060: * a particular character are not available it defaults to returning the
061: * width for the 'W' character.
062: */
063: public int getCharWidth(char c) {
064: Integer widthInteger = (Integer) (charWidths.get(new Character(
065: c)));
066: if (widthInteger == null && c != 'W')
067: return getCharWidth('W');
068: else
069: return widthInteger.intValue();
070: }
071:
072: public void addChars(char[] characters, int[] widths) {
073: for (int i = 0; i < characters.length; i++) {
074: charWidths.put(new Character(characters[i]), new Integer(
075: widths[i]));
076: }
077: }
078:
079: protected static String buildFontHeightProperty(String fontName) {
080: return "font." + fontName + ".height";
081: }
082:
083: protected static String buildFontWidthsProperty(String fontName) {
084: return "font." + fontName + ".widths";
085: }
086:
087: protected static String buildFontCharactersProperty(String fontName) {
088: return "font." + fontName + ".characters";
089: }
090:
091: /**
092: * Create an instance of <code>FontDetails</code> by loading them from the
093: * provided property object.
094: * @param fontName the font name
095: * @param fontMetricsProps the property object holding the details of this
096: * particular font.
097: * @return a new FontDetails instance.
098: */
099: public static FontDetails create(String fontName,
100: Properties fontMetricsProps) {
101: String heightStr = fontMetricsProps
102: .getProperty(buildFontHeightProperty(fontName));
103: String widthsStr = fontMetricsProps
104: .getProperty(buildFontWidthsProperty(fontName));
105: String charactersStr = fontMetricsProps
106: .getProperty(buildFontCharactersProperty(fontName));
107:
108: // Ensure that this is a font we know about
109: if (heightStr == null || widthsStr == null
110: || charactersStr == null) {
111: // We don't know all we need to about this font
112: // Since we don't know its sizes, we can't work with it
113: throw new IllegalArgumentException(
114: "The supplied FontMetrics doesn't know about the font '"
115: + fontName
116: + "', so we can't use it. Please add it to your font metrics file (see StaticFontMetrics.getFontDetails");
117: }
118:
119: int height = Integer.parseInt(heightStr);
120: FontDetails d = new FontDetails(fontName, height);
121: String[] charactersStrArray = split(charactersStr, ",", -1);
122: String[] widthsStrArray = split(widthsStr, ",", -1);
123: if (charactersStrArray.length != widthsStrArray.length)
124: throw new RuntimeException(
125: "Number of characters does not number of widths for font "
126: + fontName);
127: for (int i = 0; i < widthsStrArray.length; i++) {
128: if (charactersStrArray[i].length() != 0)
129: d.addChar(charactersStrArray[i].charAt(0), Integer
130: .parseInt(widthsStrArray[i]));
131: }
132: return d;
133: }
134:
135: /**
136: * Gets the width of all characters in a string.
137: *
138: * @param str The string to measure.
139: * @return The width of the string for a 10 point font.
140: */
141: public int getStringWidth(String str) {
142: int width = 0;
143: for (int i = 0; i < str.length(); i++) {
144: width += getCharWidth(str.charAt(i));
145: }
146: return width;
147: }
148:
149: /**
150: * Split the given string into an array of strings using the given
151: * delimiter.
152: */
153: private static String[] split(String text, String separator, int max) {
154: StringTokenizer tok = new StringTokenizer(text, separator);
155: int listSize = tok.countTokens();
156: if (max != -1 && listSize > max)
157: listSize = max;
158: String list[] = new String[listSize];
159: for (int i = 0; tok.hasMoreTokens(); i++) {
160: if (max != -1 && i == listSize - 1) {
161: StringBuffer buf = new StringBuffer(
162: (text.length() * (listSize - i)) / listSize);
163: while (tok.hasMoreTokens()) {
164: buf.append(tok.nextToken());
165: if (tok.hasMoreTokens())
166: buf.append(separator);
167: }
168: list[i] = buf.toString().trim();
169: break;
170: }
171: list[i] = tok.nextToken().trim();
172: }
173:
174: return list;
175: }
176:
177: }
|