The Unbearable Strangeness of Embedding Fonts
The 'why' and 'how' of embedding fonts is a Flash 101 topic. The main 'why' is that the user can't see fonts that she doesn't have. If your swf uses these fonts, you need to bundle them in the swf (or with the swf). The 'how' also seems very simple: in the properties panel for a given text field, click the 'Embed' button and select the character range you want to embed. Click OK. Done. Move on.
But it's really not that simple.
Once you start using fonts in a shared library, referring to embedded fonts in a css file, etc. weird problems start popping up. I've had embedded text working in some swfs but not others, static fields displaying garbage and bloated swfs.
I decided to get to the bottom of this embedded font thing. I ran a bunch of experiments, looked at the resulting fla and swf file sizes and peeked into the swfs with ASV. Here's what I've figure out:
1. Embedded fonts Alpha and Rotation
This refers to text fields that are nested in a movieclip:
If the text field is NOT using embedded fonts, and if the containing movieclip has an _alpha of less than 100, the _alpha will NOT affect the text field. All other content of the movieclip is faded, but the text field is fully opaque.
If the text field IS using embedded text, _alpha works just fine.
Rotation is similar, except that non-embedded text fields do not display at all if the containing movieclip has a _rotation other than 0. Again, if the text field is using embedded fonts, it rotates just fine.
I consider this an idiosyncrasy of Flash. It is understandable that a font needs to be embedded for the user to see it if she doesn't already have it. But why does a font need to be embedded for alpha or rotation to work? It's not obvious. It's just the way it is.
2. Do Static fields automatically embed their font?
Static text fields are similar to embedded-font dynamic text fields that have the Auto-Fill button clicked in the Embedded Characters panel. Only the character outlines that are used in the field are included in the swf.
As static fields are not accessible via ActionScript, it's impossible to change their text at runtime. Therefore, there is no need to specify a font character range as there is for dynamic text fields.
So with static fields, you don't need to worry about whether the user has the font on her system. Also, static fields nested in movieclips will fade and rotate properly. Static text fields are quick and dirty and easy to use.
3. Do static fields and embedded-font dynamic fields share font data?
If they are using the same font, they will both use that font outline data. If the static field has text "ABC" and the dynamic field uses embedded characters "ABD", the swf will have font outlines for characters "ABCD". The character outlines in the swf are the union of those needed by the static fields and the dynamic fields.
Note: If a font is used only by static fields, the font data is trimmed down. It does not contain kerning data and the swf is significantly smaller.
4. Does using the Embed Fonts button set field_txt.embedFonts = true ?
Even if only a single character is specified in the Embed Characters panel, the field's embedFonts attribute is set to true.
Of course, this will only embed a single character in the swf unless the same font is included in the FLA's library.
5. Are fonts in the FLA library included in the swf?
Answer: If the 'Export for ActionScript' and 'Export in First Frame' options are checked in the font's linkage panel.
Actually, the 'Export in First Frame' does not necessarily need to be set. See below. But the Export for ActionScript option does. If you don't set this option, the library font is useless.
6. Are library fonts stored in the FLA?
You would think that fonts are stored in the FLA. After all, bitmaps and sound assets in the FLA library are stored there; i.e. they are not just references to files on your hard drive. If you put a lot of bitmaps in your FLA file, it gets big. If you
send that FLA to a coworker, your coworker will get those assets
bundled inside the fla. Your coworker will be able to build the fla even though you did not give her the bitmaps and audio as separate files.
Unfortunately, fonts are not handled the same way. The fla only
contains a reference to the font on your hard drive. If you send the
fla to your coworker, and your coworker does not have that font
installed on her system, she will not see the same fonts. She will not
see them in the design view inside the IDE and she will not be able to
embed that font when building the swf.
When she opens the fla in Flash,
she will get that dialog box asking her to specify subtitute fonts.
However, if the font in the FLA library imports from a shared library swf, and if she has that shared library, she will be able to build a swf
that imports the font from the shared library. She will be able to successfully compile the fla in this case.
7. Can the library font export in a frame after the first?
Answer: Actually, yes
When library assets are set to load in the first frame, it delays the time that that swf can start running. Usually, you want the first frame to be as light as possible so that you can display a preloader. The library assets can be loaded on a subsequent frame by setting them on the stage on that later frame, then skipping over that ugly frame with ActionScript. (There are other techniques too.)
How do we do the same thing with fonts?
Leave the "Export in First Frame" unchecked. Create a text field in the frame where you want the font loaded. Specify the font in question from the font list (it should have an asterisk).
The field does not have to be set to embedFonts. It only has to exist and refer to the desired font. (If it is not set to embedFonts, it will not be visible, but the font will still load on that frame.)
8. Do text fields that use a library font need to also have characters embedded with the Embedded Characters panel?
The field needs to have its embedFonts attribute set to true. This can be done with ActionScript or via the Embed Characters panel. However, the selected character set in the Embed Characters panel does not matter. A single "." in the "Include these characters" field is enough to set the field's embedFonts attribute to true.
Simply using an embedded font (a font with an asterisk in the font list) is not sufficient.
A weird exception: If the font is imported from a shared library swf, the text field automatically sets embedFonts to true.
Note: Fonts in the library appear in the text properties font list under the name given in the font's library properities panel, not the original name. It also has an asterisk in the name.
9. Is using a library font equivalent to selecting the 'All' characters range in the Embed Characters panel?
Answer: Hell no
The 'All' option includes data for 39477 glyphs, even if the original font does not have that many glyphs. The non-existent glyphs are null, but they still have slots in their data tables. Your swf will be severely bloated if you use this option.
In addition, the FLA will take a long time to compile.
If the text field has a mix of bold and non-bold characters (turn on the HTML option to see this), you will get twice that number of glyphs and the bloating will be doubled.
Never use the 'All' range if your swf is going to be used on the web.
10. Why are the bold characters in my embedded font text field not visible?
Answer: If you're using a library font, that font needs to appear twice in the library, once with the bold option set.
When the flash player is using a non-embedded font, it can convert the font to bold or italic (or bold/italic) on the fly. But if the font is embedded in the swf, each version of the font needs to be included.
11. Which library font should be specified if the text field has a mix of regular and bold characters?
Answer: Either the regular or the bold library font name should work
Let's say you want a field to contain regular and bold embedded Times Roman. As an experiment, add just one font to the library, base it on Time Roman, name it "my Font" and do NOT set the bold option.
Next, create a text field with some text in it. Select the font "my Font*" from the font list. Make some of the characters bold and some not bold -- you will need to select the html option to do this. Click the Embed button and specify the letter "a" as the only character embedded (this will force embedFonts to true). Alternatively, you can use ActionScript -- field_txt.embedFonts = true.
Hit F8 and nest the text field in a movieclip. Rotate the movieclip a little (this makes it easy to see if the fonts are actually embedded when you run it).
Run the swf. The bold characters will be missing.
Add another font to the library. Again, use Times Roman, but this time select the bold style option. Give it the name "ScoobyDoo". Again, set the linkage options "Export for ActionScript" and "Export in First Frame."
Run the swf. You should see all the characters and they should be bolded properly.
You specified "my Font" for the font. You never told Flash to use the "ScoobyDoo" font for the bold text, but the bolding still works. Evidently, Flash is smart enough to look past the name you give it and find that "ScoobyDoo" is a bold version of "my Font". The name for the bold font does not matter.
Try setting the font for the text field to "ScoobyDoo". It should look the same.
Presumably, when using CSS to specify fonts and bold or italics, the behavior will be the same. I have not tested this yet.
12. Fonts that are designed to be bold or italic -- how should they be handled?
Answer: Treat them like a regular font. Don't bold or italic them.
Let's say your system has a font called Helvetica and another called Helvetica Bold. You want the normal text in a text field to use Helvetica and the bold text in that field to use Helvetica Bold. You might think that if they are both included in the FLA library and Helvetica Bold has its bold style option set, it will work.
Wrong. They are separate fonts. As far as Flash is concerned, they might as well be Arial and Times Roman.
Helvetica Bold should NOT have its bold option set. Otherwise, it will be double bolded. Text fields that use this font should NOT have their bold toggle button depressed. If you want Helvetica and Helvetica bold in one text field, use html and css or TextFormat to include more than one font in that field. But don't bold any of the characters with css or TextFormat.
13. Can static fields use fonts in a shared library?
The static text field will not cause extra font outlines to be embedded in the swf. It will use the shared font.
14. What if the bold/italic style settings of the imported font in the library do not match the settings in the shared library swf?
Answer: Things don't work
Dynamic fields will probably display nothing. Static fields that use the shared font might display garbage.
15. How are bitmap fonts handled in the library?
Answer: Basically, the same as bold and italic
If the font in the library has the 'Bitmap Text' option checked, then any text field that uses that font must have its 'Font rendering method' pulldown set to 'Bitmap text (no anti-alias)'. If these do not match, the text will not be displayed.
Also, the font size in the library font properties must match the font size in the text field. If they don't match, the text will not display.
If you want to display the text at a size different than the setting in the font properties (and you don't want another copy of the font with the correct size in your swf), you can nest the text field in a movieclip and stretch the movieclip. But it will look ugly.
16. How does the AS 2.0 Class field in the library font linkage panel work?
Answer: I have absolutely no idea.
I made a simple, skeleton class and put its name in this field (just like you can with a movieclip symbol). I put a trace statement in the class constructor. But when I run the swf, I see no trace. The constructor never executes. If I add syntax errors the class AS file, I get no compiler errors.
I don't think this field does anything at all.
You can use this field to keep short notes to yourself. Or hide secret passwords where no one will think of looking.