カスタムコンテンツプロセッサーを利用した高度な日本語表示を行う

概要

MonoGame のテキスト描画は XNA の時と同じく SpriteFont を利用した描画になります。描画の仕組みも同じで事前にフォント定義ファイル(.spritefont)を作成し、それに基づいてビルドを行い文字列のテクスチャーを作成、そのテクスチャーを描画することになります。

しかしこの方法は XNA の時と同じく、日本語の描画に対しては文字の数の多さから割と厳しい制約になったりします。

ここでは「ひにけにGD」さんのサイトで紹介されている XNA での日本語表示を MonoGame に移植してみたいと思います。

動作環境

Windows
  • Windows Vista
  • Windows 7
  • Windows 8
  • Windows 8.1
  • Windows 10
Visual Studio
  • Visual Studio 2010
  • Visual Studio 2012
  • Visual Studio 2013
  • Visual Studio 2015
MonoGame MonoGame 3.4

動作確認環境

Windows Windows 8.1
Visual Studio Visual Studio 2013
MonoGame MonoGame 3.4

内容

日本語表示について

MonoGame においてのテキスト描画は XNA と同様に SpriteFont を使うことになります。SpriteFont については XNA と同じなので「英数字を表示させる」や「フォントスタイルの詳細」を参照してください。

SpriteFont を使う場合は事前に使う文字を指定しておく必要があります。英数字記号だけであればたかだか100文字程度なので文字指定やビルド時間もほとんどコストなく行えるのですが、日本語となると数千文字となってしまうため、ビルド時間がとてつもなく長くなってしまいます。使う文字だけ指定すればある程度ビルド時間は短縮できますが、逆に使う文字を指定するのが面倒であり、使う文字に変更があった場合はさらに面倒になります。

この問題に対し、「ひにけにGD」さんのサイトでは XNA においての日本語の描画をよりスムーズに行えるようにカスタマイズされています(ちなみにサイト運営されている Yuichi Ito - MSFT 氏は XNA Framework 開発者の一人です)。これを利用すると使う文字の指定が簡単になり、ビルド時間の短縮、文字の装飾などができるようになります。詳しくはリンク先をご覧ください。

WPF フォントプロセッサーで作成されたテキストの描画

しかし、ページ先で紹介されている「WPF フォントプロセッサー」は XNA 用であるため、MonoGame ではそのまま使うことはできません。ですのでこれを MonoGame に移植してみたいと思います。

WPF フォントプロセッサーのダウンロード

以下のサイトを開きます。

ひにけにGD - 真・簡単(かもしれない)日本語表示

下の方にスクロールするとリンクが2つあり、上のリンクをクリックするとソートコードが含まれたプロジェクトがダウンロードできます。下の方は DLL だけですのでダウンロードしなくてもいいです。

プロジェクトをダウンロード

ダウンロードしたファイルは中身を取り出せるように展開しておいてください。

ダウンロードされたファイル

WPF フォントプロセッサーのプロジェクト作成

今回作成する「WPF フォントプロセッサー」の DLL は「Any CPU」で動作するものを作成したいのですが、XNA Framework の「Content Pipeline Extension Library」でプロジェクトを作成するとなぜか x86 でしか作成できないので、ここでは通常のクラス ライブラリから作成します。

クラス ライブラリの作成

プロジェクトを作成したら「Class1.cs」はいらないので削除します。

「Class1.cs」の削除

続いて参照の追加を行います。

参照の追加

WPF でテキストを描画するので、WPF 関連の参照が必要になります。まずは「フレームワーク」から「PresentationCore」にチェックを入れます。

「PresentationCore」にチェック

続いて「WindowsBase」にチェックを入れます。ここでいったん OK ボタンを押して確定し、再度参照マネージャーを開いてください。

「WindowsBase」にチェック

左の「参照」を選択して、下の「参照」ボタンをクリックしてください。

「参照」ボタンをクリック

以下のフォルダパスを開きます。

  • C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools\

そこから以下の2つの DLL を追加します。

  • MonoGame.Framework.dll
  • MonoGame.Framework.Content.Pipeline.dll

2つの DLL を追加

チェックされていることを確認し「OK」ボタンをクリックします。

チェックされていることを確認

追加された参照を確認します。

追加された参照を確認

続いてダウンロードしたプロジェクトから「WpfFontPipeline」フォルダにあるソースコードを現在編集しているプロジェクトに追加します。

ソースコードを追加

追加した状態です。

追加した状態

ビルド構成が「Release」「Any CPU」になっていることを確認します。

ビルド構成が「Release」「Any CPU」になっていることを確認

ビルドを行い、正常にビルドされたか確認します。

ビルド結果

DLL が作成されていることを確認します。

DLL が作成されていることを確認

ゲームプロジェクトの作成

MonoGame のプロジェクトを作成します。プラットフォームはなんでもかまいません。

MonoGame のプロジェクトを作成

先ほど作成した DLL を Content フォルダに入れておきます。DLL の場所はどこでも構わないのですが、その場合相対、または絶対パスが必要になるので、とりあえず今回はここにおきます。

 DLL を Content フォルダに配置

Content.mgcb を開き、「Content」を選択している状態で「References」を開きます。

※「Content.mgcb」をダブルクリックしても開かない場合は、スタートメニューから「MonoGame Plipeline」を起動してください。

References を開く

テキストボックスに先ほど作成した DLL のファイル名、または Content.mgcb からの相対パス、または絶対パスを入力します。

設定後はまだ DLL が反映されないので、いったんプロジェクトを保存、MonoGame Pipeline を終了し、再度開いてください。

DLL のファイル名を入力

スプライトフォントを作成します。メニューから「Edit」→「Add」→「New Item」を選択します。

スプライトフォントを作成

項目の中から「SpriteFont Description」を選択して追加します。(ちなみに SpriteFont を追加した後、実行時に見やすいように SpriteFont のファイルを開いてフォント名とサイズを変更しています)

「SpriteFont Description」を選択

追加した SpriteFont を選択すると、Processor から「WPF フォントプロセッサー」が選択できるようになっていることがわかります。

「WPF フォントプロセッサー」が選択できる

各パラメータが設定できるので、とりあえず今回は図のように設定してみました。残念ながら現バージョンの MonoGame Pipeline では色変更はできません。

各パラメータ設定

ビルドしてみます。JIS第2水準まで含めたので 6860 文字がビルドされました。それでも時間は 9 秒ほどなのでかなり高速化されていることがわかります。

ビルド完了

さて、この SpriteFont を使用して描画するのですが、コードの方は XNA とまったく同じです。「英数字を表示させる」で紹介しているコードをそのまま使えばテキストを描画できます。もちろん日本語も可能です。

一応追加したコードだけ載せておきたいと思います。

フィールドの定義部分です。「SpriteFont」を追加しています。

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

SpriteFont font;

LoadContent メソッド内でフォントデータを読み込み、作成しています。

protected override void LoadContent()
{
  // Create a new SpriteBatch, which can be used to draw textures.
  spriteBatch = new SpriteBatch(GraphicsDevice);

  // TODO: use this.Content to load your game content here

  // フォントデータの読み込み
  font = Content.Load<SpriteFont>("Font");
}

Draw メソッドで日本語を指定して描画しています。

protected override void Draw(GameTime gameTime)
{
  GraphicsDevice.Clear(Color.CornflowerBlue);

  // TODO: Add your drawing code here
  spriteBatch.Begin();

  spriteBatch.DrawString(font, "真・簡単(かもしれない)日本語表示",
                    new Vector2(50, 50), Color.White);

  spriteBatch.DrawString(font, @"・OpenTypeフォント対応
・処理速度の高速化
・JIS漢字追加機能
・文字装飾",
              new Vector2(50, 150), Color.White);

  spriteBatch.End();

  base.Draw(gameTime);
}

実行するとテキストが描画されます。少しわかりづらいですが、文字に枠線がついているのと、中で青のグラデーションがかかっています。

こんな感じで日本語の描画が楽になり、装飾付きの文字も描画できるようになりました。

テキストの描画結果

最後に文字の装飾の色について、MonoGame Pipeline 上では変更できませんが、ファイルを直接開いて変更できるのでその方法を説明します。

プロジェクトをいったん保存して閉じたら「.mgcb」ファイルをテキストファイルで開きます。

「.mgcb」ファイルをテキストファイルで開く

下にスクロールすると対象パラメータに色情報があるのでそこを直接編集してください。

色情報を直接編集

テキストを保存したら再度 MonoGame Pipeline を開きビルドします。実行すると色が変わっていることがわかると思います。

色変更したテキスト

ダウンロード