Flash AS3 Loading Fonts
May 13th, 2008 By: danCreate a Flash AS3 application that loads an external font at runtime… Sounds easy enough… But it is a little tricky. I needed to create a flash app that allowed users to choose a font from a list and load that into a player. I wanted to offer several fonts but did not want to bloat the load-time with unused fonts. I could not find much help on this topic… Luckily I found betriebsraum and with that I was able to hack up something that worked for me.
Step 1: Created an external swf with the font I needed. (I created separate ones for each font I was going to offer.)
- Created a new Fla and add a font to the library.
- In the Library pane(F11), click the options dropdown, and choose ‘New Font’
- Select a font, size and style–size is not important (arguably)–however, I believe you will have to create separate fonts for each style you require. The name is not important really either.
- Right click the new font in the Library and select ‘Linkage…’
- Publish the swf as ‘/font-Fontname.swf’.
Step 2: Create the Application:
- Create a new Flash CS3/As3 application set the Document class as ‘Main’ and save it as ‘/myapp.fla’
- Create a new AS3 script and save it as ‘/Main.as’
Main.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package { import flash.display.Sprite; import flash.text.*; import flash.events.*; public class Main extends Sprite { var t:TextField = new TextField(); var f = new TextFormat(); public function Main() { var font = new LoadFont("font-Zapfino.swf",["EFont01"]); font.addEventListener(LoadFont.COMPLETE, successLoadFont); font.addEventListener(LoadFont.ERROR, failLoadFont); } private function failLoadFont(e:Event){ f.font="Arial"; //default font if load fails. t.embedFonts = false; post(); } private function successLoadFont(e:Event){ var embeddedFonts:Array = Font.enumerateFonts(false); f.font=embeddedFonts[0].fontName; t.embedFonts = true; post(); } public function post(){ f.size = 36; t.defaultTextFormat = f; t.x = 100; t.y = 100; t.background = true; t.autoSize = TextFieldAutoSize.LEFT; t.text = "We are in loaded Font"; addChild(t); } } } |
- Create a new AS3 script and save it as ‘/LoadFont.as’
LoadFont.as
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package { import flash.display.*; import flash.events.*; import flash.text.*; import flash.errors.*; import flash.system.*; import flash.net.*; public class LoadFont extends EventDispatcher { public static const COMPLETE:String = "complete"; public static const ERROR:String = "error loading font"; private var loader:Loader = new Loader(); private var _fontsDomain:ApplicationDomain; private var _fontName:Array; public function LoadFont(url:String,fontName:Array):void { _fontName = fontName; trace("loading"); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, font_ioErrorHandler); loader.contentLoaderInfo.addEventListener(Event.COMPLETE,finished); loadAsset(url); } private function loadAsset(url:String):void { var request:URLRequest = new URLRequest(url); loader.load(request); } function finished(evt:Event):void { _fontsDomain = loader.contentLoaderInfo.applicationDomain; registerFonts(_fontName); dispatchEvent(new Event(LoadFont.COMPLETE)); } function font_ioErrorHandler(evt:Event):void { dispatchEvent(new Event(LoadFont.ERROR)); } public function registerFonts(fontList:Array):void { for (var i:uint = 0; i < fontList.length; i++) { Font.registerFont(getFontClass(fontList[i])); } } public function getFontClass(id:String):Class { return _fontsDomain.getDefinition(id) as Class; } public function getFont(id:String):Font { var fontClass:Class = getFontClass(id); return new fontClass as Font; } } } |


So I had this problem with a record that was being saved even though it failed validation:
cc = CreditCard.new(:card_number => 'invalid')
>> cc.save
=> false
>> cc.id
=> 3
That one had me stumped for a while until I realized I was carelessly using update_attribute in my custom writer:
...
May 13th, 2008 at 4:38 pm
Fonts are a tricky thing in ActionScript but they’ve come a long way in ActionScript 3.
One of the best new additions for dealing with dynamic fonts is the ability to search for them dynamically in memory space. Here is some code that would complement the example shown here; it retrieves a font dynamically at runtime, allowing you to get a list of available fonts and then use one of them for a text field:
This method will attempt to find the font based on the name and assign it to the specified text field instance. All that remains after that is simply to set the text in the field!
To retrieve a list of available fonts, the magic line of code is: var fontArray:Array=Font.enumerateFonts(true);
Note that the method being invoked is a singleton so no Font instance is required.
For more tips, tricks, tutorials, and expert-level advice on ActionScript 3, visit http://www.peabee.com/
May 13th, 2008 at 4:39 pm
…slight update, the method name should be “setFont”, not “set font” (it was copied from an existing class and was originally used as a setter).
May 14th, 2008 at 12:10 pm
Patrick - I’ve edited your code block with the update you mentioned, and wrapped it in code tags for readability.
July 16th, 2008 at 1:53 am
I found your article very interesting. I do have one question.
Are loaded fonts able to be used by SWF’s on other pages other than the webpage the font was loaded on.
July 22nd, 2008 at 11:13 am
[...] Looks useful - if you like this kind of thing Add to your fave social site: [...]
September 5th, 2008 at 8:10 am
Line 35 has an html error in it. ( the less than sign )
September 29th, 2008 at 1:55 pm
thanks a lot, finally one solution that works. great, kudos!
tox
September 29th, 2008 at 11:16 pm
Just what I was looking for. The Class worked great right off the bat too for what I need.
November 10th, 2008 at 9:22 am
Very useful, so tutorial i searched for weeks.
Thanks a lot men. U did a great work.
Cya
December 1st, 2008 at 10:07 pm
Very nice work, works like a charm.
December 2nd, 2008 at 12:30 pm
With this approach you can’t embed a subset of characters (like you would using the Embed button). There is another way similar but more superior than your approach.
December 2nd, 2008 at 4:08 pm
Eric - what is the more superior approach?
December 10th, 2008 at 3:38 am
Many thanks! Comes in very handy!
December 10th, 2008 at 3:39 am
Oh yeah… why Futura? Luckily I could change the font in firebug, so the page was a little readable!
January 5th, 2009 at 3:53 pm
Hallo, great class with one, i hope, simple problem. I try to use this class in an AIR project. When i load the font.swf from the application folder it works. When i load the font.swf from the application-storage folder, registerFonts trow the error [Fault] exception, information=ArgumentError: Error #1508: The value specified for argument font is invalid.
I hope (need) 4 help.
Sorry for my spelling, i’m not a native speaker.
THX f reading
Tom
January 30th, 2009 at 6:31 pm
[...] Flash AS3 Loading Fonts [...]
February 4th, 2009 at 6:18 pm
Thank you very much for the LoadFont class. It works perfectly. Only two corrections:
line 17:
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, font_ioErrorHandler); // adding contentLoaderInfo
line 34:
for (var i:uint = 0; i < fontList.length; i++) { // the < simbol
Thank you and sorry for my English
May 26th, 2009 at 7:09 am
Thanks for such a good article of runtime font embedding .I am able to implement this in my project ,fonts are coming from swf but what i’m trying to do is that getting the different font from different swf but in Font.enumerateFonts(false) does not return all of the font embed it’s just repeat the 2 or 3 fonts and sometimes just add only one . here is my code which i’m using in my project with your loadFont and other class .Thanks
public function fontupload()
{
for (var i:Number = 0; i < 4 ; i++)
{
var coantainerfonts:Coantainerfonts = new Coantainerfonts()/seprate class for fonts with-in library
coantainerfonts.mc.width = coantainerfonts.txt.width
coantainerfonts.name = “fontconatiner”+i
coantainerfonts.x = 0
coantainerfonts.y=i*(18)
fontsMC.addChild(coantainerfonts)
var tempStr:String = “_fontembed” + (i + 1) + “.swf” //refernce to differnt swf
var tempname:String = “EFont0″+(i+1)
var font = new LoadFont(tempStr, [tempname]);
font.addEventListener(LoadFont.COMPLETE, successLoadFont);
font.addEventListener(LoadFont.ERROR, failLoadFont);
}
)
}
private function successLoadFont(e:Event)
{
var mc:MovieClip = fontsMC.getChildAt(_counter) as MovieClip
var TxtRef:TextField = mc.txt as TextField
var embeddedFonts:Array = Font.enumerateFonts(false);
var txtformat:TextFormat = new TextFormat()
txtformat.font = embeddedFonts[_counter].fontName
trace(embeddedFonts[_counter].fontName)//trace similar font names
TxtRef.embedFonts = true
TxtRef.text =embeddedFonts[_counter].fontName
TxtRef.setTextFormat(txtformat)
_counter++;
}