The Unbearable Strangeness of Embedding Fonts

Tags:

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?

Answer: Yes

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?

Answer: Yes

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 ?

Answer: Yes

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?

Answer: No

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?

Answer: Maybe

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?

Answer: Yes

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.

Comments

#2 yes, unless you specify a device font like "_sans".

12# we've seen the opposite; you had to set bold on some bold fonts. Really confusing, but I agree you should stick to what you've said.

Really nice to have this conslidated in one entry, thanks for taking the time to do so!

Good point. I didn't even think about device fonts.

I assume they do behave like embedded fonts without having to explicitly embed them. Of course, assuming is a bad idea with Flash.

I've found that device fonts change a static field into a dynamic field internally (in the swf). This means that the device fonts are not automatically embedded (why should device fonts ever be embedded in a swf, right?), but it also means that when rotated, the text goes invisible and alpha has no effect.

Experiment: Create a fla with a static text field. Put "abcdefghijklmnopqrstuvwxyz" in it and don't use a device font. Build it and open it with ASV. The text field will have a name like "Symbol 2 Text". This is the signature of a static field. There will also be an embedded font with 26 character outlines.

Now, back in the fla, change the font to _sans. Build it and look at in in ASV. Now it has a name like "Symbol 2 Editable Text". This is the signature of a dynamic text field. The embedded font will have zero character outlines.

Not surprising that the device font outlines are not in the swf, but it also results in the alpha and rotation behavior mentioned above.

Hi Joelmay,

Your overview on the embedded fonts was quite useful.I have a similar requirement where I am creating font libraries for different font typefaces and locales and importing them in my main swf dynamically.All this is being done through java apis and not through any authoring environment. I want my font resources to be located on some internet-location and point to(import) them from the main swf running in a browser. I need to embed fonts basically to achieve text rotation.Is it possible(pointing to resources over the web; I am getting some security issues with it.)?
Or else is there another way to ship font library swfs to client m/c and cache it?
Please give a detailed reply.
Thanks

I haven't done what you're asking, but I think you can do the following:

Create several shared font library swfs. For example, sharedfont1.swf could have Arial embedded and named myfont1 in its library properties, sharedfont2.swf would have Helvetica embedded and named myfont1, etc. They should be structured the same.

Create a jsp that reads whichever of these shared fonts swf you want at a given time, and outputs that file as a swf file. For this example, call it sharedfonts.jsp.

In your main fla, where you import myfont1, specify sharedfonts.jsp as the url. Notice, the name of the imported shared font matches the name of that font in all the possible shared lib font swfs.

Basically, you're using the jsp file to trick your main swf into thinking there is only one shared lib font swf, but really, your jsp is delivering different swfs at different times.

I think that will work. You might need to do some fussing around to get it right. Probably need to set the MIME type of the jsp output to shockwave/flash/swf or whatever the MIME type of a swf file is.

Good luck

10. Why are the bold characters in my embedded font text field not visible?

This is incorrect, you only need one version of the font. To get it to work takes some hacking though. You need to put a dynamic text field on the stage make it HTML select your library font and type in a Bold character, an Italic character and a Normal character. Then click the embed button and choose all the glyphs you want to embed. Make sure that you have the bold and italic option checked in the library font.

I suppose that Point 10 is not literally true -- you don't need to have all variants of the font in your library. But if you don't have them in the library, those fonts variations will get sucked into the swf due to the Embed Character settings. Unless I am mistaken, Flash will not synthesize the style variations from an embedded font on the fly.

My experiment:

  • I added Lucinda Handwriting to the library. I marked it bold and italic as you specify. I named that font "Lucy".
  • I created a text field with the text "ABCDABCDABCDABCD" and selected the html button. The first 4 chars are regular, next 4 are bold, next 4 are italic and last 4 are bold/italic. The field is using the "Lucy*" font.
  • I clicked the embed button and selected UpperCase [A-Z] as the characters I want.
  • I built it. The swf looks correct. The desired font styles are visible in the text field and they look like 'Lucinda Handwriting'. So, yes all font variations can be seen even though only one font was included in the library.
  • I opened the swf with ASV.
  • There are 4 fonts in the swf. One corresponding to the library font (includes 243 character outlines and is marked bold and italic). The other 3 have 27 character outlines and are marked regular, bold and italic respectively. All fonts have the name Lucinda Handwriting as their name.

So it appears that using the library font as the text field's font does indeed act as a source font for all styles (bold, italic, bold/italic). However, a subset of font is copied into the swf for each style. The style variations are synthesized at compile time, not run time.

One thing I didn't make clear in this article, is that I'm trying to understand what actually goes into the swf. If we understand how it works, we can understand the causes of swf bloat. Of course, if you only specify a subset of the font characters (using the Embed Characters panel), you certainly can control swf bloat that way.

And if you plan on using fonts in a shared library, it is very important to understand the difference between library fonts and fonts embedded due to the Embed Characters panel.

Great overview. I wish I could have read all this about 2 years ago. It would have saved a lot of time/headache. But, I'm a better developer for it. At least that's what I tell myself. :-)

A few other things that I've noticed. In Flash 7 if you embeded a font at 10pt size then you need to display at 10pt or an integer multiple of that: 20, 30... Anything else and the font would look like kack. Flash 8 has the Safron font rendering engine which solved this. I can't discern any visual difference when an embeded font is displayed at the non-embeded size. (Does that make since?)

One of the main reasons for using device fonts is for internationalization purposes. I have a little info on that on my website.

Oh, I've figured out a way to fade/rotate non-embeded text. I'll try to remember to pop back here and let you know when the code is complete.

I never really understood what improved between Flash 7 and 8 font-wise. In Flash 7 days, I never dug in deep enough, and now, I don't have brain space for Flash 7 anymore. I'm glad Macromedia fixed it. My head is hurting enough as it is.

Thanks for the international font point. I had not thought of that. I was basically dismissing device fonts as worthless.

Must be cool to see your Flash work running on an XBox.

Actually, the opportunities presented by Flash lite are interesting. It will be important to fully understand Flash 7 font an device font issues, I would imagine.

Looking forward to your fade/rotate code. Embedded fonts are a major source of bloat, and it would be nice to have the option to not use them.

AS created text? Please do tell oz.

I figured out the fading and masking of device fonts.

http://polygeek.com/253_adobeflash/actionscript_fading-and-masking-with-...

enjoy.

Great article.
i'm trying to render fonts properly with AS2 (flash 7 and 8) and came across various issues/misdocumentations
- what was font size check box about ? someone answered only multiples of that size are properly displayed with flash 7. this is not fun. What if i choose a size of 1 pt ?
- flash 8 : dynamic text and "advanced", "pixel" rendering has bad behaviour. "subpixel" is better sometimes, and "none" behaves correctly. Also depending on these options it's very difficult to position text precisely.
- flash8 : why AS rendered dynamic text is not as nice as when you do it with static manually ? it's not that bad, but deceptive.
- flash 8 : thickness and sharpness are not well documented.

and so on. I threw my towel.

Has anyone come across the problem I'm having with embedded fonts. The text fields work when tested locally but not on the server.

I'm at a loss!

Don't worry the answer was a shared library.=)

Many thanks for sharing your knowledge with such clarity. After half a day head banging the problem we found your site and the solution.

Thank you very much for this post. You saved my day! I turned my head around fonts and flash nearly all day long and when I started thinking about this AS2.0 Class field while setting the export settings for the font I found this entry. Luckily for me I read #16 before I dug any deeper into depression. Thanks again.

i don't know exactly about what you're talking here. if i create everything from AS is not working. if i remove the line with embedFonts it's working. i have two fonts linkaged, Content and ContentBold. the text field is using the one i tell to use, no matter what tags i have into html code. so a little useless because i see no motive to create with hand a text field and then do everything from code wich i belive is working, but not tested.

so, maybe you want to share a file when you create articles like this.

var content_fmt:TextFormat = new TextFormat();
content_fmt.font = "ContentBold";

this.createTextField("my_txt", this.getNextHighestDepth(), 60, 300, 160, 72);
my_txt.html = true;
my_txt.multiline = true;
my_txt.embedFonts = true;
my_txt.htmlText = "this is bold text not bold";
my_txt.setTextFormat(content_fmt);

the line from my code is incomplete because of this blog replacement tags:

my_txt.htmlText = "this is bold text not bold";

this blog is replacing tags that are not closed and neither exist.
so do you understand anyway, there's a b tag wich is not displayed.

Sorry, I'm swamped right now. I'll try to understand your question some time next week.

i'll explain better right now i hope.
if i create the textfield from AS and i asign a font from library, i can't use mixed bold and normal text.
if the textfield is already in the stage it's working as you've said.

sample code here: http://ralcr.com/lucru/test_fonturi/test_fonturi.swf

so the question is, am i doing something wrong? in the library i have fonts with linkage content and contentbold, verdana.

thanks.

hey

seems you forgot me :)

I had the same problem that you're describing here. The only solution I could find was to use CSS. I don't know if this is the best way to do it, but it works.

check this forum:
http://flashmove.com/forum/archive/index.php/t-23343.html

Hope that helps
JRF

Does anyone know of a way to control glyphs embedded for an exported font?

It seems that if you mark a font in a library for export with "Export for runtime sharing", it embeds an ARBITRARY set of glyphs and NOT the glyphs you had specified for embedding in text fields locally. The number of characters produced is actually large - 1530 or so, and seems to vary on some unknown factor perhaps related to Flash installation, locale, or something.

This is a major problem not only because it produces a large file with characters you don't need, but also because it can actually OMIT the characters you would like to have, such as ones from Asian glyphs.

Does anyone know what ACTUALLY controls this exported font embedding behavior?

Ok - I got it!

For exported Font Symbols, the number of glyphs embedded will depend on the "Language for non-Unicode programs" system setting, modifiable in Control Panel\Regional and Language Options\Advanced.

For Arial Unicode MS, the embedded glyph count will be:

English - 243 glyphs
Russian - 1,540 glyphs
Korean - 11,920 glyphs

Some of these will produce REALLY big files.

In order for the class field to work, your class must extend MovieClip.

Actually, that precisely is my point. The font property dialog box has a field for specifying a class, but fonts are not movieclips. The field makes no sense as far as I can tell.

It appears that Macromedia/Adobe intended to add a feature, but they decided against it and accidentally left that field there.

Thanks so much for this gotcha list, already discovered a fair few myself through animating dynamic fields, but this resource helped me out when I checked a recent project on another machine and discovered that no text appeared!

Needless to say it was because the fonts hadn't embedded properly and #7 sorted it.

Many thanks for sharing your knowledge with such clarity. After half a day head banging the problem we found your site and the solution.