web-dev-qa-db-ja.com

C#アプリケーションにフォントを埋め込むにはどうすればよいですか? (Visual Studio 2005を使用)

開発中のアプリケーションにTrueTypeフォントを埋め込むための最良の方法は何ですか?基本的に、別のマシンにインストールしたときに、特定のフォントがアプリケーションで使用できることを確認したいと思います。 * .ttfフォントファイルがあり、それを埋め込むか、アプリケーションの実行時に自動的にインストールする方法が必要です。

インストール中にフォントをインストールするようにインストールプログラムを設定する必要がありますか、それともアプリケーションの実行時にフォントを動的にロードできますか?実際、どちらも知っておくと便利です。

このアプリケーションは、.NET 2.0を使用してC#で開発されています。

16
Gary Willoughby

この ブログ投稿 はあなたを助けるはずです。

基本的に、フォントを埋め込みリソースとして追加し、それを PrivateFontCollection オブジェクトにロードします。

15
dommer

これがC#に翻訳されたWillの答えです(未テスト):

PrivateFontCollection pfc = new PrivateFontCollection();

using (Stream fontStream = GetType().Assembly.GetManifestResourceStream("Alphd___.ttf"))
{
    if (null == fontStream)
    {
        return;
    }

    int fontStreamLength = (int) fontStream.Length;

    IntPtr data = Marshal.AllocCoTaskMem(fontStreamLength);

    byte[] fontData = new byte[fontStreamLength];
    fontStream.Read(fontData, 0, fontStreamLength);

    Marshal.Copy(fontData, 0, data, fontStreamLength);

    pfc.AddMemoryFont(data, fontStreamLength);

    Marshal.FreeCoTaskMem(data);
}

paint()メソッドと一緒に:

protected void Form1_Paint(object sender, PaintEventArgs e)
{
    bool bold = false;
    bool italic = false;

    e.Graphics.PageUnit = GraphicsUnit.Point;

    using (SolidBrush b = new SolidBrush(Color.Black))
    {
        int y = 5;

        foreach (FontFamily fontFamily in pfc.Families)
        {
            if (fontFamily.IsStyleAvailable(FontStyle.Regular))
            {
                using (Font font = new Font(fontFamily, 32, FontStyle.Regular))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }
            if (fontFamily.IsStyleAvailable(FontStyle.Bold))
            {
                bold = true;
                using (Font font = new Font(fontFamily, 32, FontStyle.Bold))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }
            if (fontFamily.IsStyleAvailable(FontStyle.Italic))
            {
                italic = true;
                using (Font font = new Font(fontFamily, 32, FontStyle.Italic))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }

            if(bold && italic)
            {
                using(Font font = new Font(fontFamily, 32, FontStyle.Bold | FontStyle.Italic))
                {
                    e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                }
                y += 40;
            }

            using (Font font = new Font(fontFamily, 32, FontStyle.Underline))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
                y += 40;
            }

            using (Font font = new Font(fontFamily, 32, FontStyle.Strikeout))
            {
                e.Graphics.DrawString(font.Name, font, b, 5, y, StringFormat.GenericTypographic);
            }
        }
    }
}
13
Chris Doggett

これよりも簡単です。フォントをリソースとしてアプリに埋め込み、アプリのプロパティ名前空間内の厳密に型指定されたプロパティとしてアクセスできます。しかし、与えられたリンクは良い出発点になるはずです。


VBが無効の場合:

アプリケーションのリソースとしてフォントを追加します。 リソースMyFontLolを呼び出します。このリソースには、Properties.Resources.MyFontLolから(バイト配列として)アクセスできます。

私は以下をテストしていませんが、それは実行可能であるように見えます:

public void LoadMyFontLolKThx()
{
    // get our font and wrap it in a memory stream
    byte[] myFont = Properties.Resources.MyFontLol;
    using (var ms = new MemoryStream(myFont))
    {
        // used to store our font and make it available in our app
        PrivateFontCollection pfc = new PrivateFontCollection();
        // The next call requires a pointer to our memory font
        // I'm doing it this way; not sure what best practice is
        GCHandle handle = GCHandle.Alloc(ms, GCHandleType.Pinned);
        // If Length > int.MaxValue this will throw
        checked
        {
            pfc.AddMemoryFont(
                handle.AddrOfPinnedObject(), (int)ms.Length); 
        }
        var font = new Font(pfc.Families[0],12);

        // use your font here
    }
}

最後にもう1つ。 PFCは、フォントをGDI +フォントとして保存します。これらは、一部のフォームコントロールと互換性がありません。ドキュメントから:

メモリフォントを使用するには、コントロール上のテキストをGDI +でレンダリングする必要があります。 SetCompatibleTextRenderingDefault メソッドを使用してtrueを渡し、コントロールの seCompatibleTextRendering プロパティをtrueに設定して、アプリケーションまたは個々のコントロールでGDI +レンダリングを設定します。一部のコントロールはGDI +でレンダリングできません。

11
user1228