February 23rd, 2007 by Kyle
Tags: ActionScript, as3, embedded-fonts.-embedded-true-type-fonts, Flex, Flex Builder, flex-builder-2.0.1, fonts, modules, mxml, runtime, true-type-fonts, ttf
Posted in: Flex
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:
loadedFont = ml.factory.create()as IFontModule;
Here is the code for the main application:
<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:
{
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

