Embedding fonts on the fly in AS3

Lots of posts out there talking about runtime font embedding (first one i saw and thought was intelligent was Scott G Morgan’s breakdown and explaination: http://www.scottgmorgan.com/blog/index.php/tag/fonts/).

My issues came up when using Flash instead of Flex to embed fonts at runtime. Why use Flash at all you ask? Hmm, not sure really, but in general I like to timeline some stuff so it’s more convienient to just have Flash runnig instead of Flex and Flash at the same time (that, and LOTRO of course =).

Also, i wanted the leanest most compact swf file i could get, and i wasn’t sure that Flex would exclude all it’s frameworks from the swf when i compiled so i stuck with Flash for now.

So, anyway, all good fonts load in and work etc, but an interesting thing happened on the way to the colloseum, stylesheets wouldn’t work with fonts that were working fine in textformats. Now, Scott does mention some specifcs about naming etc in Flex, but i figure that the majority of the world still is Flash based, so a general guideline to how to do it properly and have it work every time is important as a reference (because Lord knows, in a few months i’ll forget how this worked).

First of all, you need a swf with a font (or fonts) embedded as symbols in the library. You can have lots of font symbols but in general you should separate the fonts out and only load the ones you need at runtime, that way you can create a lean experience for the clients as they access your site.

This all relates to my opensource templating engine called “Daelgren”, so in general using a product like Daelgren solves these issues for you but some folks like to do things for themselves.

Forming the font symbol:

*****One very important note! The name and class must match, but the Font (True Font Name) cannot match the Name/Class name, otherwise you will not get the font to appear in stylesheeted text fields (for some reason this does work fine in TextFormatted fields)!****** In my examples I’ve used two underscores to uniquely name the font, but use any convention you like as long as the name doesn’t match the Font Name.

Properties Dialog

Properties Dialog

 

Linkage Dialog

Linkage Dialog

 

 

 

 

 

 

Save the file and produce the swf from this file.

In your main application you would use code like this to set up your movie to use external fonts:

In Flash, on the first frame, create some timeline code to load the font in at runtime:

var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.INIT, onLoaderInit );
loader.load( new URLRequest( “eurostile.swf” ) );

function onLoaderInit( event:Event ):void {
 var domain:ApplicationDomain = loader.contentLoaderInfo.applicationDomain;

// THIS VALUE IS FROM THE LINKAGE DIALOG CLASS DEFINITION
 var fontClass:Class = Class( domain.getDefinition( “__eurostile” ) );
 Font.registerFont( fontClass );
 loader.contentLoaderInfo.removeEventListener( Event.INIT, onLoaderInit );
 loader.unload();

// THIS LISTS ALL THE CURRENT FONTS REGISTERED FOR USE IN THE APPLICATION, IN THIS CASE WE ONLY HAVE ONE LOADED THUS THE USE OF [0] TO GET THE FIRST FONT 
var fonts:Array = Font.enumerateFonts();

 var myTextFormat:TextFormat = new TextFormat();
 myTextFormat.font = fonts[0].fontName;
 myTextFormat.size = 24;
 trace(“fontname:”+fonts[0].fontName);
 var myTextField:TextField = new TextField();
 myTextField.autoSize = TextFieldAutoSize.LEFT;
 myTextField.defaultTextFormat = myTextFormat;
 myTextField.embedFonts = true;
 myTextField.text = “The quick brown fox jumped over the lazy dog.”;
 myTextField.x = 0;
 myTextField.y = 0;
 addChild(myTextField);
 

// FOR AN EXTERNAL STYLE SHEET YOU’LL NEED TO DEFINE THE fontFamily NAME AS THE TRUE FONT NAME (in this example:’Eurostile LT Std’);
 var myStyleSheet:StyleSheet = new StyleSheet();
 myStyleSheet.parseCSS(“.fontclass {color: #FF0000;fontFamily: “+fonts[0].fontName+”;fontSize: 24pt;letterSpacing: 0;marginLeft: 0;}”);
 var myStyleField:TextField = new TextField();
 myStyleField.autoSize = TextFieldAutoSize.LEFT;
 myStyleField.styleSheet = myStyleSheet;
 myStyleField.embedFonts = true;
 myStyleField.border = true;
 myStyleField.text = “<p class=’fontclass’>The quick brown fox jumped over the lazy dog.</p>”;
 myStyleField.x = 0;
 myStyleField.y = 30;
 addChild(myStyleField);
}

This sample shows how to use both TextFormat and StyleSheets to set the correct values. In general, when referencing the font in your text field formats, always use the ‘true’ font name (in this case ‘Eurostile LT Std’), but when loading a font class from an external file always use the linkage name (set in both the properties and linkage dialogs in flash).

If you need more information please contact me and i’ll help you out.

Tip of the hat to Michael Heu, who’s sample code i snagged portions of for this example.

About Bela Korcsog

Proud father of two children, happy husband to one wife. I've been programming various technologies and leading the development of huge projects for most of the last ten years. I've got some specific likes and dislikes through my experiences in the web site business but generally I'm pretty straightforward about it. Not a huge fan of the latest and greatest shiny toy (it took me four years to show an interest in Flash) I'm more than happy to code in any language that comes along (Actionscript is just so darn fun).
This entry was posted in Flash. Bookmark the permalink.

5 Responses to Embedding fonts on the fly in AS3

  1. Kim says:

    Hi,

    nice work! But with this example you can’t define the characterset. flash will only include the glyphs of the font, related to your current language setting on your system. If you want to create a swf with a japanese character set, you have to switch your system to japanese. Is this right, or is there a workaround for that?

    Kind regards,
    Kim

  2. admin says:

    Hi Kim,

    There’s two things to try with creating a font instance, and one is a workaround. In the Flash file, you can create a TextField on the stage and add the character sets to that text field, make sure the textfield’s font is set to the font instance name in your library (denoted by the “*” in the name). This *should* work, but if it doesn’t try to use the original font name instead of the font instance name. This is more of a fluge rather than a real solution.

    A more realistic solution is to create the font instance using the Flex SDK and use CSS to embed the required font into the swf generated:

    @font-face {
    src:url(”../assets/MyriadWebPro.ttf”);
    fontFamily: myFontFamily;
    flashType: true;
    unicodeRange:
    U 0041-U 005A, /* Upper-Case [A..Z] */
    U 0061-U 007A, /* Lower-Case a-z */
    U 0030-U 0039, /* Numbers [0..9] */
    U 0020-U 002F, /* Punctuation */
    U 003A-U 0040, /* Punctuation */
    U 005B-U 0060, /* Punctuation */
    U 007B-U 007E; /* Punctuation */
    }

  3. Peter says:

    That doesn’t work!

    There’s two things to try with creating a font instance, and one is a workaround. In the Flash file, you can create a TextField on the stage and add the character sets to that text field, make sure the textfield’s font is set to the font instance name in your library (denoted by the “*” in the name). This *should* work, but if it doesn’t try to use the original font name instead of the font instance name. This is more of a fluge rather than a real solution.

  4. Leandro says:

    @Admin — Thanks for all the unicode ranges (especially the punctuation)

  5. Leandro says:

    Here are some more specific options:

    U+0020-U+007E – all cases, numbers + punctuation
    U+0041-U+0039 – all cases + numbers
    U+0020-U+007E – all punctuation
    U+0041-U+007A – all cases
    U+0030-U+0039 – all numbers (0-9)
    U+0041-U+005A – Upper-Case (A-Z)
    U+0061-U+007A – Lower-Case (a-z)
    U+0020-U+002F – Punctuation
    U+003A-U+0040 – Punctuation
    U+005B-U+0060 – Punctuation
    U+007B-U+007E – Punctuation