SWF TextField Factory — Dynamically Loading Fonts in AS3 using Flex SDK 3.4

3 actionscript,as3,as3 tutorials,work  |   December 10, 2009  |     2424

Hi Everyone,

it has been a long while since I wrote! Been busy. Now I have some time and the first thing I did is to get away from the Flash IDE completely. I had been waiting to be able to debug directly in FlashDevelop for a while, tried some extension that didn’t work, then Philippe did actually fix another one and it works beautifully. You can find the link here, look for Version 0.9.7 at the bottom of the first post. Unzip into your FlashDevelop plug-ins folder, restart FlashDevelop and bravo!

So I am Flash IDE Free!! Woohooo. Then the first thing I wanted to master is the Preloader, and FlashDevelop has a very nice “AS3 with Preloader” project template. It is very easy to work with. Very beautiful.

Now the next challenge, loading fonts dynamically. Euh, well, I used to do it from a FLA, was easy. But using the Flex SDK 3.4 it seems that some things changed. After HOURS of playing around, I ended up with the following system:

  • embed the font inside of a swf that contains a Main class + the font class
  • create a function that will spawn textfields already using the font inside this Main class

Although this system has some limitations, it works beautifully.

Why not just use Font.registerFont from the main SWF?
Well, cause it doesn’t work. I manage to get the reference to the fontClass, this font class:

However to my great surprise, this turns out to be a FontAsset class. ok. So FontAsset is derived from Font; so I try to do something like this:

But I get an error, the parameter to registerFont is invalid. Euh? What? So I toy around with the applicationDomain using a LoadContext to ensure the loaded SWF sits in the same domain as my main SWF.. same problem..

weird. Then I try to list embedded fonts from inside of the loaded swf like so:

What do I get? The fonts ARE available in that “context”. Ok. So maybe it doesn’t like the FontAsset class.. how do I get a pure Font class? After some researching, I find this post which describes the “constructor” property of all objects.. cool. This will let you simulate “duplicateMovieClip” if you think about it for a minute.. just like in the old AS2 days. THIS is the ONLY function I miss from AS2. Sometimes I like wasting a whole day on a problem, you might not solve the said problem, but you do find some really cool stuff along the way ;).

So, back to fonts. First add a function inside of the embedFonts.swf code to let me get access to the listed fonts.. like so..

Now I can call this function from the main SWF, get a reference to the Font object that is registered in the child ApplicationDomain and register it in the main SWF’s ApplicationDomain.. you think eh?

uh oh? Error again! Damn. What to do?

Turning Point

After all this mis-understanding between me and the Flex SDK, I thought: “Man, why isn’t it simple like in FLA files?”. Then I thought, if the font is registered in that context, let’s create a textfield in the context, set it’s format properly, and see if it will appear.. It did. Then, I thought, ok, so the TextField works with the proper font, lets try to pull it outside of the loaded SWF and add it to the stage of the main SWF. That worked too… so here you go: perfect base for the Factory pattern..

This is the final solution; with a description of the UTF ranges I use to limit file size.

Other interesting facts I picked up during the day

  • OTF Fonts cannot be embedded.. no matter how hard you try
  • Embedding directly from the TTF gives much smaller file sizes then embedding “System Fonts”
  • You can specify exact characters to be included by using unicodeRange="U+0020-U+002F" as demonstrated up there
  • Fonts have always been a pain in the ass in Flash / ActionScript, no matter what they say
  • This post was really useful!
  • This post (hi Dave!! what’s up?) seems to be obsolete?!?!

Sample usage

First, rename embedFonts.swf to a proper name: arial.swf and put it where it belongs (./lib/fonts folder).

Then add this to your Main class..

Voilà! Source code with FlashDevelop project and everything for the first part can be found here.. Second part, well, if you can’t figure out how to use it (hey, ask questions, I will try to answer), maybe you should be trying some easier tutorials somewhere on the internet first, then once you’ve mastered the basics… come back here!

Last note
If anybody can prove me wrong, LEAVE A COMMENT! thank you.

Hang in there. Much more to come!

Comments

Leave a Reply