2010-05-28 27 views

cevap

14

, sen PrivateFontCollection.AddMemoryFont() yöntemini kullanmak gerekir. Örneğin, ben bir kaynak olarak bir yazı adlı dosyayı "test.ttf" eklendi ve şu şekilde kullanılır:

using System.Drawing.Text; 
using System.Runtime.InteropServices; 
... 
public partial class Form1 : Form { 
    private static PrivateFontCollection myFonts; 
    private static IntPtr fontBuffer; 

    public Form1() { 
     InitializeComponent(); 
     if (myFonts == null) { 
      myFonts = new PrivateFontCollection(); 
      byte[] font = Properties.Resources.test; 
      fontBuffer = Marshal.AllocCoTaskMem(font.Length); 
      Marshal.Copy(font, 0, fontBuffer, font.Length); 
      myFonts.AddMemoryFont(fontBuffer, font.Length); 
     } 
    } 

    protected override void OnPaint(PaintEventArgs e) { 
     FontFamily fam = myFonts.Families[0]; 
     using (Font fnt = new Font(fam, 16)) { 
      TextRenderer.DrawText(e.Graphics, "Private font", fnt, Point.Empty, Color.Black); 
      //e.Graphics.DrawString("Private font", fnt, Brushes.Black, 0, 0); 
     } 
    } 
} 

fontBuffer değişken kasıtlı statik olduğuna dikkat etmeyin. AddMemoryFont() kullandığınızda bellek yönetimi zordur, fontun kullanılabildiği ve PrivateFontCollection öğesinin henüz kaldırılmadığı sürece belleğin geçerli kalması gerekir. Bu garantiye sahip değilseniz, Marshal.FreeCoTaskMem() öğesini çağırmamaya dikkat edin; bu, metin bozulmasını teşhis etmenin çok zor olmasına neden olan bir çok genel hatadır. Şanslı olduğunuzda sadece bir AccessViolationException alırsınız. Programın ömrü için geçerli tutmak basit bir çözümdür.

+0

Mükemmel. Mesaj için teşekkürler. – Harsha

+1

@HansPassant: Eğer eklemek istediğim yazı tipi dosyası, '.ttf' yerine '.bin' uzantısına sahip olsaydı. –

+1

Bir şeyler yapmadan önce PInvoke kullanmam gerekiyordu. ['AddFontMemResourceEx'] işlevi (https://msdn.microsoft.com/en-us/library/windows/desktop/dd183325 (v = vs.85) .aspx) kullanılmalıdır ... belki de 'PrivateFontCollection' .AddMemoryFont() ', yazı tipinin sistem belleğinde olmasını bekler. Ayrıca, bunun bir metin kutusunun yazı tipini değiştirmek yerine yazı kutusunun yazı tipini değiştirdiğim bir şey olup olmadığını merak ediyorum. (Ancak 'PrivateFontCollection.AddFontFile()' kullanarak hala PInvoke fonksiyonu olmadan çalıştı). –

İlgili konular