ヘキサ日記 Blog

 

2017年5月15日

フォントのDistanceFieldTexture生成ツールをつくる その4

みなさんこんにちは。

週末にボルダリングに行ったおかげで筋肉痛中のグリフォンです。

 

さて今回も前回の続き「フォントのDistanceFieldTexture生成ツールをつくる」のその4です。

 

大まかな処理の流れは以下

フォントを1文字ずつ読み出してピクセル情報を取得

ピクセル情報からDistance Field情報を生成

CharacterInfoを生成

アトラステクスチャに書き込む

アトラステクスチャとFontSettingsを出力保存

 

 

今回はを説明していきます。(後半戦です)

private bool WriteOutputFontTexture(string writeChar)
{
    var srcPixels = _BufferTexture.GetPixels32();
    var srcWidth  = _BufferTexture.width;
    var srcHeight = _BufferTexture.height;
    var dstPixels = _OutputFontTexture.GetPixels32();
    var dstWidth  = _OutputFontTexture.width;
    var dstHeight = _OutputFontTexture.height;

    while( _OutputPageNo < 4 ) {
        if( dstHeight > _OutputOffsetY + srcHeight ) {
            if( dstWidth > _OutputOffsetX + srcWidth ) {
                // 現在の行に収まる
                {
                    // ピクセルコピー
                    for( int y=0; y<srcHeight; ++y ) {
                        for( int x=0; x<srcWidth; ++x ) {
                            var srcPos = (y * srcWidth) + x;
                            var dstPos = ((_OutputOffsetY + y) * dstWidth) + (_OutputOffsetX + x);
                            switch( _OutputPageNo ) {
                                case 0: dstPixels[dstPos].r = srcPixels[srcPos].a; break;
                                case 1: dstPixels[dstPos].g = srcPixels[srcPos].a; break;
                                case 2: dstPixels[dstPos].b = srcPixels[srcPos].a; break;
                                case 3: dstPixels[dstPos].a = srcPixels[srcPos].a; break;
                            }
                        }
                    }

                    // テクスチャに反映
                    _OutputFontTexture.SetPixels32(dstPixels);
                    _OutputFontTexture.Apply();


                    /** ここに前回の「文字情報を成形」を挟みます **/
                    
                    
                    // 書き込み情報を更新
                    _OutputOffsetX     = _OutputOffsetX + srcWidth;
                    _OutputOffsetNextY = (int)Mathf.Max(_OutputOffsetNextY, _OutputOffsetY + srcHeight); // ←高さが高いオフセットを保存
                }
                return true; // 書き込み成功
            }
            else {
                // 次の行へ
                _OutputOffsetX     = 0;
                _OutputOffsetY     = _OutputOffsetNextY;
                _OutputOffsetNextY = 0;
            }
        }
        else {
            // 次のページへ
            _OutputPageNo++;
            _OutputOffsetX     = 0;
            _OutputOffsetY     = 0;
            _OutputOffsetNextY = 0;
        }

    return false; // 書き込み失敗
}

 

今回のアトラステクスチャはRGBAチャンネルに別々の文字郡を格納していきます。

 

_OutputPageNo が現在の格納先チャンネルを表しています。(0=R, 1=G, 2=B, 3=A)

 

_OutputOffsetX ・ _OutputOffsetY が書き込むピクセルの基準座標になります。

 

そして今回のポイントは、_OutputOffsetNextY です。

_OutputOffsetY が有るにも関わらず、なぜ別に必要なのか

 

それは、文字ごとに高さが違うからです。

今回のアトラステクスチャには、まずX方向に1行ずつ埋めていき、次にY方向に1行ずらしてまたX方向に埋めていきます。

 

そのため、_OutputOffsetY のみだと1行の最後の文字の高さが低い場合、次の行の文字が重なってしまいます。

20170516_ng

 

そこで、1行のうちで最も高い高さを _OutputOffsetNextY に保持して次の行のオフセットとして使います。

20170516_ok

これで文字が重なることはなくなります。

 

今回はここまで。次回はいよいよラストですお楽しみに


ヘキサブログ ピックアップ



過去の日記はこちら

2017年6月
« 5月    
 1234
567891011
12131415161718
19202122232425
2627282930