Dynamic Font Loading

Written by Aaron Clinger on January 10th, 2007

This article originally appeared on the old wiki in early 2007 and addresses font loading in ActionScript 2.0. With the introduction of ActionScript 3.0 there are quite a few simple techniques to load fonts and we found that FontManger was no longer needed.

If you wish to load fonts in AS3 you can do so with SwfLoad and external asset classes.

Many large flash projects or multilingual sites are prime candidates for dynamic font loading and switching. Unfortunately this is not as easy as a loadMovie call. Flash makes it close to impossible to accomplish. So hard in fact that there are costly Flash components to handle this need. Hold onto your money; after reading this article you will be able to dynamically load fonts for free.

As you can see above, dynamic font loading in Flash/ActionScript 2.0 is possible. Click on a font name to load it in! The great advantage of CASA Lib’s implementation is the ability to define which characters you embed (as opposed to embedding an entire font face). It also allows the use of non true type fonts.

The Trick (Hack)

Getting Font loading to work in Flash is really a hack. It is complicated to set the files up, but CASA Lib has made the code aspect simple, quick and elegant.

Please note: This is also fairly well covered in the FontManager class.

Setting Up Your Files

To create an externally loadable Font resource please use the following steps:

  1. Create a new FLA file and name it yourFontDesc_lib.fla.
  2. On the root of yourFontDesc_lib.fla create a dynamic TextField.
  3. Choose a typeface and embed all characters you want to include. Include “Basic Latin” for this example.
  4. Enter some text into the TextField. This is required to have the font successfully register. It is recommend to enter the font name into the field.
  5. Give the TextField an instance name of font_txt.
  6. Convert the TextField to a symbol, give it a name of myFont, and make sure its type is MovieClip.
  7. Make sure “Export for runtime sharing” is checked under Linkage, and give it an identifier of myFont.
  8. In the URL field type [yourFontDesc_lib].swf (Univers_55_lib.swf in the screenshot below). This path is relative to the HTML file that your shell SWF will be loaded into, so change the path in this URL field if necessary.
  9. Click OK to apply these changes to the symbol.
  10. Publish this file and save it. You can now close this FLA.
  11. Create a new FLA and name it yourFontDesc.fla.
  12. In yourFontDesc.fla create a new symbol, give it a name of myFontContainer, and make sure the type is MovieClip.
  13. Check “Import for runtime sharing” under Linkage, and give it an Identifier of myFontContainer.
  14. In the URL field type the same URL you used in the [yourFontDec_lib].fla URL field (Univers_55_lib.swf in the screenshot below). It actually doesn’t matter what you type here, because it will automatically update with the correct value (even if it gives you an error) once you complete the next few steps.
  15. Under Source click the browse button and find yourFontDesc_lib.fla and click Open.
  16. Select source symbol myFont and click OK.
  17. Click OK to apply these changes to the symbol.
  18. Make sure the the symbol is on the main stage at the root level and give it an instance name of fontContainer_mc.
  19. On a frame at the root place the following code (REQUIRED):
    import org.casalib.load.media.font.FontManager;
    FontManager.registerFont("myFontRefrenceName", this.fontContainer_mc.font_txt, this, true);
    
    Please also read the documentation for registerFont. If you are concerned about the extra file size added by the FontManager class, you can compile against an intrinsic class for your external font SWFs.
  20. Publish this file and save it. You can now close this FLA.

Implementing the Code

First let’s explain the ActionScript you added to your external font SWF:

referenceName
The unique reference name of your font. This can be any name of your choice. You will need this name later to assign the typeface to a TextField.
field
TextField with the embedded font.
sender_mc
Reference to the external SWFs root/shell; if this code is on the top timeline sender_mc should be this.
isLastRegister
[optional] Indicates it’s the last font registered true, or that there are other fonts left to register false; defaults to false. This is used when registering multiple fonts in the same file. You only set true on the last register so FontManager knows when it can clean up and unload the SWF.
Returns
Returns true if parameter sender_mc was referenced correctly and the font was successfully registered; otherwise false.

The hardest parts are over. Let’s create a final FLA, name it shell.fla. In shell.fla on root timeline enter the following code:

  1. First we need to import the FontManager class into our Flash shell (the SWF loading the fonts):
    import org.casalib.load.media.font.FontManager;
  2. Before we can start the load process we will create a dynamic TextField:
    this.createTextField("headline_txt", this.getNextHighestDepth(), 10, 10, 250, 250);
    this.headline_txt.multiline = this.headline_txt.wordWrap = this.headline_txt.border = true;
    this.headline_txt.type = "input";
    var myFormat:TextFormat = new TextFormat();
    this.myFormat.size = 20;
    this.headline_txt.setNewTextFormat(myFormat);
    this.headline_txt.text = "Lorem Ipsum.";
    
  3. Now we create a new FontManager object, passing in the path to the SWF font wrapper containing the code we entered above:
    var fontLoad:FontManager = FontManager.loadFont("yourFontDesc.swf");
  4. We add an event observer so we know when the font has successfully loaded and registered: (See documentation for all dispatched events)
    this.fontLoad.addEventObserver(this, FontManager.EVENT_FONT_REGISTER, "onFontRegister");
  5. Now let us create the function that handles the event:
    function onFontRegister(refrenceName:String, fontTextFormat:TextFormat):Void {
    	FontManager.applyTextFormatByReferenceName(refrenceName, this.headline_txt);
    }
    
    The function uses the applyTextFormatByReferenceName method to apply the Font to a TextField with an instance name of headline_txt. FontManager automatically determines if the font is a System Font (_sans, _typewriter or _serif) or a non-system font and sets the embedFonts property of the TextField accordingly.
  6. Now all we have to do is start the font load process:
    this.fontLoad.start();

You should see the TextField with containing “Lorem Ipsum.” set in the typeface you just loaded.

Caveats

If any static/dynamic embedded text field in the flash movie uses the same font as the font you’re trying to load, that font will not be properly registered. This is true for any dynamic font loading and is due to a limitation in Flash and not CASA Lib. Note that this will not generate any error messages. Even though the font loads appear to register properly, they will fail silently. The solution is to not use any fonts in static text fields that you want to load or breaking apart the static text fields into shapes.

Conclusion

This article only covers the basics of FontManager. There are additional options and functions we did not cover. This example should serve as a great start to creating robust, dynamic font loading solutions.

Comments

Written by Sergio Daroca on July 13th, 2009

Hi !
Nice framework-lib, class and tips, but I wonder
Can this technique be used with CSS and styleSheets?

Written by Aaron Clinger on July 14th, 2009

Sergio,

Yes you are able to use CSS/style sheets with this AS2 technique.

You need to make sure FontManager has loaded the fonts before trying to apply a style sheet that references those fonts. You can reference the font in the style sheet by it’s true font name (the name that is displayed in the font properties menu), just like how you would if the font was embedded in the same SWF. If you are creating the style sheet object at run time you can get the font name directly from font manager like this:

trace(FontManager.getTextFormatByReferenceName("myFontRefrenceName").font);

Written by Williams on November 14th, 2009

A sample or where purchase the code, I use AS2, and at now not is possible for my learn AS3, and this code I need, not is possible a working example???

Written by Williams on November 14th, 2009

A sample with source code, of course… Sorry

Written by Williams on November 14th, 2009

Well, I download from http all the files, decompile, and at now woek, very thanks for this code, excellent!!! Is really very difficult to load dinamically external embedded fonts, nice code, very nice…

Thanks…

Written by cheryl on November 30th, 2009

Is there a work around to applying a font after the css has been applied to the text box? I see the css and the font working when the css is applied afterwards. I would like the option to be able to change the font even after the css has been applied.

Written by Aaron Clinger on December 30th, 2009

Hi Cheryl: You will have to apply the CSS again or wait until the fonts have been loaded for them to display. But you can easily switch fonts by either using applyTextFormatByReferenceName again with a different reference name, or applying a stylesheet with the new font (I explain this a bit in my comment response to Sergio above). I hope that helps.

Written by Tobias on April 3rd, 2010

Can you please explain how to get the fonts in an AS3 project? All you mention is that i’m supposed to use the SwfLoad object. But how am I supposed to go on from there? It’s not as easy as just creating a class reference. What am I supposed to do with the SWF that I’m loading. Do i need to embed something there…???

Even though i love this framework, your documentation could definitely do with some examples.

Written by Aaron Clinger on April 3rd, 2010

CASA Lib provides documentation and examples for all it’s classes, but doesn’t give documentation for common programming tasks/techniques outside CASA Lib’s scope. I did a web search on your behalf and found a great screencast on how to embed fonts into a SWF: http://www.gotoandlearn.com/play?id=102 Once you have followed those steps you can use SWFLoad to load the font library into your main shell SWF. Good luck.

Written by tom on April 28th, 2010

there is one problem if i want to load two fonts with the same font family and different style, for example i prepared font ‘Helvetica’ style ‘Normal’ and ‘Helvetica’ ‘Bold’ (in thwo different sets of course) and after load the fonts the ‘Normal’ is replaced with the bold version, if the font family is different it is working fine - for example if for the bold vesrion using ‘Helvetica new’ and style bold

Written by gmae on June 21st, 2010

Do you know Rappelz Rupees? If you are a better gamer, I think you want to get much rappelz gold.

Written by Greg on July 5th, 2010

How can I get the basic utils loaded?  Flash can seem to find the as files after I’ve extracted them.

Written by Frederik on November 9th, 2010

Hello CasaLib,

what I don’t understand is the runtime-shared-libary thing. Can’t I just load an extrnal swf, reference a textfield in it which has a font embedded, and then assign the textformat of this textfield to a newly created textfield?

Why is it necessary to use runtime shared libraries?

Thanks

Frederik

Comments are no longer accepted for this blog post.