Tuesday, June 19, 2007

Flash CS3 & ActionScript 3 Example: Loading fonts at runtime

This example demonstrates, how a movie can use fonts embedded into another movie. All resources I found so far (like AS3 Runtime Font Loading) use some Flex2 code to get it done. My example is based on pure Flash CS3.

Step 1: Create Embedded Font Movie:

Create a new movie with name embeddedFont.fla and add a new font to your Library:


Now edit the Linkage Properties:

Save the file and publish as swf.

Step 2: Create Class Files:

Create a new movie with name FontLoadingExample.as and add the following code:

package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;

public class FontLoadingExample extends Sprite {

private var textFieldFactory:TextFieldFactory;

public function FontLoadingExample() {
trace("FontLoadingExample")
textFieldFactory = new TextFieldFactory();
textFieldFactory.addEventListener(TextFieldFactory.FONT_LOADED, fontReady);
textFieldFactory.loadFont("embeddedFont.swf")
}

private function fontReady(e:Event):void {
var tf:TextField = textFieldFactory.getNewTextField("Bingo!", 0x000000, 14);
addChild(tf);
}
}
}

Now create a new movie with name TextFieldFactory.as and add the following code:

package {

import flash.text.Font;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormatAlign;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.utils.*;
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;

public class TextFieldFactory extends EventDispatcher {

public static var FONT_LOADED:String = "fontLoaded";
private static var embeddedFont:Font = null;
private var loader:Loader = null;

public function TextFieldFactory() {
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
}

public function loadFont(swfURL:String):void {
var context:LoaderContext = new LoaderContext();
context.applicationDomain=ApplicationDomain.currentDomain;
loader.load(new URLRequest(swfURL), context);
}

private function completeHandler(event:Event):void {
var embeddedFontClass:Class = loader.contentLoaderInfo.applicationDomain.getDefinition("EmbeddedGaramond") as Class;
Font.registerFont(embeddedFontClass);
var embeddedFontsArray:Array = Font.enumerateFonts(false);
embeddedFont = embeddedFontsArray[0];
dispatchEvent(new Event(TextFieldFactory.FONT_LOADED));
}

public function getNewTextField(t:String, c:uint, s:uint):TextField {
if ((embeddedFont != null) && embeddedFont.hasGlyphs(t)) {
return getNewTextFieldEmbeddedFont(t, c, s)
}
else {
return getNewTextFieldDeviceFont(t, c, s)
}
}

public function getNewTextFieldEmbeddedFont(t:String, c:uint, s:uint):TextField {
trace("getNewTextFieldEmbeddedFont: "+t);

var tf:TextField = new TextField();
var fo:TextFormat = new TextFormat();

fo.font = embeddedFont.fontName;
fo.color = c;
fo.size = s
tf.defaultTextFormat = fo;
tf.autoSize = TextFieldAutoSize.LEFT
tf.type = TextFieldType.DYNAMIC;
tf.multiline = false;
tf.selectable = false;
tf.textColor = c;
tf.embedFonts = true;
tf.antiAliasType = AntiAliasType.ADVANCED;
tf.border = true;
tf.wordWrap = false;
tf.text = t;
return tf;
}

public function getNewTextFieldDeviceFont(t:String, c:uint, s:uint):TextField {
var tf:TextField = new TextField();
var fo:TextFormat = new TextFormat();

trace("getNewTextFieldDeviceFont: "+t);
fo.font = "_serif";
fo.color = c;
fo.size = s
tf.defaultTextFormat = fo;
tf.autoSize = TextFieldAutoSize.LEFT
tf.type = TextFieldType.DYNAMIC;
tf.multiline = false;
tf.selectable = false;
tf.textColor = c;
tf.embedFonts = false;
tf.border = true;
tf.wordWrap = false;
tf.text = t;
return tf;
}

}
}

Save both files.

Step 3: Create the Font Loading Movie:

Create a new movie with name FontLoadingExample.fla and and set the document class to FontLoadingExample.fla.


Save, publish and run the movie. You will see the words "Bingo!" set with the embedded font.

5 comments:

john07 said...

All work for en lang.
But for ru lang I can't get working examle. Russian letters dissappear. Have any idea?

Сергей Педан said...
This comment has been removed by the author.
Unknown said...

Does this work with CSS Styles? I want to be able to do something where a sentence passed to the textfield could have individual elements wrapped in span's that have different classes.

Where one is a style from a stylesheet that specifies one font and another would be a class that specifies another font. Both being embedded with this method.

Know if that's possible?

CodingFather said...

There are some video tutorials on http://codervods.com about ActionScript fonts, I thought you might be interested.

Kaushik said...

Hey, Thanks for this post. It helped me a lot.
I think in CS3 All fonts are not getting embedded. Though your post is very helpful.