Skip to Content »

FlashApe » Dynamically loading fonts at runtime

 Dynamically loading fonts at runtime

  • May 21st, 2008
  • 3:36 pm

Had a crazy time with this one...mostly, I think, due to FlashPlayer's security mechanisms, which was making it a little difficult to test locally.

Anyway, I created the font swfs using flex, since that would allow me to set select a range of fonts to embed, as opposed to using a font library asset in a CS 3 swf, which doesn't.

Creating the font swf in Flex is mega-easy. What i did was set up a project in FlexBuilder named 'Fonts', then created another runnable Application class that matches the name of the font. By the way, Scott Morgan's article on YDN was where I got most of this from. I just changed a couple of small things from his article.

Here's the entire AS class that I used to export the font. This class declares the fonts as embedded assets and gives the font assets a class name. In the constructor for the class, the font is registered with the flash.text.Font class using Font.registerFont(fontClass). That's it.

ArialNarrow.as

Actionscript:
  1. package
  2. {
  3.     import flash.display.Sprite;
  4.     import flash.text.Font;
  5.     import flash.system.Security;
  6.    
  7.     public class ArialNarrow extends Sprite
  8.     {
  9.        
  10.         /**
  11.          *  Embed the fonts in all of their different variations that we want to have accessible.
  12.          *  Remeber that bold is a 'fontWeight' and italic is a 'fontStyle'.
  13.          *  The unicode range is the basic Latin 1 character set.
  14.         */   
  15.         [Embed(source='assets/Arial Narrow.ttf', fontFamily='Arial Narrow', fontName='Arial Narrow', fontWeight="normal", mimeType="application/x-font-truetype", unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E')] 
  16.       public static var ArialNarrow:Class
  17.      
  18.       [Embed(source='assets/Arial Narrow Bold.ttf', fontFamily='Arial Narrow', fontName='Arial Narrow',  fontWeight="bold", unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E')] 
  19.       public static var ArialNarrowBold:Class;
  20.      
  21.       [Embed(source='assets/Arial Narrow Italic.ttf', fontFamily='Arial Narrow', fontName='Arial Narrow',  fontStyle='italic', unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E')] 
  22.       public static var ArialNarrowItalic:Class;
  23.      
  24.       [Embed(source='assets/Arial Narrow Bold Italic.ttf', fontFamily='Arial Narrow', fontName='Arial Narrow', fontWeight="bold",  fontStyle='italic', unicodeRange='U+0020-U+002F,U+0030-U+0039,U+003A-U+0040,U+0041-U+005A,U+005B-U+0060,U+0061-U+007A,U+007B-U+007E')] 
  25.       public static var ArialNarrowBoldItalic:Class;
  26.            
  27.         public function ArialNarrow()
  28.         {
  29.             super();
  30.             Security.allowDomain("*");
  31.             registerFonts();
  32.         }
  33.        
  34.         /**
  35.          *  Flash keeps a table of fonts available for embedding.
  36.          *  In order to let Flash know that we have loaded a new font
  37.          *  available for embedding, we need to register that font's class reference
  38.          *  with the Font class.
  39.          *
  40.          */  
  41.         public function registerFonts():void{
  42.             Font.registerFont(ArialNarrow)
  43.             Font.registerFont(ArialNarrowBold)
  44.             Font.registerFont(ArialNarrowItalic)
  45.             Font.registerFont(ArialNarrowBoldItalic)
  46.         }
  47.        
  48.     }
  49. }

Couple of notes about the embed metadata tags. First, i had to set the fontFamily attribute to the name of the font as I was going to use it in the app. I was using HTML text, so <font face="Arial Narrow" ... ></font> worked fine. Also, as noted in the comments in the class, when embedding multiple variations of the same font, keep in mind there is a distinction between 'fontWeight' and 'fontStyle'. Don't try to declare 'bold' as a fontStyle or you will get errors like 'exception during transcoding: Font for alias with bold weight was not found at:'.

Another hugely important thing to note is that in the swf in which you are loading the fonts into, there can be no references to the font already. If you have text fields on stage or anything that use that font, it won't work. I had to go back and set all my text fields to use _sans. Once I removed all references to the font, the loaded font showed up. I use Charles debug, and it was through that which I actually found out I had the font reference in the main swf. If you click on the swf in the structure pane, then click on the response tab up top, it gives you a breakdown on the fonts that are in your swf (there's a 'swf' tab on the bottom once you are looking at the response window, the info about the swf is in there).

5 People had this to say...

Gravatar
  • Xilver
  • May 22nd, 2008
  • 1:43 am

Nice writeup, helped me out a lot. However, I seem to have a problem, and I hope you can help me out, since documentation on this is really hard to come by.

Some of our customers are Fortune 500 companies, and as such, most of the content needs to be translated into a lot of different languages, so you can imagine the character set horror we come across :)

Often, the designers need to add extra characters to a specific font, and when they do that, they create a new font based on the original, and call it for example X_Arial. We make sure that in that case, the font family is the same for all subsets of that font. However, even though X_Arial, X_Arial Bold, X_Arial Italic,... all have X_Arial as font family, Flex will still treat them as separate fonts, unlike when you use the normal Arial.

I have opened the fonts in High-Logic Font Creator, but I can see no differences. I would assume if they have the same family, they would be counted as one font?

Gravatar
  • rich
  • May 22nd, 2008
  • 9:11 am

hmm...that's a little bit of a tough one for me without getting my hands on it to play with it. Are you using CSS in Flex to style the text? Can you post some more specific info about how you're defining/using the loaded fonts?

Gravatar
  • ljones
  • May 27th, 2008
  • 10:00 am

I tried this but for whatever reason my applicationDomain failed to show the proper font. So i modified the code to:

var a_TestFont:Class = event.target.content.a_TestFont as Class;
Font.registerFont(a_TestFont);

And this worked fine. just in case anyone else has this problem. Thanks for the article.

Gravatar
  • rich
  • May 27th, 2008
  • 10:09 am

cool,thanks for that. I didn't have to do that, but maybe that was because I used a LoaderContext with applicationDomain=currentDomain.

[...] article explain the same approach, but it need to add extra font family (Bold or Italic) at specific font [...]

Want your say?

* Required fields. Your e-mail address will not be published on this site


You can use the following XHTML tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>