This is really part 2 in the series. Part 1 was Changing embedded True Type fonts at Runtime in Flex Applications

The interface that I have each font swf implementing is the same, so I have not posted the code.

The application has undergone some slight refactoring and I have added a few things.
I chose to use the ModuleManager.getModule(url) rather than using the mx:ModuleLoader tag.
The module Manager was more flexible and really should be used for loading non-visual modules.

Note the way that you get access to the loaded module after it has loaded:

 var ml:IModuleInfo = e.target as IModuleInfo;
 loadedFont = ml.factory.create()as IFontModule;
 

Here is the code for the main application:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="setText()">
<mx:Panel height="100%" width="100%">
    <mx:TextArea id="input" height="100%" width="100%" text="starting up…"/>
    <mx:ControlBar>
        <mx:VBox>
            <mx:HBox>
              <mx:Button label="_sans" click="{this.fontName = ‘_sans’; progMessage = ”; setText()}" />
              <mx:Button label="Arial" click="{setFont(’Arial’,'normal’, ‘normal’)}" />
              <mx:Button label="Trebuchet" click="{setFont(’Trebuchet’, ‘normal’, ‘normal’)}" />
              <mx:Button label="Rotate +1" click="{++input.rotation}" />
              <mx:Button label="Rotate -1" click="{–input.rotation}" />
              <mx:Button label="Small" click="{fontSize=6; setText()}" />
              <mx:Button label="Medium" click="{fontSize=11; setText()}" />
              <mx:Button label="Large" click="{fontSize=20; setText()}" />
              <mx:Button label="Normal" click="{(this.fontName!=’_sans’) ? fontName=loadedFont.fontName_Normal:’_sans’} { fontWeight=’normal’; fontStyle=’normal’; setText()}" />  
              <mx:Button label="Bold" click="{(this.fontName!=’_sans’) ? fontName=loadedFont.fontName_Bold:’_sans’} { fontWeight=’bold’; fontStyle=’normal’; setText()}" />
              <mx:Button label="Italic" click="{(this.fontName!=’_sans’) ? fontName=loadedFont.fontName_Italic:’_sans’} {fontWeight=’normal’; fontStyle=’italic’; setText()}" />  
              <mx:Button label="Bold/Italic" click="{(this.fontName!=’_sans’) ? fontName=loadedFont.fontName_BoldItalic:’_sans’} {fontWeight=’bold’; fontStyle=’italic’; setText()}" />
            </mx:HBox>     
           
            <mx:HBox>
                <mx:Label text="fontName: {fontName}"/>
                <mx:Label text="fontSize: {fontSize}"/>
                <mx:Label text="fontWeight: {fontWeight}"/>
                <mx:Label text="fontStyle: {fontStyle}"/>      
            </mx:HBox>
           
            <mx:HBox>
                <mx:Label id="l2" text="{progMessage}"/>
                <mx:Label id="l1" text="{progBar}"/>
            </mx:HBox>  
        </mx:VBox>
    </mx:ControlBar>
</mx:Panel>
   
<mx:Script>
    <![CDATA[
    import mx.modules.IModuleInfo;
    import mx.modules.Module;
    import mx.modules.ModuleBase;
    import mx.modules.ModuleLoader;
    import mx.events.ModuleEvent;
    import mx.modules.ModuleManager;
    import mx.controls.Alert;

    [Bindable]
    public var fontName:String = "_sans";
    [Bindable]
    public var fontSize:int = 11;
    [Bindable]
    public var fontWeight:String="normal";
    [Bindable]
    public var fontStyle:String="normal";

    private var loadedFont:IFontModule;

    [Bindable]
    public var progBar:String = "";
    [Bindable]
    public var progMessage:String = "";
   
    private var mldr:IModuleInfo;
   
    public function setFont(fontface:String, fontWeight:String, fontStyle:String):void{
        var tf:TextFormat = new TextFormat();
        tf.font = fontface;
        if (Application.application.systemManager.isFontFaceEmbedded(tf)){
            progMessage = "Module for font " + fontface + " already loaded";
            this.fontName=fontface;
            this.fontWeight=fontWeight;
            this.fontStyle=fontStyle;
            setText();
        }
        else {
            loadFont(fontface);
        }
    }

    public function loadFont(font:String):void
    {
        var url:String=font + ".swf";
       
        progBar = "";
        progMessage = "";
       
        mldr = ModuleManager.getModule(url);
        mldr.addEventListener( ModuleEvent.PROGRESS, progressEventHandler );
        mldr.addEventListener( ModuleEvent.READY, onComplete );
        mldr.addEventListener( ModuleEvent.ERROR, onError );       
        mldr.load();
    }

    public function setText():void
    {
        input.setStyle( "fontFamily", fontName );
        input.setStyle( "fontSize", fontSize );
        input.setStyle( "fontWeight", fontWeight );
        input.setStyle( "fontStyle", fontStyle );
        input.text="This is the theme to Garry’s Show,\n"
                    +"The theme to Garry’s show.\n"
                    +"Garry called me up and asked if I would right his theme song.\n"
                    +"I’m almost halfway finished,\n"
                    +"How do you like it so far,\n"
                    +"How do you like the theme to Garry’s Show.\n\n"
                    +"This is the theme to Garry’s Show,\n"
                    +"The opening theme to Garry’s show.\n"
                    +"This is the music that you hear as you watch the credits.\n"
                    +"We’re almost to the part of where I start to whistle.\n"
                    +"Then we’ll watch ‘It’s Garry Shandling’s Show’.\n\n"
                    +"This was the theme to Garry Shandling’s show.";
    }

    public function onComplete(e:ModuleEvent):void
    {
        var ml:IModuleInfo = e.target as IModuleInfo;
        loadedFont = ml.factory.create()as IFontModule;
       
        if(loadedFont!=null){
            var args:Array=[loadedFont.fontName_Normal,"normal","normal"];
            callLater(setFont,args);
            progBar = "";
            progMessage = "Module Loaded";
        }
        else{
            fontNotLoaded();
        }
    }

    private function progressEventHandler(e:ProgressEvent):void {
        progBar += ".";
        progMessage = "Module " +  Math.round((e.bytesLoaded/e.bytesTotal) * 100) + "% loaded";
    }
   
    public function onError(e:ModuleEvent):void
    {
        fontNotLoaded();
    }
   
    private function fontNotLoaded():void{
        Alert.show(‘font not loaded! Defaulting to _sans’);
        progBar = "";
        progMessage = "Module NOT Loaded!";    
        this.fontName="_sans";
        this.fontWeight=‘normal’;
        this.fontStyle=‘normal’;
        setText();
        progMessage = "";
    }
]]>
</mx:Script>   
</mx:Application>
 

The only real difference in the font classes are the importing and extending of ModuleBase.
Here is the font class for the Trebuchet font:

package
{
    import mx.modules.ModuleBase;
    import flash.text.Font;

    public class Trebuchet extends ModuleBase implements IFontModule
    {
        public static var FONTNAME_NORMAL:String="Trebuchet MS";
        public static var FONTNAME_BOLD:String="Trebuchet MS Bold";
        public static var FONTNAME_ITALIC:String="Trebuchet MS Italic";
        public static var FONTNAME_BOLD_ITALIC:String="Trebuchet MS Bold Italic";                  
       
        [Embed(source="assets/trebuc.ttf", fontName="Trebuchet MS")]
        public static var trebuchetRegular:Class;
       
        [Embed(source="assets/trebucit.ttf", fontName="Trebuchet MS Italic", fontStyle="italic")]
        public static var trebuchetItalic:Class;
       
        [Embed(source="assets/trebucbd.ttf", fontName="Trebuchet MS Bold", fontWeight="bold")]
        public static var trebuchetBold:Class;
       
        [Embed(source="assets/trebucbi.ttf", fontName="Trebuchet MS Bold Italic", fontWeight="bold", fontStyle="italic")]
        public static var trebuchetBoldItalic:Class;

        public function Trebuchet()
        {
            super();
            trace("Trebuchet loaded.");
            Font.registerFont(trebuchetRegular);
            Font.registerFont(trebuchetItalic);
            Font.registerFont(trebuchetBold);
            Font.registerFont(trebuchetBoldItalic);
        }

        public function get fontName_Normal():String
        {
            return FONTNAME_NORMAL;
        }
       
        public function get fontName_Bold():String
        {
            return FONTNAME_BOLD;
        }
       
        public function get fontName_Italic():String
        {
            return FONTNAME_ITALIC;
        }
       
        public function get fontName_BoldItalic():String
        {
            return FONTNAME_BOLD_ITALIC;
        }              
    }
}
 

A zip file of an entire Flex Builder 2.0.1 project with this code can be downloaded here.

Stay tuned for the next installment: Using Runtime CSS to Change embedded True Type fonts at Runtime in Flex Applications.

-Kyle