2013-12-14 77 views
0

我使用此代碼加載嵌入字體:標籤不使用自定義字體

PrivateFontCollection pfc = new PrivateFontCollection(); //declared outside this function 

using (Stream fontStream = GetType().Assembly.GetManifestResourceStream("NucWar.BSOD_Font.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事件,並使用此:

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); 
     } 
    } 
} 

太正常工作,字體是畫在表格上5倍,因爲它應該。

所以我覺得很困惑,當我使用此功能:

//Yes, pts is a valid size. eg 16, 20, 22, 30 
private void AdjustFontSize(float pts) 
{ 
    int count = 0; 
    //_yPos is a dict<string, int> that contains the Name of each Label control, and its original Y position 
    // Therefore, Keys contains the Name prop of each label 
    foreach (var lbl in _yPos.Keys)         
    { 
     var con = Controls[lbl] as Label; //Current label 
     FontFamily f = pfc.Families[0]; //Get the font out of pfc. Debugging confirms that f is not null and has a font in it. 

     //Why this no work? It works fine if I use a built in font, like "Times" 
     con.Font = new Font(f, pts, FontStyle.Regular); 

     //Messing with the location prop, still working on it. Probably not important 
     con.Location = new Point(con.Location.X, (int) (_yPos[lbl] + Math.Pow(1.15, (int) pts)*count++)); 

    } 
} 

和標籤字體更改爲Arial,不是我想要的字體。真正困擾我的是,如果我更改con.Font = ...以使用"Times"而不是f它正確更改爲Times字體。最重要的是,我知道字體正確加載,因爲表單正確繪製。通過這個邏輯,我正確地更改字體,並且正確加載字體,所以它應該可以工作。

+0

聽起來很奇怪,你裝的字體有什麼特別之處嗎?我的意思是你可以嘗試另一個字體文件,看看它是否可以工作,控制的默認文本渲染與自定義繪圖與GDI +之間可能有一些區別。 –

+0

據我所知,它只是一個正常的TTF。我給另一個文件去看看會發生什麼。 –

+0

AdjustFontSize方法是通過創建新字體來爲所有標籤設置字體,但是當標籤重新繪製時,您的繪畫邏輯將使用您加載的原始字體。 – ahazzah

回答

0

您需要將UseCompatibleTextRendering設置爲true才能使用不屬於Windows字體庫的本地加載字體。

Label具有2條渲染路徑第一(和默認)是使用不能使用Font對象,並且需要將其轉換成內部格式,並預計實際的字體是在Windows庫GDI渲染。

UseCompatibleTextRendering是真正使用第二條路徑是使用GDI +,通過使用Graphics.DrawString方法並傳入分配給標籤Font看起來很像你的paint方法。

您還可以使用Application.SetCompatibleTextRenderingDefault來設置全局設置而不是每個控件,該默認設置通過WinForms應用程序默認創建,您的Program.cs中已存在該設置。

+0

我沒有意識到這會很簡單。謝謝!這是你承諾的50名代表。 –