0

I've just added a ttf file to the project (c# 2008 express) as "file" and build option to embedded resource.

I'm having problems when trying to set this font like this: (I know the next line is wrong...)

this.label1.Font = AlarmWatch.Properties.Resources.Baby_Universe;

Error 1 Cannot implicitly convert type 'byte[]' to 'System.Drawing.Font' C:\Users\hongo\Documents\Visual Studio 2008\Projects\AlarmWatch\AlarmWatch\Form1.Designer.cs 57 32 AlarmWatch

I know it is byte[] cause I've set the option build as embedded resource, but comparing with this line that is correct:

this.label1.Font = new System.Drawing.Font("OCR A Extended",
                           24F, System.Drawing.FontStyle.Regular,
                           System.Drawing.GraphicsUnit.Point, ((byte)(0)));

How can I set this.label1 to use the new font?

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
HoNgOuRu
  • 239
  • 3
  • 6
  • 12

2 Answers2

2

There is a AddMemoryFont method in the System.Drawing.Text namespace, which loads a font from a memory (it takes a pointer to the memory block, so you'll need to do some unsafe operation to get pointer to your byte array - I found an example here). More about the method on MSDN.

There is also a related StackOverflow question showing how to import Win API function to load the font directly (in case the above .NET method doesn't work).

EDIT A translation of the key part from Visual Basic might look like this (haven't checked it though):

// This should be probably a field of some class
PrivateFontCollection pfc = new PrivateFontCollection();

// allocate memory and copy byte[] to the location
IntPtr data = Marshal.AllocCoTaskMem(yourByteArray.Length);
Marshal.Copy(yourFontArray, 0, data, yourFontArray.Length);

// pass the font to the font collection
pfc.AddMemoryFont(data, fontStream.Length)

// Free the unsafe memory
Marshal.FreeCoTaskMem(data)

Once you have this, you should be able to refer to the font using its usual name.

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • hi, thanks for your answer. I went to that page but, I don't know how to put that code in my application because it is in visual basic and cannot translate it well... – HoNgOuRu Mar 28 '10 at 23:38
  • I get the correct name, size and style...but if I try to set the font to a label it won't do it, it goes back to the default font instead. the line i like this label1.Font = new Font(pfc.Families[0].Name,15f); I placed the lines you gave me in the form_load method, and try to set the label in that block of code right after those lines.... – HoNgOuRu Mar 29 '10 at 02:17
0
private static void AddFontFromResource(PrivateFontCollection privateFontCollection, string fontResourceName)
{
    var fontBytes = GetFontResourceBytes(typeof (App).Assembly, fontResourceName);
    var fontData = Marshal.AllocCoTaskMem(fontBytes.Length);
    Marshal.Copy(fontBytes, 0, fontData, fontBytes.Length);
    privateFontCollection.AddMemoryFont(fontData, fontBytes.Length);
    Marshal.FreeCoTaskMem(fontData);
}

private static byte[] GetFontResourceBytes(Assembly assembly, string fontResourceName)
{
    var resourceStream = assembly.GetManifestResourceStream(fontResourceName);
    if (resourceStream == null)
        throw new Exception(string.Format("Unable to find font '{0}' in embedded resources.", fontResourceName));
    var fontBytes = new byte[resourceStream.Length];
    resourceStream.Read(fontBytes, 0, (int)resourceStream.Length);
    resourceStream.Close();
    return fontBytes;
}
sky-dev
  • 6,190
  • 2
  • 33
  • 32