How to use Font Symbols (Embedded Fonts) with ActionScript

ActionScript 2.0 ActionScript 3.0

You certainly don’t need ActionScript to make use of embedded fonts.  You can always just embed font outlines manually by selecting a text field, then using the Embed button in the Property inspector.  Select your range of characters, type in your text, then publish; you’re good to go (and you only need to do it with dynamic and input text fields:  static text fields embed font outlines automatically).  In fact, if your text field has an instance name — something you can also set in the Property inspector — then you can determine its text content with ActionScript and the embedded font outlines still hold.  But if you’re using ActionScript to create text fields on the fly, the mechanics are a bit different.  Let’s take a look. 

First, create your font symbol

To get your font(s) into the SWF, use a Font symbol. They’re easy enough to make, but doing so is not necessarily as intuitive as using Insert > New Symbol or Modify > Convert to Symbol. Instead, right-click/Command-click inside the Library panel and choose New Font from the context menu.  This brings up the Font Symbol Properties dialog.  Ignore the Name field for the moment.  Use the listbox in the Font field to find the font you want to embed.  Different variations, such as bold and italic, must each be imported as individual symbols, so select the appropriate checkbox if necessary.  You’ll see a choice for Bitmap text, but you should only select that if you want your fonts rendered as bitmaps (rasterized; that is, no vector shapes).  Doing so can save on file size, but your embedded fonts won’t scale as well, like any bitmap.  The Size field only matters if you use bitmapped text.

Once you’ve chosen your font and selected the variations (if desired), give your font a name in the Name field.  This is the name what will show up in the Library panel, so you might want to use, say, “Blackadder normal” for the non-bold, non-italic version of a font named Blackadder ITC and “Blackadder italic” for the italic version of that font.

Having font symbols in your Library isn’t enough.  You’ve also got to give them Linkage identifiers (AS2) or Linkage classes (AS3).  Right-click/Command-click on each font symbol and select Linkage from the context menu.  Select Export for ActionScript, which will do a number of things at once: either a) in AS1 or AS2 documents, it will enable the Identifier and Class fields, then populate the Identifier field with the font’s Library name; or b) in AS3 documents, it will enable the Class and Base Class fields, then populate the Class field with the font’s Library name (the Base Class field will be populated with a reference to the flash.text.Font class).

If you’re using AS3 and supplying a class name, you need to make sure your Linkage class name is valid. Like variables, class names can only contain alphanumeric characters — no punctuation, except for underscore (_) or dollar sign ($), and no spaces — and the first character can’t be a number. For this example, your “Blackadder normal” might become, say, BlackadderNormal. When you click OK on the Linkage Properties dialog, Flash will warn you that no such class exists and will offer to write it for you automatically. Agree to that, and you’re ready for the code.

Now, on to the ActionScript.

An answer, short and sweet, and how it works (AS2)

There are two ways to make use of an embedded font with code:  either with an instance of the TextFormat class or the StyleSheet class.  We’ll look at both.  Here’s the first example:

var fmt:TextFormat = new TextFormat();
fmt.font = "Blackadder normal";
fmt.size = 32;

var text1:TextField = this.createTextField("tf1", 0, 0, 0, 0, 0);
text1.autoSize = "left";
text1.embedFonts = true;
text1.setNewTextFormat(fmt);
text1.text = "Lorem ipsum dolor sit amet."

In the first line, an arbitrarily named variable, fmt, is declared and set to an instance of the TextFormat class.  TextFormat features all sorts of styling properties, and two of those are font and size.  Here, the font property is set to “Blackadder normal,” which is the Linkage identifier that was given to the font in the Linkage Properties dialog.

Next, another arbitrarily named variable, text1, is declared and set to an instance of the TextField class.  In AS2, there is no direct way to instantiate a text field, such as new TextField (for that, you need AS3).  The indirect way is to use the MovieClip.createTextField() method, which is here invoked on the global this property, which happens to refer to a movie clip because this code is in a frame of the main timeline (the main timeline is, in fact a movie clip).  This method provides a return value, which is a reference to the newly made text field, stored in the variable text1.  So text1 is enough to refer to the new text field, but you could also use tf1, which is the instance name provided as the first parameter.  The rest of the parameters, all zeroes, can be other values if you like, but whatever you use, they refer to (in order):  depth, x position, y position, width, and height.  Why set them all to zero?  Well, x and y are totally up to you.  I usually prefer to set a width and height of zero because the very next line, text1.autoSize = "left", instructs the text field to resize as needed to contain its text (other valid autoSize values are "center" and "right", which change the justification of the text).

The line after that is the important one.  The TextField.embedFonts property, as invoked on text1, is set to true.  Next, the TextField.setNewTextformat() sets the fmt object (the TextFormat instance) as the default styling for this text field.  Finally, a string of text is supplied to the TextField.text property.  Be aware that you can also use TextField.setTextFormat(), which allows you to set formatting after text has been added to the text field (optional parameters even allow you to specify which characters should be affected).

Alternatively, you can format your text with the StyleSheet class, which requires HTML formatted text.  Check it out:

var css:TextField.StyleSheet = new TextField.StyleSheet();
css.setStyle("p", {fontFamily:"Blackadder normal", fontSize:32});
css.setStyle("a", {textDecoration:"underline"});

var text2:TextField = this.createTextField("tf2", 1, 0, 0, 0, 0);
text2.autoSize = "left";
text2.embedFonts = true;
text2.styleSheet = css;
text2.html = true;
text2.htmlText = "<p>Lorem ipsum dolor
<a href='http://www.quip.net/'>sit amet</a>.</p>";
text2._y = 52;

This time, no TextFormat instance is needed.  Instead, you’re creating a StyleSheet object, which works very much like normal CSS.  Note that in AS2, the StyleSheet class is accessible as a child of the TextField class, which is why both terms appear in the variable declaration and new expression.  If you like, you can use the import directive and avoid the extra keystrokes, like this:

import TextField.StyleSheet;
var css:StyleSheet = new StyleSheet();

Either which way.

In any case, an arbitrarily named variable, css, is declared and set to an instance of the StyleSheet class.  This gives css access to all the functionality defined by that class, which includes a setStyle method.  The StyleSheet.setStyle() method accepts two parameters:  a) the name of a CSS selector (in other words, what HTML element to style), and b) an object that contains the CSS style properties to use.  In actual CSS, the fontFamily property would be font-family, and fontSize would be font-size.  In ActionScript, it’s close enough, but bear in mind that Flash only understands a very small subset of the CSS spec, just like it only understands a very small subset of the HTML spec.  In that second parameter, the curly braces ({}) are a shortcut for the expression new Object().  Note that fontFamily is set, once again, to the Linkage identifier set earlier.

After that, the rest is pretty much the same.  Note that this time the text field is created at depth 2, so that it doesn’t overwrite the first one.  Again, embedFonts is set to true.  This time, because the text is formatted as HTML, the TextField.html property is set to true, and the htmlText property is used to supply the text.  The TextField._y property is set to 52 just so the second text field appears beneath the first one.

An answer, short and sweet, and how it works (AS3)

ActionScript 3.0 works a bit differently, but the new approach makes sense in an elegant way.  Check back to the AS2 version for information on the details that overlap, but here are the same two examples in AS3, with a brief summary of changes after each one.

var fnt: BlackadderNormal = new BlackadderNormal();

var fmt:TextFormat = new TextFormat();
fmt.font = fnt.fontName;
fmt.size = 32;

var text1:TextField =  new TextField();
text1.autoSize = "left";
text1.embedFonts = true;
text1.defaultTextFormat = fmt;
text1.text = "Lorem ipsum dolor sit amet."
addChild(text1);

This time, the font is simply instantiated, just like any other object — because it is a Font instance.  So … an arbitrarily named variable, fnt, is declared and set to an instance of BlackadderNormal, as supplied in the Class field of the Linkage Properties dialog.

The TextFormat instance works almost exactly the same, only this time, the font property is set to the Font.fontName property of the fnt (BlackadderNormal) instance.

The TextField instance is also very nearly the same.  In ActionScript 3.0, you have the convenience of simply saying new TextField(), which is nice.  Instead of the setNewTextFormat() method, you’ve got a defaultTextFormat property (AS3 still has the setTextFormat() method for text already present; works pretty much the same).

The final line, addChild(text1), adds the text field to the display list, so that it becomes visible.

Here’s the StyleSheet update:

var css:StyleSheet = new StyleSheet();
css.setStyle("p", {fontFamily:fnt.fontName, fontSize:32});
css.setStyle("a", {textDecoration:"underline"});

var text2:TextField =  new TextField();
text2.autoSize = "left";
text2.embedFonts = true;
text2.styleSheet = css;
text2.htmlText = "<p>Lorem ipsum dolor
<a href='http://www.quip.net/'>sit amet</a>.</p>";
text2.y = 52;
addChild(text2);

This time, the StyleSheet class stands alone.  Here, the fontFamily property is set to fnt.fontName, rather than the Linkage identifier of AS2.  The second text field is created just like the first, as a direct instantiation, and the addChild() method adds the second text field to the display list as well.  Notice that in AS3, the TextField._y property loses its underscore, as is the case with all previously underscored properties.

Leave a Reply