tags:

views:

2015

answers:

3

Hi,

I'd like to load a font from an external server and once is loaded (I guess that's necessary) use it to create a few textfields.

I'm trying:

font_uri = new Uri("http://localhost/assets/fonts/wingding.ttf");
bf_helvetica = new FontFamily(font_uri, "bf_helvetica");

TextBlock test_tb = new TextBlock();
test_tb.Text = "This is a test";
test_tb.FontSize = 16;
test_tb.Foreground = Brushes.Red;
test_tb.FontFamily = bf_helvetica;
stage.Children.Add(test_tb);

But it creates the textblock with the default font. Any ideas?

Thanks in advance :)

+2  A: 

If you can load it into a Stream, try using a PrivateFontCollection. Example code in my answer to another question.

EDIT: See System.Net.WebRequest.GetRequestStream, load the URI into a Stream, then load that Stream into the PFC as mentioned in the linked code.

Also, I'd save the file locally, and look for it there first, so you don't have to download it every time you run the program.

EDIT AGAIN: Sorry, not WebRequest.GetRequestStream, you want WebResponse.GetResponseStream(). Here's some sample code to do exactly what you're looking for.

using System;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Net;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace RemoteFontTest
{
    public partial class Form1 : Form
    {
        readonly PrivateFontCollection pfc = new PrivateFontCollection();

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            WebRequest request = WebRequest.Create(@"http://somedomain.com/foo/blah/somefont.ttf");
            request.Credentials = CredentialCache.DefaultCredentials;

            WebResponse response = request.GetResponse();

            using (Stream fontStream = response.GetResponseStream())
            {
                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);
            }
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            using (SolidBrush brush = new SolidBrush(Color.Black))
            {
                using (Font font = new Font(pfc.Families[0], 32, FontStyle.Regular, GraphicsUnit.Point))
                {
                    e.Graphics.DrawString(font.Name, font, brush, 10, 10, StringFormat.GenericTypographic);
                }
            }
        }
    }
}
Chris Doggett
:S Isn't there an easier way?The problem is I can't make it work when I have the font in "Resources", so I am looking for the easiest solution.
ozke
I didn't mean to load it from a resource, but try to figure out how to download your font from the specified URL into some sort of Stream (FileStream, MemoryStream, etc...), and then load it into the PFC. Don't worry about the resource part of the code I linked.
Chris Doggett
A: 

Is the family name you pass to the FontFamily constructor actually a family name exposed by the font file? In your example, if you loaded the Wingding.ttf, the font family name would be Wingdings, not bf_helvetica. If the font file is bf_helvetica.ttf, the family name is likely something other than the name of the font, like Helvetica or Helvetica Bold.

KnownIssues
A: 

Hi, I posted a solution for true type fonts but it could work with other types.

C# HOW TO ADD A TTF TO the project in Visual Studio

http://hongouru.blogspot.com/2010/10/c-how-to-add-fonts-ttf-true-type-fonts.html

I hope it helps.

HoNgOuRu