blob: 11131b66a16d25132109f1a03cc3d9026764f9e5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package org.eclipse.swt.internal.graphics;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
public class FontSizeEstimation {
public static Point stringExtent( String string, Font font ) {
if ( string == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
int width = getLineWidth( string, font );
int height = getCharHeight( font ) + 2;
return new Point( width, height );
}
/**
* respects line breaks and wrap
*/
public static Point textExtent( final String string,
final int wrapWidth,
final Font font )
{
if ( string == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
int lineCount = 0;
int maxWidth = 0;
String[] lines = string.split( "\n" );
for( int i = 0; i < lines.length; i++ ) {
String line = lines[ i ];
lineCount++;
int width = getLineWidth( line, font );
if( wrapWidth > 0 ) {
boolean done = false;
while( !done ) {
int index = getLongestMatch( line, wrapWidth, font );
if( index == 0 || index == line.length() ) {
// line fits or cannot be wrapped
done = true;
} else {
// wrap line
String substr = line.substring( 0, index );
width = getLineWidth( substr, font );
maxWidth = Math.max( maxWidth, width );
line = line.substring( index, line.length() );
lineCount++;
}
}
}
maxWidth = Math.max( maxWidth, width );
}
int height = Math.round( getCharHeight( font ) * 1.25f * lineCount );
return new Point( maxWidth, height );
}
public static int getCharHeight( final Font font ) {
// at 72 dpi, 1 pt == 1 px
return font.getSize();
}
public static float getAvgCharWidth( final Font font ) {
float width = font.getSize() * 0.48f;
if( ( font.getStyle() & SWT.BOLD ) != 0 ) {
width *= 1.45;
}
return width;
}
/**
* @return The length of the longest substring, whose width is smaller or
* equal to wrapWidth. If there is no such substring, zero is
* returned. The result is never negative.
*/
private static int getLongestMatch( final String string,
final int wrapWidth,
final Font font )
{
int result = 0;
if( getLineWidth( string, font ) < wrapWidth ) {
result = string.length();
} else {
String subStr = nextSubLine( string, 0 );
boolean done = false;
while( !done && getLineWidth( subStr, font ) <= wrapWidth ) {
result = subStr.length();
// loop prevention (see bug 182754)
if( subStr.length() == string.length() ) {
done = true;
} else {
subStr = nextSubLine( string, subStr.length() + 1 );
}
}
}
return result;
}
/**
* Returns the next substring that can be wrapped.
*/
private static String nextSubLine( final String line,
final int startIndex )
{
String result = line;
int index = line.indexOf( ' ', startIndex );
if( index != -1 ) {
result = line.substring( 0, index );
}
return result;
}
/**
* Returns the width of a given string in pixels. Linebreaks are ignored.
*/
private static int getLineWidth( final String line, final Font font ) {
return Math.round( getAvgCharWidth( font ) * line.length() );
}
}