[AS3] Recursive Font Embeding
So, i’m sure that you had this problem before. You put a dynamic textfield on a MovieClip or Sprite and then set’s it to a variable coming from a XML file. Your client start using the website and complains to you that he cannot see the text in the right font on his computer, or some characters are missing.
Well….the truth is: the way Flash deals with font managing just suck! Normally, you’ll have to export the font’s characters. To do this follow these steps:
- On the Main Menu go to Text -> Font Embeding
- Click on the + thing and add a new font.
- Give a name to the font
- Select the font on the combobox, and select which group of characters to be exported.
Tip: Be sure to select only the characters you’ll actually use (it doesn’t make sense to export Japanese characters to a brazilian website, right?), because flash will export them on the SWF and this will increase filesize.
5. Go to the actionscript tab and select “Export for Actionscript”
Tip: This is actually optional, but if you are doing a lot of actionscript coding, it’s good to do this because you can use the font asset as an actionscript object and initialize with the new keyword and everything.
6. Select the Textfield you want that font for and type the name of the font you set on step 3. Notice that Flash will put an * after the font name. This is just to identify the font as a library asset.
Now there’s the trick. For every dynamic textfield you have, you must set TextField.embedFonts = true to it’s instance. This is a pain in the ass to do. I did some googling and found a cool code that seb ly implemented here. I’m reproducing the code below:
function recursiveEmbed(container : DisplayObjectContainer) : void
{
for(var i: int = 0; i < container.numChildren; i++)
{
var child : DisplayObject = container.getChildAt(i);
if(child is DisplayObjectContainer)
recursiveEmbed(child as DisplayObjectContainer);
else if (child is TextField)
TextField(child).embedFonts = true;
}
}
You can use it like this on your root movieclip or Document Class or whatever:
recursiveEmbed(this)This is nice. but, it kinda sucks having to do this to every DisplayObjectContainer, right? So, i created a new class, CustomDisplayObjectContainer so you don’t need to worry about doing it anymore.
package
{
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.text.TextField;
/**
* ...
* @author GUi
*/
public class CustomDisplayObjectContainer extends DisplayObjectContainer
{
super();
}
override public function addChild(p_target:DisplayObject):void
{
super.addChild(p_target);
recursiveEmbed(p_target);
}
protected function recursiveEmbed(container : DisplayObjectContainer) : void
{
for(var i: int = 0; i < container.numChildren; i++)
{
var child :DisplayObject = container.getChildAt(i);
if(child is DisplayObjectContainer) recursiveEmbed(child as DisplayObjectContainer);
else if (child is TextField) TextField(child).embedFonts = true;
}
}
}
So, let’s say that your document class extends this class..You’ll never have to deal with embed font issues again. Neat, huh?
Tip: Be sure to export all characters and all fonts before testing, or this script won’t work.
Also, check out the new Text Layout Framework video on AdobeTV to learn how to use the state of the art text in Flash.