Dynamically loading fonts using ActionScript 3

Posted on November 1, 2008

Dynamically loading and using fonts in Adobe Flash is surprisingly easy accomplished using AS3. Many people still have no clue about this feature, and to me it’s come in quite useful many times. For example, excluding a couple of fonts from your “main” SWF can shave off 50-150 kb. Perhaps enough to save you the work of creating a traditional wrapper, merely displaying a loader while your application is loading…

So! For the purposes of this tutorial, create a new FLA. Then head in to the library and embed a font. I’m going for Calibri.

Export a font in Adobe Flash IDE.

Export a font in Adobe Flash IDE.

The key fields to remember are the name of your font and the class. In our case, these are “Calibri” and “ThisIsMyFont”.

In a nutshell, we will load the SWF you generate from the FLA. Once loaded, we’ll peep into its context and attempt to find a class called “ThisIsMyFont”. If it can be found, then we’ll try to instantiate and register the class within our current context.

Now, on to the code! Begin by loading your SWF containing the font(s). We’re going to use a simple Loader for the task. Please note the event listener on the loaders contentLoaderInfo as it will be instrumental next.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
var loader:Loader = new Loader();
 
loader.load(
  new URLRequest(
    "fonts.swf"
  )
);
 
loader.contentLoaderInfo.addEventListener(
  Event.COMPLETE,
  onComplete
);

The method below will trigger once the SWF has loaded.

?View Code ACTIONSCRIPT
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
private function onComplete(evt:Event):void {
 
  var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
 
  loaderInfo.removeEventListener(
    Event.COMPLETE,
    onComplete
  );
 
  var appDomain:ApplicationDomain = loaderInfo.applicationDomain;
 
  var thisIsMyFont:Class;
 
  try {
 
    thisIsMyFont = appDomain.getDefinition(
      "ThisIsMyFont"
    ) as Class;
 
  } catch(ex:Error) {
 
    throw new Error(
      "The font could not be found!"
    );
 
  }
 
  Font.registerFont(thisIsMyFont);
 
  trace(
    "Now there are " + Font.enumerateFonts().length + " fonts available"
  );
 
}

If all goes well, you should receive two trace messages indicating the number of available (embedded) fonts before, and after our load.

Remember how I mentioned there were two key fields in the Adobe Flash IDE library panel? We have already used one of them; the class name of our exported font. Now, when we need to use our newly registered font, the font’s name is what we want. As you may know, there are some quirks in Flash when it comes to fonts. So, in order to find out the actual name of the font you have embedded and loaded, just iterate the available fonts once and make a note of the name to use.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
var fonts:Array = Font.enumerateFonts();
 
for(var i:int = 0; i < fonts.length; i ++) {
 
  trace(fonts[i].fontName);
 
}

This will yield a single message in our example: Calibri. That means we can create our TextField using our font and we also know what font name to pass to TextFormat.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var tf:TextField = new TextField();
 
tf.embedFonts = true;
 
tf.defaultTextFormat = new TextFormat(
  "Calibri",
  30,
  0x00
);
 
tf.autoSize = TextFieldAutoSize.LEFT;
 
tf.text = "Hello Dynamically Embedded Font!";
 
tf.rotation = 20;
 
addChild(tf);

Voilá. That’s it! Now you know how to dynamically load and use fonts in Flash. Personally, I always store my font names in static variables so they can be switched out easily later on. It also makes it easier to share fonts across applications consisting of multiple SWF files.

Tags: , , ,

Comments are closed.