【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

FontSourceによるフォントの取得

SilverlightではSystem.Windows.Documents.FontSourceでフォントを読み込んで描画に使用できます。GDI+のPrivateFontCollectionに相当しますが、Familiesに相当するものがないため、あらかじめフォント名を調べておく必要があります。mplus-2p-black.ttfなら"M+ 2p"、みかちゃんなら"mikachan"です。みかちゃんWindowsで開くと書体名が「みかちゃん」と表示されますが、"みかちゃん"と指定しても認識しません。この辺の勝手が分からなくてハマりました。
GDI+のPrivateFontCollectionでフォント名を列挙するコードは以下の通りです(Silverlightでは使えません)。みかちゃんを調べると"mikachan"ではなく"みかちゃん"と出てくるため、必ずしもSilverlightで認識されるフォント名が取得できるとは限りません。

var ofd = new OpenFileDialog { Filter = "TrueType (*.ttf;*.ttc)|*.ttf;*.ttc" };
if (ofd.ShowDialog() != DialogResult.OK) return;
var pf = new PrivateFontCollection();
pf.AddFontFile(ofd.FileName);
var sb = new StringBuilder();
foreach (var ff in pf.Families) sb.AppendLine(ff.Name);
MessageBox.Show(sb.ToString());

フォントをプロジェクトに追加するとデフォルトのビルドアクションがResourceになります。この状態でXAMLからFontFamily(FontSourceではない)を指定して直接読み込むことができます。ビルドアクションをResourceではなく「埋め込まれたリソース」にすると認識しません。

<TextBlock Text="TEST" FontFamily="mplus-2p-black.ttf#M+ 2p" FontSize="48" />

ビルドアクションをコンテンツにしたフォントを読み込むコードは以下の通りです。コンテンツにしておけばXAPをZIPとして展開するだけでファイルが取り出せて便利です。FontSourceに渡したStreamはDispose()するとエラーになります。

var uri = new Uri("mplus-2p-black.ttf", UriKind.Relative);
var stream = Application.GetResourceStream(uri).Stream;
var tb = new TextBlock
{
    Text = "TEST",
    FontSource = new FontSource(stream),
    FontFamily = new FontFamily("M+ 2p"),
    FontSize = 48
};
LayoutRoot.Children.Add(tb);

外部から取得する方法は以下で詳しく説明されています。ZIPファイルを取得して中身を取り出す方法は興味深いです。