| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| |
| package org.apache.poi.hssf.usermodel; |
| |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Properties; |
| import java.util.StringTokenizer; |
| |
| /** |
| * Stores width and height details about a font. |
| */ |
| public class FontDetails |
| { |
| private String _fontName; |
| private int _height; |
| private final Map<Character, Integer> charWidths = new HashMap<Character, Integer>(); |
| |
| /** |
| * Construct the font details with the given name and height. |
| * |
| * @param fontName The font name. |
| * @param height The height of the font. |
| */ |
| public FontDetails( String fontName, int height ) |
| { |
| _fontName = fontName; |
| _height = height; |
| } |
| |
| public String getFontName() |
| { |
| return _fontName; |
| } |
| |
| public int getHeight() |
| { |
| return _height; |
| } |
| |
| public void addChar( char c, int width ) |
| { |
| charWidths.put(Character.valueOf(c), Integer.valueOf(width)); |
| } |
| |
| /** |
| * Retrieves the width of the specified character. If the metrics for |
| * a particular character are not available it defaults to returning the |
| * width for the 'W' character. |
| */ |
| public int getCharWidth( char c ) |
| { |
| Integer widthInteger = charWidths.get(Character.valueOf(c)); |
| if (widthInteger == null) { |
| return 'W' == c ? 0 : getCharWidth('W'); |
| } |
| return widthInteger; |
| } |
| |
| public void addChars( char[] characters, int[] widths ) |
| { |
| for ( int i = 0; i < characters.length; i++ ) |
| { |
| charWidths.put( Character.valueOf(characters[i]), Integer.valueOf(widths[i])); |
| } |
| } |
| |
| protected static String buildFontHeightProperty(String fontName) { |
| return "font." + fontName + ".height"; |
| } |
| protected static String buildFontWidthsProperty(String fontName) { |
| return "font." + fontName + ".widths"; |
| } |
| protected static String buildFontCharactersProperty(String fontName) { |
| return "font." + fontName + ".characters"; |
| } |
| |
| /** |
| * Create an instance of <code>FontDetails</code> by loading them from the |
| * provided property object. |
| * @param fontName the font name |
| * @param fontMetricsProps the property object holding the details of this |
| * particular font. |
| * @return a new FontDetails instance. |
| */ |
| public static FontDetails create( String fontName, Properties fontMetricsProps ) |
| { |
| String heightStr = fontMetricsProps.getProperty( buildFontHeightProperty(fontName) ); |
| String widthsStr = fontMetricsProps.getProperty( buildFontWidthsProperty(fontName) ); |
| String charactersStr = fontMetricsProps.getProperty( buildFontCharactersProperty(fontName) ); |
| |
| // Ensure that this is a font we know about |
| if(heightStr == null || widthsStr == null || charactersStr == null) { |
| // We don't know all we need to about this font |
| // Since we don't know its sizes, we can't work with it |
| throw new IllegalArgumentException("The supplied FontMetrics doesn't know about the font '" + fontName + "', so we can't use it. Please add it to your font metrics file (see StaticFontMetrics.getFontDetails"); |
| } |
| |
| int height = Integer.parseInt(heightStr); |
| FontDetails d = new FontDetails(fontName, height); |
| String[] charactersStrArray = split(charactersStr, ",", -1); |
| String[] widthsStrArray = split(widthsStr, ",", -1); |
| if (charactersStrArray.length != widthsStrArray.length) |
| throw new RuntimeException("Number of characters does not number of widths for font " + fontName); |
| for ( int i = 0; i < widthsStrArray.length; i++ ) |
| { |
| if (charactersStrArray[i].length() != 0) |
| d.addChar(charactersStrArray[i].charAt(0), Integer.parseInt(widthsStrArray[i])); |
| } |
| return d; |
| } |
| |
| /** |
| * Gets the width of all characters in a string. |
| * |
| * @param str The string to measure. |
| * @return The width of the string for a 10 point font. |
| */ |
| public int getStringWidth(String str) |
| { |
| int width = 0; |
| for (int i = 0; i < str.length(); i++) |
| { |
| width += getCharWidth(str.charAt(i)); |
| } |
| return width; |
| } |
| |
| /** |
| * Split the given string into an array of strings using the given |
| * delimiter. |
| */ |
| private static String[] split(String text, String separator, int max) |
| { |
| StringTokenizer tok = new StringTokenizer(text, separator); |
| int listSize = tok.countTokens(); |
| if(max != -1 && listSize > max) |
| listSize = max; |
| String list[] = new String[listSize]; |
| for(int i = 0; tok.hasMoreTokens(); i++) |
| { |
| if(max != -1 && i == listSize - 1) |
| { |
| StringBuffer buf = new StringBuffer((text.length() * (listSize - i)) / listSize); |
| while(tok.hasMoreTokens()) |
| { |
| buf.append(tok.nextToken()); |
| if(tok.hasMoreTokens()) |
| buf.append(separator); |
| } |
| list[i] = buf.toString().trim(); |
| break; |
| } |
| list[i] = tok.nextToken().trim(); |
| } |
| |
| return list; |
| } |
| } |