175 lines
6.1 KiB
Java
175 lines
6.1 KiB
Java
/* ====================================================================
|
|
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<>();
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
}
|