Flash AS3 Loading Fonts

May 13th, 2008 By: dan

Create a Flash AS3 application that loads an external font at runtime… Sounds easy enough… But it is a little tricky. I needed to create a flash app that allowed users to choose a font from a list and load that into a player. I wanted to offer several fonts but did not want to bloat the load-time with unused fonts. I could not find much help on this topic… Luckily I found betriebsraum and with that I was able to hack up something that worked for me.So here is what i did:step 1: Created an external swf with the font I needed. (I created separate ones for each font I was going to offer.)

  • Created a new Fla and add a font to the library.
  • In the Library pane(F11), click the options dropdown, and choose ‘New Font’
  • Select a font, size and style–size is not important ( arguably)–however, I believe you will have to create separate fonts for each style you require. The name is not important really either.
  • Right click the new font in the Library and select ‘Linkage…’
    • Check ‘Export for ActionScript’ and ‘Export in first frame’.
    • Give it a Class:–this name is important and you will need to remember it. I used ‘EFont01′ fig. 1
    • Linking
  • Publish the swf as ‘/font-Fontname.swf’.

Step 2: Create the Application:

  • Create a new Flash CS3/As3 application set the Document class as ‘Main’ and save it as ‘/myapp.fla’
  • Create a new AS3 script and save it as ‘/Main.as’

Main.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package {
 	import flash.display.Sprite;
 	import flash.text.*;
 	import flash.events.*;
 	public class Main extends Sprite {
 	 	var t:TextField = new TextField();
 	 	var f = new TextFormat();
 	 	public function Main() {
 	 	 	var font = new LoadFont("font-Zapfino.swf",["EFont01"]);
 	 	 	font.addEventListener(LoadFont.COMPLETE, successLoadFont);
 	 	 	font.addEventListener(LoadFont.ERROR, failLoadFont);
 	  	}
 	 	private function failLoadFont(e:Event){
 	 	 	f.font="Arial"; //default font if load fails.
 	 	 	t.embedFonts = false;
 	 	 	post();
 	 	}
 	 	private function successLoadFont(e:Event){
 	 	 	var embeddedFonts:Array = Font.enumerateFonts(false);
 	 	 	f.font=embeddedFonts[0].fontName;
 	 	 	t.embedFonts = true;
 	 	 	post();
 	 	}
 	 	public function post(){
 	 	 	f.size = 36;
 	 	 	t.defaultTextFormat = f;
 	 	 	t.x = 100;
 	 	 	t.y = 100;
 	 	 	t.background = true;
 	 	 	t.autoSize = TextFieldAutoSize.LEFT;
 	 	 	t.text = "We are in loaded Font";
 	 	 	addChild(t);
 	 	}
 	}
}
  • Create a new AS3 script and save it as ‘/LoadFont.as’

LoadFont.as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package {
 	import flash.display.*;
 	import flash.events.*;
 	import flash.text.*;
 	import flash.errors.*;
 	import flash.system.*;
 	import flash.net.*;
 	public class LoadFont extends EventDispatcher {
 	 	public static const COMPLETE:String = "complete";
 	 	public static const ERROR:String = "error loading font";
 	 	private var loader:Loader = new Loader();
 	 	private var _fontsDomain:ApplicationDomain;
 	 	private var _fontName:Array;
 	 	public function LoadFont(url:String,fontName:Array):void {
 	 	 	_fontName = fontName;
 	 	 	trace("loading");
 	 	 	loader.addEventListener(IOErrorEvent.IO_ERROR, font_ioErrorHandler);
 	 	 	loader.contentLoaderInfo.addEventListener(Event.COMPLETE,finished);
 	 	 	loadAsset(url);
 	 	}
 	 	private function loadAsset(url:String):void {
 	 	 	var request:URLRequest = new URLRequest(url);
 	 	 	loader.load(request);
 	 	 }
 	 	function finished(evt:Event):void {
 	 	 	_fontsDomain = loader.contentLoaderInfo.applicationDomain;
 	 	 	registerFonts(_fontName);
 	 	 	dispatchEvent(new Event(LoadFont.COMPLETE));
 	 	}
 	 	function font_ioErrorHandler(evt:Event):void {
 	 	 	dispatchEvent(new Event(LoadFont.ERROR));
 	 	 }
 	 	public function registerFonts(fontList:Array):void {
 	 	 	for (var i:uint = 0; i < fontList.length; i++) {
 	 	 	 	Font.registerFont(getFontClass(fontList[i]));
 	 	 	}
 	 	}
 	 	public function getFontClass(id:String):Class {
 	 	 	return _fontsDomain.getDefinition(id)  as  Class;
 	 	 }
 	 	public function getFont(id:String):Font {
 	 	 	var fontClass:Class = getFontClass(id);
 	 	 	return new fontClass    as  Font;
 	 	}
 	}
}

5 Responses to “Flash AS3 Loading Fonts”

  1. Patrick Bay Says:

    Fonts are a tricky thing in ActionScript but they’ve come a long way in ActionScript 3.
    One of the best new additions for dealing with dynamic fonts is the ability to search for them dynamically in memory space. Here is some code that would complement the example shown here; it retrieves a font dynamically at runtime, allowing you to get a list of available fonts and then use one of them for a text field:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    public function setFont(fontName:String, field:TextField) {				
    	//Use two methods to find the associated font. 
    	//Step 1: Search through enumerated fonts, including system fonts for a match:			
    	var realFontName:String=new String();
    	var fontArray:Array=Font.enumerateFonts(true);
    	for (var item in fontArray) {
    		if (fontArray[item].fontName==fontName) {
    			realFontName=fontArray[item].fontName;
    			break;
    		}//if
    	}//for
    	//Step 2: If not found, try getting it via a linkage through the class definition:
    	if ((realFontName=='') || (realFontName==null)) {
    		try {
    			var fontClass:*=getDefinitionByName(fontName);
    		} catch (err:ReferenceError) {
    			//There was an error...no such font found!
    			return;
    		}//catch
    		var tempInstance=new fontClass();
    		realFontName=tempInstance.fontName;				
    		tempInstance=null;
    	}//if			
    	var format:TextFormat = new TextFormat();
    	format.font=realFontName;
    	field.embedFonts=true;
    }//set font

    This method will attempt to find the font based on the name and assign it to the specified text field instance. All that remains after that is simply to set the text in the field!

    To retrieve a list of available fonts, the magic line of code is: var fontArray:Array=Font.enumerateFonts(true);

    Note that the method being invoked is a singleton so no Font instance is required.

    For more tips, tricks, tutorials, and expert-level advice on ActionScript 3, visit http://www.peabee.com/

  2. Patrick Bay Says:

    …slight update, the method name should be “setFont”, not “set font” (it was copied from an existing class and was originally used as a setter).

  3. admin Says:

    Patrick - I’ve edited your code block with the update you mentioned, and wrapped it in code tags for readability.

  4. John Breakey Says:

    I found your article very interesting. I do have one question.
    Are loaded fonts able to be used by SWF’s on other pages other than the webpage the font was loaded on.

  5. The Field » Archive » Loading fonts at runtime in Flash Says:

    [...] Looks useful - if you like this kind of thing Add to your fave social site: [...]

Leave a Reply