Load font dynamically on runtime

Sometimes you want to be able to keep your fonts in a seperate swf file, a “font library” if you will, that you can load dynamically on runtime. Here’s how to do that in AS3:

The first thing you have to do is create a new flash file to store the font(s). Then, right click the library and select “New Font…”.
newfont

Choose the font you want to embed and give it a name. Any name will do here, as this is only the library name and will not affect our code in any way. I prefer to name the font with the same name as the linkage name I plan to give it.
myfont

Click ok, and then right click the font in the library and select “Linkage…”. Check the “Export for ActionScript” and “Export in first frame” options, give your font the linkage name of your own liking and click OK.
linkage

And now you’re ready. Export the file to swf and there’s your font resource file.

If you want to use that font, you first have to load it into the application domain, and then register it on the global font list using the Font.registerFont function. The textfield can’t display it until it has the embedFonts property set to true and the font name in its textformat.
You can see an example in the following code, ready to be pasted into your frame:

var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
l.load(new URLRequest("MyFont.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));

function onLoaded(e:Event):void {
	// Register the font to the global font list
	Font.registerFont( Class( ApplicationDomain.currentDomain.getDefinition("MyFont")));
	
	myTextField.embedFonts = true;
	// instantiate the font just to get the real font name, or if you know the name before hand you can just hard-code it in here
	var fontName:String = new (ApplicationDomain.currentDomain.getDefinition("MyFont"))().fontName;
	var tf:TextFormat = new TextFormat(fontName);
	// Set the text format for the text already in the text field
	myTextField.setTextFormat(tf);
	// and for future changes
	myTextField.defaultTextFormat = tf;
}

Tags: , , , , , , ,

5 Responses to “Load font dynamically on runtime”

  1. Matt Says:

    Just keep in mind that if you load a SWF that has any of the same fonts in static or dynamic text fields placed at author time, you’ll experience conflicts with any of your runtime loaded fonts. I’ve been battling with this problem for the last two weeks.

    http://blog.nobien.net/2009/06/03/runtime-font-loading-and-static-textfield-conflicts/

  2. Flassari Says:

    This happens because when you assign the font to a static or dynamic text field, a class holding the font (holding only the characters you used in the text fields, or more if you embedded any in the dynamic ones) is generated and put into the application domain. You can not override classes with the same name already in the application domain, so when you load the font file, the font class in it is silently ignored (this applies to all classes you try to override).
    The only workaround I could come up with is breaking (ctrl+b) all the static text fields until they’re just shapes, and putting the font of the dynamic text fields to default system font, and then set the font to the loaded one dynamically on runtime after the font has been loaded.
    Just make sure that the font is not already in use anywhere or it will not be loaded.

  3. Andre Says:

    Thanks for the post, very helpfull. BUT im having issues when i want to load the font SWF files from a http://www.domain.com address

    ie, loading in ‘MyFont.swf’ works well
    loading in ‘http://www.domain.com/MyFont.swf’ does not.

    any ideas on how to solve this?

    thnks.

  4. Flassari Says:

    @Andre, you might be needing a crossdomain.xml file on your website to allow other swfs to access the file.

  5. Dave Says:

    Flassari, thanks for the post, worked well, instead I used the e.target.applicationDomain.getDefinition instead of the ApplicationDomain.currentDomain.getDefinition and it all worked famously! The one line registerFont and the return of the fontName was perfect for me.

    Thanks!