Having trouble with embedded fonts and HTML text in Flash CS5?
I discovered this morning that the SWFs I had previously published with Flash CS3/4 no longer display some of their embedded fonts once I republished them in CS5. Specifically, embedded fonts that are applied as styles for a TextField's htmlText were randomly broken. I'll share some details about how I was able to fix this.
The Old Setup
The method that I've always used in CS3/4 to embed fonts is to create dynamic text fields in the first frame of the FLA somewhere offstage. I create a text field for each font and embed the required glyphs for the application, being careful to choose only the necessary characters to keep the file size down. I write the name of the font in the dynamic text field, e.g. "WhitneySans Medium" in case I need to modify the embedded glyphs later on:

To apply font styles to tags in HTML text, I write CSS rules that reference the embedded fonts. I had some trouble with this at first, but I discovered that in AS3, I could trace out the embedded fonts to determine how to reference them in the CSS rules. This code snippet prints the names of the embedded fonts (note, this code can go in your document class' constructor, and you'll need the correct imports in your .as file):
var fonts:Array = Font.enumerateFonts();
for (var i:int = 0; i < fonts.length; i++)
trace(fonts[i].fontName);
With this example in CS4, the results are:
Arial
Arial Bold
Arial Italic
WhitneySans Medium
If I were trying to apply "Arial Italic" to <em> tags in a text field's htmlText, I could set up styles like so:
var styles:StyleSheet = new StyleSheet();
styles.setStyle("em", {
display: "inline",
fontFamily: "Arial Bold" // this should be the exact name traced out with Font.enumerateFonts()
});
myTextField.styleSheet = styles;
myTextField.embedFonts = true;
myTextField.htmlText = "Work, you <em>damned font</em>!";
Unfortunately, for the particular fonts I'm using, this method breaks down a bit in Flash CS5.
The New Way
The font embedding implementation in Flash CS5 is slightly different and actually quite better for my tastes. Rather than needing to create unused dynamic text fields somewhere offstage, you actually embed all the fonts for your project in one place with the new "Font Embedding" dialog. With your FLA open, click the "Font Embedding..." option in the "Text" menu. Use this dialog to set up all of your fonts in a very straightforward way (I won't go into details – it's pretty easy to figure out):

I don't bother with exporting the embedded fonts as symbols for ActionScript. Perhaps if you needed to load and register fonts from a shared assets SWF file, this would be useful, but for a single SWF file using the methods described here, it appears to be unnecessary.
If you've upgraded from Flash CS3/4 to CS5, you'll notice that your old FLAs' embedded fonts will automatically get detected and pulled into the new font embedding dialog. With the method I describe here, you can safely remove the unused dynamic text fields from the timeline. The font embedding dialog automatically registers and makes your embedded fonts accessible in code. The problem I encountered is that referencing the fonts by name for CSS styles did not work exactly the same way. The enumerateFonts() script from above now traces out:
Arial
Arial
Arial
WhitneySans Medium
So rather than automatically naming each font according to its style, Flash now uses the base font name and requires you to use the font's other attributes to reference it in your code. An updated script is elucidating in figuring out how to do this:
var fonts:Array = Font.enumerateFonts();
for (var i:int = 0; i < fonts.length; i++)
trace(fonts[i].fontName + " - " + fonts[i].fontStyle);In CS5, this produces:
Arial - regular
Arial - bold
Arial - italic
WhitneySans Medium - regularTo achieve italic <em> tags in CS5, this is how my code looks:
var styles:StyleSheet = new StyleSheet();
styles.setStyle("em", {
display: "inline",
fontFamily: "Arial",
fontStyle: "italic"
});
myTextField.styleSheet = styles;
myTextField.embedFonts = true;
myTextField.htmlText = "Come back, you <em>damned font</em>!";
Rather than just using a font family name, I actually have to use fontStyle (or fontWeight to get to the bold version of Arial). To me, this feels a lot more like the usual experience with CSS, so I think it's a better implementation.
Fortunately, this was a pretty easy patch at the end of the day, and I like the new font embedding methodology a lot better. Happy coding!




Comments
I've been searching for the solution to this for months and I'm still not able to make this work in CS5. I have set up a empy document, with 4 weights of Univers exported for ActionScript from the library. Here's my timeline code:
var css:StyleSheet;
function init():void{
//these are 4 versions of Univers i have exported in my library. some sources say they must be registered, some say they dont.
/*Font.registerFont(UniversLC);
Font.registerFont(UniversLCO);
Font.registerFont(UniversBC);
Font.registerFont(UniversBCO);*/
var cl:URLLoader=new URLLoader(new URLRequest("test.css"));
cl.addEventListener(Event.COMPLETE, cssLoaded);
}
function cssLoaded(evt:Event):void{
css=new StyleSheet();
css.parseCSS(evt.target.data);
var xl:URLLoader=new URLLoader(new URLRequest("test.xml"));
xl.addEventListener(Event.COMPLETE, xmlLoaded);
}
function xmlLoaded(evt:Event):void{
var xmlData:XML=new XML(evt.target.data);
var tf:TextField=new TextField();
tf.multiline=true;
tf.width=tf.height=500;
addChild(tf);
tf.styleSheet=css;
//some sources have said to add this line, some say not to:
//tf.embedFonts=true;
tf.htmlText=xmlData.here;
}
init();
Locally, the text shows up fine, but apparently it is not pulling the font from the library but rather from what is installed on my system, as on most other computers all the text will show up as just Times. If I set the embedFonts to true, I get NO text, and whether or not I use the register fonts commands appears to have no affect. Unfortunately there appears to be no official documentation on this problem that is helpful, and I am getting conflicting help from the very few blogs that touch on this. If anyone is able to help, you can have my firstborn child, or really anything that is mine. I am desperate. I've zipped up the fonts, css, xml, and fla if anyone is feeling extra helpful. It is available here: danehansen.com
Thanks in advance.
Hi Dane, I was able to debug your .fla and get the embedded fonts working. There were two basic problems:
1) The fonts were all embedded as "TLF (DF4)" fonts. Using the method from "The New Way" section of this article, I traced the "fontType" property of each embedded font and found that these types of fonts have a type of "embeddedCFF." According to the flash.text.FontType class documentation, these types of fonts will not render in plain TextFields and can only be used with the classes in the flash.text.engine package. The solution for this is to embed these as "Classic (DF3)" fonts under the ActionScript tab of the font embedding dialog, which makes their "fontType" appear simply as "embedded."
2) The CSS was not referencing the font names the way that they exist "under the hood" once embedded in Flash. Please refer to "The New Way" section of this article for details about how to see the names Flash assigns your embedded fonts. I updated the CSS to reference these names and use either "font-style: italic;" or "font-weight: bold;" as necessary.
I'll follow up and send you an email with these code changes so you can see the specifics. Good luck!
How do you get this to work with <b>bold</b> tags in xml?
Hi,
I'm trying to change the font but can't figure out how. I would like it to be Euphemia UCAS, I have embedded this in the fla but no luck.
Heres the code:
function callFullImage(myNumber) {
myURL = myImages[myNumber].attributes.full_url;
myTitle = myImages[myNumber].attributes.title;
_root.createEmptyMovieClip("fullImage_mc",_root.getNextHighestDepth());
fullImage_mc._x = _root.full_x;
fullImage_mc._y = _root.full_y;
var fullClipLoader = new MovieClipLoader();
var fullPreloader = new Object();
fullClipLoader.addListener(fullPreloader);
fullPreloader.onLoadStart = function(target) {
target.createTextField("my_txt",target.getNextHighestDepth(),0,0,200,20);
target.my_txt.selectable = false;
target.my_txt.textColor = 0xFFFFFF;
};
fullPreloader.onLoadProgress = function(target, loadedBytes, totalBytes) {
target.my_txt.text = Math.floor((loadedBytes/totalBytes)*100);
};
fullPreloader.onLoadComplete = function(target) {
new Tween(target, "_alpha", Strong.easeOut, 0, 100, .5, true);
target.my_txt.text = myTitle;
target.my_txt._y = 540;
target.my_txt.textColor = 0xFFFFFF;
};
fullClipLoader.loadClip(myURL,fullImage_mc);
}
any help you can give would be hugely appreciated!!!
Thanks!
hi there
i, too, am having trouble with the new cs5 handling of embedding fonts in a textfield that loads xml
i am using helvetica neue lt std 55 roman, and can get that plus italic and bold to work, however, i was getting very strange vertical lines on the screen; see this screenshot:
www.donaldluxton.com
any advice would be greatly appreciated! thank you
for all having problems with exporting the fonts: blog.johannest.com
Leave a Comment