Desire for wealth

Last-Modified: Friday, 19-Sep-2014 09:07:37 JST / PV : 20514256 / Owner : Nihondo

だめちゅんにっき

ひとつ前の記事

Xcodeプログラミング入門 - 3/20 01:10

ひとつ先の記事

ココア図書館 #02 - 縁取り付きの文字列を描画する その2 - 3/25 01:16

3月22日(月)

ココア図書館 #01 - 縁取り付きの文字列を描画する

ココア図書館CV:斎藤千和で人里離れた山の奥にある小さなサイト。そこにはゆかり姫ラブな管理人と、女医ハック狂いの管理人と、Cocoa の勉強を始めた管理人がいるのです(←なんか失敗っぽい)。

というわけで、Cocoa による HackENT の開発を通して、もしかしたら誰かの役に立つかもしれなかったり、再利用できそうなものをまとめていく『ココア図書館』です。

第一回目の今回はカラオケには必須な縁取り文字の書き方です。

ちょっと気を引くために、こんなネタを選んでみました。

縁取り文字の例1 縁取り文字の例2
こんな感じに縁取りされた文字を書くのは結構難儀なんですよ。

#01 - 縁取り付きの文字列を描画する
-(void) writeBorderString: (NSString *) string
                  AtPoint: (NSPoint) point
            withAttribute: (NSMutableDictionary *) fontAttribute
       andBorderAttribute: (NSMutableDictionary *) fontBorderAttribute
              borderWidth: (float) width
/*
    string:描画する文字列
    point:描画開始位置
    fontAttribute:塗りつぶしの属性(NSFontAttributeName、NSForegroundColorAttributeNameのみ)
    fontBorderAttribute:縁取りの属性(NSForegroundColorAttributeNameのみ)
    width:縁取りの幅
*/
{
    NSBezierPath *path = [[NSBezierPath bezierPath] autorelease];
    NSTextStorage *textStorage = [[[NSTextStorage alloc] initWithString:string
                                                             attributes:fontAttribute] autorelease];
    NSLayoutManager *layoutManager = [[[NSLayoutManager alloc] init] autorelease];
    NSTextContainer *textContainer = [[[NSTextContainer alloc] init] autorelease];
    NSRange range;
    float x = point.x;
    float y = point.y;
    unsigned glyphLength;
    
    /* NSLayoutManager(グリフのレイアウトおよび描画、生成)の準備 */
    [layoutManager addTextContainer:textContainer];
    /* NSTextStorage(文字列を保持している)に、レイアウトを適用する */
    [textStorage addLayoutManager:layoutManager];
    /* NSTextContainer(テキストの描画範囲) */
    range = [layoutManager glyphRangeForTextContainer:textContainer];
    
    /* グリフ番号の配列を作成 */
    NSGlyph glyph[range.length];
    glyphLength = [layoutManager getGlyphs:glyph range:range];
    
    /* 縁取りの描画 */
    /* ベジェパスの開始位置を設定 */
    /*(descender:g,j,p,q,yなどベースラインより下に伸びている部分を補正する) */
    [path moveToPoint:NSMakePoint(x,y-[[fontAttribute objectForKey:NSFontAttributeName] descender])];
    /* 縁取りの太さを設定 */
    [path setLineWidth:borderWidth];
    /* 縁取りの角の丸め */
    [path setLineJoinStyle:NSRoundLineJoinStyle];
    /* 縁取りの色を設定 */
    [[fontBorderAttribute objectForKey:NSForegroundColorAttributeName] set];
    /* 得たグリフ番号の配列からベジェパスを作成 */
    [path appendBezierPathWithGlyphs:glyph count:glyphLength
                                          inFont:[fontAttribute objectForKey:NSFontAttributeName]];
    /* ベジェパスを描画 */
    [path stroke];
    
    /* 中身の塗りつぶし */
    /* ベジェパスの開始位置を再度設定(ペン位置を戻す) */
    [path moveToPoint:NSMakePoint(x,y-[[fontAttribute objectForKey:NSFontAttributeName] descender])];
    /* 塗りつぶしの色を設定 */
    [[fontAttribute objectForKey:NSForegroundColorAttributeName] set];
    /* ベジェパス内を塗りつぶし */
    [path fill];
}

キャッチーなネタを選んだら内容が重たくなってしまいました。NSTextStorage に属性付き文字列を格納して、NSLayoutManager でその文字列をグリフ(文字の輪郭とでも言ったらいいのでしょうかね)に変換してレイアウトして、NSTextContainer で描画範囲を確定します。

グリフ番号の配列をもとにしてグリフを得るのですが、最初 NSTextStorage のフォント属性と、描画したいグリフのフォント属性を間違えて設定していたために随分苦労しちゃった。フォントが違えばグリフ番号が違うのも当たり前みたいですね。

さて、この関数ですけど、こんな感じで使います。

    [theImage lockFocus];

/* フォント種類とサイズを指定 */
[fontAttribute setObject:[NSFont fontWithName:@"Osaka" size:fontSize] forKey:NSFontAttributeName];
/* フォントの塗りつぶし色を指定 */
[fontAttribute setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName];

/* フォントの縁取り色を指定 */
[fontBorderAttribute setObject:[NSColor blackColor] forKey:NSForegroundColorAttributeName];

[self writeBorderString:string AtPoint:NSMakePoint(0,0)
withAttribute:fontAttribute andBorderAttribute:fontBorderAttribute borderWidth:10.0];

[theImage unlockFocus];

フォント属性を中身と縁とで分けて設定します。なんかこの辺の使い方は設計ミスった気もするなぁ。

そんなわけでいつまで続くかはめちゃめちゃ不安ですが、とりあえず『ココア図書館』スタートさせます。

今後は、今回みたいなまとまったものじゃなくて、うちの覚え書きみたいなものになっていくと思っていますが、共有できるものはどんどん共有していきたいものですね。とりあえず次回も文字描画がらみかなぁ?

3/22 01:14

このエントリーをはてなブックマークに追加

twitter

最近の記事

Tune-up iTunes 11.1リリース(Mac版 iTunes 11.1対応版) - 9/29 21:47

Tune-up iTunesのiTunes 11.1対応について - 9/26 01:28

HTC J Oneを自炊コミックのために買ってみたら、動画再生がすごかった - 6/ 3 01:35

ファルセット聴くだけで泣くようになってしまった『高垣彩陽 2ndコンサートツアー 〜relation of colors〜 舞浜公演』 - 6/ 2 01:18

「ファンタジーライフ Link!」に備えて、無印「ファンタジーライフ」のDL版を安く買ってレベル上げながら待つのがいいよ - 5/28 00:56

iOS版 JoyHackPlayer テスター募集 & JoyHack System 最新ビルド公開 - 4/28 22:00

Tune-up iTunes の Mountain Lion 対応版をリリース - 7/29 19:49

C81 持ち込みカラオケシステム「女医ハック」頒布〜64bit Intel Mac対応/予約画面更新 - 12/30 19:55

GALAXY Note が 自炊コミックリーダーに最適すぎる - 11/ 6 03:23

Mac/Windows で動く美声時計.Rビューア公開 & 美声時計1,2ビューアを Lion 対応 - 9/25 02:52

さらに以前の記事へ