長方形に合わせてフォントを拡張する方法が必要です
質問
私はただの長方形(の長さ)に収まるようにフォントを拡張するいくつかのコードを書きました。それは18の幅から始まり、それが収まるまでダウン反復処理します。
これは恐ろしく非効率的なようだが、私はそれを行うための非ループ方法を見つけることができません。 このラインは、スケールゲームグリッド内のラベルのためのものであるので、私はワークアラウンド溶液(ラッピング、切断及び矩形を越えて延在するすべての受け入れられない)を見ることができません。
これは実際にはかなり速いですが、私は長方形の何百ものためにこれをやっている、それだけでタッチを、それを遅くするために十分な速さです。
より良いものを誰もが立ち上がっていない場合は、、私は(それが18よりもはるかに近いですように)テーブルから始まるの推測をロードし、これを使用します - 。それは素晴らしい作品遅れを除く
public Font scaleFont(String text, Rectangle rect, Graphics g, Font pFont) {
float nextTry=18.0f;
Font font=pFont;
while(x > 4) {
font=g.getFont().deriveFont(nextTry);
FontMetrics fm=g.getFontMetrics(font);
int width=fm.stringWidth(text);
if(width <= rect.width)
return font;
nextTry*=.9;
}
return font;
}
解決
半擬似コード
public Font scaleFont(String text, Rectangle rect, Graphics g, Font pFont) {
float fontSize = 20.0f;
Font font = pFont;
font = g.getFont().deriveFont(fontSize);
int width = g.getFontMetrics(font).stringWidth(text);
fontSize = (rect.width / width ) * fontSize;
return g.getFont().deriveFont(fontSize);
}
これを使用していないとして、あなたはpFontに渡し、なぜ私はわからないんだけど...
他のヒント
あなたは補間検索を使用することができます:
public static Font scaleFont(String text, Rectangle rect, Graphics g, Font pFont) {
float min=0.1f;
float max=72f;
float size=18.0f;
Font font=pFont;
while(max - min <= 0.1) {
font = g.getFont().deriveFont(size);
FontMetrics fm = g.getFontMetrics(font);
int width = fm.stringWidth(text);
if (width == rect.width) {
return font;
} else {
if (width < rect.width) {
min = size;
} else {
max = size;
}
size = Math.min(max, Math.max(min, size * (float)rect.width / (float)width));
}
}
return font;
}
より良い結果のためにintの代わりに浮いているように、すべての幅の変数を変更します。
public static Font scaleFontToFit(String text, int width, Graphics g, Font pFont)
{
float fontSize = pFont.getSize();
float fWidth = g.getFontMetrics(pFont).stringWidth(text);
if(fWidth <= width)
return pFont;
fontSize = ((float)width / fWidth) * fontSize;
return pFont.deriveFont(fontSize);
}
private Font scaleFont ( String text, Rectangle rect, Graphics gc )
{
final float fMinimumFont = 0.1f;
float fMaximumFont = 1000f;
/* Use Point2d.Float to hold ( font, width of font in pixels ) pairs. */
Point2D.Float lowerPoint = new Point2D.Float ( fMinimumFont, getWidthInPixelsOfString ( text, fMinimumFont, gc ) );
Point2D.Float upperPoint = new Point2D.Float ( fMaximumFont, getWidthInPixelsOfString ( text, fMaximumFont, gc ) );
Point2D.Float midPoint = new Point2D.Float ();
for ( int i = 0; i < 50; i++ )
{
float middleFont = ( lowerPoint.x + upperPoint.x ) / 2;
midPoint.setLocation ( middleFont, getWidthInPixelsOfString ( text, middleFont, gc ) );
if ( midPoint.y >= rect.getWidth () * .95 && midPoint.y <= rect.getWidth () )
break;
else if ( midPoint.y < rect.getWidth () )
lowerPoint.setLocation ( midPoint );
else if ( midPoint.y > rect.getWidth () )
upperPoint.setLocation ( midPoint );
}
fMaximumFont = midPoint.x;
Font font = gc.getFont ().deriveFont ( fMaximumFont );
/* Now use Point2d.Float to hold ( font, height of font in pixels ) pairs. */
lowerPoint.setLocation ( fMinimumFont, getHeightInPixelsOfString ( text, fMinimumFont, gc ) );
upperPoint.setLocation ( fMaximumFont, getHeightInPixelsOfString ( text, fMaximumFont, gc ) );
if ( upperPoint.y < rect.getHeight () )
return font;
for ( int i = 0; i < 50; i++ )
{
float middleFont = ( lowerPoint.x + upperPoint.x ) / 2;
midPoint.setLocation ( middleFont, getHeightInPixelsOfString ( text, middleFont, gc ) );
if ( midPoint.y >= rect.getHeight () * .95 && midPoint.y <= rect.getHeight () )
break;
else if ( midPoint.y < rect.getHeight () )
lowerPoint.setLocation ( midPoint );
else if ( midPoint.y > rect.getHeight () )
upperPoint.setLocation ( midPoint );
}
fMaximumFont = midPoint.x;
font = gc.getFont ().deriveFont ( fMaximumFont );
return font;
}
private float getWidthInPixelsOfString ( String str, float fontSize, Graphics gc )
{
Font font = gc.getFont ().deriveFont ( fontSize );
return getWidthInPixelsOfString ( str, font, gc );
}
private float getWidthInPixelsOfString ( String str, Font font, Graphics gc )
{
FontMetrics fm = gc.getFontMetrics ( font );
int nWidthInPixelsOfCurrentFont = fm.stringWidth ( str );
return (float) nWidthInPixelsOfCurrentFont;
}
private float getHeightInPixelsOfString ( String string, float fontSize, Graphics gc )
{
Font font = gc.getFont ().deriveFont ( fontSize );
return getHeightInPixelsOfString ( string, font, gc );
}
private float getHeightInPixelsOfString ( String string, Font font, Graphics gc )
{
FontMetrics metrics = gc.getFontMetrics ( font );
int nHeightInPixelsOfCurrentFont = (int) metrics.getStringBounds ( string, gc ).getHeight () - metrics.getDescent () - metrics.getLeading ();
return (float) nHeightInPixelsOfCurrentFont * .75f;
}
いくつかの粒状低/高 - -
あなたは、二分探索パターン使用効率を向上させることができる。いずれか1、0.5又は0.25ポイント
たとえば、18で高すぎると思いますか?低すぎる、9に移動しますか? 13.5、低すぎ? 15.75、高すぎますか? 14!
異なる、明白な方法は、長方形に合わせてテキストをビットマップに前延伸していて、その後、ビットマップを縮小するだろう。しかし、理由など手作りのフォントデザインとヒンティングの、右のフォントサイズが最高の見ている結果(最速おそらくないが)。
を生成見つけます所属していません StackOverflow