Xamarin.Android 文字列の描画

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

1 はじめに

今回は、Xamarin.Androidの文字列描画です。

Xamarin.Androidには、iOSのように器用なNSStringが無いので、文字列も他の図形と同じく、CanvasとPaintを使用して描画することになります。

サンプルは、ViewクラスのDraw()メソッドをオーバーライドしたものになっています。Xamarin.AndroidでViewのサブクラス化がピンとこない場合は、下記をご参照ください。

Xamarin.Android テンプレート(Blank App)

なお、描画に必要な「Paint」の扱い方は、「Xamarin.Androdi 図形(直線)の描画」で紹介したものと同じです。

2 フォント

(1) 規定のフォント

フォントの指定には、Typefaceというクラスが使用されます。 Typefaceには、いくつかの規定値があり、これらを使用すれば軽易にフォント指定ができます。

AndroidDrawString001

public override void Draw(Canvas canvas) {
    base.Draw(canvas);

    using (var paint = new Paint() {
                TextSize = 80,//フォントのサイズ 30pt
                Color = Color.White, //描画色(白)
                AntiAlias = true//アンチエイリアス有効
            }) {


        const string str = "Developers.IO";
       const int h = 100;
        const int x = 70;
        var y = 100;

        //デフォルトのフォント
        paint.SetTypeface(Typeface.Default);
        canvas.DrawText(str, x, y, paint);

        //太字フォント
        y += h;
        paint.SetTypeface(Typeface.DefaultBold);
        canvas.DrawText(str, x, y, paint);

        //等幅のフォント
        y += h;
        paint.SetTypeface(Typeface.Monospace);
        canvas.DrawText(str, x, y, paint);

        //ゴシック体のような「ひげ無しフォント」
        y += h;
        paint.SetTypeface(Typeface.SansSerif);
        canvas.DrawText(str, x, y, paint);

        //明朝体のような「ひげ付きフォント」
        y += h;
        paint.SetTypeface(Typeface.Serif);
        canvas.DrawText(str, x, y, paint);
    }
}

AndroidDrawString002

(2) フォントスタイル

太字・イタリックなどのフォントのスタイルはTypefaceStyleを使用して指定します。

AndroidDrawString003

TypefaceStyleは、TypefaceのCreate()の第2パラメータでセットされます。

//ノーマル
paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.Normal));
canvas.DrawText(str, x, y, paint);

//太字
paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.Bold));
canvas.DrawText(str, x, y, paint);

//イタリック
paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.Italic));
canvas.DrawText(str, x, y, paint);

//太字+イタリック
paint.SetTypeface(Typeface.Create(Typeface.Default, TypefaceStyle.BoldItalic));
canvas.DrawText(str, x, y, paint);

AndroidDrawString004

(3) フォントファイル

AndroidDrawString005

TTFファイルからフォントを取得して利用することが可能です。 次のコードは、Assetsに置いた たぬきフォントのTanukiMagic.ttf を使用して文字列を描画しています。

//フォントファイル(TanukiMagic.ttf)を使用して描画する
paint.SetTypeface(Typeface.CreateFromAsset(Context.Assets, "TanukiMagic.ttf"));
canvas.DrawText("本日は晴天なり", x, y, paint);

AndroidDrawString006

3 属性

Androidでは、文字属性を表現するクラスはありませんが、Paintの機能によって次のような表現が可能です。

(1) 影

PaintのSetShadowLayer()で影を描画します。

var paint = new Paint {
    TextSize = 80, //文字サイズ80pt
    Color = Color.Red, //文字の色(赤)
    AntiAlias = true//アンチエイリアス有効
};
const int x = 70;
var y = 100;

//背景を白色にする
canvas.DrawColor(Color.White);
const int radius = 8;//ぼやけ具合
const int dx = 3;//元の文字からのづれ
const int dy = 3;//元の文字からのづれ
paint.SetShadowLayer(radius, dx, dy, Color.Black);

canvas.DrawText("本日は晴天なり", x, y, paint);

AndroidDrawString007

(2) 中抜き文字

Paint.Style.Strokeで、中抜き文字を表現できます。

var paint = new Paint {
    TextSize = 80, //文字サイズ80pt
    StrokeWidth = 2,//枠線の幅
    Color = Color.White, //文字の色(白)
    AntiAlias = true//アンチエイリアス有効
};
const int x = 70;
var y = 100;

paint.SetStyle(Paint.Style.Stroke);
canvas.DrawText("本日は晴天なり", x, y, paint);

AndroidDrawString008

4 パス上への描画

DrawTextOnPath()を使用すると、設定されたパスに沿った、文字列の描画が可能です。

var paint = new Paint() {
    TextSize = 60, //文字サイズ60pt
    Color = Color.Yellow, //描画色(黄)
    AntiAlias = true//アンチエイリアス有効
};

const int x = 370; //円の中心
const int y = 400; //円の中心
const int radius = 200; //円の半径
const int hOffset = 745;//表示開始のオフセット


// 円のパスを作成
var path = new Path();
path.AddCircle(x, y, radius, Path.Direction.Cw);
//パス上に文字を描画
canvas.DrawTextOnPath("本日は晴天なり", path, hOffset, 0, paint);

AndroidDrawString009

5 文字サイズの取得

文字列を描画する面積を取得したい場合があります。 PaintのMeasureText()を使用すれば、その時のフォントに応じた描画サイズ(ただし横幅のみ)が取得できます。

public override void Draw(Canvas canvas) {
    base.Draw(canvas);

    using (var paint = new Paint() {
               AntiAlias = true,//アンチエイリアス有効
               Color = Color.White //描画色(白)
           }) {

        const int x = 10;
        const int h = 45;
        var y = 40;
        var pt = 40;
        Disp("40ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 50;
        Disp("50ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 60;
        Disp("60ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 70;
        Disp("70ポイントの文字列", x, y += pt + h, pt, canvas, paint);
        pt = 80;
        Disp("80ポイントの文字列", x, y += pt + h, pt, canvas, paint);
    }
}

//文字列と座標及びフォントサイズを指定して描画する
private static void Disp(string str, int x, int y, int pt, Canvas canvas, Paint paint) {
    //文字列のサイズの取得
    paint.TextSize = pt;
    //サイズの取得
    var width = paint.MeasureText(str);
    //文字列の描画
    paint.TextSize = pt;
    canvas.DrawText(str, x, y + pt, paint);
    //サイズの描画
    var s = string.Format("size:{0}", width);
    paint.TextSize = 35;
    canvas.DrawText(s, x, y, paint);
}

AndroidDrawString010

6 まとめ

今回は、Xamarin.Androidの文字列の描画についてまとめてみました。 iOSに比べると、表現力が豊かな気がします。 なお、こちらもXamarin.FormsでBoxViewなどのレンダラー拡張で、必要になるかもしれません。

7 参考リンク


たぬきフォント
Xamarin.Formsで明朝系フォントを使用する
IPAexフォントおよびIPAフォントについて
漢字が使える日本語フォント 無料ダウンロード 50種類
Xamarin.Androdi 図形(直線)の描画
Xamarin記事一覧(SAPPOROWORKSの覚書)