ひとつ前の記事
1年越しの夢かなう〜ステレオハック開始 - 3/31 01:18
ひとつ先の記事
理奈ザウにっき(4) - 4/ 1 02:50
4月 1日(木)
ココア図書館 #03 - 決められた幅に収まるようにフォントサイズを調整する
CV:斎藤千和で人里離れた山の奥にある小さなサイト。そこにはゆかり姫ラブな管理人と、女医ハック狂いの管理人と、Cocoa の勉強を始めた管理人がいるのです(←もう3回目)。
HackENT で表示される文字列のフォントサイズはまちまちです。例えば、次のような感じです。
これは、決められた幅(この例の場合、ウィンドウの横幅)に対して、はみ出さないようにフォントサイズを調整して描画しているからです。歌詞の行のうちで、最大の長さのものが、折り返さないで画面内に表示できるようにフォントサイズを変えてやるわけです。
上記の例は、曲名表示のスクリーンショットですが、歌詞の表示にもこれは当てはまります。
「ええと、歌詞のなかで一番長い行が何文字だから…、フォントサイズこれだったら画面に収まるかなぁ?」みたいなことを、データ作成者が考えなくてもいいようにしたかったからです。見やすさのためには、できるかぎり大きな文字で表示したいけど、フォントサイズの制御はユーザには意識させないようにという思想です。
あまりいいネタではないですが、また使いそうなので、ここに記しておきます。NSString の sizeWithAttributes を用いて、描画する際の幅を算出しています。
- (float) adjustFontSize:(NSString *)writeStr
withAttribute:(NSMutableDictionary *)fontAttribute maxWidth:(float)maxWidth
/*
writeStr : 描画する文字列
fontAttribute : フォント属性
maxWidth : 文字列をおさめたい横方向のサイズ
*/
{
/* フォントサイズを取り出す */
float fontSize = [[fontAttribute objectForKey:@"NSFontAttributeName"] pointSize] / 10;
/* 指定したフォント属性で文字列を描画したときの幅を求める */
float strWidth = [writeStr sizeWithAttributes:fontAttribute].width;
/* 書いてみたら決められた幅からはみ出してしまうとき */
if( strWidth > maxWidth ){
/* フォントサイズの補正 */
fontSize *= maxWidth / strWidth;
}
return( fontSize );
}
といった感じで、strWidth(描画しようとしている文字列の幅)が、maxWidth(収めたい幅)を超えたときに、フォントサイズを小さくして対応しようというものです。
引数の fontAttribute は例えば以下のように設定します。
[fontAttribute setObject:[NSFont fontWithName:@"Osaka" size:64] forKey:NSFontAttributeName];
Osaka の 64 ポイントで描画したときに 1280 ピクセルの幅になってしまうような文字列があったとして、それを 640 ピクセルに収めたければ、フォントサイズを(640/1280)倍してやればいいという理屈ですね。説明するまでもないか。
亜流としてフォントサイズを変えないで、NSAffineTransform で、アフィン変換をかけるという手もあります。
NSAffineTransform *scaleMatrix;
scaleMatrix = [NSAffineTransform transform];
[scaleMatrix scaleXBy:maxWidth / strWidth yBy:1.0];
[scaleMatrix concat];
こんな風にしておけば、フォントの横方向を縮めて、縦長文字で描画してくれますよね。drawAtPoint で実際に描画するポイントもアフィン変換されることに気をつけておきます。
もうひとつ気をつけることがあって「アフィン変換」じゃなくて、「あひーっ!変換」をすると、描画しようとする文字列はおかしくなってしまうでよ。あひーっ!(←もうやめたほうがいいてすかね)
2004/4/ 1 01:21