Embedding fonts in Flex

Learn how to include special characters in Flex from a font

This post is a tutorial about how to embed fonts in Flex. Enjoy it and you may also want to take a look at another text that gives a good base to this topic:
Different languages and fonts

Introduction

With Flex you can create an ActionScript class that serves only as a font repository. You can also set the unicode range choosing which character set you want, this way it isn’t necessary to embed the entire font and the size of the swf decreases.

To identify the code related to the characters you need, there is the file called flash-unicode-file table.xml with all them listed. Search the directory of your Flex Builder installation for the file, for example, in my computer it’s here:
C:/Arquivos de programas/Adobe/Flex Builder 3/sdks/3.0.0/frameworks/flash-unicode-table.xml

In this file you can see the codes that represent the characters in unicode. You can specify them one by one, separated by commas, or may include a hyphen to tell Flex that it’s a set of characters, for example, U+00A1-U+00A8, which means a group of japanese kanjis.

The Class

The code below is the file myFont.as, which serves only to embed a font in a SWF.


import flash.display.Sprite;
import flash.text.Font;

public class myFont extends Sprite {

     [Embed(source="C:/directory/ myFont.ttf",
      fontName="_ myFont",
      fontWeight="bold",
      mimeType="application/x-font",
      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,U+0020,U+00A1-U+00FF,U+2000-U+206F,U+20A0-U+20CF,U+2100-U+2183")]
     
      public static var _ myFont:Class;
      Font.registerFont(_myFont);
}

The tag [Embed] tells the compiler that will be included a file in the swf, which in this case is a font and therefore we set the mimeType and inform the fontWeight. The source informs where physically is our font file, and fontName defines how Actionscript will call the font. The unicodeRange defines the characters that we need, which in this case correspond to all Roman alphabet and also the accentuation.

The statement as a public variable of type Class and its register through the method "Font.registerFont" makes it a font available to all Flex applications that may load this swf.

Despite it’s a class used in our Flex application, note that there isn’t any call to UIComponent, because if we do this, the swf file size would get too large unnecessarily. Since we need only the flash player core functions and not all the Flex framework.

Compiling with DOS

To compile the file myFont.as you need to use a command in DOS, the mxmlc, because it’s not possible to compile this file to swf directly by Flex Builder.

You must go to the Windows taskbar menu in Start -> Run and then type "cmd". At the command prompt, type the command "cd" to change the directory to where your mxmlc.exe file is, which usually is found at the Flex installation directory in /sdks/3.0.0/bin. Finally just type "mxmlc myFont.as" and a file myFont.swf will be compiled from this ActionScript code.

Dos

With these steps you can create different swfs for each font (or style) that you want, using them in your application as needed. To do this you need to load and manage the swf exchange for the various fonts that may exist in your application.

The Code

First, we must create a class responsible for loading the swfs with fonts. See this example with the file FontLoader.as:


import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.text.*;

import mx.core.Application;

public class FontLoader extends Sprite {
    [Bindable]
    public var fonte:String;
    //array para guardar os nomes de swfs carregados
    private var carregadas:Array = new Array();
     
    public function FontLoader() {
      //já abro de inicio com o latin
       loadFont("myFontLatin");
    }
   
    public function loadFont(url:String):void {
      fonte = "_" + url;
      // antes de carregar eu confiro se o swf já não foi carregado
      if (carregadas.indexOf(fonte) == -1){
          var loader:Loader = new Loader();
        loader.contentLoaderInfo.addEventListener(Event.COMPLETE,
         fontLoaded);
        loader.load(new URLRequest(url + ".swf"));
        carregadas.push(fonte);
      }
      else {
          setaFamily();
      }
     
    }
   
    private function fontLoaded(event:Event):void {
     setaFamily();
    }
    private function setaFamily():void {
     Application.application.setStyle("fontFamily",fonte);
    }
}

And then, at the main file of my application, I need just to create one instance from this class, which loads the basic font when it starts:

[Bindable]
public var fontLoader:FontLoader = new FontLoader();

When you need to change the font, for example, when you change an alphabet from one language to another, simply call the method loadFont, passing the name of the new swf:

fontLoader.loadFont("myOtherFont");

Observation

If you are using modules in Flex, there is a bug with TextArea, which does not include the fonts from the application and to solve this problem set the font by recovering the instance created before:

fontFamily="{parentApplication.fontLoader.fonte}"